@strapi/strapi 4.2.0 → 4.3.0-beta.1
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 -0
- package/lib/Strapi.js +37 -8
- package/lib/commands/admin-create.js +2 -1
- package/lib/commands/admin-reset.js +2 -1
- package/lib/commands/build.js +8 -46
- package/lib/commands/builders/admin.js +56 -0
- package/lib/commands/builders/index.js +9 -0
- package/lib/commands/builders/typescript.js +32 -0
- package/lib/commands/configurationDump.js +2 -1
- package/lib/commands/configurationRestore.js +3 -1
- package/lib/commands/console.js +4 -3
- package/lib/commands/content-types/list.js +2 -1
- package/lib/commands/controllers/list.js +2 -1
- package/lib/commands/develop.js +111 -74
- package/lib/commands/hooks/list.js +2 -1
- package/lib/commands/middlewares/list.js +2 -1
- package/lib/commands/policies/list.js +2 -1
- package/lib/commands/routes/list.js +2 -1
- package/lib/commands/services/list.js +2 -1
- package/lib/commands/start.js +18 -2
- package/lib/commands/watchAdmin.js +5 -10
- package/lib/compile.js +20 -0
- package/lib/core/app-configuration/index.js +4 -3
- package/lib/core/app-configuration/load-config-file.js +3 -1
- package/lib/core/bootstrap.js +2 -2
- package/lib/core/loaders/apis.js +6 -5
- package/lib/core/loaders/components.js +5 -4
- package/lib/core/loaders/middlewares.js +4 -2
- package/lib/core/loaders/plugins/get-enabled-plugins.js +2 -1
- package/lib/core/loaders/plugins/get-user-plugins-config.js +2 -2
- package/lib/core/loaders/plugins/index.js +1 -1
- package/lib/core/loaders/policies.js +4 -2
- package/lib/core/loaders/src-index.js +6 -4
- package/lib/core/registries/policies.d.ts +1 -1
- package/lib/core-api/controller/index.d.ts +16 -14
- package/lib/core-api/service/index.d.ts +10 -9
- package/lib/factories.d.ts +22 -18
- package/lib/index.d.ts +7 -6
- package/lib/index.js +1 -0
- package/lib/load/load-files.js +3 -1
- package/lib/middlewares/favicon.js +1 -1
- package/lib/middlewares/public/index.js +1 -1
- package/lib/services/entity-service/index.d.ts +7 -1
- package/lib/services/entity-service/index.js +11 -1
- package/lib/services/fs.js +1 -1
- package/lib/services/metrics/index.js +5 -1
- package/lib/services/metrics/sender.js +7 -0
- package/lib/services/server/middleware.js +1 -1
- package/lib/services/utils/upload-files.js +1 -1
- package/lib/types/strapi.d.ts +370 -0
- package/lib/types/utils.d.ts +1 -0
- package/lib/utils/get-dirs.js +24 -10
- package/lib/utils/import-default.js +10 -0
- package/lib/utils/index.js +2 -0
- package/lib/utils/lifecycles.js +15 -0
- package/lib/utils/update-notifier/index.js +1 -1
- package/package.json +15 -13
package/lib/commands/start.js
CHANGED
|
@@ -1,8 +1,24 @@
|
|
|
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 () => {
|
|
10
|
+
const appDir = process.cwd();
|
|
11
|
+
|
|
12
|
+
const isTSProject = await tsUtils.isUsingTypeScript(appDir);
|
|
13
|
+
|
|
14
|
+
const outDir = await tsUtils.resolveOutDir(appDir);
|
|
15
|
+
const distDir = isTSProject ? outDir : appDir;
|
|
16
|
+
|
|
17
|
+
const buildDirExists = fs.existsSync(outDir);
|
|
18
|
+
if (isTSProject && !buildDirExists)
|
|
19
|
+
throw new Error(
|
|
20
|
+
`${outDir} directory not found. Please run the build command before starting your application`
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
return strapi({ appDir, distDir }).start();
|
|
24
|
+
};
|
|
@@ -3,16 +3,15 @@
|
|
|
3
3
|
const strapiAdmin = require('@strapi/admin');
|
|
4
4
|
const { getConfigUrls, getAbsoluteServerUrl } = require('@strapi/utils');
|
|
5
5
|
|
|
6
|
-
const
|
|
6
|
+
const getEnabledPlugins = require('../core/loaders/plugins/get-enabled-plugins');
|
|
7
7
|
const addSlash = require('../utils/addSlash');
|
|
8
8
|
const strapi = require('../index');
|
|
9
|
-
const getEnabledPlugins = require('../core/loaders/plugins/get-enabled-plugins');
|
|
10
9
|
|
|
11
10
|
module.exports = async function({ browser }) {
|
|
12
|
-
const
|
|
11
|
+
const appContext = await strapi.compile();
|
|
13
12
|
|
|
14
13
|
const strapiInstance = strapi({
|
|
15
|
-
|
|
14
|
+
...appContext,
|
|
16
15
|
autoReload: true,
|
|
17
16
|
serveAdminPanel: false,
|
|
18
17
|
});
|
|
@@ -23,14 +22,12 @@ module.exports = async function({ browser }) {
|
|
|
23
22
|
|
|
24
23
|
const adminPort = strapiInstance.config.get('admin.port', 8000);
|
|
25
24
|
const adminHost = strapiInstance.config.get('admin.host', 'localhost');
|
|
26
|
-
const adminWatchIgnoreFiles = strapiInstance.config.get('admin.watchIgnoreFiles', []);
|
|
27
25
|
|
|
28
26
|
const backendURL = getAbsoluteServerUrl(strapiInstance.config, true);
|
|
29
27
|
|
|
30
|
-
ee({ dir });
|
|
31
|
-
|
|
32
28
|
strapiAdmin.watchAdmin({
|
|
33
|
-
|
|
29
|
+
appDir: appContext.appDir,
|
|
30
|
+
buildDestDir: appContext.distDir,
|
|
34
31
|
plugins,
|
|
35
32
|
port: adminPort,
|
|
36
33
|
host: adminHost,
|
|
@@ -38,8 +35,6 @@ module.exports = async function({ browser }) {
|
|
|
38
35
|
options: {
|
|
39
36
|
backend: backendURL,
|
|
40
37
|
adminPath: addSlash(adminPath),
|
|
41
|
-
watchIgnoreFiles: adminWatchIgnoreFiles,
|
|
42
|
-
features: ee.isEE ? ee.features.getEnabled() : [],
|
|
43
38
|
},
|
|
44
39
|
});
|
|
45
40
|
};
|
package/lib/compile.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const tsUtils = require('@strapi/typescript-utils');
|
|
4
|
+
|
|
5
|
+
module.exports = async dir => {
|
|
6
|
+
const appDir = dir || process.cwd();
|
|
7
|
+
const isTSProject = await tsUtils.isUsingTypeScript(appDir);
|
|
8
|
+
const outDir = await tsUtils.resolveOutDir(appDir);
|
|
9
|
+
|
|
10
|
+
if (isTSProject) {
|
|
11
|
+
await tsUtils.compile(appDir, {
|
|
12
|
+
watch: false,
|
|
13
|
+
configOptions: { options: { incremental: true } },
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const distDir = isTSProject ? outDir : appDir;
|
|
18
|
+
|
|
19
|
+
return { appDir, distDir };
|
|
20
|
+
};
|
|
@@ -31,12 +31,13 @@ const defaultConfig = {
|
|
|
31
31
|
},
|
|
32
32
|
};
|
|
33
33
|
|
|
34
|
-
module.exports = (
|
|
34
|
+
module.exports = (dirs, initialConfig = {}) => {
|
|
35
|
+
const { appDir, distDir } = dirs;
|
|
35
36
|
const { autoReload = false, serveAdminPanel = true } = initialConfig;
|
|
36
37
|
|
|
37
|
-
const pkgJSON = require(path.resolve(
|
|
38
|
+
const pkgJSON = require(path.resolve(appDir, 'package.json'));
|
|
38
39
|
|
|
39
|
-
const configDir = path.resolve(
|
|
40
|
+
const configDir = path.resolve(distDir || process.cwd(), 'config');
|
|
40
41
|
|
|
41
42
|
const rootConfig = {
|
|
42
43
|
launchedAt: Date.now(),
|
|
@@ -4,9 +4,11 @@ const path = require('path');
|
|
|
4
4
|
const fs = require('fs');
|
|
5
5
|
const { templateConfiguration, env } = require('@strapi/utils');
|
|
6
6
|
|
|
7
|
+
const importDefault = require('../../utils/import-default');
|
|
8
|
+
|
|
7
9
|
const loadJsFile = file => {
|
|
8
10
|
try {
|
|
9
|
-
const jsModule =
|
|
11
|
+
const jsModule = importDefault(file);
|
|
10
12
|
|
|
11
13
|
// call if function
|
|
12
14
|
if (typeof jsModule === 'function') {
|
package/lib/core/bootstrap.js
CHANGED
|
@@ -25,9 +25,9 @@ module.exports = async function({ strapi }) {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
// ensure public repository exists
|
|
28
|
-
if (!(await fse.pathExists(strapi.dirs.public))) {
|
|
28
|
+
if (!(await fse.pathExists(strapi.dirs.static.public))) {
|
|
29
29
|
throw new Error(
|
|
30
|
-
`The public folder (${strapi.dirs.public}) doesn't exist or is not accessible. Please make sure it exists.`
|
|
30
|
+
`The public folder (${strapi.dirs.static.public}) doesn't exist or is not accessible. Please make sure it exists.`
|
|
31
31
|
);
|
|
32
32
|
}
|
|
33
33
|
};
|
package/lib/core/loaders/apis.js
CHANGED
|
@@ -5,6 +5,7 @@ const { existsSync } = require('fs-extra');
|
|
|
5
5
|
const _ = require('lodash');
|
|
6
6
|
const fse = require('fs-extra');
|
|
7
7
|
const { isKebabCase } = require('@strapi/utils');
|
|
8
|
+
const { importDefault } = require('../../utils');
|
|
8
9
|
|
|
9
10
|
const DEFAULT_CONTENT_TYPE = {
|
|
10
11
|
schema: {},
|
|
@@ -19,11 +20,11 @@ const isDirectory = fd => fd.isDirectory();
|
|
|
19
20
|
const isDotFile = fd => fd.name.startsWith('.');
|
|
20
21
|
|
|
21
22
|
module.exports = async strapi => {
|
|
22
|
-
if (!existsSync(strapi.dirs.api)) {
|
|
23
|
-
|
|
23
|
+
if (!existsSync(strapi.dirs.dist.api)) {
|
|
24
|
+
return;
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
const apisFDs = await (await fse.readdir(strapi.dirs.api, { withFileTypes: true }))
|
|
27
|
+
const apisFDs = await (await fse.readdir(strapi.dirs.dist.api, { withFileTypes: true }))
|
|
27
28
|
.filter(isDirectory)
|
|
28
29
|
.filter(_.negate(isDotFile));
|
|
29
30
|
|
|
@@ -32,7 +33,7 @@ module.exports = async strapi => {
|
|
|
32
33
|
// only load folders
|
|
33
34
|
for (const apiFD of apisFDs) {
|
|
34
35
|
const apiName = normalizeName(apiFD.name);
|
|
35
|
-
const api = await loadAPI(join(strapi.dirs.api, apiFD.name));
|
|
36
|
+
const api = await loadAPI(join(strapi.dirs.dist.api, apiFD.name));
|
|
36
37
|
|
|
37
38
|
apis[apiName] = api;
|
|
38
39
|
}
|
|
@@ -154,7 +155,7 @@ const loadFile = file => {
|
|
|
154
155
|
|
|
155
156
|
switch (ext) {
|
|
156
157
|
case '.js':
|
|
157
|
-
return
|
|
158
|
+
return importDefault(file);
|
|
158
159
|
case '.json':
|
|
159
160
|
return fse.readJSON(file);
|
|
160
161
|
default:
|
|
@@ -6,19 +6,20 @@ const { pathExists } = require('fs-extra');
|
|
|
6
6
|
const loadFiles = require('../../load/load-files');
|
|
7
7
|
|
|
8
8
|
module.exports = async strapi => {
|
|
9
|
-
if (!(await pathExists(strapi.dirs.components))) {
|
|
9
|
+
if (!(await pathExists(strapi.dirs.dist.components))) {
|
|
10
10
|
return {};
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
const map = await loadFiles(strapi.dirs.components, '*/*.*(js|json)');
|
|
13
|
+
const map = await loadFiles(strapi.dirs.dist.components, '*/*.*(js|json)');
|
|
14
14
|
|
|
15
15
|
return Object.keys(map).reduce((acc, category) => {
|
|
16
16
|
Object.keys(map[category]).forEach(key => {
|
|
17
17
|
const schema = map[category][key];
|
|
18
18
|
|
|
19
|
-
const filePath = join(strapi.dirs.components, category, schema.__filename__);
|
|
20
|
-
|
|
21
19
|
if (!schema.collectionName) {
|
|
20
|
+
// NOTE: We're using the filepath from the app directory instead of the dist for information purpose
|
|
21
|
+
const filePath = join(strapi.dirs.app.components, category, schema.__filename__);
|
|
22
|
+
|
|
22
23
|
return strapi.stopWithError(
|
|
23
24
|
`Component ${key} is missing a "collectionName" property.\nVerify file ${filePath}.`
|
|
24
25
|
);
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
const { join, extname, basename } = require('path');
|
|
4
4
|
const fse = require('fs-extra');
|
|
5
5
|
|
|
6
|
+
const { importDefault } = require('../../utils');
|
|
7
|
+
|
|
6
8
|
// TODO:: allow folders with index.js inside for bigger policies
|
|
7
9
|
module.exports = async function loadMiddlewares(strapi) {
|
|
8
10
|
const localMiddlewares = await loadLocalMiddlewares(strapi);
|
|
@@ -13,7 +15,7 @@ module.exports = async function loadMiddlewares(strapi) {
|
|
|
13
15
|
};
|
|
14
16
|
|
|
15
17
|
const loadLocalMiddlewares = async strapi => {
|
|
16
|
-
const dir = strapi.dirs.middlewares;
|
|
18
|
+
const dir = strapi.dirs.dist.middlewares;
|
|
17
19
|
|
|
18
20
|
if (!(await fse.pathExists(dir))) {
|
|
19
21
|
return {};
|
|
@@ -28,7 +30,7 @@ const loadLocalMiddlewares = async strapi => {
|
|
|
28
30
|
|
|
29
31
|
if (fd.isFile() && extname(name) === '.js') {
|
|
30
32
|
const key = basename(name, '.js');
|
|
31
|
-
middlewares[key] =
|
|
33
|
+
middlewares[key] = importDefault(fullPath);
|
|
32
34
|
}
|
|
33
35
|
}
|
|
34
36
|
|
|
@@ -29,10 +29,11 @@ const toDetailedDeclaration = declaration => {
|
|
|
29
29
|
let detailedDeclaration = pick(['enabled'], declaration);
|
|
30
30
|
if (has('resolve', declaration)) {
|
|
31
31
|
let pathToPlugin = '';
|
|
32
|
+
|
|
32
33
|
try {
|
|
33
34
|
pathToPlugin = dirname(require.resolve(declaration.resolve));
|
|
34
35
|
} catch (e) {
|
|
35
|
-
pathToPlugin = resolve(strapi.dirs.root, declaration.resolve);
|
|
36
|
+
pathToPlugin = resolve(strapi.dirs.app.root, declaration.resolve);
|
|
36
37
|
|
|
37
38
|
if (!existsSync(pathToPlugin) || !statSync(pathToPlugin).isDirectory()) {
|
|
38
39
|
throw new Error(`${declaration.resolve} couldn't be resolved`);
|
|
@@ -12,9 +12,9 @@ const loadConfigFile = require('../../app-configuration/load-config-file');
|
|
|
12
12
|
* @return {Promise<{}>}
|
|
13
13
|
*/
|
|
14
14
|
const getUserPluginsConfig = async () => {
|
|
15
|
-
const globalUserConfigPath = join(strapi.dirs.config, 'plugins.js');
|
|
15
|
+
const globalUserConfigPath = join(strapi.dirs.dist.config, 'plugins.js');
|
|
16
16
|
const currentEnvUserConfigPath = join(
|
|
17
|
-
strapi.dirs.config,
|
|
17
|
+
strapi.dirs.dist.config,
|
|
18
18
|
'env',
|
|
19
19
|
process.env.NODE_ENV,
|
|
20
20
|
'plugins.js'
|
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
const { join, extname, basename } = require('path');
|
|
4
4
|
const fse = require('fs-extra');
|
|
5
5
|
|
|
6
|
+
const { importDefault } = require('../../utils');
|
|
7
|
+
|
|
6
8
|
// TODO:: allow folders with index.js inside for bigger policies
|
|
7
9
|
module.exports = async function loadPolicies(strapi) {
|
|
8
|
-
const dir = strapi.dirs.policies;
|
|
10
|
+
const dir = strapi.dirs.dist.policies;
|
|
9
11
|
|
|
10
12
|
if (!(await fse.pathExists(dir))) {
|
|
11
13
|
return;
|
|
@@ -20,7 +22,7 @@ module.exports = async function loadPolicies(strapi) {
|
|
|
20
22
|
|
|
21
23
|
if (fd.isFile() && extname(name) === '.js') {
|
|
22
24
|
const key = basename(name, '.js');
|
|
23
|
-
policies[key] =
|
|
25
|
+
policies[key] = importDefault(fullPath);
|
|
24
26
|
}
|
|
25
27
|
}
|
|
26
28
|
|
|
@@ -4,6 +4,8 @@ const { resolve } = require('path');
|
|
|
4
4
|
const { statSync, existsSync } = require('fs');
|
|
5
5
|
const { yup } = require('@strapi/utils');
|
|
6
6
|
|
|
7
|
+
const { importDefault } = require('../../utils');
|
|
8
|
+
|
|
7
9
|
const srcSchema = yup
|
|
8
10
|
.object()
|
|
9
11
|
.shape({
|
|
@@ -18,16 +20,16 @@ const validateSrcIndex = srcIndex => {
|
|
|
18
20
|
};
|
|
19
21
|
|
|
20
22
|
module.exports = strapi => {
|
|
21
|
-
if (!existsSync(strapi.dirs.src)) {
|
|
22
|
-
|
|
23
|
+
if (!existsSync(strapi.dirs.dist.src)) {
|
|
24
|
+
return;
|
|
23
25
|
}
|
|
24
26
|
|
|
25
|
-
const pathToSrcIndex = resolve(strapi.dirs.src, 'index.js');
|
|
27
|
+
const pathToSrcIndex = resolve(strapi.dirs.dist.src, 'index.js');
|
|
26
28
|
if (!existsSync(pathToSrcIndex) || statSync(pathToSrcIndex).isDirectory()) {
|
|
27
29
|
return {};
|
|
28
30
|
}
|
|
29
31
|
|
|
30
|
-
const srcIndex =
|
|
32
|
+
const srcIndex = importDefault(pathToSrcIndex);
|
|
31
33
|
|
|
32
34
|
try {
|
|
33
35
|
validateSrcIndex(srcIndex);
|
|
@@ -1,25 +1,27 @@
|
|
|
1
|
-
import { Context } from 'koa';
|
|
1
|
+
import { Context, Next } from 'koa';
|
|
2
2
|
|
|
3
|
-
type
|
|
3
|
+
type ControllerResponse<T = unknown> = T | Promise<T> | undefined;
|
|
4
4
|
|
|
5
|
-
interface
|
|
5
|
+
interface Controller {
|
|
6
6
|
transformResponse(data: object, meta: object): object;
|
|
7
7
|
sanitizeOutput(data: object, ctx: Context): Promise<object>;
|
|
8
8
|
sanitizeInput(data: object, ctx: Context): Promise<object>;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
export interface SingleTypeController extends
|
|
12
|
-
find(ctx: Context):
|
|
13
|
-
update(ctx: Context):
|
|
14
|
-
delete(ctx: Context):
|
|
11
|
+
export interface SingleTypeController extends Controller {
|
|
12
|
+
find?(ctx: Context, next: Next): ControllerResponse;
|
|
13
|
+
update?(ctx: Context, next: Next): ControllerResponse;
|
|
14
|
+
delete?(ctx: Context, next: Next): ControllerResponse;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
export interface CollectionTypeController extends
|
|
18
|
-
find(ctx: Context):
|
|
19
|
-
findOne(ctx: Context):
|
|
20
|
-
create(ctx: Context):
|
|
21
|
-
update(ctx: Context):
|
|
22
|
-
delete(ctx: Context):
|
|
17
|
+
export interface CollectionTypeController extends Controller {
|
|
18
|
+
find?(ctx: Context, next: Next): ControllerResponse;
|
|
19
|
+
findOne?(ctx: Context, next: Next): ControllerResponse;
|
|
20
|
+
create?(ctx: Context, next: Next): ControllerResponse;
|
|
21
|
+
update?(ctx: Context, next: Next): ControllerResponse;
|
|
22
|
+
delete?(ctx: Context, next: Next): ControllerResponse;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
export type
|
|
25
|
+
export type GenericController = Partial<Controller> & {
|
|
26
|
+
[method: string | number | symbol]: (ctx: Context) => unknown;
|
|
27
|
+
};
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
type Entity = object;
|
|
2
2
|
|
|
3
3
|
interface BaseService {
|
|
4
|
-
getFetchParams(params: object): object;
|
|
4
|
+
getFetchParams?(params: object): object;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
export interface SingleTypeService extends BaseService {
|
|
8
|
-
find(params: object): Promise<Entity
|
|
9
|
-
createOrUpdate(params: object): Promise<Entity
|
|
10
|
-
delete(params: object): Promise<Entity
|
|
8
|
+
find?(params: object): Promise<Entity> | Entity;
|
|
9
|
+
createOrUpdate?(params: object): Promise<Entity> | Entity;
|
|
10
|
+
delete?(params: object): Promise<Entity> | Entity;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
export interface CollectionTypeService extends BaseService {
|
|
14
|
-
find(params: object): Promise<Entity[]
|
|
15
|
-
findOne(params: object): Promise<Entity
|
|
16
|
-
create(params: object): Promise<Entity
|
|
17
|
-
update(params: object): Promise<Entity
|
|
18
|
-
delete(params: object): Promise<Entity
|
|
14
|
+
find?(params: object): Promise<Entity[]> | Entity;
|
|
15
|
+
findOne?(entityId: string,params: object): Promise<Entity> | Entity;
|
|
16
|
+
create?(params: object): Promise<Entity> | Entity;
|
|
17
|
+
update?(entityId: string,params: object): Promise<Entity> | Entity;
|
|
18
|
+
delete?(entityId: string,params: object): Promise<Entity> | Entity;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export type Service = SingleTypeService | CollectionTypeService;
|
|
22
|
+
|
package/lib/factories.d.ts
CHANGED
|
@@ -1,36 +1,37 @@
|
|
|
1
1
|
import { Service } from './core-api/service';
|
|
2
|
-
import { Controller } from './core-api/controller';
|
|
2
|
+
import { Controller, GenericController } from './core-api/controller';
|
|
3
3
|
import { Middleware } from './middlewares';
|
|
4
4
|
import { Policy } from './core/registries/policies';
|
|
5
|
+
import { Strapi } from '@strapi/strapi'
|
|
5
6
|
|
|
6
|
-
type ControllerConfig = Controller;
|
|
7
|
+
type ControllerConfig<T extends Controller = Controller> = T;
|
|
7
8
|
|
|
8
9
|
type ServiceConfig = Service;
|
|
9
10
|
|
|
10
11
|
type HandlerConfig = {
|
|
11
|
-
auth
|
|
12
|
-
policies
|
|
13
|
-
middlewares
|
|
12
|
+
auth?: false | { scope: string[] };
|
|
13
|
+
policies?: Array<string | Policy>;
|
|
14
|
+
middlewares?: Array<string | Middleware>;
|
|
14
15
|
};
|
|
15
16
|
|
|
16
17
|
type SingleTypeRouterConfig = {
|
|
17
|
-
find
|
|
18
|
-
update
|
|
19
|
-
delete
|
|
18
|
+
find?: HandlerConfig;
|
|
19
|
+
update?: HandlerConfig;
|
|
20
|
+
delete?: HandlerConfig;
|
|
20
21
|
};
|
|
21
22
|
|
|
22
23
|
type CollectionTypeRouterConfig = {
|
|
23
|
-
find
|
|
24
|
-
findOne
|
|
25
|
-
create
|
|
26
|
-
update
|
|
27
|
-
delete
|
|
24
|
+
find?: HandlerConfig;
|
|
25
|
+
findOne?: HandlerConfig;
|
|
26
|
+
create?: HandlerConfig;
|
|
27
|
+
update?: HandlerConfig;
|
|
28
|
+
delete?: HandlerConfig;
|
|
28
29
|
};
|
|
29
30
|
|
|
30
31
|
type RouterConfig = {
|
|
31
|
-
prefix
|
|
32
|
+
prefix?: string;
|
|
32
33
|
only: string[];
|
|
33
|
-
except
|
|
34
|
+
except?: string[];
|
|
34
35
|
config: SingleTypeRouterConfig | CollectionTypeRouterConfig;
|
|
35
36
|
};
|
|
36
37
|
|
|
@@ -43,6 +44,9 @@ interface Router {
|
|
|
43
44
|
routes: Route[];
|
|
44
45
|
}
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
type ControllerCallback <T extends GenericController = GenericController> = (params:{strapi:Strapi}) => T;
|
|
48
|
+
type ServiceCallback <T extends Service = Sevice> = (params:{strapi:Strapi}) => T
|
|
49
|
+
|
|
50
|
+
export function createCoreRouter(uid: string, cfg?: RouterConfig = {}): () => Router;
|
|
51
|
+
export function createCoreController<T extends GenericController = GenericController>(uid: string, cfg?: ControllerCallback<T> | T = {}): () => T & Controller;
|
|
52
|
+
export function createCoreService<T extends Service = Service>(uid: string, cfg?: ServiceCallback<T> | T = {}): () => T ;
|
package/lib/index.d.ts
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { Database } from '@strapi/database';
|
|
2
2
|
import { EntityService } from './services/entity-service';
|
|
3
|
-
import { Strapi as StrapiClass } from './Strapi';
|
|
4
3
|
|
|
4
|
+
import * as Core from './types/strapi';
|
|
5
5
|
export * as factories from './factories';
|
|
6
|
-
interface StrapiInterface extends StrapiClass {
|
|
7
|
-
query: Database['query'];
|
|
8
|
-
entityService: EntityService;
|
|
9
|
-
}
|
|
10
6
|
|
|
11
|
-
export type
|
|
7
|
+
export type { Core };
|
|
8
|
+
|
|
9
|
+
// Alias to resolve the Strapi global type easily
|
|
10
|
+
export type Strapi = Core.Strapi;
|
|
11
|
+
|
|
12
|
+
export interface StrapiInterface extends Core.Strapi {};
|
|
12
13
|
|
|
13
14
|
declare global {
|
|
14
15
|
interface AllTypes {}
|
package/lib/index.js
CHANGED
package/lib/load/load-files.js
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const _ = require('lodash');
|
|
5
5
|
const fse = require('fs-extra');
|
|
6
|
+
|
|
7
|
+
const { importDefault } = require('../utils');
|
|
6
8
|
const glob = require('./glob');
|
|
7
9
|
const filePathToPath = require('./filepath-to-prop-path');
|
|
8
10
|
|
|
@@ -19,7 +21,7 @@ const filePathToPath = require('./filepath-to-prop-path');
|
|
|
19
21
|
const loadFiles = async (
|
|
20
22
|
dir,
|
|
21
23
|
pattern,
|
|
22
|
-
{ requireFn =
|
|
24
|
+
{ requireFn = importDefault, shouldUseFileNameAsKey = () => true, globArgs = {} } = {}
|
|
23
25
|
) => {
|
|
24
26
|
const root = {};
|
|
25
27
|
const files = await glob(pattern, { cwd: dir, ...globArgs });
|
|
@@ -15,5 +15,5 @@ const defaults = {
|
|
|
15
15
|
module.exports = (config, { strapi }) => {
|
|
16
16
|
const { maxAge, path: faviconPath } = defaultsDeep(defaults, config);
|
|
17
17
|
|
|
18
|
-
return favicon(resolve(strapi.dirs.root, faviconPath), { maxAge });
|
|
18
|
+
return favicon(resolve(strapi.dirs.app.root, faviconPath), { maxAge });
|
|
19
19
|
};
|
|
@@ -6,6 +6,7 @@ type ID = number | string;
|
|
|
6
6
|
type EntityServiceAction =
|
|
7
7
|
| 'findMany'
|
|
8
8
|
| 'findPage'
|
|
9
|
+
| 'findWithRelationCountsPage'
|
|
9
10
|
| 'findWithRelationCounts'
|
|
10
11
|
| 'findOne'
|
|
11
12
|
| 'count'
|
|
@@ -54,7 +55,7 @@ export interface EntityService {
|
|
|
54
55
|
pagination: PaginationInfo;
|
|
55
56
|
}>;
|
|
56
57
|
|
|
57
|
-
|
|
58
|
+
findWithRelationCountsPage<K extends keyof AllTypes, T extends AllTypes[K]>(
|
|
58
59
|
uid: K,
|
|
59
60
|
params: Params<T>
|
|
60
61
|
): Promise<{
|
|
@@ -62,6 +63,11 @@ export interface EntityService {
|
|
|
62
63
|
pagination: PaginationInfo;
|
|
63
64
|
}>;
|
|
64
65
|
|
|
66
|
+
findWithRelationCounts<K extends keyof AllTypes, T extends AllTypes[K]>(
|
|
67
|
+
uid: K,
|
|
68
|
+
params: Params<T>
|
|
69
|
+
): Promise<T[]>;
|
|
70
|
+
|
|
65
71
|
findOne<K extends keyof AllTypes, T extends AllTypes[K]>(
|
|
66
72
|
uid: K,
|
|
67
73
|
entityId: ID,
|
|
@@ -125,7 +125,7 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
125
125
|
},
|
|
126
126
|
|
|
127
127
|
// TODO: streamline the logic based on the populate option
|
|
128
|
-
async
|
|
128
|
+
async findWithRelationCountsPage(uid, opts) {
|
|
129
129
|
const wrappedParams = await this.wrapParams(opts, { uid, action: 'findWithRelationCounts' });
|
|
130
130
|
|
|
131
131
|
const query = transformParamsToQuery(uid, wrappedParams);
|
|
@@ -138,6 +138,16 @@ const createDefaultImplementation = ({ strapi, db, eventHub, entityValidator })
|
|
|
138
138
|
};
|
|
139
139
|
},
|
|
140
140
|
|
|
141
|
+
async findWithRelationCounts(uid, opts) {
|
|
142
|
+
const wrappedParams = await this.wrapParams(opts, { uid, action: 'findWithRelationCounts' });
|
|
143
|
+
|
|
144
|
+
const query = transformParamsToQuery(uid, wrappedParams);
|
|
145
|
+
|
|
146
|
+
const results = await db.query(uid).findMany(query);
|
|
147
|
+
|
|
148
|
+
return results;
|
|
149
|
+
},
|
|
150
|
+
|
|
141
151
|
async findOne(uid, entityId, opts) {
|
|
142
152
|
const wrappedParams = await this.wrapParams(opts, { uid, action: 'findOne' });
|
|
143
153
|
|
package/lib/services/fs.js
CHANGED
|
@@ -12,7 +12,7 @@ module.exports = strapi => {
|
|
|
12
12
|
|
|
13
13
|
const normalizedPath = path.normalize(filePath).replace(/^\/?(\.\/|\.\.\/)+/, '');
|
|
14
14
|
|
|
15
|
-
return path.resolve(strapi.dirs.root, normalizedPath);
|
|
15
|
+
return path.resolve(strapi.dirs.app.root, normalizedPath);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
const strapiFS = {
|
|
@@ -33,6 +33,10 @@ const createTelemetryInstance = strapi => {
|
|
|
33
33
|
const sendEvent = wrapWithRateLimit(sender, { limitedEvents: LIMITED_EVENTS });
|
|
34
34
|
|
|
35
35
|
return {
|
|
36
|
+
get isDisabled() {
|
|
37
|
+
return isDisabled;
|
|
38
|
+
},
|
|
39
|
+
|
|
36
40
|
register() {
|
|
37
41
|
if (!isDisabled) {
|
|
38
42
|
const pingCron = scheduleJob('0 0 12 * * *', () => sendEvent('ping'));
|
|
@@ -92,7 +96,7 @@ const hashProject = strapi =>
|
|
|
92
96
|
|
|
93
97
|
const hashDep = strapi => {
|
|
94
98
|
const depStr = JSON.stringify(strapi.config.info.dependencies);
|
|
95
|
-
const readmePath = path.join(strapi.dirs.root, 'README.md');
|
|
99
|
+
const readmePath = path.join(strapi.dirs.app.root, 'README.md');
|
|
96
100
|
|
|
97
101
|
try {
|
|
98
102
|
if (fs.existsSync(readmePath)) {
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const os = require('os');
|
|
4
|
+
const path = require('path');
|
|
4
5
|
const _ = require('lodash');
|
|
5
6
|
const isDocker = require('is-docker');
|
|
6
7
|
const fetch = require('node-fetch');
|
|
7
8
|
const ciEnv = require('ci-info');
|
|
9
|
+
const { isUsingTypeScriptSync } = require('@strapi/typescript-utils');
|
|
8
10
|
const ee = require('../../utils/ee');
|
|
9
11
|
const machineID = require('../../utils/machine-id');
|
|
10
12
|
const stringifyDeep = require('./stringify-deep');
|
|
@@ -36,6 +38,9 @@ module.exports = strapi => {
|
|
|
36
38
|
const deviceId = machineID();
|
|
37
39
|
const isEE = strapi.EE === true && ee.isEE === true;
|
|
38
40
|
|
|
41
|
+
const serverRootPath = strapi.dirs.app.root;
|
|
42
|
+
const adminRootPath = path.join(strapi.dirs.app.root, 'src', 'admin');
|
|
43
|
+
|
|
39
44
|
const anonymous_metadata = {
|
|
40
45
|
environment: strapi.config.environment,
|
|
41
46
|
os: os.type(),
|
|
@@ -47,6 +52,8 @@ module.exports = strapi => {
|
|
|
47
52
|
version: strapi.config.get('info.strapi'),
|
|
48
53
|
strapiVersion: strapi.config.get('info.strapi'),
|
|
49
54
|
projectType: isEE ? 'Enterprise' : 'Community',
|
|
55
|
+
useTypescriptOnServer: isUsingTypeScriptSync(serverRootPath),
|
|
56
|
+
useTypescriptOnAdmin: isUsingTypeScriptSync(adminRootPath),
|
|
50
57
|
};
|
|
51
58
|
|
|
52
59
|
addPackageJsonStrapiMetadata(anonymous_metadata, strapi);
|