diff --git a/packages/strapi-connector-mongoose/lib/queries.js b/packages/strapi-connector-mongoose/lib/queries.js index 3977056bcf..018f8ae4d0 100644 --- a/packages/strapi-connector-mongoose/lib/queries.js +++ b/packages/strapi-connector-mongoose/lib/queries.js @@ -484,6 +484,7 @@ module.exports = ({ model, modelKey, strapi }) => { const filters = modelUtils.convertParams(modelKey, params); const $or = buildSearchOr(model, params._q); + if ($or.length === 0) return Promise.resolve([]); return model .find({ $or }) @@ -496,6 +497,7 @@ module.exports = ({ model, modelKey, strapi }) => { function countSearch(params) { const $or = buildSearchOr(model, params._q); + if ($or.length === 0) return Promise.resolve(0); return model.find({ $or }).countDocuments(); } @@ -525,6 +527,7 @@ const buildSearchOr = (model, query) => { case 'string': case 'text': case 'password': + case 'uid': return acc.concat({ [curr]: { $regex: query, $options: 'i' } }); case 'boolean': if (query === 'true' || query === 'false') { diff --git a/packages/strapi-generate-api/json/routes.json.js b/packages/strapi-generate-api/json/routes.json.js index ad6d78f9d3..f6d306a804 100644 --- a/packages/strapi-generate-api/json/routes.json.js +++ b/packages/strapi-generate-api/json/routes.json.js @@ -97,46 +97,19 @@ function generateCollectionTypeRoutes({ route, name }) { */ module.exports = scope => { - const routes = - scope.contentTypeKind === 'singleType' - ? generateSingleTypeRoutes({ - route: scope.route, - name: scope.name, - }) - : generateCollectionTypeRoutes({ - route: scope.route, - name: scope.name, - }); + let routes = []; + if (!scope.args.plugin) { + routes = + scope.contentTypeKind === 'singleType' + ? generateSingleTypeRoutes({ route: scope.route, name: scope.name }) + : generateCollectionTypeRoutes({ route: scope.route, name: scope.name }); + } - // We have to delete current file + // if routes.json already exists, then merge if (fs.existsSync(scope.rootPath)) { - let current; - - try { - // Copy current routes.json - current = require(scope.rootPath); - - // Remove current routes.json - fs.unlinkSync(scope.rootPath); - } catch (e) { - console.error(e); - current = { - routes: [], - }; - } - - try { - _.set( - current, - 'routes', - _.concat(routes, _.differenceWith(current.routes, routes, _.isEqual)) - ); - - return current; - } catch (e) { - console.error(e); - return; - } + let current = require(scope.rootPath); + fs.unlinkSync(scope.rootPath); + routes = _.concat(routes, _.differenceWith(current.routes, routes, _.isEqual)); } return { routes }; diff --git a/packages/strapi-generate-api/lib/before.js b/packages/strapi-generate-api/lib/before.js index 345dfe9f47..28191502e0 100644 --- a/packages/strapi-generate-api/lib/before.js +++ b/packages/strapi-generate-api/lib/before.js @@ -11,6 +11,7 @@ const path = require('path'); // Public node modules. const _ = require('lodash'); const pluralize = require('pluralize'); +const { nameToSlug } = require('strapi-utils'); /** * This `before` function is run before generating targets. @@ -26,7 +27,7 @@ module.exports = (scope, cb) => { } // Format `id`. - const name = scope.name || _.trim(_.camelCase(scope.id)); + const name = scope.name || nameToSlug(scope.id); const environment = process.env.NODE_ENV || 'development'; scope.contentTypeKind = scope.args.kind || 'collectionType'; @@ -58,12 +59,6 @@ module.exports = (scope, cb) => { filePath, }); - // Humanize output. - _.defaults(scope, { - humanizeId: name, - humanizedPath: filePath, - }); - // Validate optional attribute arguments. const invalidAttributes = []; diff --git a/packages/strapi-generate-api/package.json b/packages/strapi-generate-api/package.json index 10a82fe28d..9b54ce1197 100644 --- a/packages/strapi-generate-api/package.json +++ b/packages/strapi-generate-api/package.json @@ -14,7 +14,8 @@ }, "dependencies": { "lodash": "^4.17.11", - "pluralize": "^7.0.0" + "pluralize": "^7.0.0", + "strapi-utils": "^3.0.0-beta.19.3" }, "scripts": { "test": "echo \"no tests yet\"" diff --git a/packages/strapi-generate-controller/lib/before.js b/packages/strapi-generate-controller/lib/before.js index 8067b0b2cf..c206d390c1 100644 --- a/packages/strapi-generate-controller/lib/before.js +++ b/packages/strapi-generate-controller/lib/before.js @@ -6,6 +6,7 @@ // Public node modules. const _ = require('lodash'); +const { nameToSlug } = require('strapi-utils'); /* eslint-disable prefer-template */ /** * This `before` function is run before generating targets. @@ -22,18 +23,15 @@ module.exports = (scope, cb) => { ); } + // Format `id`. + const name = scope.name || nameToSlug(scope.id); + // `scope.args` are the raw command line arguments. _.defaults(scope, { - id: _.trim(_.deburr(scope.id)), + name, api: scope.id, }); - // Determine default values based on the available scope. - _.defaults(scope, { - globalID: _.upperFirst(_.camelCase(scope.id)), - ext: '.js', - }); - // Determine the destination path. let filePath; if (scope.args.api) { @@ -43,20 +41,14 @@ module.exports = (scope, cb) => { } else if (scope.args.extend) { filePath = `./extensions/${scope.args.extend}/controllers`; } else { - filePath = `./api/${scope.id}/controllers`; + filePath = `./api/${name}/controllers`; } // Take another pass to take advantage of the defaults absorbed in previous passes. _.defaults(scope, { rootPath: scope.rootPath, filePath, - filename: scope.globalID + scope.ext, - }); - - // Humanize output. - _.defaults(scope, { - humanizeId: _.camelCase(scope.id).toLowerCase(), - humanizedPath: '`' + scope.filePath + '`', + filename: `${name}.js`, }); // Trigger callback with no error to proceed. diff --git a/packages/strapi-generate-controller/package.json b/packages/strapi-generate-controller/package.json index 41ac9fdc62..253093716d 100644 --- a/packages/strapi-generate-controller/package.json +++ b/packages/strapi-generate-controller/package.json @@ -14,7 +14,8 @@ "lib": "./lib" }, "dependencies": { - "lodash": "^4.17.11" + "lodash": "^4.17.11", + "strapi-utils": "^3.0.0-beta.19.3" }, "scripts": { "test": "echo \"no tests yet\"" diff --git a/packages/strapi-generate-controller/templates/controller.template b/packages/strapi-generate-controller/templates/controller.template index 12a7559680..929ca9ff11 100644 --- a/packages/strapi-generate-controller/templates/controller.template +++ b/packages/strapi-generate-controller/templates/controller.template @@ -1,7 +1,7 @@ 'use strict'; /** - * A set of functions called "actions" for `<%= globalID %>` + * A set of functions called "actions" for `<%= name %>` */ module.exports = { diff --git a/packages/strapi-generate-model/lib/before.js b/packages/strapi-generate-model/lib/before.js index e24d0c1c5c..d27a9cbe92 100644 --- a/packages/strapi-generate-model/lib/before.js +++ b/packages/strapi-generate-model/lib/before.js @@ -11,6 +11,7 @@ const path = require('path'); // Public node modules. const _ = require('lodash'); const pluralize = require('pluralize'); +const { nameToSlug, nameToCollectionName } = require('strapi-utils'); // Fetch stub attribute template on initial load. const attributeTemplate = fs.readFileSync( @@ -34,41 +35,31 @@ module.exports = (scope, cb) => { ); } + // Format `id`. + const name = scope.name || nameToSlug(scope.id); + // `scope.args` are the raw command line arguments. _.defaults(scope, { - id: _.trim(_.deburr(scope.id)), - idPluralized: pluralize.plural(_.trim(_.deburr(scope.id))), + name, environment: process.env.NODE_ENV || 'development', }); - // Determine default values based on the available scope. - _.defaults(scope, { - globalID: _.upperFirst(_.camelCase(scope.id)), - ext: '.js', - }); - // Determine the destination path. let filePath; if (scope.args.api) { - filePath = `./api/${scope.args.api}`; + filePath = `./api/${scope.args.api}/models`; } else if (scope.args.plugin) { filePath = `./plugins/${scope.args.plugin}/models`; } else { - filePath = `./api/${scope.id}`; + filePath = `./api/${name}/models`; } // Take another pass to take advantage of the defaults absorbed in previous passes. _.defaults(scope, { rootPath: scope.rootPath, filePath, - filename: scope.globalID + scope.ext, - filenameSettings: scope.globalID + '.settings.json', - }); - - // Humanize output. - _.defaults(scope, { - humanizeId: _.camelCase(scope.id).toLowerCase(), - humanizedPath: '`' + scope.filePath + '`', + filename: `${name}.js`, + filenameSettings: `${name}.settings.json`, }); // Validate optional attribute arguments. @@ -82,9 +73,7 @@ module.exports = (scope, cb) => { // Handle invalid attributes. if (!parts[1] || !parts[0]) { - invalidAttributes.push( - 'Error: Invalid attribute notation `' + attribute + '`.' - ); + invalidAttributes.push('Error: Invalid attribute notation `' + attribute + '`.'); return; } @@ -97,12 +86,10 @@ module.exports = (scope, cb) => { // Set collectionName scope.collectionName = _.has(scope.args, 'collectionName') ? scope.args.collectionName - : undefined; + : nameToCollectionName(pluralize(scope.id)); // Set description - scope.description = _.has(scope.args, 'description') - ? scope.args.description - : undefined; + scope.description = _.has(scope.args, 'description') ? scope.args.description : undefined; // Handle invalid action arguments. // Send back invalidActions. @@ -141,13 +128,7 @@ module.exports = (scope, cb) => { scope.args.connection || JSON.parse( fs.readFileSync( - path.resolve( - scope.rootPath, - 'config', - 'environments', - scope.environment, - 'database.json' - ) + path.resolve(scope.rootPath, 'config', 'environments', scope.environment, 'database.json') ) ).defaultConnection || ''; diff --git a/packages/strapi-generate-model/lib/index.js b/packages/strapi-generate-model/lib/index.js index 3266bf096c..564116ea33 100644 --- a/packages/strapi-generate-model/lib/index.js +++ b/packages/strapi-generate-model/lib/index.js @@ -16,7 +16,10 @@ module.exports = { templatesDirectory: scope => { try { // Try to reach the path. If it fail, throw an error. - fs.accessSync(path.resolve(__dirname, '..', 'templates', scope.args.tpl), fs.constants.R_OK | fs.constants.W_OK); + fs.accessSync( + path.resolve(__dirname, '..', 'templates', scope.args.tpl), + fs.constants.R_OK | fs.constants.W_OK + ); return path.resolve(__dirname, '..', 'templates', scope.args.tpl); } catch (e) { @@ -26,11 +29,11 @@ module.exports = { }, before: require('./before'), targets: { - ':filePath/models/:filename': { - template: 'model.template' + ':filePath/:filename': { + template: 'model.template', }, - ':filePath/models/:filenameSettings': { - template: 'model.settings.template' - } - } + ':filePath/:filenameSettings': { + template: 'model.settings.template', + }, + }, }; diff --git a/packages/strapi-generate-model/package.json b/packages/strapi-generate-model/package.json index 0d455036c6..5d110e15f6 100644 --- a/packages/strapi-generate-model/package.json +++ b/packages/strapi-generate-model/package.json @@ -15,7 +15,8 @@ }, "dependencies": { "lodash": "^4.17.11", - "pluralize": "^7.0.0" + "pluralize": "^7.0.0", + "strapi-utils": "^3.0.0-beta.19.3" }, "scripts": { "test": "echo \"no tests yet\"" diff --git a/packages/strapi-generate-model/templates/bookshelf/model.settings.template b/packages/strapi-generate-model/templates/bookshelf/model.settings.template index 8afd29e826..41ce2be590 100644 --- a/packages/strapi-generate-model/templates/bookshelf/model.settings.template +++ b/packages/strapi-generate-model/templates/bookshelf/model.settings.template @@ -1,6 +1,7 @@ { + "kind": "collectionType", "connection": "<%= connection %>", - "collectionName": "<%= collectionName || idPluralized %>", + "collectionName": "<%= collectionName %>", "info": { "name": "<%= id %>", "description": "<%= description %>" diff --git a/packages/strapi-generate-model/templates/bookshelf/model.template b/packages/strapi-generate-model/templates/bookshelf/model.template index f392b92f14..efcdb9e76a 100644 --- a/packages/strapi-generate-model/templates/bookshelf/model.template +++ b/packages/strapi-generate-model/templates/bookshelf/model.template @@ -1,7 +1,7 @@ 'use strict'; /** - * Lifecycle callbacks for the `<%= globalID %>` model. + * Lifecycle callbacks for the `<%= name %>` model. */ module.exports = { diff --git a/packages/strapi-generate-model/templates/mongoose/model.settings.template b/packages/strapi-generate-model/templates/mongoose/model.settings.template index 99bfc2e48a..87e65530f0 100644 --- a/packages/strapi-generate-model/templates/mongoose/model.settings.template +++ b/packages/strapi-generate-model/templates/mongoose/model.settings.template @@ -1,6 +1,7 @@ { + "kind": "collectionType", "connection": "<%= connection %>", - "collectionName": "<%= collectionName || '' %>", + "collectionName": "<%= collectionName %>", "info": { "name": "<%= id %>", "description": "<%= description %>" diff --git a/packages/strapi-generate-model/templates/mongoose/model.template b/packages/strapi-generate-model/templates/mongoose/model.template index 30172b433f..4416021b74 100644 --- a/packages/strapi-generate-model/templates/mongoose/model.template +++ b/packages/strapi-generate-model/templates/mongoose/model.template @@ -1,7 +1,7 @@ 'use strict'; /** - * Lifecycle callbacks for the `<%= globalID %>` model. + * Lifecycle callbacks for the `<%= name %>` model. */ module.exports = { diff --git a/packages/strapi-generate-plugin/json/routes.json.js b/packages/strapi-generate-plugin/json/routes.json.js index fda8c8c691..5456426c81 100644 --- a/packages/strapi-generate-plugin/json/routes.json.js +++ b/packages/strapi-generate-plugin/json/routes.json.js @@ -7,14 +7,16 @@ module.exports = scope => { function generateRoutes() { return { - routes: [{ - method: 'GET', - path: '/', - handler: scope.globalID + '.index', - config: { - policies: [] - } - }] + routes: [ + { + method: 'GET', + path: '/', + handler: scope.name + '.index', + config: { + policies: [], + }, + }, + ], }; } diff --git a/packages/strapi-generate-plugin/lib/before.js b/packages/strapi-generate-plugin/lib/before.js index 67a50d3630..2239255a2f 100644 --- a/packages/strapi-generate-plugin/lib/before.js +++ b/packages/strapi-generate-plugin/lib/before.js @@ -8,6 +8,7 @@ const path = require('path'); const fs = require('fs-extra'); const _ = require('lodash'); +const { nameToSlug } = require('strapi-utils'); /** * This `before` function is run before generating targets. @@ -22,20 +23,12 @@ module.exports = (scope, cb) => { return cb.invalid('Usage: `$ strapi generate:plugin pluginName`'); } - // `scope.args` are the raw command line arguments. - _.defaults(scope, { - id: _.trim(_.deburr(scope.id)), - }); - - // Determine default values based on the available scope. - _.defaults(scope, { - globalID: _.upperFirst(_.camelCase(scope.id)), - ext: '.js', - }); + // Format `id`. + const name = scope.name || nameToSlug(scope.id); // Plugin info. _.defaults(scope, { - name: scope.args.name || scope.id, + name, author: scope.author || 'A Strapi developer', email: scope.email || '', year: new Date().getFullYear(), @@ -44,23 +37,15 @@ module.exports = (scope, cb) => { // Take another pass to take advantage of the defaults absorbed in previous passes. _.defaults(scope, { - filename: `${scope.globalID}${scope.ext}`, - }); - - // Humanize output. - _.defaults(scope, { - humanizeId: scope.id.toLowerCase(), - humanizedPath: '`./plugins`', + filename: `${name}.js`, + filePath: './plugins', }); const pluginDir = path.resolve(scope.rootPath, 'plugins'); fs.ensureDirSync(pluginDir); // Copy the admin files. - fs.copySync( - path.resolve(__dirname, '..', 'files'), - path.resolve(pluginDir, scope.humanizeId) - ); + fs.copySync(path.resolve(__dirname, '..', 'files'), path.resolve(pluginDir, name)); // Trigger callback with no error to proceed. return cb.success(); diff --git a/packages/strapi-generate-plugin/lib/index.js b/packages/strapi-generate-plugin/lib/index.js index 9404c2cdf6..e2c0e692f0 100644 --- a/packages/strapi-generate-plugin/lib/index.js +++ b/packages/strapi-generate-plugin/lib/index.js @@ -19,42 +19,42 @@ module.exports = { templatesDirectory: path.resolve(__dirname, '..', 'templates'), before: require('./before'), targets: { - 'plugins/:humanizeId/.gitignore': { + 'plugins/:name/.gitignore': { copy: 'gitignore', }, // Use the default `controller` file as a template for // every generated controller. - 'plugins/:humanizeId/controllers/:filename': { + 'plugins/:name/controllers/:filename': { template: 'controller.template', }, // every generated controller. - 'plugins/:humanizeId/services/:filename': { + 'plugins/:name/services/:filename': { template: 'service.template', }, // Generate routes. - 'plugins/:humanizeId/config/routes.json': { + 'plugins/:name/config/routes.json': { jsonfile: routesJSON, }, // Main package. - 'plugins/:humanizeId/package.json': { + 'plugins/:name/package.json': { jsonfile: packageJSON, }, // Copy dot files. - 'plugins/:humanizeId/.editorconfig': { + 'plugins/:name/.editorconfig': { copy: 'editorconfig', }, - 'plugins/:humanizeId/.gitattributes': { + 'plugins/:name/.gitattributes': { copy: 'gitattributes', }, // Copy Markdown files with some information. - 'plugins/:humanizeId/README.md': { + 'plugins/:name/README.md': { template: 'README.md', }, }, diff --git a/packages/strapi-generate-plugin/package.json b/packages/strapi-generate-plugin/package.json index f0daa13a0a..046270ebdd 100644 --- a/packages/strapi-generate-plugin/package.json +++ b/packages/strapi-generate-plugin/package.json @@ -14,7 +14,8 @@ }, "dependencies": { "fs-extra": "^8.0.1", - "lodash": "^4.17.11" + "lodash": "^4.17.11", + "strapi-utils": "^3.0.0-beta.19.3" }, "scripts": { "test": "echo \"no tests yet\"" diff --git a/packages/strapi-generate-plugin/templates/controller.template b/packages/strapi-generate-plugin/templates/controller.template index 5db3e2d6e8..6d32cf8c7f 100644 --- a/packages/strapi-generate-plugin/templates/controller.template +++ b/packages/strapi-generate-plugin/templates/controller.template @@ -3,7 +3,7 @@ /** * <%= filename %> controller * - * @description: A set of functions called "actions" of the `<%= humanizeId %>` plugin. + * @description: A set of functions called "actions" of the `<%= name %>` plugin. */ module.exports = { diff --git a/packages/strapi-generate-policy/lib/before.js b/packages/strapi-generate-policy/lib/before.js index a8649dc36b..03e576a1d7 100644 --- a/packages/strapi-generate-policy/lib/before.js +++ b/packages/strapi-generate-policy/lib/before.js @@ -6,6 +6,7 @@ // Public node modules. const _ = require('lodash'); +const { nameToSlug } = require('strapi-utils'); /** * This `before` function is run before generating targets. @@ -18,9 +19,14 @@ const _ = require('lodash'); /* eslint-disable prefer-template */ module.exports = (scope, cb) => { if (!scope.rootPath || !scope.id) { - return cb.invalid('Usage: `$ strapi generate:policy policyName --api apiName --plugin pluginName`'); + return cb.invalid( + 'Usage: `$ strapi generate:policy policyName --api apiName --plugin pluginName`' + ); } + // Format `id`. + const name = scope.name || nameToSlug(scope.id); + let filePath; if (scope.args.api) { filePath = `./api/${scope.args.api}/config/policies`; @@ -30,21 +36,11 @@ module.exports = (scope, cb) => { filePath = './config/policies'; } - // Determine default values based on the available scope. - _.defaults(scope, { - ext: '.js' - }); - // Take another pass to take advantage of the defaults absorbed in previous passes. _.defaults(scope, { + name, filePath, - filename: scope.id + scope.ext - }); - - // Humanize output. - _.defaults(scope, { - humanizeId: scope.id, - humanizedPath: '`' + scope.filePath + '`' + filename: `${name}.js`, }); // Trigger callback with no error to proceed. diff --git a/packages/strapi-generate-policy/package.json b/packages/strapi-generate-policy/package.json index 1b0d408541..b545a4099c 100644 --- a/packages/strapi-generate-policy/package.json +++ b/packages/strapi-generate-policy/package.json @@ -14,7 +14,8 @@ "lib": "./lib" }, "dependencies": { - "lodash": "^4.17.11" + "lodash": "^4.17.11", + "strapi-utils": "^3.0.0-beta.19.3" }, "scripts": { "test": "echo \"no tests yet\"" diff --git a/packages/strapi-generate-service/lib/before.js b/packages/strapi-generate-service/lib/before.js index 10e1008cfa..2919c6a633 100644 --- a/packages/strapi-generate-service/lib/before.js +++ b/packages/strapi-generate-service/lib/before.js @@ -6,6 +6,7 @@ // Public node modules. const _ = require('lodash'); +const { nameToSlug } = require('strapi-utils'); /** * This `before` function is run before generating targets. @@ -18,19 +19,18 @@ const _ = require('lodash'); /* eslint-disable prefer-template */ module.exports = (scope, cb) => { if (!scope.rootPath || !scope.id) { - return cb.invalid('Usage: `$ strapi generate:service serviceName --api apiName --plugin pluginName`'); + return cb.invalid( + 'Usage: `$ strapi generate:service serviceName --api apiName --plugin pluginName`' + ); } + // Format `id`. + const name = scope.name || nameToSlug(scope.id); + // `scope.args` are the raw command line arguments. _.defaults(scope, { - id: _.trim(_.deburr(scope.id)), - api: scope.args.api || scope.id - }); - - // Determine default values based on the available scope. - _.defaults(scope, { - globalID: _.upperFirst(_.camelCase(scope.id)), - ext: '.js' + name, + api: scope.args.api || scope.id, }); // Determine the destination path. @@ -40,20 +40,14 @@ module.exports = (scope, cb) => { } else if (scope.args.plugin) { filePath = `./plugins/${scope.args.plugin}/services`; } else { - filePath = `./api/${scope.id}/services`; + filePath = `./api/${name}/services`; } // Take another pass to take advantage of the defaults absorbed in previous passes. _.defaults(scope, { rootPath: scope.rootPath, filePath, - filename: scope.globalID + scope.ext - }); - - // Humanize output. - _.defaults(scope, { - humanizeId: _.camelCase(scope.id).toLowerCase(), - humanizedPath: '`' + scope.filePath + '`' + filename: `${name}.js`, }); // Trigger callback with no error to proceed. diff --git a/packages/strapi-generate-service/lib/index.js b/packages/strapi-generate-service/lib/index.js index d1b73b5982..87452b5f03 100644 --- a/packages/strapi-generate-service/lib/index.js +++ b/packages/strapi-generate-service/lib/index.js @@ -16,7 +16,10 @@ module.exports = { templatesDirectory: scope => { try { // Try to reach the path. If it fail, throw an error. - fs.accessSync(path.resolve(__dirname, '..', 'templates', scope.args.tpl), fs.constants.R_OK | fs.constants.W_OK); + fs.accessSync( + path.resolve(__dirname, '..', 'templates', scope.args.tpl), + fs.constants.R_OK | fs.constants.W_OK + ); return path.resolve(__dirname, '..', 'templates', scope.args.tpl); } catch (e) { @@ -26,8 +29,8 @@ module.exports = { }, before: require('./before'), targets: { - 'api/:api/services/:filename': { - template: 'service.template' - } - } + ':filePath/:filename': { + template: 'service.template', + }, + }, }; diff --git a/packages/strapi-generate-service/package.json b/packages/strapi-generate-service/package.json index 6dd5a14959..ea9c30fb65 100644 --- a/packages/strapi-generate-service/package.json +++ b/packages/strapi-generate-service/package.json @@ -14,7 +14,8 @@ "lib": "./lib" }, "dependencies": { - "lodash": "^4.17.11" + "lodash": "^4.17.11", + "strapi-utils": "^3.0.0-beta.19.3" }, "scripts": { "test": "echo \"no tests yet\"" diff --git a/packages/strapi-generate-service/templates/bookshelf/service.template b/packages/strapi-generate-service/templates/bookshelf/service.template index 511a0c9ac7..2b4df98b29 100644 --- a/packages/strapi-generate-service/templates/bookshelf/service.template +++ b/packages/strapi-generate-service/templates/bookshelf/service.template @@ -1,7 +1,7 @@ 'use strict'; /** - * `<%= globalID %>` service. + * `<%= name %>` service. */ module.exports = { diff --git a/packages/strapi-generate-service/templates/mongoose/service.template b/packages/strapi-generate-service/templates/mongoose/service.template index 511a0c9ac7..2b4df98b29 100644 --- a/packages/strapi-generate-service/templates/mongoose/service.template +++ b/packages/strapi-generate-service/templates/mongoose/service.template @@ -1,7 +1,7 @@ 'use strict'; /** - * `<%= globalID %>` service. + * `<%= name %>` service. */ module.exports = { diff --git a/packages/strapi-generate/lib/generate.js b/packages/strapi-generate/lib/generate.js index 80916c7416..d47ed93544 100644 --- a/packages/strapi-generate/lib/generate.js +++ b/packages/strapi-generate/lib/generate.js @@ -30,7 +30,7 @@ function generate(generator, scope, cb) { const sb = reportback.extend(cb, { error: cb.error, invalid: cb.invalid, - alreadyExists: 'error' + alreadyExists: 'error', }); // Resolve string shorthand for generator defs @@ -38,119 +38,151 @@ function generate(generator, scope, cb) { if (typeof generator === 'string') { const generatorName = generator; generator = { - generator: generatorName + generator: generatorName, }; } // Run the generator's `before()` method proceeding. - generator.before(scope, reportback.extend({ - error: sb.error, - invalid: sb.invalid, - success: () => { + generator.before( + scope, + reportback.extend({ + error: sb.error, + invalid: sb.invalid, + success: () => { + // Process all of the generator's targets concurrently. + async.each( + Object.keys(generator.targets), + (keyPath, asyncEachCb) => { + const asyncEachSb = reportback.extend(asyncEachCb); - // Process all of the generator's targets concurrently. - async.each(Object.keys(generator.targets), (keyPath, asyncEachCb) => { - const asyncEachSb = reportback.extend(asyncEachCb); - - // Create a new scope object for this target, - // with references to the important bits of the original - // (depth will be passed-by-value, but that's what we want). - // Then generate the target, passing along a reference to - // the base `generate` method to allow for recursive generators. - const target = generator.targets[keyPath]; - if (!target) { - return asyncEachSb(new Error('Error: Invalid target: {"' + keyPath + '": ' + util.inspect(target) + '}')); - } - - // Input tolerance. - if (keyPath === '') { - keyPath = '.'; - } - - // Interpret `keyPath` using Express's parameterized route conventions, - // first parsing params, then replacing them with their proper values from scope. - const params = []; - pathRegexp(keyPath, params); - let err; - const parsedKeyPath = _.reduce(params, (memoKeyPath, param) => { - if (err) { - return false; - } - - try { - const paramMatchExpr = ':' + param.name; - let actualParamValue = scope[param.name]; - if (!actualParamValue) { - err = new Error( - 'generator error:\n' + - 'A scope variable (`' + param.name + '`) was referenced in target: `' + memoKeyPath + '`,\n' + - 'but `' + param.name + '` does not exist in the generator\'s scope.' + // Create a new scope object for this target, + // with references to the important bits of the original + // (depth will be passed-by-value, but that's what we want). + // Then generate the target, passing along a reference to + // the base `generate` method to allow for recursive generators. + const target = generator.targets[keyPath]; + if (!target) { + return asyncEachSb( + new Error( + 'Error: Invalid target: {"' + keyPath + '": ' + util.inspect(target) + '}' + ) ); - return false; } - actualParamValue = String(actualParamValue); - return memoKeyPath.replace(paramMatchExpr, actualParamValue); - } catch (e) { - err = new Error('Error: Could not parse target key ' + memoKeyPath); - err.message = e; - return false; + // Input tolerance. + if (keyPath === '') { + keyPath = '.'; + } + + // Interpret `keyPath` using Express's parameterized route conventions, + // first parsing params, then replacing them with their proper values from scope. + const params = []; + pathRegexp(keyPath, params); + let err; + const parsedKeyPath = _.reduce( + params, + (memoKeyPath, param) => { + if (err) { + return false; + } + + try { + const paramMatchExpr = ':' + param.name; + let actualParamValue = scope[param.name]; + if (!actualParamValue) { + err = new Error( + 'generator error:\n' + + 'A scope variable (`' + + param.name + + '`) was referenced in target: `' + + memoKeyPath + + '`,\n' + + 'but `' + + param.name + + "` does not exist in the generator's scope." + ); + return false; + } + actualParamValue = String(actualParamValue); + + return memoKeyPath.replace(paramMatchExpr, actualParamValue); + } catch (e) { + err = new Error('Error: Could not parse target key ' + memoKeyPath); + err.message = e; + return false; + } + }, + keyPath + ); + if (!parsedKeyPath) { + return asyncEachSb(err); + } + + // Create path from `rootPath` to `keyPath` to use as the `rootPath` + // for any generators or helpers in this target + // (use a copy so that child generators don't mutate the scope). + const targetScope = _.merge({}, scope, { + rootPath: path.resolve(scope.rootPath, parsedKeyPath), + + // Include reference to original keypath for error reporting. + keyPath, + }); + + // If `target` is an array, run each item. + if (_.isArray(target)) { + async.eachSeries( + target, + (targetItem, asyncEachSeriesCb) => { + generateTarget( + { + target: targetItem, + parent: generator, + scope: _.cloneDeep(targetScope), + recursiveGenerate: generate, + }, + asyncEachSeriesCb + ); + }, + asyncEachSb + ); + return; + } + + // Otherwise, just run the single target generator/helper. + generateTarget( + { + target, + parent: generator, + scope: targetScope, + recursiveGenerate: generate, + }, + asyncEachSb + ); + }, + + err => { + // Expose a `error` handler in generators. + if (err) { + const errorFn = + generator.error || + function defaultError(err, scope, _cb) { + return _cb(err); + }; + return errorFn(err, scope, sb); + } + + // Expose a `after` handler in generators (on success only). + const afterFn = + generator.after || + function defaultAfter(scope, _cb) { + return _cb(); + }; + return afterFn(scope, sb); } - }, keyPath); - if (!parsedKeyPath) { - return asyncEachSb(err); - } - - // Create path from `rootPath` to `keyPath` to use as the `rootPath` - // for any generators or helpers in this target - // (use a copy so that child generators don't mutate the scope). - const targetScope = _.merge({}, scope, { - rootPath: path.resolve(scope.rootPath, parsedKeyPath), - - // Include reference to original keypath for error reporting. - keyPath - }); - - // If `target` is an array, run each item. - if (_.isArray(target)) { - async.eachSeries(target, (targetItem, asyncEachSeriesCb) => { - generateTarget({ - target: targetItem, - parent: generator, - scope: _.cloneDeep(targetScope), - recursiveGenerate: generate - }, asyncEachSeriesCb); - }, asyncEachSb); - return; - } - - // Otherwise, just run the single target generator/helper. - generateTarget({ - target, - parent: generator, - scope: targetScope, - recursiveGenerate: generate - }, asyncEachSb); + ); }, - - err => { - - // Expose a `error` handler in generators. - if (err) { - const errorFn = generator.error || function defaultError(err, scope, _cb) { - return _cb(err); - }; - return errorFn(err, scope, sb); - } - - // Expose a `after` handler in generators (on success only). - const afterFn = generator.after || function defaultAfter(scope, _cb) { - return _cb(); - }; - return afterFn(scope, sb); - }); - } - })); + }) + ); } module.exports = generate; diff --git a/packages/strapi-plugin-content-type-builder/services/ComponentCategories.js b/packages/strapi-plugin-content-type-builder/services/ComponentCategories.js index 988fa7e1af..5cba16c3cb 100644 --- a/packages/strapi-plugin-content-type-builder/services/ComponentCategories.js +++ b/packages/strapi-plugin-content-type-builder/services/ComponentCategories.js @@ -2,7 +2,7 @@ const { join } = require('path'); -const { nameToSlug } = require('../utils/helpers'); +const { nameToSlug } = require('strapi-utils'); const createBuilder = require('./schema-builder'); /** diff --git a/packages/strapi-plugin-content-type-builder/services/ContentTypes.js b/packages/strapi-plugin-content-type-builder/services/ContentTypes.js index 9197f06234..c15f767447 100644 --- a/packages/strapi-plugin-content-type-builder/services/ContentTypes.js +++ b/packages/strapi-plugin-content-type-builder/services/ContentTypes.js @@ -7,7 +7,7 @@ const generator = require('strapi-generate'); const createBuilder = require('./schema-builder'); const apiHandler = require('./api-handler'); const { formatAttributes, replaceTemporaryUIDs } = require('../utils/attributes'); -const { nameToSlug } = require('../utils/helpers'); +const { nameToSlug } = require('strapi-utils'); /** * Format a contentType info to be used by the front-end diff --git a/packages/strapi-plugin-content-type-builder/services/schema-builder/component-builder.js b/packages/strapi-plugin-content-type-builder/services/schema-builder/component-builder.js index 6710dc27bf..ecf392d294 100644 --- a/packages/strapi-plugin-content-type-builder/services/schema-builder/component-builder.js +++ b/packages/strapi-plugin-content-type-builder/services/schema-builder/component-builder.js @@ -5,7 +5,7 @@ const _ = require('lodash'); const pluralize = require('pluralize'); const { isConfigurable } = require('../../utils/attributes'); -const { nameToSlug, nameToCollectionName } = require('../../utils/helpers'); +const { nameToSlug, nameToCollectionName } = require('strapi-utils'); const createSchemaHandler = require('./schema-handler'); module.exports = function createComponentBuilder() { diff --git a/packages/strapi-plugin-content-type-builder/services/schema-builder/content-type-builder.js b/packages/strapi-plugin-content-type-builder/services/schema-builder/content-type-builder.js index 8708bb9f95..8b15cf986b 100644 --- a/packages/strapi-plugin-content-type-builder/services/schema-builder/content-type-builder.js +++ b/packages/strapi-plugin-content-type-builder/services/schema-builder/content-type-builder.js @@ -5,7 +5,7 @@ const _ = require('lodash'); const pluralize = require('pluralize'); const { isRelation, toUID, isConfigurable } = require('../../utils/attributes'); -const { nameToSlug, nameToCollectionName } = require('../../utils/helpers'); +const { nameToSlug, nameToCollectionName } = require('strapi-utils'); const { typeKinds } = require('../../controllers/validation/constants'); const createSchemaHandler = require('./schema-handler'); diff --git a/packages/strapi-plugin-content-type-builder/utils/helpers.js b/packages/strapi-plugin-content-type-builder/utils/helpers.js index 7117247a8d..4a336af25c 100644 --- a/packages/strapi-plugin-content-type-builder/utils/helpers.js +++ b/packages/strapi-plugin-content-type-builder/utils/helpers.js @@ -1,7 +1,5 @@ 'use strict'; -const slugify = require('@sindresorhus/slugify'); - const escapeNewlines = (content = '', placeholder = '\n') => { return content.replace(/[\r\n]+/g, placeholder); }; @@ -26,13 +24,8 @@ const deepTrimObject = attribute => { * Converts a name to a slug * @param {string} name a name to convert */ -const nameToSlug = name => slugify(name, { separator: '-' }); - -const nameToCollectionName = name => slugify(name, { separator: '_' }); module.exports = { escapeNewlines, deepTrimObject, - nameToSlug, - nameToCollectionName, }; diff --git a/packages/strapi-plugin-users-permissions/config/schema.graphql.js b/packages/strapi-plugin-users-permissions/config/schema.graphql.js index 40e87590ac..ca53141b8c 100644 --- a/packages/strapi-plugin-users-permissions/config/schema.graphql.js +++ b/packages/strapi-plugin-users-permissions/config/schema.graphql.js @@ -44,6 +44,10 @@ module.exports = { jwt: String! user: UsersPermissionsMe! } + + type ForgotPassword { + ok: Boolean + } `, query: ` me: UsersPermissionsMe @@ -51,6 +55,9 @@ module.exports = { mutation: ` login(input: UsersPermissionsLoginInput!): UsersPermissionsLoginPayload! register(input: UserInput!): UsersPermissionsLoginPayload! + forgotPassword(email: String!): ForgotPassword + changePassword(password: String!, passwordConfirmation: String!, code: String!): UsersPermissionsLoginPayload + emailConfirmation(confirmation: String!): UsersPermissionsLoginPayload `, resolver: { Query: { @@ -199,6 +206,56 @@ module.exports = { }; }, }, + forgotPassword: { + description: 'Request a reset password token', + resolverOf: 'plugins::users-permissions.auth.forgotPassword', + resolver: async (obj, options, { context }) => { + context.request.body = _.toPlainObject(options); + + await strapi.plugins['users-permissions'].controllers.auth.forgotPassword(context); + let output = context.body.toJSON ? context.body.toJSON() : context.body; + + checkBadRequest(output); + + return { + ok: output.ok || output + }; + } + }, + changePassword: { + description: 'Change your password based on a code', + resolverOf: 'plugins::users-permissions.auth.changePassword', + resolver: async (obj, options, { context }) => { + context.request.body = _.toPlainObject(options); + + await strapi.plugins['users-permissions'].controllers.auth.changePassword(context); + let output = context.body.toJSON ? context.body.toJSON() : context.body; + + checkBadRequest(output); + + return { + user: output.user || output, + jwt: output.jwt + }; + } + }, + emailConfirmation: { + description: 'Confirm an email users email address', + resolverOf: 'plugins::users-permissions.auth.emailConfirmation', + resolver: async (obj, options, { context }) => { + context.query = _.toPlainObject(options); + + await strapi.plugins['users-permissions'].controllers.auth.emailConfirmation(context, true); + let output = context.body.toJSON ? context.body.toJSON() : context.body; + + checkBadRequest(output); + + return { + user: output.user || output, + jwt: output.jwt + }; + } + } }, }, }; diff --git a/packages/strapi-plugin-users-permissions/controllers/Auth.js b/packages/strapi-plugin-users-permissions/controllers/Auth.js index 3aae9b4b44..cb0b5f1a4a 100644 --- a/packages/strapi-plugin-users-permissions/controllers/Auth.js +++ b/packages/strapi-plugin-users-permissions/controllers/Auth.js @@ -568,28 +568,39 @@ module.exports = { } }, - async emailConfirmation(ctx) { + async emailConfirmation(ctx, returnUser) { const params = ctx.query; const decodedToken = await strapi.plugins['users-permissions'].services.jwt.verify( params.confirmation ); - await strapi.plugins['users-permissions'].services.user.edit( + let user = await strapi.plugins['users-permissions'].services.user.edit( { id: decodedToken.id }, { confirmed: true } ); - const settings = await strapi - .store({ - environment: '', - type: 'plugin', - name: 'users-permissions', - key: 'advanced', - }) - .get(); + if(returnUser) { + ctx.send({ + jwt: strapi.plugins['users-permissions'].services.jwt.issue({ + id: user.id + }), + user: sanitizeEntity(user.toJSON ? user.toJSON() : user, { + model: strapi.query('user', 'users-permissions').model + }) + }); + } else { + const settings = await strapi + .store({ + environment: '', + type: 'plugin', + name: 'users-permissions', + key: 'advanced', + }) + .get(); - ctx.redirect(settings.email_confirmation_redirection || '/'); + ctx.redirect(settings.email_confirmation_redirection || '/'); + } }, async sendEmailConfirmation(ctx) { diff --git a/packages/strapi-provider-email-amazon-ses/lib/index.js b/packages/strapi-provider-email-amazon-ses/lib/index.js index ea375d4b71..bb9dc84a18 100644 --- a/packages/strapi-provider-email-amazon-ses/lib/index.js +++ b/packages/strapi-provider-email-amazon-ses/lib/index.js @@ -48,8 +48,8 @@ module.exports = { return new Promise((resolve, reject) => { // Default values. options = _.isObject(options) ? options : {}; - options.from = options.from || config.amazon_ses_default_from; - options.replyTo = options.replyTo || config.amazon_ses_default_replyto; + options.from = config.amazon_ses_default_from || options.from; + options.replyTo = config.amazon_ses_default_replyto || options.replyTo; options.text = options.text || options.html; options.html = options.html || options.text; diff --git a/packages/strapi-utils/lib/index.js b/packages/strapi-utils/lib/index.js index cd820c9f24..57ad61ca6e 100644 --- a/packages/strapi-utils/lib/index.js +++ b/packages/strapi-utils/lib/index.js @@ -15,6 +15,7 @@ const models = require('./models'); const policy = require('./policy'); const templateConfiguration = require('./templateConfiguration'); const { yup, formatYupErrors } = require('./validators'); +const { nameToSlug, nameToCollectionName } = require('./stringFormatting'); module.exports = { yup, @@ -29,4 +30,6 @@ module.exports = { parseMultipartData, sanitizeEntity, parseType, + nameToSlug, + nameToCollectionName, }; diff --git a/packages/strapi-utils/lib/stringFormatting.js b/packages/strapi-utils/lib/stringFormatting.js new file mode 100644 index 0000000000..425398abed --- /dev/null +++ b/packages/strapi-utils/lib/stringFormatting.js @@ -0,0 +1,12 @@ +'use strict'; + +const slugify = require('@sindresorhus/slugify'); + +const nameToSlug = name => slugify(name, { separator: '-' }); + +const nameToCollectionName = name => slugify(name, { separator: '_' }); + +module.exports = { + nameToSlug, + nameToCollectionName, +}; diff --git a/packages/strapi-utils/package.json b/packages/strapi-utils/package.json index 292aa5a806..34bef87b8e 100644 --- a/packages/strapi-utils/package.json +++ b/packages/strapi-utils/package.json @@ -14,6 +14,7 @@ }, "main": "./lib", "dependencies": { + "@sindresorhus/slugify": "^0.11.0", "date-fns": "^2.8.1", "lodash": "4.17.12", "pino": "^4.7.1", diff --git a/packages/strapi/lib/commands/generate.js b/packages/strapi/lib/commands/generate.js index 641fb2bb71..7866f02d99 100644 --- a/packages/strapi/lib/commands/generate.js +++ b/packages/strapi/lib/commands/generate.js @@ -56,14 +56,8 @@ module.exports = function(id, cliArguments) { if (scope.generatorType !== 'new') { logger.info( - 'Generated a new ' + - scope.generatorType + - ' `' + - scope.humanizeId + - '` at ' + - scope.humanizedPath + - '.' - ); // eslint-disable-line prefer-template + `Generated a new ${scope.generatorType} \`${scope.name}\` at \`${scope.filePath}\`.` + ); } process.exit(0); diff --git a/yarn.lock b/yarn.lock index fc14bc6e7a..6a74ba188a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2410,6 +2410,22 @@ escape-string-regexp "^1.0.5" lodash.deburr "^4.1.0" +"@sindresorhus/slugify@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/slugify/-/slugify-0.11.0.tgz#642acb99adefa4187285fd17de88745afc161de8" + integrity sha512-ECTZT6z1hYDsopRh8GECaQ5L6hoJHVd4uq5hPi8se9GB31tgtZfnlM8G64hZVhJNmtJ9eIK0SuNhtsaPQStXEQ== + dependencies: + "@sindresorhus/transliterate" "^0.1.0" + escape-string-regexp "^2.0.0" + +"@sindresorhus/transliterate@^0.1.0": + version "0.1.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/transliterate/-/transliterate-0.1.0.tgz#c063bfc4102783fb19c91c2f8c1efb3adfb754be" + integrity sha512-bO6v0M0EuJPjm5Ntfow4nk+r3EZQ41n0ahvAmh766FzPqlm6V/2uDc01vZI3gLeI/1lgV2BTMb6QvxOk9z73ng== + dependencies: + escape-string-regexp "^2.0.0" + lodash.deburr "^4.1.0" + "@snyk/cli-interface@1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@snyk/cli-interface/-/cli-interface-1.5.0.tgz#b9dbe6ebfb86e67ffabf29d4e0d28a52670ac456" @@ -6964,6 +6980,11 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + escodegen@1.8.x: version "1.8.1" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018"