From 41fe55ec059d94288e4fd79d616776582261c3fa Mon Sep 17 00:00:00 2001 From: Dmitry Sharabin Date: Tue, 30 Jul 2024 19:25:53 +0200 Subject: [PATCH 1/9] First stab at adding support for GitLab --- backends/gitlab/index.js | 37 +++++++++++++++++++++++++++++++++++++ backends/index-fn.js | 1 + 2 files changed, 38 insertions(+) create mode 100644 backends/gitlab/index.js diff --git a/backends/gitlab/index.js b/backends/gitlab/index.js new file mode 100644 index 0000000..3d4658a --- /dev/null +++ b/backends/gitlab/index.js @@ -0,0 +1,37 @@ +import OAuthBackend from "../../src/oauth-backend.js"; + +/** + * @category GitLab + */ +export default class Gitlab extends OAuthBackend { + static capabilities = { auth: true, put: false, upload: false }; + static defaultPermissions = { read: true }; + + static fileBased = true; + + static urls = [ + "http{s}?://gitlab.com/:id(.+)/-/blob/:branch/:path(.+)", + ]; + + static userCall = "user"; + static userSchema = { + username: "username", + name: ["name", "username"], + avatar: "avatar_url", + url: "web_url", + }; + + static apiDomain = "https://gitlab.com/api/v4/"; + static oAuth = "https://gitlab.com/oauth/authorize"; + + static parseURL (source) { + let ret = super.parseURL(source); + ret.id = encodeURIComponent(ret.id); + return ret; + } + + get (ref = this.ref) { + let { id, branch, path } = ref; + return this.request(`projects/${ id }/repository/files/${ path }/raw?ref=${ branch }`); + } +} diff --git a/backends/index-fn.js b/backends/index-fn.js index a348b11..b38b8cd 100644 --- a/backends/index-fn.js +++ b/backends/index-fn.js @@ -9,3 +9,4 @@ export {default as Dropbox} from "./dropbox/index.js"; export * from "./google/index.js"; export * from "./coda/index.js"; export {default as Firebase} from "./firebase/index.js"; +export {default as Gitlab} from "./gitlab/index.js"; From 2054e7f41392f1fab577334b358063ff050cce7d Mon Sep 17 00:00:00 2001 From: Dmitry Sharabin Date: Wed, 31 Jul 2024 10:45:36 +0200 Subject: [PATCH 2/9] Add support for put() --- backends/gitlab/index.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/backends/gitlab/index.js b/backends/gitlab/index.js index 3d4658a..9af08f2 100644 --- a/backends/gitlab/index.js +++ b/backends/gitlab/index.js @@ -4,7 +4,7 @@ import OAuthBackend from "../../src/oauth-backend.js"; * @category GitLab */ export default class Gitlab extends OAuthBackend { - static capabilities = { auth: true, put: false, upload: false }; + static capabilities = { auth: true, put: true, upload: false }; static defaultPermissions = { read: true }; static fileBased = true; @@ -26,12 +26,22 @@ export default class Gitlab extends OAuthBackend { static parseURL (source) { let ret = super.parseURL(source); - ret.id = encodeURIComponent(ret.id); + ret.apiCall = `projects/${ encodeURIComponent(ret.id) }/repository/files/${ ret.path }`; return ret; } get (ref = this.ref) { - let { id, branch, path } = ref; - return this.request(`projects/${ id }/repository/files/${ path }/raw?ref=${ branch }`); + let { apiCall, branch } = ref; + return this.request(`${ apiCall }/raw?ref=${ branch }`); + } + + async put (data, {ref = this.ref} = {}) { + let { apiCall, path, branch } = ref; + let body = { + branch, + content: await this.stringify(data), + commit_message: `Update file ${ path }`, + }; + return this.request(apiCall, body, "PUT"); } } From f7347d1cf1ba7a06815af7a9ce1ae29d7e5f8291 Mon Sep 17 00:00:00 2001 From: Dmitry Sharabin Date: Wed, 31 Jul 2024 10:49:03 +0200 Subject: [PATCH 3/9] Pass options --- backends/gitlab/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/gitlab/index.js b/backends/gitlab/index.js index 9af08f2..4fde94c 100644 --- a/backends/gitlab/index.js +++ b/backends/gitlab/index.js @@ -39,7 +39,7 @@ export default class Gitlab extends OAuthBackend { let { apiCall, path, branch } = ref; let body = { branch, - content: await this.stringify(data), + content: await this.stringify(data, {ref}), commit_message: `Update file ${ path }`, }; return this.request(apiCall, body, "PUT"); From dcdbd01b747978c2a79725a9792c3ceb70b277d2 Mon Sep 17 00:00:00 2001 From: Dmitry Sharabin Date: Wed, 31 Jul 2024 10:55:46 +0200 Subject: [PATCH 4/9] Add localization phrases --- backends/gitlab/index.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/backends/gitlab/index.js b/backends/gitlab/index.js index 4fde94c..25fd045 100644 --- a/backends/gitlab/index.js +++ b/backends/gitlab/index.js @@ -30,6 +30,10 @@ export default class Gitlab extends OAuthBackend { return ret; } + static phrases = { + "updated_file": (name = "file") => "Updated " + name, + }; + get (ref = this.ref) { let { apiCall, branch } = ref; return this.request(`${ apiCall }/raw?ref=${ branch }`); @@ -40,7 +44,7 @@ export default class Gitlab extends OAuthBackend { let body = { branch, content: await this.stringify(data, {ref}), - commit_message: `Update file ${ path }`, + commit_message: this.constructor.phrase("updated_file", path), }; return this.request(apiCall, body, "PUT"); } From 18902e460c6772f38b4d45c86df572b7c7a5858b Mon Sep 17 00:00:00 2001 From: Dmitry Sharabin Date: Wed, 31 Jul 2024 10:58:10 +0200 Subject: [PATCH 5/9] =?UTF-8?q?Rename:=20apiCall=20=E2=86=92=20fileCall?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backends/gitlab/index.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/backends/gitlab/index.js b/backends/gitlab/index.js index 25fd045..babe54d 100644 --- a/backends/gitlab/index.js +++ b/backends/gitlab/index.js @@ -26,7 +26,7 @@ export default class Gitlab extends OAuthBackend { static parseURL (source) { let ret = super.parseURL(source); - ret.apiCall = `projects/${ encodeURIComponent(ret.id) }/repository/files/${ ret.path }`; + ret.fileCall = `projects/${ encodeURIComponent(ret.id) }/repository/files/${ ret.path }`; return ret; } @@ -35,17 +35,17 @@ export default class Gitlab extends OAuthBackend { }; get (ref = this.ref) { - let { apiCall, branch } = ref; - return this.request(`${ apiCall }/raw?ref=${ branch }`); + let { fileCall, branch } = ref; + return this.request(`${ fileCall }/raw?ref=${ branch }`); } async put (data, {ref = this.ref} = {}) { - let { apiCall, path, branch } = ref; + let { fileCall, path, branch } = ref; let body = { branch, content: await this.stringify(data, {ref}), commit_message: this.constructor.phrase("updated_file", path), }; - return this.request(apiCall, body, "PUT"); + return this.request(fileCall, body, "PUT"); } } From bca657f2d55c7d829c6bc9b10df18de36c9f5f7d Mon Sep 17 00:00:00 2001 From: Dmitry Sharabin Date: Wed, 31 Jul 2024 10:59:07 +0200 Subject: [PATCH 6/9] Move phrases up --- backends/gitlab/index.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/backends/gitlab/index.js b/backends/gitlab/index.js index babe54d..ff2cfac 100644 --- a/backends/gitlab/index.js +++ b/backends/gitlab/index.js @@ -24,16 +24,16 @@ export default class Gitlab extends OAuthBackend { static apiDomain = "https://gitlab.com/api/v4/"; static oAuth = "https://gitlab.com/oauth/authorize"; + static phrases = { + "updated_file": (name = "file") => "Updated " + name, + }; + static parseURL (source) { let ret = super.parseURL(source); ret.fileCall = `projects/${ encodeURIComponent(ret.id) }/repository/files/${ ret.path }`; return ret; } - static phrases = { - "updated_file": (name = "file") => "Updated " + name, - }; - get (ref = this.ref) { let { fileCall, branch } = ref; return this.request(`${ fileCall }/raw?ref=${ branch }`); From 6d1e1f803db80c05f83b0d9759100a1300a14d42 Mon Sep 17 00:00:00 2001 From: Dmitry Sharabin Date: Wed, 31 Jul 2024 11:18:14 +0200 Subject: [PATCH 7/9] Encode id on URL parsing --- backends/gitlab/index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backends/gitlab/index.js b/backends/gitlab/index.js index ff2cfac..8e8bbd3 100644 --- a/backends/gitlab/index.js +++ b/backends/gitlab/index.js @@ -30,7 +30,8 @@ export default class Gitlab extends OAuthBackend { static parseURL (source) { let ret = super.parseURL(source); - ret.fileCall = `projects/${ encodeURIComponent(ret.id) }/repository/files/${ ret.path }`; + ret.id = encodeURIComponent(ret.id); + ret.fileCall = `projects/${ ret.id }/repository/files/${ ret.path }`; return ret; } From 09f583c2bb06f35ac77e99d5138b64070c882414 Mon Sep 17 00:00:00 2001 From: Dmitry Sharabin Date: Wed, 31 Jul 2024 12:21:52 +0200 Subject: [PATCH 8/9] Add support for uploading files --- backends/gitlab/index.js | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/backends/gitlab/index.js b/backends/gitlab/index.js index 8e8bbd3..d14ea19 100644 --- a/backends/gitlab/index.js +++ b/backends/gitlab/index.js @@ -1,10 +1,11 @@ import OAuthBackend from "../../src/oauth-backend.js"; +import { readFile } from "../../src/util.js"; /** * @category GitLab */ export default class Gitlab extends OAuthBackend { - static capabilities = { auth: true, put: true, upload: false }; + static capabilities = { auth: true, put: true, upload: true }; static defaultPermissions = { read: true }; static fileBased = true; @@ -26,6 +27,7 @@ export default class Gitlab extends OAuthBackend { static phrases = { "updated_file": (name = "file") => "Updated " + name, + "uploaded_file": (name = "file") => "Uploaded " + name, }; static parseURL (source) { @@ -49,4 +51,30 @@ export default class Gitlab extends OAuthBackend { }; return this.request(fileCall, body, "PUT"); } + + async upload (file, path = file.name) { + let { id, branch } = this.ref; + let fileCall = `projects/${ id }/repository/files/${ encodeURIComponent(path) }`; + + let type = file.type; + let isText = type.startsWith("text/") || type.startsWith("application/") && !type.endsWith("pdf"); + let content; + if (isText) { + content = await readFile(file, "Text"); + } + else { + content = await readFile(file); + content = content.slice(5); // remove “data:” + type = type.replace("+", "\\+"); // escape “+” in, e.g., “image/svg+xml” + content = content.replace(RegExp(`^${type}(;base64)?,`), ""); + } + + let body = { + branch, + content, + commit_message: this.constructor.phrase("uploaded_file", path), + encoding: isText ? "text" : "base64", + }; + return this.request(fileCall, body, "POST"); + } } From b51b49b4e8eb71fc8bab6319480934456b3e7928 Mon Sep 17 00:00:00 2001 From: Dmitry Sharabin Date: Wed, 31 Jul 2024 12:27:23 +0200 Subject: [PATCH 9/9] Encode all needed components --- backends/gitlab/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backends/gitlab/index.js b/backends/gitlab/index.js index d14ea19..4ef3d94 100644 --- a/backends/gitlab/index.js +++ b/backends/gitlab/index.js @@ -32,7 +32,7 @@ export default class Gitlab extends OAuthBackend { static parseURL (source) { let ret = super.parseURL(source); - ret.id = encodeURIComponent(ret.id); + ["id", "path"].forEach(key => ret[key] = encodeURIComponent(ret[key])); ret.fileCall = `projects/${ ret.id }/repository/files/${ ret.path }`; return ret; }