@silexlabs/silex 3.0.0-alpha.30 → 3.0.0-alpha.32

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 (41) hide show
  1. package/.silex.js +1 -8
  2. package/CONTRIBUTING.md +48 -25
  3. package/README.md +94 -0
  4. package/dist/client/css/admin.css +4 -66
  5. package/dist/client/js/main.js +45 -95
  6. package/dist/client/js/main.js.LICENSE.txt +1 -1
  7. package/dist/constants.js +4 -0
  8. package/dist/page.js +15 -0
  9. package/dist/server/cli.js +9 -0
  10. package/dist/server/config.js +31 -11
  11. package/dist/server/{start.js → express.js} +1 -1
  12. package/dist/server/index.js +9 -3
  13. package/dist/types.js +34 -0
  14. package/package.json +5 -4
  15. package/public/silex.js +25 -0
  16. package/src/example-client-config.js +47 -0
  17. package/src/plugins/DefaultBackend.js +19 -4
  18. package/src/plugins/ExpressPlugin.js +9 -0
  19. package/src/plugins/PublishPlugin.js +4 -4
  20. package/src/plugins/WebsitePlugin.js +77 -18
  21. package/src/ts/client/config.ts +20 -2
  22. package/src/ts/client/grapesjs/blocks.ts +18 -86
  23. package/src/ts/client/grapesjs/index.ts +22 -8
  24. package/src/ts/client/grapesjs/internal-links.test.ts +1 -0
  25. package/src/ts/client/grapesjs/publish.ts +4 -4
  26. package/src/ts/client/grapesjs/semantic.ts +1 -0
  27. package/src/ts/client/index.ts +21 -8
  28. package/src/ts/constants.ts +5 -0
  29. package/src/ts/server/cli.ts +6 -0
  30. package/src/ts/server/config.ts +45 -16
  31. package/src/ts/server/{start.ts → express.ts} +1 -1
  32. package/src/ts/server/index.ts +9 -2
  33. package/src/ts/types.ts +6 -12
  34. package/tsconfig-server-debug.json +2 -2
  35. package/tsconfig-server-release.json +2 -2
  36. package/tsconfig.json +2 -2
  37. package/webpack.config.js +0 -1
  38. package/public/example-config.js +0 -31
  39. package/readme.md +0 -51
  40. /package/dist/{server/events.js → events.js} +0 -0
  41. /package/src/ts/{server/events.ts → events.ts} +0 -0
@@ -23,7 +23,7 @@
23
23
  * Date: 2023-03-08T15:28Z
24
24
  */
25
25
 
26
- /*! @silexlabs/grapesjs-loading - 1.0.7 */
26
+ /*! @silexlabs/grapesjs-loading - 1.0.8 */
27
27
 
28
28
  /*! grapesjs-style-filter - 1.0.1 */
29
29
 
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CLIENT_CONFIG_FILE_NAME = void 0;
4
+ exports.CLIENT_CONFIG_FILE_NAME = 'silex.js';
package/dist/page.js ADDED
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getPageLink = exports.getPageSlug = void 0;
4
+ function getPageSlug(pageName = 'index') {
5
+ return pageName
6
+ .toLowerCase()
7
+ .replace(/[^a-z0-9 -]/g, '')
8
+ .replace(/\s+/g, '-')
9
+ .replace(/-+/g, '-');
10
+ }
11
+ exports.getPageSlug = getPageSlug;
12
+ function getPageLink(pageName = 'index') {
13
+ return `./${getPageSlug(pageName)}.html`;
14
+ }
15
+ exports.getPageLink = getPageLink;
@@ -12,6 +12,9 @@ const options = (0, cli_1.parse)({
12
12
  'ssl-certificate': [false, 'Path to SSL certificate', 'file'],
13
13
  'force-https-trust-xfp-header': [false, 'Sets the trustXFPHeader param of the express module "cookie-session". Use only with --force-https', 'boolean'],
14
14
  'session-secret': ['s', 'Session secret', 'string'],
15
+ 'cors-url': ['', 'Enable CORS for URL (can be "*")', 'string'],
16
+ 'client-config': ['', 'Path to client config file to be served on .silex-client.js', 'string'],
17
+ 'fs-root': ['', 'Path to the root folder where to store websites. Used by the default backend (fs).', 'string'],
15
18
  }, {});
16
19
  if (options.config)
17
20
  process.env.CONFIG = options.config;
@@ -31,4 +34,10 @@ if (options['force-https-trust-xfp-header'])
31
34
  process.env.SILEX_FORCE_HTTPS_TRUST_XFP_HEADER = options['force-https-trust-xfp-header'];
32
35
  if (options['session-secret'])
33
36
  process.env.SILEX_SESSION_SECRET = options['session-secret'];
37
+ if (options['cors-url'])
38
+ process.env.SILEX_CORS_URL = options['cors-url'];
39
+ if (options['client-config'])
40
+ process.env.SILEX_CLIENT_CONFIG = options['client-config'];
41
+ if (options['fs-root'])
42
+ process.env.FS_ROOT = options['fs-root'];
34
43
  require("./index");
@@ -3,6 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ServerConfig = void 0;
4
4
  const silex_plugins_1 = require("@silexlabs/silex-plugins");
5
5
  const path_1 = require("path");
6
+ const constants_1 = require("../constants");
7
+ const express_1 = require("express");
8
+ const promises_1 = require("fs/promises");
9
+ const events_1 = require("../events");
6
10
  class ServerConfig extends silex_plugins_1.Config {
7
11
  url;
8
12
  debug;
@@ -20,10 +24,36 @@ exports.ServerConfig = ServerConfig;
20
24
  async function default_1() {
21
25
  const port = process.env.PORT || '6805';
22
26
  const debug = process.env.SILEX_DEBUG === 'true';
27
+ const clientConfigPath = process.env.SILEX_CLIENT_CONFIG;
23
28
  const url = process.env.SERVER_URL || `http://localhost:${port}`;
24
29
  const config = new ServerConfig(url, debug, port, '/api');
30
+ if (clientConfigPath) {
31
+ config.on(events_1.EVENT_STARTUP_START, async ({ app }) => {
32
+ console.log(`> Serving client side config ${clientConfigPath} at ${constants_1.CLIENT_CONFIG_FILE_NAME}`);
33
+ const router = (0, express_1.Router)();
34
+ app.use(router);
35
+ let clientConfig = (await (0, promises_1.readFile)(clientConfigPath)).toString();
36
+ router.get(`/${constants_1.CLIENT_CONFIG_FILE_NAME}`, async (res, req, next) => {
37
+ if (config.debug) {
38
+ console.log('[Debug mode] Reloading config file', clientConfigPath);
39
+ clientConfig = (await (0, promises_1.readFile)(clientConfigPath)).toString();
40
+ }
41
+ req.header('Content-Type', 'application/javascript').send(clientConfig);
42
+ });
43
+ });
44
+ }
45
+ if (process.env.CONFIG) {
46
+ const userConfigPath = process.env.CONFIG;
47
+ console.log('> Loading user config', userConfigPath);
48
+ try {
49
+ await config.addPlugin(userConfigPath, {});
50
+ }
51
+ catch (e) {
52
+ throw new Error(`User config file ${userConfigPath} error: ${e.message}`);
53
+ }
54
+ }
25
55
  const configFilePath = (0, path_1.resolve)(__dirname, '../../.silex.js');
26
- console.log('Loading config', configFilePath);
56
+ console.log('> Loading config', configFilePath);
27
57
  try {
28
58
  await config.addPlugin(configFilePath, {});
29
59
  }
@@ -35,16 +65,6 @@ async function default_1() {
35
65
  throw new Error(`Error in config file ${configFilePath}: ${e.message}`);
36
66
  }
37
67
  }
38
- if (process.env.CONFIG) {
39
- const userConfigPath = process.env.CONFIG;
40
- console.log('Loading user config', userConfigPath);
41
- try {
42
- await config.addPlugin(userConfigPath, {});
43
- }
44
- catch (e) {
45
- throw new Error(`User config file ${userConfigPath} not found: ${e.message}`);
46
- }
47
- }
48
68
  return config;
49
69
  }
50
70
  exports.default = default_1;
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const express_1 = __importDefault(require("express"));
7
- const events_1 = require("./events");
7
+ const events_1 = require("../events");
8
8
  async function default_1(config) {
9
9
  const app = (0, express_1.default)();
10
10
  await config.emit(events_1.EVENT_STARTUP_START, { app });
@@ -27,10 +27,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  const config_1 = __importDefault(require("./config"));
30
- const start_1 = __importDefault(require("./start"));
30
+ const express_1 = __importDefault(require("./express"));
31
+ const config = __importStar(require("./config"));
32
+ const types = __importStar(require("../types"));
33
+ const events = __importStar(require("../events"));
34
+ const constants = __importStar(require("../constants"));
35
+ const page = __importStar(require("../page"));
36
+ exports.default = { config, types, events, constants, page };
31
37
  async function main() {
32
38
  const config = await (0, config_1.default)();
33
- const app = await (0, start_1.default)(config);
39
+ const app = await (0, express_1.default)(config);
34
40
  console.info(`
35
41
  I'm ready, listening to port ${config.port}
36
42
  `);
@@ -46,7 +52,7 @@ async function startLiverReload() {
46
52
  const server = createServer({
47
53
  delay: 0,
48
54
  }, () => {
49
- console.info(`\nDebug mode\nLive reload server is running.\nWatching ${dist}`);
55
+ console.info(`\n> Debug mode\n> Live reload server is running.\n> Watching ${dist}`);
50
56
  });
51
57
  server.watch(dist);
52
58
  }
package/dist/types.js ADDED
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Unit = exports.defaultSite = exports.defaultPublicationSettings = void 0;
4
+ exports.defaultPublicationSettings = {
5
+ path: 'publication',
6
+ url: '',
7
+ autoHomePage: true,
8
+ assets: { path: 'assets', url: '/assets' },
9
+ html: { path: '' },
10
+ css: { path: 'css', url: '/css' },
11
+ };
12
+ exports.defaultSite = {
13
+ pages: [{ name: 'Main', id: 'main', frames: [{ component: { type: 'text', stylable: [] }, components: [] }] }],
14
+ assets: [],
15
+ styles: [],
16
+ name: 'New website',
17
+ settings: {
18
+ description: '',
19
+ title: '',
20
+ head: '',
21
+ lang: '',
22
+ favicon: '',
23
+ 'og:title': '',
24
+ 'og:description': '',
25
+ 'og:image': '',
26
+ },
27
+ fonts: [],
28
+ symbols: [],
29
+ publication: exports.defaultPublicationSettings,
30
+ };
31
+ var Unit;
32
+ (function (Unit) {
33
+ Unit["PX"] = "px";
34
+ })(Unit = exports.Unit || (exports.Unit = {}));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@silexlabs/silex",
3
3
  "description": "Free and easy website builder for everyone.",
4
- "version": "3.0.0-alpha.30",
4
+ "version": "3.0.0-alpha.32",
5
5
  "version:backwardcompat": "3.0.0",
6
6
  "author": {
7
7
  "name": "Alex Hoyau",
@@ -74,21 +74,22 @@
74
74
  "@directus/sdk": "^10.3.3",
75
75
  "@silexlabs/grapesjs-directus-storage": "1.0.15",
76
76
  "@silexlabs/grapesjs-fonts": "1.0.12",
77
- "@silexlabs/grapesjs-loading": "1.0.7",
77
+ "@silexlabs/grapesjs-loading": "1.0.8",
78
78
  "@silexlabs/grapesjs-symbols": "1.0.18",
79
79
  "@silexlabs/grapesjs-ui-suggest-classes": "1.0.23",
80
- "@silexlabs/silex-plugins": "^1.0.6",
80
+ "@silexlabs/silex-plugins": "^1.0.10",
81
81
  "adm-zip": "0.5.10",
82
82
  "body-parser": "1.20.2",
83
83
  "cli": "^1.0.1",
84
84
  "compression": "1.7.4",
85
85
  "cookie-parser": "1.4.6",
86
86
  "cookie-session": "2.0.0",
87
+ "cors": "^2.8.5",
87
88
  "cross-env": "7.0.3",
88
89
  "express": "4.18.2",
89
90
  "express-force-ssl": "0.3.2",
90
91
  "formidable": "2.1.1",
91
- "grapesjs": "0.21.1",
92
+ "grapesjs": "0.21.2",
92
93
  "grapesjs-blocks-basic": "1.0.1",
93
94
  "grapesjs-custom-code": "1.0.1",
94
95
  "grapesjs-plugin-forms": "2.0.5",
@@ -0,0 +1,25 @@
1
+ // This file is loaded by Silex when the user opens the editor
2
+ // Unless you override the default config with the environment variable SILEX_CLIENT_CONFIG or the CLI option --client-config
3
+ export default async function (config) {
4
+ // // For example add a GrapesJs plugin like this
5
+ // config.editor.plugins.push(plugin)
6
+ // config.editor.pluginsOpts[plugin] = {
7
+ // }
8
+ // // Or like this to override the default options
9
+ // // See the docs for the list of options
10
+ // return {
11
+ // ...config,
12
+ // editor: {
13
+ // ...config.editor,
14
+ // plugins: [
15
+ // ...config.editor.plugins,
16
+ // plugin,
17
+ // ],
18
+ // pluginsOpts: {
19
+ // ...config.editor.pluginsOpts,
20
+ // [plugin]: {
21
+ // },
22
+ // },
23
+ // },
24
+ // }
25
+ }
@@ -0,0 +1,47 @@
1
+ import directusStorage from 'https://unpkg.com/@silexlabs/grapesjs-directus-storage'
2
+ console.log('directusStorage', directusStorage, directusStorage?.default)
3
+
4
+ // Use the environment variable SILEX_CLIENT_CONFIG or the CLI option --client-config to override the default config with this file
5
+ export default async function (config, options) {
6
+ console.log('In example config')
7
+ //await config.addPlugin('gjs-blocks-basic', 'https://unpkg.com/grapesjs-blocks-basic', {
8
+ // blocks: ['text', 'image', 'video', 'map'],
9
+ //})
10
+
11
+ // Optional plugins
12
+ await config.addPlugin([
13
+ '@silexlabs/grapesjs-directus-storage',
14
+ './plugins/@silexlabs/grapesjs-directus-storage/dist/index.js',
15
+ ], {
16
+ '@silexlabs/grapesjs-directus-storage': {
17
+ directusUrl: 'http://localhost:8055',
18
+ },
19
+ './plugins/@silexlabs/grapesjs-directus-storage/dist/index.js': {
20
+ directusUrl: 'http://localhost:8055',
21
+ },
22
+ })
23
+
24
+ // Return an object to override default config
25
+ return {
26
+ ...config,
27
+ ...options,
28
+ editor: {
29
+ ...config.editor,
30
+ storageManager: {
31
+ autoload: false,
32
+ type: 'directus',
33
+ },
34
+ plugins: [
35
+ ...config.editor.plugins,
36
+ directusStorage,
37
+ ],
38
+ pluginsOpts: {
39
+ ...config.editor.pluginsOpts,
40
+ [directusStorage]: {
41
+ directusUrl: 'http://localhost:8055',
42
+ },
43
+ },
44
+ },
45
+ }
46
+ }
47
+
@@ -1,4 +1,4 @@
1
- const { readFile, writeFile, mkdir, copyFile } = require('node:fs/promises')
1
+ const { readFile, writeFile, mkdir, copyFile, readdir, stat, rm } = require('node:fs/promises')
2
2
  const { join, dirname, basename } = require('path')
3
3
  const { homedir } = require('os')
4
4
 
@@ -20,8 +20,6 @@ async function mkdirIfNotExists(path, options = null) {
20
20
  const FS_ROOT = process.env.FS_ROOT || join(homedir(), '.silex')
21
21
  const ASSETS_PATH = 'assets'
22
22
  const ASSETS_URL = 'assets'
23
- const HTML_PATH = ''
24
- const CSS_PATH = ''
25
23
  const DATA_FILE_NAME = '/.silex.data.json'
26
24
  const PUBLICATION_PATH = 'publication'
27
25
 
@@ -45,9 +43,26 @@ exports.init = async function (id) {
45
43
  await mkdirIfNotExists(uploadDir, { recursive: true, })
46
44
  }
47
45
 
46
+ exports.del = async function (id) {
47
+ const folder = path(id)
48
+ console.log('Delete', folder)
49
+ await rm(folder, {recursive: true})
50
+ return {ok: true}
51
+ }
52
+
53
+ // List projects
54
+ exports.list = async function () {
55
+ const ids = await readdir(FS_ROOT)
56
+ return Promise.all(ids.map(async id => ({
57
+ id,
58
+ ...await exports.readData(id),
59
+ stats: await stat(path(id) + DATA_FILE_NAME),
60
+ })))
61
+ }
48
62
  // Read project data
49
63
  exports.readData = async function (id) {
50
- return readFile(path(id) + DATA_FILE_NAME)
64
+ const data = await readFile(path(id) + DATA_FILE_NAME)
65
+ return JSON.parse(data.toString())
51
66
  }
52
67
  // Write project data
53
68
  exports.writeData = async function (id, data) {
@@ -2,6 +2,7 @@ const bodyParser = require('body-parser')
2
2
  const compression = require('compression')
3
3
  const cookieParser = require('cookie-parser')
4
4
  const session = require('cookie-session')
5
+ const cors = require('cors')
5
6
 
6
7
  module.exports = async function(config, opts = {}) {
7
8
  // Options with defaults
@@ -10,10 +11,18 @@ module.exports = async function(config, opts = {}) {
10
11
  textLimit: process.env.SILEX_EXPRESS_TEXT_LIMIT || '10mb',
11
12
  sessionName: process.env.SILEX_SESSION_NAME || 'silex-session',
12
13
  sessionSecret: process.env.SILEX_SESSION_SECRET || 'replace this session secret in env vars',
14
+ cors: process.env.SILEX_CORS_URL,
13
15
  ...opts,
14
16
  }
15
17
 
16
18
  config.on('silex:startup:start', ({app}) => {
19
+ // CORS
20
+ if (options.cors) {
21
+ console.log('> CORS are ENABLED:', options.cors)
22
+ app.use(cors({
23
+ origin: options.cors,
24
+ }))
25
+ }
17
26
  // compress gzip when possible
18
27
  app.use(compression())
19
28
 
@@ -28,9 +28,9 @@ module.exports = async function(config, opts = {}) {
28
28
  router.post('/publish', async function(req, res) {
29
29
  const { pages, files, id } = req.body.data
30
30
  if (!pages || !id) {
31
- console.error('Error in the request, pages and id parmas required', {id})
31
+ console.error('Error in the request, pages and id params required', {id})
32
32
  res.status(400).send({
33
- message: 'Error in the request, pages and id parmas required',
33
+ message: 'Error in the request, pages and id params required',
34
34
  })
35
35
  } else {
36
36
  // Optim
@@ -46,7 +46,7 @@ module.exports = async function(config, opts = {}) {
46
46
  }).trim()
47
47
  })
48
48
  // Publication
49
- await config.emit(EVENT_PUBLISH_START, { id, files, req})
49
+ await config.emit('silex:publish:start', { id, files, req})
50
50
  let url
51
51
  try {
52
52
  url = await publish(id, files, req.body.data)
@@ -56,7 +56,7 @@ module.exports = async function(config, opts = {}) {
56
56
  return
57
57
  }
58
58
  const mutable = { id, files, req, res, url, statusUrl: options.statusUrl }
59
- await config.emit(EVENT_PUBLISH_END, mutable)
59
+ await config.emit('silex:publish:end', mutable)
60
60
  res.json({
61
61
  url: mutable.url,
62
62
  statusUrl: mutable.statusUrl,
@@ -3,9 +3,12 @@ const { resolve } = require('path')
3
3
  const formidable = require('formidable')
4
4
 
5
5
  const { noCache } = require('./Cache')
6
+ const { defaultSite } = require('@silexlabs/silex').default.types
6
7
 
7
8
  const EVENT_READ_START = 'EVENT_READ_START'
8
9
  const EVENT_READ_END = 'EVENT_READ_END'
10
+ const EVENT_DELETE_START = 'EVENT_WRITE_START'
11
+ const EVENT_DELETE_END = 'EVENT_WRITE_END'
9
12
  const EVENT_WRITE_START = 'EVENT_WRITE_START'
10
13
  const EVENT_WRITE_END = 'EVENT_WRITE_END'
11
14
  const EVENT_ASSET_READ_START = 'EVENT_ASSET_READ_START'
@@ -18,13 +21,15 @@ module.exports = async function(config, opts = {}) {
18
21
  const options = {
19
22
  // Defaults
20
23
  backend: 'src/plugins/DefaultBackend.js',
24
+ // Default data for new websites
25
+ defaultSite,
21
26
  // Options
22
27
  ...opts
23
28
  }
24
29
 
25
30
  // Link to the desired backend
26
31
  const backend = resolve(__dirname, '../..', options.backend)
27
- const { assetsDir, assetUrl, init, writeData, readData } = require(backend)
32
+ const { assetsDir, assetUrl, init, writeData, readData, list, del } = require(backend)
28
33
 
29
34
  config.on('silex:startup:start', ({app}) => {
30
35
  const router = Router()
@@ -32,6 +37,7 @@ module.exports = async function(config, opts = {}) {
32
37
  // website specials
33
38
  router.get('/website', readWebsite)
34
39
  router.post('/website', writeWebsite)
40
+ router.delete('/website', deleteWebsite)
35
41
  router.get(/\/assets\/(.*)/, readAsset)
36
42
  router.post('/assets', writeAsset)
37
43
 
@@ -39,21 +45,40 @@ module.exports = async function(config, opts = {}) {
39
45
  })
40
46
 
41
47
  async function readWebsite(req, res) {
42
- const id = req.query.id
43
- config.emit(EVENT_READ_START, { req, id })
44
- try {
45
- const data = await readData(id)
46
- config.emit(EVENT_READ_END, { req, res, data, id })
47
- res
48
- .type('application/json')
49
- .send(data)
50
- } catch (err) {
51
- if(err.code === 'ENOENT') {
52
- console.error('Read file error, website does not exist', err)
53
- res.status(404).json({ message: 'Read file error, website does not exist: ' + err.message, code: err.code})
54
- } else {
55
- console.error('Read file error', err)
56
- res.status(400).json({ message: 'Read file error: ' + err.message, code: err.code})
48
+ const { id } = req.query
49
+ if(id) {
50
+ // Returns a website data
51
+ try {
52
+ config.emit(EVENT_READ_START, { req, id })
53
+ const data = await readData(id)
54
+ config.emit(EVENT_READ_END, { req, res, data, id })
55
+ res
56
+ .type('application/json')
57
+ .send({
58
+ ...options.defaultSite,
59
+ ...data,
60
+ })
61
+ } catch (err) {
62
+ if(err.code === 'ENOENT') {
63
+ console.error('Read file error, website does not exist', err)
64
+ res.status(404).json({ message: 'Read file error, website does not exist: ' + err.message, code: err.code})
65
+ } else {
66
+ console.error('Read file error', err)
67
+ res.status(400).json({ message: err.message, code: err.code})
68
+ }
69
+ }
70
+ } else {
71
+ // list websites
72
+ try {
73
+ config.emit(EVENT_READ_START, { req, id })
74
+ const data = await list()
75
+ config.emit(EVENT_READ_END, { req, res, data, id })
76
+ res
77
+ .type('application/json')
78
+ .send(data)
79
+ } catch (err) {
80
+ console.error('List sites error', err)
81
+ res.status(400).json({ message: err.message, code: err.code })
57
82
  }
58
83
  }
59
84
  }
@@ -79,8 +104,6 @@ module.exports = async function(config, opts = {}) {
79
104
 
80
105
  async function writeWebsite(req, res) {
81
106
  const id = req.query.id
82
- await init(id)
83
-
84
107
  const [data, err] = fromBody(req.body)
85
108
  if(err) {
86
109
  res.status(400).json({ message: 'Error writing data file, could not parse the provided body: ' + err.message, code: err.code})
@@ -88,6 +111,7 @@ module.exports = async function(config, opts = {}) {
88
111
  }
89
112
  config.emit(EVENT_WRITE_START, { req, id, data })
90
113
  try {
114
+ await init(id)
91
115
  await writeData(id, data)
92
116
  } catch (err) {
93
117
  console.error('Error writing data file', err)
@@ -102,6 +126,41 @@ module.exports = async function(config, opts = {}) {
102
126
  })
103
127
  }
104
128
 
129
+ async function deleteWebsite(req, res) {
130
+ const { id } = req.query
131
+ if(id) {
132
+ try {
133
+ config.emit(EVENT_DELETE_START, { req, id })
134
+ const data = await del(id)
135
+ config.emit(EVENT_DELETE_END, { req, res, data, id })
136
+ res
137
+ .type('application/json')
138
+ .send(data)
139
+ } catch (err) {
140
+ if(err.code === 'ENOENT') {
141
+ console.error('Delete file error, website does not exist', err)
142
+ res.status(404).json({ message: 'Delete file error, website does not exist: ' + err.message, code: err.code})
143
+ } else {
144
+ console.error('Delete file error', err)
145
+ res.status(400).json({ message: err.message, code: err.code})
146
+ }
147
+ }
148
+ } else {
149
+ // list websites
150
+ try {
151
+ config.emit(EVENT_DELETE_START, { req, id })
152
+ const data = await list()
153
+ config.emit(EVENT_DELETE_END, { req, res, data, id })
154
+ res
155
+ .type('application/json')
156
+ .send(data)
157
+ } catch (err) {
158
+ console.error('List sites error', err)
159
+ res.status(400).json({ message: err.message, code: err.code })
160
+ }
161
+ }
162
+ }
163
+
105
164
  async function readAsset(req, res) {
106
165
  const id = req.query.id
107
166
  const fileName = req.params[0]
@@ -1,12 +1,14 @@
1
- import { Config } from '@silexlabs/silex-plugins'
1
+ import { Config, Plugin } from '@silexlabs/silex-plugins'
2
2
  import { getEditorConfig } from './grapesjs'
3
+ import { CLIENT_CONFIG_FILE_NAME } from '../constants'
3
4
 
4
5
  /**
5
6
  * @fileoverview Silex client side config
6
7
  */
7
8
 
8
9
  const id = new URL(location.href).searchParams.get('id') || 'default'
9
- const rootUrl = '.'
10
+ const lang = new URL(location.href).searchParams.get('lang') || 'en'
11
+ const rootUrl = `${location.protocol}//${location.host}${location.pathname}`
10
12
 
11
13
  export class SilexConfig extends Config {
12
14
  /**
@@ -14,8 +16,24 @@ export class SilexConfig extends Config {
14
16
  */
15
17
  debug = false
16
18
 
19
+ /**
20
+ * language for I18n module
21
+ */
22
+ lang = lang
23
+
17
24
  /**
18
25
  * Grapesjs config
19
26
  */
20
27
  editor = getEditorConfig(id, rootUrl)
28
+
29
+ /**
30
+ * Client config url
31
+ * This is the url of the config file which is a plugin
32
+ */
33
+ clientConfigUrl = `${rootUrl}${CLIENT_CONFIG_FILE_NAME}`
34
+
35
+ /**
36
+ * GrapesJs plugins
37
+ */
38
+ grapesJsPlugins: Plugin[] = []
21
39
  }