@strapi/strapi 4.2.0-beta.0 → 4.2.0-beta.3
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/README.md +2 -3
- package/bin/strapi.js +7 -0
- package/lib/Strapi.js +22 -4
- package/lib/commands/admin-create.js +15 -1
- package/lib/commands/admin-reset.js +15 -1
- package/lib/commands/build.js +4 -5
- package/lib/commands/builders/admin.js +4 -3
- package/lib/commands/builders/typescript.js +3 -6
- package/lib/commands/configurationDump.js +14 -1
- package/lib/commands/configurationRestore.js +16 -1
- package/lib/commands/console.js +16 -2
- package/lib/commands/develop.js +10 -4
- package/lib/commands/opt-out-telemetry.js +83 -0
- package/lib/commands/routes/list.js +15 -1
- package/lib/commands/start.js +12 -2
- package/lib/commands/watchAdmin.js +3 -4
- package/lib/core/app-configuration/index.js +5 -3
- package/lib/core/bootstrap.js +9 -1
- package/lib/core/loaders/apis.js +13 -9
- package/lib/core/loaders/index.js +1 -0
- package/lib/core/loaders/plugins/get-enabled-plugins.js +1 -6
- package/lib/core/loaders/sanitizers.js +5 -0
- package/lib/core/registries/policies.d.ts +1 -1
- package/lib/core/registries/sanitizers.js +26 -0
- package/lib/core-api/controller/index.d.ts +14 -9
- package/lib/core-api/service/index.d.ts +10 -9
- package/lib/factories.d.ts +21 -17
- package/lib/index.d.ts +7 -6
- package/lib/middlewares/body.js +38 -10
- package/lib/middlewares/public/index.js +1 -1
- package/lib/middlewares/session.js +3 -1
- package/lib/services/entity-validator/validators.js +3 -1
- package/lib/services/metrics/index.js +7 -1
- package/lib/services/metrics/sender.js +7 -0
- package/lib/services/server/index.js +1 -1
- package/lib/types/strapi.d.ts +291 -0
- package/lib/types/utils.d.ts +1 -0
- package/lib/utils/get-dirs.js +5 -4
- package/lib/utils/update-notifier/index.js +2 -2
- package/package.json +14 -13
package/README.md
CHANGED
|
@@ -114,8 +114,7 @@ For general help using Strapi, please refer to [the official Strapi documentatio
|
|
|
114
114
|
- [Discord](https://discord.strapi.io) (For live discussion with the Community and Strapi team)
|
|
115
115
|
- [GitHub](https://github.com/strapi/strapi) (Bug reports, Contributions)
|
|
116
116
|
- [Community Forum](https://forum.strapi.io) (Questions and Discussions)
|
|
117
|
-
- [
|
|
118
|
-
- [ProductBoard](https://portal.productboard.com/strapi/tabs/2-under-consideration) (Roadmap, Feature requests)
|
|
117
|
+
- [Roadmap & Feature Requests](https://feedback.strapi.io/)
|
|
119
118
|
- [Twitter](https://twitter.com/strapijs) (Get the news fast)
|
|
120
119
|
- [Facebook](https://www.facebook.com/Strapi-616063331867161)
|
|
121
120
|
- [YouTube Channel](https://www.youtube.com/strapi) (Learn from Video Tutorials)
|
|
@@ -126,7 +125,7 @@ Follow our [migration guides](https://docs.strapi.io/developer-docs/latest/updat
|
|
|
126
125
|
|
|
127
126
|
## Roadmap
|
|
128
127
|
|
|
129
|
-
Check out our [roadmap](https://
|
|
128
|
+
Check out our [roadmap](https://feedback.strapi.io/) to get informed of the latest features released and the upcoming ones. You may also give us insights and vote for a specific feature.
|
|
130
129
|
|
|
131
130
|
## Documentation
|
|
132
131
|
|
package/bin/strapi.js
CHANGED
|
@@ -95,6 +95,7 @@ program
|
|
|
95
95
|
.option('--dbssl <dbssl>', 'Database SSL')
|
|
96
96
|
.option('--dbfile <dbfile>', 'Database file path for sqlite')
|
|
97
97
|
.option('--dbforce', 'Allow overwriting existing database content')
|
|
98
|
+
.option('-ts, --typescript', 'Create a typescript project')
|
|
98
99
|
.description('Create a new application')
|
|
99
100
|
.action(require('../lib/commands/new'));
|
|
100
101
|
|
|
@@ -227,4 +228,10 @@ program
|
|
|
227
228
|
.description('List all the application controllers')
|
|
228
229
|
.action(getLocalScript('controllers/list'));
|
|
229
230
|
|
|
231
|
+
// `$ strapi opt-out-telemetry`
|
|
232
|
+
program
|
|
233
|
+
.command('telemetry:disable')
|
|
234
|
+
.description('Stop Strapi from sending anonymous telemetry and metadata')
|
|
235
|
+
.action(getLocalScript('opt-out-telemetry'));
|
|
236
|
+
|
|
230
237
|
program.parseAsync(process.argv);
|
package/lib/Strapi.js
CHANGED
|
@@ -38,10 +38,15 @@ const apisRegistry = require('./core/registries/apis');
|
|
|
38
38
|
const bootstrap = require('./core/bootstrap');
|
|
39
39
|
const loaders = require('./core/loaders');
|
|
40
40
|
const { destroyOnSignal } = require('./utils/signals');
|
|
41
|
+
const sanitizersRegistry = require('./core/registries/sanitizers');
|
|
41
42
|
|
|
42
43
|
// TODO: move somewhere else
|
|
43
44
|
const draftAndPublishSync = require('./migrations/draft-publish');
|
|
44
45
|
|
|
46
|
+
/**
|
|
47
|
+
* A map of all the available Strapi lifecycles
|
|
48
|
+
* @type {import('@strapi/strapi').Core.Lifecycles}
|
|
49
|
+
*/
|
|
45
50
|
const LIFECYCLES = {
|
|
46
51
|
REGISTER: 'register',
|
|
47
52
|
BOOTSTRAP: 'bootstrap',
|
|
@@ -65,18 +70,18 @@ const resolveWorkingDirectories = opts => {
|
|
|
65
70
|
const appDir = opts.appDir ? path.resolve(cwd, opts.appDir) : cwd;
|
|
66
71
|
const distDir = opts.distDir ? path.resolve(cwd, opts.distDir) : appDir;
|
|
67
72
|
|
|
68
|
-
return { appDir, distDir };
|
|
73
|
+
return { app: appDir, dist: distDir };
|
|
69
74
|
};
|
|
70
75
|
|
|
76
|
+
/** @implements {import('@strapi/strapi').Strapi} */
|
|
71
77
|
class Strapi {
|
|
72
78
|
constructor(opts = {}) {
|
|
73
79
|
destroyOnSignal(this);
|
|
74
80
|
|
|
75
|
-
|
|
76
|
-
this.dirs = utils.getDirs(resolveWorkingDirectories(opts));
|
|
81
|
+
const rootDirs = resolveWorkingDirectories(opts);
|
|
77
82
|
|
|
78
83
|
// Load the app configuration from the dist directory
|
|
79
|
-
const appConfig = loadConfiguration(
|
|
84
|
+
const appConfig = loadConfiguration({ appDir: rootDirs.app, distDir: rootDirs.dist }, opts);
|
|
80
85
|
|
|
81
86
|
// Instanciate the Strapi container
|
|
82
87
|
this.container = createContainer(this);
|
|
@@ -93,6 +98,10 @@ class Strapi {
|
|
|
93
98
|
this.container.register('plugins', pluginsRegistry(this));
|
|
94
99
|
this.container.register('apis', apisRegistry(this));
|
|
95
100
|
this.container.register('auth', createAuth(this));
|
|
101
|
+
this.container.register('sanitizers', sanitizersRegistry(this));
|
|
102
|
+
|
|
103
|
+
// Create a mapping of every useful directory (for the app, dist and static directories)
|
|
104
|
+
this.dirs = utils.getDirs(rootDirs, { strapi: this });
|
|
96
105
|
|
|
97
106
|
// Strapi state management variables
|
|
98
107
|
this.isLoaded = false;
|
|
@@ -188,6 +197,10 @@ class Strapi {
|
|
|
188
197
|
return this.container.get('auth');
|
|
189
198
|
}
|
|
190
199
|
|
|
200
|
+
get sanitizers() {
|
|
201
|
+
return this.container.get('sanitizers');
|
|
202
|
+
}
|
|
203
|
+
|
|
191
204
|
async start() {
|
|
192
205
|
try {
|
|
193
206
|
if (!this.isLoaded) {
|
|
@@ -335,6 +348,10 @@ class Strapi {
|
|
|
335
348
|
this.app = await loaders.loadSrcIndex(this);
|
|
336
349
|
}
|
|
337
350
|
|
|
351
|
+
async loadSanitizers() {
|
|
352
|
+
await loaders.loadSanitizers(this);
|
|
353
|
+
}
|
|
354
|
+
|
|
338
355
|
registerInternalHooks() {
|
|
339
356
|
this.container.get('hooks').set('strapi::content-types.beforeSync', createAsyncParallelHook());
|
|
340
357
|
this.container.get('hooks').set('strapi::content-types.afterSync', createAsyncParallelHook());
|
|
@@ -346,6 +363,7 @@ class Strapi {
|
|
|
346
363
|
async register() {
|
|
347
364
|
await Promise.all([
|
|
348
365
|
this.loadApp(),
|
|
366
|
+
this.loadSanitizers(),
|
|
349
367
|
this.loadPlugins(),
|
|
350
368
|
this.loadAdmin(),
|
|
351
369
|
this.loadAPIs(),
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const { yup } = require('@strapi/utils');
|
|
4
4
|
const _ = require('lodash');
|
|
5
5
|
const inquirer = require('inquirer');
|
|
6
|
+
const tsUtils = require('@strapi/typescript-utils');
|
|
6
7
|
const strapi = require('../index');
|
|
7
8
|
|
|
8
9
|
const emailValidator = yup
|
|
@@ -90,7 +91,20 @@ module.exports = async function(cmdOptions = {}) {
|
|
|
90
91
|
};
|
|
91
92
|
|
|
92
93
|
async function createAdmin({ email, password, firstname, lastname }) {
|
|
93
|
-
const
|
|
94
|
+
const appDir = process.cwd();
|
|
95
|
+
|
|
96
|
+
const isTSProject = await tsUtils.isUsingTypeScript(appDir);
|
|
97
|
+
const outDir = await tsUtils.resolveOutDir(appDir);
|
|
98
|
+
|
|
99
|
+
if (isTSProject)
|
|
100
|
+
await tsUtils.compile(appDir, {
|
|
101
|
+
watch: false,
|
|
102
|
+
configOptions: { options: { incremental: true } },
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
const distDir = isTSProject ? outDir : appDir;
|
|
106
|
+
|
|
107
|
+
const app = await strapi({ appDir, distDir }).load();
|
|
94
108
|
|
|
95
109
|
const user = await app.admin.services.user.exists({ email });
|
|
96
110
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const _ = require('lodash');
|
|
4
4
|
const inquirer = require('inquirer');
|
|
5
|
+
const tsUtils = require('@strapi/typescript-utils');
|
|
5
6
|
const strapi = require('../index');
|
|
6
7
|
|
|
7
8
|
const promptQuestions = [
|
|
@@ -42,7 +43,20 @@ module.exports = async function(cmdOptions = {}) {
|
|
|
42
43
|
};
|
|
43
44
|
|
|
44
45
|
async function changePassword({ email, password }) {
|
|
45
|
-
const
|
|
46
|
+
const appDir = process.cwd();
|
|
47
|
+
|
|
48
|
+
const isTSProject = await tsUtils.isUsingTypeScript(appDir);
|
|
49
|
+
const outDir = await tsUtils.resolveOutDir(appDir);
|
|
50
|
+
|
|
51
|
+
if (isTSProject)
|
|
52
|
+
await tsUtils.compile(appDir, {
|
|
53
|
+
watch: false,
|
|
54
|
+
configOptions: { options: { incremental: true } },
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const distDir = isTSProject ? outDir : appDir;
|
|
58
|
+
|
|
59
|
+
const app = await strapi({ appDir, distDir }).load();
|
|
46
60
|
|
|
47
61
|
await app.admin.services.user.resetPasswordByEmail(email, password);
|
|
48
62
|
|
package/lib/commands/build.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
const path = require('path');
|
|
3
2
|
|
|
4
3
|
const tsUtils = require('@strapi/typescript-utils');
|
|
5
4
|
const { buildAdmin, buildTypeScript } = require('./builders');
|
|
@@ -11,20 +10,20 @@ module.exports = async ({ optimization, forceBuild = true }) => {
|
|
|
11
10
|
let buildDestDir = process.cwd();
|
|
12
11
|
const srcDir = process.cwd();
|
|
13
12
|
|
|
14
|
-
const
|
|
13
|
+
const useTypeScriptServer = await tsUtils.isUsingTypeScript(srcDir);
|
|
14
|
+
const outDir = await tsUtils.resolveOutDir(srcDir);
|
|
15
15
|
|
|
16
16
|
// Typescript
|
|
17
|
-
if (
|
|
17
|
+
if (useTypeScriptServer) {
|
|
18
18
|
await buildTypeScript({ srcDir, watch: false });
|
|
19
19
|
|
|
20
20
|
// Update the dir path for the next steps
|
|
21
|
-
buildDestDir =
|
|
21
|
+
buildDestDir = outDir;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
await buildAdmin({
|
|
25
25
|
buildDestDir,
|
|
26
26
|
forceBuild,
|
|
27
|
-
isTSProject,
|
|
28
27
|
optimization,
|
|
29
28
|
srcDir,
|
|
30
29
|
});
|
|
@@ -10,10 +10,12 @@ const addSlash = require('../../utils/addSlash');
|
|
|
10
10
|
const strapi = require('../../index');
|
|
11
11
|
const getEnabledPlugins = require('../../core/loaders/plugins/get-enabled-plugins');
|
|
12
12
|
|
|
13
|
-
module.exports = async ({ buildDestDir, forceBuild = true,
|
|
13
|
+
module.exports = async ({ buildDestDir, forceBuild = true, optimization, srcDir }) => {
|
|
14
14
|
const strapiInstance = strapi({
|
|
15
|
-
//
|
|
15
|
+
// Directories
|
|
16
|
+
appDir: srcDir,
|
|
16
17
|
distDir: buildDestDir,
|
|
18
|
+
// Options
|
|
17
19
|
autoReload: true,
|
|
18
20
|
serveAdminPanel: false,
|
|
19
21
|
});
|
|
@@ -46,7 +48,6 @@ module.exports = async ({ buildDestDir, forceBuild = true, isTSProject, optimiza
|
|
|
46
48
|
backend: serverUrl,
|
|
47
49
|
adminPath: addSlash(adminPath),
|
|
48
50
|
},
|
|
49
|
-
useTypeScript: isTSProject,
|
|
50
51
|
})
|
|
51
52
|
.then(() => {
|
|
52
53
|
console.log('Admin UI built successfully');
|
|
@@ -5,8 +5,8 @@ const fs = require('fs-extra');
|
|
|
5
5
|
const tsUtils = require('@strapi/typescript-utils');
|
|
6
6
|
|
|
7
7
|
const cleanupDistDirectory = async distDir => {
|
|
8
|
-
if (!await fs.pathExists(distDir)){
|
|
9
|
-
return
|
|
8
|
+
if (!(await fs.pathExists(distDir))) {
|
|
9
|
+
return;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
const dirContent = await fs.readdir(distDir);
|
|
@@ -14,21 +14,18 @@ const cleanupDistDirectory = async distDir => {
|
|
|
14
14
|
// Ignore the admin build folder
|
|
15
15
|
.filter(filename => filename !== 'build');
|
|
16
16
|
|
|
17
|
-
|
|
18
17
|
for (const filename of validFilenames) {
|
|
19
18
|
await fs.remove(path.resolve(distDir, filename));
|
|
20
19
|
}
|
|
21
20
|
};
|
|
22
21
|
|
|
23
22
|
module.exports = async ({ srcDir, distDir, watch = false }) => {
|
|
24
|
-
const isTSProject = await tsUtils.
|
|
23
|
+
const isTSProject = await tsUtils.isUsingTypeScript(srcDir);
|
|
25
24
|
|
|
26
25
|
if (!isTSProject) {
|
|
27
26
|
throw new Error(`tsconfig file not found in ${srcDir}`);
|
|
28
27
|
}
|
|
29
28
|
|
|
30
|
-
|
|
31
|
-
|
|
32
29
|
await cleanupDistDirectory(distDir);
|
|
33
30
|
|
|
34
31
|
return tsUtils.compile(srcDir, { watch });
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const fs = require('fs');
|
|
4
|
+
const tsUtils = require('@strapi/typescript-utils');
|
|
4
5
|
const strapi = require('../index');
|
|
5
6
|
|
|
6
7
|
const CHUNK_SIZE = 100;
|
|
@@ -12,7 +13,19 @@ const CHUNK_SIZE = 100;
|
|
|
12
13
|
module.exports = async function({ file: filePath, pretty }) {
|
|
13
14
|
const output = filePath ? fs.createWriteStream(filePath) : process.stdout;
|
|
14
15
|
|
|
15
|
-
const
|
|
16
|
+
const appDir = process.cwd();
|
|
17
|
+
|
|
18
|
+
const isTSProject = await tsUtils.isUsingTypeScript(appDir);
|
|
19
|
+
const outDir = await tsUtils.resolveOutDir(appDir);
|
|
20
|
+
if (isTSProject)
|
|
21
|
+
await tsUtils.compile(appDir, {
|
|
22
|
+
watch: false,
|
|
23
|
+
configOptions: { options: { incremental: true } },
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const distDir = isTSProject ? outDir : appDir;
|
|
27
|
+
|
|
28
|
+
const app = await strapi({ appDir, distDir }).load();
|
|
16
29
|
|
|
17
30
|
const count = await app.query('strapi::core-store').count();
|
|
18
31
|
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const _ = require('lodash');
|
|
5
|
+
const tsUtils = require('@strapi/typescript-utils');
|
|
6
|
+
|
|
5
7
|
const strapi = require('../index');
|
|
6
8
|
|
|
7
9
|
/**
|
|
@@ -12,7 +14,20 @@ const strapi = require('../index');
|
|
|
12
14
|
module.exports = async function({ file: filePath, strategy = 'replace' }) {
|
|
13
15
|
const input = filePath ? fs.readFileSync(filePath) : await readStdin(process.stdin);
|
|
14
16
|
|
|
15
|
-
const
|
|
17
|
+
const appDir = process.cwd();
|
|
18
|
+
|
|
19
|
+
const isTSProject = await tsUtils.isUsingTypeScript(appDir);
|
|
20
|
+
const outDir = await tsUtils.resolveOutDir(appDir);
|
|
21
|
+
|
|
22
|
+
if (isTSProject)
|
|
23
|
+
await tsUtils.compile(appDir, {
|
|
24
|
+
watch: false,
|
|
25
|
+
configOptions: { options: { incremental: true } },
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const distDir = isTSProject ? outDir : appDir;
|
|
29
|
+
|
|
30
|
+
const app = await strapi({ appDir, distDir }).load();
|
|
16
31
|
|
|
17
32
|
let dataToImport;
|
|
18
33
|
try {
|
package/lib/commands/console.js
CHANGED
|
@@ -1,14 +1,28 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const REPL = require('repl');
|
|
4
|
+
const tsUtils = require('@strapi/typescript-utils');
|
|
5
|
+
|
|
4
6
|
const strapi = require('../index');
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* `$ strapi console`
|
|
8
10
|
*/
|
|
9
|
-
module.exports = () => {
|
|
11
|
+
module.exports = async () => {
|
|
10
12
|
// Now load up the Strapi framework for real.
|
|
11
|
-
const
|
|
13
|
+
const appDir = process.cwd();
|
|
14
|
+
const isTSProject = await tsUtils.isUsingTypeScript(appDir);
|
|
15
|
+
const outDir = await tsUtils.resolveOutDir(appDir);
|
|
16
|
+
|
|
17
|
+
if (isTSProject)
|
|
18
|
+
await tsUtils.compile(appDir, {
|
|
19
|
+
watch: false,
|
|
20
|
+
configOptions: { options: { incremental: true } },
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const distDir = isTSProject ? outDir : appDir;
|
|
24
|
+
|
|
25
|
+
const app = await strapi({ appDir, distDir }).load();
|
|
12
26
|
|
|
13
27
|
app.start().then(() => {
|
|
14
28
|
const repl = REPL.start(app.config.info.name + ' > ' || 'strapi > '); // eslint-disable-line prefer-template
|
package/lib/commands/develop.js
CHANGED
|
@@ -6,6 +6,7 @@ const fs = require('fs-extra');
|
|
|
6
6
|
const chokidar = require('chokidar');
|
|
7
7
|
const execa = require('execa');
|
|
8
8
|
const { getOr } = require('lodash/fp');
|
|
9
|
+
const { joinBy } = require('@strapi/utils');
|
|
9
10
|
const tsUtils = require('@strapi/typescript-utils');
|
|
10
11
|
|
|
11
12
|
const loadConfiguration = require('../core/app-configuration');
|
|
@@ -20,8 +21,9 @@ const { buildTypeScript, buildAdmin } = require('./builders');
|
|
|
20
21
|
module.exports = async function({ build, watchAdmin, polling, browser }) {
|
|
21
22
|
const appDir = process.cwd();
|
|
22
23
|
|
|
23
|
-
const isTSProject = await tsUtils.
|
|
24
|
-
const
|
|
24
|
+
const isTSProject = await tsUtils.isUsingTypeScript(appDir);
|
|
25
|
+
const outDir = await tsUtils.resolveOutDir(appDir);
|
|
26
|
+
const distDir = isTSProject ? outDir : appDir;
|
|
25
27
|
|
|
26
28
|
try {
|
|
27
29
|
if (cluster.isMaster || cluster.isPrimary) {
|
|
@@ -49,7 +51,7 @@ const primaryProcess = async ({ distDir, appDir, build, isTSProject, watchAdmin,
|
|
|
49
51
|
await buildTypeScript({ srcDir: appDir, distDir, watch: false });
|
|
50
52
|
}
|
|
51
53
|
|
|
52
|
-
const config = loadConfiguration(distDir);
|
|
54
|
+
const config = loadConfiguration({ appDir, distDir });
|
|
53
55
|
const serveAdminPanel = getOr(true, 'admin.serveAdminPanel')(config);
|
|
54
56
|
|
|
55
57
|
const buildExists = fs.existsSync(path.join(distDir, 'build'));
|
|
@@ -60,7 +62,6 @@ const primaryProcess = async ({ distDir, appDir, build, isTSProject, watchAdmin,
|
|
|
60
62
|
await buildAdmin({
|
|
61
63
|
buildDestDir: distDir,
|
|
62
64
|
forceBuild: false,
|
|
63
|
-
isTSProject,
|
|
64
65
|
optimization: false,
|
|
65
66
|
srcDir: appDir,
|
|
66
67
|
});
|
|
@@ -157,6 +158,9 @@ function watchFileChanges({ appDir, strapiInstance, watchIgnoreFiles, polling })
|
|
|
157
158
|
/tmp/,
|
|
158
159
|
'**/src/admin/**',
|
|
159
160
|
'**/src/plugins/**/admin/**',
|
|
161
|
+
// FIXME pass the plugin path to the strapiAdmin.build and strapiAdmin.watch in order to stop copying
|
|
162
|
+
// the FE files when using TS
|
|
163
|
+
'**/dist/src/plugins/test/admin/**',
|
|
160
164
|
'**/documentation',
|
|
161
165
|
'**/documentation/**',
|
|
162
166
|
'**/node_modules',
|
|
@@ -167,6 +171,8 @@ function watchFileChanges({ appDir, strapiInstance, watchIgnoreFiles, polling })
|
|
|
167
171
|
'**/index.html',
|
|
168
172
|
'**/public',
|
|
169
173
|
'**/public/**',
|
|
174
|
+
strapiInstance.dirs.static.public,
|
|
175
|
+
joinBy('/', strapiInstance.dirs.static.public, '**'),
|
|
170
176
|
'**/*.db*',
|
|
171
177
|
'**/exports/**',
|
|
172
178
|
'**/dist/**',
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { resolve } = require('path');
|
|
4
|
+
const fse = require('fs-extra');
|
|
5
|
+
const chalk = require('chalk');
|
|
6
|
+
const fetch = require('node-fetch');
|
|
7
|
+
const machineID = require('../utils/machine-id');
|
|
8
|
+
|
|
9
|
+
const readPackageJSON = async path => {
|
|
10
|
+
try {
|
|
11
|
+
const packageObj = await fse.readJson(path);
|
|
12
|
+
const uuid = packageObj.strapi ? packageObj.strapi.uuid : null;
|
|
13
|
+
|
|
14
|
+
return { uuid, packageObj };
|
|
15
|
+
} catch (err) {
|
|
16
|
+
console.error(`${chalk.red('Error')}: ${err.message}`);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const writePackageJSON = async (path, file, spacing) => {
|
|
21
|
+
try {
|
|
22
|
+
await fse.writeJson(path, file, { spaces: spacing });
|
|
23
|
+
return true;
|
|
24
|
+
} catch (err) {
|
|
25
|
+
console.error(`${chalk.red('Error')}: ${err.message}`);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const sendEvent = async uuid => {
|
|
30
|
+
try {
|
|
31
|
+
await fetch('https://analytics.strapi.io/track', {
|
|
32
|
+
method: 'POST',
|
|
33
|
+
body: JSON.stringify({
|
|
34
|
+
event: 'didOptOutTelemetry',
|
|
35
|
+
uuid,
|
|
36
|
+
deviceId: machineID(),
|
|
37
|
+
}),
|
|
38
|
+
headers: { 'Content-Type': 'application/json' },
|
|
39
|
+
});
|
|
40
|
+
} catch (e) {
|
|
41
|
+
//...
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
module.exports = async function optOutTelemetry() {
|
|
46
|
+
const packageJSONPath = resolve(process.cwd(), 'package.json');
|
|
47
|
+
const exists = await fse.pathExists(packageJSONPath);
|
|
48
|
+
|
|
49
|
+
if (!exists) {
|
|
50
|
+
console.log(`${chalk.yellow('Warning')}: could not find package.json`);
|
|
51
|
+
process.exit(0);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const { uuid, packageObj } = await readPackageJSON(packageJSONPath);
|
|
55
|
+
|
|
56
|
+
if ((packageObj.strapi && packageObj.strapi.telemetryDisabled) || !uuid) {
|
|
57
|
+
console.log(`${chalk.yellow('Warning:')} telemetry is already disabled`);
|
|
58
|
+
process.exit(0);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const updatedPackageJSON = {
|
|
62
|
+
...packageObj,
|
|
63
|
+
strapi: {
|
|
64
|
+
...packageObj.strapi,
|
|
65
|
+
telemetryDisabled: true,
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const write = await writePackageJSON(packageJSONPath, updatedPackageJSON, 2);
|
|
70
|
+
|
|
71
|
+
if (!write) {
|
|
72
|
+
console.log(
|
|
73
|
+
`${chalk.yellow(
|
|
74
|
+
'Warning'
|
|
75
|
+
)}: There has been an error, please set "telemetryDisabled": true in the "strapi" object of your package.json manually.`
|
|
76
|
+
);
|
|
77
|
+
process.exit(0);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
await sendEvent(uuid);
|
|
81
|
+
console.log(`${chalk.green('Successfully opted out of Strapi telemetry')}`);
|
|
82
|
+
process.exit(0);
|
|
83
|
+
};
|
|
@@ -3,11 +3,25 @@
|
|
|
3
3
|
const CLITable = require('cli-table3');
|
|
4
4
|
const chalk = require('chalk');
|
|
5
5
|
const { toUpper } = require('lodash/fp');
|
|
6
|
+
const tsUtils = require('@strapi/typescript-utils');
|
|
6
7
|
|
|
7
8
|
const strapi = require('../../index');
|
|
8
9
|
|
|
9
10
|
module.exports = async function() {
|
|
10
|
-
const
|
|
11
|
+
const appDir = process.cwd();
|
|
12
|
+
|
|
13
|
+
const isTSProject = await tsUtils.isUsingTypeScript(appDir);
|
|
14
|
+
const outDir = await tsUtils.resolveOutDir(appDir);
|
|
15
|
+
|
|
16
|
+
if (isTSProject)
|
|
17
|
+
await tsUtils.compile(appDir, {
|
|
18
|
+
watch: false,
|
|
19
|
+
configOptions: { options: { incremental: true } },
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const distDir = isTSProject ? outDir : appDir;
|
|
23
|
+
|
|
24
|
+
const app = await strapi({ appDir, distDir }).load();
|
|
11
25
|
|
|
12
26
|
const list = app.server.listRoutes();
|
|
13
27
|
|
package/lib/commands/start.js
CHANGED
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const tsUtils = require('@strapi/typescript-utils');
|
|
3
4
|
const strapi = require('../index');
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* `$ strapi start`
|
|
7
8
|
*/
|
|
8
|
-
module.exports =
|
|
9
|
+
module.exports = async specifiedDir => {
|
|
10
|
+
const appDir = process.cwd();
|
|
11
|
+
const isTSProject = await tsUtils.isUsingTypeScript(appDir);
|
|
12
|
+
const outDir = await tsUtils.resolveOutDir(appDir);
|
|
13
|
+
const buildDirExists = fs.existsSync(outDir);
|
|
14
|
+
if (isTSProject && !buildDirExists) throw new Error(`${outDir} directory not found. Please run the build command before starting your application`);
|
|
15
|
+
const distDir = isTSProject && !specifiedDir ? outDir : specifiedDir;
|
|
16
|
+
|
|
17
|
+
strapi({ distDir }).start();
|
|
18
|
+
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const path = require('path');
|
|
4
3
|
const strapiAdmin = require('@strapi/admin');
|
|
5
4
|
const tsUtils = require('@strapi/typescript-utils');
|
|
6
5
|
const { getConfigUrls, getAbsoluteServerUrl } = require('@strapi/utils');
|
|
@@ -12,8 +11,9 @@ const strapi = require('../index');
|
|
|
12
11
|
module.exports = async function({ browser }) {
|
|
13
12
|
const currentDirectory = process.cwd();
|
|
14
13
|
|
|
15
|
-
const isTSProject = await tsUtils.
|
|
16
|
-
const
|
|
14
|
+
const isTSProject = await tsUtils.isUsingTypeScript(currentDirectory);
|
|
15
|
+
const outDir = await tsUtils.resolveOutDir(currentDirectory);
|
|
16
|
+
const buildDestDir = isTSProject ? outDir : currentDirectory;
|
|
17
17
|
|
|
18
18
|
const strapiInstance = strapi({
|
|
19
19
|
distDir: buildDestDir,
|
|
@@ -41,6 +41,5 @@ module.exports = async function({ browser }) {
|
|
|
41
41
|
backend: backendURL,
|
|
42
42
|
adminPath: addSlash(adminPath),
|
|
43
43
|
},
|
|
44
|
-
useTypeScript: isTSProject,
|
|
45
44
|
});
|
|
46
45
|
};
|
|
@@ -21,6 +21,7 @@ const defaultConfig = {
|
|
|
21
21
|
proxy: false,
|
|
22
22
|
cron: { enabled: false },
|
|
23
23
|
admin: { autoOpen: false },
|
|
24
|
+
dirs: { public: './public' },
|
|
24
25
|
},
|
|
25
26
|
admin: {},
|
|
26
27
|
api: {
|
|
@@ -30,12 +31,13 @@ const defaultConfig = {
|
|
|
30
31
|
},
|
|
31
32
|
};
|
|
32
33
|
|
|
33
|
-
module.exports = (
|
|
34
|
+
module.exports = (dirs, initialConfig = {}) => {
|
|
35
|
+
const { appDir, distDir } = dirs;
|
|
34
36
|
const { autoReload = false, serveAdminPanel = true } = initialConfig;
|
|
35
37
|
|
|
36
|
-
const pkgJSON = require(path.resolve(
|
|
38
|
+
const pkgJSON = require(path.resolve(appDir, 'package.json'));
|
|
37
39
|
|
|
38
|
-
const configDir = path.resolve(
|
|
40
|
+
const configDir = path.resolve(distDir || process.cwd(), 'config');
|
|
39
41
|
|
|
40
42
|
const rootConfig = {
|
|
41
43
|
launchedAt: Date.now(),
|
package/lib/core/bootstrap.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const { getConfigUrls } = require('@strapi/utils');
|
|
4
|
+
const fse = require('fs-extra');
|
|
4
5
|
|
|
5
|
-
module.exports = function({ strapi }) {
|
|
6
|
+
module.exports = async function({ strapi }) {
|
|
6
7
|
strapi.config.port = strapi.config.get('server.port') || strapi.config.port;
|
|
7
8
|
strapi.config.host = strapi.config.get('server.host') || strapi.config.host;
|
|
8
9
|
|
|
@@ -22,4 +23,11 @@ module.exports = function({ strapi }) {
|
|
|
22
23
|
if (!shouldServeAdmin) {
|
|
23
24
|
strapi.config.serveAdminPanel = false;
|
|
24
25
|
}
|
|
26
|
+
|
|
27
|
+
// ensure public repository exists
|
|
28
|
+
if (!(await fse.pathExists(strapi.dirs.static.public))) {
|
|
29
|
+
throw new Error(
|
|
30
|
+
`The public folder (${strapi.dirs.static.public}) doesn't exist or is not accessible. Please make sure it exists.`
|
|
31
|
+
);
|
|
32
|
+
}
|
|
25
33
|
};
|
package/lib/core/loaders/apis.js
CHANGED
|
@@ -7,31 +7,35 @@ const fse = require('fs-extra');
|
|
|
7
7
|
const { isKebabCase } = require('@strapi/utils');
|
|
8
8
|
const { importDefault } = require('../../utils');
|
|
9
9
|
|
|
10
|
-
// to handle names with numbers in it we first check if it is already in kebabCase
|
|
11
|
-
const normalizeName = name => (isKebabCase(name) ? name : _.kebabCase(name));
|
|
12
|
-
|
|
13
10
|
const DEFAULT_CONTENT_TYPE = {
|
|
14
11
|
schema: {},
|
|
15
12
|
actions: {},
|
|
16
13
|
lifecycles: {},
|
|
17
14
|
};
|
|
18
15
|
|
|
16
|
+
// to handle names with numbers in it we first check if it is already in kebabCase
|
|
17
|
+
const normalizeName = name => (isKebabCase(name) ? name : _.kebabCase(name));
|
|
18
|
+
|
|
19
|
+
const isDirectory = fd => fd.isDirectory();
|
|
20
|
+
const isDotFile = fd => fd.name.startsWith('.');
|
|
21
|
+
|
|
19
22
|
module.exports = async strapi => {
|
|
20
23
|
if (!existsSync(strapi.dirs.dist.api)) {
|
|
21
24
|
return;
|
|
22
25
|
}
|
|
23
26
|
|
|
24
|
-
const apisFDs = await fse.readdir(strapi.dirs.dist.api, { withFileTypes: true })
|
|
27
|
+
const apisFDs = await (await fse.readdir(strapi.dirs.dist.api, { withFileTypes: true }))
|
|
28
|
+
.filter(isDirectory)
|
|
29
|
+
.filter(_.negate(isDotFile));
|
|
30
|
+
|
|
25
31
|
const apis = {};
|
|
26
32
|
|
|
27
33
|
// only load folders
|
|
28
34
|
for (const apiFD of apisFDs) {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const api = await loadAPI(join(strapi.dirs.dist.api, apiFD.name));
|
|
35
|
+
const apiName = normalizeName(apiFD.name);
|
|
36
|
+
const api = await loadAPI(join(strapi.dirs.dist.api, apiFD.name));
|
|
32
37
|
|
|
33
|
-
|
|
34
|
-
}
|
|
38
|
+
apis[apiName] = api;
|
|
35
39
|
}
|
|
36
40
|
|
|
37
41
|
validateContentTypesUnicity(apis);
|