@silexlabs/silex 3.0.0-alpha.48 → 3.0.0-alpha.49

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 (40) hide show
  1. package/dist/client/client/config.d.ts +2 -0
  2. package/dist/client/css/admin.css +15 -0
  3. package/dist/client/js/main.js +12 -12
  4. package/dist/plugins/client/plugins/client/website-info.d.ts +1 -0
  5. package/dist/plugins/client/plugins/client/website-info.js +55 -0
  6. package/dist/plugins/client/plugins/client/website-info.js.map +1 -0
  7. package/dist/plugins/server/plugins/server/GitlabConnector.js +4 -4
  8. package/dist/plugins/server/plugins/server/GitlabConnector.js.map +1 -1
  9. package/dist/plugins/server/plugins/server/SslPlugin.js +5 -5
  10. package/dist/plugins/server/plugins/server/SslPlugin.js.map +1 -1
  11. package/dist/plugins/server/plugins/server/StaticPlugin.js +4 -0
  12. package/dist/plugins/server/plugins/server/StaticPlugin.js.map +1 -1
  13. package/dist/plugins/server/server/config.js +4 -5
  14. package/dist/plugins/server/server/config.js.map +1 -1
  15. package/dist/plugins/server/server/connectors/FsStorage.js +1 -1
  16. package/dist/plugins/server/server/connectors/FsStorage.js.map +1 -1
  17. package/dist/server/server/config.js +4 -5
  18. package/dist/server/server/connectors/FsStorage.js +1 -1
  19. package/dist/server/server/express.js +2 -2
  20. package/package.json +1 -1
  21. package/public/silex.js +5 -0
  22. package/src/css/grapesjs.scss +1 -0
  23. package/src/css/index.scss +1 -0
  24. package/src/css/website-info.scss +13 -0
  25. package/src/ts/client/api.ts +1 -1
  26. package/src/ts/client/config.ts +3 -0
  27. package/src/ts/client/grapesjs/LoginDialog.ts +0 -1
  28. package/src/ts/client/grapesjs/index.ts +0 -2
  29. package/src/ts/client/grapesjs/settings.ts +1 -1
  30. package/src/ts/client/grapesjs/storage.ts +0 -1
  31. package/src/ts/client/index.ts +1 -3
  32. package/src/ts/plugins/client/website-info.ts +63 -0
  33. package/src/ts/plugins/server/GitlabConnector.ts +4 -4
  34. package/src/ts/plugins/server/SslPlugin.ts +5 -5
  35. package/src/ts/plugins/server/StaticPlugin.ts +4 -0
  36. package/src/ts/server/config.ts +4 -5
  37. package/src/ts/server/connectors/FsStorage.ts +1 -1
  38. package/src/ts/server/express.ts +2 -2
  39. package/dist/client/client/grapesjs/website-info.d.ts +0 -2
  40. package/src/ts/client/grapesjs/website-info.ts +0 -39
@@ -0,0 +1,63 @@
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 { ClientEvent } from '../../client/events.js'
19
+
20
+ interface WebsiteInfoOptions {
21
+ websiteId: string
22
+ connectorId: string
23
+ appendTo: 'commands' | 'options' | 'views' | 'project-bar-container' | 'project-bar-panel' | 'views-container'
24
+ }
25
+
26
+ export default async function(config) {
27
+ config.on(ClientEvent.GRAPESJS_START, async () => {
28
+ const grapesPlugin = (editor, opts: Partial<WebsiteInfoOptions>) => {
29
+ const options = {
30
+ appendTo: 'commands',
31
+ ...opts,
32
+ } as WebsiteInfoOptions
33
+ editor.on('storage:end:load', async () => {
34
+ // Get website meta data
35
+ const { websiteId, connectorId } = options
36
+ // Get the website meta data
37
+ const websiteMeta = await config.api.websiteMetaRead({ websiteId, connectorId })
38
+ displayWebsiteMeta(websiteMeta)
39
+ })
40
+ return {}
41
+ }
42
+
43
+ config.grapesJsConfig.plugins.push(grapesPlugin)
44
+ config.grapesJsConfig.pluginsOpts[grapesPlugin.toString()] = {
45
+ websiteId: config.websiteId,
46
+ connectorId: config.storageId,
47
+ }
48
+ function displayWebsiteMeta(websiteMeta) {
49
+ // Create the container
50
+ const container = document.createElement('div')
51
+ container.classList.add('gjs-website-meta')
52
+ // Add the container to the UI
53
+ // Add the name of the website in the top bar
54
+ const topBar = document.querySelector('.gjs-pn-devices-c')
55
+ topBar?.appendChild(container)
56
+ // Display the website meta data
57
+ container.innerHTML = `
58
+ <div class="gjs-website-meta-image" style="background: url(${websiteMeta.imageUrl});"></div>
59
+ <div class="gjs-website-meta-name">${websiteMeta.name}</div>
60
+ `
61
+ }
62
+ })
63
+ }
@@ -119,7 +119,7 @@ export default class GitlabConnector implements StorageConnector {
119
119
  constructor(private config: ServerConfig, opts: Partial<GitlabOptions>) {
120
120
  this.options = {
121
121
  branch: 'main',
122
- assetsFolder: '',
122
+ assetsFolder: 'assets',
123
123
  metaRepo: 'silex-meta',
124
124
  metaRepoFile: 'websites.json',
125
125
  ...opts,
@@ -131,7 +131,7 @@ export default class GitlabConnector implements StorageConnector {
131
131
  // **
132
132
  // Convenience methods for the Gitlab API
133
133
  private getAssetPath(path: string): string {
134
- return `${this.options.assetsFolder}${path}`
134
+ return encodeURIComponent(`${this.options.assetsFolder}${path}`)
135
135
  }
136
136
 
137
137
  private async createFile(session: GitlabSession, websiteId: WebsiteId, path: string, content: string, isBase64 = false): Promise<void> {
@@ -375,7 +375,6 @@ export default class GitlabConnector implements StorageConnector {
375
375
  const { content } = result
376
376
  const contentDecoded = Buffer.from(content, 'base64').toString('utf8')
377
377
  const websites = (JSON.parse(contentDecoded) as MetaRepoFileContent).websites
378
- console.log('listWebsites', {websites, contentDecoded, content, result})
379
378
  return Object.entries(websites).map(([websiteId, {meta, createdAt, updatedAt}]) => ({
380
379
  websiteId,
381
380
  createdAt: new Date(createdAt),
@@ -514,7 +513,7 @@ export default class GitlabConnector implements StorageConnector {
514
513
  } catch (e) {
515
514
  // If the file does not exist, create it
516
515
  if (e.statusCode === 404 || e.httpStatusCode === 404 || e.message.endsWith('A file with this name doesn\'t exist')) {
517
- await this.createFile(session, websiteId, file.path, content, true)
516
+ await this.createFile(session, websiteId, this.getAssetPath(file.path), content, true)
518
517
  } else {
519
518
  throw e
520
519
  }
@@ -537,6 +536,7 @@ export default class GitlabConnector implements StorageConnector {
537
536
  if(!response.ok) throw new ApiError(`Gitlab API error: ${json?.message ?? json?.error ?? response.statusText}`, response.status)
538
537
  // From base64 string to buffer
539
538
  const buf = Buffer.from(json.content, 'base64')
539
+ // Return the image bytes
540
540
  return buf
541
541
  }
542
542
 
@@ -47,18 +47,18 @@ export default async function(config, opts = {}) {
47
47
  // SSL
48
48
  // force ssl if the env var SILEX_FORCE_HTTPS is set
49
49
  if (options.forceHttps) {
50
- console.log('> [SslPlugin] Force SSL option is enabled')
50
+ console.info('> [SslPlugin] Force SSL option is enabled')
51
51
  app.set('forceSSLOptions', {
52
52
  trustXFPHeader: !!options.trustXFPHeader,
53
53
  })
54
54
  router.use(forceSSL)
55
55
  } else {
56
- console.log('> [SslPlugin] Force SSL option is disabled, env var SILEX_FORCE_HTTPS not set')
56
+ console.info('> [SslPlugin] Force SSL option is disabled, env var SILEX_FORCE_HTTPS not set')
57
57
  }
58
58
 
59
59
  // SSL certificate
60
60
  if (options.privateKey && options.certificate) {
61
- console.log('> [SslPlugin] SSL certificate is enabled, found certificate:', options.certificate)
61
+ console.info('> [SslPlugin] SSL certificate is enabled, found certificate:', options.certificate)
62
62
  try {
63
63
  const privateKey = readFileSync(options.privateKey).toString()
64
64
  const certificate = readFileSync(options.certificate).toString()
@@ -71,13 +71,13 @@ export default async function(config, opts = {}) {
71
71
  }
72
72
 
73
73
  createServer(sslServerOptions, this).listen(options.sslPort, () => {
74
- console.log('> [SslPlugin] Listening on port ', options.sslPort)
74
+ console.info('> [SslPlugin] Listening on port ', options.sslPort)
75
75
  })
76
76
  } catch (e) {
77
77
  console.error('> [SslPlugin] Load certificate failed.', e)
78
78
  }
79
79
  } else {
80
- console.log('> [SslPlugin] Certificate disabled, env vars SILEX_SSL_CERTIFICATE and SILEX_SSL_PRIVATE_KEY not set')
80
+ console.info('> [SslPlugin] Certificate disabled, env vars SILEX_SSL_CERTIFICATE and SILEX_SSL_PRIVATE_KEY not set')
81
81
  }
82
82
  app.use(router)
83
83
  })
@@ -48,6 +48,9 @@ export default async function(config, opts = {}) {
48
48
  }, {
49
49
  route: '/',
50
50
  path: join(__dirname, '../../../../..', 'dist', 'client'),
51
+ }, {
52
+ route: '/',
53
+ path: join(__dirname, '../../../../..', 'dist', 'plugins', 'client'),
51
54
  },
52
55
  ]
53
56
  // add project route for source maps
@@ -57,6 +60,7 @@ export default async function(config, opts = {}) {
57
60
  }] : []),
58
61
  ...opts,
59
62
  }
63
+ console.info('> [StaticPlugin] Serving static files')
60
64
 
61
65
  config.on(ServerEvent.STARTUP_START, ({app}) => {
62
66
  const router = express.Router()
@@ -103,7 +103,7 @@ export class ServerConfig extends Config {
103
103
  async addRoutes(app: Application) {
104
104
  const path = process.env.SILEX_CLIENT_CONFIG
105
105
  if (path) {
106
- console.log(`> Serving client side config ${path} at ${CLIENT_CONFIG_FILE_NAME}`)
106
+ console.info(`> Serving client side config ${path} at ${CLIENT_CONFIG_FILE_NAME}`)
107
107
  try {
108
108
  // Load the client config file
109
109
  let clientConfig = (await readFile(path as string)).toString()
@@ -111,7 +111,7 @@ export class ServerConfig extends Config {
111
111
  app.get(`/${CLIENT_CONFIG_FILE_NAME}`, async (req: Request, res: Response) => {
112
112
  // Reload each time in debug mode
113
113
  if (this.debug) {
114
- console.log('[Debug mode] Reloading config file', path)
114
+ console.info('[Debug mode] Reloading config file', path)
115
115
  clientConfig = (await readFile(path)).toString()
116
116
  }
117
117
  // Send the config file
@@ -143,7 +143,7 @@ export class ServerConfig extends Config {
143
143
  */
144
144
  async loadUserConfig() {
145
145
  if (this.userConfigPath) {
146
- console.log('> Loading user config', this.userConfigPath)
146
+ console.info('> Loading user config', this.userConfigPath)
147
147
  try {
148
148
  // Initiate the process with the config file which is just another plugin
149
149
  await this.addPlugin(this.userConfigPath, {})
@@ -158,12 +158,11 @@ export class ServerConfig extends Config {
158
158
  * This is the main config file
159
159
  */
160
160
  async loadSilexConfig() {
161
- console.log('> Loading config', this.configFilePath)
161
+ console.info('> Loading config', this.configFilePath)
162
162
  try {
163
163
  // Initiate the process with the config file which is just another plugin
164
164
  await this.addPlugin(this.configFilePath, {})
165
165
  } catch(e) {
166
- console.log(e.requireStack[0])
167
166
  // Check if the error is about the config file not found and not another module not found in the config file
168
167
  if(e.code === 'MODULE_NOT_FOUND' && (!e.requireStack || !e.requireStack.find(path => path === this.configFilePath))) {
169
168
  console.info('> /!\\ Config file not found', this.configFilePath)
@@ -32,7 +32,7 @@ import { fileURLToPath } from 'url'
32
32
  if(!globalThis.__dirname) {
33
33
  // @ts-ignore
34
34
  globalThis.__dirname = dirname(process.cwd() + '/src/ts/server/connectors/FsStorage.ts')
35
- console.log('Redefining __dirname', globalThis.__dirname)
35
+ console.info('Redefining __dirname', globalThis.__dirname)
36
36
  }
37
37
 
38
38
  type FsSession = ConnectorSession
@@ -33,7 +33,7 @@ export function create(config: ServerConfig): Application {
33
33
  // CORS
34
34
  const options = config.expressOptions
35
35
  if (options.cors) {
36
- console.log('> CORS are ENABLED:', options.cors)
36
+ console.info('> CORS are ENABLED:', options.cors)
37
37
  app.use(cors({
38
38
  origin: options.cors,
39
39
  }))
@@ -45,7 +45,7 @@ export function create(config: ServerConfig): Application {
45
45
  app.use(bodyParser.json({ limit: options.jsonLimit }))
46
46
  app.use(bodyParser.text({ limit: options.textLimit }))
47
47
  app.use(bodyParser.urlencoded({ limit: options.urlencodedLimit }))
48
- console.log('> Session name:', options.sessionName)
48
+ console.info('> Session name:', options.sessionName)
49
49
  app.use(cookieParser() as any)
50
50
  app.use(session({
51
51
  name: options.sessionName,
@@ -1,2 +0,0 @@
1
- declare const _default: (config: any, opts?: any) => void;
2
- export default _default;
@@ -1,39 +0,0 @@
1
- import { ClientEvent } from '../events'
2
- import { websiteMetaRead } from '../api'
3
- import { WebsiteMeta, WebsiteMetaFileContent } from '../../types'
4
-
5
- export default (config, opts: any = {}) => {
6
- config.on(ClientEvent.STARTUP_END, async ({ editor }) => {
7
- console.log('websiteMetaPlugin STARTUP')
8
- console.log('websiteMetaPlugin storage:end:load')
9
- // Get website meta data
10
- const websiteMeta = await websiteMetaRead({websiteId: config.websiteId, connectorId: config.connectorId})
11
- // Display in the editor
12
- displayWebsiteMeta(editor, websiteMeta)
13
- editor.on('storage:end:load', async () => {
14
- })
15
- })
16
- }
17
-
18
- function displayWebsiteMeta(editor, websiteMeta: WebsiteMeta) {
19
- // Check if the container exists in the UI
20
- let container = document.querySelector('.gjs-website-meta')
21
- if(!container) {
22
- // Create the container
23
- container = document.createElement('div')
24
- container.classList.add('gjs-website-meta')
25
- // Add the container to the UI
26
- editor.Panels.add('gjs-website-meta', {
27
- id: 'gjs-website-meta',
28
- el: container,
29
- visible: true,
30
- })
31
- }
32
- // Display the website meta data
33
- container.innerHTML = `
34
- <div class="gjs-website-meta-title">Website</div>
35
- <div class="gjs-website-meta-name">${websiteMeta.name}</div>
36
- <div class="gjs-website-meta-image" style="background: ${websiteMeta.imageUrl}"></div>
37
- `
38
- console.log('displayWebsiteMeta', websiteMeta, container)
39
- }