@akemona-org/strapi 3.7.0
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/LICENSE +22 -0
- package/README.md +163 -0
- package/bin/strapi.js +239 -0
- package/index.d.ts +13 -0
- package/lib/Strapi.js +498 -0
- package/lib/commands/admin-reset.js +51 -0
- package/lib/commands/build.js +47 -0
- package/lib/commands/configurationDump.js +50 -0
- package/lib/commands/configurationRestore.js +160 -0
- package/lib/commands/console.js +26 -0
- package/lib/commands/develop.js +155 -0
- package/lib/commands/generate-template.js +97 -0
- package/lib/commands/generate.js +66 -0
- package/lib/commands/install.js +48 -0
- package/lib/commands/new.js +11 -0
- package/lib/commands/start.js +8 -0
- package/lib/commands/uninstall.js +68 -0
- package/lib/commands/watchAdmin.js +35 -0
- package/lib/core/app-configuration/config-loader.js +56 -0
- package/lib/core/app-configuration/config-provider.js +28 -0
- package/lib/core/app-configuration/index.js +99 -0
- package/lib/core/bootstrap.js +166 -0
- package/lib/core/fs.js +52 -0
- package/lib/core/index.js +21 -0
- package/lib/core/load-admin.js +36 -0
- package/lib/core/load-apis.js +22 -0
- package/lib/core/load-components.js +43 -0
- package/lib/core/load-extensions.js +71 -0
- package/lib/core/load-functions.js +21 -0
- package/lib/core/load-hooks.js +117 -0
- package/lib/core/load-middlewares.js +130 -0
- package/lib/core/load-modules.js +61 -0
- package/lib/core/load-plugins.js +68 -0
- package/lib/core/load-policies.js +36 -0
- package/lib/core/walk.js +27 -0
- package/lib/core-api/controller.js +158 -0
- package/lib/core-api/index.js +33 -0
- package/lib/core-api/service/collection-type.js +122 -0
- package/lib/core-api/service/index.js +81 -0
- package/lib/core-api/service/single-type.js +68 -0
- package/lib/hooks/index.js +97 -0
- package/lib/index.js +3 -0
- package/lib/load/check-reserved-filename.js +18 -0
- package/lib/load/filepath-to-prop-path.js +22 -0
- package/lib/load/glob.js +15 -0
- package/lib/load/index.js +9 -0
- package/lib/load/load-config-files.js +22 -0
- package/lib/load/load-files.js +56 -0
- package/lib/load/package-path.js +9 -0
- package/lib/load/require-file-parse.js +15 -0
- package/lib/middlewares/boom/defaults.json +5 -0
- package/lib/middlewares/boom/index.js +147 -0
- package/lib/middlewares/cors/index.js +66 -0
- package/lib/middlewares/cron/defaults.json +5 -0
- package/lib/middlewares/cron/index.js +43 -0
- package/lib/middlewares/csp/defaults.json +5 -0
- package/lib/middlewares/csp/index.js +26 -0
- package/lib/middlewares/favicon/defaults.json +7 -0
- package/lib/middlewares/favicon/index.js +35 -0
- package/lib/middlewares/gzip/defaults.json +6 -0
- package/lib/middlewares/gzip/index.js +19 -0
- package/lib/middlewares/hsts/defaults.json +7 -0
- package/lib/middlewares/hsts/index.js +30 -0
- package/lib/middlewares/index.js +120 -0
- package/lib/middlewares/ip/defaults.json +7 -0
- package/lib/middlewares/ip/index.js +25 -0
- package/lib/middlewares/language/defaults.json +9 -0
- package/lib/middlewares/language/index.js +40 -0
- package/lib/middlewares/logger/defaults.json +8 -0
- package/lib/middlewares/logger/index.js +63 -0
- package/lib/middlewares/p3p/defaults.json +6 -0
- package/lib/middlewares/p3p/index.js +29 -0
- package/lib/middlewares/parser/defaults.json +10 -0
- package/lib/middlewares/parser/index.js +71 -0
- package/lib/middlewares/poweredBy/defaults.json +5 -0
- package/lib/middlewares/poweredBy/index.js +16 -0
- package/lib/middlewares/public/assets/images/group_people_1.png +0 -0
- package/lib/middlewares/public/assets/images/group_people_2.png +0 -0
- package/lib/middlewares/public/assets/images/group_people_3.png +0 -0
- package/lib/middlewares/public/assets/images/logo_login.png +0 -0
- package/lib/middlewares/public/defaults.json +8 -0
- package/lib/middlewares/public/index.html +66 -0
- package/lib/middlewares/public/index.js +98 -0
- package/lib/middlewares/public/serve-static.js +23 -0
- package/lib/middlewares/responseTime/defaults.json +5 -0
- package/lib/middlewares/responseTime/index.js +25 -0
- package/lib/middlewares/responses/defaults.json +5 -0
- package/lib/middlewares/responses/index.js +18 -0
- package/lib/middlewares/router/defaults.json +7 -0
- package/lib/middlewares/router/index.js +64 -0
- package/lib/middlewares/router/utils/composeEndpoint.js +25 -0
- package/lib/middlewares/router/utils/routerChecker.js +92 -0
- package/lib/middlewares/session/defaults.json +18 -0
- package/lib/middlewares/session/index.js +140 -0
- package/lib/middlewares/xframe/defaults.json +6 -0
- package/lib/middlewares/xframe/index.js +33 -0
- package/lib/middlewares/xss/defaults.json +6 -0
- package/lib/middlewares/xss/index.js +30 -0
- package/lib/services/core-store.js +144 -0
- package/lib/services/entity-service.js +260 -0
- package/lib/services/entity-validator/index.js +199 -0
- package/lib/services/entity-validator/validators.js +125 -0
- package/lib/services/event-hub.js +15 -0
- package/lib/services/metrics/index.js +103 -0
- package/lib/services/metrics/is-truthy.js +9 -0
- package/lib/services/metrics/middleware.js +33 -0
- package/lib/services/metrics/rate-limiter.js +27 -0
- package/lib/services/metrics/sender.js +76 -0
- package/lib/services/metrics/stringify-deep.js +22 -0
- package/lib/services/utils/upload-files.js +70 -0
- package/lib/services/webhook-runner.js +159 -0
- package/lib/services/webhook-store.js +97 -0
- package/lib/services/worker-queue.js +58 -0
- package/lib/utils/addSlash.js +10 -0
- package/lib/utils/ee.js +123 -0
- package/lib/utils/get-prefixed-dependencies.js +7 -0
- package/lib/utils/index.js +25 -0
- package/lib/utils/openBrowser.js +145 -0
- package/lib/utils/resources/key.pub +9 -0
- package/lib/utils/resources/openChrome.applescript +83 -0
- package/lib/utils/run-checks.js +37 -0
- package/lib/utils/success.js +31 -0
- package/lib/utils/update-notifier/index.js +96 -0
- package/lib/utils/url-from-segments.js +13 -0
- package/package.json +143 -0
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const _ = require('lodash');
|
|
5
|
+
const strapi = require('../index');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Will restore configurations. It reads from a file or stdin
|
|
9
|
+
* @param {string} file filepath to use as input
|
|
10
|
+
* @param {string} strategy import strategy. one of (replace, merge, keep, default: replace)
|
|
11
|
+
*/
|
|
12
|
+
module.exports = async function({ file: filePath, strategy = 'replace' }) {
|
|
13
|
+
const input = filePath ? fs.readFileSync(filePath) : await readStdin(process.stdin);
|
|
14
|
+
|
|
15
|
+
const app = await strapi().load();
|
|
16
|
+
|
|
17
|
+
let dataToImport;
|
|
18
|
+
try {
|
|
19
|
+
dataToImport = JSON.parse(input);
|
|
20
|
+
} catch (error) {
|
|
21
|
+
throw new Error(`Invalid input data: ${error.message}. Expected a valid JSON array.`);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (!Array.isArray(dataToImport)) {
|
|
25
|
+
throw new Error(`Invalid input data. Expected a valid JSON array.`);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const importer = createImporter(app.db, strategy);
|
|
29
|
+
|
|
30
|
+
for (const config of dataToImport) {
|
|
31
|
+
await importer.import(config);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
console.log(
|
|
35
|
+
`Successfully imported configuration with ${strategy} strategy. Statistics: ${importer.printStatistics()}.`
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
process.exit(0);
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const readStdin = () => {
|
|
42
|
+
const { stdin } = process;
|
|
43
|
+
let result = '';
|
|
44
|
+
|
|
45
|
+
if (stdin.isTTY) return Promise.resolve(result);
|
|
46
|
+
|
|
47
|
+
return new Promise((resolve, reject) => {
|
|
48
|
+
stdin.setEncoding('utf8');
|
|
49
|
+
stdin.on('readable', () => {
|
|
50
|
+
let chunk;
|
|
51
|
+
while ((chunk = stdin.read())) {
|
|
52
|
+
result += chunk;
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
stdin.on('end', () => {
|
|
57
|
+
resolve(result);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
stdin.on('error', reject);
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const createImporter = (db, strategy) => {
|
|
65
|
+
switch (strategy) {
|
|
66
|
+
case 'replace':
|
|
67
|
+
return createReplaceImporter(db);
|
|
68
|
+
case 'merge':
|
|
69
|
+
return createMergeImporter(db);
|
|
70
|
+
case 'keep':
|
|
71
|
+
return createKeepImporter(db);
|
|
72
|
+
default:
|
|
73
|
+
throw new Error(`No importer available for strategy "${strategy}"`);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Replace importer. Will replace the keys that already exist and create the new ones
|
|
79
|
+
* @param {Object} db - DatabaseManager instance
|
|
80
|
+
*/
|
|
81
|
+
const createReplaceImporter = db => {
|
|
82
|
+
const stats = {
|
|
83
|
+
created: 0,
|
|
84
|
+
replaced: 0,
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
return {
|
|
88
|
+
printStatistics() {
|
|
89
|
+
return `${stats.created} created, ${stats.replaced} replaced`;
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
async import(conf) {
|
|
93
|
+
const matching = await db.query('core_store').count({ key: conf.key });
|
|
94
|
+
if (matching > 0) {
|
|
95
|
+
stats.replaced += 1;
|
|
96
|
+
await db.query('core_store').update({ key: conf.key }, conf);
|
|
97
|
+
} else {
|
|
98
|
+
stats.created += 1;
|
|
99
|
+
await db.query('core_store').create(conf);
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Merge importer. Will merge the keys that already exist with their new value and create the new ones
|
|
107
|
+
* @param {Object} db - DatabaseManager instance
|
|
108
|
+
*/
|
|
109
|
+
const createMergeImporter = db => {
|
|
110
|
+
const stats = {
|
|
111
|
+
created: 0,
|
|
112
|
+
merged: 0,
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
return {
|
|
116
|
+
printStatistics() {
|
|
117
|
+
return `${stats.created} created, ${stats.merged} merged`;
|
|
118
|
+
},
|
|
119
|
+
|
|
120
|
+
async import(conf) {
|
|
121
|
+
const existingConf = await db.query('core_store').find({ key: conf.key });
|
|
122
|
+
if (existingConf) {
|
|
123
|
+
stats.merged += 1;
|
|
124
|
+
await db.query('core_store').update({ key: conf.key }, _.merge(existingConf, conf));
|
|
125
|
+
} else {
|
|
126
|
+
stats.created += 1;
|
|
127
|
+
await db.query('core_store').create(conf);
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Merge importer. Will keep the keys that already exist without changing them and create the new ones
|
|
135
|
+
* @param {Object} db - DatabaseManager instance
|
|
136
|
+
*/
|
|
137
|
+
const createKeepImporter = db => {
|
|
138
|
+
const stats = {
|
|
139
|
+
created: 0,
|
|
140
|
+
untouched: 0,
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
return {
|
|
144
|
+
printStatistics() {
|
|
145
|
+
return `${stats.created} created, ${stats.untouched} untouched`;
|
|
146
|
+
},
|
|
147
|
+
|
|
148
|
+
async import(conf) {
|
|
149
|
+
const matching = await db.query('core_store').count({ key: conf.key });
|
|
150
|
+
if (matching > 0) {
|
|
151
|
+
stats.untouched += 1;
|
|
152
|
+
// if configuration already exists do not overwrite it
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
stats.created += 1;
|
|
157
|
+
await db.query('core_store').create(conf);
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const REPL = require('repl');
|
|
4
|
+
const strapi = require('../index');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* `$ strapi console`
|
|
8
|
+
*/
|
|
9
|
+
module.exports = () => {
|
|
10
|
+
// Now load up the Strapi framework for real.
|
|
11
|
+
const app = strapi();
|
|
12
|
+
|
|
13
|
+
app.start(() => {
|
|
14
|
+
const repl = REPL.start(app.config.info.name + ' > ' || 'strapi > '); // eslint-disable-line prefer-template
|
|
15
|
+
|
|
16
|
+
repl.on('exit', function(err) {
|
|
17
|
+
if (err) {
|
|
18
|
+
app.log.error(err);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
app.server.destroy();
|
|
23
|
+
process.exit(0);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
};
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const cluster = require('cluster');
|
|
5
|
+
const fs = require('fs-extra');
|
|
6
|
+
const chokidar = require('chokidar');
|
|
7
|
+
const execa = require('execa');
|
|
8
|
+
|
|
9
|
+
const { logger } = require('@akemona-org/strapi-utils');
|
|
10
|
+
const loadConfiguration = require('../core/app-configuration');
|
|
11
|
+
const strapi = require('../index');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* `$ strapi develop`
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
module.exports = async function ({ build, watchAdmin, polling, browser }) {
|
|
18
|
+
const dir = process.cwd();
|
|
19
|
+
const config = loadConfiguration(dir);
|
|
20
|
+
|
|
21
|
+
const adminWatchIgnoreFiles = config.get('server.admin.watchIgnoreFiles', []);
|
|
22
|
+
const serveAdminPanel = config.get('server.admin.serveAdminPanel', true);
|
|
23
|
+
|
|
24
|
+
const buildExists = fs.existsSync(path.join(dir, 'build'));
|
|
25
|
+
// Don't run the build process if the admin is in watch mode
|
|
26
|
+
if (build && !watchAdmin && serveAdminPanel && !buildExists) {
|
|
27
|
+
try {
|
|
28
|
+
execa.shellSync('npm run -s build -- --no-optimization', {
|
|
29
|
+
stdio: 'inherit',
|
|
30
|
+
});
|
|
31
|
+
} catch (err) {
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
if (cluster.isMaster) {
|
|
38
|
+
if (watchAdmin) {
|
|
39
|
+
try {
|
|
40
|
+
execa('npm', ['run', '-s', 'strapi', 'watch-admin', '--', '--browser', browser], {
|
|
41
|
+
stdio: 'inherit',
|
|
42
|
+
});
|
|
43
|
+
} catch (err) {
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
cluster.on('message', (worker, message) => {
|
|
49
|
+
switch (message) {
|
|
50
|
+
case 'reload':
|
|
51
|
+
logger.info('The server is restarting\n');
|
|
52
|
+
worker.send('isKilled');
|
|
53
|
+
break;
|
|
54
|
+
case 'kill':
|
|
55
|
+
worker.kill();
|
|
56
|
+
cluster.fork();
|
|
57
|
+
break;
|
|
58
|
+
case 'stop':
|
|
59
|
+
worker.kill();
|
|
60
|
+
process.exit(1);
|
|
61
|
+
default:
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
cluster.fork();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (cluster.isWorker) {
|
|
70
|
+
const strapiInstance = strapi({
|
|
71
|
+
dir,
|
|
72
|
+
autoReload: true,
|
|
73
|
+
serveAdminPanel: watchAdmin ? false : true,
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
watchFileChanges({
|
|
77
|
+
dir,
|
|
78
|
+
strapiInstance,
|
|
79
|
+
watchIgnoreFiles: adminWatchIgnoreFiles,
|
|
80
|
+
polling,
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
process.on('message', (message) => {
|
|
84
|
+
switch (message) {
|
|
85
|
+
case 'isKilled':
|
|
86
|
+
strapiInstance.server.destroy(() => {
|
|
87
|
+
process.send('kill');
|
|
88
|
+
});
|
|
89
|
+
break;
|
|
90
|
+
default:
|
|
91
|
+
// Do nothing.
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
return strapiInstance.start();
|
|
96
|
+
}
|
|
97
|
+
} catch (e) {
|
|
98
|
+
logger.error(e);
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Init file watching to auto restart strapi app
|
|
105
|
+
* @param {Object} options - Options object
|
|
106
|
+
* @param {string} options.dir - This is the path where the app is located, the watcher will watch the files under this folder
|
|
107
|
+
* @param {Strapi} options.strapi - Strapi instance
|
|
108
|
+
* @param {array} options.watchIgnoreFiles - Array of custom file paths that should not be watched
|
|
109
|
+
*/
|
|
110
|
+
function watchFileChanges({ dir, strapiInstance, watchIgnoreFiles, polling }) {
|
|
111
|
+
const restart = () => {
|
|
112
|
+
if (strapiInstance.reload.isWatching && !strapiInstance.reload.isReloading) {
|
|
113
|
+
strapiInstance.reload.isReloading = true;
|
|
114
|
+
strapiInstance.reload();
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const watcher = chokidar.watch(dir, {
|
|
119
|
+
ignoreInitial: true,
|
|
120
|
+
usePolling: polling,
|
|
121
|
+
ignored: [
|
|
122
|
+
/(^|[/\\])\../, // dot files
|
|
123
|
+
/tmp/,
|
|
124
|
+
'admin',
|
|
125
|
+
'admin/**',
|
|
126
|
+
'extensions/**/admin',
|
|
127
|
+
'extensions/**/admin/**',
|
|
128
|
+
'**/documentation',
|
|
129
|
+
'**/documentation/**',
|
|
130
|
+
'**/node_modules',
|
|
131
|
+
'**/node_modules/**',
|
|
132
|
+
'**/plugins.json',
|
|
133
|
+
'**/index.html',
|
|
134
|
+
'**/public',
|
|
135
|
+
'**/public/**',
|
|
136
|
+
'**/*.db*',
|
|
137
|
+
'**/exports/**',
|
|
138
|
+
...watchIgnoreFiles,
|
|
139
|
+
],
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
watcher
|
|
143
|
+
.on('add', (path) => {
|
|
144
|
+
strapiInstance.log.info(`File created: ${path}`);
|
|
145
|
+
restart();
|
|
146
|
+
})
|
|
147
|
+
.on('change', (path) => {
|
|
148
|
+
strapiInstance.log.info(`File changed: ${path}`);
|
|
149
|
+
restart();
|
|
150
|
+
})
|
|
151
|
+
.on('unlink', (path) => {
|
|
152
|
+
strapiInstance.log.info(`File deleted: ${path}`);
|
|
153
|
+
restart();
|
|
154
|
+
});
|
|
155
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { resolve, join, basename } = require('path');
|
|
4
|
+
const fse = require('fs-extra');
|
|
5
|
+
const chalk = require('chalk');
|
|
6
|
+
const inquirer = require('inquirer');
|
|
7
|
+
|
|
8
|
+
// All directories that a template could need
|
|
9
|
+
const TEMPLATE_CONTENT = ['api', 'components', 'config/functions/bootstrap.js', 'data'];
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
*
|
|
13
|
+
* @param {string} templatePath Absolute path to template directory
|
|
14
|
+
* @param {string} rootBase Name of the root directory
|
|
15
|
+
*/
|
|
16
|
+
async function copyContent(templatePath, rootBase) {
|
|
17
|
+
for (const item of TEMPLATE_CONTENT) {
|
|
18
|
+
try {
|
|
19
|
+
const pathToCopy = join(process.cwd(), item);
|
|
20
|
+
|
|
21
|
+
if (!(await fse.pathExists(pathToCopy))) {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
await fse.copy(pathToCopy, join(templatePath, item));
|
|
26
|
+
const currentProjectBase = basename(process.cwd());
|
|
27
|
+
console.log(
|
|
28
|
+
`${chalk.green(
|
|
29
|
+
'success'
|
|
30
|
+
)}: copy ${currentProjectBase}/${item} => ${rootBase}/template/${item}`
|
|
31
|
+
);
|
|
32
|
+
} catch (error) {
|
|
33
|
+
console.error(`${chalk.red('error')}: ${error.message}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
*
|
|
40
|
+
* @param {string} rootPath Absolute path to the root directory
|
|
41
|
+
*/
|
|
42
|
+
async function writeTemplateJson(rootPath) {
|
|
43
|
+
try {
|
|
44
|
+
await fse.writeJSON(join(rootPath, 'template.json'), {});
|
|
45
|
+
console.log(`${chalk.green('success')}: create JSON config file`);
|
|
46
|
+
} catch (error) {
|
|
47
|
+
console.error(`${chalk.red('error')}: ${error.message}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
*
|
|
53
|
+
* @param {string} rootPath Absolute path to the root directory
|
|
54
|
+
* @returns boolean
|
|
55
|
+
*/
|
|
56
|
+
async function templateConfigExists(rootPath) {
|
|
57
|
+
const jsonConfig = await fse.pathExists(join(rootPath, 'template.json'));
|
|
58
|
+
const functionConfig = await fse.pathExists(join(rootPath, 'template.js'));
|
|
59
|
+
|
|
60
|
+
return jsonConfig || functionConfig;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
module.exports = async function generateTemplate(directory) {
|
|
64
|
+
const rootPath = resolve(directory);
|
|
65
|
+
|
|
66
|
+
// Get path to template directory: <rootPath>/template
|
|
67
|
+
const templatePath = join(rootPath, 'template');
|
|
68
|
+
|
|
69
|
+
// Check if the template directory exists
|
|
70
|
+
const exists = await fse.pathExists(templatePath);
|
|
71
|
+
const rootBase = basename(rootPath);
|
|
72
|
+
|
|
73
|
+
if (exists) {
|
|
74
|
+
// Confirm the user wants to replace the existing template
|
|
75
|
+
const inquiry = await inquirer.prompt({
|
|
76
|
+
type: 'confirm',
|
|
77
|
+
name: 'confirm',
|
|
78
|
+
message: `${chalk.yellow(rootBase)} already exists. Do you want to replace it?`,
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
if (!inquiry.confirm) {
|
|
82
|
+
process.exit(0);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Create or replace root directory with <roothPath>/template
|
|
87
|
+
await fse.ensureDir(templatePath);
|
|
88
|
+
// Copy content to /template
|
|
89
|
+
await copyContent(templatePath, rootBase);
|
|
90
|
+
// Create config file if it doesn't exist
|
|
91
|
+
const configExists = await templateConfigExists(rootPath);
|
|
92
|
+
if (!configExists) {
|
|
93
|
+
await writeTemplateJson(rootPath);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
console.log(`${chalk.green('success')}: generated template at ${chalk.yellow(rootPath)}`);
|
|
97
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Module dependencies
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Node.js core.
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
// Master of ceremonies for generators.
|
|
11
|
+
const generate = require('@akemona-org/strapi-generate');
|
|
12
|
+
|
|
13
|
+
// Logger.
|
|
14
|
+
const { logger } = require('@akemona-org/strapi-utils');
|
|
15
|
+
|
|
16
|
+
// Local Strapi dependencies.
|
|
17
|
+
const packageJSON = require('../../package.json');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* `$ strapi generate`
|
|
21
|
+
*
|
|
22
|
+
* Scaffolding for the application in our working directory.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
module.exports = function (id, cliArguments) {
|
|
26
|
+
// Build initial scope.
|
|
27
|
+
const scope = {
|
|
28
|
+
rootPath: process.cwd(),
|
|
29
|
+
strapiRoot: path.resolve(__dirname, '..'),
|
|
30
|
+
id: id,
|
|
31
|
+
args: cliArguments,
|
|
32
|
+
strapiPackageJSON: packageJSON,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
scope.generatorType = process.argv[2].split(':')[1];
|
|
36
|
+
|
|
37
|
+
// Show usage if no generator type is defined.
|
|
38
|
+
if (!scope.generatorType) {
|
|
39
|
+
return logger.error('Write `$ strapi generate:something` instead.');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return generate(scope, {
|
|
43
|
+
// Log and exit the REPL in case there is an error
|
|
44
|
+
// while we were trying to generate the requested generator.
|
|
45
|
+
error(msg) {
|
|
46
|
+
logger.error(msg);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
// Log and exit the REPL in case of success
|
|
51
|
+
// but first make sure we have all the info we need.
|
|
52
|
+
success() {
|
|
53
|
+
if (!scope.outputPath && scope.filename && scope.destDir) {
|
|
54
|
+
scope.outputPath = scope.destDir + scope.filename;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (scope.generatorType !== 'new') {
|
|
58
|
+
logger.info(
|
|
59
|
+
`Generated a new ${scope.generatorType} \`${scope.name}\` at \`${scope.filePath}\`.`
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
process.exit(0);
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { join } = require('path');
|
|
4
|
+
const { existsSync } = require('fs-extra');
|
|
5
|
+
const ora = require('ora');
|
|
6
|
+
const execa = require('execa');
|
|
7
|
+
const findPackagePath = require('../load/package-path');
|
|
8
|
+
|
|
9
|
+
module.exports = async plugins => {
|
|
10
|
+
const loader = ora();
|
|
11
|
+
const dir = process.cwd();
|
|
12
|
+
|
|
13
|
+
const version = require(join(dir, 'package.json')).dependencies.strapi;
|
|
14
|
+
|
|
15
|
+
const pluginArgs = plugins.map(name => `strapi-plugin-${name}@${version}`);
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
loader.start(`Installing dependencies`);
|
|
19
|
+
|
|
20
|
+
const useYarn = existsSync(join(dir, 'yarn.lock'));
|
|
21
|
+
if (useYarn) {
|
|
22
|
+
await execa('yarn', ['add', ...pluginArgs]);
|
|
23
|
+
} else {
|
|
24
|
+
await execa('npm', ['install', '--save', ...pluginArgs]);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
loader.succeed();
|
|
28
|
+
|
|
29
|
+
// check if rebuild is necessary
|
|
30
|
+
let shouldRebuild = false;
|
|
31
|
+
for (let name of plugins) {
|
|
32
|
+
let pkgPath = findPackagePath(`strapi-plugin-${name}`);
|
|
33
|
+
if (existsSync(join(pkgPath, 'admin', 'src', 'index.js'))) {
|
|
34
|
+
shouldRebuild = true;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (shouldRebuild) {
|
|
39
|
+
loader.start(`Rebuilding admin UI`);
|
|
40
|
+
await execa('npm', ['run', 'build']);
|
|
41
|
+
loader.succeed();
|
|
42
|
+
}
|
|
43
|
+
} catch (err) {
|
|
44
|
+
loader.clear();
|
|
45
|
+
console.error(err.message);
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { join } = require('path');
|
|
4
|
+
const { existsSync, removeSync } = require('fs-extra');
|
|
5
|
+
const ora = require('ora');
|
|
6
|
+
const execa = require('execa');
|
|
7
|
+
const inquirer = require('inquirer');
|
|
8
|
+
const findPackagePath = require('../load/package-path');
|
|
9
|
+
|
|
10
|
+
module.exports = async (plugins, { deleteFiles }) => {
|
|
11
|
+
const answers = await inquirer.prompt([
|
|
12
|
+
{
|
|
13
|
+
type: 'confirm',
|
|
14
|
+
name: 'deleteFiles',
|
|
15
|
+
message: `Do you want to delete the plugin generated files in the extensions folder ?`,
|
|
16
|
+
default: true,
|
|
17
|
+
when: !deleteFiles,
|
|
18
|
+
},
|
|
19
|
+
]);
|
|
20
|
+
|
|
21
|
+
const loader = ora();
|
|
22
|
+
const dir = process.cwd();
|
|
23
|
+
|
|
24
|
+
const pluginArgs = plugins.map(name => `strapi-plugin-${name}`);
|
|
25
|
+
|
|
26
|
+
try {
|
|
27
|
+
// verify should rebuild before removing the pacakge
|
|
28
|
+
let shouldRebuild = false;
|
|
29
|
+
for (let name of plugins) {
|
|
30
|
+
let pkgPath = findPackagePath(`strapi-plugin-${name}`);
|
|
31
|
+
if (existsSync(join(pkgPath, 'admin', 'src', 'index.js'))) {
|
|
32
|
+
shouldRebuild = true;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
loader.start(`Uninstalling dependencies`);
|
|
37
|
+
|
|
38
|
+
const useYarn = existsSync(join(dir, 'yarn.lock'));
|
|
39
|
+
if (useYarn) {
|
|
40
|
+
await execa('yarn', ['remove', ...pluginArgs]);
|
|
41
|
+
} else {
|
|
42
|
+
await execa('npm', ['remove', ...pluginArgs]);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
loader.succeed();
|
|
46
|
+
|
|
47
|
+
if (deleteFiles === true || answers.deleteFiles === true) {
|
|
48
|
+
loader.start('Deleting old files');
|
|
49
|
+
for (let name of plugins) {
|
|
50
|
+
const pluginDir = join(dir, 'extensions', name);
|
|
51
|
+
if (existsSync(pluginDir)) {
|
|
52
|
+
removeSync(pluginDir);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
loader.succeed();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (shouldRebuild) {
|
|
59
|
+
loader.start(`Rebuilding admin UI`);
|
|
60
|
+
await execa('npm', ['run', 'build']);
|
|
61
|
+
loader.succeed();
|
|
62
|
+
}
|
|
63
|
+
} catch (err) {
|
|
64
|
+
loader.clear();
|
|
65
|
+
console.error(err.message);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line node/no-extraneous-require
|
|
4
|
+
const strapiAdmin = require('@akemona-org/strapi-admin');
|
|
5
|
+
const { getConfigUrls, getAbsoluteServerUrl } = require('@akemona-org/strapi-utils');
|
|
6
|
+
const loadConfiguration = require('../core/app-configuration');
|
|
7
|
+
const ee = require('../utils/ee');
|
|
8
|
+
const addSlash = require('../utils/addSlash');
|
|
9
|
+
|
|
10
|
+
module.exports = async function ({ browser }) {
|
|
11
|
+
const dir = process.cwd();
|
|
12
|
+
|
|
13
|
+
const config = loadConfiguration(dir);
|
|
14
|
+
|
|
15
|
+
const { adminPath } = getConfigUrls(config.get('server'), true);
|
|
16
|
+
|
|
17
|
+
const adminPort = config.get('server.admin.port', 8000);
|
|
18
|
+
const adminHost = config.get('server.admin.host', 'localhost');
|
|
19
|
+
const adminWatchIgnoreFiles = config.get('server.admin.watchIgnoreFiles', []);
|
|
20
|
+
|
|
21
|
+
ee({ dir });
|
|
22
|
+
|
|
23
|
+
strapiAdmin.watchAdmin({
|
|
24
|
+
dir,
|
|
25
|
+
port: adminPort,
|
|
26
|
+
host: adminHost,
|
|
27
|
+
browser,
|
|
28
|
+
options: {
|
|
29
|
+
backend: getAbsoluteServerUrl(config, true),
|
|
30
|
+
publicPath: addSlash(adminPath),
|
|
31
|
+
watchIgnoreFiles: adminWatchIgnoreFiles,
|
|
32
|
+
features: ee.isEE ? ee.features.getEnabled() : [],
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
};
|