This commit is contained in:
Pierre Noël 2021-07-29 16:39:26 +02:00
parent 6dab3a5ebb
commit 3b179169d4
40 changed files with 195 additions and 137 deletions

View File

@ -1,6 +1,10 @@
{
"kind": "collectionType",
"collectionName": "countries",
"info": {
"displayName": "country",
"singularName": "country",
"pluralName": "countries",
"name": "country",
"description": ""
},

View File

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

View File

@ -1,5 +1,6 @@
module.exports = () => {
return {
module.exports = {
defaults: { mazdaz: { enabled: true } },
load: {
initialize() {},
};
},
};

View File

@ -14,7 +14,7 @@ const hasProperty = curry((property, subject) => {
const getValidOptions = pick(['applyToProperties']);
const toSubjectTemplate = ct => ({ uid: ct.uid, label: ct.info.name, properties: [] });
const toSubjectTemplate = ct => ({ uid: ct.uid, label: ct.info.singularName, properties: [] });
module.exports = {
isOfKind,

View File

@ -2,7 +2,6 @@
const _ = require('lodash');
const { getOr } = require('lodash/fp');
const pluralize = require('pluralize');
const generator = require('@strapi/generate');
const { nameToSlug, contentTypes: contentTypesUtils } = require('@strapi/utils');
@ -29,8 +28,8 @@ const getRestrictRelationsTo = (contentType = {}) => {
};
const getformattedName = (contentType = {}) => {
const { uid, info } = contentType;
const name = _.get(info, 'name') || _.upperFirst(pluralize(uid));
const { info } = contentType;
const name = _.get(info, 'displayName');
return name;
};

View File

@ -2,6 +2,7 @@
const path = require('path');
const _ = require('lodash');
const { capitalize } = require('lodash/fp');
const createSchemaHandler = require('./schema-handler');
const createComponentBuilder = require('./component-builder');
@ -41,7 +42,7 @@ module.exports = function createBuilder() {
modelName: contentType.modelName,
plugin: contentType.plugin,
uid: contentType.uid,
filename: `${contentType.info.singularName}.json`,
filename: capitalize(`${contentType.info.singularName}.settings.json`),
dir: path.join(strapi.dir, dir),
schema: contentType.__schema__,
};

View File

@ -98,7 +98,7 @@ class SqliteDialect extends Dialect {
transformErrors(error) {
switch (error.errno) {
case 19: {
throw new errors.NotNullConstraint();
throw new errors.NotNullConstraint(); // TODO: extract column name
}
default: {
super.transformErrors(error);

View File

@ -5,7 +5,7 @@ class NotNullConstraint extends Error {
super();
this.name = 'NotNullConstraint';
this.message = `Not null constraint violation${column ? `on on column ${column}` : ''}.`;
this.stack = null;
this.stack = '';
}
}

View File

@ -3,7 +3,7 @@
const _ = require('lodash');
const getProviderSettings = () => {
return strapi.plugins.email.config;
return strapi.config.get('plugins.email');
};
const send = async options => {
@ -37,8 +37,8 @@ const sendTemplatedEmail = (emailOptions = {}, emailTemplate = {}, data = {}) =>
return strapi.plugins.email.provider.send({ ...emailOptions, ...templatedAttributes });
};
module.exports = {
module.exports = () => ({
getProviderSettings,
send,
sendTemplatedEmail,
};
});

View File

@ -332,10 +332,10 @@ class Strapi {
await this.container.load();
const modules = await loadModules(this);
this.plugins = this.container.plugins.getAll();
const modules = await loadModules(this);
this.api = modules.api;
this.admin = modules.admin;
this.components = modules.components;

View File

@ -2,6 +2,14 @@
const { cloneDeep } = require('lodash/fp');
const _ = require('lodash');
const { hasDraftAndPublish } = require('@strapi/utils').contentTypes;
const {
CREATED_AT_ATTRIBUTE,
UPDATED_AT_ATTRIBUTE,
PUBLISHED_AT_ATTRIBUTE,
CREATED_BY_ATTRIBUTE,
UPDATED_BY_ATTRIBUTE,
} = require('@strapi/utils').contentTypes.constants;
const { validateContentTypeDefinition } = require('./validator');
const createContentType = (definition, { apiName, pluginName } = {}) => {
@ -18,6 +26,15 @@ ${e.errors}
const createdContentType = cloneDeep(definition);
// general info
Object.assign(createdContentType.schema, {
kind: createdContentType.schema.kind || 'collectionType',
__schema__: pickSchema(definition.schema),
modelType: 'contentType',
modelName: definition.schema.info.singularName,
connection: 'default',
});
if (apiName) {
Object.assign(createdContentType.schema, {
uid: `application::${apiName}.${definition.schema.info.singularName}`,
@ -42,19 +59,57 @@ ${e.errors}
});
}
Object.assign(createdContentType.schema, {
kind: createdContentType.schema.kind || 'collectionType',
__schema__: pickSchema(definition.schema),
modelType: 'contentType',
modelName: definition.schema.info.singularName,
connection: 'default',
Object.defineProperty(createdContentType.schema, 'privateAttributes', {
get() {
// FIXME: to fix
// return strapi.getModel(model.uid).privateAttributes;
return [];
},
});
// Object.defineProperty(createdContentType.schema, 'privateAttributes', {
// get() {
// console.log('createdContentType.privateAttributes', )
// return strapi.getModel(createdContentType.schema.uid).privateAttributes;
// },
// });
// attributes
Object.assign(createdContentType.schema.attributes, {
[CREATED_AT_ATTRIBUTE]: {
type: 'datetime',
// default: () => new Date(),
},
[UPDATED_AT_ATTRIBUTE]: {
type: 'datetime',
},
});
if (hasDraftAndPublish(createdContentType.schema)) {
createdContentType.schema.attributes[PUBLISHED_AT_ATTRIBUTE] = {
type: 'datetime',
configurable: false,
writable: true,
visible: false,
};
}
const isPrivate = !_.get(createdContentType.schema, 'options.populateCreatorFields', false);
createdContentType.schema.attributes[CREATED_BY_ATTRIBUTE] = {
type: 'relation',
relation: 'oneToOne',
target: 'strapi::user',
configurable: false,
writable: false,
visible: false,
useJoinTable: false,
private: isPrivate,
};
createdContentType.schema.attributes[UPDATED_BY_ATTRIBUTE] = {
type: 'relation',
relation: 'oneToOne',
target: 'strapi::user',
configurable: false,
writable: false,
visible: false,
useJoinTable: false,
private: isPrivate,
};
return createdContentType;
};

View File

@ -23,9 +23,11 @@ module.exports = async function(strapi) {
await loaders.loadInternalMiddlewares(middlewares);
// local middleware
await loaders.loadLocalMiddlewares(appPath, middlewares);
// plugins middlewares
await loaders.loadPluginsMiddlewares(strapi.plugins, middlewares);
// local plugin middlewares
await loaders.loadLocalPluginsMiddlewares(appPath, middlewares);
// load admin middlwares
// load admin middlewares
await loaders.loadAdminMiddlewares(middlewares);
return middlewares;
@ -54,9 +56,14 @@ const createLoaders = strapi => {
loadMiddlewaresInDir(path.resolve(appPath, 'middlewares'), middlewares);
const loadPluginsMiddlewares = async (plugins, middlewares) => {
for (let pluginName of plugins) {
const dir = path.resolve(findPackagePath(`@strapi/plugin-${pluginName}`), 'middlewares');
await loadMiddlewaresInDir(dir, middlewares);
for (const pluginName in plugins) {
const pluginMiddlewares = plugins[pluginName].middlewares;
for (const middlewareName in pluginMiddlewares) {
middlewares[middlewareName] = {
loaded: false,
...pluginMiddlewares[middlewareName],
};
}
}
};

View File

@ -80,6 +80,7 @@ ${e.errors.join('\n')}
contentTypes: contentTypeProvider,
policy: (...args) => policyProvider.get(...args),
policies: policyProvider,
middlewares: cleanPluginServer.middlewares,
};
};

View File

@ -46,7 +46,6 @@ module.exports = async function() {
() => reject(`(middleware: ${middlewareKey}) is taking too long to load.`),
middlewareConfig.timeout || 1000
);
this.middleware[middlewareKey] = merge(this.middleware[middlewareKey], module);
Promise.resolve()

View File

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

View File

@ -5,31 +5,34 @@ const range = require('koa-range');
const koaStatic = require('koa-static');
const _ = require('lodash');
module.exports = strapi => ({
initialize() {
const configPublicPath = strapi.config.get(
'middleware.settings.public.path',
strapi.config.paths.static
);
const staticDir = resolve(strapi.dir, configPublicPath);
module.exports = {
defaults: { upload: { enabled: true } },
load: {
initialize() {
const configPublicPath = strapi.config.get(
'middleware.settings.public.path',
strapi.config.paths.static
);
const staticDir = resolve(strapi.dir, configPublicPath);
strapi.app.on('error', err => {
if (err.code === 'EPIPE') {
// when serving audio or video the browsers sometimes close the connection to go to range requests instead.
// This causes koa to emit a write EPIPE error. We can ignore it.
// Right now this ignores it globally and we cannot do much more because it is how koa handles it.
return;
}
strapi.app.on('error', err => {
if (err.code === 'EPIPE') {
// when serving audio or video the browsers sometimes close the connection to go to range requests instead.
// This causes koa to emit a write EPIPE error. We can ignore it.
// Right now this ignores it globally and we cannot do much more because it is how koa handles it.
return;
}
strapi.app.onerror(err);
});
strapi.app.onerror(err);
});
const localServerConfig =
_.get(strapi, 'plugins.upload.config.providerOptions.localServer') || {};
strapi.router.get(
'/uploads/(.*)',
range,
koaStatic(staticDir, { defer: true, ...localServerConfig })
);
const localServerConfig =
_.get(strapi, 'plugins.upload.config.providerOptions.localServer') || {};
strapi.router.get(
'/uploads/(.*)',
range,
koaStatic(staticDir, { defer: true, ...localServerConfig })
);
},
},
});
};

View File

@ -1,29 +1,24 @@
'use strict';
/**
* Module dependencies
*/
// Public node modules.
const path = require('path');
const _ = require('lodash');
const swaggerUi = require('swagger-ui-dist');
const koaStatic = require('koa-static');
// Variables.
const initialRoutes = [];
module.exports = strapi => {
return {
module.exports = {
defaults: { documentation: { enabled: true } },
load: {
beforeInitialize() {
strapi.config.middleware.load.before.push('documentation');
initialRoutes.push(..._.cloneDeep(strapi.plugins.documentation.config.routes));
initialRoutes.push(..._.cloneDeep(strapi.plugins.documentation.routes));
},
initialize() {
// Find the plugins routes.
strapi.plugins.documentation.config.routes = strapi.plugins.documentation.config.routes.map(
strapi.plugins.documentation.routes = strapi.plugins.documentation.routes.map(
(route, index) => {
if (route.handler === 'Documentation.getInfos') {
return route;
@ -54,5 +49,5 @@ module.exports = strapi => {
})(ctx, next);
});
},
};
},
};

View File

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

View File

@ -1,16 +1,16 @@
'use strict';
const { getOr, get, isMatch } = require('lodash/fp');
const { getOr, isMatch } = require('lodash/fp');
const _ = require('lodash');
module.exports = strapi => {
return {
module.exports = {
defaults: { i18n: { enabled: true } },
load: {
beforeInitialize() {
strapi.config.middleware.load.before.unshift('i18n');
},
initialize() {
const routes = get('plugins.content-manager.config.routes', strapi);
const routes = strapi.plugins['content-manager'].routes;
const routesToAddPolicyTo = routes.filter(
route =>
isMatch({ method: 'POST', path: '/collection-types/:model' }, route) ||
@ -24,5 +24,5 @@ module.exports = strapi => {
_.set(route, 'config.policies', policies);
});
},
};
},
};

View File

@ -1,7 +1,7 @@
'use strict';
const i18nMiddleware = require('./i18n');
const i18n = require('./i18n');
module.exports = {
i18nMiddleware,
i18n,
};

View File

@ -3,8 +3,6 @@
const { has, omit, isArray } = require('lodash/fp');
const { getService } = require('../utils');
const { syncLocalizations, syncNonLocalizedAttributes } = require('./localizations');
const LOCALE_QUERY_FILTER = 'locale';
const SINGLE_ENTRY_ACTIONS = ['findOne', 'update', 'delete'];
const BULK_ACTIONS = ['delete'];
@ -107,6 +105,7 @@ const decorator = service => ({
async create(uid, opts) {
const model = strapi.getModel(uid);
const { syncLocalizations, syncNonLocalizedAttributes } = getService('localizations');
const { isLocalizedContentType } = getService('content-types');
if (!isLocalizedContentType(model)) {
@ -132,6 +131,7 @@ const decorator = service => ({
async update(uid, entityId, opts) {
const model = strapi.getModel(uid);
const { syncNonLocalizedAttributes } = getService('localizations');
const { isLocalizedContentType } = getService('content-types');
if (!isLocalizedContentType(model)) {

View File

@ -18,4 +18,4 @@ type S = {
['core-api']: typeof coreAPI;
};
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

@ -1,3 +0,0 @@
{
"routes": []
}

View File

@ -1,5 +0,0 @@
{
"dsn": null,
"sendMetadata": true,
"init": {}
}

View File

@ -1,9 +0,0 @@
'use strict';
/**
* sentry.js controller
*
* @description: A set of functions called "actions" of the `sentry` plugin.
*/
module.exports = {};

View File

@ -5,7 +5,8 @@
"strapi": {
"name": "Sentry",
"icon": "plug",
"description": "sentry.plugin.description"
"description": "sentry.plugin.description",
"kind": "plugin"
},
"dependencies": {
"@sentry/node": "6.7.1"

View File

@ -0,0 +1,10 @@
'use strict';
module.exports = {
default: {
dsn: null,
sendMetadata: true,
init: {},
},
validator: () => {},
};

View File

@ -0,0 +1,7 @@
'use strict';
const sentry = require('./sentry');
module.exports = {
sentry,
};

View File

@ -20,7 +20,7 @@ jest.mock('@sentry/node', () => {
});
let sentryService = require('../sentry');
const defaultConfig = require('../../config/settings.json');
const defaultConfig = require('../../config').default;
describe('Sentry service', () => {
beforeEach(() => {
@ -37,7 +37,7 @@ describe('Sentry service', () => {
info: jest.fn(),
},
};
sentryService = require('../sentry');
sentryService = require('..');
});
afterEach(() => {

View File

@ -0,0 +1,7 @@
'use strict';
const sentry = require('./sentry');
module.exports = {
sentry,
};

View File

@ -2,9 +2,8 @@
// FIXME
/* eslint-disable import/extensions */
const Sentry = require('@sentry/node');
const defaultSettings = require('../config/settings.json');
const createSentryService = () => {
const createSentryService = strapi => {
let isReady = false;
let instance = null;
let settings = {};
@ -20,10 +19,7 @@ const createSentryService = () => {
}
// Retrieve user settings and merge them with the default ones
settings = {
...defaultSettings,
...strapi.plugins.sentry.config,
};
settings = strapi.config.get('plugins.sentry');
try {
// Don't init Sentry if no DSN was provided
@ -85,4 +81,4 @@ const createSentryService = () => {
};
};
module.exports = createSentryService();
module.exports = ({ strapi }) => createSentryService(strapi);

View File

@ -0,0 +1,13 @@
'use strict';
const bootstrap = require('./server/bootstrap');
const services = require('./server/services');
const middlewares = require('./server/middlewares');
const config = require('./server/config');
module.exports = () => ({
bootstrap,
config,
middlewares,
services,
});

View File

@ -30,6 +30,7 @@ module.exports = async () => {
await getService('users-permissions').initialize();
// TODO: adapt with new extension system
if (!_.get(strapi.plugins['users-permissions'], 'config.jwtSecret')) {
const jwtSecret = uuid();
_.set(strapi.plugins['users-permissions'], 'config.jwtSecret', jwtSecret);

View File

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

View File

@ -1,14 +1,10 @@
'use strict';
/**
* Module dependencies
*/
// Public node modules.
const _ = require('lodash');
module.exports = strapi => {
return {
module.exports = {
defaults: { 'users-permissions': { enabled: true } },
load: {
beforeInitialize() {
strapi.config.middleware.load.before.unshift('users-permissions');
},
@ -36,5 +32,5 @@ module.exports = strapi => {
});
}
},
};
},
};

View File

@ -592,7 +592,7 @@ const getProfile = async (provider, query, callback) => {
const buildRedirectUri = strapi => (provider = '') =>
`${getAbsoluteServerUrl(strapi.config)}/connect/${provider}/callback`;
module.exports = strapi => ({
module.exports = ({ strapi }) => ({
connect: connect(strapi),
buildRedirectUri: buildRedirectUri(strapi),
});

View File

@ -234,9 +234,8 @@ module.exports = ({ strapi }) => ({
const routes = Object.keys(strapi.api || {}).reduce((acc, current) => {
return acc.concat(_.get(strapi.api[current].config, 'routes', []));
}, []);
const clonedPlugins = _.cloneDeep(strapi.plugins);
const pluginsRoutes = Object.keys(clonedPlugins || {}).reduce((acc, current) => {
const routes = _.get(clonedPlugins, [current, 'config', 'routes'], []).reduce((acc, curr) => {
const pluginsRoutes = Object.keys(strapi.plugins).reduce((acc, current) => {
const routes = strapi.container.plugin(current).routes.reduce((acc, curr) => {
const prefix = curr.config.prefix;
const path = prefix !== undefined ? `${prefix}${curr.path}` : `/${current}${curr.path}`;
_.set(curr, 'path', path);