@strapi/strapi 4.0.0-beta.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.
Files changed (143) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +144 -0
  3. package/bin/strapi.js +186 -0
  4. package/lib/Strapi.js +470 -0
  5. package/lib/commands/admin-reset.js +51 -0
  6. package/lib/commands/build.js +56 -0
  7. package/lib/commands/configurationDump.js +50 -0
  8. package/lib/commands/configurationRestore.js +169 -0
  9. package/lib/commands/console.js +26 -0
  10. package/lib/commands/develop.js +157 -0
  11. package/lib/commands/generate-template.js +97 -0
  12. package/lib/commands/install.js +48 -0
  13. package/lib/commands/new.js +11 -0
  14. package/lib/commands/start.js +8 -0
  15. package/lib/commands/uninstall.js +68 -0
  16. package/lib/commands/watchAdmin.js +45 -0
  17. package/lib/container.js +45 -0
  18. package/lib/core/app-configuration/config-loader.js +20 -0
  19. package/lib/core/app-configuration/index.js +75 -0
  20. package/lib/core/app-configuration/load-config-file.js +43 -0
  21. package/lib/core/app-configuration/load-functions.js +28 -0
  22. package/lib/core/bootstrap.js +60 -0
  23. package/lib/core/domain/component/index.js +24 -0
  24. package/lib/core/domain/component/validator.js +29 -0
  25. package/lib/core/domain/content-type/index.js +140 -0
  26. package/lib/core/domain/content-type/validator.js +64 -0
  27. package/lib/core/domain/module/index.js +106 -0
  28. package/lib/core/domain/module/validation.js +36 -0
  29. package/lib/core/loaders/admin.js +16 -0
  30. package/lib/core/loaders/apis.js +157 -0
  31. package/lib/core/loaders/components.js +41 -0
  32. package/lib/core/loaders/index.js +11 -0
  33. package/lib/core/loaders/middlewares.js +86 -0
  34. package/lib/core/loaders/plugins/get-enabled-plugins.js +100 -0
  35. package/lib/core/loaders/plugins/index.js +109 -0
  36. package/lib/core/loaders/policies.js +28 -0
  37. package/lib/core/loaders/src-index.js +38 -0
  38. package/lib/core/registries/apis.js +43 -0
  39. package/lib/core/registries/config.js +21 -0
  40. package/lib/core/registries/content-types.js +53 -0
  41. package/lib/core/registries/controllers.js +43 -0
  42. package/lib/core/registries/hooks.js +37 -0
  43. package/lib/core/registries/middlewares.js +30 -0
  44. package/lib/core/registries/modules.js +44 -0
  45. package/lib/core/registries/plugins.js +28 -0
  46. package/lib/core/registries/policies.js +38 -0
  47. package/lib/core/registries/services.js +58 -0
  48. package/lib/core/utils.js +35 -0
  49. package/lib/core-api/controller/collection-type.js +84 -0
  50. package/lib/core-api/controller/index.js +26 -0
  51. package/lib/core-api/controller/single-type.js +44 -0
  52. package/lib/core-api/controller/transform.js +97 -0
  53. package/lib/core-api/index.js +39 -0
  54. package/lib/core-api/service/collection-type.js +84 -0
  55. package/lib/core-api/service/index.js +55 -0
  56. package/lib/core-api/service/pagination.js +125 -0
  57. package/lib/core-api/service/single-type.js +58 -0
  58. package/lib/index.d.ts +26 -0
  59. package/lib/index.js +3 -0
  60. package/lib/load/filepath-to-prop-path.js +22 -0
  61. package/lib/load/glob.js +15 -0
  62. package/lib/load/index.js +9 -0
  63. package/lib/load/load-files.js +56 -0
  64. package/lib/load/package-path.js +9 -0
  65. package/lib/middlewares/cors/index.js +66 -0
  66. package/lib/middlewares/error/defaults.json +5 -0
  67. package/lib/middlewares/error/index.js +147 -0
  68. package/lib/middlewares/favicon/defaults.json +7 -0
  69. package/lib/middlewares/favicon/index.js +31 -0
  70. package/lib/middlewares/gzip/defaults.json +6 -0
  71. package/lib/middlewares/gzip/index.js +19 -0
  72. package/lib/middlewares/helmet/defaults.json +18 -0
  73. package/lib/middlewares/helmet/index.js +9 -0
  74. package/lib/middlewares/index.js +120 -0
  75. package/lib/middlewares/ip/defaults.json +7 -0
  76. package/lib/middlewares/ip/index.js +25 -0
  77. package/lib/middlewares/logger/defaults.json +5 -0
  78. package/lib/middlewares/logger/index.js +37 -0
  79. package/lib/middlewares/parser/defaults.json +11 -0
  80. package/lib/middlewares/parser/index.js +75 -0
  81. package/lib/middlewares/poweredBy/defaults.json +5 -0
  82. package/lib/middlewares/poweredBy/index.js +16 -0
  83. package/lib/middlewares/public/assets/images/group_people_1.png +0 -0
  84. package/lib/middlewares/public/assets/images/group_people_2.png +0 -0
  85. package/lib/middlewares/public/assets/images/group_people_3.png +0 -0
  86. package/lib/middlewares/public/assets/images/logo_login.png +0 -0
  87. package/lib/middlewares/public/defaults.json +8 -0
  88. package/lib/middlewares/public/index.html +66 -0
  89. package/lib/middlewares/public/index.js +130 -0
  90. package/lib/middlewares/public/serve-static.js +23 -0
  91. package/lib/middlewares/responseTime/defaults.json +5 -0
  92. package/lib/middlewares/responseTime/index.js +25 -0
  93. package/lib/middlewares/responses/defaults.json +5 -0
  94. package/lib/middlewares/responses/index.js +19 -0
  95. package/lib/middlewares/router/defaults.json +7 -0
  96. package/lib/middlewares/router/index.js +97 -0
  97. package/lib/middlewares/session/defaults.json +18 -0
  98. package/lib/middlewares/session/index.js +140 -0
  99. package/lib/migrations/draft-publish.js +57 -0
  100. package/lib/services/auth/index.js +92 -0
  101. package/lib/services/core-store.js +145 -0
  102. package/lib/services/cron.js +54 -0
  103. package/lib/services/entity-service/components.js +365 -0
  104. package/lib/services/entity-service/index.d.ts +91 -0
  105. package/lib/services/entity-service/index.js +244 -0
  106. package/lib/services/entity-service/params.js +145 -0
  107. package/lib/services/entity-validator/index.js +187 -0
  108. package/lib/services/entity-validator/validators.js +123 -0
  109. package/lib/services/event-hub.js +15 -0
  110. package/lib/services/fs.js +58 -0
  111. package/lib/services/metrics/index.js +104 -0
  112. package/lib/services/metrics/is-truthy.js +9 -0
  113. package/lib/services/metrics/middleware.js +33 -0
  114. package/lib/services/metrics/rate-limiter.js +27 -0
  115. package/lib/services/metrics/sender.js +76 -0
  116. package/lib/services/metrics/stringify-deep.js +22 -0
  117. package/lib/services/server/admin-api.js +14 -0
  118. package/lib/services/server/api.js +32 -0
  119. package/lib/services/server/compose-endpoint.js +112 -0
  120. package/lib/services/server/content-api.js +16 -0
  121. package/lib/services/server/http-server.js +64 -0
  122. package/lib/services/server/index.js +108 -0
  123. package/lib/services/server/middleware.js +28 -0
  124. package/lib/services/server/policy.js +34 -0
  125. package/lib/services/server/routing.js +107 -0
  126. package/lib/services/utils/upload-files.js +79 -0
  127. package/lib/services/webhook-runner.js +155 -0
  128. package/lib/services/webhook-store.js +91 -0
  129. package/lib/services/worker-queue.js +58 -0
  130. package/lib/utils/addSlash.js +10 -0
  131. package/lib/utils/ee.js +123 -0
  132. package/lib/utils/get-dirs.js +15 -0
  133. package/lib/utils/get-prefixed-dependencies.js +7 -0
  134. package/lib/utils/index.js +11 -0
  135. package/lib/utils/is-initialized.js +23 -0
  136. package/lib/utils/open-browser.js +12 -0
  137. package/lib/utils/resources/key.pub +9 -0
  138. package/lib/utils/run-checks.js +22 -0
  139. package/lib/utils/startup-logger.js +90 -0
  140. package/lib/utils/success.js +31 -0
  141. package/lib/utils/update-notifier/index.js +97 -0
  142. package/lib/utils/url-from-segments.js +12 -0
  143. package/package.json +133 -0
package/lib/Strapi.js ADDED
@@ -0,0 +1,470 @@
1
+ 'use strict';
2
+
3
+ const _ = require('lodash');
4
+ const { createLogger } = require('@strapi/logger');
5
+ const { Database } = require('@strapi/database');
6
+ const { createAsyncParallelHook } = require('@strapi/utils').hooks;
7
+
8
+ const loadConfiguration = require('./core/app-configuration');
9
+
10
+ const { createContainer } = require('./container');
11
+ const utils = require('./utils');
12
+ const initializeMiddlewares = require('./middlewares');
13
+ const createStrapiFs = require('./services/fs');
14
+ const createEventHub = require('./services/event-hub');
15
+ const { createServer } = require('./services/server');
16
+ const createWebhookRunner = require('./services/webhook-runner');
17
+ const { webhookModel, createWebhookStore } = require('./services/webhook-store');
18
+ const { createCoreStore, coreStoreModel } = require('./services/core-store');
19
+ const createEntityService = require('./services/entity-service');
20
+ const createCronService = require('./services/cron');
21
+ const entityValidator = require('./services/entity-validator');
22
+ const createTelemetry = require('./services/metrics');
23
+ const createAuth = require('./services/auth');
24
+ const createUpdateNotifier = require('./utils/update-notifier');
25
+ const createStartupLogger = require('./utils/startup-logger');
26
+ const ee = require('./utils/ee');
27
+ const contentTypesRegistry = require('./core/registries/content-types');
28
+ const servicesRegistry = require('./core/registries/services');
29
+ const policiesRegistry = require('./core/registries/policies');
30
+ const middlewaresRegistry = require('./core/registries/middlewares');
31
+ const hooksRegistry = require('./core/registries/hooks');
32
+ const controllersRegistry = require('./core/registries/controllers');
33
+ const modulesRegistry = require('./core/registries/modules');
34
+ const pluginsRegistry = require('./core/registries/plugins');
35
+ const createConfigProvider = require('./core/registries/config');
36
+ const apisRegistry = require('./core/registries/apis');
37
+ const bootstrap = require('./core/bootstrap');
38
+ const loaders = require('./core/loaders');
39
+
40
+ // TODO: move somewhere else
41
+ const draftAndPublishSync = require('./migrations/draft-publish');
42
+
43
+ const LIFECYCLES = {
44
+ REGISTER: 'register',
45
+ BOOTSTRAP: 'bootstrap',
46
+ };
47
+
48
+ class Strapi {
49
+ constructor(opts = {}) {
50
+ this.dirs = utils.getDirs(opts.dir || process.cwd());
51
+ const appConfig = loadConfiguration(this.dirs.root, opts);
52
+ this.container = createContainer(this);
53
+ this.container.register('config', createConfigProvider(appConfig));
54
+ this.container.register('content-types', contentTypesRegistry(this));
55
+ this.container.register('services', servicesRegistry(this));
56
+ this.container.register('policies', policiesRegistry(this));
57
+ this.container.register('middlewares', middlewaresRegistry(this));
58
+ this.container.register('hooks', hooksRegistry(this));
59
+ this.container.register('controllers', controllersRegistry(this));
60
+ this.container.register('modules', modulesRegistry(this));
61
+ this.container.register('plugins', pluginsRegistry(this));
62
+ this.container.register('apis', apisRegistry(this));
63
+ this.container.register('auth', createAuth(this));
64
+
65
+ this.isLoaded = false;
66
+ this.reload = this.reload();
67
+ this.server = createServer(this);
68
+
69
+ this.fs = createStrapiFs(this);
70
+ this.eventHub = createEventHub();
71
+ this.startupLogger = createStartupLogger(this);
72
+ this.log = createLogger(this.config.get('logger', {}));
73
+ this.cron = createCronService();
74
+
75
+ createUpdateNotifier(this).notify();
76
+ }
77
+
78
+ get config() {
79
+ return this.container.get('config');
80
+ }
81
+
82
+ get EE() {
83
+ return ee({ dir: this.dirs.root, logger: this.log });
84
+ }
85
+
86
+ service(uid) {
87
+ return this.container.get('services').get(uid);
88
+ }
89
+
90
+ controller(uid) {
91
+ return this.container.get('controllers').get(uid);
92
+ }
93
+
94
+ contentType(name) {
95
+ return this.container.get('content-types').get(name);
96
+ }
97
+
98
+ get contentTypes() {
99
+ return this.container.get('content-types').getAll();
100
+ }
101
+
102
+ policy(name) {
103
+ return this.container.get('policies').get(name);
104
+ }
105
+
106
+ middleware(name) {
107
+ return this.container.get('middlewares').get(name);
108
+ }
109
+
110
+ plugin(name) {
111
+ return this.container.get('plugins').get(name);
112
+ }
113
+
114
+ get plugins() {
115
+ return this.container.get('plugins').getAll();
116
+ }
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
+
126
+ // api(name) {
127
+ // return this.container.get('apis').get(name);
128
+ // }
129
+
130
+ get api() {
131
+ return this.container.get('apis').getAll();
132
+ }
133
+
134
+ get auth() {
135
+ return this.container.get('auth');
136
+ }
137
+
138
+ async start() {
139
+ try {
140
+ if (!this.isLoaded) {
141
+ await this.load();
142
+ }
143
+
144
+ await this.listen();
145
+
146
+ return this;
147
+ } catch (error) {
148
+ return this.stopWithError(error);
149
+ }
150
+ }
151
+
152
+ async destroy() {
153
+ await this.server.destroy();
154
+
155
+ await Promise.all(
156
+ Object.values(this.plugins).map(plugin => {
157
+ if (_.has(plugin, 'destroy') && typeof plugin.destroy === 'function') {
158
+ return plugin.destroy();
159
+ }
160
+ })
161
+ );
162
+
163
+ if (_.has(this, 'admin')) {
164
+ await this.admin.destroy();
165
+ }
166
+
167
+ this.eventHub.removeAllListeners();
168
+
169
+ if (_.has(this, 'db')) {
170
+ await this.db.destroy();
171
+ }
172
+
173
+ this.telemetry.destroy();
174
+ this.cron.destroy();
175
+
176
+ delete global.strapi;
177
+ }
178
+
179
+ sendStartupTelemetry() {
180
+ // Get database clients
181
+ const databaseClients = _.map(this.config.get('connections'), _.property('settings.client'));
182
+
183
+ // Emit started event.
184
+ // do not await to avoid slower startup
185
+ this.telemetry.send('didStartServer', {
186
+ database: databaseClients,
187
+ plugins: this.config.installedPlugins,
188
+ providers: this.config.installedProviders,
189
+ });
190
+ }
191
+
192
+ async openAdmin({ isInitialized }) {
193
+ const shouldOpenAdmin =
194
+ this.config.get('environment') === 'development' &&
195
+ this.config.get('server.admin.autoOpen', true) !== false;
196
+
197
+ if (shouldOpenAdmin && !isInitialized) {
198
+ await utils.openBrowser(this.config);
199
+ }
200
+ }
201
+
202
+ async postListen() {
203
+ const isInitialized = await utils.isInitialized(this);
204
+
205
+ this.startupLogger.logStartupMessage({ isInitialized });
206
+
207
+ this.sendStartupTelemetry();
208
+ this.openAdmin({ isInitialized });
209
+ }
210
+
211
+ /**
212
+ * Add behaviors to the server
213
+ */
214
+ async listen() {
215
+ return new Promise((resolve, reject) => {
216
+ const onListen = async error => {
217
+ if (error) {
218
+ return reject(error);
219
+ }
220
+
221
+ try {
222
+ await this.postListen();
223
+
224
+ resolve();
225
+ } catch (error) {
226
+ reject(error);
227
+ }
228
+ };
229
+
230
+ const listenSocket = this.config.get('server.socket');
231
+
232
+ if (listenSocket) {
233
+ return this.server.listen(listenSocket, onListen);
234
+ }
235
+
236
+ const { host, port } = this.config.get('server');
237
+ return this.server.listen(port, host, onListen);
238
+ });
239
+ }
240
+
241
+ stopWithError(err, customMessage) {
242
+ this.log.debug(`⛔️ Server wasn't able to start properly.`);
243
+ if (customMessage) {
244
+ this.log.error(customMessage);
245
+ }
246
+
247
+ this.log.error(err);
248
+ return this.stop();
249
+ }
250
+
251
+ stop(exitCode = 1) {
252
+ this.server.destroy();
253
+
254
+ if (this.config.get('autoReload')) {
255
+ process.send('stop');
256
+ }
257
+
258
+ // Kill process
259
+ process.exit(exitCode);
260
+ }
261
+
262
+ async loadAdmin() {
263
+ await loaders.loadAdmin(this);
264
+ }
265
+
266
+ async loadPlugins() {
267
+ await loaders.loadPlugins(this);
268
+ }
269
+
270
+ async loadPolicies() {
271
+ await loaders.loadPolicies(this);
272
+ }
273
+
274
+ async loadAPIs() {
275
+ await loaders.loadAPIs(this);
276
+ }
277
+
278
+ async loadComponents() {
279
+ this.components = await loaders.loadComponents(this);
280
+ }
281
+
282
+ async loadMiddlewares() {
283
+ this.middleware = await loaders.loadMiddlewares(this);
284
+ }
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
+
298
+ async load() {
299
+ await Promise.all([
300
+ this.loadApp(),
301
+ this.loadPlugins(),
302
+ this.loadAdmin(),
303
+ this.loadAPIs(),
304
+ this.loadComponents(),
305
+ this.loadMiddlewares(),
306
+ this.loadPolicies(),
307
+ ]);
308
+
309
+ await bootstrap({ strapi: this });
310
+
311
+ // init webhook runner
312
+ this.webhookRunner = createWebhookRunner({
313
+ eventHub: this.eventHub,
314
+ logger: this.log,
315
+ configuration: this.config.get('server.webhooks', {}),
316
+ });
317
+
318
+ this.registerInternalHooks();
319
+
320
+ await this.runLifecyclesFunctions(LIFECYCLES.REGISTER);
321
+
322
+ const contentTypes = [
323
+ coreStoreModel,
324
+ webhookModel,
325
+ ...Object.values(strapi.contentTypes),
326
+ ...Object.values(strapi.components),
327
+ ];
328
+
329
+ this.db = await Database.init({
330
+ ...this.config.get('database'),
331
+ models: Database.transformContentTypes(contentTypes),
332
+ });
333
+
334
+ this.store = createCoreStore({ db: this.db });
335
+ this.webhookStore = createWebhookStore({ db: this.db });
336
+
337
+ this.entityValidator = entityValidator;
338
+ this.entityService = createEntityService({
339
+ strapi: this,
340
+ db: this.db,
341
+ eventHub: this.eventHub,
342
+ entityValidator: this.entityValidator,
343
+ });
344
+
345
+ const cronTasks = this.config.get('server.cron.tasks', {});
346
+ this.cron.add(cronTasks);
347
+
348
+ this.telemetry = createTelemetry(this);
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
+
380
+ // Initialize middlewares.
381
+ await initializeMiddlewares(this);
382
+
383
+ await this.runLifecyclesFunctions(LIFECYCLES.BOOTSTRAP);
384
+
385
+ this.cron.start();
386
+
387
+ this.isLoaded = true;
388
+
389
+ return this;
390
+ }
391
+
392
+ async startWebhooks() {
393
+ const webhooks = await this.webhookStore.findWebhooks();
394
+ webhooks.forEach(webhook => this.webhookRunner.add(webhook));
395
+ }
396
+
397
+ reload() {
398
+ const state = {
399
+ shouldReload: 0,
400
+ };
401
+
402
+ const reload = function() {
403
+ if (state.shouldReload > 0) {
404
+ // Reset the reloading state
405
+ state.shouldReload -= 1;
406
+ reload.isReloading = false;
407
+ return;
408
+ }
409
+
410
+ if (this.config.get('autoReload')) {
411
+ this.server.destroy();
412
+ process.send('reload');
413
+ }
414
+ };
415
+
416
+ Object.defineProperty(reload, 'isWatching', {
417
+ configurable: true,
418
+ enumerable: true,
419
+ set(value) {
420
+ // Special state when the reloader is disabled temporarly (see GraphQL plugin example).
421
+ if (state.isWatching === false && value === true) {
422
+ state.shouldReload += 1;
423
+ }
424
+ state.isWatching = value;
425
+ },
426
+ get() {
427
+ return state.isWatching;
428
+ },
429
+ });
430
+
431
+ reload.isReloading = false;
432
+ reload.isWatching = true;
433
+
434
+ return reload;
435
+ }
436
+
437
+ async runLifecyclesFunctions(lifecycleName) {
438
+ // plugins
439
+ await this.container.get('modules')[lifecycleName]();
440
+
441
+ // user
442
+ const lifecycleFunction = this.app[lifecycleName];
443
+ if (lifecycleFunction) {
444
+ await lifecycleFunction({ strapi: this });
445
+ }
446
+
447
+ // admin
448
+ await this.admin[lifecycleName]({ strapi: this });
449
+ }
450
+
451
+ getModel(uid) {
452
+ return this.contentTypes[uid] || this.components[uid];
453
+ }
454
+
455
+ /**
456
+ * Binds queries with a specific model
457
+ * @param {string} uid
458
+ */
459
+ query(uid) {
460
+ return this.db.query(uid);
461
+ }
462
+ }
463
+
464
+ module.exports = options => {
465
+ const strapi = new Strapi(options);
466
+ global.strapi = strapi;
467
+ return strapi;
468
+ };
469
+
470
+ module.exports.Strapi = Strapi;
@@ -0,0 +1,51 @@
1
+ 'use strict';
2
+
3
+ const _ = require('lodash');
4
+ const inquirer = require('inquirer');
5
+ const strapi = require('../index');
6
+
7
+ const promptQuestions = [
8
+ { type: 'input', name: 'email', message: 'User email?' },
9
+ { type: 'password', name: 'password', message: 'New password?' },
10
+ {
11
+ type: 'confirm',
12
+ name: 'confirm',
13
+ message: "Do you really want to reset this user's password?",
14
+ },
15
+ ];
16
+
17
+ /**
18
+ * Reset user's password
19
+ * @param {Object} cmdOptions - command options
20
+ * @param {string} cmdOptions.email - user's email
21
+ * @param {string} cmdOptions.password - user's new password
22
+ */
23
+ module.exports = async function(cmdOptions = {}) {
24
+ const { email, password } = cmdOptions;
25
+
26
+ if (_.isEmpty(email) && _.isEmpty(password) && process.stdin.isTTY) {
27
+ const inquiry = await inquirer.prompt(promptQuestions);
28
+
29
+ if (!inquiry.confirm) {
30
+ process.exit(0);
31
+ }
32
+
33
+ return changePassword(inquiry);
34
+ }
35
+
36
+ if (_.isEmpty(email) || _.isEmpty(password)) {
37
+ console.error('Missing required options `email` or `password`');
38
+ process.exit(1);
39
+ }
40
+
41
+ return changePassword({ email, password });
42
+ };
43
+
44
+ async function changePassword({ email, password }) {
45
+ const app = await strapi().load();
46
+
47
+ await app.admin.services.user.resetPasswordByEmail(email, password);
48
+
49
+ console.log(`Successfully reset user's password`);
50
+ process.exit(0);
51
+ }
@@ -0,0 +1,56 @@
1
+ 'use strict';
2
+ const { green } = require('chalk');
3
+
4
+ const strapiAdmin = require('@strapi/admin');
5
+ const { getConfigUrls } = require('@strapi/utils');
6
+
7
+ const ee = require('../utils/ee');
8
+ const addSlash = require('../utils/addSlash');
9
+ const strapi = require('../index');
10
+ const getEnabledPlugins = require('../core/loaders/plugins/get-enabled-plugins');
11
+
12
+ /**
13
+ * `$ strapi build`
14
+ */
15
+ module.exports = async ({ clean, optimization }) => {
16
+ const dir = process.cwd();
17
+
18
+ const strapiInstance = strapi({
19
+ dir,
20
+ autoReload: true,
21
+ serveAdminPanel: false,
22
+ });
23
+
24
+ const plugins = await getEnabledPlugins(strapiInstance);
25
+
26
+ const env = strapiInstance.config.get('environment');
27
+ const { serverUrl, adminPath } = getConfigUrls(strapiInstance.config.get('server'), true);
28
+
29
+ console.log(`Building your admin UI with ${green(env)} configuration ...`);
30
+
31
+ if (clean) {
32
+ await strapiAdmin.clean({ dir });
33
+ }
34
+
35
+ ee({ dir });
36
+
37
+ return strapiAdmin
38
+ .build({
39
+ dir,
40
+ plugins,
41
+ // front end build env is always production for now
42
+ env: 'production',
43
+ optimize: optimization,
44
+ options: {
45
+ backend: serverUrl,
46
+ adminPath: addSlash(adminPath),
47
+ },
48
+ })
49
+ .then(() => {
50
+ process.exit();
51
+ })
52
+ .catch(err => {
53
+ console.error(err);
54
+ process.exit(1);
55
+ });
56
+ };
@@ -0,0 +1,50 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const strapi = require('../index');
5
+
6
+ const CHUNK_SIZE = 100;
7
+
8
+ /**
9
+ * Will dump configurations to a file or stdout
10
+ * @param {string} file filepath to use as output
11
+ */
12
+ module.exports = async function({ file: filePath, pretty }) {
13
+ const output = filePath ? fs.createWriteStream(filePath) : process.stdout;
14
+
15
+ const app = await strapi().load();
16
+
17
+ const count = await app.query('strapi::core-store').count();
18
+
19
+ const exportData = [];
20
+
21
+ const pageCount = Math.ceil(count / CHUNK_SIZE);
22
+
23
+ for (let page = 0; page < pageCount; page++) {
24
+ const results = await app
25
+ .query('strapi::core-store')
26
+ .findMany({ limit: CHUNK_SIZE, offset: page * CHUNK_SIZE, orderBy: 'key' });
27
+
28
+ results
29
+ .filter(result => result.key.startsWith('plugin_'))
30
+ .forEach(result => {
31
+ exportData.push({
32
+ key: result.key,
33
+ value: result.value,
34
+ type: result.type,
35
+ environment: result.environment,
36
+ tag: result.tag,
37
+ });
38
+ });
39
+ }
40
+
41
+ output.write(JSON.stringify(exportData, null, pretty ? 2 : null));
42
+ output.write('\n');
43
+ output.end();
44
+
45
+ // log success only when writting to file
46
+ if (filePath) {
47
+ console.log(`Successfully exported ${exportData.length} configuration entries`);
48
+ }
49
+ process.exit(0);
50
+ };