@silexlabs/silex 3.0.1-alpha.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 +20 -0
- package/.silex.js +67 -8
- package/LICENSE +661 -203
- package/README.md +37 -35
- package/dist/client/client/api.d.ts +90 -0
- package/dist/client/client/assetUrl.d.ts +54 -0
- package/dist/client/client/config.d.ts +102 -0
- package/dist/client/client/events.d.ts +23 -0
- package/dist/client/client/expose.d.ts +8 -0
- package/dist/client/client/grapesjs/LoginDialog.d.ts +15 -0
- package/dist/client/client/grapesjs/PublicationManager.d.ts +73 -0
- package/dist/client/client/grapesjs/PublicationUi.d.ts +59 -0
- package/dist/client/client/grapesjs/blocks.d.ts +1 -0
- 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 +9 -0
- package/dist/client/client/grapesjs/internal-links.d.ts +1 -0
- package/dist/client/client/grapesjs/keymaps.d.ts +123 -0
- package/dist/client/client/grapesjs/new-page-dialog.d.ts +2 -0
- package/dist/client/client/grapesjs/openImport.d.ts +9 -0
- package/dist/client/client/grapesjs/page-panel.d.ts +9 -0
- package/dist/client/client/grapesjs/project-bar.d.ts +21 -0
- package/dist/client/client/grapesjs/resize-panel.d.ts +1 -0
- package/dist/client/client/grapesjs/rich-text.d.ts +4 -0
- package/dist/client/client/grapesjs/semantic.d.ts +1 -0
- package/dist/client/client/grapesjs/settings-sections.d.ts +16 -0
- package/dist/client/client/grapesjs/settings.d.ts +4 -0
- package/dist/client/client/grapesjs/storage.d.ts +2 -0
- package/dist/client/client/grapesjs/symbolDialogs.d.ts +3 -0
- package/dist/client/client/grapesjs/view-buttons.d.ts +1 -0
- package/dist/client/client/index.d.ts +10 -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 -0
- package/dist/client/constants.d.ts +32 -0
- package/dist/client/css/admin.css +1114 -328
- 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 +356 -131
- package/dist/client/js/main.js.LICENSE.txt +15 -1
- package/dist/client/page.d.ts +2 -0
- 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 +339 -0
- package/dist/plugins/client/client/events.d.ts +23 -0
- package/dist/plugins/client/client/events.js +43 -0
- package/dist/plugins/client/client/events.js.map +1 -0
- package/dist/plugins/client/plugins/client/template.d.ts +2 -0
- package/dist/plugins/client/plugins/client/template.js +234 -0
- package/dist/plugins/client/plugins/client/template.js.map +1 -0
- 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 +339 -0
- package/dist/plugins/client/types.js +80 -0
- package/dist/plugins/client/types.js.map +1 -0
- package/dist/plugins/server/constants.d.ts +32 -0
- package/dist/plugins/server/constants.js +76 -0
- package/dist/plugins/server/constants.js.map +1 -0
- package/dist/plugins/server/plugins/server/Cache.d.ts +2 -0
- package/dist/plugins/server/plugins/server/Cache.js +36 -0
- package/dist/plugins/server/plugins/server/Cache.js.map +1 -0
- 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 +86 -0
- package/dist/plugins/server/plugins/server/FtpConnector.js +536 -0
- package/dist/plugins/server/plugins/server/FtpConnector.js.map +1 -0
- package/dist/plugins/server/plugins/server/GitlabConnector.d.ts +135 -0
- package/dist/plugins/server/plugins/server/GitlabConnector.js +649 -0
- package/dist/plugins/server/plugins/server/GitlabConnector.js.map +1 -0
- 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/PublicationOptimizer.d.ts +0 -0
- package/dist/plugins/server/plugins/server/PublicationOptimizer.js +14 -0
- package/dist/plugins/server/plugins/server/PublicationOptimizer.js.map +1 -0
- package/dist/plugins/server/plugins/server/SslPlugin.d.ts +1 -0
- package/dist/plugins/server/plugins/server/SslPlugin.js +86 -0
- package/dist/plugins/server/plugins/server/SslPlugin.js.map +1 -0
- package/dist/plugins/server/plugins/server/StaticPlugin.d.ts +8 -0
- package/dist/plugins/server/plugins/server/StaticPlugin.js +45 -0
- package/dist/plugins/server/plugins/server/StaticPlugin.js.map +1 -0
- package/dist/plugins/server/server/config.d.ts +59 -0
- package/dist/plugins/server/server/config.js +181 -0
- package/dist/plugins/server/server/config.js.map +1 -0
- package/dist/plugins/server/server/connectors/FsHosting.d.ts +14 -0
- package/dist/plugins/server/server/connectors/FsHosting.js +66 -0
- package/dist/plugins/server/server/connectors/FsHosting.js.map +1 -0
- package/dist/plugins/server/server/connectors/FsStorage.d.ts +44 -0
- package/dist/plugins/server/server/connectors/FsStorage.js +261 -0
- package/dist/plugins/server/server/connectors/FsStorage.js.map +1 -0
- package/dist/plugins/server/server/connectors/connectors.d.ts +86 -0
- package/dist/plugins/server/server/connectors/connectors.js +126 -0
- package/dist/plugins/server/server/connectors/connectors.js.map +1 -0
- package/dist/plugins/server/server/events.d.ts +26 -0
- package/dist/plugins/server/server/events.js +31 -0
- package/dist/plugins/server/server/events.js.map +1 -0
- package/dist/plugins/server/server/jobs.d.ts +12 -0
- package/dist/plugins/server/server/jobs.js +79 -0
- package/dist/plugins/server/server/jobs.js.map +1 -0
- package/dist/plugins/server/server/utils/validation.d.ts +7 -0
- package/dist/plugins/server/server/utils/validation.js +37 -0
- package/dist/plugins/server/server/utils/validation.js.map +1 -0
- package/dist/plugins/server/types.d.ts +339 -0
- package/dist/plugins/server/types.js +84 -0
- package/dist/plugins/server/types.js.map +1 -0
- package/dist/server/constants.js +55 -0
- package/dist/server/plugins/server/Cache.js +19 -0
- package/dist/server/server/api/api.js +20 -0
- package/dist/server/server/api/connectorApi.js +334 -0
- package/dist/server/server/api/publicationApi.js +106 -0
- package/dist/server/server/api/websiteApi.js +315 -0
- package/dist/server/server/cli.js +71 -0
- package/dist/server/server/config.js +120 -0
- package/dist/server/server/connectors/FsHosting.js +47 -0
- package/dist/server/server/connectors/FsStorage.js +228 -0
- package/dist/server/server/connectors/connectors.js +88 -0
- package/dist/server/server/events.js +14 -0
- package/dist/server/server/expose.js +27 -0
- package/dist/server/server/express.js +46 -0
- package/dist/server/server/index.js +94 -0
- package/dist/server/server/jobs.js +50 -0
- package/dist/server/server/utils/validation.js +14 -0
- package/dist/server/types.js +40 -0
- package/package.json +99 -49
- 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 +22 -23
- package/src/css/_variables.scss +24 -20
- package/src/css/dialog.scss +35 -2
- 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 +159 -1
- package/src/css/index.scss +12 -1
- package/src/css/light.scss +7 -0
- package/src/css/loader.scss +2 -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/html/templates/includes.pug +0 -1
- package/src/ts/client/api.ts +156 -0
- package/src/ts/client/assetUrl.test.ts +164 -0
- package/src/ts/client/assetUrl.ts +254 -0
- package/src/ts/client/config.ts +175 -13
- package/src/ts/client/events.ts +43 -0
- package/src/ts/client/expose.ts +27 -1
- package/src/ts/client/grapesjs/LoginDialog.ts +204 -0
- package/src/ts/client/grapesjs/PublicationManager.ts +433 -0
- package/src/ts/client/grapesjs/PublicationUi.ts +366 -0
- package/src/ts/client/grapesjs/blocks.ts +17 -0
- 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 +30 -7
- package/src/ts/client/grapesjs/footer.ts +42 -0
- package/src/ts/client/grapesjs/img.ts +147 -0
- package/src/ts/client/grapesjs/index.ts +311 -122
- package/src/ts/client/grapesjs/internal-links.test.ts +19 -1
- package/src/ts/client/grapesjs/internal-links.ts +31 -7
- package/src/ts/client/grapesjs/keymaps.ts +207 -0
- package/src/ts/client/grapesjs/new-page-dialog.ts +19 -3
- package/src/ts/client/grapesjs/openImport.ts +22 -0
- package/src/ts/client/grapesjs/page-panel.ts +109 -7
- package/src/ts/client/grapesjs/project-bar.ts +133 -72
- package/src/ts/client/grapesjs/resize-panel.ts +20 -0
- package/src/ts/client/grapesjs/rich-text.ts +38 -13
- package/src/ts/client/grapesjs/semantic.ts +20 -3
- package/src/ts/client/grapesjs/settings-sections.ts +117 -0
- package/src/ts/client/grapesjs/settings.ts +191 -96
- package/src/ts/client/grapesjs/storage.ts +187 -0
- package/src/ts/client/grapesjs/symbolDialogs.ts +21 -5
- package/src/ts/client/grapesjs/view-buttons.ts +42 -0
- package/src/ts/client/index.ts +80 -21
- package/src/ts/client/publication-transformers.test.ts +207 -0
- package/src/ts/client/publication-transformers.ts +280 -0
- package/src/ts/client/publish-custom-code-block.ts +31 -0
- package/src/ts/client/publish-fonts.ts +36 -0
- package/src/ts/client/utils.ts +70 -1
- package/src/ts/constants.ts +78 -0
- package/src/ts/externs.ts +17 -0
- package/src/ts/page.ts +20 -3
- package/src/ts/plugins/client/template.ts +246 -0
- package/src/ts/plugins/client/website-info.ts +84 -0
- package/src/ts/plugins/server/Cache.ts +32 -0
- package/src/ts/plugins/server/DownloadConnector.ts +146 -0
- package/src/ts/plugins/server/FtpConnector.test.ts +82 -0
- package/src/ts/plugins/server/FtpConnector.ts +621 -0
- package/src/ts/plugins/server/GitlabConnector.ts +749 -0
- package/src/ts/plugins/server/GitlabHostingConnector.ts +215 -0
- package/src/ts/plugins/server/PublicationOptimizer.ts +14 -0
- package/src/ts/plugins/server/SslPlugin.ts +84 -0
- package/src/ts/plugins/server/StaticPlugin.ts +45 -0
- package/src/ts/server/api/api.ts +19 -0
- package/src/ts/server/api/connectorApi.ts +464 -0
- package/src/ts/server/api/publicationApi.ts +159 -0
- package/src/ts/server/api/websiteApi.ts +462 -0
- package/src/ts/server/cli.ts +48 -14
- package/src/ts/server/config.ts +158 -60
- package/src/ts/server/connectors/FsHosting.ts +66 -0
- package/src/ts/server/connectors/FsStorage.test.ts +51 -0
- package/src/ts/server/connectors/FsStorage.ts +290 -0
- package/src/ts/server/connectors/connectors.ts +203 -0
- package/src/ts/server/events.ts +37 -0
- package/src/ts/server/expose.ts +19 -0
- package/src/ts/server/express.ts +57 -5
- package/src/ts/server/index.ts +79 -16
- package/src/ts/server/jobs.test.ts +75 -0
- package/src/ts/server/jobs.ts +89 -0
- package/src/ts/server/utils/BackwardCompat.ts +546 -528
- package/src/ts/server/utils/validation.ts +34 -0
- package/src/ts/types.ts +295 -85
- package/.dockerignore +0 -5
- package/.editorconfig +0 -14
- package/.eslintrc.json +0 -43
- package/.github/FUNDING.yml +0 -13
- package/.github/workflows/docker-hub-publish.yml +0 -36
- package/.github/workflows/npm-publish.yml +0 -19
- package/.github/workflows/test.yml +0 -26
- package/.nvmrc +0 -1
- package/.silex/default/.silex.data.json +0 -1
- package/CODE_OF_CONDUCT.md +0 -128
- package/CONTRIBUTING.md +0 -131
- package/Dockerfile +0 -15
- package/directus.silex.js +0 -7
- package/dist/constants.js +0 -4
- package/dist/events.js +0 -5
- package/dist/page.js +0 -15
- package/dist/server/cli.js +0 -43
- package/dist/server/config.js +0 -70
- package/dist/server/express.js +0 -18
- package/dist/server/index.js +0 -58
- package/dist/types.js +0 -34
- package/jest.config.js +0 -10
- package/logos/logo_by_ceubri/silex-icon-2018@200px.png +0 -0
- package/logos/logo_by_ceubri/silex-icon-2018@4x.png +0 -0
- package/logos/logo_by_ceubri/silex-logo-2018-white-transp.pdf +0 -0
- package/logos/logo_by_ceubri/silex-logo-2018-white.jpg +0 -0
- package/logos/logo_by_ceubri/silex-logo-2018-white.pdf +0 -0
- package/logos/logo_by_ceubri/silex-logo-2018-white.png +0 -0
- package/logos/logo_by_ceubri/silex-logo-2018-white@0.5x.png +0 -0
- package/logos/logo_by_ceubri/silex-logo-2018-white@0.75x.png +0 -0
- package/logos/logo_by_ceubri/silex-logo-2018-white@4x.jpg +0 -0
- package/logos/logo_by_ceubri/silex-logo-2018-white@4x.png +0 -0
- package/logos/logo_by_ceubri/silex-logo-2018.ai +5 -2521
- package/logos/logo_by_ceubri/silex-logo-2018.jpg +0 -0
- package/logos/logo_by_ceubri/silex-logo-2018.pdf +0 -0
- package/logos/logo_by_ceubri/silex-logo-2018.png +0 -0
- package/logos/logo_by_ceubri/silex-logo-2018@0.5x.png +0 -0
- package/logos/logo_by_ceubri/silex-logo-2018@0.75x.png +0 -0
- package/logos/logo_by_ceubri/silex-logo-2018@4x.jpg +0 -0
- package/logos/logo_by_ceubri/silex-logo-2018@4x.png +0 -0
- package/logos/silexlabs.png +0 -0
- package/src/example-client-config.js +0 -47
- package/src/plugins/AuthPlugin.js +0 -21
- package/src/plugins/Cache.js +0 -11
- package/src/plugins/DefaultBackend.js +0 -149
- package/src/plugins/ExpressPlugin.js +0 -39
- package/src/plugins/HooksPlugin.js +0 -58
- package/src/plugins/PublishPlugin.js +0 -69
- package/src/plugins/SslPlugin.js +0 -66
- package/src/plugins/StaticPlugin.js +0 -48
- package/src/plugins/WebsitePlugin.js +0 -207
- package/src/ts/client/grapesjs/publish.ts +0 -386
- package/src/ts/client/grapesjs/template.ts +0 -166
- package/src/ts/events.ts +0 -2
- package/tsconfig-server-debug.json +0 -19
- package/tsconfig-server-release.json +0 -19
- package/tsconfig.jest.json +0 -9
- package/tsconfig.json +0 -26
- package/webpack.config.js +0 -28
- package/webpack.debug.config.js +0 -8
|
@@ -0,0 +1,433 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Silex website builder, free/libre no-code tool for makers.
|
|
3
|
+
* Copyright (c) 2023 lexoyo and Silex Labs foundation
|
|
4
|
+
*
|
|
5
|
+
* This program is free software: you can redistribute it and/or modify
|
|
6
|
+
* it under the terms of the GNU Affero General Public License as published by
|
|
7
|
+
* the Free Software Foundation, either version 3 of the License, or any later version.
|
|
8
|
+
*
|
|
9
|
+
* This program is distributed in the hope that it will be useful,
|
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
* GNU Affero General Public License for more details.
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of the GNU Affero General Public License
|
|
15
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import { getPageSlug } from '../../page'
|
|
19
|
+
import { ApiConnectorLoggedInPostMessage, ApiConnectorLoginQuery, ApiPublicationPublishBody, ClientSideFile, ClientSideFileType, ConnectorData, ConnectorType, ConnectorUser, JobStatus, Initiator, PublicationData, PublicationJobData, PublicationSettings, WebsiteData, WebsiteFile, WebsiteId, WebsiteSettings } from '../../types'
|
|
20
|
+
import { Editor } from 'grapesjs'
|
|
21
|
+
import { PublicationUi } from './PublicationUi'
|
|
22
|
+
import { getUser, logout, publicationStatus, publish } from '../api'
|
|
23
|
+
import { API_CONNECTOR_LOGIN, API_CONNECTOR_PATH, API_PATH } from '../../constants'
|
|
24
|
+
import { ClientEvent } from '../events'
|
|
25
|
+
import { resetRenderComponents, resetRenderCssRules, transformPermalink, transformFiles, transformPath, renderComponents, renderCssRules } from '../publication-transformers'
|
|
26
|
+
import { displayedToStored } from '../assetUrl'
|
|
27
|
+
import { hashString } from '../utils'
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @fileoverview Publication manager for Silex
|
|
31
|
+
* This plugin adds a publication feature to Silex
|
|
32
|
+
* It lets the user publish the website to a hosting service
|
|
33
|
+
* It can optionally display a button and a dialog
|
|
34
|
+
* Useful commands:
|
|
35
|
+
* - publish: starts the publication process and optionally open the dialog
|
|
36
|
+
* - publish-login: open the login dialog
|
|
37
|
+
* - publish-logout: logout from the hosting service and let the user choose a hosting service again
|
|
38
|
+
*/
|
|
39
|
+
|
|
40
|
+
// Constants
|
|
41
|
+
export const cmdPublicationStart = 'publish'
|
|
42
|
+
export const cmdPublicationLogin = 'publish-login'
|
|
43
|
+
export const cmdPublicationLogout = 'publish-logout'
|
|
44
|
+
|
|
45
|
+
// Types
|
|
46
|
+
export type PublishableEditor = Editor & {
|
|
47
|
+
PublicationManager: PublicationManager
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export enum PublicationStatus {
|
|
51
|
+
STATUS_NONE = 'STATUS_NONE',
|
|
52
|
+
STATUS_PENDING = 'STATUS_PENDING',
|
|
53
|
+
STATUS_ERROR = 'STATUS_ERROR',
|
|
54
|
+
STATUS_SUCCESS = 'STATUS_SUCCESS',
|
|
55
|
+
STATUS_LOGGED_OUT = 'STATUS_AUTH_ERROR',
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export type PublicationManagerOptions = {
|
|
59
|
+
appendTo?: string // If not provided, no button nor dialog will be created
|
|
60
|
+
websiteId: WebsiteId
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// plugin init cod
|
|
64
|
+
export default function publishPlugin(editor, opts) {
|
|
65
|
+
(editor as PublishableEditor).PublicationManager = new PublicationManager(editor, opts)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function jobStatusToPublicationStatus(status: JobStatus): PublicationStatus {
|
|
69
|
+
switch (status) {
|
|
70
|
+
case JobStatus.IN_PROGRESS:
|
|
71
|
+
return PublicationStatus.STATUS_PENDING
|
|
72
|
+
case JobStatus.ERROR:
|
|
73
|
+
return PublicationStatus.STATUS_ERROR
|
|
74
|
+
case JobStatus.SUCCESS:
|
|
75
|
+
return PublicationStatus.STATUS_SUCCESS
|
|
76
|
+
}
|
|
77
|
+
throw new Error(`Unknown job status ${status}`)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Orging and path, should we use config.rootUrl?
|
|
81
|
+
const SERVER_URL = window.location.origin + window.location.pathname.replace(/\/$/, '')
|
|
82
|
+
|
|
83
|
+
// The publication manager class
|
|
84
|
+
// This class is responsible for the publication dialog and for the publication process
|
|
85
|
+
// It is added to the editor instance as editor.PublicationManager
|
|
86
|
+
export class PublicationManager {
|
|
87
|
+
/**
|
|
88
|
+
* Publication dialog
|
|
89
|
+
* This class is responsible for the UI
|
|
90
|
+
*/
|
|
91
|
+
dialog?: PublicationUi
|
|
92
|
+
/**
|
|
93
|
+
* Publication settings
|
|
94
|
+
* This is the data which is stored in the website settings
|
|
95
|
+
*/
|
|
96
|
+
_settings: PublicationSettings
|
|
97
|
+
get settings(): PublicationSettings {
|
|
98
|
+
return this._settings
|
|
99
|
+
}
|
|
100
|
+
set settings(newSettings: PublicationSettings) {
|
|
101
|
+
this._settings = newSettings
|
|
102
|
+
this.dialog && (this.dialog.settings = newSettings)
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Plugin options
|
|
106
|
+
* This is the data which is passed to the plugin by grapesjs
|
|
107
|
+
*/
|
|
108
|
+
options: PublicationManagerOptions
|
|
109
|
+
/**
|
|
110
|
+
* Publication job during the publication process
|
|
111
|
+
*/
|
|
112
|
+
job: PublicationJobData | null = null
|
|
113
|
+
/**
|
|
114
|
+
* Publication state
|
|
115
|
+
* This is the state of the publication process
|
|
116
|
+
*/
|
|
117
|
+
status: PublicationStatus = PublicationStatus.STATUS_NONE
|
|
118
|
+
|
|
119
|
+
constructor(private editor: PublishableEditor, opts: PublicationManagerOptions) {
|
|
120
|
+
this.options = {
|
|
121
|
+
appendTo: 'options',
|
|
122
|
+
...opts,
|
|
123
|
+
} as PublicationManagerOptions
|
|
124
|
+
// Save the publication settings in the website settings
|
|
125
|
+
editor.on('storage:start:store', (data) => {
|
|
126
|
+
data.publication = this.settings
|
|
127
|
+
})
|
|
128
|
+
// load publication settings from the website
|
|
129
|
+
editor.on('storage:end:load', (data) => {
|
|
130
|
+
this.settings = data.publication ?? {}
|
|
131
|
+
// Check if the user is logged in
|
|
132
|
+
getUser({ type: ConnectorType.HOSTING, connectorId: this.settings.connector?.connectorId })
|
|
133
|
+
.then((user) => {})
|
|
134
|
+
.catch((err) => {
|
|
135
|
+
this.status = PublicationStatus.STATUS_LOGGED_OUT
|
|
136
|
+
this.settings = {}
|
|
137
|
+
this.dialog && this.dialog.displayError('Please login', this.job, this.status)
|
|
138
|
+
})
|
|
139
|
+
})
|
|
140
|
+
// Add the publish command to the editor
|
|
141
|
+
editor.Commands.add(cmdPublicationStart, () => this.startPublication())
|
|
142
|
+
editor.Commands.add(cmdPublicationLogin, (editor: PublishableEditor, sender: any, connector: ConnectorData) => this.goLogin(connector))
|
|
143
|
+
editor.Commands.add(cmdPublicationLogout, () => this.goLogout())
|
|
144
|
+
// Add the publication dialog to the editor
|
|
145
|
+
if (this.options.appendTo) {
|
|
146
|
+
this.dialog = new PublicationUi(editor, {
|
|
147
|
+
appendTo: this.options.appendTo,
|
|
148
|
+
})
|
|
149
|
+
} else {
|
|
150
|
+
console.info('PublicationUi is disabled because no appendTo option is set')
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async goLogin(connector: ConnectorData) {
|
|
155
|
+
let preventDefault = false
|
|
156
|
+
this.editor.trigger(ClientEvent.PUBLISH_LOGIN_START, { connector, publicationManager: this, preventDefault: () => preventDefault = true })
|
|
157
|
+
if(preventDefault) {
|
|
158
|
+
this.status = PublicationStatus.STATUS_NONE
|
|
159
|
+
this.dialog && this.dialog.displayPending(this.job, this.status)
|
|
160
|
+
return
|
|
161
|
+
}
|
|
162
|
+
// Check if the user is already logged in
|
|
163
|
+
if(connector.isLoggedIn) {
|
|
164
|
+
this.settings = {
|
|
165
|
+
...this.settings, // In case there are options
|
|
166
|
+
connector,
|
|
167
|
+
}
|
|
168
|
+
this.status = PublicationStatus.STATUS_NONE
|
|
169
|
+
// Save the website with the new settings
|
|
170
|
+
// WIP: prevent saving during publication
|
|
171
|
+
// await this.editor.store(null)
|
|
172
|
+
// Display the dialog
|
|
173
|
+
this.dialog && this.dialog.displayPending(this.job, this.status)
|
|
174
|
+
return
|
|
175
|
+
}
|
|
176
|
+
this.settings = {}
|
|
177
|
+
this.status = PublicationStatus.STATUS_LOGGED_OUT
|
|
178
|
+
this.dialog && this.dialog.displayPending(this.job, this.status)
|
|
179
|
+
const params: ApiConnectorLoginQuery = {
|
|
180
|
+
connectorId: connector.connectorId,
|
|
181
|
+
type: connector.type,
|
|
182
|
+
}
|
|
183
|
+
window.open(connector.oauthUrl || `${SERVER_URL}${API_PATH}${API_CONNECTOR_PATH}${API_CONNECTOR_LOGIN}?connectorId=${params.connectorId}&type=${params.type}`, '_blank')
|
|
184
|
+
return new Promise<void>((resolve, reject) => {
|
|
185
|
+
const onMessage = async (event) => {
|
|
186
|
+
const data = event.data as ApiConnectorLoggedInPostMessage
|
|
187
|
+
if (data?.type === 'login') {
|
|
188
|
+
window.removeEventListener('message', onMessage)
|
|
189
|
+
if (data.error) {
|
|
190
|
+
this.status = PublicationStatus.STATUS_LOGGED_OUT
|
|
191
|
+
this.settings = {}
|
|
192
|
+
this.dialog && this.dialog.displayError(data.message, this.job, this.status)
|
|
193
|
+
reject(new Error(data.message))
|
|
194
|
+
} else {
|
|
195
|
+
this.editor.trigger(ClientEvent.PUBLISH_LOGIN_END)
|
|
196
|
+
//const uesr = await getUser({type: connector.type, connectorId: data.connectorId})
|
|
197
|
+
this.settings.connector = connector
|
|
198
|
+
this.settings.options = data.options
|
|
199
|
+
this.status = PublicationStatus.STATUS_NONE
|
|
200
|
+
// Save the website with the new settings
|
|
201
|
+
// WIP: prevent saving during publication
|
|
202
|
+
// await this.editor.store(null)
|
|
203
|
+
// Display the dialog
|
|
204
|
+
this.dialog && this.dialog.displayPending(this.job, this.status)
|
|
205
|
+
//await this.startPublication()
|
|
206
|
+
resolve()
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
window.addEventListener('message', onMessage, false)
|
|
211
|
+
})
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
async goLogout() {
|
|
215
|
+
try {
|
|
216
|
+
await logout({type: ConnectorType.HOSTING, connectorId: this.settings.connector.connectorId})
|
|
217
|
+
this.settings = {}
|
|
218
|
+
this.dialog && this.dialog.displayPending(this.job, this.status)
|
|
219
|
+
} catch (e) {
|
|
220
|
+
console.error('logout error', e)
|
|
221
|
+
this.status = PublicationStatus.STATUS_ERROR
|
|
222
|
+
this.dialog && this.dialog.displayError(e.message, this.job, this.status)
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
async getPublicationData(projectData, siteSettings, preventDefault: () => void): Promise<PublicationData> {
|
|
227
|
+
// Data to publish
|
|
228
|
+
// See assetUrl.ts which is a default transformer, always present
|
|
229
|
+
this.setPublicationTransformers()
|
|
230
|
+
// Build the files structure
|
|
231
|
+
const files: ClientSideFile[] = (await this.getHtmlFiles(siteSettings, preventDefault))
|
|
232
|
+
.flatMap(file => ([{
|
|
233
|
+
path: file.htmlPath, // Already "transformed" in getHtmlFiles
|
|
234
|
+
content: file.html,
|
|
235
|
+
type: ClientSideFileType.HTML,
|
|
236
|
+
} as ClientSideFile, {
|
|
237
|
+
path: file.cssPath, // Already "transformed" in getHtmlFiles
|
|
238
|
+
content: file.css,
|
|
239
|
+
type: ClientSideFileType.CSS,
|
|
240
|
+
} as ClientSideFile]))
|
|
241
|
+
.concat(projectData.assets
|
|
242
|
+
.map(asset => {
|
|
243
|
+
// TODO: is this needed?
|
|
244
|
+
// // Remove /assets that is added by grapesjs
|
|
245
|
+
// const initialPath = asset.src
|
|
246
|
+
// .replace(/^\/assets/, '')
|
|
247
|
+
// Transform the file paths with the transformers
|
|
248
|
+
const path = transformPath(this.editor, asset.src, ClientSideFileType.ASSET)
|
|
249
|
+
//const src = transformPermalink(this.editor, asset.src, ClientSideFileType.ASSET)
|
|
250
|
+
// This is done in transformPermalink and transformPath but other transformers may change it
|
|
251
|
+
// So we do this only using displayedToStored for the path
|
|
252
|
+
// As path is used to download the asset
|
|
253
|
+
const src = displayedToStored(asset.src)
|
|
254
|
+
// Remove the /asset prefix to keep only the file name
|
|
255
|
+
.replace(/^\/assets\//, '')
|
|
256
|
+
return {
|
|
257
|
+
...asset,
|
|
258
|
+
path,
|
|
259
|
+
src,
|
|
260
|
+
type: ClientSideFileType.ASSET, // Replaces grapesjs's 'image' type
|
|
261
|
+
} as ClientSideFile
|
|
262
|
+
}))
|
|
263
|
+
// Create the data to send to the server
|
|
264
|
+
const data: PublicationData = {
|
|
265
|
+
...projectData,
|
|
266
|
+
assets: projectData.assets.map(asset => ({
|
|
267
|
+
...asset,
|
|
268
|
+
src: displayedToStored(asset.src),
|
|
269
|
+
})),
|
|
270
|
+
settings: siteSettings,
|
|
271
|
+
publication: this.settings,
|
|
272
|
+
files,
|
|
273
|
+
}
|
|
274
|
+
this.resetPublicationTransformers()
|
|
275
|
+
// Let plugins transform the data
|
|
276
|
+
transformFiles(this.editor, data)
|
|
277
|
+
this.editor.trigger(ClientEvent.PUBLISH_DATA, { data, preventDefault, publicationManager: this })
|
|
278
|
+
// Return the data
|
|
279
|
+
return data
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Start the publication process
|
|
284
|
+
* This is the command "publish"
|
|
285
|
+
*/
|
|
286
|
+
async startPublication() {
|
|
287
|
+
try {
|
|
288
|
+
if (this.status === PublicationStatus.STATUS_PENDING) throw new Error('Publication is already in progress')
|
|
289
|
+
this.status = PublicationStatus.STATUS_PENDING
|
|
290
|
+
this.job = null
|
|
291
|
+
this.dialog && this.dialog.displayPending(this.job, this.status)
|
|
292
|
+
// Get the data to publish, clone the objects because plugins can change it
|
|
293
|
+
const projectData = { ...this.editor.getProjectData() as WebsiteData }
|
|
294
|
+
const siteSettings = { ...this.editor.getModel().get('settings') as WebsiteSettings }
|
|
295
|
+
let preventDefaultStart = false
|
|
296
|
+
this.editor.trigger(ClientEvent.PUBLISH_START, {projectData, siteSettings, preventDefault: () => preventDefaultStart = true, publicationManager: this })
|
|
297
|
+
if(preventDefaultStart) {
|
|
298
|
+
this.status = PublicationStatus.STATUS_NONE
|
|
299
|
+
this.dialog && this.dialog.displayPending(this.job, this.status)
|
|
300
|
+
return
|
|
301
|
+
}
|
|
302
|
+
// Get the data to publish
|
|
303
|
+
let preventDefaultData = false
|
|
304
|
+
const data = await this.getPublicationData(projectData, siteSettings, () => preventDefaultData = true)
|
|
305
|
+
if(preventDefaultData) {
|
|
306
|
+
this.status = PublicationStatus.STATUS_NONE
|
|
307
|
+
this.dialog && this.dialog.displayPending(this.job, this.status)
|
|
308
|
+
return
|
|
309
|
+
}
|
|
310
|
+
// User and where to publish
|
|
311
|
+
const storageUser = this.editor.getModel().get('user') as ConnectorUser
|
|
312
|
+
if(!storageUser) throw new Error('User not logged in to a storage connector')
|
|
313
|
+
if(!this.settings.connector?.connectorId) throw new Error('User not logged in to a hosting connector')
|
|
314
|
+
const websiteId = this.options.websiteId
|
|
315
|
+
const storageId = storageUser.storage.connectorId
|
|
316
|
+
// Use the publication API
|
|
317
|
+
const [url, job] = await publish({
|
|
318
|
+
websiteId,
|
|
319
|
+
hostingId: this.settings.connector.connectorId,
|
|
320
|
+
storageId,
|
|
321
|
+
data: data as ApiPublicationPublishBody,
|
|
322
|
+
options: this.settings.options,
|
|
323
|
+
})
|
|
324
|
+
|
|
325
|
+
// in gitlab pages situation, getUrl from gitlabHostingConnector gives publication url obtained with Gitlab API pages
|
|
326
|
+
console.info('Gitlab url: ', url)
|
|
327
|
+
// could be used in an future UI
|
|
328
|
+
|
|
329
|
+
this.job = job
|
|
330
|
+
this.status = jobStatusToPublicationStatus(this.job.status)
|
|
331
|
+
this.trackProgress()
|
|
332
|
+
} catch (e) {
|
|
333
|
+
console.error('publish error', e)
|
|
334
|
+
if(e.code === 401 || e.httpStatusCode === 401) {
|
|
335
|
+
this.status = PublicationStatus.STATUS_LOGGED_OUT
|
|
336
|
+
this.settings = {}
|
|
337
|
+
this.dialog && this.dialog.displayError('Please login.', this.job, this.status)
|
|
338
|
+
} else {
|
|
339
|
+
this.status = PublicationStatus.STATUS_ERROR
|
|
340
|
+
this.dialog && this.dialog.displayError(`An error occured, your site is not published. ${e.message}`, this.job, this.status)
|
|
341
|
+
}
|
|
342
|
+
this.editor.trigger(ClientEvent.PUBLISH_ERROR, { success: false, message: e.message })
|
|
343
|
+
this.editor.trigger(ClientEvent.PUBLISH_END, { success: false, message: e.message })
|
|
344
|
+
return
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
async getHtmlFiles(siteSettings: WebsiteSettings, preventDefault): Promise<WebsiteFile[]> {
|
|
349
|
+
return Promise.all(this.editor.Pages.getAll().map(async page => {
|
|
350
|
+
// Clone the settings because plugins can change them
|
|
351
|
+
siteSettings = { ...siteSettings }
|
|
352
|
+
const pageSettings = { ...page.get('settings') as WebsiteSettings }
|
|
353
|
+
// Utility function to get a setting from the page or the site settings
|
|
354
|
+
function getSetting(name) {
|
|
355
|
+
return (pageSettings || {})[name] || (siteSettings || [])[name] || ''
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Get the content from GrapesJS
|
|
359
|
+
const body = page.getMainComponent()
|
|
360
|
+
const cssContent = this.editor.getCss({ component: body })
|
|
361
|
+
console.time(`getHtml ${page.getId()} ${page.get('name')}`)
|
|
362
|
+
const htmlContent = this.editor.getHtml({ component: body })
|
|
363
|
+
console.timeEnd(`getHtml ${page.getId()} ${page.get('name')}`)
|
|
364
|
+
|
|
365
|
+
// Transform the file paths
|
|
366
|
+
const slug = getPageSlug(page.get('name'))
|
|
367
|
+
const cssInitialPath = `/css/${slug}-${await hashString(cssContent)}.css`
|
|
368
|
+
const htmlInitialPath = `/${slug}.html`
|
|
369
|
+
const cssPermalink = transformPermalink(this.editor, cssInitialPath, ClientSideFileType.CSS, Initiator.HTML)
|
|
370
|
+
const cssPath = transformPath(this.editor, cssInitialPath, ClientSideFileType.CSS)
|
|
371
|
+
const htmlPath = transformPath(this.editor, htmlInitialPath, ClientSideFileType.HTML)
|
|
372
|
+
|
|
373
|
+
// Let plugins transform the data
|
|
374
|
+
this.editor.trigger(ClientEvent.PUBLISH_PAGE, { page, siteSettings, pageSettings, preventDefault, publicationManager: this })
|
|
375
|
+
|
|
376
|
+
// Useful data for HTML result
|
|
377
|
+
const title = getSetting('title')
|
|
378
|
+
const favicon = getSetting('favicon')
|
|
379
|
+
// Return the HTML file
|
|
380
|
+
return {
|
|
381
|
+
html: `<!DOCTYPE html>
|
|
382
|
+
<html lang="${getSetting('lang')}">
|
|
383
|
+
<head>
|
|
384
|
+
<meta charset="UTF-8">
|
|
385
|
+
<link rel="stylesheet" href="${cssPermalink}" />
|
|
386
|
+
${siteSettings?.head || ''}
|
|
387
|
+
${pageSettings?.head || ''}
|
|
388
|
+
${ title ? `<title>${ title }</title>` : '' }
|
|
389
|
+
${ favicon ? `<link rel="icon" href="${favicon}" />` : '' }
|
|
390
|
+
${['description', 'og:title', 'og:description', 'og:image']
|
|
391
|
+
.filter(prop => !!getSetting(prop))
|
|
392
|
+
.map(prop => `<meta name="${prop}" property="${prop}" content="${getSetting(prop)}"/>`)
|
|
393
|
+
.join('\n')
|
|
394
|
+
}
|
|
395
|
+
</head>
|
|
396
|
+
${htmlContent}
|
|
397
|
+
</html>`,
|
|
398
|
+
css: cssContent,
|
|
399
|
+
cssPath,
|
|
400
|
+
htmlPath,
|
|
401
|
+
}
|
|
402
|
+
}))
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
async trackProgress() {
|
|
406
|
+
try {
|
|
407
|
+
this.job = await publicationStatus({jobId: this.job.jobId})
|
|
408
|
+
this.status = jobStatusToPublicationStatus(this.job.status)
|
|
409
|
+
} catch (e) {
|
|
410
|
+
this.status = PublicationStatus.STATUS_ERROR
|
|
411
|
+
this.dialog && this.dialog.displayError(`An error occured, your site is not published. ${e.message}`, this.job, this.status)
|
|
412
|
+
this.editor.trigger(ClientEvent.PUBLISH_END, { success: false, message: e.message })
|
|
413
|
+
this.editor.trigger(ClientEvent.PUBLISH_ERROR, { success: false, message: e.message })
|
|
414
|
+
return
|
|
415
|
+
}
|
|
416
|
+
if (this.job.status === JobStatus.IN_PROGRESS) {
|
|
417
|
+
setTimeout(() => this.trackProgress(), 2000)
|
|
418
|
+
} else {
|
|
419
|
+
this.editor.trigger(ClientEvent.PUBLISH_END, { success: this.job.status === JobStatus.SUCCESS, message: this.job.message })
|
|
420
|
+
}
|
|
421
|
+
this.dialog && this.dialog.displayPending(this.job, this.status)
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
private setPublicationTransformers() {
|
|
425
|
+
renderComponents(this.editor)
|
|
426
|
+
renderCssRules(this.editor)
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
private resetPublicationTransformers() {
|
|
430
|
+
resetRenderComponents(this.editor)
|
|
431
|
+
resetRenderCssRules(this.editor)
|
|
432
|
+
}
|
|
433
|
+
}
|