@silexlabs/silex 3.0.1-0 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.default +3 -2
- package/.silex.js +39 -1
- package/README.md +37 -35
- package/dist/client/client/api.d.ts +8 -1
- package/dist/client/client/assetUrl.d.ts +54 -0
- package/dist/client/client/config.d.ts +60 -1
- package/dist/client/client/events.d.ts +19 -10
- package/dist/client/client/grapesjs/PublicationManager.d.ts +6 -8
- package/dist/client/client/grapesjs/PublicationUi.d.ts +8 -10
- package/dist/client/client/grapesjs/breadcrumbs.d.ts +1 -0
- package/dist/client/client/grapesjs/css-props.d.ts +6 -0
- package/dist/client/client/grapesjs/footer.d.ts +2 -0
- package/dist/client/client/grapesjs/img.d.ts +6 -0
- package/dist/client/client/grapesjs/index.d.ts +6 -2
- package/dist/client/client/grapesjs/internal-links.d.ts +1 -1
- package/dist/client/client/grapesjs/keymaps.d.ts +123 -0
- package/dist/client/client/grapesjs/new-page-dialog.d.ts +1 -1
- package/dist/client/client/grapesjs/page-panel.d.ts +7 -1
- package/dist/client/client/grapesjs/project-bar.d.ts +20 -0
- package/dist/client/client/grapesjs/resize-panel.d.ts +1 -0
- package/dist/client/client/grapesjs/rich-text.d.ts +4 -1
- package/dist/client/client/grapesjs/semantic.d.ts +1 -1
- package/dist/client/client/grapesjs/settings-sections.d.ts +16 -0
- package/dist/client/client/grapesjs/settings.d.ts +3 -1
- package/dist/client/client/grapesjs/storage.d.ts +1 -0
- package/dist/client/client/grapesjs/symbolDialogs.d.ts +1 -1
- package/dist/client/client/grapesjs/view-buttons.d.ts +1 -0
- package/dist/client/client/index.d.ts +5 -0
- package/dist/client/client/publication-transformers.d.ts +42 -0
- package/dist/client/client/publish-custom-code-block.d.ts +4 -0
- package/dist/client/client/publish-fonts.d.ts +4 -0
- package/dist/client/client/utils.d.ts +22 -1
- package/dist/client/constants.d.ts +3 -0
- package/dist/client/css/admin.css +1107 -411
- package/dist/client/css/admin.css.map +1 -0
- package/dist/client/grapesjs-filter-styles/dist/index.d.ts +4 -0
- package/dist/client/grapesjs-fonts/dist/index.d.ts +4 -0
- package/dist/client/grapesjs-fonts/src/commands.d.ts +3 -0
- package/dist/client/grapesjs-fonts/src/fonts.d.ts +4 -0
- package/dist/client/grapesjs-storage-rate-limit/dist/index.d.ts +4 -0
- package/dist/client/grapesjs-ui-suggest-classes/dist/index.d.ts +4 -0
- package/dist/client/index.html +3 -2
- package/dist/client/js/main.js +305 -170
- package/dist/client/js/main.js.LICENSE.txt +21 -1
- package/dist/client/page.d.ts +1 -1
- package/dist/client/silex-lib/src/ts/client/api.d.ts +90 -0
- package/dist/client/silex-lib/src/ts/client/assetUrl.d.ts +54 -0
- package/dist/client/silex-lib/src/ts/client/config.d.ts +102 -0
- package/dist/client/silex-lib/src/ts/client/events.d.ts +23 -0
- package/dist/client/silex-lib/src/ts/client/expose.d.ts +8 -0
- package/dist/client/silex-lib/src/ts/client/grapesjs/LoginDialog.d.ts +15 -0
- package/dist/client/silex-lib/src/ts/client/grapesjs/PublicationManager.d.ts +73 -0
- package/dist/client/silex-lib/src/ts/client/grapesjs/PublicationUi.d.ts +59 -0
- package/dist/client/silex-lib/src/ts/client/grapesjs/blocks.d.ts +1 -0
- package/dist/client/silex-lib/src/ts/client/grapesjs/breadcrumbs.d.ts +1 -0
- package/dist/client/silex-lib/src/ts/client/grapesjs/css-props.d.ts +6 -0
- package/dist/client/silex-lib/src/ts/client/grapesjs/footer.d.ts +2 -0
- package/dist/client/silex-lib/src/ts/client/grapesjs/img.d.ts +6 -0
- package/dist/client/silex-lib/src/ts/client/grapesjs/index.d.ts +9 -0
- package/dist/client/silex-lib/src/ts/client/grapesjs/internal-links.d.ts +1 -0
- package/dist/client/silex-lib/src/ts/client/grapesjs/keymaps.d.ts +123 -0
- package/dist/client/silex-lib/src/ts/client/grapesjs/new-page-dialog.d.ts +2 -0
- package/dist/client/silex-lib/src/ts/client/grapesjs/openImport.d.ts +9 -0
- package/dist/client/silex-lib/src/ts/client/grapesjs/page-panel.d.ts +9 -0
- package/dist/client/silex-lib/src/ts/client/grapesjs/project-bar.d.ts +21 -0
- package/dist/client/silex-lib/src/ts/client/grapesjs/resize-panel.d.ts +1 -0
- package/dist/client/silex-lib/src/ts/client/grapesjs/rich-text.d.ts +4 -0
- package/dist/client/silex-lib/src/ts/client/grapesjs/semantic.d.ts +1 -0
- package/dist/client/silex-lib/src/ts/client/grapesjs/settings-sections.d.ts +16 -0
- package/dist/client/silex-lib/src/ts/client/grapesjs/settings.d.ts +4 -0
- package/dist/client/silex-lib/src/ts/client/grapesjs/storage.d.ts +2 -0
- package/dist/client/silex-lib/src/ts/client/grapesjs/symbolDialogs.d.ts +3 -0
- package/dist/client/silex-lib/src/ts/client/grapesjs/view-buttons.d.ts +1 -0
- package/dist/client/silex-lib/src/ts/client/index.d.ts +10 -0
- package/dist/client/silex-lib/src/ts/client/publication-transformers.d.ts +42 -0
- package/dist/client/silex-lib/src/ts/client/publish-custom-code-block.d.ts +4 -0
- package/dist/client/silex-lib/src/ts/client/publish-fonts.d.ts +4 -0
- package/dist/client/silex-lib/src/ts/client/utils.d.ts +22 -0
- package/dist/client/silex-lib/src/ts/constants.d.ts +32 -0
- package/dist/client/silex-lib/src/ts/page.d.ts +2 -0
- package/dist/client/silex-lib/src/ts/types.d.ts +339 -0
- package/dist/client/types.d.ts +59 -35
- package/dist/plugins/client/client/events.d.ts +19 -10
- package/dist/plugins/client/client/events.js +11 -0
- package/dist/plugins/client/client/events.js.map +1 -1
- package/dist/plugins/client/plugins/client/template.js +119 -71
- package/dist/plugins/client/plugins/client/template.js.map +1 -1
- package/dist/plugins/client/plugins/client/website-info.d.ts +1 -0
- package/dist/plugins/client/plugins/client/website-info.js +72 -0
- package/dist/plugins/client/plugins/client/website-info.js.map +1 -0
- package/dist/plugins/client/types.d.ts +59 -35
- package/dist/plugins/client/types.js +23 -0
- package/dist/plugins/client/types.js.map +1 -1
- package/dist/plugins/server/constants.d.ts +3 -0
- package/dist/plugins/server/constants.js +28 -1
- package/dist/plugins/server/constants.js.map +1 -1
- package/dist/plugins/server/plugins/server/Cache.js +9 -5
- package/dist/plugins/server/plugins/server/Cache.js.map +1 -1
- package/dist/plugins/server/plugins/server/DownloadConnector.d.ts +29 -0
- package/dist/plugins/server/plugins/server/DownloadConnector.js +127 -0
- package/dist/plugins/server/plugins/server/DownloadConnector.js.map +1 -0
- package/dist/plugins/server/plugins/server/FtpConnector.d.ts +5 -2
- package/dist/plugins/server/plugins/server/FtpConnector.js +38 -23
- package/dist/plugins/server/plugins/server/FtpConnector.js.map +1 -1
- package/dist/plugins/server/plugins/server/GitlabConnector.d.ts +63 -9
- package/dist/plugins/server/plugins/server/GitlabConnector.js +367 -91
- package/dist/plugins/server/plugins/server/GitlabConnector.js.map +1 -1
- package/dist/plugins/server/plugins/server/GitlabHostingConnector.d.ts +16 -0
- package/dist/plugins/server/plugins/server/GitlabHostingConnector.js +209 -0
- package/dist/plugins/server/plugins/server/GitlabHostingConnector.js.map +1 -0
- package/dist/plugins/server/plugins/server/SslPlugin.js +6 -6
- package/dist/plugins/server/plugins/server/SslPlugin.js.map +1 -1
- package/dist/plugins/server/plugins/server/StaticPlugin.d.ts +8 -1
- package/dist/plugins/server/plugins/server/StaticPlugin.js +5 -31
- package/dist/plugins/server/plugins/server/StaticPlugin.js.map +1 -1
- package/dist/plugins/server/server/config.js +8 -9
- package/dist/plugins/server/server/config.js.map +1 -1
- package/dist/plugins/server/server/connectors/FsHosting.d.ts +3 -2
- package/dist/plugins/server/server/connectors/FsHosting.js +18 -7
- package/dist/plugins/server/server/connectors/FsHosting.js.map +1 -1
- package/dist/plugins/server/server/connectors/FsStorage.d.ts +3 -1
- package/dist/plugins/server/server/connectors/FsStorage.js +35 -28
- package/dist/plugins/server/server/connectors/FsStorage.js.map +1 -1
- package/dist/plugins/server/server/connectors/connectors.d.ts +7 -7
- package/dist/plugins/server/server/connectors/connectors.js +6 -7
- package/dist/plugins/server/server/connectors/connectors.js.map +1 -1
- package/dist/plugins/server/server/events.js +16 -0
- package/dist/plugins/server/server/events.js.map +1 -1
- package/dist/plugins/server/server/jobs.d.ts +6 -0
- package/dist/plugins/server/server/jobs.js +12 -8
- package/dist/plugins/server/server/jobs.js.map +1 -1
- package/dist/plugins/server/server/utils/validation.js +1 -2
- package/dist/plugins/server/server/utils/validation.js.map +1 -1
- package/dist/plugins/server/types.d.ts +59 -35
- package/dist/plugins/server/types.js +24 -1
- package/dist/plugins/server/types.js.map +1 -1
- package/dist/server/constants.js +27 -1
- package/dist/server/plugins/server/Cache.js +9 -5
- package/dist/server/server/api/api.js +1 -1
- package/dist/server/server/api/connectorApi.js +154 -25
- package/dist/server/server/api/publicationApi.js +17 -25
- package/dist/server/server/api/websiteApi.js +30 -8
- package/dist/server/server/cli.js +9 -6
- package/dist/server/server/config.js +8 -9
- package/dist/server/server/connectors/FsHosting.js +17 -7
- package/dist/server/server/connectors/FsStorage.js +34 -28
- package/dist/server/server/connectors/connectors.js +6 -7
- package/dist/server/server/express.js +4 -5
- package/dist/server/server/index.js +5 -1
- package/dist/server/server/jobs.js +11 -8
- package/dist/server/server/utils/validation.js +1 -2
- package/dist/server/types.js +13 -1
- package/package.json +56 -42
- package/public/assets/download.png +0 -0
- package/public/assets/favicon.ico +0 -0
- package/public/assets/favicon.png +0 -0
- package/public/assets/ftp.png +0 -0
- package/public/assets/gitlab.png +0 -0
- package/public/assets/gitlab2.png +0 -0
- package/public/assets/laptop.png +0 -0
- package/public/assets/logo-silex-small.png +0 -0
- package/public/silex.js +5 -23
- package/src/css/_variables.scss +23 -20
- package/src/css/dialog.scss +27 -1
- package/src/css/fonts.scss +31 -0
- package/src/css/footer.scss +12 -0
- package/src/css/grapesjs-light.scss +180 -0
- package/src/css/grapesjs-plugins.scss +227 -0
- package/src/css/grapesjs.scss +84 -10
- package/src/css/index.scss +12 -1
- package/src/css/light.scss +7 -0
- package/src/css/project-bar.scss +32 -16
- package/src/css/silex.scss +79 -5
- package/src/css/website-info.scss +14 -0
- package/src/html/index.pug +3 -3
- package/src/ts/client/api.ts +38 -14
- package/src/ts/client/assetUrl.test.ts +164 -0
- package/src/ts/client/assetUrl.ts +254 -0
- package/src/ts/client/config.ts +133 -5
- package/src/ts/client/events.ts +21 -9
- package/src/ts/client/grapesjs/LoginDialog.ts +4 -2
- package/src/ts/client/grapesjs/PublicationManager.ts +180 -54
- package/src/ts/client/grapesjs/PublicationUi.ts +122 -86
- package/src/ts/client/grapesjs/breadcrumbs.ts +79 -0
- package/src/ts/client/grapesjs/css-props.ts +910 -0
- package/src/ts/client/grapesjs/eleventy.ts +11 -8
- package/{dist/plugins/client/page.js → src/ts/client/grapesjs/footer.ts} +24 -13
- package/src/ts/client/grapesjs/img.ts +147 -0
- package/src/ts/client/grapesjs/index.ts +234 -52
- package/src/ts/client/grapesjs/internal-links.test.ts +2 -1
- package/src/ts/client/grapesjs/internal-links.ts +14 -7
- package/src/ts/client/grapesjs/keymaps.ts +207 -0
- package/src/ts/client/grapesjs/new-page-dialog.ts +2 -3
- package/src/ts/client/grapesjs/page-panel.ts +92 -7
- package/src/ts/client/grapesjs/project-bar.ts +116 -72
- package/src/ts/client/grapesjs/resize-panel.ts +20 -0
- package/src/ts/client/grapesjs/rich-text.ts +21 -13
- package/src/ts/client/grapesjs/semantic.ts +3 -3
- package/src/ts/client/grapesjs/settings-sections.ts +117 -0
- package/src/ts/client/grapesjs/settings.ts +174 -96
- package/src/ts/client/grapesjs/storage.ts +98 -33
- package/src/ts/client/grapesjs/symbolDialogs.ts +3 -4
- package/src/ts/{plugins/server/AuthPlugin.ts → client/grapesjs/view-buttons.ts} +23 -19
- package/src/ts/client/index.ts +35 -16
- package/src/ts/client/publication-transformers.test.ts +207 -0
- package/src/ts/client/publication-transformers.ts +280 -0
- package/{dist/plugins/client/client/utils.js → src/ts/client/publish-custom-code-block.ts} +14 -8
- package/src/ts/client/publish-fonts.ts +36 -0
- package/src/ts/client/utils.ts +53 -1
- package/src/ts/constants.ts +31 -0
- package/src/ts/page.ts +2 -2
- package/src/ts/plugins/client/template.ts +125 -75
- package/src/ts/plugins/client/website-info.ts +84 -0
- package/src/ts/plugins/server/Cache.ts +6 -2
- package/src/ts/plugins/server/DownloadConnector.ts +146 -0
- package/src/ts/plugins/server/FtpConnector.ts +47 -21
- package/src/ts/plugins/server/GitlabConnector.ts +423 -108
- package/src/ts/plugins/server/GitlabHostingConnector.ts +215 -0
- package/src/ts/plugins/server/SslPlugin.ts +5 -5
- package/src/ts/plugins/server/StaticPlugin.ts +3 -30
- package/src/ts/server/api/connectorApi.ts +165 -28
- package/src/ts/server/api/publicationApi.ts +17 -24
- package/src/ts/server/api/websiteApi.ts +57 -14
- package/src/ts/server/cli.ts +7 -5
- package/src/ts/server/config.ts +9 -10
- package/src/ts/server/connectors/FsHosting.ts +14 -8
- package/src/ts/server/connectors/FsStorage.ts +40 -7
- package/src/ts/server/connectors/connectors.ts +8 -6
- package/src/ts/server/events.ts +17 -0
- package/src/ts/server/express.ts +2 -2
- package/src/ts/server/index.ts +6 -0
- package/src/ts/server/jobs.ts +14 -2
- package/src/ts/server/utils/BackwardCompat.ts +530 -529
- package/src/ts/types.ts +78 -34
- package/dist/plugins/client/client/utils.d.ts +0 -1
- package/dist/plugins/client/client/utils.js.map +0 -1
- package/dist/plugins/client/page.d.ts +0 -2
- package/dist/plugins/client/page.js.map +0 -1
- package/dist/plugins/client/plugins/client/publicationRenderer.d.ts +0 -2
- package/dist/plugins/client/plugins/client/publicationRenderer.js +0 -128
- package/dist/plugins/client/plugins/client/publicationRenderer.js.map +0 -1
- package/dist/plugins/server/plugins/server/AuthPlugin.d.ts +0 -1
- package/dist/plugins/server/plugins/server/AuthPlugin.js +0 -38
- package/dist/plugins/server/plugins/server/AuthPlugin.js.map +0 -1
- package/dist/plugins/server/plugins/server/HooksPlugin.d.ts +0 -7
- package/dist/plugins/server/plugins/server/HooksPlugin.js +0 -74
- package/dist/plugins/server/plugins/server/HooksPlugin.js.map +0 -1
- package/src/example-client-config.js +0 -64
- package/src/ts/plugins/client/publicationRenderer.ts +0 -128
- package/src/ts/plugins/server/HooksPlugin.ts +0 -76
|
@@ -47,98 +47,217 @@ const connectors_1 = require("../../server/connectors/connectors");
|
|
|
47
47
|
const types_1 = require("../../types");
|
|
48
48
|
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
49
49
|
const crypto_1 = __importStar(require("crypto"));
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
const path_1 = require("path");
|
|
51
|
+
const svg = `<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
52
|
+
<svg
|
|
53
|
+
xmlns:svg="http://www.w3.org/2000/svg"
|
|
54
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
55
|
+
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
56
|
+
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
57
|
+
width="1000"
|
|
58
|
+
height="963.197"
|
|
59
|
+
viewBox="0 0 1000 963.197"
|
|
60
|
+
version="1.1"
|
|
61
|
+
id="svg85">
|
|
62
|
+
<sodipodi:namedview
|
|
63
|
+
id="namedview87"
|
|
64
|
+
pagecolor="#ffffff"
|
|
65
|
+
bordercolor="#666666"
|
|
66
|
+
borderopacity="1.0"
|
|
67
|
+
inkscape:pageshadow="2"
|
|
68
|
+
inkscape:pageopacity="0.0"
|
|
69
|
+
inkscape:pagecheckerboard="0"
|
|
70
|
+
showgrid="false"
|
|
71
|
+
inkscape:zoom="1"
|
|
72
|
+
inkscape:cx="991.5"
|
|
73
|
+
inkscape:cy="964.5"
|
|
74
|
+
inkscape:window-width="1126"
|
|
75
|
+
inkscape:window-height="895"
|
|
76
|
+
inkscape:window-x="774"
|
|
77
|
+
inkscape:window-y="12"
|
|
78
|
+
inkscape:window-maximized="0"
|
|
79
|
+
inkscape:current-layer="svg85" />
|
|
80
|
+
<defs
|
|
81
|
+
id="defs74">
|
|
82
|
+
<style
|
|
83
|
+
id="style72">.cls-1{fill:#e24329;}.cls-2{fill:#fc6d26;}.cls-3{fill:#fca326;}</style>
|
|
84
|
+
</defs>
|
|
85
|
+
<g
|
|
86
|
+
id="LOGO"
|
|
87
|
+
transform="matrix(5.2068817,0,0,5.2068817,-489.30756,-507.76085)">
|
|
88
|
+
<path
|
|
89
|
+
class="cls-1"
|
|
90
|
+
d="m 282.83,170.73 -0.27,-0.69 -26.14,-68.22 a 6.81,6.81 0 0 0 -2.69,-3.24 7,7 0 0 0 -8,0.43 7,7 0 0 0 -2.32,3.52 l -17.65,54 h -71.47 l -17.65,-54 a 6.86,6.86 0 0 0 -2.32,-3.53 7,7 0 0 0 -8,-0.43 6.87,6.87 0 0 0 -2.69,3.24 L 97.44,170 l -0.26,0.69 a 48.54,48.54 0 0 0 16.1,56.1 l 0.09,0.07 0.24,0.17 39.82,29.82 19.7,14.91 12,9.06 a 8.07,8.07 0 0 0 9.76,0 l 12,-9.06 19.7,-14.91 40.06,-30 0.1,-0.08 a 48.56,48.56 0 0 0 16.08,-56.04 z"
|
|
91
|
+
id="path76" />
|
|
92
|
+
<path
|
|
93
|
+
class="cls-2"
|
|
94
|
+
d="m 282.83,170.73 -0.27,-0.69 a 88.3,88.3 0 0 0 -35.15,15.8 L 190,229.25 c 19.55,14.79 36.57,27.64 36.57,27.64 l 40.06,-30 0.1,-0.08 a 48.56,48.56 0 0 0 16.1,-56.08 z"
|
|
95
|
+
id="path78" />
|
|
96
|
+
<path
|
|
97
|
+
class="cls-3"
|
|
98
|
+
d="m 153.43,256.89 19.7,14.91 12,9.06 a 8.07,8.07 0 0 0 9.76,0 l 12,-9.06 19.7,-14.91 c 0,0 -17.04,-12.89 -36.59,-27.64 -19.55,14.75 -36.57,27.64 -36.57,27.64 z"
|
|
99
|
+
id="path80" />
|
|
100
|
+
<path
|
|
101
|
+
class="cls-2"
|
|
102
|
+
d="M 132.58,185.84 A 88.19,88.19 0 0 0 97.44,170 l -0.26,0.69 a 48.54,48.54 0 0 0 16.1,56.1 l 0.09,0.07 0.24,0.17 39.82,29.82 c 0,0 17,-12.85 36.57,-27.64 z"
|
|
103
|
+
id="path82" />
|
|
104
|
+
</g>
|
|
105
|
+
</svg>`;
|
|
106
|
+
const encodedSvg = encodeURIComponent(svg);
|
|
107
|
+
const ICON = '/assets/gitlab.png';
|
|
53
108
|
class GitlabConnector {
|
|
54
109
|
config;
|
|
55
110
|
connectorId = 'gitlab';
|
|
56
111
|
connectorType = types_1.ConnectorType.STORAGE;
|
|
57
112
|
displayName = 'GitLab';
|
|
58
|
-
icon =
|
|
113
|
+
icon = ICON;
|
|
59
114
|
disableLogout = false;
|
|
60
|
-
color = '#
|
|
61
|
-
background = '
|
|
115
|
+
color = '#2B1B63';
|
|
116
|
+
background = 'rgba(252, 109, 38, 0.2)';
|
|
62
117
|
options;
|
|
63
118
|
constructor(config, opts) {
|
|
64
119
|
this.config = config;
|
|
65
120
|
this.options = {
|
|
66
121
|
branch: 'main',
|
|
67
|
-
assetsFolder: '',
|
|
122
|
+
assetsFolder: 'assets',
|
|
123
|
+
//metaRepo: 'silex-meta',
|
|
124
|
+
//metaRepoFile: 'websites.json',
|
|
125
|
+
repoPrefix: 'silex_',
|
|
126
|
+
scope: 'api', // 'api+read_api+read_user+read_repository+write_repository+email+sudo+profile+openid'
|
|
68
127
|
...opts,
|
|
69
128
|
};
|
|
70
129
|
if (!this.options.clientId)
|
|
71
130
|
throw new Error('Missing Gitlab client ID');
|
|
72
131
|
if (!this.options.clientSecret)
|
|
73
132
|
throw new Error('Missing Gitlab client secret');
|
|
133
|
+
if (!this.options.domain)
|
|
134
|
+
throw new Error('Missing Gitlab domain');
|
|
135
|
+
if (!this.options.timeOut)
|
|
136
|
+
this.options.timeOut = 15000; /* default value */
|
|
74
137
|
}
|
|
75
138
|
// **
|
|
76
139
|
// Convenience methods for the Gitlab API
|
|
77
140
|
getAssetPath(path) {
|
|
78
|
-
return
|
|
141
|
+
return encodeURIComponent((0, path_1.join)(this.options.assetsFolder, path));
|
|
142
|
+
}
|
|
143
|
+
isUsingOfficialInstance() {
|
|
144
|
+
const gitlabDomainRegexp = /(^|\b)(gitlab\.com)($|\b)/;
|
|
145
|
+
return gitlabDomainRegexp.test(this.options.domain);
|
|
79
146
|
}
|
|
80
147
|
async createFile(session, websiteId, path, content, isBase64 = false) {
|
|
81
148
|
// Remove leading slash
|
|
82
149
|
const safePath = path.replace(/^\//, '');
|
|
150
|
+
const encodePath = decodeURIComponent(path);
|
|
83
151
|
return this.callApi(session, `api/v4/projects/${websiteId}/repository/files/${safePath}`, 'POST', {
|
|
84
152
|
id: websiteId,
|
|
85
153
|
branch: this.options.branch,
|
|
86
154
|
content,
|
|
87
|
-
commit_message: `Create file ${
|
|
155
|
+
commit_message: `Create file ${encodePath} from Silex`,
|
|
88
156
|
encoding: isBase64 ? 'base64' : undefined,
|
|
89
157
|
});
|
|
90
158
|
}
|
|
91
159
|
async updateFile(session, websiteId, path, content, isBase64 = false) {
|
|
92
160
|
// Remove leading slash
|
|
93
161
|
const safePath = path.replace(/^\//, '');
|
|
162
|
+
const encodePath = decodeURIComponent(path);
|
|
94
163
|
return this.callApi(session, `api/v4/projects/${websiteId}/repository/files/${safePath}`, 'PUT', {
|
|
95
164
|
id: websiteId,
|
|
96
165
|
branch: this.options.branch,
|
|
97
166
|
content: await (0, connectors_1.contentToString)(content),
|
|
98
|
-
commit_message: `Update website asset ${
|
|
167
|
+
commit_message: `Update website asset ${encodePath} from Silex`,
|
|
99
168
|
encoding: isBase64 ? 'base64' : undefined,
|
|
100
169
|
});
|
|
101
170
|
}
|
|
102
|
-
async
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
const
|
|
106
|
-
const url = `https://gitlab.com/${path}?${tokenParam}${paramsStr}`;
|
|
171
|
+
async readFile(session, websiteId, fileName) {
|
|
172
|
+
const safePath = fileName.replace(/^\//, '');
|
|
173
|
+
// Call the API
|
|
174
|
+
const url = `${this.options.domain}/api/v4/projects/${websiteId}/repository/files/${safePath}?ref=${this.options.branch}&access_token=${this.getSessionToken(session).token?.access_token}`;
|
|
107
175
|
const response = await (0, node_fetch_1.default)(url, {
|
|
108
|
-
method,
|
|
176
|
+
method: 'GET',
|
|
109
177
|
headers: {
|
|
110
178
|
'Content-Type': 'application/json',
|
|
111
179
|
},
|
|
112
|
-
body: body ? JSON.stringify(body) : undefined
|
|
113
180
|
});
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
181
|
+
const json = await response.json();
|
|
182
|
+
if (!response.ok)
|
|
183
|
+
throw new types_1.ApiError(`Error reading file "${fileName}" from Gitlab: ${json?.message ?? json?.error ?? response.statusText}`, response.status);
|
|
184
|
+
// From base64 string to buffer
|
|
185
|
+
const buf = Buffer.from(json.content, 'base64');
|
|
186
|
+
// Return the image bytes
|
|
187
|
+
return buf;
|
|
188
|
+
}
|
|
189
|
+
/*
|
|
190
|
+
* Get the meta repo path for the current user
|
|
191
|
+
* The meta repo contains a JSON file which contains the list of websites
|
|
192
|
+
*/
|
|
193
|
+
//private getMetaRepoPath(session: GitlabSession): string {
|
|
194
|
+
// if(!this.getSessionToken(session).username) throw new ApiError('Missing Gitlab user ID. User not logged in?', 401)
|
|
195
|
+
// return encodeURIComponent(`${this.getSessionToken(session).username}/${this.options.metaRepo}`)
|
|
196
|
+
//}
|
|
197
|
+
///**
|
|
198
|
+
// * Initialize the storage with a meta repo
|
|
199
|
+
// */
|
|
200
|
+
//private async initStorage(session: GitlabSession): Promise<void> {
|
|
201
|
+
// // Create the meta repo
|
|
202
|
+
// try {
|
|
203
|
+
// const project = await this.callApi(session, 'api/v4/projects/', 'POST', {
|
|
204
|
+
// name: this.options.metaRepo,
|
|
205
|
+
// }) as any
|
|
206
|
+
// return this.createFile(session, this.getMetaRepoPath(session), this.options.metaRepoFile, JSON.stringify({
|
|
207
|
+
// websites: {}
|
|
208
|
+
// } as MetaRepoFileContent))
|
|
209
|
+
// } catch (e) {
|
|
210
|
+
// console.error('Could not init storage', e.statusCode, e.httpStatusCode, e)
|
|
211
|
+
// throw e
|
|
212
|
+
// }
|
|
213
|
+
//}
|
|
214
|
+
/**
|
|
215
|
+
* Call the Gitlab API with the user's token and handle errors
|
|
216
|
+
*/
|
|
217
|
+
async callApi(session, path, method = 'GET', body = null, params = {}) {
|
|
218
|
+
const token = this.getSessionToken(session).token;
|
|
219
|
+
const tokenParam = token ? `access_token=${token.access_token}&` : '';
|
|
220
|
+
const paramsStr = Object.entries(params).map(([k, v]) => `${k}=${encodeURIComponent(v.toString())}`).join('&');
|
|
221
|
+
const url = `${this.options.domain}/${path}?${tokenParam}${paramsStr}`;
|
|
222
|
+
const headers = {
|
|
223
|
+
'Content-Type': 'application/json',
|
|
224
|
+
};
|
|
225
|
+
if (method === 'GET' && body) {
|
|
226
|
+
console.error('Gitlab API error (4) - GET request with body', { url, method, body, params });
|
|
227
|
+
}
|
|
228
|
+
// With or without body
|
|
229
|
+
let response;
|
|
117
230
|
try {
|
|
118
|
-
|
|
231
|
+
response = await (0, node_fetch_1.default)(url, body && method !== 'GET' ? {
|
|
232
|
+
method,
|
|
233
|
+
headers,
|
|
234
|
+
body: body ? JSON.stringify(body) : undefined
|
|
235
|
+
} : {
|
|
236
|
+
method,
|
|
237
|
+
headers,
|
|
238
|
+
});
|
|
119
239
|
}
|
|
120
240
|
catch (e) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
throw e;
|
|
124
|
-
}
|
|
125
|
-
else {
|
|
126
|
-
// Useless error linked to the fact that the response is not JSON
|
|
127
|
-
//console.error('Gitlab API error - could not parse response', response.status, response.statusText, {url, method, body, params, text})
|
|
128
|
-
return text;
|
|
129
|
-
}
|
|
241
|
+
console.error('Gitlab API error (0)', e);
|
|
242
|
+
throw new types_1.ApiError(`Gitlab API error (0): ${e.message} ${e.code} ${e.name} ${e.type}`, 500);
|
|
130
243
|
}
|
|
244
|
+
let json;
|
|
245
|
+
// Handle the case when the server returns a non-JSON response (e.g. 400 Bad Request)
|
|
246
|
+
const text = await response.text();
|
|
131
247
|
if (!response.ok) {
|
|
132
|
-
if (
|
|
248
|
+
if (text.includes('A file with this name doesn\'t exist')) {
|
|
249
|
+
throw new types_1.ApiError('Gitlab API error (5): Not Found', 404);
|
|
250
|
+
}
|
|
251
|
+
else if (response.status === 401 && this.getSessionToken(session).token?.refresh_token) {
|
|
133
252
|
// Refresh the token
|
|
134
|
-
const token = session
|
|
253
|
+
const token = this.getSessionToken(session).token;
|
|
135
254
|
const body = {
|
|
136
255
|
grant_type: 'refresh_token',
|
|
137
|
-
refresh_token: token
|
|
256
|
+
refresh_token: token?.refresh_token,
|
|
138
257
|
client_id: this.options.clientId,
|
|
139
258
|
client_secret: this.options.clientSecret,
|
|
140
259
|
};
|
|
141
|
-
const response = await (0, node_fetch_1.default)('
|
|
260
|
+
const response = await (0, node_fetch_1.default)(this.options.domain + '/oauth/token', {
|
|
142
261
|
method: 'POST',
|
|
143
262
|
headers: {
|
|
144
263
|
'Content-Type': 'application/json',
|
|
@@ -147,20 +266,42 @@ class GitlabConnector {
|
|
|
147
266
|
});
|
|
148
267
|
const refreshJson = await response.json();
|
|
149
268
|
if (response.ok) {
|
|
150
|
-
session
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
269
|
+
this.setSessionToken(session, {
|
|
270
|
+
token: {
|
|
271
|
+
...token,
|
|
272
|
+
...refreshJson,
|
|
273
|
+
},
|
|
274
|
+
});
|
|
154
275
|
return await this.callApi(session, path, method, body, params);
|
|
155
276
|
}
|
|
156
277
|
else {
|
|
157
|
-
|
|
158
|
-
|
|
278
|
+
const message = typeof refreshJson?.message === 'object' ? Object.entries(refreshJson.message).map(entry => entry.join(' ')).join(' ') : refreshJson?.message ?? refreshJson?.error ?? response.statusText;
|
|
279
|
+
console.error('Gitlab API error (2) - could not refresh token', response.status, response.statusText, { message }, 'refresh_token:', token?.refresh_token);
|
|
280
|
+
// Workaround for when the token is invalid
|
|
281
|
+
// It happens often which is not normal (refresh token should last 6 months)
|
|
282
|
+
this.logout(session);
|
|
283
|
+
// Notify the user
|
|
284
|
+
throw new types_1.ApiError(`Gitlab API error (2): ${message}`, response.status);
|
|
159
285
|
}
|
|
160
286
|
}
|
|
161
287
|
else {
|
|
162
|
-
|
|
163
|
-
|
|
288
|
+
const message = typeof json?.message === 'object' ? Object.entries(json.message).map(entry => entry.join(' ')).join(' ') : json?.message ?? json?.error ?? response.statusText;
|
|
289
|
+
console.error('Gitlab API error (1)', response.status, response.statusText, { url, method, body, params, text, message });
|
|
290
|
+
throw new types_1.ApiError(`Gitlab API error (1): ${message}`, response.status);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
try {
|
|
294
|
+
json = JSON.parse(text);
|
|
295
|
+
}
|
|
296
|
+
catch (e) {
|
|
297
|
+
if (!response.ok) {
|
|
298
|
+
// A real error
|
|
299
|
+
throw e;
|
|
300
|
+
}
|
|
301
|
+
else {
|
|
302
|
+
// Useless error linked to the fact that the response is not JSON
|
|
303
|
+
console.error('Gitlab API error (3) - could not parse response', response.status, response.statusText, { url, method, body, params, text });
|
|
304
|
+
return text;
|
|
164
305
|
}
|
|
165
306
|
}
|
|
166
307
|
return json;
|
|
@@ -196,14 +337,22 @@ class GitlabConnector {
|
|
|
196
337
|
// Create the code challenge
|
|
197
338
|
const codeChallenge = await this.generateCodeChallenge(codeVerifier);
|
|
198
339
|
// Store the code verifier and code challenge in the session
|
|
199
|
-
session
|
|
200
|
-
...session
|
|
340
|
+
this.setSessionToken(session, {
|
|
341
|
+
...this.getSessionToken(session),
|
|
201
342
|
state,
|
|
202
343
|
codeVerifier,
|
|
203
344
|
codeChallenge,
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
|
|
345
|
+
});
|
|
346
|
+
return `${this.options.domain}/oauth/authorize?client_id=${this.options.clientId}&redirect_uri=${redirect_uri}&response_type=code&state=${this.getSessionToken(session).state}&scope=${this.options.scope}&code_challenge=${codeChallenge}&code_challenge_method=S256`;
|
|
347
|
+
}
|
|
348
|
+
getSessionToken(session) {
|
|
349
|
+
return (session ?? {})[this.connectorId] ?? {};
|
|
350
|
+
}
|
|
351
|
+
setSessionToken(session, token) {
|
|
352
|
+
session[this.connectorId] = token;
|
|
353
|
+
}
|
|
354
|
+
resetSessionToken(session) {
|
|
355
|
+
delete session[this.connectorId];
|
|
207
356
|
}
|
|
208
357
|
getOptions(formData) {
|
|
209
358
|
return {}; // FIXME: store branch
|
|
@@ -215,7 +364,7 @@ class GitlabConnector {
|
|
|
215
364
|
return null;
|
|
216
365
|
}
|
|
217
366
|
async isLoggedIn(session) {
|
|
218
|
-
return !!session
|
|
367
|
+
return !!this.getSessionToken(session).token;
|
|
219
368
|
}
|
|
220
369
|
/**
|
|
221
370
|
* Get the token from return code
|
|
@@ -223,13 +372,20 @@ class GitlabConnector {
|
|
|
223
372
|
* OAuth2 Step #2 from https://docs.gitlab.com/ee/api/oauth2.html#authorization-code-with-proof-key-for-code-exchange-pkce
|
|
224
373
|
*/
|
|
225
374
|
async setToken(session, loginResult) {
|
|
226
|
-
|
|
375
|
+
const sessionToken = this.getSessionToken(session);
|
|
376
|
+
if (!loginResult.state || loginResult.state !== sessionToken?.state) {
|
|
377
|
+
this.logout(session);
|
|
227
378
|
throw new types_1.ApiError('Invalid state', 401);
|
|
228
|
-
|
|
379
|
+
}
|
|
380
|
+
if (!sessionToken?.codeVerifier) {
|
|
381
|
+
this.logout(session);
|
|
229
382
|
throw new types_1.ApiError('Missing code verifier', 401);
|
|
230
|
-
|
|
383
|
+
}
|
|
384
|
+
if (!sessionToken?.codeChallenge) {
|
|
385
|
+
this.logout(session);
|
|
231
386
|
throw new types_1.ApiError('Missing code challenge', 401);
|
|
232
|
-
|
|
387
|
+
}
|
|
388
|
+
const response = await (0, node_fetch_1.default)(this.options.domain + '/oauth/token', {
|
|
233
389
|
method: 'POST',
|
|
234
390
|
headers: {
|
|
235
391
|
'Content-Type': 'application/json',
|
|
@@ -240,31 +396,70 @@ class GitlabConnector {
|
|
|
240
396
|
code: loginResult.code,
|
|
241
397
|
grant_type: 'authorization_code',
|
|
242
398
|
redirect_uri: this.getRedirect(),
|
|
243
|
-
code_verifier:
|
|
399
|
+
code_verifier: sessionToken.codeVerifier,
|
|
244
400
|
}),
|
|
245
|
-
})
|
|
246
|
-
|
|
247
|
-
|
|
401
|
+
});
|
|
402
|
+
const token = await response.json();
|
|
403
|
+
// Store the token in the session
|
|
404
|
+
this.setSessionToken(session, {
|
|
405
|
+
token,
|
|
406
|
+
...this.getSessionToken(session),
|
|
407
|
+
});
|
|
248
408
|
// We need to get the user ID for listWebsites
|
|
249
409
|
const user = await this.callApi(session, 'api/v4/user');
|
|
250
|
-
|
|
410
|
+
// Store the user details in the session
|
|
411
|
+
this.setSessionToken(session, {
|
|
412
|
+
...this.getSessionToken(session),
|
|
413
|
+
userId: user.id,
|
|
414
|
+
username: user.username,
|
|
415
|
+
});
|
|
251
416
|
}
|
|
252
417
|
async logout(session) {
|
|
253
|
-
|
|
418
|
+
this.resetSessionToken(session);
|
|
254
419
|
}
|
|
255
420
|
async getUser(session) {
|
|
256
421
|
const user = await this.callApi(session, 'api/v4/user');
|
|
257
422
|
return {
|
|
258
423
|
name: user.name,
|
|
259
424
|
email: user.email,
|
|
425
|
+
picture: user.avatar_url,
|
|
260
426
|
storage: await (0, connectors_1.toConnectorData)(session, this),
|
|
261
427
|
};
|
|
262
428
|
}
|
|
263
429
|
async listWebsites(session) {
|
|
264
|
-
|
|
265
|
-
|
|
430
|
+
//try {
|
|
431
|
+
// const result = await this.callApi(session, `api/v4/projects/${this.getMetaRepoPath(session)}/repository/files/${this.options.metaRepoFile}`, 'GET', null, {
|
|
432
|
+
// ref: this.options.branch,
|
|
433
|
+
// })
|
|
434
|
+
// const { content } = result
|
|
435
|
+
// const contentDecoded = Buffer.from(content, 'base64').toString('utf8')
|
|
436
|
+
// const websites = (JSON.parse(contentDecoded) as MetaRepoFileContent).websites
|
|
437
|
+
// return Object.entries(websites).map(([websiteId, {meta, createdAt, updatedAt}]) => ({
|
|
438
|
+
// websiteId,
|
|
439
|
+
// createdAt: new Date(createdAt),
|
|
440
|
+
// updatedAt: new Date(updatedAt),
|
|
441
|
+
// ...meta,
|
|
442
|
+
// }))
|
|
443
|
+
//} catch (e) {
|
|
444
|
+
// console.error('Could not list websites', e.statusCode, e.httpStatusCode, e.code)
|
|
445
|
+
// if (e.statusCode === 404 || e.httpStatusCode === 404) {
|
|
446
|
+
// await this.initStorage(session)
|
|
447
|
+
// return []
|
|
448
|
+
// } else {
|
|
449
|
+
// throw e
|
|
450
|
+
// }
|
|
451
|
+
//}
|
|
452
|
+
const userId = this.getSessionToken(session).userId;
|
|
453
|
+
if (!userId) {
|
|
454
|
+
this.logout(session);
|
|
455
|
+
throw new types_1.ApiError('Missing Gitlab user ID. User not logged in?', 401);
|
|
456
|
+
}
|
|
457
|
+
const projects = await this.callApi(session, `api/v4/users/${userId}/projects`);
|
|
458
|
+
return projects
|
|
459
|
+
.filter(p => p.name.startsWith(this.options.repoPrefix))
|
|
460
|
+
.map(p => ({
|
|
266
461
|
websiteId: p.id,
|
|
267
|
-
name: p.name,
|
|
462
|
+
name: p.name.replace(this.options.repoPrefix, ''),
|
|
268
463
|
createdAt: p.created_at,
|
|
269
464
|
updatedAt: p.last_activity_at,
|
|
270
465
|
connectorUserSettings: {},
|
|
@@ -281,10 +476,10 @@ class GitlabConnector {
|
|
|
281
476
|
}
|
|
282
477
|
async createWebsite(session, websiteMeta) {
|
|
283
478
|
const project = await this.callApi(session, 'api/v4/projects/', 'POST', {
|
|
284
|
-
name: websiteMeta.name,
|
|
479
|
+
name: this.options.repoPrefix + websiteMeta.name,
|
|
285
480
|
});
|
|
286
481
|
await this.createFile(session, project.id, constants_1.WEBSITE_DATA_FILE, JSON.stringify({}));
|
|
287
|
-
await this.createFile(session, project.id,
|
|
482
|
+
//await this.createFile(session, project.id, WEBSITE_META_DATA_FILE, JSON.stringify(websiteMeta))
|
|
288
483
|
//await this.updateWebsite(session, project.id, {} as WebsiteData)
|
|
289
484
|
//await this.setWebsiteMeta(session, project.id, websiteMeta)
|
|
290
485
|
return project.id;
|
|
@@ -294,68 +489,149 @@ class GitlabConnector {
|
|
|
294
489
|
branch: this.options.branch,
|
|
295
490
|
commit_message: 'Update website data from Silex',
|
|
296
491
|
content: JSON.stringify(websiteData),
|
|
297
|
-
file_path: constants_1.WEBSITE_DATA_FILE,
|
|
298
492
|
id: websiteId,
|
|
299
493
|
});
|
|
300
494
|
}
|
|
301
495
|
async deleteWebsite(session, websiteId) {
|
|
496
|
+
// Delete repo
|
|
302
497
|
await this.callApi(session, `api/v4/projects/${websiteId}`, 'DELETE');
|
|
498
|
+
//// Load the meta repo data
|
|
499
|
+
//const file = await this.callApi(session, `api/v4/projects/${this.getMetaRepoPath(session)}/repository/files/${this.options.metaRepoFile}`, 'GET', null, {
|
|
500
|
+
// ref: this.options.branch,
|
|
501
|
+
//})
|
|
502
|
+
//const metaRepo = JSON.parse(Buffer.from(file.content, 'base64').toString('utf8')) as MetaRepoFileContent
|
|
503
|
+
//const data = metaRepo.websites[websiteId]
|
|
504
|
+
//if(!data) throw new ApiError(`Website ${websiteId} not found`, 404)
|
|
505
|
+
//// Update or create the website meta data
|
|
506
|
+
//delete metaRepo.websites[websiteId]
|
|
507
|
+
//// Save the meta repo data
|
|
508
|
+
//const project = await this.callApi(session, `api/v4/projects/${this.getMetaRepoPath(session)}/repository/files/${this.options.metaRepoFile}`, 'PUT', {
|
|
509
|
+
// branch: this.options.branch,
|
|
510
|
+
// commit_message: `Delete meta data of ${data.meta.name} (${websiteId}) from Silex`,
|
|
511
|
+
// content: JSON.stringify(metaRepo),
|
|
512
|
+
// file_path: this.options.metaRepoFile,
|
|
513
|
+
//})
|
|
514
|
+
}
|
|
515
|
+
async duplicateWebsite(session, websiteId) {
|
|
516
|
+
// Get the repo meta data
|
|
517
|
+
const meta = await this.getWebsiteMeta(session, websiteId);
|
|
518
|
+
// List all the repository files
|
|
519
|
+
const blobs = await this.callApi(session, `api/v4/projects/${websiteId}/repository/tree`, 'GET', null, {
|
|
520
|
+
recursive: true,
|
|
521
|
+
});
|
|
522
|
+
const files = blobs
|
|
523
|
+
.filter(item => item.type === 'blob')
|
|
524
|
+
.map(item => item.path);
|
|
525
|
+
// Create a new repo
|
|
526
|
+
const newId = await this.createWebsite(session, {
|
|
527
|
+
...meta,
|
|
528
|
+
name: meta.name + ' Copy ' + new Date().toISOString().replace(/T.*/, '') + ' ' + Math.random().toString(36).substring(2, 4),
|
|
529
|
+
});
|
|
530
|
+
// Upload all files
|
|
531
|
+
for (const file of files) {
|
|
532
|
+
const path = encodeURIComponent(file);
|
|
533
|
+
const content = await this.readFile(session, websiteId, path);
|
|
534
|
+
// From buffer to string
|
|
535
|
+
const contentStr = content.toString('base64');
|
|
536
|
+
switch (file) {
|
|
537
|
+
case constants_1.WEBSITE_DATA_FILE:
|
|
538
|
+
await this.updateFile(session, newId, path, contentStr, true);
|
|
539
|
+
break;
|
|
540
|
+
default:
|
|
541
|
+
await this.createFile(session, newId, path, contentStr, true);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
303
544
|
}
|
|
304
545
|
async getWebsiteMeta(session, websiteId) {
|
|
305
|
-
const
|
|
546
|
+
//const file = await this.callApi(session, `api/v4/projects/${this.getMetaRepoPath(session)}/repository/files/${this.options.metaRepoFile}`, 'GET', null, {
|
|
547
|
+
// ref: this.options.branch,
|
|
548
|
+
//})
|
|
549
|
+
//const metaRepo = JSON.parse(Buffer.from(file.content, 'base64').toString('utf8')) as MetaRepoFileContent
|
|
550
|
+
//if(!metaRepo.websites[websiteId]) throw new ApiError(`Website ${websiteId} not found`, 404)
|
|
551
|
+
//return {
|
|
552
|
+
// websiteId,
|
|
553
|
+
// createdAt: new Date(metaRepo.websites[websiteId].createdAt),
|
|
554
|
+
// updatedAt: new Date(metaRepo.websites[websiteId].updatedAt),
|
|
555
|
+
// ...metaRepo.websites[websiteId].meta,
|
|
556
|
+
//}
|
|
557
|
+
// const response = await this.callApi(session, `api/v4/projects/${websiteId}/repository/files/${WEBSITE_META_DATA_FILE}`, 'GET', null, {
|
|
558
|
+
// ref: this.options.branch,
|
|
559
|
+
// }) as any
|
|
560
|
+
// Base64 to string to JSON
|
|
561
|
+
// const contentDecoded = Buffer.from(response.content, 'base64').toString('utf8')
|
|
562
|
+
// const websiteMeta = JSON.parse(contentDecoded) as WebsiteMetaFileContent
|
|
563
|
+
const project = await this.callApi(session, `api/v4/projects/${websiteId}`);
|
|
306
564
|
return {
|
|
307
|
-
websiteId
|
|
308
|
-
name: project.name,
|
|
565
|
+
websiteId,
|
|
566
|
+
name: project.name.replace(this.options.repoPrefix, ''),
|
|
567
|
+
imageUrl: project.avatar_url,
|
|
309
568
|
createdAt: project.created_at,
|
|
310
569
|
updatedAt: project.last_activity_at,
|
|
311
570
|
connectorUserSettings: {},
|
|
312
571
|
};
|
|
313
572
|
}
|
|
314
573
|
async setWebsiteMeta(session, websiteId, websiteMeta) {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
574
|
+
//// Load the meta repo data
|
|
575
|
+
//const file = await this.callApi(session, `api/v4/projects/${this.getMetaRepoPath(session)}/repository/files/${this.options.metaRepoFile}`, 'GET', null, {
|
|
576
|
+
// ref: this.options.branch,
|
|
577
|
+
//})
|
|
578
|
+
//const metaRepo = JSON.parse(Buffer.from(file.content, 'base64').toString('utf8')) as MetaRepoFileContent
|
|
579
|
+
//// Update or create the website meta data
|
|
580
|
+
//metaRepo.websites[websiteId] = {
|
|
581
|
+
// updatedAt: new Date().toISOString(),
|
|
582
|
+
// createdAt: metaRepo.websites[websiteId]?.createdAt ?? new Date().toISOString(),
|
|
583
|
+
// meta: websiteMeta,
|
|
584
|
+
//}
|
|
585
|
+
//// Save the meta repo data
|
|
586
|
+
//const project = await this.callApi(session, `api/v4/projects/${this.getMetaRepoPath(session)}/repository/files/${this.options.metaRepoFile}`, 'PUT', {
|
|
587
|
+
// branch: this.options.branch,
|
|
588
|
+
// commit_message: `Update website meta data of ${websiteMeta.name} (${websiteId}) from Silex`,
|
|
589
|
+
// content: JSON.stringify(metaRepo),
|
|
590
|
+
// file_path: this.options.metaRepoFile,
|
|
591
|
+
//})
|
|
592
|
+
// Rename the repo if needed
|
|
593
|
+
const oldMeta = await this.getWebsiteMeta(session, websiteId);
|
|
594
|
+
if (websiteMeta.name !== oldMeta.name) {
|
|
595
|
+
await this.callApi(session, `api/v4/projects/${websiteId}`, 'PUT', {
|
|
596
|
+
name: this.options.repoPrefix + websiteMeta.name,
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
//// Update the metadata file
|
|
600
|
+
//await this.callApi(session, `api/v4/projects/${websiteId}/repository/files/${WEBSITE_META_DATA_FILE}`, 'PUT', {
|
|
601
|
+
// branch: this.options.branch,
|
|
602
|
+
// commit_message: 'Update website meta data from Silex',
|
|
603
|
+
// content: JSON.stringify(websiteMeta),
|
|
604
|
+
// file_path: WEBSITE_META_DATA_FILE,
|
|
605
|
+
// id: websiteId,
|
|
606
|
+
//})
|
|
322
607
|
}
|
|
323
608
|
async writeAssets(session, websiteId, files, status) {
|
|
609
|
+
status && await status({ message: 'in progress...', status: types_1.JobStatus.IN_PROGRESS });
|
|
324
610
|
// For each file
|
|
325
611
|
for (const file of files) {
|
|
326
612
|
// Convert to base64
|
|
327
613
|
const content = (await (0, connectors_1.contentToBuffer)(file.content)).toString('base64');
|
|
614
|
+
const path = this.getAssetPath(file.path);
|
|
328
615
|
try {
|
|
329
|
-
await this.updateFile(session, websiteId,
|
|
616
|
+
await this.updateFile(session, websiteId, path, content, true);
|
|
330
617
|
}
|
|
331
618
|
catch (e) {
|
|
332
619
|
// If the file does not exist, create it
|
|
333
|
-
if (e.statusCode === 404 || e.message.endsWith('A file with this name doesn\'t exist')) {
|
|
334
|
-
await this.createFile(session, websiteId,
|
|
620
|
+
if (e.statusCode === 404 || e.httpStatusCode === 404 || e.message.endsWith('A file with this name doesn\'t exist')) {
|
|
621
|
+
await this.createFile(session, websiteId, path, content, true);
|
|
335
622
|
}
|
|
336
623
|
else {
|
|
624
|
+
status && await status({ message: 'Error', status: types_1.JobStatus.ERROR });
|
|
337
625
|
throw e;
|
|
338
626
|
}
|
|
339
627
|
}
|
|
340
628
|
}
|
|
629
|
+
status && await status({ message: 'Successfull', status: types_1.JobStatus.SUCCESS });
|
|
341
630
|
}
|
|
342
631
|
async readAsset(session, websiteId, fileName) {
|
|
343
632
|
// Remove leading slash
|
|
344
633
|
const finalPath = this.getAssetPath(fileName);
|
|
345
|
-
|
|
346
|
-
const url = `https://gitlab.com/api/v4/projects/${websiteId}/repository/files/${finalPath}?ref=${this.options.branch}&access_token=${session.gitlab?.token?.access_token}`;
|
|
347
|
-
const response = await (0, node_fetch_1.default)(url, {
|
|
348
|
-
method: 'GET',
|
|
349
|
-
headers: {
|
|
350
|
-
'Content-Type': 'application/json',
|
|
351
|
-
},
|
|
352
|
-
});
|
|
353
|
-
const json = await response.json();
|
|
354
|
-
if (!response.ok)
|
|
355
|
-
throw new types_1.ApiError(`Gitlab API error: ${json?.message ?? json?.error ?? response.statusText}`, response.status);
|
|
356
|
-
// From base64 string to buffer
|
|
357
|
-
const buf = Buffer.from(json.content, 'base64');
|
|
358
|
-
return buf;
|
|
634
|
+
return this.readFile(session, websiteId, finalPath);
|
|
359
635
|
}
|
|
360
636
|
async deleteAssets(session, websiteId, fileNames) {
|
|
361
637
|
return this.callApi(session, `api/v4/projects/${websiteId}/repository/commits`, 'POST', {
|