This commit is contained in:
Pierre Noël 2021-08-20 15:23:02 +02:00
parent 98719b6c64
commit 09945a46df
42 changed files with 745 additions and 869 deletions

View File

@ -6,7 +6,7 @@ const routes = require('./routes');
module.exports = strapi => ({
beforeInitialize() {
strapi.config.middleware.load.before.unshift('features-routes'); // TODO
strapi.config.middleware.load.before.unshift('features-routes');
},
initialize() {

View File

@ -16,4 +16,4 @@ type S = {
metrics: typeof metrics;
};
export function getService<T extends keyof S>(name: T): S[T];
export function getService<T extends keyof S>(name: T): ReturnType<S[T]>;

View File

@ -3,30 +3,32 @@
const { intersection, prop } = require('lodash/fp');
const { getRelationalFields } = require('@strapi/utils').relations;
const sendDidConfigureListView = strapi => async (contentType, configuration) => {
const displayedFields = prop('length', configuration.layouts.list);
const relationalFields = getRelationalFields(contentType);
const displayedRelationalFields = intersection(relationalFields, configuration.layouts.list)
.length;
module.exports = ({ strapi }) => {
const sendDidConfigureListView = async (contentType, configuration) => {
const displayedFields = prop('length', configuration.layouts.list);
const relationalFields = getRelationalFields(contentType);
const displayedRelationalFields = intersection(relationalFields, configuration.layouts.list)
.length;
const data = {
containsRelationalFields: !!displayedRelationalFields,
const data = {
containsRelationalFields: !!displayedRelationalFields,
};
if (data.containsRelationalFields) {
Object.assign(data, {
displayedFields,
displayedRelationalFields,
});
}
try {
await strapi.telemetry.send('didConfigureListView', data);
} catch (e) {
// silence
}
};
if (data.containsRelationalFields) {
Object.assign(data, {
displayedFields,
displayedRelationalFields,
});
}
try {
await strapi.telemetry.send('didConfigureListView', data);
} catch (e) {
// silence
}
return {
sendDidConfigureListView,
};
};
module.exports = ({ strapi }) => ({
sendDidConfigureListView: sendDidConfigureListView(strapi),
});

View File

@ -20,4 +20,4 @@ type S = {
uid: typeof uid;
};
export function getService<T extends keyof S>(name: T): S[T];
export function getService<T extends keyof S>(name: T): ReturnType<S[T]>;

View File

@ -3,7 +3,8 @@
"version": "3.6.6",
"description": "Strapi plugin to create content type (API).",
"strapi": {
"name": "Content Type Builder",
"name": "content-type-builder",
"displayName": "Content Type Builder",
"icon": "paint-brush",
"description": "content-type-builder.plugin.description",
"kind": "plugin"

View File

@ -49,7 +49,6 @@ const formatContentType = contentType => {
description: _.get(info, 'description', ''),
draftAndPublish: contentTypesUtils.hasDraftAndPublish({ options }),
pluginOptions: contentType.pluginOptions,
// connection,
kind: kind || 'collectionType',
collectionName,
attributes: formatAttributes(contentType),
@ -239,7 +238,6 @@ const deleteContentType = async (uid, defaultBuilder = undefined) => {
const builder = defaultBuilder || createBuilder();
// make a backup
const apiHandler = strapi.service('plugin::content-type-builder.api-handler');
await new Promise(resolve => setTimeout(resolve, 3000));
await apiHandler.backup(uid);
const contentType = builder.deleteContentType(uid);

View File

@ -153,14 +153,12 @@ function createSchemaBuilder({ components, contentTypes }) {
*
* @returns {void}
*/
async writeFiles() {
return Promise.all(
[...Array.from(tmpComponents.values()), ...Array.from(tmpContentTypes.values())].map(
schema => {
return schema.flush();
}
)
)
writeFiles() {
const schemas = [
...Array.from(tmpComponents.values()),
...Array.from(tmpContentTypes.values()),
];
return Promise.all(schemas.map(schema => schema.flush()))
.catch(error => {
strapi.log.error('Error writing schema files');
strapi.log.error(error);

View File

@ -8,4 +8,4 @@ type S = {
builder: typeof builder;
};
export function getService<T extends keyof S>(name: T): S[T];
export function getService<T extends keyof S>(name: T): ReturnType<S[T]>;

View File

@ -49,7 +49,7 @@ const createConnectorRegistry = ({ defaultConnection, connections }) => {
return _connectors.get(defaultConnector);
},
getByConnection(connection = 'default') {
getByConnection(connection) {
if (!_.has(connections, connection)) {
throw new Error('Trying to access a connector for an unknown connection');
}

View File

@ -3,7 +3,8 @@
"version": "3.6.6",
"description": "Easily configure your Strapi application to send emails.",
"strapi": {
"name": "Email",
"name": "email",
"displayName": "Email",
"icon": "paper-plane",
"description": "email.plugin.description",
"required": true,

View File

@ -25,8 +25,6 @@ const createTelemetry = require('./services/metrics');
const createUpdateNotifier = require('./utils/update-notifier');
const createStartupLogger = require('./utils/startup-logger');
const ee = require('./utils/ee');
// const createContainer = require('./core/container');
// const createContainer = require('./core/container');
const contentTypesRegistry = require('./core/registries/content-types');
const servicesRegistry = require('./core/registries/services');
const policiesRegistry = require('./core/registries/policies');
@ -241,10 +239,6 @@ class Strapi {
this.container.get('modules').add(`plugin::${pluginName}`, plugin);
}
// await this.container.load();
// this.plugins = this.container.plugins.getAll();
const modules = await loadModules(this);
this.loadAdmin();
@ -354,18 +348,6 @@ class Strapi {
return reload;
}
async runBootstraps() {
for (const plugin of this.plugin.getAll()) {
await plugin.bootstrap(this);
}
}
async runRegisters() {
for (const plugin of this.plugin.getAll()) {
await plugin.register(this);
}
}
async runLifecyclesFunctions(lifecycleName) {
const execLifecycle = async fn => {
if (!fn) {
@ -378,11 +360,7 @@ class Strapi {
const configPath = `functions.${lifecycleName}`;
// plugins
if (lifecycleName === LIFECYCLES.BOOTSTRAP) {
await this.container.get('modules').bootstrap();
} else if (lifecycleName === LIFECYCLES.REGISTER) {
await this.container.get('modules').register();
}
await this.container.get('modules')[lifecycleName]();
// user
await execLifecycle(this.config.get(configPath));

View File

@ -11,8 +11,6 @@ dotenv.config({ path: process.env.ENV_PATH });
process.env.NODE_ENV = process.env.NODE_ENV || 'development';
const getPrefixedDeps = require('../../utils/get-prefixed-dependencies');
// const loadPolicies = require('../load-policies');
// const loadFunctions = require('../load-functions');
const loadConfigDir = require('./config-loader');
const { version: strapiVersion } = require(path.join(__dirname, '../../../package.json'));
@ -81,10 +79,8 @@ module.exports = (dir, initialConfig = {}) => {
...pkgJSON,
strapi: strapiVersion,
},
// installedPlugins: getPrefixedDeps('@strapi/plugin', pkgJSON),
installedMiddlewares: getPrefixedDeps('@strapi/middleware', pkgJSON),
installedHooks: getPrefixedDeps('@strapi/hook', pkgJSON),
// installedProviders: getPrefixedDeps('@strapi/provider', pkgJSON),
};
const baseConfig = omit('plugins', loadConfigDir(configDir)); // plugin config will be loaded later

View File

@ -1,6 +1,6 @@
'use strict';
const { cloneDeep, kebabCase } = require('lodash/fp');
const { cloneDeep } = require('lodash/fp');
const _ = require('lodash');
const { hasDraftAndPublish } = require('@strapi/utils').contentTypes;
const {
@ -26,7 +26,7 @@ const createContentType = (uid, definition) => {
kind: createdContentType.schema.kind || 'collectionType',
__schema__: pickSchema(definition.schema),
modelType: 'contentType',
modelName: kebabCase(definition.schema.info.singularName),
modelName: definition.schema.info.singularName,
connection: 'default',
});

View File

@ -19,11 +19,11 @@ const contentTypeSchemaValidator = yup.object().shape({
.shape({
singularName: yup
.string()
.isCamelCase()
.isKebabCase()
.required(),
pluralName: yup
.string()
.isCamelCase()
.isKebabCase()
.required(),
displayName: yup.string().required(),
})

View File

@ -9,27 +9,27 @@ const createModule = (namespace, rawModule, strapi) => {
throw new Error(`strapi-server.js is invalid for plugin ${namespace}.\n${e.errors.join('\n')}`);
}
const loaded = [];
const called = {};
return {
async bootstrap() {
if (loaded.includes('bootstrap')) {
if (called.bootstrap) {
throw new Error(`Bootstrap for ${namespace} has already been called`);
}
loaded.push('bootstrap');
called.bootstrap = true;
await rawModule.bootstrap(strapi);
},
async register() {
if (loaded.includes('register')) {
if (called.register) {
throw new Error(`Register for ${namespace} has already been called`);
}
loaded.push('register');
called.register = true;
await rawModule.register(strapi);
},
async destroy() {
if (loaded.includes('destroy')) {
if (called.destroy) {
throw new Error(`Destroy for ${namespace} has already been called`);
}
loaded.push('destroy');
called.destroy = true;
await rawModule.destroy(strapi);
},
load() {

View File

@ -4,11 +4,17 @@ const { dirname, join } = require('path');
const { statSync, existsSync } = require('fs');
const _ = require('lodash');
const { get, has, pick, pickBy, defaultsDeep, map, prop, pipe } = require('lodash/fp');
const { nameToSlug } = require('@strapi/utils');
const { isKebabCase } = require('@strapi/utils');
const loadConfigFile = require('../app-configuration/load-config-file');
const isStrapiPlugin = info => get('strapi.kind', info) === 'plugin';
const validatePluginName = pluginName => {
if (!isKebabCase(pluginName)) {
throw new Error(`Plugin name "${pluginName}" is not in kebab (an-example-of-kebab-case)`);
}
};
const toDetailedDeclaration = declaration => {
if (typeof declaration === 'boolean') {
return { enabled: declaration };
@ -42,8 +48,8 @@ const getEnabledPlugins = async strapi => {
const packageInfo = require(packagePath);
if (isStrapiPlugin(packageInfo)) {
const cleanPluginName = nameToSlug(packageInfo.strapi.name);
installedPlugins[cleanPluginName] = toDetailedDeclaration({
validatePluginName(packageInfo.strapi.name);
installedPlugins[packageInfo.strapi.name] = toDetailedDeclaration({
enabled: true,
resolve: packagePath,
});
@ -56,8 +62,8 @@ const getEnabledPlugins = async strapi => {
? loadConfigFile(userPluginConfigPath)
: {};
_.forEach(userPluginsConfig, (declaration, pluginName) => {
const cleanPluginName = nameToSlug(pluginName);
declaredPlugins[cleanPluginName] = toDetailedDeclaration(declaration);
validatePluginName(pluginName);
declaredPlugins[pluginName] = toDetailedDeclaration(declaration);
});
const declaredPluginsResolves = map(prop('pathToPlugin'), declaredPlugins);

View File

@ -1,7 +1,7 @@
'use strict';
const _ = require('lodash');
const { toLower, kebabCase, camelCase } = require('lodash/fp');
const { toLower } = require('lodash/fp');
const { getConfigUrls } = require('@strapi/utils');
const pluralize = require('pluralize');
const { createContentType } = require('../domain/content-type');
@ -26,13 +26,34 @@ module.exports = function(strapi) {
};
ct.schema.info.displayName = model.info.name;
ct.schema.info.singularName = camelCase(modelName);
ct.schema.info.pluralName = pluralize(camelCase(modelName));
ct.schema.info.singularName = modelName;
ct.schema.info.pluralName = pluralize(modelName);
const createdContentType = createContentType(
`api::${apiName}.${kebabCase(ct.schema.info.singularName)}`,
ct
);
strapi.container.get('content-types').add(`api::${apiName}`, {
[ct.schema.info.singularName]: ct,
});
// TODO: check unicity of pluralName and singularName amongs user's CT
// const validateContentTypesUnicity = (...contentTypesMaps) => {
// const names = [];
// const arrayOfAllContentTypes = flatten(contentTypesMaps.map(values));
// console.log('arrayOfAllContentTypes', arrayOfAllContentTypes.map(ct => ct.schema.info.singularName));
// arrayOfAllContentTypes.forEach(ct => {
// const singularName = kebabCase(ct.schema.info.singularName);
// const pluralName = kebabCase(ct.schema.info.pluralName);
// if (names.includes(singularName)) {
// throw new Error(`The singular name "${ct.schema.info.singularName}" should be unique`);
// }
// names.push(singularName);
// if (names.includes(pluralName)) {
// throw new Error(`The plural name "${ct.schema.info.pluralName}" should be unique`);
// }
// names.push(pluralName);
// });
// };
const createdContentType = strapi.container
.get('content-types')
.get(`api::${apiName}.${ct.schema.info.singularName}`);
Object.assign(model, createdContentType.schema);
strapi.contentTypes[model.uid] = model;
@ -75,18 +96,13 @@ module.exports = function(strapi) {
// Init admin models.
Object.keys(strapi.admin.models || []).forEach(modelName => {
let model = strapi.admin.models[modelName];
// mutate model
const ct = { schema: model, actions: {}, lifecycles: {} };
ct.schema.info = {};
ct.schema.info.displayName = camelCase(modelName);
ct.schema.info.singularName = camelCase(modelName);
ct.schema.info.pluralName = `${camelCase(modelName)}s`;
ct.schema.info.displayName = model.info.name;
ct.schema.info.singularName = modelName;
ct.schema.info.pluralName = pluralize(modelName);
const createdContentType = createContentType(
`strapi::${kebabCase(ct.schema.info.singularName)}`,
ct
);
const createdContentType = createContentType(`strapi::${ct.schema.info.singularName}`, ct);
Object.assign(model, createdContentType.schema);
strapi.contentTypes[model.uid] = model;

View File

@ -1,73 +0,0 @@
'use strict';
const path = require('path');
const { existsSync } = require('fs-extra');
const fse = require('fs-extra');
const _ = require('lodash');
const loadConfig = require('../../load/load-config-files');
const loadFiles = require('../../load/load-files');
const glob = require('../../load/glob');
const filePathToPath = require('../../load/filepath-to-prop-path');
/**
* Loads the extensions folder
*/
module.exports = async function(strapi) {
const appPath = strapi.config.get('appPath');
const extensionsDir = path.resolve(appPath, 'extensions');
if (!existsSync(extensionsDir)) {
throw new Error(`Missing extensions folder. Please create one in your app root directory`);
}
const configs = await loadConfig(extensionsDir, '*/config/**/*.+(js|json)');
const controllersAndServices = await loadFiles(
extensionsDir,
'*/{controllers,services}/*.+(js|json)'
);
const overwrites = await loadOverwrites(extensionsDir);
return {
overwrites,
merges: _.merge({}, configs, controllersAndServices),
};
};
const OVERWRITABLE_FOLDERS_GLOB = 'models';
// returns a list of path and module to overwrite
const loadOverwrites = async extensionsDir => {
const files = await glob(`*/${OVERWRITABLE_FOLDERS_GLOB}/*.*(js|json)`, {
cwd: extensionsDir,
});
const overwrites = {};
files.forEach(file => {
const absolutePath = path.resolve(extensionsDir, file);
// load module
delete require.cache[absolutePath];
let mod;
if (path.extname(absolutePath) === '.json') {
mod = fse.readJsonSync(absolutePath);
} else {
mod = require(absolutePath);
}
const propPath = filePathToPath(file);
const strPath = propPath.join('.');
if (overwrites[strPath]) {
_.merge(overwrites[strPath], mod);
} else {
overwrites[strPath] = mod;
}
});
return Object.keys(overwrites).map(strPath => ({
path: strPath.split('.'),
mod: overwrites[strPath],
}));
};

View File

@ -1,53 +1,21 @@
/**
* Load Modules is the root module loader.
* This is where all the strapi enviornment is laoded
* - APIs
* - Plugins
* - Hooks
* - Middlewres
* - Components
* - ContentTypes
*/
'use strict';
const loadApis = require('./load-apis');
// const loadPlugins = require('./load-plugins');
const loadMiddlewares = require('./load-middlewares');
const loadExtensions = require('./load-extensions');
const loadComponents = require('./load-components');
module.exports = async strapi => {
const [api, middlewares, extensions, components] = await Promise.all([
const [api, middlewares, components] = await Promise.all([
loadApis(strapi),
loadMiddlewares(strapi),
loadExtensions(strapi),
loadMiddlewares(strapi), // TODO: load in the middleware registry directly
loadComponents(strapi),
]);
// TODO: move this into the appropriate loaders
/**
* Handle plugin extensions
*/
// merge extensions config folders
// _.mergeWith(plugins, extensions.merges, (objValue, srcValue, key) => {
// // concat routes
// if (_.isArray(srcValue) && _.isArray(objValue) && key === 'routes') {
// return srcValue.concat(objValue);
// }
// });
// // overwrite plugins with extensions overwrites
// extensions.overwrites.forEach(({ path, mod }) => {
// _.assign(_.get(plugins, path), mod);
// });
return {
api,
middlewares,
extensions,
components,
};
};

View File

@ -6,7 +6,7 @@ module.exports = (initialConfig = {}) => {
const _config = Object.assign({}, initialConfig); // not deep clone because it would break some config
return {
..._config, // to remove
..._config, // TODO: to remove
get(path, defaultValue) {
return _.get(_config, path, defaultValue);
},

View File

@ -3,22 +3,6 @@
const { pickBy, has } = require('lodash/fp');
const { createContentType } = require('../domain/content-type');
// const validateContentTypesUnicity = contentTypes => {
// const names = [];
// contentTypes.forEach(ct => {
// const singularName = kebabCase(ct.schema.info.singularName);
// const pluralName = kebabCase(ct.schema.info.pluralName);
// if (names.includes(singularName)) {
// throw new Error(`The singular name "${ct.schema.info.singularName}" should be unique`);
// }
// names.push(singularName);
// if (names.includes(pluralName)) {
// throw new Error(`The plural name "${ct.schema.info.pluralName}" should be unique`);
// }
// names.push(pluralName);
// });
// };
const validateKeySameToSingularName = contentTypes => {
for (const ctName in contentTypes) {
const contentType = contentTypes[ctName];

View File

@ -3,24 +3,24 @@
const { pickBy, has } = require('lodash/fp');
const middlewaresRegistry = () => {
const _middlewares = {};
const middlewares = {};
return {
get(middlewareUID) {
return _middlewares[middlewareUID];
return middlewares[middlewareUID];
},
getAll(prefix = '') {
return pickBy((middleware, middlewareUID) => middlewareUID.startsWith(prefix))(_middlewares);
return pickBy((middleware, middlewareUID) => middlewareUID.startsWith(prefix))(middlewares);
},
add(namespace, middlewares) {
for (const middlewareName in middlewares) {
const middleware = middlewares[middlewareName];
const uid = `${namespace}.${middlewareName}`;
if (has(uid, _middlewares)) {
if (has(uid, middlewares)) {
throw new Error(`Middleware ${uid} has already been registered.`);
}
_middlewares[uid] = middleware;
middlewares[uid] = middleware;
}
},
};

View File

@ -12,7 +12,9 @@ describe('metrics', () => {
metrics({
config: {
get: get(this),
get(path) {
return get(path, this);
},
uuid: 'test',
environment: 'dev',
info: {
@ -32,7 +34,9 @@ describe('metrics', () => {
metrics({
config: {
get: get(this),
get(path) {
return get(path, this);
},
uuid: false,
environment: 'dev',
info: {
@ -50,7 +54,9 @@ describe('metrics', () => {
test('Send payload with meta', () => {
const { send } = metrics({
config: {
get: get(this),
get(path) {
return get(path, this);
},
uuid: 'test',
environment: 'dev',
info: {
@ -80,7 +86,9 @@ describe('metrics', () => {
test('Does not send payload when disabled', () => {
const { send } = metrics({
config: {
get: get(this),
get(path) {
return get(path, this);
},
uuid: false,
packageJsonStrapi: {},
environment: 'dev',

View File

@ -23,7 +23,7 @@ const LIMITED_EVENTS = [
];
const createTelemetryInstance = strapi => {
const { uuid } = strapi.config;
const uuid = strapi.config.get('uuid');
const isDisabled = !uuid || isTruthy(process.env.STRAPI_TELEMETRY_DISABLED);
const crons = [];
@ -83,7 +83,8 @@ const hash = str =>
.update(str)
.digest('hex');
const hashProject = strapi => hash(`${strapi.config.info.name}${strapi.config.info.description}`);
const hashProject = strapi =>
hash(`${strapi.config.get('info.name')}${strapi.config.get('info.description')}`);
const hashDep = strapi => {
const depStr = JSON.stringify(strapi.config.info.dependencies);

View File

@ -3,5 +3,5 @@
const file = require('./file');
module.exports = {
[file.schema.info.singularName]: file,
file,
};

View File

@ -4,4 +4,4 @@ type S = {
upload: typeof upload;
};
export function getService<T extends keyof S>(name: T): S[T];
export function getService<T extends keyof S>(name: T): ReturnType<S[T]>;

View File

@ -23,6 +23,8 @@ const {
escapeQuery,
stringIncludes,
stringEquals,
isKebabCase,
isCamelCase,
} = require('./string-formatting');
const { removeUndefined } = require('./object-formatting');
const { getConfigUrls, getAbsoluteAdminUrl, getAbsoluteServerUrl } = require('./config');
@ -60,6 +62,8 @@ module.exports = {
generateTimestampCode,
stringIncludes,
stringEquals,
isKebabCase,
isCamelCase,
contentTypes,
webhook,
env,

View File

@ -33,6 +33,8 @@ const escapeQuery = (query, charsToEscape, escapeChar = '\\') => {
const stringIncludes = (arr, val) => arr.map(String).includes(String(val));
const stringEquals = (a, b) => String(a) === String(b);
const isCamelCase = value => /^[a-z][a-zA-Z0-9]+$/.test(value);
const isKebabCase = value => /^([a-z][a-z0-9]*)(-[a-z0-9]+)*$/.test(value);
module.exports = {
nameToSlug,
@ -42,4 +44,6 @@ module.exports = {
escapeQuery,
stringIncludes,
stringEquals,
isCamelCase,
isKebabCase,
};

View File

@ -2,6 +2,7 @@
const yup = require('yup');
const _ = require('lodash');
const utils = require('./string-formatting');
const MixedSchemaType = yup.mixed;
@ -21,7 +22,11 @@ function isFunction(message = '${path} is not a function') {
}
function isCamelCase(message = '${path} is not in camel case (anExampleOfCamelCase)') {
return this.test('is in camelCase', message, value => value === _.camelCase(value));
return this.test('is in camelCase', message, value => utils.isCamelCase(value));
}
function isKebabCase(message = '${path} is not in kebab case (an-example-of-kebab-case)') {
return this.test('is in kebab-case', message, value => utils.isKebabCase(value));
}
function onlyContainsFunctions(message = '${path} contains values that are not functions') {
@ -36,6 +41,7 @@ yup.addMethod(yup.mixed, 'notNil', isNotNill);
yup.addMethod(yup.mixed, 'notNull', isNotNull);
yup.addMethod(yup.mixed, 'isFunction', isFunction);
yup.addMethod(yup.string, 'isCamelCase', isCamelCase);
yup.addMethod(yup.string, 'isKebabCase', isKebabCase);
yup.addMethod(yup.object, 'onlyContainsFunctions', onlyContainsFunctions);
class StrapiIDSchema extends MixedSchemaType {

View File

@ -1,7 +1,7 @@
'use strict';
const localeModel = require('./locale');
const locale = require('./locale');
module.exports = {
[localeModel.schema.info.singularName]: localeModel,
locale,
};

View File

@ -1,14 +0,0 @@
'use strict';
module.exports = {
// find() {},
// create() {},
// findPage() {},
// findWithRelationCounts() {},
// findOne() {},
// update() {},
// delete() {},
// search() {},
// searchWithRelationCounts() {},
// searchPage() {},
};

View File

@ -1,11 +1,7 @@
'use strict';
const schema = require('./schema');
const actions = require('./actions');
const lifecycles = require('./lifecycles');
module.exports = {
schema,
actions,
lifecycles,
};

View File

@ -1,5 +0,0 @@
'use strict';
module.exports = {
beforeCreate() {},
afterCreate() {},
};

View File

@ -7,6 +7,7 @@ module.exports = {
defaults: { i18n: { enabled: true } },
load: {
beforeInitialize() {
console.log('beforeInitialize i18n');
strapi.config.middleware.load.before.unshift('i18n');
},
initialize() {

View File

@ -1,5 +0,0 @@
{
"sentry": {
"enabled": true
}
}

View File

@ -1,33 +1,36 @@
'use strict';
module.exports = strapi => ({
beforeInitialize() {
strapi.config.middleware.load.after.unshift('sentry');
},
initialize() {
const { sentry } = strapi.plugins.sentry.services;
sentry.init();
module.exports = {
defaults: { sentry: { enabled: true } },
load: {
beforeInitialize() {
strapi.config.middleware.load.after.unshift('sentry');
},
initialize() {
const { sentry } = strapi.plugins.sentry.services;
sentry.init();
strapi.app.use(async (ctx, next) => {
try {
await next();
} catch (error) {
sentry.sendError(error, (scope, sentryInstance) => {
scope.addEventProcessor(event => {
// Parse Koa context to add error metadata
return sentryInstance.Handlers.parseRequest(event, ctx.request, {
// Don't parse the transaction name, we'll do it manually
transaction: false,
strapi.app.use(async (ctx, next) => {
try {
await next();
} catch (error) {
sentry.sendError(error, (scope, sentryInstance) => {
scope.addEventProcessor(event => {
// Parse Koa context to add error metadata
return sentryInstance.Handlers.parseRequest(event, ctx.request, {
// Don't parse the transaction name, we'll do it manually
transaction: false,
});
});
// Manually add transaction name
scope.setTag('transaction', `${ctx.method} ${ctx.request.url}`);
// Manually add Strapi version
scope.setTag('strapi_version', strapi.config.info.strapi);
scope.setTag('method', ctx.method);
});
// Manually add transaction name
scope.setTag('transaction', `${ctx.method} ${ctx.request.url}`);
// Manually add Strapi version
scope.setTag('strapi_version', strapi.config.info.strapi);
scope.setTag('method', ctx.method);
});
throw error;
}
});
throw error;
}
});
},
},
});
};

View File

@ -26,7 +26,7 @@ const createSentryService = strapi => {
if (settings.dsn) {
Sentry.init({
dsn: settings.dsn,
environment: strapi.config.environment,
environment: strapi.config.get('environment'),
...settings.init,
});
// Store the successfully initialized Sentry instance

View File

@ -36,7 +36,7 @@ describe('USERS PERMISSIONS | COMPONENTS | UserPermissions | init', () => {
application: [{ method: 'GET', path: '/addresses' }],
};
const policies = ['isAuthenticated', 'rateLimit', 'custompolicy'];
const policies = ['isAuthenticated', 'rateLimit', 'customPolicy'];
const expected = {
initialData: permissions,

View File

@ -33,8 +33,8 @@ module.exports = async () => {
// TODO: adapt with new extension system
if (!strapi.config.get('plugin.users-permissions.jwtSecret')) {
const jwtSecret = uuid();
strapi.config.set('plugin.users-permissions.jwtSecret', jwtSecret),
(strapi.reload.isWatching = false);
strapi.config.set('plugin.users-permissions.jwtSecret', jwtSecret);
strapi.reload.isWatching = false;
if (!process.env.JWT_SECRET) {
await strapi.fs.appendFile('.env', `JWT_SECRET=${jwtSecret}\n`);

View File

@ -5,7 +5,7 @@ const role = require('./role');
const user = require('./user');
module.exports = {
[permission.schema.info.singularName]: permission,
[role.schema.info.singularName]: role,
[user.schema.info.singularName]: user,
permission,
role,
user,
};

File diff suppressed because it is too large Load Diff

View File

@ -8,4 +8,4 @@ type S = {
jwt: typeof jwt;
};
export function getService<T extends keyof S>(name: T): S[T];
export function getService<T extends keyof S>(name: T): ReturnType<S[T]>;