@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.
- package/.silex.js +1 -8
- package/CONTRIBUTING.md +48 -25
- package/README.md +94 -0
- package/dist/client/css/admin.css +4 -66
- package/dist/client/js/main.js +45 -95
- package/dist/client/js/main.js.LICENSE.txt +1 -1
- package/dist/constants.js +4 -0
- package/dist/page.js +15 -0
- package/dist/server/cli.js +9 -0
- package/dist/server/config.js +31 -11
- package/dist/server/{start.js → express.js} +1 -1
- package/dist/server/index.js +9 -3
- package/dist/types.js +34 -0
- package/package.json +5 -4
- package/public/silex.js +25 -0
- package/src/example-client-config.js +47 -0
- package/src/plugins/DefaultBackend.js +19 -4
- package/src/plugins/ExpressPlugin.js +9 -0
- package/src/plugins/PublishPlugin.js +4 -4
- package/src/plugins/WebsitePlugin.js +77 -18
- package/src/ts/client/config.ts +20 -2
- package/src/ts/client/grapesjs/blocks.ts +18 -86
- package/src/ts/client/grapesjs/index.ts +22 -8
- package/src/ts/client/grapesjs/internal-links.test.ts +1 -0
- package/src/ts/client/grapesjs/publish.ts +4 -4
- package/src/ts/client/grapesjs/semantic.ts +1 -0
- package/src/ts/client/index.ts +21 -8
- package/src/ts/constants.ts +5 -0
- package/src/ts/server/cli.ts +6 -0
- package/src/ts/server/config.ts +45 -16
- package/src/ts/server/{start.ts → express.ts} +1 -1
- package/src/ts/server/index.ts +9 -2
- package/src/ts/types.ts +6 -12
- package/tsconfig-server-debug.json +2 -2
- package/tsconfig-server-release.json +2 -2
- package/tsconfig.json +2 -2
- package/webpack.config.js +0 -1
- package/public/example-config.js +0 -31
- package/readme.md +0 -51
- /package/dist/{server/events.js → events.js} +0 -0
- /package/src/ts/{server/events.ts → events.ts} +0 -0
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;
|
package/dist/server/cli.js
CHANGED
|
@@ -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");
|
package/dist/server/config.js
CHANGED
|
@@ -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("
|
|
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 });
|
package/dist/server/index.js
CHANGED
|
@@ -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
|
|
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,
|
|
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(`\
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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",
|
package/public/silex.js
ADDED
|
@@ -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
|
-
|
|
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
|
|
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
|
|
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(
|
|
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(
|
|
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
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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]
|
package/src/ts/client/config.ts
CHANGED
|
@@ -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
|
|
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
|
}
|