@silexlabs/silex 3.0.0-alpha.100

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.
Files changed (282) hide show
  1. package/.env.default +19 -0
  2. package/.silex.js +37 -0
  3. package/LICENSE +661 -0
  4. package/README.md +96 -0
  5. package/dist/client/client/api.d.ts +85 -0
  6. package/dist/client/client/assetUrl.d.ts +51 -0
  7. package/dist/client/client/config.d.ts +58 -0
  8. package/dist/client/client/events.d.ts +14 -0
  9. package/dist/client/client/expose.d.ts +8 -0
  10. package/dist/client/client/grapesjs/LoginDialog.d.ts +15 -0
  11. package/dist/client/client/grapesjs/PublicationManager.d.ts +72 -0
  12. package/dist/client/client/grapesjs/PublicationUi.d.ts +62 -0
  13. package/dist/client/client/grapesjs/blocks.d.ts +1 -0
  14. package/dist/client/client/grapesjs/breadcrumbs.d.ts +1 -0
  15. package/dist/client/client/grapesjs/footer.d.ts +2 -0
  16. package/dist/client/client/grapesjs/index.d.ts +5 -0
  17. package/dist/client/client/grapesjs/internal-links.d.ts +1 -0
  18. package/dist/client/client/grapesjs/new-page-dialog.d.ts +2 -0
  19. package/dist/client/client/grapesjs/openImport.d.ts +9 -0
  20. package/dist/client/client/grapesjs/page-panel.d.ts +3 -0
  21. package/dist/client/client/grapesjs/project-bar.d.ts +1 -0
  22. package/dist/client/client/grapesjs/rich-text.d.ts +1 -0
  23. package/dist/client/client/grapesjs/semantic.d.ts +1 -0
  24. package/dist/client/client/grapesjs/settings.d.ts +2 -0
  25. package/dist/client/client/grapesjs/storage.d.ts +1 -0
  26. package/dist/client/client/grapesjs/symbolDialogs.d.ts +3 -0
  27. package/dist/client/client/index.d.ts +5 -0
  28. package/dist/client/client/publication-transformers.d.ts +41 -0
  29. package/dist/client/client/utils.d.ts +2 -0
  30. package/dist/client/constants.d.ts +29 -0
  31. package/dist/client/css/admin.css +4491 -0
  32. package/dist/client/index.html +9 -0
  33. package/dist/client/js/main.js +321 -0
  34. package/dist/client/js/main.js.LICENSE.txt +24 -0
  35. package/dist/client/page.d.ts +2 -0
  36. package/dist/client/types.d.ts +334 -0
  37. package/dist/plugins/client/client/api.d.ts +85 -0
  38. package/dist/plugins/client/client/api.js +114 -0
  39. package/dist/plugins/client/client/api.js.map +1 -0
  40. package/dist/plugins/client/client/assetUrl.d.ts +51 -0
  41. package/dist/plugins/client/client/assetUrl.js +224 -0
  42. package/dist/plugins/client/client/assetUrl.js.map +1 -0
  43. package/dist/plugins/client/client/config.d.ts +58 -0
  44. package/dist/plugins/client/client/config.js +90 -0
  45. package/dist/plugins/client/client/config.js.map +1 -0
  46. package/dist/plugins/client/client/events.d.ts +14 -0
  47. package/dist/plugins/client/client/events.js +34 -0
  48. package/dist/plugins/client/client/events.js.map +1 -0
  49. package/dist/plugins/client/client/grapesjs/LoginDialog.d.ts +15 -0
  50. package/dist/plugins/client/client/grapesjs/LoginDialog.js +195 -0
  51. package/dist/plugins/client/client/grapesjs/LoginDialog.js.map +1 -0
  52. package/dist/plugins/client/client/grapesjs/PublicationManager.d.ts +72 -0
  53. package/dist/plugins/client/client/grapesjs/PublicationManager.js +356 -0
  54. package/dist/plugins/client/client/grapesjs/PublicationManager.js.map +1 -0
  55. package/dist/plugins/client/client/grapesjs/PublicationUi.d.ts +62 -0
  56. package/dist/plugins/client/client/grapesjs/PublicationUi.js +336 -0
  57. package/dist/plugins/client/client/grapesjs/PublicationUi.js.map +1 -0
  58. package/dist/plugins/client/client/grapesjs/blocks.d.ts +1 -0
  59. package/dist/plugins/client/client/grapesjs/blocks.js +37 -0
  60. package/dist/plugins/client/client/grapesjs/blocks.js.map +1 -0
  61. package/dist/plugins/client/client/grapesjs/breadcrumbs.d.ts +1 -0
  62. package/dist/plugins/client/client/grapesjs/breadcrumbs.js +75 -0
  63. package/dist/plugins/client/client/grapesjs/breadcrumbs.js.map +1 -0
  64. package/dist/plugins/client/client/grapesjs/footer.d.ts +2 -0
  65. package/dist/plugins/client/client/grapesjs/footer.js +28 -0
  66. package/dist/plugins/client/client/grapesjs/footer.js.map +1 -0
  67. package/dist/plugins/client/client/grapesjs/index.d.ts +5 -0
  68. package/dist/plugins/client/client/grapesjs/index.js +313 -0
  69. package/dist/plugins/client/client/grapesjs/index.js.map +1 -0
  70. package/dist/plugins/client/client/grapesjs/internal-links.d.ts +1 -0
  71. package/dist/plugins/client/client/grapesjs/internal-links.js +219 -0
  72. package/dist/plugins/client/client/grapesjs/internal-links.js.map +1 -0
  73. package/dist/plugins/client/client/grapesjs/new-page-dialog.d.ts +2 -0
  74. package/dist/plugins/client/client/grapesjs/new-page-dialog.js +83 -0
  75. package/dist/plugins/client/client/grapesjs/new-page-dialog.js.map +1 -0
  76. package/dist/plugins/client/client/grapesjs/openImport.d.ts +9 -0
  77. package/dist/plugins/client/client/grapesjs/openImport.js +74 -0
  78. package/dist/plugins/client/client/grapesjs/openImport.js.map +1 -0
  79. package/dist/plugins/client/client/grapesjs/page-panel.d.ts +3 -0
  80. package/dist/plugins/client/client/grapesjs/page-panel.js +113 -0
  81. package/dist/plugins/client/client/grapesjs/page-panel.js.map +1 -0
  82. package/dist/plugins/client/client/grapesjs/project-bar.d.ts +1 -0
  83. package/dist/plugins/client/client/grapesjs/project-bar.js +104 -0
  84. package/dist/plugins/client/client/grapesjs/project-bar.js.map +1 -0
  85. package/dist/plugins/client/client/grapesjs/rich-text.d.ts +1 -0
  86. package/dist/plugins/client/client/grapesjs/rich-text.js +31 -0
  87. package/dist/plugins/client/client/grapesjs/rich-text.js.map +1 -0
  88. package/dist/plugins/client/client/grapesjs/semantic.d.ts +1 -0
  89. package/dist/plugins/client/client/grapesjs/semantic.js +110 -0
  90. package/dist/plugins/client/client/grapesjs/semantic.js.map +1 -0
  91. package/dist/plugins/client/client/grapesjs/settings.d.ts +2 -0
  92. package/dist/plugins/client/client/grapesjs/settings.js +198 -0
  93. package/dist/plugins/client/client/grapesjs/settings.js.map +1 -0
  94. package/dist/plugins/client/client/grapesjs/storage.d.ts +1 -0
  95. package/dist/plugins/client/client/grapesjs/storage.js +126 -0
  96. package/dist/plugins/client/client/grapesjs/storage.js.map +1 -0
  97. package/dist/plugins/client/client/grapesjs/symbolDialogs.d.ts +3 -0
  98. package/dist/plugins/client/client/grapesjs/symbolDialogs.js +36 -0
  99. package/dist/plugins/client/client/grapesjs/symbolDialogs.js.map +1 -0
  100. package/dist/plugins/client/client/publication-transformers.d.ts +41 -0
  101. package/dist/plugins/client/client/publication-transformers.js +238 -0
  102. package/dist/plugins/client/client/publication-transformers.js.map +1 -0
  103. package/dist/plugins/client/client/utils.d.ts +2 -0
  104. package/dist/plugins/client/client/utils.js +25 -0
  105. package/dist/plugins/client/client/utils.js.map +1 -0
  106. package/dist/plugins/client/constants.d.ts +29 -0
  107. package/dist/plugins/client/constants.js +46 -0
  108. package/dist/plugins/client/constants.js.map +1 -0
  109. package/dist/plugins/client/page.d.ts +2 -0
  110. package/dist/plugins/client/page.js +31 -0
  111. package/dist/plugins/client/page.js.map +1 -0
  112. package/dist/plugins/client/plugins/client/11ty.d.ts +17 -0
  113. package/dist/plugins/client/plugins/client/11ty.js +86 -0
  114. package/dist/plugins/client/plugins/client/11ty.js.map +1 -0
  115. package/dist/plugins/client/plugins/client/publicationRenderer.d.ts +2 -0
  116. package/dist/plugins/client/plugins/client/publicationRenderer.js +170 -0
  117. package/dist/plugins/client/plugins/client/publicationRenderer.js.map +1 -0
  118. package/dist/plugins/client/plugins/client/template.d.ts +2 -0
  119. package/dist/plugins/client/plugins/client/template.js +183 -0
  120. package/dist/plugins/client/plugins/client/template.js.map +1 -0
  121. package/dist/plugins/client/plugins/client/website-info.d.ts +1 -0
  122. package/dist/plugins/client/plugins/client/website-info.js +72 -0
  123. package/dist/plugins/client/plugins/client/website-info.js.map +1 -0
  124. package/dist/plugins/client/types.d.ts +334 -0
  125. package/dist/plugins/client/types.js +74 -0
  126. package/dist/plugins/client/types.js.map +1 -0
  127. package/dist/plugins/server/constants.d.ts +29 -0
  128. package/dist/plugins/server/constants.js +49 -0
  129. package/dist/plugins/server/constants.js.map +1 -0
  130. package/dist/plugins/server/plugins/server/AuthPlugin.d.ts +1 -0
  131. package/dist/plugins/server/plugins/server/AuthPlugin.js +40 -0
  132. package/dist/plugins/server/plugins/server/AuthPlugin.js.map +1 -0
  133. package/dist/plugins/server/plugins/server/Cache.d.ts +2 -0
  134. package/dist/plugins/server/plugins/server/Cache.js +32 -0
  135. package/dist/plugins/server/plugins/server/Cache.js.map +1 -0
  136. package/dist/plugins/server/plugins/server/DownloadConnector.d.ts +29 -0
  137. package/dist/plugins/server/plugins/server/DownloadConnector.js +129 -0
  138. package/dist/plugins/server/plugins/server/DownloadConnector.js.map +1 -0
  139. package/dist/plugins/server/plugins/server/FtpConnector.d.ts +86 -0
  140. package/dist/plugins/server/plugins/server/FtpConnector.js +526 -0
  141. package/dist/plugins/server/plugins/server/FtpConnector.js.map +1 -0
  142. package/dist/plugins/server/plugins/server/GitlabConnector.d.ts +87 -0
  143. package/dist/plugins/server/plugins/server/GitlabConnector.js +564 -0
  144. package/dist/plugins/server/plugins/server/GitlabConnector.js.map +1 -0
  145. package/dist/plugins/server/plugins/server/PublicationOptimizer.d.ts +0 -0
  146. package/dist/plugins/server/plugins/server/PublicationOptimizer.js +14 -0
  147. package/dist/plugins/server/plugins/server/PublicationOptimizer.js.map +1 -0
  148. package/dist/plugins/server/plugins/server/SslPlugin.d.ts +1 -0
  149. package/dist/plugins/server/plugins/server/SslPlugin.js +86 -0
  150. package/dist/plugins/server/plugins/server/SslPlugin.js.map +1 -0
  151. package/dist/plugins/server/plugins/server/StaticPlugin.d.ts +1 -0
  152. package/dist/plugins/server/plugins/server/StaticPlugin.js +78 -0
  153. package/dist/plugins/server/plugins/server/StaticPlugin.js.map +1 -0
  154. package/dist/plugins/server/server/config.d.ts +59 -0
  155. package/dist/plugins/server/server/config.js +181 -0
  156. package/dist/plugins/server/server/config.js.map +1 -0
  157. package/dist/plugins/server/server/connectors/FsHosting.d.ts +13 -0
  158. package/dist/plugins/server/server/connectors/FsHosting.js +54 -0
  159. package/dist/plugins/server/server/connectors/FsHosting.js.map +1 -0
  160. package/dist/plugins/server/server/connectors/FsStorage.d.ts +43 -0
  161. package/dist/plugins/server/server/connectors/FsStorage.js +257 -0
  162. package/dist/plugins/server/server/connectors/FsStorage.js.map +1 -0
  163. package/dist/plugins/server/server/connectors/connectors.d.ts +87 -0
  164. package/dist/plugins/server/server/connectors/connectors.js +127 -0
  165. package/dist/plugins/server/server/connectors/connectors.js.map +1 -0
  166. package/dist/plugins/server/server/events.d.ts +26 -0
  167. package/dist/plugins/server/server/events.js +31 -0
  168. package/dist/plugins/server/server/events.js.map +1 -0
  169. package/dist/plugins/server/server/jobs.d.ts +12 -0
  170. package/dist/plugins/server/server/jobs.js +77 -0
  171. package/dist/plugins/server/server/jobs.js.map +1 -0
  172. package/dist/plugins/server/server/utils/validation.d.ts +7 -0
  173. package/dist/plugins/server/server/utils/validation.js +38 -0
  174. package/dist/plugins/server/server/utils/validation.js.map +1 -0
  175. package/dist/plugins/server/types.d.ts +334 -0
  176. package/dist/plugins/server/types.js +78 -0
  177. package/dist/plugins/server/types.js.map +1 -0
  178. package/dist/server/constants.js +29 -0
  179. package/dist/server/plugins/server/Cache.js +15 -0
  180. package/dist/server/server/api/api.js +20 -0
  181. package/dist/server/server/api/connectorApi.js +216 -0
  182. package/dist/server/server/api/publicationApi.js +108 -0
  183. package/dist/server/server/api/websiteApi.js +296 -0
  184. package/dist/server/server/cli.js +68 -0
  185. package/dist/server/server/config.js +120 -0
  186. package/dist/server/server/connectors/FsHosting.js +35 -0
  187. package/dist/server/server/connectors/FsStorage.js +225 -0
  188. package/dist/server/server/connectors/connectors.js +89 -0
  189. package/dist/server/server/events.js +14 -0
  190. package/dist/server/server/expose.js +27 -0
  191. package/dist/server/server/express.js +47 -0
  192. package/dist/server/server/index.js +90 -0
  193. package/dist/server/server/jobs.js +48 -0
  194. package/dist/server/server/utils/validation.js +15 -0
  195. package/dist/server/types.js +34 -0
  196. package/package.json +209 -0
  197. package/public/assets/container.png +0 -0
  198. package/public/assets/favicon.png +0 -0
  199. package/public/assets/logo-silex-small.png +0 -0
  200. package/public/robots.txt +2 -0
  201. package/public/silex.js +24 -0
  202. package/src/css/_mixins.scss +8 -0
  203. package/src/css/_variables.scss +33 -0
  204. package/src/css/dialog.scss +41 -0
  205. package/src/css/footer.scss +12 -0
  206. package/src/css/grapesjs-light.scss +180 -0
  207. package/src/css/grapesjs.scss +152 -0
  208. package/src/css/index.scss +32 -0
  209. package/src/css/light.scss +7 -0
  210. package/src/css/loader.scss +12 -0
  211. package/src/css/page-panel.scss +65 -0
  212. package/src/css/project-bar.scss +102 -0
  213. package/src/css/silex.scss +189 -0
  214. package/src/css/website-info.scss +14 -0
  215. package/src/html/debug.pug +8 -0
  216. package/src/html/index.pug +39 -0
  217. package/src/html/templates/includes.pug +1 -0
  218. package/src/html/templates/workspace.pug +2 -0
  219. package/src/ts/client/api.ts +144 -0
  220. package/src/ts/client/assetUrl.test.ts +125 -0
  221. package/src/ts/client/assetUrl.ts +235 -0
  222. package/src/ts/client/config.ts +105 -0
  223. package/src/ts/client/events.ts +34 -0
  224. package/src/ts/client/expose.ts +30 -0
  225. package/src/ts/client/grapesjs/LoginDialog.ts +204 -0
  226. package/src/ts/client/grapesjs/PublicationManager.ts +370 -0
  227. package/src/ts/client/grapesjs/PublicationUi.ts +342 -0
  228. package/src/ts/client/grapesjs/blocks.ts +37 -0
  229. package/src/ts/client/grapesjs/breadcrumbs.ts +79 -0
  230. package/src/ts/client/grapesjs/eleventy.ts +47 -0
  231. package/src/ts/client/grapesjs/footer.ts +27 -0
  232. package/src/ts/client/grapesjs/index.ts +335 -0
  233. package/src/ts/client/grapesjs/internal-links.test.ts +105 -0
  234. package/src/ts/client/grapesjs/internal-links.ts +225 -0
  235. package/src/ts/client/grapesjs/new-page-dialog.ts +90 -0
  236. package/src/ts/client/grapesjs/openImport.ts +81 -0
  237. package/src/ts/client/grapesjs/page-panel.ts +118 -0
  238. package/src/ts/client/grapesjs/project-bar.ts +107 -0
  239. package/src/ts/client/grapesjs/rich-text.ts +33 -0
  240. package/src/ts/client/grapesjs/semantic.ts +114 -0
  241. package/src/ts/client/grapesjs/settings.ts +208 -0
  242. package/src/ts/client/grapesjs/storage.ts +121 -0
  243. package/src/ts/client/grapesjs/symbolDialogs.ts +38 -0
  244. package/src/ts/client/index.ts +98 -0
  245. package/src/ts/client/publication-transformers.test.ts +199 -0
  246. package/src/ts/client/publication-transformers.ts +263 -0
  247. package/src/ts/client/utils.ts +28 -0
  248. package/src/ts/constants.ts +52 -0
  249. package/src/ts/externs.ts +18 -0
  250. package/src/ts/page.ts +31 -0
  251. package/src/ts/plugins/client/11ty.ts +104 -0
  252. package/src/ts/plugins/client/publicationRenderer.ts +174 -0
  253. package/src/ts/plugins/client/template.ts +192 -0
  254. package/src/ts/plugins/client/website-info.ts +84 -0
  255. package/src/ts/plugins/server/AuthPlugin.ts +38 -0
  256. package/src/ts/plugins/server/Cache.ts +28 -0
  257. package/src/ts/plugins/server/DownloadConnector.ts +148 -0
  258. package/src/ts/plugins/server/FtpConnector.test.ts +82 -0
  259. package/src/ts/plugins/server/FtpConnector.ts +609 -0
  260. package/src/ts/plugins/server/GitlabConnector.ts +644 -0
  261. package/src/ts/plugins/server/PublicationOptimizer.ts +14 -0
  262. package/src/ts/plugins/server/SslPlugin.ts +84 -0
  263. package/src/ts/plugins/server/StaticPlugin.ts +79 -0
  264. package/src/ts/server/api/api.ts +19 -0
  265. package/src/ts/server/api/connectorApi.ts +345 -0
  266. package/src/ts/server/api/publicationApi.ts +159 -0
  267. package/src/ts/server/api/websiteApi.ts +432 -0
  268. package/src/ts/server/cli.ts +65 -0
  269. package/src/ts/server/config.ts +189 -0
  270. package/src/ts/server/connectors/FsHosting.ts +60 -0
  271. package/src/ts/server/connectors/FsStorage.test.ts +51 -0
  272. package/src/ts/server/connectors/FsStorage.ts +261 -0
  273. package/src/ts/server/connectors/connectors.ts +203 -0
  274. package/src/ts/server/events.ts +37 -0
  275. package/src/ts/server/expose.ts +19 -0
  276. package/src/ts/server/express.ts +70 -0
  277. package/src/ts/server/index.ts +100 -0
  278. package/src/ts/server/jobs.test.ts +75 -0
  279. package/src/ts/server/jobs.ts +87 -0
  280. package/src/ts/server/utils/BackwardCompat.ts +552 -0
  281. package/src/ts/server/utils/validation.ts +34 -0
  282. package/src/ts/types.ts +339 -0
@@ -0,0 +1,370 @@
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, 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
+
27
+ /**
28
+ * @fileoverview Publication manager for Silex
29
+ * This plugin adds a publication feature to Silex
30
+ * It lets the user publish the website to a hosting service
31
+ * It can optionally display a button and a dialog
32
+ * Useful commands:
33
+ * - publish: starts the publication process and optionally open the dialog
34
+ * - publish-login: open the login dialog
35
+ * - publish-logout: logout from the hosting service and let the user choose a hosting service again
36
+ */
37
+
38
+ // Constants
39
+ export const cmdPublicationStart = 'publish'
40
+ export const cmdPublicationLogin = 'publish-login'
41
+ export const cmdPublicationLogout = 'publish-logout'
42
+
43
+ // Types
44
+ export type PublishableEditor = Editor & {
45
+ PublicationManager: PublicationManager
46
+ }
47
+
48
+ export enum PublicationStatus {
49
+ STATUS_NONE = 'STATUS_NONE',
50
+ STATUS_PENDING = 'STATUS_PENDING',
51
+ STATUS_ERROR = 'STATUS_ERROR',
52
+ STATUS_SUCCESS = 'STATUS_SUCCESS',
53
+ STATUS_LOGGED_OUT = 'STATUS_AUTH_ERROR',
54
+ }
55
+
56
+ export type PublicationManagerOptions = {
57
+ appendTo?: string // If not provided, no button nor dialog will be created
58
+ websiteId: WebsiteId
59
+ }
60
+
61
+ // plugin init cod
62
+ export default function publishPlugin(editor, opts) {
63
+ (editor as PublishableEditor).PublicationManager = new PublicationManager(editor, opts)
64
+ }
65
+
66
+ function jobStatusToPublicationStatus(status: JobStatus): PublicationStatus {
67
+ switch (status) {
68
+ case JobStatus.IN_PROGRESS:
69
+ return PublicationStatus.STATUS_PENDING
70
+ case JobStatus.ERROR:
71
+ return PublicationStatus.STATUS_ERROR
72
+ case JobStatus.SUCCESS:
73
+ return PublicationStatus.STATUS_SUCCESS
74
+ }
75
+ throw new Error(`Unknown job status ${status}`)
76
+ }
77
+
78
+ // Orging and path, should we use config.rootUrl?
79
+ const SERVER_URL = window.location.origin + window.location.pathname.replace(/\/$/, '')
80
+
81
+ // The publication manager class
82
+ // This class is responsible for the publication dialog and for the publication process
83
+ // It is added to the editor instance as editor.PublicationManager
84
+ export class PublicationManager {
85
+ /**
86
+ * Publication dialog
87
+ * This class is responsible for the UI
88
+ */
89
+ dialog?: PublicationUi
90
+ /**
91
+ * Publication settings
92
+ * This is the data which is stored in the website settings
93
+ */
94
+ _settings: PublicationSettings
95
+ get settings(): PublicationSettings {
96
+ return this._settings
97
+ }
98
+ set settings(newSettings: PublicationSettings) {
99
+ this._settings = newSettings
100
+ this.dialog && (this.dialog.settings = newSettings)
101
+ }
102
+ /**
103
+ * Plugin options
104
+ * This is the data which is passed to the plugin by grapesjs
105
+ */
106
+ options: PublicationManagerOptions
107
+ /**
108
+ * Publication job during the publication process
109
+ */
110
+ job: PublicationJobData | null = null
111
+ /**
112
+ * Publication state
113
+ * This is the state of the publication process
114
+ */
115
+ status: PublicationStatus = PublicationStatus.STATUS_NONE
116
+
117
+ constructor(private editor: PublishableEditor, opts: PublicationManagerOptions) {
118
+ this.options = {
119
+ appendTo: 'options',
120
+ ...opts,
121
+ } as PublicationManagerOptions
122
+ // Save the publication settings in the website settings
123
+ editor.on('storage:start:store', (data) => {
124
+ data.publication = this.settings
125
+ })
126
+ // load publication settings from the website
127
+ editor.on('storage:end:load', (data) => {
128
+ this.settings = data.publication ?? {}
129
+ // Check if the user is logged in
130
+ getUser({ type: ConnectorType.HOSTING, connectorId: this.settings.connector?.connectorId })
131
+ .then((user) => {})
132
+ .catch((err) => {
133
+ this.status = PublicationStatus.STATUS_LOGGED_OUT
134
+ this.settings = {}
135
+ this.dialog && this.dialog.displayError('Please login', this.job, this.status)
136
+ })
137
+ })
138
+ // Add the publish command to the editor
139
+ editor.Commands.add(cmdPublicationStart, () => this.startPublication())
140
+ editor.Commands.add(cmdPublicationLogin, (editor: PublishableEditor, sender: any, connector: ConnectorData) => this.goLogin(connector))
141
+ editor.Commands.add(cmdPublicationLogout, () => this.goLogout())
142
+ // Add the publication dialog to the editor
143
+ if (this.options.appendTo) {
144
+ this.dialog = new PublicationUi(editor, {
145
+ appendTo: this.options.appendTo,
146
+ })
147
+ } else {
148
+ console.info('PublicationUi is disabled because no appendTo option is set')
149
+ }
150
+ }
151
+
152
+ async goLogin(connector: ConnectorData) {
153
+ // Check if the user is already logged in
154
+ if(connector.isLoggedIn) {
155
+ this.settings = {
156
+ ...this.settings, // In case there are options
157
+ connector,
158
+ }
159
+ this.status = PublicationStatus.STATUS_NONE
160
+ // Save the website with the new settings
161
+ this.editor.store(null)
162
+ // Display the dialog
163
+ this.dialog && this.dialog.displayPending(this.job, this.status)
164
+ return
165
+ }
166
+ this.settings = {}
167
+ this.status = PublicationStatus.STATUS_LOGGED_OUT
168
+ this.dialog && this.dialog.displayPending(this.job, this.status)
169
+ const params: ApiConnectorLoginQuery = {
170
+ connectorId: connector.connectorId,
171
+ type: connector.type,
172
+ }
173
+ window.open(connector.oauthUrl || `${SERVER_URL}${API_PATH}${API_CONNECTOR_PATH}${API_CONNECTOR_LOGIN}?connectorId=${params.connectorId}&type=${params.type}`, '_blank')
174
+ return new Promise(resolve => {
175
+ const onMessage = async (event) => {
176
+ const data = event.data as ApiConnectorLoggedInPostMessage
177
+ if (data?.type === 'login') {
178
+ window.removeEventListener('message', onMessage)
179
+ if (data.error) {
180
+ this.status = PublicationStatus.STATUS_LOGGED_OUT
181
+ this.settings = {}
182
+ this.dialog && this.dialog.displayError(data.message, this.job, this.status)
183
+ } else {
184
+ this.editor.trigger(ClientEvent.PUBLISH_LOGIN_END)
185
+ //const uesr = await getUser({type: connector.type, connectorId: data.connectorId})
186
+ this.settings.connector = connector
187
+ this.settings.options = data.options
188
+ this.status = PublicationStatus.STATUS_NONE
189
+ // Save the website with the new settings
190
+ this.editor.store(null)
191
+ // Display the dialog
192
+ this.dialog && this.dialog.displayPending(this.job, this.status)
193
+ //await this.startPublication()
194
+ }
195
+ }
196
+ }
197
+ window.addEventListener('message', onMessage, false)
198
+ })
199
+ }
200
+
201
+ async goLogout() {
202
+ try {
203
+ await logout({type: ConnectorType.HOSTING, connectorId: this.settings.connector.connectorId})
204
+ this.settings = {}
205
+ this.dialog && this.dialog.displayPending(this.job, this.status)
206
+ } catch (e) {
207
+ console.error('logout error', e)
208
+ this.status = PublicationStatus.STATUS_ERROR
209
+ this.dialog && this.dialog.displayError(e.message, this.job, this.status)
210
+ }
211
+ }
212
+
213
+ /**
214
+ * Start the publication process
215
+ * This is the command "publish"
216
+ */
217
+ async startPublication() {
218
+ if (this.status === PublicationStatus.STATUS_PENDING) throw new Error('Publication is already in progress')
219
+ this.status = PublicationStatus.STATUS_PENDING
220
+ this.job = null
221
+ this.dialog && this.dialog.displayPending(this.job, this.status)
222
+ this.editor.trigger(ClientEvent.PUBLISH_START)
223
+ // User and where to publish
224
+ const storageUser = this.editor.getModel().get('user') as ConnectorUser
225
+ if(!storageUser) throw new Error('User not logged in to a storage connector')
226
+ if(!this.settings.connector?.connectorId) throw new Error('User not logged in to a hosting connector')
227
+ const websiteId = this.options.websiteId
228
+ const storageId = storageUser.storage.connectorId
229
+ // Data to publish
230
+ // See assetUrl.ts which is a default transformer, always present
231
+ this.setPublicationTransformers()
232
+ const projectData = this.editor.getProjectData() as WebsiteData
233
+ const siteSettings = this.editor.getModel().get('settings') as WebsiteSettings
234
+ // Build the files structure
235
+ const files: ClientSideFile[] = (await this.getHtmlFiles(siteSettings))
236
+ .flatMap(file => ([{
237
+ path: file.htmlPath, // Already "transformed" in getHtmlFiles
238
+ content: file.html,
239
+ type: ClientSideFileType.HTML,
240
+ } as ClientSideFile, {
241
+ path: file.cssPath, // Already "transformed" in getHtmlFiles
242
+ content: file.css,
243
+ type: ClientSideFileType.CSS,
244
+ } as ClientSideFile]))
245
+ .concat(projectData.assets
246
+ .map(asset => {
247
+ // TODO: is this needed?
248
+ // // Remove /assets that is added by grapesjs
249
+ // const initialPath = asset.src
250
+ // .replace(/^\/assets/, '')
251
+ // Transform the file paths with the transformers
252
+ const path = transformPath(this.editor, asset.src, ClientSideFileType.ASSET)
253
+ const src = transformPermalink(this.editor, asset.src, ClientSideFileType.ASSET)
254
+ return {
255
+ ...asset,
256
+ path,
257
+ src,
258
+ type: ClientSideFileType.ASSET, // Replaces grapesjs's 'image' type
259
+ } as ClientSideFile
260
+ }))
261
+ // Create the data to send to the server
262
+ const data: PublicationData = {
263
+ ...projectData,
264
+ settings: siteSettings,
265
+ publication: this.settings,
266
+ files,
267
+ }
268
+ this.resetPublicationTransformers()
269
+ transformFiles(this.editor, data)
270
+ this.editor.trigger(ClientEvent.PUBLISH_DATA, data)
271
+ try {
272
+ const [url, job] = await publish({
273
+ websiteId,
274
+ hostingId: this.settings.connector.connectorId,
275
+ storageId,
276
+ data: data as ApiPublicationPublishBody,
277
+ options: this.settings.options,
278
+ })
279
+ this.job = job
280
+ this.status = jobStatusToPublicationStatus(this.job.status)
281
+ // Save the publication settings
282
+ // Useless because the url is useful after publish only
283
+ //if(this.settings.url !== url) {
284
+ // this.settings.url = url
285
+ // await this.editor.store(null)
286
+ //}
287
+ this.trackProgress()
288
+ } catch (e) {
289
+ console.error('publish error', e)
290
+ if(e.code === 401 || e.httpStatusCode === 401) {
291
+ this.status = PublicationStatus.STATUS_LOGGED_OUT
292
+ this.settings = {}
293
+ this.dialog && this.dialog.displayError('Please login.', this.job, this.status)
294
+ } else {
295
+ this.status = PublicationStatus.STATUS_ERROR
296
+ this.dialog && this.dialog.displayError(`An error occured, your site is not published. ${e.message}`, this.job, this.status)
297
+ }
298
+ this.editor.trigger(ClientEvent.PUBLISH_ERROR, { success: false, message: e.message })
299
+ this.editor.trigger(ClientEvent.PUBLISH_END, { success: false, message: e.message })
300
+ return
301
+ }
302
+ }
303
+
304
+ async getHtmlFiles(siteSettings: WebsiteSettings): Promise<WebsiteFile[]> {
305
+ return this.editor.Pages.getAll().map(page => {
306
+ const pageSettings = page.get('settings') as WebsiteSettings
307
+ function getSetting(name) {
308
+ return (pageSettings || {})[name] || (siteSettings || [])[name] || ''
309
+ }
310
+ const component = page.getMainComponent()
311
+ // Transform the file paths
312
+ const slug = getPageSlug(page.get('name'))
313
+ const cssInitialPath = `/css/${slug}.css`
314
+ const htmlInitialPath = `/${slug}.html`
315
+ const cssPermalink = transformPermalink(this.editor, cssInitialPath, ClientSideFileType.CSS)
316
+ const cssPath = transformPath(this.editor, cssInitialPath, ClientSideFileType.CSS)
317
+ const htmlPath = transformPath(this.editor, htmlInitialPath, ClientSideFileType.HTML)
318
+ const body = this.editor.getHtml({ component })
319
+ return {
320
+ html: `<!DOCTYPE html>
321
+ <html lang="${getSetting('lang')}">
322
+ <head>
323
+ <link rel="stylesheet" href="${cssPermalink}" />
324
+ ${siteSettings?.head || ''}
325
+ ${pageSettings?.head || ''}
326
+ <title>${getSetting('title')}</title>
327
+ <link rel="icon" href="${getSetting('favicon')}" />
328
+ ${['description', 'og:title', 'og:description', 'og:image']
329
+ .map(prop => `<meta property="${prop}" content="${getSetting(prop)}"/>`)
330
+ .join('\n')
331
+ }
332
+ </head>
333
+ ${body}
334
+ </html>`,
335
+ css: this.editor.getCss({ component }),
336
+ cssPath,
337
+ htmlPath,
338
+ }
339
+ })
340
+ }
341
+
342
+ async trackProgress() {
343
+ try {
344
+ this.job = await publicationStatus({jobId: this.job.jobId})
345
+ this.status = jobStatusToPublicationStatus(this.job.status)
346
+ } catch (e) {
347
+ this.status = PublicationStatus.STATUS_ERROR
348
+ this.dialog && this.dialog.displayError(`An error occured, your site is not published. ${e.message}`, this.job, this.status)
349
+ this.editor.trigger(ClientEvent.PUBLISH_END, { success: false, message: e.message })
350
+ this.editor.trigger(ClientEvent.PUBLISH_ERROR, { success: false, message: e.message })
351
+ return
352
+ }
353
+ if (this.job.status === JobStatus.IN_PROGRESS) {
354
+ setTimeout(() => this.trackProgress(), 2000)
355
+ } else {
356
+ this.editor.trigger(ClientEvent.PUBLISH_END, { success: this.job.status === JobStatus.SUCCESS, message: this.job.message })
357
+ }
358
+ this.dialog && this.dialog.displayPending(this.job, this.status)
359
+ }
360
+
361
+ private setPublicationTransformers() {
362
+ renderComponents(this.editor)
363
+ renderCssRules(this.editor)
364
+ }
365
+
366
+ private resetPublicationTransformers() {
367
+ resetRenderComponents(this.editor)
368
+ resetRenderCssRules(this.editor)
369
+ }
370
+ }