@strapi/strapi 4.0.0-next.11 → 4.0.0-next.15
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/bin/strapi.js +1 -4
- package/lib/Strapi.js +82 -28
- package/lib/commands/console.js +1 -1
- package/lib/commands/develop.js +4 -3
- package/lib/core/domain/content-type/index.js +3 -7
- package/lib/core/domain/module/index.js +2 -2
- package/lib/core/loaders/apis.js +4 -6
- package/lib/core/loaders/components.js +3 -5
- package/lib/core/loaders/index.js +1 -0
- package/lib/core/loaders/middlewares.js +1 -1
- package/lib/core/loaders/plugins/get-enabled-plugins.js +2 -2
- package/lib/core/loaders/plugins/index.js +7 -7
- package/lib/core/loaders/policies.js +1 -1
- package/lib/core/loaders/src-index.js +38 -0
- package/lib/core/registries/hooks.js +37 -0
- package/lib/core/registries/services.js +7 -7
- package/lib/core-api/controller/collection-type.js +5 -5
- package/lib/core-api/controller/single-type.js +3 -3
- package/lib/core-api/controller/transform.js +28 -3
- package/lib/core-api/service/collection-type.js +18 -19
- package/lib/core-api/service/single-type.js +10 -14
- package/lib/index.d.ts +9 -31
- package/lib/middlewares/cors/index.js +1 -1
- package/lib/middlewares/{boom → error}/defaults.json +1 -1
- package/lib/middlewares/{boom → error}/index.js +1 -1
- package/lib/middlewares/favicon/index.js +1 -2
- package/lib/middlewares/index.js +1 -1
- package/lib/middlewares/public/index.js +2 -2
- package/lib/middlewares/responses/index.js +2 -1
- package/lib/middlewares/router/index.js +5 -3
- package/lib/migrations/draft-publish.js +57 -0
- package/lib/services/auth/index.js +2 -2
- package/lib/services/core-store.js +64 -49
- package/lib/services/cron.js +54 -0
- package/lib/services/entity-service/components.js +37 -12
- package/lib/services/entity-service/index.d.ts +91 -0
- package/lib/services/entity-service/index.js +52 -50
- package/lib/services/entity-service/params.js +74 -57
- package/lib/services/fs.js +1 -1
- package/lib/services/metrics/index.js +1 -1
- package/lib/services/server/policy.js +15 -4
- package/lib/services/webhook-runner.js +1 -1
- package/lib/utils/ee.js +3 -3
- package/lib/utils/get-dirs.js +15 -0
- package/lib/utils/index.js +2 -0
- package/lib/utils/update-notifier/index.js +2 -1
- package/package.json +88 -98
- package/lib/middlewares/cron/defaults.json +0 -5
- package/lib/middlewares/cron/index.js +0 -43
- package/lib/middlewares/language/defaults.json +0 -9
- package/lib/middlewares/language/index.js +0 -40
package/bin/strapi.js
CHANGED
|
@@ -58,10 +58,7 @@ const getLocalScript = name => (...args) => {
|
|
|
58
58
|
};
|
|
59
59
|
|
|
60
60
|
// Initial program setup
|
|
61
|
-
program
|
|
62
|
-
.storeOptionsAsProperties(false)
|
|
63
|
-
.passCommandToAction(false)
|
|
64
|
-
.allowUnknownOption(true);
|
|
61
|
+
program.storeOptionsAsProperties(false).allowUnknownOption(true);
|
|
65
62
|
|
|
66
63
|
program.helpOption('-h, --help', 'Display help for command');
|
|
67
64
|
program.addHelpCommand('help [command]', 'Display help for command');
|
package/lib/Strapi.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const _ = require('lodash');
|
|
4
4
|
const { createLogger } = require('@strapi/logger');
|
|
5
5
|
const { Database } = require('@strapi/database');
|
|
6
|
+
const { createAsyncParallelHook } = require('@strapi/utils').hooks;
|
|
6
7
|
|
|
7
8
|
const loadConfiguration = require('./core/app-configuration');
|
|
8
9
|
|
|
@@ -16,6 +17,7 @@ const createWebhookRunner = require('./services/webhook-runner');
|
|
|
16
17
|
const { webhookModel, createWebhookStore } = require('./services/webhook-store');
|
|
17
18
|
const { createCoreStore, coreStoreModel } = require('./services/core-store');
|
|
18
19
|
const createEntityService = require('./services/entity-service');
|
|
20
|
+
const createCronService = require('./services/cron');
|
|
19
21
|
const entityValidator = require('./services/entity-validator');
|
|
20
22
|
const createTelemetry = require('./services/metrics');
|
|
21
23
|
const createAuth = require('./services/auth');
|
|
@@ -26,6 +28,7 @@ const contentTypesRegistry = require('./core/registries/content-types');
|
|
|
26
28
|
const servicesRegistry = require('./core/registries/services');
|
|
27
29
|
const policiesRegistry = require('./core/registries/policies');
|
|
28
30
|
const middlewaresRegistry = require('./core/registries/middlewares');
|
|
31
|
+
const hooksRegistry = require('./core/registries/hooks');
|
|
29
32
|
const controllersRegistry = require('./core/registries/controllers');
|
|
30
33
|
const modulesRegistry = require('./core/registries/modules');
|
|
31
34
|
const pluginsRegistry = require('./core/registries/plugins');
|
|
@@ -34,6 +37,9 @@ const apisRegistry = require('./core/registries/apis');
|
|
|
34
37
|
const bootstrap = require('./core/bootstrap');
|
|
35
38
|
const loaders = require('./core/loaders');
|
|
36
39
|
|
|
40
|
+
// TODO: move somewhere else
|
|
41
|
+
const draftAndPublishSync = require('./migrations/draft-publish');
|
|
42
|
+
|
|
37
43
|
const LIFECYCLES = {
|
|
38
44
|
REGISTER: 'register',
|
|
39
45
|
BOOTSTRAP: 'bootstrap',
|
|
@@ -41,14 +47,15 @@ const LIFECYCLES = {
|
|
|
41
47
|
|
|
42
48
|
class Strapi {
|
|
43
49
|
constructor(opts = {}) {
|
|
44
|
-
this.
|
|
45
|
-
const appConfig = loadConfiguration(this.
|
|
50
|
+
this.dirs = utils.getDirs(opts.dir || process.cwd());
|
|
51
|
+
const appConfig = loadConfiguration(this.dirs.root, opts);
|
|
46
52
|
this.container = createContainer(this);
|
|
47
53
|
this.container.register('config', createConfigProvider(appConfig));
|
|
48
54
|
this.container.register('content-types', contentTypesRegistry(this));
|
|
49
55
|
this.container.register('services', servicesRegistry(this));
|
|
50
56
|
this.container.register('policies', policiesRegistry(this));
|
|
51
57
|
this.container.register('middlewares', middlewaresRegistry(this));
|
|
58
|
+
this.container.register('hooks', hooksRegistry(this));
|
|
52
59
|
this.container.register('controllers', controllersRegistry(this));
|
|
53
60
|
this.container.register('modules', modulesRegistry(this));
|
|
54
61
|
this.container.register('plugins', pluginsRegistry(this));
|
|
@@ -63,6 +70,7 @@ class Strapi {
|
|
|
63
70
|
this.eventHub = createEventHub();
|
|
64
71
|
this.startupLogger = createStartupLogger(this);
|
|
65
72
|
this.log = createLogger(this.config.get('logger', {}));
|
|
73
|
+
this.cron = createCronService();
|
|
66
74
|
|
|
67
75
|
createUpdateNotifier(this).notify();
|
|
68
76
|
}
|
|
@@ -72,7 +80,7 @@ class Strapi {
|
|
|
72
80
|
}
|
|
73
81
|
|
|
74
82
|
get EE() {
|
|
75
|
-
return ee({ dir: this.
|
|
83
|
+
return ee({ dir: this.dirs.root, logger: this.log });
|
|
76
84
|
}
|
|
77
85
|
|
|
78
86
|
service(uid) {
|
|
@@ -107,6 +115,14 @@ class Strapi {
|
|
|
107
115
|
return this.container.get('plugins').getAll();
|
|
108
116
|
}
|
|
109
117
|
|
|
118
|
+
hook(name) {
|
|
119
|
+
return this.container.get('hooks').get(name);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
get hooks() {
|
|
123
|
+
return this.container.get('hooks');
|
|
124
|
+
}
|
|
125
|
+
|
|
110
126
|
// api(name) {
|
|
111
127
|
// return this.container.get('apis').get(name);
|
|
112
128
|
// }
|
|
@@ -115,6 +131,10 @@ class Strapi {
|
|
|
115
131
|
return this.container.get('apis').getAll();
|
|
116
132
|
}
|
|
117
133
|
|
|
134
|
+
get auth() {
|
|
135
|
+
return this.container.get('auth');
|
|
136
|
+
}
|
|
137
|
+
|
|
118
138
|
async start() {
|
|
119
139
|
try {
|
|
120
140
|
if (!this.isLoaded) {
|
|
@@ -151,6 +171,7 @@ class Strapi {
|
|
|
151
171
|
}
|
|
152
172
|
|
|
153
173
|
this.telemetry.destroy();
|
|
174
|
+
this.cron.destroy();
|
|
154
175
|
|
|
155
176
|
delete global.strapi;
|
|
156
177
|
}
|
|
@@ -173,7 +194,7 @@ class Strapi {
|
|
|
173
194
|
this.config.get('environment') === 'development' &&
|
|
174
195
|
this.config.get('server.admin.autoOpen', true) !== false;
|
|
175
196
|
|
|
176
|
-
if (shouldOpenAdmin
|
|
197
|
+
if (shouldOpenAdmin && !isInitialized) {
|
|
177
198
|
await utils.openBrowser(this.config);
|
|
178
199
|
}
|
|
179
200
|
}
|
|
@@ -262,8 +283,21 @@ class Strapi {
|
|
|
262
283
|
this.middleware = await loaders.loadMiddlewares(this);
|
|
263
284
|
}
|
|
264
285
|
|
|
286
|
+
async loadApp() {
|
|
287
|
+
this.app = await loaders.loadSrcIndex(this);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
registerInternalHooks() {
|
|
291
|
+
this.hooks.set('strapi::content-types.beforeSync', createAsyncParallelHook());
|
|
292
|
+
this.hooks.set('strapi::content-types.afterSync', createAsyncParallelHook());
|
|
293
|
+
|
|
294
|
+
this.hook('strapi::content-types.beforeSync').register(draftAndPublishSync.disable);
|
|
295
|
+
this.hook('strapi::content-types.afterSync').register(draftAndPublishSync.enable);
|
|
296
|
+
}
|
|
297
|
+
|
|
265
298
|
async load() {
|
|
266
299
|
await Promise.all([
|
|
300
|
+
this.loadApp(),
|
|
267
301
|
this.loadPlugins(),
|
|
268
302
|
this.loadAdmin(),
|
|
269
303
|
this.loadAPIs(),
|
|
@@ -281,6 +315,8 @@ class Strapi {
|
|
|
281
315
|
configuration: this.config.get('server.webhooks', {}),
|
|
282
316
|
});
|
|
283
317
|
|
|
318
|
+
this.registerInternalHooks();
|
|
319
|
+
|
|
284
320
|
await this.runLifecyclesFunctions(LIFECYCLES.REGISTER);
|
|
285
321
|
|
|
286
322
|
const contentTypes = [
|
|
@@ -295,19 +331,10 @@ class Strapi {
|
|
|
295
331
|
models: Database.transformContentTypes(contentTypes),
|
|
296
332
|
});
|
|
297
333
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
this.store = createCoreStore({
|
|
301
|
-
environment: this.config.get('environment'),
|
|
302
|
-
db: this.db,
|
|
303
|
-
});
|
|
304
|
-
|
|
334
|
+
this.store = createCoreStore({ db: this.db });
|
|
305
335
|
this.webhookStore = createWebhookStore({ db: this.db });
|
|
306
336
|
|
|
307
|
-
await this.startWebhooks();
|
|
308
|
-
|
|
309
337
|
this.entityValidator = entityValidator;
|
|
310
|
-
|
|
311
338
|
this.entityService = createEntityService({
|
|
312
339
|
strapi: this,
|
|
313
340
|
db: this.db,
|
|
@@ -315,13 +342,48 @@ class Strapi {
|
|
|
315
342
|
entityValidator: this.entityValidator,
|
|
316
343
|
});
|
|
317
344
|
|
|
345
|
+
const cronTasks = this.config.get('server.cron.tasks', {});
|
|
346
|
+
this.cron.add(cronTasks);
|
|
347
|
+
|
|
318
348
|
this.telemetry = createTelemetry(this);
|
|
319
349
|
|
|
350
|
+
let oldContentTypes;
|
|
351
|
+
if (await this.db.connection.schema.hasTable(coreStoreModel.collectionName)) {
|
|
352
|
+
oldContentTypes = await this.store.get({
|
|
353
|
+
type: 'strapi',
|
|
354
|
+
name: 'content_types',
|
|
355
|
+
key: 'schema',
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
await this.hook('strapi::content-types.beforeSync').call({
|
|
360
|
+
oldContentTypes,
|
|
361
|
+
contentTypes: strapi.contentTypes,
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
await this.db.schema.sync();
|
|
365
|
+
|
|
366
|
+
await this.hook('strapi::content-types.afterSync').call({
|
|
367
|
+
oldContentTypes,
|
|
368
|
+
contentTypes: strapi.contentTypes,
|
|
369
|
+
});
|
|
370
|
+
|
|
371
|
+
await this.store.set({
|
|
372
|
+
type: 'strapi',
|
|
373
|
+
name: 'content_types',
|
|
374
|
+
key: 'schema',
|
|
375
|
+
value: strapi.contentTypes,
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
await this.startWebhooks();
|
|
379
|
+
|
|
320
380
|
// Initialize middlewares.
|
|
321
381
|
await initializeMiddlewares(this);
|
|
322
382
|
|
|
323
383
|
await this.runLifecyclesFunctions(LIFECYCLES.BOOTSTRAP);
|
|
324
384
|
|
|
385
|
+
this.cron.start();
|
|
386
|
+
|
|
325
387
|
this.isLoaded = true;
|
|
326
388
|
|
|
327
389
|
return this;
|
|
@@ -354,14 +416,14 @@ class Strapi {
|
|
|
354
416
|
Object.defineProperty(reload, 'isWatching', {
|
|
355
417
|
configurable: true,
|
|
356
418
|
enumerable: true,
|
|
357
|
-
set
|
|
419
|
+
set(value) {
|
|
358
420
|
// Special state when the reloader is disabled temporarly (see GraphQL plugin example).
|
|
359
421
|
if (state.isWatching === false && value === true) {
|
|
360
422
|
state.shouldReload += 1;
|
|
361
423
|
}
|
|
362
424
|
state.isWatching = value;
|
|
363
425
|
},
|
|
364
|
-
get
|
|
426
|
+
get() {
|
|
365
427
|
return state.isWatching;
|
|
366
428
|
},
|
|
367
429
|
});
|
|
@@ -373,21 +435,14 @@ class Strapi {
|
|
|
373
435
|
}
|
|
374
436
|
|
|
375
437
|
async runLifecyclesFunctions(lifecycleName) {
|
|
376
|
-
const execLifecycle = async fn => {
|
|
377
|
-
if (!fn) {
|
|
378
|
-
return;
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
return fn({ strapi: this });
|
|
382
|
-
};
|
|
383
|
-
|
|
384
|
-
const configPath = `functions.${lifecycleName}`;
|
|
385
|
-
|
|
386
438
|
// plugins
|
|
387
439
|
await this.container.get('modules')[lifecycleName]();
|
|
388
440
|
|
|
389
441
|
// user
|
|
390
|
-
|
|
442
|
+
const lifecycleFunction = this.app[lifecycleName];
|
|
443
|
+
if (lifecycleFunction) {
|
|
444
|
+
await lifecycleFunction({ strapi: this });
|
|
445
|
+
}
|
|
391
446
|
|
|
392
447
|
// admin
|
|
393
448
|
await this.admin[lifecycleName](this);
|
|
@@ -400,7 +455,6 @@ class Strapi {
|
|
|
400
455
|
/**
|
|
401
456
|
* Binds queries with a specific model
|
|
402
457
|
* @param {string} uid
|
|
403
|
-
* @returns {}
|
|
404
458
|
*/
|
|
405
459
|
query(uid) {
|
|
406
460
|
return this.db.query(uid);
|
package/lib/commands/console.js
CHANGED
|
@@ -10,7 +10,7 @@ module.exports = () => {
|
|
|
10
10
|
// Now load up the Strapi framework for real.
|
|
11
11
|
const app = strapi();
|
|
12
12
|
|
|
13
|
-
app.start(() => {
|
|
13
|
+
app.start().then(() => {
|
|
14
14
|
const repl = REPL.start(app.config.info.name + ' > ' || 'strapi > '); // eslint-disable-line prefer-template
|
|
15
15
|
|
|
16
16
|
repl.on('exit', function(err) {
|
package/lib/commands/develop.js
CHANGED
|
@@ -27,8 +27,9 @@ module.exports = async function({ build, watchAdmin, polling, browser }) {
|
|
|
27
27
|
// Don't run the build process if the admin is in watch mode
|
|
28
28
|
if (build && !watchAdmin && serveAdminPanel && !buildExists) {
|
|
29
29
|
try {
|
|
30
|
-
execa.
|
|
30
|
+
execa.sync('npm run -s build -- --no-optimization', {
|
|
31
31
|
stdio: 'inherit',
|
|
32
|
+
shell: true,
|
|
32
33
|
});
|
|
33
34
|
} catch (err) {
|
|
34
35
|
process.exit(1);
|
|
@@ -124,8 +125,8 @@ function watchFileChanges({ dir, strapiInstance, watchIgnoreFiles, polling }) {
|
|
|
124
125
|
/tmp/,
|
|
125
126
|
'**/admin',
|
|
126
127
|
'**/admin/**',
|
|
127
|
-
'extensions/**/admin',
|
|
128
|
-
'extensions/**/admin/**',
|
|
128
|
+
'src/extensions/**/admin',
|
|
129
|
+
'src/extensions/**/admin/**',
|
|
129
130
|
'**/documentation',
|
|
130
131
|
'**/documentation/**',
|
|
131
132
|
'**/node_modules',
|
|
@@ -68,12 +68,10 @@ const createContentType = (uid, definition) => {
|
|
|
68
68
|
Object.assign(schema.attributes, {
|
|
69
69
|
[CREATED_AT_ATTRIBUTE]: {
|
|
70
70
|
type: 'datetime',
|
|
71
|
-
default: () => new Date(),
|
|
72
71
|
},
|
|
73
72
|
// TODO: handle on edit set to new date
|
|
74
73
|
[UPDATED_AT_ATTRIBUTE]: {
|
|
75
74
|
type: 'datetime',
|
|
76
|
-
default: () => new Date(),
|
|
77
75
|
},
|
|
78
76
|
});
|
|
79
77
|
|
|
@@ -110,11 +108,9 @@ const createContentType = (uid, definition) => {
|
|
|
110
108
|
private: isPrivate,
|
|
111
109
|
};
|
|
112
110
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
lifecycles: lifecycles,
|
|
117
|
-
};
|
|
111
|
+
Object.assign(schema, { actions, lifecycles });
|
|
112
|
+
|
|
113
|
+
return schema;
|
|
118
114
|
};
|
|
119
115
|
|
|
120
116
|
const getGlobalId = (model, modelName, prefix) => {
|
|
@@ -62,8 +62,8 @@ const createModule = (namespace, rawModule, strapi) => {
|
|
|
62
62
|
strapi.container.get('config').set(uidToPath(namespace), rawModule.config);
|
|
63
63
|
},
|
|
64
64
|
routes: rawModule.routes,
|
|
65
|
-
config(path) {
|
|
66
|
-
return strapi.container.get('config').get(`${uidToPath(namespace)}.${path}
|
|
65
|
+
config(path, defaultValue) {
|
|
66
|
+
return strapi.container.get('config').get(`${uidToPath(namespace)}.${path}`, defaultValue);
|
|
67
67
|
},
|
|
68
68
|
contentType(ctName) {
|
|
69
69
|
return strapi.container.get('content-types').get(`${namespace}.${ctName}`);
|
package/lib/core/loaders/apis.js
CHANGED
|
@@ -14,20 +14,18 @@ const DEFAULT_CONTENT_TYPE = {
|
|
|
14
14
|
};
|
|
15
15
|
|
|
16
16
|
module.exports = async strapi => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
if (!existsSync(apisDir)) {
|
|
20
|
-
throw new Error(`Missing api folder. Please create one in your app root directory`);
|
|
17
|
+
if (!existsSync(strapi.dirs.api)) {
|
|
18
|
+
throw new Error('Missing api folder. Please create one at `./src/api`');
|
|
21
19
|
}
|
|
22
20
|
|
|
23
|
-
const apisFDs = await fse.readdir(
|
|
21
|
+
const apisFDs = await fse.readdir(strapi.dirs.api, { withFileTypes: true });
|
|
24
22
|
const apis = {};
|
|
25
23
|
|
|
26
24
|
// only load folders
|
|
27
25
|
for (const apiFD of apisFDs) {
|
|
28
26
|
if (apiFD.isDirectory()) {
|
|
29
27
|
const apiName = normalizeName(apiFD.name);
|
|
30
|
-
const api = await loadAPI(join(
|
|
28
|
+
const api = await loadAPI(join(strapi.dirs.api, apiFD.name));
|
|
31
29
|
|
|
32
30
|
apis[apiName] = api;
|
|
33
31
|
}
|
|
@@ -6,19 +6,17 @@ const { pathExists } = require('fs-extra');
|
|
|
6
6
|
const loadFiles = require('../../load/load-files');
|
|
7
7
|
|
|
8
8
|
module.exports = async strapi => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
if (!(await pathExists(componentsDir))) {
|
|
9
|
+
if (!(await pathExists(strapi.dirs.components))) {
|
|
12
10
|
return {};
|
|
13
11
|
}
|
|
14
12
|
|
|
15
|
-
const map = await loadFiles(
|
|
13
|
+
const map = await loadFiles(strapi.dirs.components, '*/*.*(js|json)');
|
|
16
14
|
|
|
17
15
|
return Object.keys(map).reduce((acc, category) => {
|
|
18
16
|
Object.keys(map[category]).forEach(key => {
|
|
19
17
|
const schema = map[category][key];
|
|
20
18
|
|
|
21
|
-
const filePath = join(
|
|
19
|
+
const filePath = join(strapi.dirs.components, category, schema.__filename__);
|
|
22
20
|
|
|
23
21
|
if (!schema.collectionName) {
|
|
24
22
|
return strapi.stopWithError(
|
|
@@ -45,7 +45,7 @@ const createLoaders = strapi => {
|
|
|
45
45
|
loadMiddlewaresInDir(path.resolve(__dirname, '..', '..', 'middlewares'), middlewares);
|
|
46
46
|
|
|
47
47
|
const loadLocalMiddlewares = (appPath, middlewares) =>
|
|
48
|
-
loadMiddlewaresInDir(path.resolve(appPath, 'middlewares'), middlewares);
|
|
48
|
+
loadMiddlewaresInDir(path.resolve(appPath, 'src', 'middlewares'), middlewares);
|
|
49
49
|
|
|
50
50
|
const loadMiddlewareDependencies = async (packages, middlewares) => {
|
|
51
51
|
for (let packageName of packages) {
|
|
@@ -32,7 +32,7 @@ const toDetailedDeclaration = declaration => {
|
|
|
32
32
|
try {
|
|
33
33
|
pathToPlugin = dirname(require.resolve(declaration.resolve));
|
|
34
34
|
} catch (e) {
|
|
35
|
-
pathToPlugin = resolve(strapi.
|
|
35
|
+
pathToPlugin = resolve(strapi.dirs.root, declaration.resolve);
|
|
36
36
|
|
|
37
37
|
if (!existsSync(pathToPlugin) || !statSync(pathToPlugin).isDirectory()) {
|
|
38
38
|
throw new Error(`${declaration.resolve} couldn't be resolved`);
|
|
@@ -72,7 +72,7 @@ const getEnabledPlugins = async strapi => {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
const declaredPlugins = {};
|
|
75
|
-
const userPluginConfigPath = join(strapi.
|
|
75
|
+
const userPluginConfigPath = join(strapi.dirs.config, 'plugins.js');
|
|
76
76
|
const userPluginsConfig = existsSync(userPluginConfigPath)
|
|
77
77
|
? loadConfigFile(userPluginConfigPath)
|
|
78
78
|
: {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const { join
|
|
3
|
+
const { join } = require('path');
|
|
4
4
|
const { existsSync } = require('fs');
|
|
5
5
|
const { defaultsDeep, getOr, get } = require('lodash/fp');
|
|
6
6
|
const { env } = require('@strapi/utils');
|
|
@@ -9,12 +9,12 @@ const loadFiles = require('../../../load/load-files');
|
|
|
9
9
|
const getEnabledPlugins = require('./get-enabled-plugins');
|
|
10
10
|
|
|
11
11
|
const defaultPlugin = {
|
|
12
|
-
bootstrap
|
|
13
|
-
destroy
|
|
14
|
-
register
|
|
12
|
+
bootstrap() {},
|
|
13
|
+
destroy() {},
|
|
14
|
+
register() {},
|
|
15
15
|
config: {
|
|
16
16
|
default: {},
|
|
17
|
-
validator
|
|
17
|
+
validator() {},
|
|
18
18
|
},
|
|
19
19
|
routes: [],
|
|
20
20
|
controllers: {},
|
|
@@ -25,7 +25,7 @@ const defaultPlugin = {
|
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
const applyUserExtension = async plugins => {
|
|
28
|
-
const extensionsDir =
|
|
28
|
+
const extensionsDir = strapi.dirs.extensions;
|
|
29
29
|
if (!existsSync(extensionsDir)) {
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
@@ -62,7 +62,7 @@ const formatContentTypes = plugins => {
|
|
|
62
62
|
};
|
|
63
63
|
|
|
64
64
|
const applyUserConfig = plugins => {
|
|
65
|
-
const userPluginConfigPath = join(strapi.
|
|
65
|
+
const userPluginConfigPath = join(strapi.dirs.config, 'plugins.js');
|
|
66
66
|
const userPluginsConfig = existsSync(userPluginConfigPath)
|
|
67
67
|
? loadConfigFile(userPluginConfigPath)
|
|
68
68
|
: {};
|
|
@@ -5,7 +5,7 @@ const fse = require('fs-extra');
|
|
|
5
5
|
|
|
6
6
|
// TODO:: allow folders with index.js inside for bigger policies
|
|
7
7
|
module.exports = async function loadPolicies(strapi) {
|
|
8
|
-
const dir =
|
|
8
|
+
const dir = strapi.dirs.policies;
|
|
9
9
|
|
|
10
10
|
if (!(await fse.pathExists(dir))) {
|
|
11
11
|
return;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { resolve } = require('path');
|
|
4
|
+
const { statSync, existsSync } = require('fs');
|
|
5
|
+
const { yup } = require('@strapi/utils');
|
|
6
|
+
|
|
7
|
+
const srcSchema = yup
|
|
8
|
+
.object()
|
|
9
|
+
.shape({
|
|
10
|
+
bootstrap: yup.mixed().isFunction(),
|
|
11
|
+
register: yup.mixed().isFunction(),
|
|
12
|
+
})
|
|
13
|
+
.noUnknown();
|
|
14
|
+
|
|
15
|
+
const validateSrcIndex = srcIndex => {
|
|
16
|
+
return srcSchema.validateSync(srcIndex, { strict: true, abortEarly: false });
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
module.exports = strapi => {
|
|
20
|
+
if (!existsSync(strapi.dirs.src)) {
|
|
21
|
+
throw new Error('Missing src folder. Please create one at `./src`');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const pathToSrcIndex = resolve(strapi.dirs.src, 'index.js');
|
|
25
|
+
if (!existsSync(pathToSrcIndex) || statSync(pathToSrcIndex).isDirectory()) {
|
|
26
|
+
return {};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const srcIndex = require(pathToSrcIndex);
|
|
30
|
+
|
|
31
|
+
try {
|
|
32
|
+
validateSrcIndex(srcIndex);
|
|
33
|
+
} catch (e) {
|
|
34
|
+
strapi.stopWithError({ message: `Invalid file \`./src/index.js\`: ${e.message}` });
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return srcIndex;
|
|
38
|
+
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { pickBy, has } = require('lodash/fp');
|
|
4
|
+
const { addNamespace, hasNamespace } = require('../utils');
|
|
5
|
+
|
|
6
|
+
const hooksRegistry = () => {
|
|
7
|
+
const hooks = {};
|
|
8
|
+
|
|
9
|
+
return {
|
|
10
|
+
get(hookUID) {
|
|
11
|
+
return hooks[hookUID];
|
|
12
|
+
},
|
|
13
|
+
getAll(namespace) {
|
|
14
|
+
return pickBy((_, uid) => hasNamespace(uid, namespace))(hooks);
|
|
15
|
+
},
|
|
16
|
+
set(uid, hook) {
|
|
17
|
+
if (has(uid, hooks)) {
|
|
18
|
+
throw new Error(`hook ${uid} has already been registered.`);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
hooks[uid] = hook;
|
|
22
|
+
return this;
|
|
23
|
+
},
|
|
24
|
+
add(namespace, hooks) {
|
|
25
|
+
for (const hookName in hooks) {
|
|
26
|
+
const hook = hooks[hookName];
|
|
27
|
+
const uid = addNamespace(hookName, namespace);
|
|
28
|
+
|
|
29
|
+
this.set(uid, hook);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return this;
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
module.exports = hooksRegistry;
|
|
@@ -6,18 +6,18 @@ const { addNamespace, hasNamespace } = require('../utils');
|
|
|
6
6
|
|
|
7
7
|
const servicesRegistry = strapi => {
|
|
8
8
|
const services = {};
|
|
9
|
-
const
|
|
9
|
+
const instantiatedServices = {};
|
|
10
10
|
|
|
11
11
|
return {
|
|
12
12
|
get(uid) {
|
|
13
|
-
if (
|
|
14
|
-
return
|
|
13
|
+
if (instantiatedServices[uid]) {
|
|
14
|
+
return instantiatedServices[uid];
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
const service = services[uid];
|
|
18
18
|
if (service) {
|
|
19
|
-
|
|
20
|
-
return
|
|
19
|
+
instantiatedServices[uid] = service({ strapi });
|
|
20
|
+
return instantiatedServices[uid];
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
return undefined;
|
|
@@ -28,7 +28,7 @@ const servicesRegistry = strapi => {
|
|
|
28
28
|
return _.mapValues(filteredServices, (service, serviceUID) => this.get(serviceUID));
|
|
29
29
|
},
|
|
30
30
|
set(uid, value) {
|
|
31
|
-
|
|
31
|
+
instantiatedServices[uid] = value;
|
|
32
32
|
return this;
|
|
33
33
|
},
|
|
34
34
|
add(namespace, newServices) {
|
|
@@ -50,7 +50,7 @@ const servicesRegistry = strapi => {
|
|
|
50
50
|
throw new Error(`Service ${serviceUID} doesn't exist`);
|
|
51
51
|
}
|
|
52
52
|
const newService = extendFn(currentService);
|
|
53
|
-
|
|
53
|
+
instantiatedServices[serviceUID] = newService;
|
|
54
54
|
},
|
|
55
55
|
};
|
|
56
56
|
};
|
|
@@ -16,7 +16,7 @@ const createCollectionTypeController = ({ service, sanitize, transformResponse }
|
|
|
16
16
|
async find(ctx) {
|
|
17
17
|
const { query } = ctx;
|
|
18
18
|
|
|
19
|
-
const { results, pagination } = await service.find(
|
|
19
|
+
const { results, pagination } = await service.find(query);
|
|
20
20
|
|
|
21
21
|
return transformResponse(sanitize(results), { pagination });
|
|
22
22
|
},
|
|
@@ -30,7 +30,7 @@ const createCollectionTypeController = ({ service, sanitize, transformResponse }
|
|
|
30
30
|
const { id } = ctx.params;
|
|
31
31
|
const { query } = ctx;
|
|
32
32
|
|
|
33
|
-
const entity = await service.findOne(id,
|
|
33
|
+
const entity = await service.findOne(id, query);
|
|
34
34
|
|
|
35
35
|
return transformResponse(sanitize(entity));
|
|
36
36
|
},
|
|
@@ -45,7 +45,7 @@ const createCollectionTypeController = ({ service, sanitize, transformResponse }
|
|
|
45
45
|
|
|
46
46
|
const { data, files } = parseBody(ctx);
|
|
47
47
|
|
|
48
|
-
const entity = await service.create({
|
|
48
|
+
const entity = await service.create({ ...query, data, files });
|
|
49
49
|
|
|
50
50
|
return transformResponse(sanitize(entity));
|
|
51
51
|
},
|
|
@@ -61,7 +61,7 @@ const createCollectionTypeController = ({ service, sanitize, transformResponse }
|
|
|
61
61
|
|
|
62
62
|
const { data, files } = parseBody(ctx);
|
|
63
63
|
|
|
64
|
-
const entity = await service.update(id, {
|
|
64
|
+
const entity = await service.update(id, { ...query, data, files });
|
|
65
65
|
|
|
66
66
|
return transformResponse(sanitize(entity));
|
|
67
67
|
},
|
|
@@ -75,7 +75,7 @@ const createCollectionTypeController = ({ service, sanitize, transformResponse }
|
|
|
75
75
|
const { id } = ctx.params;
|
|
76
76
|
const { query } = ctx;
|
|
77
77
|
|
|
78
|
-
const entity = await service.delete(id,
|
|
78
|
+
const entity = await service.delete(id, query);
|
|
79
79
|
return transformResponse(sanitize(entity));
|
|
80
80
|
},
|
|
81
81
|
};
|
|
@@ -14,7 +14,7 @@ const createSingleTypeController = ({ service, sanitize, transformResponse }) =>
|
|
|
14
14
|
*/
|
|
15
15
|
async find(ctx) {
|
|
16
16
|
const { query } = ctx;
|
|
17
|
-
const entity = await service.find(
|
|
17
|
+
const entity = await service.find(query);
|
|
18
18
|
return transformResponse(sanitize(entity));
|
|
19
19
|
},
|
|
20
20
|
|
|
@@ -27,7 +27,7 @@ const createSingleTypeController = ({ service, sanitize, transformResponse }) =>
|
|
|
27
27
|
const { query } = ctx.request;
|
|
28
28
|
const { data, files } = parseBody(ctx);
|
|
29
29
|
|
|
30
|
-
const entity = await service.createOrUpdate({
|
|
30
|
+
const entity = await service.createOrUpdate({ ...query, data, files });
|
|
31
31
|
|
|
32
32
|
return transformResponse(sanitize(entity));
|
|
33
33
|
},
|
|
@@ -35,7 +35,7 @@ const createSingleTypeController = ({ service, sanitize, transformResponse }) =>
|
|
|
35
35
|
async delete(ctx) {
|
|
36
36
|
const { query } = ctx;
|
|
37
37
|
|
|
38
|
-
const entity = await service.delete(
|
|
38
|
+
const entity = await service.delete(query);
|
|
39
39
|
return transformResponse(sanitize(entity));
|
|
40
40
|
},
|
|
41
41
|
};
|