@akemona-org/strapi 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +163 -0
- package/bin/strapi.js +239 -0
- package/index.d.ts +13 -0
- package/lib/Strapi.js +498 -0
- package/lib/commands/admin-reset.js +51 -0
- package/lib/commands/build.js +47 -0
- package/lib/commands/configurationDump.js +50 -0
- package/lib/commands/configurationRestore.js +160 -0
- package/lib/commands/console.js +26 -0
- package/lib/commands/develop.js +155 -0
- package/lib/commands/generate-template.js +97 -0
- package/lib/commands/generate.js +66 -0
- package/lib/commands/install.js +48 -0
- package/lib/commands/new.js +11 -0
- package/lib/commands/start.js +8 -0
- package/lib/commands/uninstall.js +68 -0
- package/lib/commands/watchAdmin.js +35 -0
- package/lib/core/app-configuration/config-loader.js +56 -0
- package/lib/core/app-configuration/config-provider.js +28 -0
- package/lib/core/app-configuration/index.js +99 -0
- package/lib/core/bootstrap.js +166 -0
- package/lib/core/fs.js +52 -0
- package/lib/core/index.js +21 -0
- package/lib/core/load-admin.js +36 -0
- package/lib/core/load-apis.js +22 -0
- package/lib/core/load-components.js +43 -0
- package/lib/core/load-extensions.js +71 -0
- package/lib/core/load-functions.js +21 -0
- package/lib/core/load-hooks.js +117 -0
- package/lib/core/load-middlewares.js +130 -0
- package/lib/core/load-modules.js +61 -0
- package/lib/core/load-plugins.js +68 -0
- package/lib/core/load-policies.js +36 -0
- package/lib/core/walk.js +27 -0
- package/lib/core-api/controller.js +158 -0
- package/lib/core-api/index.js +33 -0
- package/lib/core-api/service/collection-type.js +122 -0
- package/lib/core-api/service/index.js +81 -0
- package/lib/core-api/service/single-type.js +68 -0
- package/lib/hooks/index.js +97 -0
- package/lib/index.js +3 -0
- package/lib/load/check-reserved-filename.js +18 -0
- package/lib/load/filepath-to-prop-path.js +22 -0
- package/lib/load/glob.js +15 -0
- package/lib/load/index.js +9 -0
- package/lib/load/load-config-files.js +22 -0
- package/lib/load/load-files.js +56 -0
- package/lib/load/package-path.js +9 -0
- package/lib/load/require-file-parse.js +15 -0
- package/lib/middlewares/boom/defaults.json +5 -0
- package/lib/middlewares/boom/index.js +147 -0
- package/lib/middlewares/cors/index.js +66 -0
- package/lib/middlewares/cron/defaults.json +5 -0
- package/lib/middlewares/cron/index.js +43 -0
- package/lib/middlewares/csp/defaults.json +5 -0
- package/lib/middlewares/csp/index.js +26 -0
- package/lib/middlewares/favicon/defaults.json +7 -0
- package/lib/middlewares/favicon/index.js +35 -0
- package/lib/middlewares/gzip/defaults.json +6 -0
- package/lib/middlewares/gzip/index.js +19 -0
- package/lib/middlewares/hsts/defaults.json +7 -0
- package/lib/middlewares/hsts/index.js +30 -0
- package/lib/middlewares/index.js +120 -0
- package/lib/middlewares/ip/defaults.json +7 -0
- package/lib/middlewares/ip/index.js +25 -0
- package/lib/middlewares/language/defaults.json +9 -0
- package/lib/middlewares/language/index.js +40 -0
- package/lib/middlewares/logger/defaults.json +8 -0
- package/lib/middlewares/logger/index.js +63 -0
- package/lib/middlewares/p3p/defaults.json +6 -0
- package/lib/middlewares/p3p/index.js +29 -0
- package/lib/middlewares/parser/defaults.json +10 -0
- package/lib/middlewares/parser/index.js +71 -0
- package/lib/middlewares/poweredBy/defaults.json +5 -0
- package/lib/middlewares/poweredBy/index.js +16 -0
- package/lib/middlewares/public/assets/images/group_people_1.png +0 -0
- package/lib/middlewares/public/assets/images/group_people_2.png +0 -0
- package/lib/middlewares/public/assets/images/group_people_3.png +0 -0
- package/lib/middlewares/public/assets/images/logo_login.png +0 -0
- package/lib/middlewares/public/defaults.json +8 -0
- package/lib/middlewares/public/index.html +66 -0
- package/lib/middlewares/public/index.js +98 -0
- package/lib/middlewares/public/serve-static.js +23 -0
- package/lib/middlewares/responseTime/defaults.json +5 -0
- package/lib/middlewares/responseTime/index.js +25 -0
- package/lib/middlewares/responses/defaults.json +5 -0
- package/lib/middlewares/responses/index.js +18 -0
- package/lib/middlewares/router/defaults.json +7 -0
- package/lib/middlewares/router/index.js +64 -0
- package/lib/middlewares/router/utils/composeEndpoint.js +25 -0
- package/lib/middlewares/router/utils/routerChecker.js +92 -0
- package/lib/middlewares/session/defaults.json +18 -0
- package/lib/middlewares/session/index.js +140 -0
- package/lib/middlewares/xframe/defaults.json +6 -0
- package/lib/middlewares/xframe/index.js +33 -0
- package/lib/middlewares/xss/defaults.json +6 -0
- package/lib/middlewares/xss/index.js +30 -0
- package/lib/services/core-store.js +144 -0
- package/lib/services/entity-service.js +260 -0
- package/lib/services/entity-validator/index.js +199 -0
- package/lib/services/entity-validator/validators.js +125 -0
- package/lib/services/event-hub.js +15 -0
- package/lib/services/metrics/index.js +103 -0
- package/lib/services/metrics/is-truthy.js +9 -0
- package/lib/services/metrics/middleware.js +33 -0
- package/lib/services/metrics/rate-limiter.js +27 -0
- package/lib/services/metrics/sender.js +76 -0
- package/lib/services/metrics/stringify-deep.js +22 -0
- package/lib/services/utils/upload-files.js +70 -0
- package/lib/services/webhook-runner.js +159 -0
- package/lib/services/webhook-store.js +97 -0
- package/lib/services/worker-queue.js +58 -0
- package/lib/utils/addSlash.js +10 -0
- package/lib/utils/ee.js +123 -0
- package/lib/utils/get-prefixed-dependencies.js +7 -0
- package/lib/utils/index.js +25 -0
- package/lib/utils/openBrowser.js +145 -0
- package/lib/utils/resources/key.pub +9 -0
- package/lib/utils/resources/openChrome.applescript +83 -0
- package/lib/utils/run-checks.js +37 -0
- package/lib/utils/success.js +31 -0
- package/lib/utils/update-notifier/index.js +96 -0
- package/lib/utils/url-from-segments.js +13 -0
- package/package.json +143 -0
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Dependencies.
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const fs = require('fs-extra');
|
|
6
|
+
const _ = require('lodash');
|
|
7
|
+
const glob = require('../load/glob');
|
|
8
|
+
const findPackagePath = require('../load/package-path');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Load hooks
|
|
12
|
+
*/
|
|
13
|
+
module.exports = async function({ installedHooks, installedPlugins, appPath }) {
|
|
14
|
+
let hooks = {};
|
|
15
|
+
|
|
16
|
+
await Promise.all([
|
|
17
|
+
loadHookDependencies(installedHooks, hooks),
|
|
18
|
+
// local middleware
|
|
19
|
+
loadLocalHooks(appPath, hooks),
|
|
20
|
+
// admin hooks
|
|
21
|
+
loadAdminHooks(hooks),
|
|
22
|
+
// plugins middlewares
|
|
23
|
+
loadPluginsHooks(installedPlugins, hooks),
|
|
24
|
+
// local plugin middlewares
|
|
25
|
+
loadLocalPluginsHooks(appPath, hooks),
|
|
26
|
+
]);
|
|
27
|
+
|
|
28
|
+
return hooks;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const loadHooksInDir = async (dir, hooks) => {
|
|
32
|
+
const files = await glob('*/*(index|defaults).*(js|json)', {
|
|
33
|
+
cwd: dir,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
files.forEach(f => {
|
|
37
|
+
const name = f.split('/')[0];
|
|
38
|
+
mountHooks(name, [path.resolve(dir, f)], hooks);
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const loadLocalHooks = (appPath, hooks) => loadHooksInDir(path.resolve(appPath, 'hooks'), hooks);
|
|
43
|
+
|
|
44
|
+
const loadPluginsHooks = async (plugins, hooks) => {
|
|
45
|
+
for (let pluginName of plugins) {
|
|
46
|
+
const dir = path.resolve(findPackagePath(`strapi-plugin-${pluginName}`), 'hooks');
|
|
47
|
+
await loadHooksInDir(dir, hooks);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const loadAdminHooks = async hooks => {
|
|
52
|
+
const hooksDir = 'hooks';
|
|
53
|
+
const dir = path.resolve(findPackagePath('strapi-admin'), hooksDir);
|
|
54
|
+
await loadHooksInDir(dir, hooks);
|
|
55
|
+
|
|
56
|
+
// load ee admin hooks if they exist
|
|
57
|
+
if (process.env.STRAPI_DISABLE_EE !== 'true' && strapi.EE) {
|
|
58
|
+
await loadHooksInDir(`${dir}/../ee/${hooksDir}`, hooks);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const loadLocalPluginsHooks = async (appPath, hooks) => {
|
|
63
|
+
const pluginsDir = path.resolve(appPath, 'plugins');
|
|
64
|
+
if (!fs.existsSync(pluginsDir)) return;
|
|
65
|
+
|
|
66
|
+
const pluginsNames = await fs.readdir(pluginsDir);
|
|
67
|
+
|
|
68
|
+
for (let pluginName of pluginsNames) {
|
|
69
|
+
// ignore files
|
|
70
|
+
const stat = await fs.stat(path.resolve(pluginsDir, pluginName));
|
|
71
|
+
if (!stat.isDirectory()) continue;
|
|
72
|
+
|
|
73
|
+
const dir = path.resolve(pluginsDir, pluginName, 'hooks');
|
|
74
|
+
await loadHooksInDir(dir, hooks);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const loadHookDependencies = async (installedHooks, hooks) => {
|
|
79
|
+
for (let hook of installedHooks) {
|
|
80
|
+
const hookDir = path.dirname(require.resolve(`strapi-hook-${hook}`));
|
|
81
|
+
|
|
82
|
+
const files = await glob('*(index|defaults).*(js|json)', {
|
|
83
|
+
cwd: hookDir,
|
|
84
|
+
absolute: true,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
mountHooks(hook, files, hooks);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const mountHooks = (name, files, hooks) => {
|
|
92
|
+
files.forEach(file => {
|
|
93
|
+
hooks[name] = hooks[name] || { loaded: false };
|
|
94
|
+
|
|
95
|
+
let dependencies = [];
|
|
96
|
+
try {
|
|
97
|
+
dependencies = _.get(require(`strapi-hook-${name}/package.json`), 'strapi.dependencies', []);
|
|
98
|
+
} catch (err) {
|
|
99
|
+
// Silent
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (_.endsWith(file, 'index.js') && !hooks[name].load) {
|
|
103
|
+
Object.defineProperty(hooks[name], 'load', {
|
|
104
|
+
configurable: false,
|
|
105
|
+
enumerable: true,
|
|
106
|
+
get: () => require(file)(strapi),
|
|
107
|
+
});
|
|
108
|
+
hooks[name].dependencies = dependencies;
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (_.endsWith(file, 'defaults.json')) {
|
|
113
|
+
hooks[name].defaults = require(file);
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
};
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Dependencies.
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const fs = require('fs-extra');
|
|
6
|
+
const _ = require('lodash');
|
|
7
|
+
const glob = require('../load/glob');
|
|
8
|
+
const findPackagePath = require('../load/package-path');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Load middlewares
|
|
12
|
+
*/
|
|
13
|
+
module.exports = async function(strapi) {
|
|
14
|
+
const { installedMiddlewares, installedPlugins, appPath } = strapi.config;
|
|
15
|
+
|
|
16
|
+
let middlewares = {};
|
|
17
|
+
|
|
18
|
+
const loaders = createLoaders(strapi);
|
|
19
|
+
|
|
20
|
+
await loaders.loadMiddlewareDependencies(installedMiddlewares, middlewares);
|
|
21
|
+
// internal middlewares
|
|
22
|
+
await loaders.loadInternalMiddlewares(middlewares);
|
|
23
|
+
// local middleware
|
|
24
|
+
await loaders.loadLocalMiddlewares(appPath, middlewares);
|
|
25
|
+
// plugins middlewares
|
|
26
|
+
await loaders.loadPluginsMiddlewares(installedPlugins, middlewares);
|
|
27
|
+
// local plugin middlewares
|
|
28
|
+
await loaders.loadLocalPluginsMiddlewares(appPath, middlewares);
|
|
29
|
+
// load admin middlwares
|
|
30
|
+
await loaders.loadAdminMiddlewares(middlewares);
|
|
31
|
+
|
|
32
|
+
return middlewares;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Build loader functions
|
|
37
|
+
* @param {*} strapi - strapi instance
|
|
38
|
+
*/
|
|
39
|
+
const createLoaders = strapi => {
|
|
40
|
+
const loadMiddlewaresInDir = async (dir, middlewares) => {
|
|
41
|
+
const files = await glob('*/*(index|defaults).*(js|json)', {
|
|
42
|
+
cwd: dir,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
files.forEach(f => {
|
|
46
|
+
const name = f.split('/')[0];
|
|
47
|
+
mountMiddleware(name, [path.resolve(dir, f)], middlewares);
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const loadInternalMiddlewares = middlewares =>
|
|
52
|
+
loadMiddlewaresInDir(path.resolve(__dirname, '..', 'middlewares'), middlewares);
|
|
53
|
+
|
|
54
|
+
const loadLocalMiddlewares = (appPath, middlewares) =>
|
|
55
|
+
loadMiddlewaresInDir(path.resolve(appPath, 'middlewares'), middlewares);
|
|
56
|
+
|
|
57
|
+
const loadPluginsMiddlewares = async (plugins, middlewares) => {
|
|
58
|
+
for (let pluginName of plugins) {
|
|
59
|
+
const dir = path.resolve(findPackagePath(`strapi-plugin-${pluginName}`), 'middlewares');
|
|
60
|
+
await loadMiddlewaresInDir(dir, middlewares);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const loadLocalPluginsMiddlewares = async (appPath, middlewares) => {
|
|
65
|
+
const pluginsDir = path.resolve(appPath, 'plugins');
|
|
66
|
+
if (!fs.existsSync(pluginsDir)) return;
|
|
67
|
+
|
|
68
|
+
const pluginsNames = await fs.readdir(pluginsDir);
|
|
69
|
+
|
|
70
|
+
for (let pluginFolder of pluginsNames) {
|
|
71
|
+
// ignore files
|
|
72
|
+
const stat = await fs.stat(path.resolve(pluginsDir, pluginFolder));
|
|
73
|
+
if (!stat.isDirectory()) continue;
|
|
74
|
+
|
|
75
|
+
const dir = path.resolve(pluginsDir, pluginFolder, 'middlewares');
|
|
76
|
+
await loadMiddlewaresInDir(dir, middlewares);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const loadAdminMiddlewares = async middlewares => {
|
|
81
|
+
const middlewaresDir = 'middlewares';
|
|
82
|
+
const dir = path.resolve(findPackagePath(`strapi-admin`), middlewaresDir);
|
|
83
|
+
await loadMiddlewaresInDir(dir, middlewares);
|
|
84
|
+
|
|
85
|
+
// load ee admin middlewares if they exist
|
|
86
|
+
if (process.env.STRAPI_DISABLE_EE !== 'true' && strapi.EE) {
|
|
87
|
+
await loadMiddlewaresInDir(`${dir}/../ee/${middlewaresDir}`, middlewares);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const loadMiddlewareDependencies = async (packages, middlewares) => {
|
|
92
|
+
for (let packageName of packages) {
|
|
93
|
+
const baseDir = path.dirname(require.resolve(`strapi-middleware-${packageName}`));
|
|
94
|
+
const files = await glob('*(index|defaults).*(js|json)', {
|
|
95
|
+
cwd: baseDir,
|
|
96
|
+
absolute: true,
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
mountMiddleware(packageName, files, middlewares);
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
|
|
103
|
+
const mountMiddleware = (name, files, middlewares) => {
|
|
104
|
+
files.forEach(file => {
|
|
105
|
+
middlewares[name] = middlewares[name] || { loaded: false };
|
|
106
|
+
|
|
107
|
+
if (_.endsWith(file, 'index.js') && !middlewares[name].load) {
|
|
108
|
+
return Object.defineProperty(middlewares[name], 'load', {
|
|
109
|
+
configurable: false,
|
|
110
|
+
enumerable: true,
|
|
111
|
+
get: () => require(file)(strapi),
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (_.endsWith(file, 'defaults.json')) {
|
|
116
|
+
middlewares[name].defaults = require(file);
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
return {
|
|
123
|
+
loadInternalMiddlewares,
|
|
124
|
+
loadLocalMiddlewares,
|
|
125
|
+
loadPluginsMiddlewares,
|
|
126
|
+
loadLocalPluginsMiddlewares,
|
|
127
|
+
loadMiddlewareDependencies,
|
|
128
|
+
loadAdminMiddlewares,
|
|
129
|
+
};
|
|
130
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Load Modules is the root module loader.
|
|
3
|
+
* This is where all the strapi enviornment is laoded
|
|
4
|
+
* - APIs
|
|
5
|
+
* - Plugins
|
|
6
|
+
* - Hooks
|
|
7
|
+
* - Middlewres
|
|
8
|
+
* - Components
|
|
9
|
+
* - ContentTypes
|
|
10
|
+
*/
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
const _ = require('lodash');
|
|
14
|
+
|
|
15
|
+
const loadApis = require('./load-apis');
|
|
16
|
+
const loadAdmin = require('./load-admin');
|
|
17
|
+
const loadPlugins = require('./load-plugins');
|
|
18
|
+
const loadMiddlewares = require('./load-middlewares');
|
|
19
|
+
const loadExtensions = require('./load-extensions');
|
|
20
|
+
const loadHooks = require('./load-hooks');
|
|
21
|
+
const loadComponents = require('./load-components');
|
|
22
|
+
|
|
23
|
+
module.exports = async strapi => {
|
|
24
|
+
const [api, admin, plugins, middlewares, hook, extensions, components] = await Promise.all([
|
|
25
|
+
loadApis(strapi),
|
|
26
|
+
loadAdmin(strapi),
|
|
27
|
+
loadPlugins(strapi),
|
|
28
|
+
loadMiddlewares(strapi),
|
|
29
|
+
loadHooks(strapi.config),
|
|
30
|
+
loadExtensions(strapi.config),
|
|
31
|
+
loadComponents(strapi),
|
|
32
|
+
]);
|
|
33
|
+
|
|
34
|
+
// TODO: move this into the appropriate loaders
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Handle plugin extensions
|
|
38
|
+
*/
|
|
39
|
+
// merge extensions config folders
|
|
40
|
+
_.mergeWith(plugins, extensions.merges, (objValue, srcValue, key) => {
|
|
41
|
+
// concat routes
|
|
42
|
+
if (_.isArray(srcValue) && _.isArray(objValue) && key === 'routes') {
|
|
43
|
+
return srcValue.concat(objValue);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// overwrite plugins with extensions overwrites
|
|
48
|
+
extensions.overwrites.forEach(({ path, mod }) => {
|
|
49
|
+
_.assign(_.get(plugins, path), mod);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
return {
|
|
53
|
+
api,
|
|
54
|
+
admin,
|
|
55
|
+
plugins,
|
|
56
|
+
middlewares,
|
|
57
|
+
hook,
|
|
58
|
+
extensions,
|
|
59
|
+
components,
|
|
60
|
+
};
|
|
61
|
+
};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { join } = require('path');
|
|
4
|
+
const { existsSync } = require('fs-extra');
|
|
5
|
+
const _ = require('lodash');
|
|
6
|
+
const findPackagePath = require('../load/package-path');
|
|
7
|
+
const loadFiles = require('../load/load-files');
|
|
8
|
+
const loadConfig = require('../load/load-config-files');
|
|
9
|
+
|
|
10
|
+
module.exports = async ({ dir, config }) => {
|
|
11
|
+
const localPlugins = await loadLocalPlugins({ dir, config });
|
|
12
|
+
const plugins = await loadPlugins({
|
|
13
|
+
installedPlugins: config.installedPlugins,
|
|
14
|
+
config,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const pluginsIntersection = _.intersection(Object.keys(localPlugins), Object.keys(plugins));
|
|
18
|
+
|
|
19
|
+
if (pluginsIntersection.length > 0) {
|
|
20
|
+
throw new Error(
|
|
21
|
+
`You have some local plugins with the same name as npm installed plugins:\n${pluginsIntersection
|
|
22
|
+
.map(p => `- ${p}`)
|
|
23
|
+
.join('\n')}`
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// check for conflicts
|
|
28
|
+
return _.merge(plugins, localPlugins);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const loadLocalPlugins = async ({ dir, config }) => {
|
|
32
|
+
const pluginsDir = join(dir, 'plugins');
|
|
33
|
+
|
|
34
|
+
if (!existsSync(pluginsDir)) return {};
|
|
35
|
+
|
|
36
|
+
const [files, configs] = await Promise.all([
|
|
37
|
+
loadFiles(pluginsDir, '{*/!(config)/*.*(js|json),*/package.json}'),
|
|
38
|
+
loadConfig(pluginsDir, '*/config/**/*.+(js|json)'),
|
|
39
|
+
]);
|
|
40
|
+
const userConfigs = Object.keys(files).reduce((acc, plugin) => {
|
|
41
|
+
acc[plugin] = { config: config.get(['plugins', plugin], {}) };
|
|
42
|
+
return acc;
|
|
43
|
+
}, {});
|
|
44
|
+
return _.merge(files, configs, userConfigs);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
const loadPlugins = async ({ installedPlugins, config }) => {
|
|
48
|
+
let plugins = {};
|
|
49
|
+
|
|
50
|
+
for (let plugin of installedPlugins) {
|
|
51
|
+
const pluginPath = findPackagePath(`strapi-plugin-${plugin}`);
|
|
52
|
+
|
|
53
|
+
const files = await loadFiles(
|
|
54
|
+
pluginPath,
|
|
55
|
+
'{!(config|node_modules|tests)/*.*(js|json),package.json}'
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
const { config: pluginConfig } = await loadConfig(pluginPath);
|
|
59
|
+
|
|
60
|
+
const userConfig = config.get(['plugins', plugin], {});
|
|
61
|
+
|
|
62
|
+
const mergedConfig = _.merge(pluginConfig, userConfig);
|
|
63
|
+
|
|
64
|
+
_.set(plugins, plugin, _.assign({}, files, { config: mergedConfig }));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return plugins;
|
|
68
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const assert = require('assert');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const _ = require('lodash');
|
|
6
|
+
const fse = require('fs-extra');
|
|
7
|
+
|
|
8
|
+
module.exports = dir => {
|
|
9
|
+
if (!fse.existsSync(dir)) return {};
|
|
10
|
+
|
|
11
|
+
const root = {};
|
|
12
|
+
const paths = fse.readdirSync(dir, { withFileTypes: true }).filter(fd => fd.isFile());
|
|
13
|
+
|
|
14
|
+
for (let fd of paths) {
|
|
15
|
+
const { name } = fd;
|
|
16
|
+
const fullPath = dir + path.sep + name;
|
|
17
|
+
|
|
18
|
+
const ext = path.extname(name);
|
|
19
|
+
const key = path.basename(name, ext);
|
|
20
|
+
root[_.toLower(key)] = loadPolicy(fullPath);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return root;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const loadPolicy = file => {
|
|
27
|
+
try {
|
|
28
|
+
const policy = require(file);
|
|
29
|
+
|
|
30
|
+
assert(typeof policy === 'function', 'Policy must be a function.');
|
|
31
|
+
|
|
32
|
+
return policy;
|
|
33
|
+
} catch (error) {
|
|
34
|
+
throw `Could not load policy ${file}: ${error.message}`;
|
|
35
|
+
}
|
|
36
|
+
};
|
package/lib/core/walk.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const assert = require('assert');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const fse = require('fs-extra');
|
|
6
|
+
|
|
7
|
+
module.exports = function walk(dir, { loader } = {}) {
|
|
8
|
+
assert(typeof loader === 'function', 'opts.loader must be a function');
|
|
9
|
+
|
|
10
|
+
const root = {};
|
|
11
|
+
const paths = fse.readdirSync(dir, { withFileTypes: true });
|
|
12
|
+
|
|
13
|
+
for (let fd of paths) {
|
|
14
|
+
const { name } = fd;
|
|
15
|
+
const fullPath = dir + path.sep + name;
|
|
16
|
+
|
|
17
|
+
if (fd.isDirectory()) {
|
|
18
|
+
root[name] = walk(fullPath, { loader });
|
|
19
|
+
} else {
|
|
20
|
+
const ext = path.extname(name);
|
|
21
|
+
const key = path.basename(name, ext);
|
|
22
|
+
root[key] = loader(fullPath);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return root;
|
|
27
|
+
};
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const _ = require('lodash');
|
|
4
|
+
const { parseMultipartData, sanitizeEntity } = require('@akemona-org/strapi-utils');
|
|
5
|
+
|
|
6
|
+
const createSanitizeFn = (model) => (data) => {
|
|
7
|
+
return sanitizeEntity(data, { model: strapi.getModel(model.uid) });
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* default bookshelf controller
|
|
12
|
+
*
|
|
13
|
+
*/
|
|
14
|
+
module.exports = ({ service, model }) => {
|
|
15
|
+
if (model.kind === 'singleType') {
|
|
16
|
+
return createSingleTypeController({ model, service });
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return createCollectionTypeController({ model, service });
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Returns a single type controller to handle default core-api actions
|
|
24
|
+
*/
|
|
25
|
+
const createSingleTypeController = ({ model, service }) => {
|
|
26
|
+
const sanitize = createSanitizeFn(model);
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
/**
|
|
30
|
+
* Retrieve single type content
|
|
31
|
+
*
|
|
32
|
+
* @return {Object|Array}
|
|
33
|
+
*/
|
|
34
|
+
async find(ctx) {
|
|
35
|
+
const { query } = ctx;
|
|
36
|
+
const entity = await service.find(query);
|
|
37
|
+
return sanitize(entity);
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* create or update single type content.
|
|
42
|
+
*
|
|
43
|
+
* @return {Object}
|
|
44
|
+
*/
|
|
45
|
+
async update(ctx) {
|
|
46
|
+
const { body, query } = ctx.request;
|
|
47
|
+
|
|
48
|
+
let entity;
|
|
49
|
+
if (ctx.is('multipart')) {
|
|
50
|
+
const { data, files } = parseMultipartData(ctx);
|
|
51
|
+
entity = await service.createOrUpdate(data, { files, query });
|
|
52
|
+
} else {
|
|
53
|
+
entity = await service.createOrUpdate(body, { query });
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return sanitize(entity);
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
async delete(ctx) {
|
|
60
|
+
const entity = await service.delete(ctx.query);
|
|
61
|
+
return sanitize(entity);
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
*
|
|
68
|
+
* Returns a collection type controller to handle default core-api actions
|
|
69
|
+
*/
|
|
70
|
+
const createCollectionTypeController = ({ model, service }) => {
|
|
71
|
+
const sanitize = createSanitizeFn(model);
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
/**
|
|
75
|
+
* Retrieve records.
|
|
76
|
+
*
|
|
77
|
+
* @return {Object|Array}
|
|
78
|
+
*/
|
|
79
|
+
async find(ctx) {
|
|
80
|
+
let entities;
|
|
81
|
+
if (_.has(ctx.query, '_q')) {
|
|
82
|
+
entities = await service.search(ctx.query);
|
|
83
|
+
} else {
|
|
84
|
+
entities = await service.find(ctx.query);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return sanitize(entities);
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Retrieve a record.
|
|
92
|
+
*
|
|
93
|
+
* @return {Object}
|
|
94
|
+
*/
|
|
95
|
+
async findOne(ctx) {
|
|
96
|
+
const { query, params } = ctx;
|
|
97
|
+
const entity = await service.findOne({ ...query, id: params.id });
|
|
98
|
+
|
|
99
|
+
return sanitize(entity);
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Count records.
|
|
104
|
+
*
|
|
105
|
+
* @return {Number}
|
|
106
|
+
*/
|
|
107
|
+
count(ctx) {
|
|
108
|
+
if (_.has(ctx.query, '_q')) {
|
|
109
|
+
return service.countSearch(ctx.query);
|
|
110
|
+
}
|
|
111
|
+
return service.count(ctx.query);
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Create a record.
|
|
116
|
+
*
|
|
117
|
+
* @return {Object}
|
|
118
|
+
*/
|
|
119
|
+
async create(ctx) {
|
|
120
|
+
let entity;
|
|
121
|
+
if (ctx.is('multipart')) {
|
|
122
|
+
const { data, files } = parseMultipartData(ctx);
|
|
123
|
+
entity = await service.create(data, { files });
|
|
124
|
+
} else {
|
|
125
|
+
entity = await service.create(ctx.request.body);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return sanitize(entity);
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Update a record.
|
|
133
|
+
*
|
|
134
|
+
* @return {Object}
|
|
135
|
+
*/
|
|
136
|
+
async update(ctx) {
|
|
137
|
+
let entity;
|
|
138
|
+
if (ctx.is('multipart')) {
|
|
139
|
+
const { data, files } = parseMultipartData(ctx);
|
|
140
|
+
entity = await service.update({ id: ctx.params.id }, data, { files });
|
|
141
|
+
} else {
|
|
142
|
+
entity = await service.update({ id: ctx.params.id }, ctx.request.body);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return sanitize(entity);
|
|
146
|
+
},
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Destroy a record.
|
|
150
|
+
*
|
|
151
|
+
* @return {Object}
|
|
152
|
+
*/
|
|
153
|
+
async delete(ctx) {
|
|
154
|
+
const entity = await service.delete({ id: ctx.params.id });
|
|
155
|
+
return sanitize(entity);
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core API
|
|
3
|
+
*/
|
|
4
|
+
'use strict';
|
|
5
|
+
|
|
6
|
+
const _ = require('lodash');
|
|
7
|
+
|
|
8
|
+
const createController = require('./controller');
|
|
9
|
+
const { createService } = require('./service');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Returns a service and a controller built based on the content type passed
|
|
13
|
+
*/
|
|
14
|
+
function createCoreApi({ api, model, strapi }) {
|
|
15
|
+
const { modelName } = model;
|
|
16
|
+
|
|
17
|
+
// find corresponding service and controller
|
|
18
|
+
const userService = _.get(api, ['services', modelName], {});
|
|
19
|
+
const userController = _.get(api, ['controllers', modelName], {});
|
|
20
|
+
|
|
21
|
+
const service = Object.assign(createService({ model, strapi }), userService);
|
|
22
|
+
|
|
23
|
+
const controller = Object.assign(createController({ service, model }), userController);
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
service,
|
|
27
|
+
controller,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
module.exports = {
|
|
32
|
+
createCoreApi,
|
|
33
|
+
};
|