diff --git a/examples/getstarted/api/articles/config/schema.graphql b/examples/getstarted/api/articles/config/schema.graphql new file mode 100644 index 0000000000..f053ebf797 --- /dev/null +++ b/examples/getstarted/api/articles/config/schema.graphql @@ -0,0 +1 @@ +module.exports = {}; diff --git a/examples/getstarted/api/articles/controllers/Articles.js b/examples/getstarted/api/articles/controllers/Articles.js index 86cfb50284..f053ebf797 100644 --- a/examples/getstarted/api/articles/controllers/Articles.js +++ b/examples/getstarted/api/articles/controllers/Articles.js @@ -1,5 +1 @@ -module.exports = { - find(ctx) { - ctx.body = 'coucou'; - }, -}; +module.exports = {}; diff --git a/examples/getstarted/api/articles/models/Articles.settings.json b/examples/getstarted/api/articles/models/Articles.settings.json index dbdeac20c3..6afe659c4a 100644 --- a/examples/getstarted/api/articles/models/Articles.settings.json +++ b/examples/getstarted/api/articles/models/Articles.settings.json @@ -9,6 +9,8 @@ "timestamps": true }, "attributes": { - + "title": { + "type": "string" + } } } diff --git a/examples/getstarted/api/tags/config/schema.graphql b/examples/getstarted/api/tags/config/schema.graphql new file mode 100644 index 0000000000..4ba52ba2c8 --- /dev/null +++ b/examples/getstarted/api/tags/config/schema.graphql @@ -0,0 +1 @@ +module.exports = {} diff --git a/examples/getstarted/api/tags/models/Tags.settings.json b/examples/getstarted/api/tags/models/Tags.settings.json index e9e5ac6fa6..63917ec163 100644 --- a/examples/getstarted/api/tags/models/Tags.settings.json +++ b/examples/getstarted/api/tags/models/Tags.settings.json @@ -9,6 +9,8 @@ "timestamps": true }, "attributes": { - + "name": { + "type": "string" + } } } diff --git a/examples/getstarted/extensions/users-permissions/config/actions.json b/examples/getstarted/extensions/users-permissions/config/actions.json deleted file mode 100644 index 5baf9610c5..0000000000 --- a/examples/getstarted/extensions/users-permissions/config/actions.json +++ /dev/null @@ -1 +0,0 @@ -{"actions":["application.articles.find","application.articles.findone","application.articles.count","application.articles.create","application.articles.update","application.articles.destroy","application.tags.find","application.tags.findone","application.tags.count","application.tags.create","application.tags.update","application.tags.destroy","content-manager.contentmanager.models","content-manager.contentmanager.find","content-manager.contentmanager.count","content-manager.contentmanager.findone","content-manager.contentmanager.create","content-manager.contentmanager.update","content-manager.contentmanager.updatesettings","content-manager.contentmanager.delete","content-manager.contentmanager.deleteall","content-type-builder.contenttypebuilder.getmodels","content-type-builder.contenttypebuilder.getmodel","content-type-builder.contenttypebuilder.getconnections","content-type-builder.contenttypebuilder.createmodel","content-type-builder.contenttypebuilder.updatemodel","content-type-builder.contenttypebuilder.deletemodel","content-type-builder.contenttypebuilder.autoreload","content-type-builder.contenttypebuilder.checktableexists","email.email.send","email.email.getenvironments","email.email.getsettings","email.email.updatesettings","settings-manager.settingsmanager.menu","settings-manager.settingsmanager.environments","settings-manager.settingsmanager.languages","settings-manager.settingsmanager.databases","settings-manager.settingsmanager.database","settings-manager.settingsmanager.databasemodel","settings-manager.settingsmanager.get","settings-manager.settingsmanager.update","settings-manager.settingsmanager.createlanguage","settings-manager.settingsmanager.deletelanguage","settings-manager.settingsmanager.createdatabase","settings-manager.settingsmanager.updatedatabase","settings-manager.settingsmanager.deletedatabase","settings-manager.settingsmanager.autoreload","upload.upload.upload","upload.upload.getenvironments","upload.upload.getsettings","upload.upload.updatesettings","upload.upload.find","upload.upload.findone","upload.upload.count","upload.upload.destroy","upload.upload.search","users-permissions.auth.callback","users-permissions.auth.changepassword","users-permissions.auth.connect","users-permissions.auth.forgotpassword","users-permissions.auth.register","users-permissions.auth.emailconfirmation","users-permissions.user.find","users-permissions.user.me","users-permissions.user.findone","users-permissions.user.create","users-permissions.user.update","users-permissions.user.destroy","users-permissions.user.destroyall","users-permissions.userspermissions.createrole","users-permissions.userspermissions.deleteprovider","users-permissions.userspermissions.deleterole","users-permissions.userspermissions.getpermissions","users-permissions.userspermissions.getpolicies","users-permissions.userspermissions.getrole","users-permissions.userspermissions.getroles","users-permissions.userspermissions.getroutes","users-permissions.userspermissions.index","users-permissions.userspermissions.init","users-permissions.userspermissions.searchusers","users-permissions.userspermissions.updaterole","users-permissions.userspermissions.getemailtemplate","users-permissions.userspermissions.updateemailtemplate","users-permissions.userspermissions.getadvancedsettings","users-permissions.userspermissions.updateadvancedsettings","users-permissions.userspermissions.getproviders","users-permissions.userspermissions.updateproviders"]} \ No newline at end of file diff --git a/examples/getstarted/package.json b/examples/getstarted/package.json index 371d1fc40a..beb16a7adf 100644 --- a/examples/getstarted/package.json +++ b/examples/getstarted/package.json @@ -29,6 +29,7 @@ "strapi-plugin-content-manager": "3.0.0-alpha.25.2", "strapi-plugin-content-type-builder": "3.0.0-alpha.25.2", "strapi-plugin-email": "3.0.0-alpha.25.2", + "strapi-plugin-graphql": "^0.0.0", "strapi-plugin-settings-manager": "3.0.0-alpha.25.2", "strapi-plugin-upload": "3.0.0-alpha.25.2", "strapi-plugin-users-permissions": "3.0.0-alpha.25.2", diff --git a/examples/getstarted/plugins/myplugin/config/schema.graphql b/examples/getstarted/plugins/myplugin/config/schema.graphql new file mode 100644 index 0000000000..4ba52ba2c8 --- /dev/null +++ b/examples/getstarted/plugins/myplugin/config/schema.graphql @@ -0,0 +1 @@ +module.exports = {} diff --git a/examples/getstarted/plugins/myplugin/controllers/test.js b/examples/getstarted/plugins/myplugin/controllers/test.js new file mode 100644 index 0000000000..1328e25312 --- /dev/null +++ b/examples/getstarted/plugins/myplugin/controllers/test.js @@ -0,0 +1,8 @@ +module.exports = { + findOne(ctx) { + ctx.body = {}; + }, + find(ctx) { + ctx.body = []; + }, +}; diff --git a/packages/strapi-hook-bookshelf/lib/utils/connectivity.js b/packages/strapi-hook-bookshelf/lib/utils/connectivity.js index 09d68974cc..b2b5be2e93 100644 --- a/packages/strapi-hook-bookshelf/lib/utils/connectivity.js +++ b/packages/strapi-hook-bookshelf/lib/utils/connectivity.js @@ -23,7 +23,7 @@ module.exports = (scope, success, error) => { } // eslint-disable-next-line import/no-unresolved - knex = knex({ + const client = knex({ client: scope.client.module, connection: Object.assign({}, scope.database.settings, { user: scope.database.settings.username @@ -31,15 +31,15 @@ module.exports = (scope, success, error) => { useNullAsDefault: true }); - knex.raw('select 1+1 as result').then(() => { + client.raw('select 1+1 as result').then(() => { const selectQueries = { postgres: 'SELECT tablename FROM pg_tables WHERE schemaname=\'public\'', mysql: 'SELECT * FROM information_schema.tables', sqlite: 'select * from sqlite_master' }; - knex.raw(selectQueries[scope.client.database]).then((tables) => { - knex.destroy(); + client.raw(selectQueries[scope.client.database]).then((tables) => { + client.destroy(); const next = () => { rimraf(scope.tmpPath, (err) => { diff --git a/packages/strapi-plugin-graphql/hooks/graphql/index.js b/packages/strapi-plugin-graphql/hooks/graphql/index.js index 8e26fe4d38..987302669b 100644 --- a/packages/strapi-plugin-graphql/hooks/graphql/index.js +++ b/packages/strapi-plugin-graphql/hooks/graphql/index.js @@ -6,12 +6,13 @@ // Public node modules. const _ = require('lodash'); -const path = require('path'); -const glob = require('glob'); const { ApolloServer } = require('apollo-server-koa'); const depthLimit = require('graphql-depth-limit'); +const loadConfigs = require('./load-config'); module.exports = strapi => { + const { appPath, installedPlugins } = strapi.config; + return { beforeInitialize: async function() { // Try to inject this hook just after the others hooks to skip the router processing. @@ -20,132 +21,40 @@ module.exports = strapi => { } strapi.config.hook.load.after.push('graphql'); - // Load core utils. - const utils = require(path.resolve( - strapi.config.appPath, - 'node_modules', - 'strapi', - 'lib', - 'utils' - )); - // Set '*.graphql' files configurations in the global variable. - await Promise.all([ - // Load root configurations. - new Promise((resolve, reject) => { - glob( - './config/*.graphql?(.js)', - { - cwd: strapi.config.appPath, - }, - (err, files) => { - if (err) { - return reject(err); - } - - utils.loadConfig - .call(strapi, files, true) - .then(resolve) - .catch(reject); - } - ); - }), - // Load APIs configurations. - new Promise((resolve, reject) => { - glob( - './api/*/config/*.graphql?(.js)', - { - cwd: strapi.config.appPath, - }, - (err, files) => { - if (err) { - return reject(err); - } - - utils.loadConfig - .call(strapi, files, true) - .then(resolve) - .catch(reject); - } - ); - }), - // Load plugins configurations. - new Promise((resolve, reject) => { - glob( - './plugins/*/config/*.graphql?(.js)', - { - cwd: strapi.config.appPath, - }, - (err, files) => { - if (err) { - return reject(err); - } - - utils.loadConfig - .call(strapi, files, true) - .then(resolve) - .catch(reject); - } - ); - }), - ]); + const configs = await loadConfigs({ appPath, installedPlugins }); + _.merge(strapi, configs); /* * Create a merge of all the GraphQL configuration. */ + const apisSchemas = Object.keys(strapi.api || {}).map(key => + _.get(strapi.api[key], 'config.schema.graphql', {}) + ); - // Set path with initial state. - _.set(strapi.plugins.graphql, 'config._schema.graphql', { - definition: '', - query: '', - mutation: '', - type: {}, - resolver: {}, - }); + const pluginsSchemas = Object.keys(strapi.plugins || {}).map(key => + _.get(strapi.plugins[key], 'config.schema.graphql', {}) + ); - // Merge user API. - Object.keys(strapi.api || {}).reduce((acc, current) => { - const { definition, query, mutation, type, resolver } = _.get( - strapi.api[current], - 'config.schema.graphql', - {} - ); - - acc.definition += definition || ''; - acc.query += query || ''; - acc.mutation += mutation || ''; - - return _.merge(acc, { - type, - resolver, - }); - }, strapi.plugins.graphql.config._schema.graphql); - - // Merge plugins API. - Object.keys(strapi.plugins || {}).reduce((acc, current) => { - const { definition, query, mutation, type, resolver } = _.get( - strapi.plugins[current], - 'config.schema.graphql', - {} - ); - - acc.definition += definition || ''; - acc.query += query || ''; - acc.mutation += mutation || ''; - - return _.merge(acc, { - type, - resolver, - }); - }, strapi.plugins.graphql.config._schema.graphql); + // save the final schema in the plugin's config + _.set( + strapi, + ['plugins', 'graphql', 'config', '_schema', 'graphql'], + mergeSchemas([...apisSchemas, ...pluginsSchemas]) + ); }, initialize: function(cb) { - const { typeDefs, resolvers } = strapi.plugins.graphql.services.schema.generateSchema(); + const { + typeDefs, + resolvers, + } = strapi.plugins.graphql.services.schema.generateSchema(); if (_.isEmpty(typeDefs)) { - strapi.log.warn('GraphQL schema has not been generated because it\'s empty'); + strapi.log.warn( + 'The GraphQL schema has not been generated because it is empty' + ); return cb(); } @@ -155,6 +64,7 @@ module.exports = strapi => { resolvers, context: ({ ctx }) => { // Initiliase loaders for this request. + // TODO: set loaders in the context not globally strapi.plugins.graphql.services.loaders.initializeLoader(); return { @@ -189,3 +99,21 @@ module.exports = strapi => { }, }; }; + +/** + * Merges a list of schemas + * @param {Array} schemas - The list of schemas to merge + */ +const mergeSchemas = schemas => { + return schemas.reduce((acc, el) => { + const { definition, query, mutation, type, resolver } = el; + + return _.merge(acc, { + definition: `${acc.definition || ''} ${definition || ''}`, + query: `${acc.query || ''} ${query || ''}`, + mutation: `${acc.mutation || ''} ${mutation || ''}`, + type, + resolver, + }); + }, {}); +}; diff --git a/packages/strapi-plugin-graphql/hooks/graphql/load-config.js b/packages/strapi-plugin-graphql/hooks/graphql/load-config.js new file mode 100644 index 0000000000..e66da72769 --- /dev/null +++ b/packages/strapi-plugin-graphql/hooks/graphql/load-config.js @@ -0,0 +1,36 @@ +const loadUtils = require('strapi/lib/load'); +const _ = require('lodash'); + +const loadApisGraphqlConfig = appPath => + loadUtils.loadFiles(appPath, 'api/**/config/*.graphql?(.js)'); + +const loadPluginsGraphqlConfig = async installedPlugins => { + const root = {}; + + for (let pluginName of installedPlugins) { + const pluginDir = loadUtils.findPackagePath(`strapi-plugin-${pluginName}`); + + const result = await loadUtils.loadFiles( + pluginDir, + 'config/*.graphql?(.js)' + ); + _.set(root, ['plugins', pluginName], result); + } + return root; +}; + +const loadLocalPluginsGraphqlConfig = async appPath => + loadUtils.loadFiles(appPath, 'plugins/**/config/*.graphql?(.js)'); + +/** + * Loads the graphql config files + */ +module.exports = async ({ appPath, installedPlugins }) => { + const [apis, plugins, localPlugins] = await Promise.all([ + loadApisGraphqlConfig(appPath), + loadPluginsGraphqlConfig(installedPlugins), + loadLocalPluginsGraphqlConfig(appPath), + ]); + + return _.merge({}, apis, plugins, localPlugins); +}; diff --git a/packages/strapi-plugin-graphql/services/Resolvers.js b/packages/strapi-plugin-graphql/services/Resolvers.js index 8cdb7f977e..f74348744f 100644 --- a/packages/strapi-plugin-graphql/services/Resolvers.js +++ b/packages/strapi-plugin-graphql/services/Resolvers.js @@ -112,6 +112,7 @@ const buildShadowCRUD = (models, plugin) => { delete attributes[association.alias]; }); + acc.definition += `${Schema.getDescription( type[globalId], model diff --git a/packages/strapi-plugin-graphql/services/Schema.js b/packages/strapi-plugin-graphql/services/Schema.js index a8d72bb61d..ebac664342 100644 --- a/packages/strapi-plugin-graphql/services/Schema.js +++ b/packages/strapi-plugin-graphql/services/Schema.js @@ -136,11 +136,18 @@ const schemaBuilder = { // build defaults schemas if shadowCRUD is enabled if (strapi.plugins.graphql.config.shadowCRUD !== false) { - const models = Object.keys(strapi.models).filter(model => model !== 'core_store'); + const models = Object.keys(strapi.models).filter( + model => model !== 'core_store' + ); const modelCruds = Resolvers.buildShadowCRUD(models); shadowCRUD = Object.keys(strapi.plugins).reduce((acc, plugin) => { - const { definition, query, mutation, resolver } = Resolvers.buildShadowCRUD( + const { + definition, + query, + mutation, + resolver, + } = Resolvers.buildShadowCRUD( Object.keys(strapi.plugins[plugin].models), plugin ); @@ -165,14 +172,17 @@ const schemaBuilder = { } = strapi.plugins.graphql.config._schema.graphql; // Polymorphic. - const { polymorphicDef, polymorphicResolver } = Types.addPolymorphicUnionType( - definition, - shadowCRUD.definition - ); + const { + polymorphicDef, + polymorphicResolver, + } = Types.addPolymorphicUnionType(definition, shadowCRUD.definition); // Build resolvers. const resolvers = - _.omitBy(_.merge(shadowCRUD.resolver, resolver, polymorphicResolver), _.isEmpty) || {}; + _.omitBy( + _.merge(shadowCRUD.resolver, resolver, polymorphicResolver), + _.isEmpty + ) || {}; // Transform object to only contain function. Object.keys(resolvers).reduce((acc, type) => { @@ -188,8 +198,13 @@ const schemaBuilder = { acc[type][resolver] = acc[type][resolver].resolver; } - if (_.isString(acc[type][resolver]) || _.isPlainObject(acc[type][resolver])) { - const { plugin = '' } = _.isPlainObject(acc[type][resolver]) ? acc[type][resolver] : {}; + if ( + _.isString(acc[type][resolver]) || + _.isPlainObject(acc[type][resolver]) + ) { + const { plugin = '' } = _.isPlainObject(acc[type][resolver]) + ? acc[type][resolver] + : {}; switch (type) { case 'Mutation': @@ -226,24 +241,34 @@ const schemaBuilder = { ${definition} ${shadowCRUD.definition} type Query {${shadowCRUD.query && - this.formatGQL(shadowCRUD.query, resolver.Query, null, 'query')}${query}} + this.formatGQL( + shadowCRUD.query, + resolver.Query, + null, + 'query' + )}${query}} type Mutation {${shadowCRUD.mutation && - this.formatGQL(shadowCRUD.mutation, resolver.Mutation, null, 'mutation')}${mutation}} + this.formatGQL( + shadowCRUD.mutation, + resolver.Mutation, + null, + 'mutation' + )}${mutation}} ${Types.addCustomScalar(resolvers)} ${Types.addInput()} ${polymorphicDef} `; - // Build schema. - const schema = makeExecutableSchema({ - typeDefs, - resolvers, - }); + // // Build schema. + // const schema = makeExecutableSchema({ + // typeDefs, + // resolvers, + // }); - if (!strapi.config.currentEnvironment.server.production) { - // Write schema. - this.writeGenerateSchema(graphql.printSchema(schema)); - } + // if (!strapi.config.currentEnvironment.server.production) { + // // Write schema. + // this.writeGenerateSchema(graphql.printSchema(schema)); + // } // Remove custom scaler (like Upload); typeDefs = Types.removeCustomScalar(typeDefs, resolvers); @@ -263,7 +288,7 @@ const schemaBuilder = { writeGenerateSchema: schema => { const generatedFolder = path.resolve( strapi.config.appPath, - 'plugins', + 'extensions', 'graphql', 'config', 'generated' diff --git a/packages/strapi-plugin-graphql/services/Types.js b/packages/strapi-plugin-graphql/services/Types.js index bf9977408c..373885ee3d 100644 --- a/packages/strapi-plugin-graphql/services/Types.js +++ b/packages/strapi-plugin-graphql/services/Types.js @@ -30,7 +30,7 @@ module.exports = { modelName = '', attributeName = '', rootType = 'query', - action = '' + action = '', }) { // Type if (definition.type) { @@ -155,11 +155,11 @@ module.exports = { */ addPolymorphicUnionType: (customDefs, defs) => { + const def = customDefs + defs; const types = graphql - .parse(customDefs + defs) + .parse(def) .definitions.filter( - def => - def.kind === 'ObjectTypeDefinition' && def.name.value !== 'Query', + def => def.kind === 'ObjectTypeDefinition' && def.name.value !== 'Query' ) .map(def => def.name.value); @@ -216,7 +216,7 @@ module.exports = { modelName: globalId, attributeName: attribute, rootType: 'mutation', - action: 'update' + action: 'update', })}`; }) .join('\n')} diff --git a/packages/strapi/lib/Strapi.js b/packages/strapi/lib/Strapi.js index 040ca3f16c..14a342e305 100644 --- a/packages/strapi/lib/Strapi.js +++ b/packages/strapi/lib/Strapi.js @@ -18,7 +18,7 @@ const { bootstrap, plugins, admin, - store, + initCoreStore, } = require('./core'); const initializeMiddlewares = require('./middlewares'); const initializeHooks = require('./hooks'); @@ -228,17 +228,19 @@ class Strapi extends EventEmitter { 'package.json' )); - this.config.installedPlugins = Object.keys( - this.config.info.dependencies - ).filter(d => d.startsWith('strapi-plugin')); + this.config.installedPlugins = Object.keys(this.config.info.dependencies) + .filter(d => d.startsWith('strapi-plugin')) + .map(pkgName => pkgName.substring('strapi-plugin'.length + 1)); this.config.installedMiddlewares = Object.keys( this.config.info.dependencies - ).filter(d => d.startsWith('strapi-middleware')); + ) + .filter(d => d.startsWith('strapi-middleware')) + .map(pkgName => pkgName.substring('strapi-middleware'.length + 1)); - this.config.installedHooks = Object.keys( - this.config.info.dependencies - ).filter(d => d.startsWith('strapi-hook')); + this.config.installedHooks = Object.keys(this.config.info.dependencies) + .filter(d => d.startsWith('strapi-hook')) + .map(pkgName => pkgName.substring('strapi-hook'.length + 1)); // load configs _.merge(this, await loadConfigs(this.config)); @@ -258,7 +260,7 @@ class Strapi extends EventEmitter { // Usage. await utils.usage(this.config); // Init core store - await store.call(this); + initCoreStore(this); // Initialize hooks and middlewares. await Promise.all([ initializeMiddlewares.call(this), diff --git a/packages/strapi/lib/core/index.js b/packages/strapi/lib/core/index.js index 6226288972..3c82fe95df 100644 --- a/packages/strapi/lib/core/index.js +++ b/packages/strapi/lib/core/index.js @@ -7,7 +7,7 @@ const loadHooks = require('./load-hooks'); const bootstrap = require('./bootstrap'); const plugins = require('./plugins'); const admin = require('./admin'); -const store = require('./store'); +const initCoreStore = require('./init-core-store'); module.exports = { loadConfigs, @@ -17,5 +17,5 @@ module.exports = { bootstrap, plugins, admin, - store, + initCoreStore, }; diff --git a/packages/strapi/lib/core/init-core-store.js b/packages/strapi/lib/core/init-core-store.js new file mode 100644 index 0000000000..f5989ad2ae --- /dev/null +++ b/packages/strapi/lib/core/init-core-store.js @@ -0,0 +1,152 @@ +'use strict'; + +module.exports = strapi => { + strapi.models['core_store'] = coreStoreModel; + strapi.store = createStore(strapi); +}; + +const coreStoreModel = { + connection: 'default', + info: { + name: 'core_store', + description: '', + }, + attributes: { + key: { + type: 'string', + }, + value: { + type: 'text', + }, + type: { + type: 'string', + }, + environment: { + type: 'string', + }, + tag: { + type: 'string', + }, + }, + globalId: 'StrapiConfigs', + collectionName: 'core_store', +}; + +const createStore = strapi => { + return (source = {}) => { + const get = async (params = {}) => { + Object.assign(source, params); + + const { + key, + environment = strapi.config.environment, + type = 'core', + name = '', + tag = '', + } = source; + + const prefix = `${type}${name ? `_${name}` : ''}`; + + const where = { + key: `${prefix}_${key}`, + environment, + tag, + }; + + let data; + if (strapi.models['core_store'].orm === 'mongoose') { + data = await strapi.models['core_store'].findOne(where); + } else { + data = await strapi.models['core_store'] + .forge(where) + .fetch() + .then(config => config && config.toJSON()); + } + + if (!data) { + return null; + } + + if ( + data.type === 'object' || + data.type === 'array' || + data.type === 'boolean' + ) { + try { + return JSON.parse(data.value); + } catch (err) { + return new Date(data.value); + } + } else if (data.type === 'number') { + return parseFloat(data.value); + } else { + return null; + } + }; + + const set = async (params = {}) => { + Object.assign(source, params); + + const { + key, + value, + environment = strapi.config.environment, + type, + name, + tag = '', + } = source; + + const prefix = `${type}${name ? `_${name}` : ''}`; + + const where = { + key: `${prefix}_${key}`, + environment, + tag, + }; + + let data; + if (strapi.models['core_store'].orm === 'mongoose') { + data = await strapi.models['core_store'].findOne(where); + } else { + data = await strapi.models['core_store'] + .forge(where) + .fetch() + .then(config => config && config.toJSON()); + } + + if (data) { + Object.assign(data, { + value: JSON.stringify(value) || value.toString(), + type: (typeof value).toString(), + }); + + if (strapi.models['core_store'].orm === 'mongoose') { + await strapi.models['core_store'].updateOne({ _id: data._id }, data, { + strict: false, + }); + } else { + await strapi.models['core_store'] + .forge({ id: data.id }) + .save(data, { patch: true }); + } + } else { + Object.assign(where, { + value: JSON.stringify(value) || value.toString(), + type: (typeof value).toString(), + tag, + }); + + if (strapi.models['core_store'].orm === 'mongoose') { + await strapi.models['core_store'].create(where); + } else { + await strapi.models['core_store'].forge().save(where); + } + } + }; + + return { + get, + set, + }; + }; +}; diff --git a/packages/strapi/lib/core/load-apis.js b/packages/strapi/lib/core/load-apis.js index fb28c15711..fe883e9209 100644 --- a/packages/strapi/lib/core/load-apis.js +++ b/packages/strapi/lib/core/load-apis.js @@ -1,16 +1,13 @@ 'use strict'; -// Dependencies. -// const glob = require('glob'); const path = require('path'); -const slash = require('slash'); const _ = require('lodash'); -const glob = require('../load/glob'); const findPackagePath = require('../load/package-path'); +const loadFiles = require('../load/load-files'); module.exports = async function({ appPath, installedPlugins }) { const [api, admin, plugins, localPlugins] = await Promise.all([ - loadAppApis(appPath), + loadLocalApis(appPath), loadAdminApis(), loadPluginsApis(installedPlugins), loadLocalPluginsApis(appPath), @@ -23,91 +20,29 @@ module.exports = async function({ appPath, installedPlugins }) { }; }; -const loadFile = (obj, dir, file, prefix = null) => { - const rootPath = path - .join(path.dirname(file), path.basename(file, path.extname(file))) - .replace(/(\.settings|.json|.js)/g, '') - .toLowerCase(); +const loadLocalApis = appPath => + loadFiles(path.resolve(appPath, 'api'), '*/!(config)/*.*(js|json)'); - const propPath = slash(rootPath).split('/'); - - // merge is necessary for models to be able to merge Model.js with Model.settings.js which have the same path - _.merge( - obj, - _.set( - {}, - prefix ? [prefix].concat(propPath) : propPath, - require(path.join(dir, file)) - ) +const loadAdminApis = () => + loadFiles( + findPackagePath('strapi-admin'), + '!(config|node_modules|scripts)//*.*(js|json)' ); -}; -const loadAppApis = async appPath => { - let apis = {}; - const apiPath = path.resolve(appPath, 'api'); - - const files = await glob('*/!(config)/*.*(js|json)', { - cwd: apiPath, - }); - - for (let file of files) { - loadFile(apis, apiPath, file); - } - - return apis; -}; - -const loadAdminApis = async () => { - let admin = {}; - const adminPath = path.resolve(findPackagePath('strapi-admin')); - - const files = await glob('!(config|node_modules|scripts)//*.*(js|json)', { - cwd: adminPath, - }); - - for (let file of files) { - loadFile(admin, adminPath, file); - } - - return admin; -}; - -const loadLocalPluginsApis = async appPath => { - let localPlugins = {}; - - const pluginsPath = path.resolve(appPath, 'plugins'); - - const files = await glob('*/!(config)/*.*(js|json)', { - cwd: pluginsPath, - }); - - for (let file of files) { - loadFile(localPlugins, pluginsPath, file); - } - - return localPlugins; -}; +const loadLocalPluginsApis = appPath => + loadFiles(path.resolve(appPath, 'plugins'), '*/!(config)/*.*(js|json)'); const loadPluginsApis = async installedPlugins => { let plugins = {}; for (let plugin of installedPlugins) { - const pluginPath = path.resolve(findPackagePath(plugin)); + const pluginPath = findPackagePath(`strapi-plugin-${plugin}`); - const files = await glob( - '{!(config|node_modules|test)//*.*(js|json),package.json}', - { - cwd: pluginPath, - } + const result = await loadFiles( + pluginPath, + '{!(config|node_modules|test)//*.*(js|json),package.json}' ); - for (let file of files) { - loadFile( - plugins, - pluginPath, - file, - plugin.substr('strapi-plugin-'.length) - ); - } + _.set(plugins, plugin, result); } return plugins; diff --git a/packages/strapi/lib/core/load-configs.js b/packages/strapi/lib/core/load-configs.js index 61c0bd907a..2ddd506c31 100644 --- a/packages/strapi/lib/core/load-configs.js +++ b/packages/strapi/lib/core/load-configs.js @@ -4,10 +4,9 @@ const path = require('path'); const _ = require('lodash'); const fs = require('fs-extra'); -const loadConfig = require('../load/config'); const findPackagePath = require('../load/package-path'); - -const PLUGIN_PREFIX = 'strapi-plugin'; +const loadFiles = require('../load/load-files'); +const requireFileAndParse = require('../load/require-file-parse'); module.exports = async ({ appPath, installedPlugins }) => { const [config, admin, api, plugins, localPlugins] = await Promise.all([ @@ -26,28 +25,58 @@ module.exports = async ({ appPath, installedPlugins }) => { }; }; +const loadConfig = dir => { + return loadFiles(dir, 'config/**/*.+(js|json)', { + requireFn: requireFileAndParse, + shouldUseFileNameAsKey, + }); +}; + +const prefixedPaths = [ + ...['staging', 'production', 'development'].reduce((acc, env) => { + return acc.concat( + `environments/${env}/database`, + `environments/${env}/security`, + `environments/${env}/request`, + `environments/${env}/response`, + `environments/${env}/server` + ); + }, []), + 'functions', + 'policies', + 'locales', + 'hook', + 'middleware', + 'language', + 'queries', + 'layout', +]; + +const shouldUseFileNameAsKey = file => { + return _.some(prefixedPaths, e => file.startsWith(`config/${e}`)) + ? true + : false; +}; + // Loads an app config folder -const loadAppConfig = appPath => loadConfig(path.resolve(appPath, 'config')); +const loadAppConfig = async appPath => { + const { config } = await loadConfig(appPath); + return config; +}; // Loads the strapi-admin config folder -const loadAdminConfig = async () => ({ - config: await loadConfig( - path.resolve(findPackagePath('strapi-admin'), 'config') - ), -}); +const loadAdminConfig = () => loadConfig(findPackagePath('strapi-admin')); // Loads every apis config folder const loadApisConfig = async appPath => { let apis = {}; - const apisFolder = path.resolve(appPath, 'api'); - const apiFolders = await fs.readdir(apisFolder); + const apisDir = path.resolve(appPath, 'api'); + const apiNames = await fs.readdir(apisDir); - for (let apiFolder of apiFolders) { - const apiConfig = await loadConfig( - path.resolve(apisFolder, apiFolder, 'config') - ); + for (let apiDir of apiNames) { + const apiConfig = await loadConfig(path.resolve(apisDir, apiDir)); - _.set(apis, [apiFolder, 'config'], apiConfig); + _.set(apis, apiDir, apiConfig); } return apis; @@ -55,15 +84,13 @@ const loadApisConfig = async appPath => { const loadLocalPluginsConfig = async appPath => { let localPlugins = {}; - const pluginsFolder = path.resolve(appPath, 'plugins'); - const pluginsFolders = await fs.readdir(pluginsFolder); + const pluginsDir = path.resolve(appPath, 'plugins'); + const pluginsName = await fs.readdir(pluginsDir); - for (let pluginsFolder of pluginsFolders) { - const pluginsConfig = await loadConfig( - path.resolve(pluginsFolder, pluginsFolder, 'config') - ); + for (let pluginDir of pluginsName) { + const pluginsConfig = await loadConfig(path.resolve(pluginsDir, pluginDir)); - _.set(localPlugins, [pluginsFolder, 'config'], pluginsConfig); + _.set(localPlugins, pluginDir, pluginsConfig); } return localPlugins; @@ -74,14 +101,10 @@ const loadPluginsConfig = async pluginsNames => { let plugins = {}; for (let plugin of pluginsNames) { const pluginConfig = await loadConfig( - path.resolve(findPackagePath(plugin), 'config') + findPackagePath(`strapi-plugin-${plugin}`) ); - _.set( - plugins, - [plugin.substring(PLUGIN_PREFIX.length + 1), 'config'], - pluginConfig - ); + _.set(plugins, plugin, pluginConfig); } return plugins; diff --git a/packages/strapi/lib/core/load-hooks.js b/packages/strapi/lib/core/load-hooks.js index f4fde26b27..addb257f44 100644 --- a/packages/strapi/lib/core/load-hooks.js +++ b/packages/strapi/lib/core/load-hooks.js @@ -3,9 +3,6 @@ // Dependencies. const fs = require('fs-extra'); const path = require('path'); -const slash = require('slash'); -// const glob = require('glob'); -// const { parallel } = require('async'); const _ = require('lodash'); const glob = require('../load/glob'); const findPackagePath = require('../load/package-path'); @@ -16,7 +13,7 @@ module.exports = async function({ installedHooks, installedPlugins, appPath }) { await Promise.all([ loadHookDependencies(installedHooks, hooks), // local middleware - loadHooksInDir(path.resolve(appPath, 'hooks'), hooks), + loadLocalHooks(appPath, hooks), // plugins middlewares loadPluginsHooks(installedPlugins, hooks), // local plugin middlewares @@ -32,14 +29,20 @@ const loadHooksInDir = async (dir, hooks) => { }); files.forEach(f => { - const name = slash(f).split('/')[0]; + const name = f.split('/')[0]; mountHooks(name, [path.resolve(dir, f)], hooks); }); }; +const loadLocalHooks = (appPath, hooks) => + loadHooksInDir(path.resolve(appPath, 'hooks'), hooks); + const loadPluginsHooks = async (plugins, hooks) => { for (let pluginName of plugins) { - const dir = path.resolve(findPackagePath(pluginName), 'hooks'); + const dir = path.resolve( + findPackagePath(`strapi-plugin-${pluginName}`), + 'hooks' + ); await loadHooksInDir(dir, hooks); } }; @@ -56,14 +59,14 @@ const loadLocalPluginsHooks = async (appPath, hooks) => { const loadHookDependencies = async (installedHooks, hooks) => { for (let hook of installedHooks) { - const hookDir = path.dirname(require.resolve(hook)); + const hookDir = path.dirname(require.resolve(`strapi-hook-${hook}`)); const files = await glob('*(index|defaults).*(js|json)', { cwd: hookDir, absolute: true, }); - mountHooks(hook.substring('strapi-hook-'.length), files, hooks); + mountHooks(hook, files, hooks); } }; @@ -98,61 +101,3 @@ const mountHooks = (name, files, hooks) => { } }); }; - -// const mountHooks = function(files, cwd, source) { -// return (resolve, reject) => -// parallel( -// files.map(p => cb => { -// const folders = p -// .replace(/^.\/node_modules\/strapi-hook-/, './') -// .split('/'); -// const name = -// source === 'plugins' ? folders[folders.length - 2] : folders[1]; - -// this.hook[name] = this.hook[name] || { -// loaded: false, -// }; - -// let dependencies = []; -// if (source === 'node_modules') { -// try { -// dependencies = get( -// require(path.resolve( -// this.config.appPath, -// 'node_modules', -// `strapi-hook-${name}`, -// 'package.json' -// )), -// 'strapi.dependencies', -// [] -// ); -// } catch (err) { -// // Silent -// } -// } - -// if (endsWith(p, 'index.js') && !this.hook[name].load) { -// // Lazy loading. -// Object.defineProperty(this.hook[name], 'load', { -// configurable: false, -// enumerable: true, -// get: () => require(path.resolve(cwd, p)), -// dependencies, -// }); - -// this.hook[name].dependencies = dependencies; -// } else if (endsWith(p, 'defaults.json')) { -// this.hook[name].defaults = require(path.resolve(cwd, p)); -// } - -// cb(); -// }), -// err => { -// if (err) { -// return reject(err); -// } - -// resolve(); -// } -// ); -// }; diff --git a/packages/strapi/lib/core/load-middlewares.js b/packages/strapi/lib/core/load-middlewares.js index afeb218645..fe136785eb 100644 --- a/packages/strapi/lib/core/load-middlewares.js +++ b/packages/strapi/lib/core/load-middlewares.js @@ -3,13 +3,10 @@ // Dependencies. const fs = require('fs-extra'); const path = require('path'); -const slash = require('slash'); const _ = require('lodash'); const glob = require('../load/glob'); const findPackagePath = require('../load/package-path'); -const MIDDLEWARE_PREFIX = 'strapi-middleware'; - const requiredMiddlewares = { kcors: 'kcors', body: 'koa-body', @@ -41,14 +38,12 @@ module.exports = async function(config) { }); await Promise.all([ + // load installed middlewares loadMiddlewareDependencies(installedMiddlewares, middlewares), // internal middlewares - loadMiddlewaresInDir( - path.resolve(__dirname, '..', 'middlewares'), - middlewares - ), + loadInternalMiddlexares(middlewares), // local middleware - loadMiddlewaresInDir(path.resolve(appPath, 'middlewares'), middlewares), + loadLocalMiddlewares(appPath, middlewares), // plugins middlewares loadPluginsMiddlewares(installedPlugins, middlewares), // local plugin middlewares @@ -67,38 +62,51 @@ const loadMiddlewaresInDir = async (dir, middlewares) => { }); files.forEach(f => { - const name = slash(f).split('/')[0]; + const name = f.split('/')[0]; mountMiddleware(name, [path.resolve(dir, f)], middlewares); }); }; +const loadInternalMiddlexares = middlewares => + loadMiddlewaresInDir( + path.resolve(__dirname, '..', 'middlewares'), + middlewares + ); + +const loadLocalMiddlewares = (appPath, middlewares) => + loadMiddlewaresInDir(path.resolve(appPath, 'middlewares'), middlewares); + const loadPluginsMiddlewares = async (plugins, middlewares) => { for (let pluginName of plugins) { - const dir = path.resolve(findPackagePath(pluginName), 'middlewares'); + const dir = path.resolve( + findPackagePath(`strapi-plugin-${pluginName}`), + 'middlewares' + ); await loadMiddlewaresInDir(dir, middlewares); } }; const loadLocalPluginsMiddlewares = async (appPath, middlewares) => { - const pluginsFolder = path.resolve(appPath, 'plugins'); - const pluginsFolders = await fs.readdir(pluginsFolder); + const pluginsDir = path.resolve(appPath, 'plugins'); + const pluginsNames = await fs.readdir(pluginsDir); - for (let pluginFolder of pluginsFolders) { - const dir = path.resolve(pluginsFolder, pluginFolder, 'middlewares'); + for (let pluginFolder of pluginsNames) { + const dir = path.resolve(pluginsDir, pluginFolder, 'middlewares'); await loadMiddlewaresInDir(dir, middlewares); } }; const loadMiddlewareDependencies = async (packages, middlewares) => { for (let packageName of packages) { - const baseDir = path.dirname(require.resolve(packageName)); + const baseDir = path.dirname( + require.resolve(`strapi-middleware-${packageName}`) + ); const files = await glob('*(index|defaults).*(js|json)', { cwd: baseDir, absolute: true, }); - const name = packageName.substring(MIDDLEWARE_PREFIX.length + 1); - mountMiddleware(name, files, middlewares); + mountMiddleware(packageName, files, middlewares); } }; diff --git a/packages/strapi/lib/core/store.js b/packages/strapi/lib/core/store.js deleted file mode 100644 index 6d95c00860..0000000000 --- a/packages/strapi/lib/core/store.js +++ /dev/null @@ -1,137 +0,0 @@ -'use strict'; - -module.exports = function () { - return new Promise((resolve) => { - this.models['core_store'] = { - connection: 'default', - info: { - name: 'core_store', - description: '' - }, - attributes: { - key: { - type: 'string' - }, - value: { - type: 'text' - }, - type: { - type: 'string' - }, - environment: { - type: 'string' - }, - tag: { - type: 'string' - } - }, - globalId: 'StrapiConfigs', - collectionName: 'core_store' - }; - - this.store = (source = {}) => { - const get = async (params = {}) => { - Object.assign(source, params); - - const { - key, - environment = strapi.config.environment, - type = 'core', - name = '', - tag = '' - } = source; - - const prefix = `${type}${name ? `_${name}` : ''}`; - - - const where = { - key: `${prefix}_${key}`, - environment, - tag - }; - - const data = strapi.models['core_store'].orm === 'mongoose' - ? await strapi.models['core_store'].findOne(where) - : await strapi.models['core_store'].forge(where).fetch().then(config => { - if (config) { - return config.toJSON(); - } - }); - - if (!data) { - return null; - } - - if (data.type === 'object' || data.type === 'array' || data.type === 'boolean') { - try { - return JSON.parse(data.value); - } catch (err) { - return new Date(data.value); - } - } else if (data.type === 'number') { - return parseFloat(data.value); - } else { - return null; - } - }; - - const set = async (params = {}) => { - Object.assign(source, params); - - const { - key, - value, - environment = strapi.config.environment, - type, - name, - tag = '' - } = source; - - const prefix = `${type}${name ? `_${name}` : ''}`; - - const where = { - key: `${prefix}_${key}`, - environment, - tag - }; - - let data = strapi.models['core_store'].orm === 'mongoose' - ? await strapi.models['core_store'].findOne(where) - : await strapi.models['core_store'].forge(where).fetch().then(config => { - if (config) { - return config.toJSON(); - } - }); - - if (data) { - Object.assign(data, { - value: JSON.stringify(value) || value.toString(), - type: (typeof value).toString() - }); - - strapi.models['core_store'].orm === 'mongoose' - ? await strapi.models['core_store'].updateOne({ _id: data._id }, data, { strict: false }) - : await strapi.models['core_store'].forge({ id: data.id }).save(data, { patch: true }); - } else { - Object.assign(where, { - value: JSON.stringify(value) || value.toString(), - type: (typeof value).toString(), - tag - - }); - - strapi.models['core_store'].orm === 'mongoose' - ? await strapi.models['core_store'].create(where) - : await strapi.models['core_store'].forge().save(where); - } - }; - - return { - get, - set - }; - }; - - resolve(); - }); -}; diff --git a/packages/strapi/lib/load/config.js b/packages/strapi/lib/load/config.js deleted file mode 100644 index daa1b496df..0000000000 --- a/packages/strapi/lib/load/config.js +++ /dev/null @@ -1,70 +0,0 @@ -const path = require('path'); -const slash = require('slash'); -const _ = require('lodash'); - -const requireFile = require('./require-file'); -const glob = require('./glob'); - -const setValue = (obj, rootPath, source) => { - if (rootPath === null) { - return _.assign(obj, source); - } - - const propPath = slash(rootPath.toLowerCase()).split('/'); - if (propPath.length === 0) { - return _.assign(obj, source); - } - - _.setWith(obj, propPath, source, Object); -}; - -const prefixedPath = [ - ...['staging', 'production', 'development'].reduce((acc, env) => { - return acc.concat( - `environments/${env}/database`, - `environments/${env}/security`, - `environments/${env}/request`, - `environments/${env}/response`, - `environments/${env}/server` - ); - }, []), - 'functions', - 'policies', - 'locales', - 'hook', - 'middleware', - 'language', - 'queries', - 'layout', -]; - -/** - * Loads app config from a dir - * @param {Object} options - Options - * @param {string} options.dir - config dir to load - */ -module.exports = async dir => { - let root = {}; - - const files = await glob('**/*.+(js|json)', { - cwd: dir, - }); - - files.forEach(file => { - const m = requireFile(path.resolve(dir, file)); - - if (_.some(prefixedPath, e => slash(file).startsWith(e))) { - const rootPath = path.join( - path.dirname(file), - path.basename(file, path.extname(file)) - ); - - setValue(root, rootPath, m); - } else { - const rootPath = path.dirname(file); - setValue(root, rootPath === '.' ? null : rootPath, m); - } - }); - - return root; -}; diff --git a/packages/strapi/lib/load/index.js b/packages/strapi/lib/load/index.js new file mode 100644 index 0000000000..c15fa47953 --- /dev/null +++ b/packages/strapi/lib/load/index.js @@ -0,0 +1,7 @@ +const loadFiles = require('./load-files'); +const findPackagePath = require('./package-path'); + +module.exports = { + loadFiles, + findPackagePath, +}; diff --git a/packages/strapi/lib/load/load-files.js b/packages/strapi/lib/load/load-files.js new file mode 100644 index 0000000000..8efc22fa84 --- /dev/null +++ b/packages/strapi/lib/load/load-files.js @@ -0,0 +1,36 @@ +const path = require('path'); +const glob = require('./glob'); +const _ = require('lodash'); + +const filePathToPath = (fileP, useFileNameAsKey = true) => { + const prop = path + .normalize(fileP) + .replace(/(.settings|.json|.js)/g, '') + .toLowerCase() + .split('/') + .join('.') + .split('.'); + + return useFileNameAsKey === true ? prop : prop.slice(0, -1); +}; + +module.exports = async ( + dir, + pattern, + { requireFn = require, shouldUseFileNameAsKey = () => true } = {} +) => { + const root = {}; + const files = await glob(pattern, { cwd: dir }); + + for (let file of files) { + // TODO: need to figure out the need for clearing the cache + delete require.cache[path.resolve(dir, file)]; + const mod = requireFn(path.resolve(dir, file)); + const propPath = filePathToPath(file, shouldUseFileNameAsKey(file)); + + if (propPath.length === 0) _.merge(root, mod); + _.merge(root, _.setWith({}, propPath, mod, Object)); + } + + return root; +}; diff --git a/packages/strapi/lib/load/require-file.js b/packages/strapi/lib/load/require-file-parse.js similarity index 100% rename from packages/strapi/lib/load/require-file.js rename to packages/strapi/lib/load/require-file-parse.js diff --git a/packages/strapi/lib/utils/index.js b/packages/strapi/lib/utils/index.js index 646352f5c0..0fde795f43 100644 --- a/packages/strapi/lib/utils/index.js +++ b/packages/strapi/lib/utils/index.js @@ -23,30 +23,134 @@ module.exports = { } }, - async usage({ uuid }) { + loadFile: function(url) { + // Clear cache. + delete require.cache[require.resolve(path.resolve(this.config.appPath, url))]; + // Require without cache. + return require(path.resolve(this.config.appPath, url)); + }, + + setConfig: function(ctx, path, type, loader) { + const objPath = type === 'optional' + ? this.optionalPath(path) + : this.aggregatePath(path); + + // Load value. + const value = loader(path); + // Merge doesn't work for none-object value and function. + const obj = isObject(value) && !isFunction(value) ? merge(get(ctx, objPath), value) : value; + + // Assignation. + return setWith(ctx, objPath, obj, Object); + }, + + setConfigAdmin: function(ctx, path, type, loader) { + const objPath = 'admin.' + (type === 'optional' + ? this.optionalPath(path) + : this.aggregatePath(path)); + + // Direct assignation. + if (objPath.split('.').length === 1) { + return setWith( + ctx, + objPath, + merge(get(ctx, objPath), loader(path)), + Object + ); + } + + // Nested assignation. + return setWith(ctx, objPath, loader(path), Object); + }, + + optionalPath: path => { + return path + .replace(/(\.settings|.json|.js)/g, '') + .split('/') + .slice(1, path.split('/').length - 1) + .join('.') + .toLowerCase(); + }, + + aggregatePath: path => { + return path + .replace(/(\.settings|.json|.js)/g, '') + .split('/') + .slice(1) + .join('.') + .toLowerCase(); + }, + + loadConfig: function(files, shouldBeAggregated = false) { + const aggregate = files.filter(p => { + if (shouldBeAggregated) { + return true; + } + + if (intersection(p.split('/').map(p => p.replace('.json', '')), ['environments', 'database', 'security', 'request', 'response', 'server']).length === 2) { + return true; + } + + if ( + p.indexOf('config/functions') !== -1 || + p.indexOf('config/policies') !== -1 || + p.indexOf('config/locales') !== -1 || + p.indexOf('config/hook') !== -1 || + p.indexOf('config/middleware') !== -1 || + p.indexOf('config/language') !== -1 || + p.indexOf('config/queries') !== -1 || + p.indexOf('config/layout') !== -1 + ) { + return true; + } + + return false; + }); + + const optional = difference(files, aggregate); + + return Promise.all([ + new Promise((resolve, reject) => { + map(aggregate, p => + module.exports.setConfig(this, p, 'aggregate', this.loadFile) + ); + + resolve(); + }), + new Promise((resolve, reject) => { + map(optional, p => + module.exports.setConfig(this, p, 'optional', this.loadFile) + ); + + resolve(); + }) + ]); + }, + + usage: async function () { try { - if (!uuid) return; + if (this.config.uuid) { + const publicKey = fs.readFileSync(path.resolve(__dirname, 'resources', 'key.pub')); + const options = { timeout: 1500 }; - const publicKey = fs.readFileSync(path.resolve(__dirname, 'resources', 'key.pub')); - const options = { timeout: 1500 }; + const [usage, signedHash, required] = await Promise.all([ + fetch('https://strapi.io/assets/images/usage.gif', options), + fetch('https://strapi.io/hash.txt', options), + fetch('https://strapi.io/required.txt', options) + ]).catch(err => {}); - const [usage, signedHash, required] = await Promise.all([ - fetch('https://strapi.io/assets/images/usage.gif', options), - fetch('https://strapi.io/hash.txt', options), - fetch('https://strapi.io/required.txt', options) - ]).catch(err => {}); + if (usage.status === 200 && signedHash.status === 200) { + const code = Buffer.from(await usage.text(), 'base64').toString(); + const hash = crypto.createHash('sha512').update(code).digest('hex'); + const dependencies = Buffer.from(await required.text(), 'base64').toString(); - if (usage.status === 200 && signedHash.status === 200) { - const code = Buffer.from(await usage.text(), 'base64').toString(); - const hash = crypto.createHash('sha512').update(code).digest('hex'); - const dependencies = Buffer.from(await required.text(), 'base64').toString(); + const verifier = crypto.createVerify('RSA-SHA256').update(hash); - const verifier = crypto.createVerify('RSA-SHA256').update(hash); - - if (verifier.verify(publicKey, await signedHash.text(), 'hex')) { - return new Promise(resolve => { - vm.runInNewContext(code)(uuid, exposer(dependencies), resolve); - }); + if (verifier.verify(publicKey, await signedHash.text(), 'hex')) { + return new Promise(resolve => { + vm.runInNewContext(code)(this.config.uuid, exposer(dependencies), resolve); + }); + } } } } catch (e) { diff --git a/packages/strapi/package.json b/packages/strapi/package.json index e157b349bf..c7c856f9bc 100644 --- a/packages/strapi/package.json +++ b/packages/strapi/package.json @@ -62,7 +62,6 @@ "rimraf": "^2.6.2", "semver": "^5.4.1", "shelljs": "^0.8.3", - "slash": "^2.0.0", "stack-trace": "0.0.10", "strapi-generate": "3.0.0-alpha.25.2", "strapi-generate-admin": "3.0.0-alpha.25.2", diff --git a/yarn.lock b/yarn.lock index 3ec483623d..9e3dc9e68a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1533,6 +1533,162 @@ resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-12.0.12.tgz#45dd1d0638e8c8f153e87d296907659296873916" integrity sha512-SOhuU4wNBxhhTHxYaiG5NY4HBhDIDnJF60GU+2LqHAdKKer86//e4yg69aENCtQ04n0ovz+tq2YPME5t5yp4pw== +"@webassemblyjs/ast@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359" + integrity sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ== + dependencies: + "@webassemblyjs/helper-module-context" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/wast-parser" "1.8.5" + +"@webassemblyjs/floating-point-hex-parser@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz#1ba926a2923613edce496fd5b02e8ce8a5f49721" + integrity sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ== + +"@webassemblyjs/helper-api-error@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz#c49dad22f645227c5edb610bdb9697f1aab721f7" + integrity sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA== + +"@webassemblyjs/helper-buffer@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz#fea93e429863dd5e4338555f42292385a653f204" + integrity sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q== + +"@webassemblyjs/helper-code-frame@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz#9a740ff48e3faa3022b1dff54423df9aa293c25e" + integrity sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ== + dependencies: + "@webassemblyjs/wast-printer" "1.8.5" + +"@webassemblyjs/helper-fsm@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz#ba0b7d3b3f7e4733da6059c9332275d860702452" + integrity sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow== + +"@webassemblyjs/helper-module-context@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz#def4b9927b0101dc8cbbd8d1edb5b7b9c82eb245" + integrity sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g== + dependencies: + "@webassemblyjs/ast" "1.8.5" + mamacro "^0.0.3" + +"@webassemblyjs/helper-wasm-bytecode@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz#537a750eddf5c1e932f3744206551c91c1b93e61" + integrity sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ== + +"@webassemblyjs/helper-wasm-section@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz#74ca6a6bcbe19e50a3b6b462847e69503e6bfcbf" + integrity sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-buffer" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/wasm-gen" "1.8.5" + +"@webassemblyjs/ieee754@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz#712329dbef240f36bf57bd2f7b8fb9bf4154421e" + integrity sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.8.5.tgz#044edeb34ea679f3e04cd4fd9824d5e35767ae10" + integrity sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.8.5.tgz#a8bf3b5d8ffe986c7c1e373ccbdc2a0915f0cedc" + integrity sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw== + +"@webassemblyjs/wasm-edit@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz#962da12aa5acc1c131c81c4232991c82ce56e01a" + integrity sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-buffer" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/helper-wasm-section" "1.8.5" + "@webassemblyjs/wasm-gen" "1.8.5" + "@webassemblyjs/wasm-opt" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + "@webassemblyjs/wast-printer" "1.8.5" + +"@webassemblyjs/wasm-gen@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz#54840766c2c1002eb64ed1abe720aded714f98bc" + integrity sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/ieee754" "1.8.5" + "@webassemblyjs/leb128" "1.8.5" + "@webassemblyjs/utf8" "1.8.5" + +"@webassemblyjs/wasm-opt@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz#b24d9f6ba50394af1349f510afa8ffcb8a63d264" + integrity sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-buffer" "1.8.5" + "@webassemblyjs/wasm-gen" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + +"@webassemblyjs/wasm-parser@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz#21576f0ec88b91427357b8536383668ef7c66b8d" + integrity sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-api-error" "1.8.5" + "@webassemblyjs/helper-wasm-bytecode" "1.8.5" + "@webassemblyjs/ieee754" "1.8.5" + "@webassemblyjs/leb128" "1.8.5" + "@webassemblyjs/utf8" "1.8.5" + +"@webassemblyjs/wast-parser@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz#e10eecd542d0e7bd394f6827c49f3df6d4eefb8c" + integrity sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/floating-point-hex-parser" "1.8.5" + "@webassemblyjs/helper-api-error" "1.8.5" + "@webassemblyjs/helper-code-frame" "1.8.5" + "@webassemblyjs/helper-fsm" "1.8.5" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/wast-printer@1.8.5": + version "1.8.5" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz#114bbc481fd10ca0e23b3560fa812748b0bae5bc" + integrity sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/wast-parser" "1.8.5" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + "@yarnpkg/lockfile@^1.0.2": version "1.1.0" resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" @@ -1576,6 +1732,11 @@ acorn-dynamic-import@^2.0.0: dependencies: acorn "^4.0.3" +acorn-dynamic-import@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz#482210140582a36b83c3e342e1cfebcaa9240948" + integrity sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw== + acorn-globals@^4.1.0: version "4.3.0" resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.0.tgz#e3b6f8da3c1552a95ae627571f7dd6923bb54103" @@ -1611,7 +1772,7 @@ acorn@^5.0.0, acorn@^5.3.0, acorn@^5.5.0, acorn@^5.5.3: resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw== -acorn@^6.0.1: +acorn@^6.0.1, acorn@^6.0.5: version "6.1.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f" integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA== @@ -2012,6 +2173,14 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +aria-query@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-3.0.0.tgz#65b3fcc1ca1155a8c9ae64d6eee297f15d5133cc" + integrity sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w= + dependencies: + ast-types-flow "0.0.7" + commander "^2.11.0" + arr-diff@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" @@ -2064,6 +2233,11 @@ array-find-index@^1.0.1: resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= +array-find@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-find/-/array-find-1.0.0.tgz#6c8e286d11ed768327f8e62ecee87353ca3e78b8" + integrity sha1-bI4obRHtdoMn+OYuzuhzU8o+eLg= + array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" @@ -2207,6 +2381,11 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= +ast-types-flow@0.0.7, ast-types-flow@^0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" + integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0= + ast-types@0.9.6: version "0.9.6" resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.6.tgz#102c9e9e9005d3e7e3829bf0c4fa24ee862ee9b9" @@ -2348,6 +2527,13 @@ axios@^0.18.0: follow-redirects "^1.3.0" is-buffer "^1.1.5" +axobject-query@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.0.2.tgz#ea187abe5b9002b377f925d8bf7d1c561adf38f9" + integrity sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww== + dependencies: + ast-types-flow "0.0.7" + babel-cli@6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.26.0.tgz#502ab54874d7db88ad00b887a06383ce03d002f1" @@ -3866,7 +4052,7 @@ cacache@^10.0.4: unique-filename "^1.1.0" y18n "^4.0.0" -cacache@^11.0.1, cacache@^11.3.2: +cacache@^11.0.1, cacache@^11.0.2, cacache@^11.3.2: version "11.3.2" resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.2.tgz#2d81e308e3d258ca38125b676b98b2ac9ce69bfa" integrity sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg== @@ -4237,6 +4423,13 @@ chownr@^1.0.1, chownr@^1.1.1: resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== +chrome-trace-event@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz#45a91bd2c20c9411f0963b5aaeb9a1b95e09cc48" + integrity sha512-xDbVgyfDTT2piup/h8dK/y4QZfJRSa73bw1WZ8b4XM1o7fsFubUVGYcE+1ANtOzJJELGpYoG2961z0Z6OAld9A== + dependencies: + tslib "^1.9.0" + ci-info@^1.0.0, ci-info@^1.5.0: version "1.6.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" @@ -5373,6 +5566,11 @@ d@1: dependencies: es5-ext "^0.10.9" +damerau-levenshtein@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz#03191c432cb6eea168bb77f3a55ffdccb8978514" + integrity sha1-AxkcQyy27qFou3fzpV/9zLiXhRQ= + dargs@^4.0.1: version "4.1.0" resolved "https://registry.yarnpkg.com/dargs/-/dargs-4.1.0.tgz#03a9dbb4b5c2f139bf14ae53f0b8a2a6a86f4e17" @@ -6060,6 +6258,11 @@ email-validator@^2.0.4: resolved "https://registry.yarnpkg.com/email-validator/-/email-validator-2.0.4.tgz#b8dfaa5d0dae28f1b03c95881d904d4e40bfe7ed" integrity sha512-gYCwo7kh5S3IDyZPLZf6hSS0MnZT8QmJFqYvbqlDZSbwdZlY6QZWxJ4i/6UhITOJ4XzyI647Bm2MXKCLqnJ4nQ== +emoji-regex@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + emojis-list@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" @@ -6094,6 +6297,24 @@ enhanced-resolve@^3.4.0: object-assign "^4.0.1" tapable "^0.2.7" +enhanced-resolve@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" + integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.4.0" + tapable "^1.0.0" + +enhanced-resolve@~0.9.0: + version "0.9.1" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz#4d6e689b3725f86090927ccc86cd9f1635b89e2e" + integrity sha1-TW5omzcl+GCQknzMhs2fFjW4ni4= + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.2.0" + tapable "^0.1.8" + enpeem@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/enpeem/-/enpeem-2.2.0.tgz#b95e65d376a8b46f5425d0c9c01fd08820f3350f" @@ -6170,7 +6391,7 @@ err-code@^1.0.0: resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960" integrity sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA= -errno@^0.1.3: +errno@^0.1.3, errno@~0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" integrity sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg== @@ -6355,6 +6576,13 @@ eslint-config-airbnb-base@^10.0.0: resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-10.0.1.tgz#f17d4e52992c1d45d1b7713efbcd5ecd0e7e0506" integrity sha1-8X1OUpksHUXRt3E++81ezQ5+BQY= +eslint-config-airbnb-base@^12.1.0: + version "12.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.1.0.tgz#386441e54a12ccd957b0a92564a4bafebd747944" + integrity sha512-/vjm0Px5ZCpmJqnjIzcFb9TKZrKWz0gnuG/7Gfkt0Db1ELJR51xkZth+t14rYdqWgX836XbuxtArbIHlVhbLBA== + dependencies: + eslint-restricted-globals "^0.1.1" + eslint-config-airbnb@^13.0.0: version "13.0.0" resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-13.0.0.tgz#688d15d3c276c0c753ae538c92a44397d76ae46e" @@ -6362,6 +6590,20 @@ eslint-config-airbnb@^13.0.0: dependencies: eslint-config-airbnb-base "^10.0.0" +eslint-config-airbnb@^16.1.0: + version "16.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-16.1.0.tgz#2546bfb02cc9fe92284bf1723ccf2e87bc45ca46" + integrity sha512-zLyOhVWhzB/jwbz7IPSbkUuj7X2ox4PHXTcZkEmDqTvd0baJmJyuxlFPDlZOE/Y5bC+HQRaEkT3FoHo9wIdRiw== + dependencies: + eslint-config-airbnb-base "^12.1.0" + +eslint-config-prettier@^2.9.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-2.10.0.tgz#ec07bc1d01f87d09f61d3840d112dc8a9791e30b" + integrity sha512-Mhl90VLucfBuhmcWBgbUNtgBiK955iCDK1+aHAz7QfDQF6wuzWZ6JjihZ3ejJoGlJWIuko7xLqNm8BA5uenKhA== + dependencies: + get-stdin "^5.0.1" + eslint-import-resolver-node@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" @@ -6370,6 +6612,23 @@ eslint-import-resolver-node@^0.3.2: debug "^2.6.9" resolve "^1.5.0" +eslint-import-resolver-webpack@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-webpack/-/eslint-import-resolver-webpack-0.9.0.tgz#231ce1578ad5124da5799f029bd33d28137623e3" + integrity sha1-IxzhV4rVEk2leZ8Cm9M9KBN2I+M= + dependencies: + array-find "^1.0.0" + debug "^2.6.8" + enhanced-resolve "~0.9.0" + find-root "^1.1.0" + has "^1.0.1" + interpret "^1.0.0" + is-absolute "^0.2.3" + lodash.get "^4.4.2" + node-libs-browser "^1.0.0 || ^2.0.0" + resolve "^1.4.0" + semver "^5.3.0" + eslint-module-utils@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.3.0.tgz#546178dab5e046c8b562bbb50705e2456d7bda49" @@ -6399,6 +6658,20 @@ eslint-plugin-import@^2.11.0: read-pkg-up "^2.0.0" resolve "^1.9.0" +eslint-plugin-jsx-a11y@^6.0.3: + version "6.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.1.tgz#4ebba9f339b600ff415ae4166e3e2e008831cf0c" + integrity sha512-cjN2ObWrRz0TTw7vEcGQrx+YltMvZoOEx4hWU8eEERDnBIU00OTq7Vr+jA7DFKxiwLNv4tTh5Pq2GUNEa8b6+w== + dependencies: + aria-query "^3.0.0" + array-includes "^3.0.3" + ast-types-flow "^0.0.7" + axobject-query "^2.0.2" + damerau-levenshtein "^1.0.4" + emoji-regex "^7.0.2" + has "^1.0.3" + jsx-ast-utils "^2.0.1" + eslint-plugin-react@^7.7.0: version "7.12.4" resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.12.4.tgz#b1ecf26479d61aee650da612e425c53a99f48c8c" @@ -6417,6 +6690,11 @@ eslint-plugin-redux-saga@^0.8.0: resolved "https://registry.yarnpkg.com/eslint-plugin-redux-saga/-/eslint-plugin-redux-saga-0.8.0.tgz#0c9d6b44183ded4b7bb470cdfad30244afbb1485" integrity sha512-SXIk5Z5ggPa1618h67EKPFDP6L2/FiF9wQFZ0b9vfRlLECOVupWqoj4N9LUegBjhPgqjnHJKi9ZyXE9/vFWOjA== +eslint-restricted-globals@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz#35f0d5cbc64c2e3ed62e93b4b1a7af05ba7ed4d7" + integrity sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc= + eslint-scope@3.7.1: version "3.7.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" @@ -6433,6 +6711,14 @@ eslint-scope@^3.7.1: esrecurse "^4.1.0" estraverse "^4.1.1" +eslint-scope@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + eslint-visitor-keys@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" @@ -7107,6 +7393,20 @@ find-cache-dir@^1.0.0: make-dir "^1.0.0" pkg-dir "^2.0.0" +find-cache-dir@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== + dependencies: + commondir "^1.0.1" + make-dir "^2.0.0" + pkg-dir "^3.0.0" + +find-root@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" + integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== + find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" @@ -7502,6 +7802,11 @@ get-stdin@^4.0.1: resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= +get-stdin@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-5.0.1.tgz#122e161591e21ff4c52530305693f20e6393a398" + integrity sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g= + get-stream@3.0.0, get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" @@ -8856,6 +9161,14 @@ is-absolute-url@^2.0.0: resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" integrity sha1-UFMN+4T8yap9vnhS6Do3uTufKqY= +is-absolute@^0.2.3: + version "0.2.6" + resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-0.2.6.tgz#20de69f3db942ef2d87b9c2da36f172235b1b5eb" + integrity sha1-IN5p89uULvLYe5wto28XIjWxtes= + dependencies: + is-relative "^0.2.1" + is-windows "^0.2.0" + is-absolute@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-absolute/-/is-absolute-1.0.0.tgz#395e1ae84b11f26ad1795e73c17378e48a301576" @@ -9243,6 +9556,13 @@ is-regex@^1.0.4: dependencies: has "^1.0.1" +is-relative@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-0.2.1.tgz#d27f4c7d516d175fb610db84bbeef23c3bc97aa5" + integrity sha1-0n9MfVFtF1+2ENuEu+7yPDvJeqU= + dependencies: + is-unc-path "^0.1.1" + is-relative@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" @@ -9324,6 +9644,13 @@ is-typedarray@~1.0.0: resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= +is-unc-path@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-0.1.2.tgz#6ab053a72573c10250ff416a3814c35178af39b9" + integrity sha1-arBTpyVzwQJQ/0FqOBTDUXivObk= + dependencies: + unc-path-regex "^0.1.0" + is-unc-path@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d" @@ -9348,6 +9675,11 @@ is-whitespace@^0.3.0: resolved "https://registry.yarnpkg.com/is-whitespace/-/is-whitespace-0.3.0.tgz#1639ecb1be036aec69a54cbb401cfbed7114ab7f" integrity sha1-Fjnssb4DauxppUy7QBz77XEUq38= +is-windows@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-0.2.0.tgz#de1aa6d63ea29dd248737b69f1ff8b8002d2108c" + integrity sha1-3hqm1j6indJIc3tp8f+LgALSEIw= + is-windows@^1.0.0, is-windows@^1.0.1, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" @@ -10044,7 +10376,7 @@ json-loader@^0.5.4, json-loader@^0.5.7: resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.7.tgz#dca14a70235ff82f0ac9a3abeb60d337a365185d" integrity sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w== -json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1: +json-parse-better-errors@^1.0.0, json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== @@ -11226,6 +11558,14 @@ make-dir@^1.0.0, make-dir@^1.2.0, make-dir@^1.3.0: dependencies: pify "^3.0.0" +make-dir@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + make-error@^1.1.1: version "1.3.5" resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8" @@ -11262,6 +11602,11 @@ makeerror@1.0.x: dependencies: tmpl "1.0.x" +mamacro@^0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" + integrity sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA== + map-age-cleaner@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" @@ -11336,6 +11681,11 @@ mem@^4.0.0: mimic-fn "^2.0.0" p-is-promise "^2.0.0" +memory-fs@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.2.0.tgz#f2bb25368bc121e391c2520de92969caee0a0290" + integrity sha1-8rslNovBIeORwlIN6Slpyu4KApA= + memory-fs@^0.4.0, memory-fs@~0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" @@ -11431,7 +11781,7 @@ micromatch@^2.1.5, micromatch@^2.3.11: parse-glob "^3.0.4" regex-cache "^0.4.2" -micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.3, micromatch@^3.1.4: +micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.3, micromatch@^3.1.4, micromatch@^3.1.8: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== @@ -11977,7 +12327,7 @@ node-int64@^0.4.0: resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs= -node-libs-browser@^2.0.0: +"node-libs-browser@^1.0.0 || ^2.0.0", node-libs-browser@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.0.tgz#c72f60d9d46de08a940dedbb25f3ffa2f9bbaa77" integrity sha512-5MQunG/oyOaBdttrL40dA7bUfPORLRWMUJLQtMg7nluxUvk5XwnLdL9twQHFAjRx/y7mIMkLKT9++qPbbk6BZA== @@ -15464,7 +15814,7 @@ resolve@1.1.7, resolve@1.1.x: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.2.0, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.9.0: +resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.2.0, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.5.0, resolve@^1.9.0: version "1.10.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.10.0.tgz#3bdaaeaf45cc07f375656dfd2e54ed0810b101ba" integrity sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg== @@ -16340,6 +16690,14 @@ source-map-support@^0.5.11, source-map-support@^0.5.6, source-map-support@^0.5.7 buffer-from "^1.0.0" source-map "^0.6.0" +source-map-support@~0.5.10: + version "0.5.12" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599" + integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map-url@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" @@ -16550,12 +16908,10 @@ stealthy-require@^1.1.1: resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" integrity sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks= -"strapi-lint@file:packages/strapi-lint": - version "3.0.0-alpha.25.2" - dependencies: - babel-eslint "^8.2.3" - prettier "^1.12.1" - shelljs "^0.7.8" +strapi-plugin-graphql@^0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/strapi-plugin-graphql/-/strapi-plugin-graphql-0.0.0.tgz#1980b285424378d3619f47f3245051329cd7bb4c" + integrity sha1-GYCyhUJDeNNhn0fzJFBRMpzXu0w= stream-browserify@^2.0.1: version "2.0.2" @@ -16959,11 +17315,21 @@ table@4.0.2: slice-ansi "1.0.0" string-width "^2.1.1" +tapable@^0.1.8: + version "0.1.10" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.1.10.tgz#29c35707c2b70e50d07482b5d202e8ed446dafd4" + integrity sha1-KcNXB8K3DlDQdIK10gLo7URtr9Q= + tapable@^0.2.7: version "0.2.9" resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.9.tgz#af2d8bbc9b04f74ee17af2b4d9048f807acd18a8" integrity sha512-2wsvQ+4GwBvLPLWsNfLCDYGsW6xb7aeC6utq2Qh0PFwgEy7K7dsma9Jsmb2zSQj7GvYAyUGSntLtsv++GmgL1A== +tapable@^1.0.0, tapable@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.1.tgz#4d297923c5a72a42360de2ab52dadfaaec00018e" + integrity sha512-9I2ydhj8Z9veORCw5PRm4u9uebCn0mcCa6scWoNcbZ6dAtoo2618u9UUzxgmsCOreJpqDDuv61LvwofW7hLcBA== + tar-stream@^1.5.2: version "1.6.2" resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" @@ -17056,6 +17422,29 @@ terraformer@~1.0.5: optionalDependencies: "@types/geojson" "^1.0.0" +terser-webpack-plugin@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.2.3.tgz#3f98bc902fac3e5d0de730869f50668561262ec8" + integrity sha512-GOK7q85oAb/5kE12fMuLdn2btOS9OBZn4VsecpHDywoUC/jLhSAKOiYo0ezx7ss2EXPMzyEWFoE0s1WLE+4+oA== + dependencies: + cacache "^11.0.2" + find-cache-dir "^2.0.0" + schema-utils "^1.0.0" + serialize-javascript "^1.4.0" + source-map "^0.6.1" + terser "^3.16.1" + webpack-sources "^1.1.0" + worker-farm "^1.5.2" + +terser@^3.16.1: + version "3.17.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-3.17.0.tgz#f88ffbeda0deb5637f9d24b0da66f4e15ab10cb2" + integrity sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ== + dependencies: + commander "^2.19.0" + source-map "~0.6.1" + source-map-support "~0.5.10" + test-exclude@^4.1.1: version "4.2.3" resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.3.tgz#a9a5e64474e4398339245a0a769ad7c2f4a97c20" @@ -17524,7 +17913,7 @@ unbzip2-stream@^1.0.9: buffer "^5.2.1" through "^2.3.8" -unc-path-regex@^0.1.2: +unc-path-regex@^0.1.0, unc-path-regex@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo= @@ -17892,7 +18281,7 @@ warning@^4.0.1: dependencies: loose-envify "^1.0.0" -watchpack@^1.4.0: +watchpack@^1.4.0, watchpack@^1.5.0: version "1.6.0" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" integrity sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA== @@ -17952,7 +18341,7 @@ webpack-hot-middleware@^2.18.2: querystring "^0.2.0" strip-ansi "^3.0.0" -webpack-sources@^1.0.1: +webpack-sources@^1.0.1, webpack-sources@^1.1.0, webpack-sources@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.3.0.tgz#2a28dcb9f1f45fe960d8f1493252b5ee6530fa85" integrity sha512-OiVgSrbGu7NEnEvQJJgdSFPl2qWKkWq5lHMhgiToIiN9w34EBnjYzSYs+VbL5KoYiLNtFFa7BZIKxRED3I32pA== @@ -17988,6 +18377,36 @@ webpack@^3.5.5: webpack-sources "^1.0.1" yargs "^8.0.2" +webpack@^4.6.0: + version "4.29.6" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.29.6.tgz#66bf0ec8beee4d469f8b598d3988ff9d8d90e955" + integrity sha512-MwBwpiE1BQpMDkbnUUaW6K8RFZjljJHArC6tWQJoFm0oQtfoSebtg4Y7/QHnJ/SddtjYLHaKGX64CFjG5rehJw== + dependencies: + "@webassemblyjs/ast" "1.8.5" + "@webassemblyjs/helper-module-context" "1.8.5" + "@webassemblyjs/wasm-edit" "1.8.5" + "@webassemblyjs/wasm-parser" "1.8.5" + acorn "^6.0.5" + acorn-dynamic-import "^4.0.0" + ajv "^6.1.0" + ajv-keywords "^3.1.0" + chrome-trace-event "^1.0.0" + enhanced-resolve "^4.1.0" + eslint-scope "^4.0.0" + json-parse-better-errors "^1.0.2" + loader-runner "^2.3.0" + loader-utils "^1.1.0" + memory-fs "~0.4.1" + micromatch "^3.1.8" + mkdirp "~0.5.0" + neo-async "^2.5.0" + node-libs-browser "^2.0.0" + schema-utils "^1.0.0" + tapable "^1.1.0" + terser-webpack-plugin "^1.1.0" + watchpack "^1.5.0" + webpack-sources "^1.3.0" + whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: version "1.0.5" resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" @@ -18115,6 +18534,13 @@ wordwrap@~0.0.2: resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= +worker-farm@^1.5.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.6.0.tgz#aecc405976fab5a95526180846f0dba288f3a4a0" + integrity sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ== + dependencies: + errno "~0.1.7" + wrap-ansi@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85"