refacto strapi-generate-* + move nameToSlug to strapi-utils

Signed-off-by: Pierre Noël <pierre.noel@strapi.io>
This commit is contained in:
Pierre Noël 2020-03-20 19:00:48 +01:00
parent 85e2dd5b53
commit be6517c02d
30 changed files with 99 additions and 112 deletions

View File

@ -11,6 +11,7 @@ const path = require('path');
// Public node modules. // Public node modules.
const _ = require('lodash'); const _ = require('lodash');
const pluralize = require('pluralize'); const pluralize = require('pluralize');
const { nameToSlug } = require('strapi-utils');
/** /**
* This `before` function is run before generating targets. * This `before` function is run before generating targets.
@ -26,7 +27,7 @@ module.exports = (scope, cb) => {
} }
// Format `id`. // Format `id`.
const name = scope.name || _.trim(_.camelCase(scope.id)); const name = scope.name || nameToSlug(scope.id);
const environment = process.env.NODE_ENV || 'development'; const environment = process.env.NODE_ENV || 'development';
scope.contentTypeKind = scope.args.kind || 'collectionType'; scope.contentTypeKind = scope.args.kind || 'collectionType';

View File

@ -14,7 +14,8 @@
}, },
"dependencies": { "dependencies": {
"lodash": "^4.17.11", "lodash": "^4.17.11",
"pluralize": "^7.0.0" "pluralize": "^7.0.0",
"strapi-utils": "^3.0.0-beta.19.3"
}, },
"scripts": { "scripts": {
"test": "echo \"no tests yet\"" "test": "echo \"no tests yet\""

View File

@ -6,6 +6,7 @@
// Public node modules. // Public node modules.
const _ = require('lodash'); const _ = require('lodash');
const { nameToSlug } = require('strapi-utils');
/* eslint-disable prefer-template */ /* eslint-disable prefer-template */
/** /**
* This `before` function is run before generating targets. * This `before` function is run before generating targets.
@ -23,7 +24,7 @@ module.exports = (scope, cb) => {
} }
// Format `id`. // Format `id`.
const name = scope.name || _.trim(_.camelCase(scope.id)); const name = scope.name || nameToSlug(scope.id);
// `scope.args` are the raw command line arguments. // `scope.args` are the raw command line arguments.
_.defaults(scope, { _.defaults(scope, {
@ -31,12 +32,6 @@ module.exports = (scope, cb) => {
api: scope.id, api: scope.id,
}); });
// Determine default values based on the available scope.
_.defaults(scope, {
globalID: _.upperFirst(_.camelCase(scope.id)),
ext: '.js',
});
// Determine the destination path. // Determine the destination path.
let filePath; let filePath;
if (scope.args.api) { if (scope.args.api) {
@ -53,7 +48,7 @@ module.exports = (scope, cb) => {
_.defaults(scope, { _.defaults(scope, {
rootPath: scope.rootPath, rootPath: scope.rootPath,
filePath, filePath,
filename: scope.globalID + scope.ext, filename: `${name}.js`,
}); });
// Trigger callback with no error to proceed. // Trigger callback with no error to proceed.

View File

@ -14,7 +14,8 @@
"lib": "./lib" "lib": "./lib"
}, },
"dependencies": { "dependencies": {
"lodash": "^4.17.11" "lodash": "^4.17.11",
"strapi-utils": "^3.0.0-beta.19.3"
}, },
"scripts": { "scripts": {
"test": "echo \"no tests yet\"" "test": "echo \"no tests yet\""

View File

@ -1,7 +1,7 @@
'use strict'; 'use strict';
/** /**
* A set of functions called "actions" for `<%= globalID %>` * A set of functions called "actions" for `<%= name %>`
*/ */
module.exports = { module.exports = {

View File

@ -11,6 +11,7 @@ const path = require('path');
// Public node modules. // Public node modules.
const _ = require('lodash'); const _ = require('lodash');
const pluralize = require('pluralize'); const pluralize = require('pluralize');
const { nameToSlug } = require('strapi-utils');
// Fetch stub attribute template on initial load. // Fetch stub attribute template on initial load.
const attributeTemplate = fs.readFileSync( const attributeTemplate = fs.readFileSync(
@ -35,7 +36,7 @@ module.exports = (scope, cb) => {
} }
// Format `id`. // Format `id`.
const name = scope.name || _.trim(_.camelCase(scope.id)); const name = scope.name || nameToSlug(scope.id);
// `scope.args` are the raw command line arguments. // `scope.args` are the raw command line arguments.
_.defaults(scope, { _.defaults(scope, {
@ -44,12 +45,6 @@ module.exports = (scope, cb) => {
environment: process.env.NODE_ENV || 'development', environment: process.env.NODE_ENV || 'development',
}); });
// Determine default values based on the available scope.
_.defaults(scope, {
globalID: _.upperFirst(name),
ext: '.js',
});
// Determine the destination path. // Determine the destination path.
let filePath; let filePath;
if (scope.args.api) { if (scope.args.api) {
@ -64,8 +59,8 @@ module.exports = (scope, cb) => {
_.defaults(scope, { _.defaults(scope, {
rootPath: scope.rootPath, rootPath: scope.rootPath,
filePath, filePath,
filename: scope.globalID + scope.ext, filename: `${name}.js`,
filenameSettings: scope.globalID + '.settings.json', filenameSettings: `${name}.settings.json`,
}); });
// Validate optional attribute arguments. // Validate optional attribute arguments.

View File

@ -15,7 +15,8 @@
}, },
"dependencies": { "dependencies": {
"lodash": "^4.17.11", "lodash": "^4.17.11",
"pluralize": "^7.0.0" "pluralize": "^7.0.0",
"strapi-utils": "^3.0.0-beta.19.3"
}, },
"scripts": { "scripts": {
"test": "echo \"no tests yet\"" "test": "echo \"no tests yet\""

View File

@ -1,7 +1,7 @@
'use strict'; 'use strict';
/** /**
* Lifecycle callbacks for the `<%= globalID %>` model. * Lifecycle callbacks for the `<%= name %>` model.
*/ */
module.exports = { module.exports = {

View File

@ -1,7 +1,7 @@
'use strict'; 'use strict';
/** /**
* Lifecycle callbacks for the `<%= globalID %>` model. * Lifecycle callbacks for the `<%= name %>` model.
*/ */
module.exports = { module.exports = {

View File

@ -7,14 +7,16 @@
module.exports = scope => { module.exports = scope => {
function generateRoutes() { function generateRoutes() {
return { return {
routes: [{ routes: [
method: 'GET', {
path: '/', method: 'GET',
handler: scope.globalID + '.index', path: '/',
config: { handler: scope.name + '.index',
policies: [] config: {
} policies: [],
}] },
},
],
}; };
} }

View File

@ -8,6 +8,7 @@
const path = require('path'); const path = require('path');
const fs = require('fs-extra'); const fs = require('fs-extra');
const _ = require('lodash'); const _ = require('lodash');
const { nameToSlug } = require('strapi-utils');
/** /**
* This `before` function is run before generating targets. * This `before` function is run before generating targets.
@ -23,13 +24,7 @@ module.exports = (scope, cb) => {
} }
// Format `id`. // Format `id`.
const name = scope.name || _.trim(_.camelCase(scope.id)); const name = scope.name || nameToSlug(scope.id);
// Determine default values based on the available scope.
_.defaults(scope, {
globalID: _.upperFirst(name),
ext: '.js',
});
// Plugin info. // Plugin info.
_.defaults(scope, { _.defaults(scope, {
@ -42,7 +37,7 @@ module.exports = (scope, cb) => {
// Take another pass to take advantage of the defaults absorbed in previous passes. // Take another pass to take advantage of the defaults absorbed in previous passes.
_.defaults(scope, { _.defaults(scope, {
filename: `${scope.globalID}${scope.ext}`, filename: `${name}.js`,
filePath: './plugins', filePath: './plugins',
}); });

View File

@ -14,7 +14,8 @@
}, },
"dependencies": { "dependencies": {
"fs-extra": "^8.0.1", "fs-extra": "^8.0.1",
"lodash": "^4.17.11" "lodash": "^4.17.11",
"strapi-utils": "^3.0.0-beta.19.3"
}, },
"scripts": { "scripts": {
"test": "echo \"no tests yet\"" "test": "echo \"no tests yet\""

View File

@ -6,6 +6,7 @@
// Public node modules. // Public node modules.
const _ = require('lodash'); const _ = require('lodash');
const { nameToSlug } = require('strapi-utils');
/** /**
* This `before` function is run before generating targets. * This `before` function is run before generating targets.
@ -24,7 +25,7 @@ module.exports = (scope, cb) => {
} }
// Format `id`. // Format `id`.
const name = scope.name || _.trim(_.camelCase(scope.id)); const name = scope.name || nameToSlug(scope.id);
let filePath; let filePath;
if (scope.args.api) { if (scope.args.api) {
@ -35,16 +36,11 @@ module.exports = (scope, cb) => {
filePath = './config/policies'; 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. // Take another pass to take advantage of the defaults absorbed in previous passes.
_.defaults(scope, { _.defaults(scope, {
name, name,
filePath, filePath,
filename: name + scope.ext, filename: `${name}.js`,
}); });
// Trigger callback with no error to proceed. // Trigger callback with no error to proceed.

View File

@ -14,7 +14,8 @@
"lib": "./lib" "lib": "./lib"
}, },
"dependencies": { "dependencies": {
"lodash": "^4.17.11" "lodash": "^4.17.11",
"strapi-utils": "^3.0.0-beta.19.3"
}, },
"scripts": { "scripts": {
"test": "echo \"no tests yet\"" "test": "echo \"no tests yet\""

View File

@ -6,6 +6,7 @@
// Public node modules. // Public node modules.
const _ = require('lodash'); const _ = require('lodash');
const { nameToSlug } = require('strapi-utils');
/** /**
* This `before` function is run before generating targets. * This `before` function is run before generating targets.
@ -24,7 +25,7 @@ module.exports = (scope, cb) => {
} }
// Format `id`. // Format `id`.
const name = scope.name || _.trim(_.camelCase(scope.id)); const name = scope.name || nameToSlug(scope.id);
// `scope.args` are the raw command line arguments. // `scope.args` are the raw command line arguments.
_.defaults(scope, { _.defaults(scope, {
@ -32,12 +33,6 @@ module.exports = (scope, cb) => {
api: scope.args.api || scope.id, api: scope.args.api || scope.id,
}); });
// Determine default values based on the available scope.
_.defaults(scope, {
globalID: _.upperFirst(name),
ext: '.js',
});
// Determine the destination path. // Determine the destination path.
let filePath; let filePath;
if (scope.args.api) { if (scope.args.api) {
@ -52,7 +47,7 @@ module.exports = (scope, cb) => {
_.defaults(scope, { _.defaults(scope, {
rootPath: scope.rootPath, rootPath: scope.rootPath,
filePath, filePath,
filename: scope.globalID + scope.ext, filename: `${name}.js`,
}); });
// Trigger callback with no error to proceed. // Trigger callback with no error to proceed.

View File

@ -14,7 +14,8 @@
"lib": "./lib" "lib": "./lib"
}, },
"dependencies": { "dependencies": {
"lodash": "^4.17.11" "lodash": "^4.17.11",
"strapi-utils": "^3.0.0-beta.19.3"
}, },
"scripts": { "scripts": {
"test": "echo \"no tests yet\"" "test": "echo \"no tests yet\""

View File

@ -1,7 +1,7 @@
'use strict'; 'use strict';
/** /**
* `<%= globalID %>` service. * `<%= name %>` service.
*/ */
module.exports = { module.exports = {

View File

@ -1,7 +1,7 @@
'use strict'; 'use strict';
/** /**
* `<%= globalID %>` service. * `<%= name %>` service.
*/ */
module.exports = { module.exports = {

View File

@ -1,6 +1,4 @@
import slugify from '@sindresorhus/slugify'; import { nameToSlug } from 'strapi-utils';
const nameToSlug = name => slugify(name, { separator: '-' });
const createUid = name => { const createUid = name => {
const modelName = nameToSlug(name); const modelName = nameToSlug(name);
@ -14,4 +12,4 @@ const createComponentUid = (name, category) => {
return `${nameToSlug(category)}.${nameToSlug(name)}`; return `${nameToSlug(category)}.${nameToSlug(name)}`;
}; };
export { createComponentUid, createUid, nameToSlug }; export { createComponentUid, createUid };

View File

@ -3,9 +3,10 @@ import * as yup from 'yup';
import { get, isEmpty, toLower, trim, toNumber } from 'lodash'; import { get, isEmpty, toLower, trim, toNumber } from 'lodash';
import { translatedErrors as errorsTrads } from 'strapi-helper-plugin'; import { translatedErrors as errorsTrads } from 'strapi-helper-plugin';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import { nameToSlug } from 'strapi-utils';
import pluginId from '../../../pluginId'; import pluginId from '../../../pluginId';
import getTrad from '../../../utils/getTrad'; import getTrad from '../../../utils/getTrad';
import { createComponentUid, createUid, nameToSlug } from './createUid'; import { createComponentUid, createUid } from './createUid';
import componentForm from './componentForm'; import componentForm from './componentForm';
import fields from './staticFields'; import fields from './staticFields';
import { NAME_REGEX, ENUM_REGEX, CATEGORY_NAME_REGEX } from './attributesRegexes'; import { NAME_REGEX, ENUM_REGEX, CATEGORY_NAME_REGEX } from './attributesRegexes';

View File

@ -8,7 +8,6 @@
"description": "content-type-builder.plugin.description" "description": "content-type-builder.plugin.description"
}, },
"dependencies": { "dependencies": {
"@sindresorhus/slugify": "0.9.1",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"fs-extra": "^7.0.0", "fs-extra": "^7.0.0",
"immutable": "^3.8.2", "immutable": "^3.8.2",

View File

@ -2,7 +2,7 @@
const { join } = require('path'); const { join } = require('path');
const { nameToSlug } = require('../utils/helpers'); const { nameToSlug } = require('strapi-utils');
const createBuilder = require('./schema-builder'); const createBuilder = require('./schema-builder');
/** /**

View File

@ -7,7 +7,7 @@ const generator = require('strapi-generate');
const createBuilder = require('./schema-builder'); const createBuilder = require('./schema-builder');
const apiHandler = require('./api-handler'); const apiHandler = require('./api-handler');
const { formatAttributes, replaceTemporaryUIDs } = require('../utils/attributes'); 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 * Format a contentType info to be used by the front-end

View File

@ -5,7 +5,7 @@ const _ = require('lodash');
const pluralize = require('pluralize'); const pluralize = require('pluralize');
const { isConfigurable } = require('../../utils/attributes'); const { isConfigurable } = require('../../utils/attributes');
const { nameToSlug, nameToCollectionName } = require('../../utils/helpers'); const { nameToSlug, nameToCollectionName } = require('strapi-utils');
const createSchemaHandler = require('./schema-handler'); const createSchemaHandler = require('./schema-handler');
module.exports = function createComponentBuilder() { module.exports = function createComponentBuilder() {

View File

@ -5,7 +5,7 @@ const _ = require('lodash');
const pluralize = require('pluralize'); const pluralize = require('pluralize');
const { isRelation, toUID, isConfigurable } = require('../../utils/attributes'); 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 { typeKinds } = require('../../controllers/validation/constants');
const createSchemaHandler = require('./schema-handler'); const createSchemaHandler = require('./schema-handler');
@ -69,9 +69,7 @@ module.exports = function createComponentBuilder() {
'default' 'default'
); );
const defaultCollectionName = `${nameToCollectionName( const defaultCollectionName = `${nameToCollectionName(pluralize(infos.name))}`;
pluralize(infos.name)
)}`;
// support self referencing content type relation // support self referencing content type relation
Object.keys(infos.attributes).forEach(key => { Object.keys(infos.attributes).forEach(key => {
@ -125,31 +123,18 @@ module.exports = function createComponentBuilder() {
return _.has(oldAttributes, key) && !isConfigurable(oldAttributes[key]); return _.has(oldAttributes, key) && !isConfigurable(oldAttributes[key]);
}); });
const newKeys = _.difference( const newKeys = _.difference(Object.keys(newAttributes), Object.keys(oldAttributes));
Object.keys(newAttributes),
Object.keys(oldAttributes)
);
const deletedKeys = _.difference( const deletedKeys = _.difference(Object.keys(oldAttributes), Object.keys(newAttributes));
Object.keys(oldAttributes),
Object.keys(newAttributes)
);
const remainingKeys = _.intersection( const remainingKeys = _.intersection(Object.keys(oldAttributes), Object.keys(newAttributes));
Object.keys(oldAttributes),
Object.keys(newAttributes)
);
// remove old relations // remove old relations
deletedKeys.forEach(key => { deletedKeys.forEach(key => {
const attribute = oldAttributes[key]; const attribute = oldAttributes[key];
// if the old relation has a target attribute. we need to remove it // if the old relation has a target attribute. we need to remove it
if ( if (isConfigurable(attribute) && isRelation(attribute) && _.has(attribute, 'via')) {
isConfigurable(attribute) &&
isRelation(attribute) &&
_.has(attribute, 'via')
) {
this.unsetRelation(attribute); this.unsetRelation(attribute);
} }
}); });
@ -172,15 +157,11 @@ module.exports = function createComponentBuilder() {
} }
if (isRelation(oldAttribute) && isRelation(newAttribute)) { if (isRelation(oldAttribute) && isRelation(newAttribute)) {
if ( if (_.has(oldAttribute, 'via') && oldAttribute.via !== newAttribute.targetAttribute) {
_.has(oldAttribute, 'via') &&
oldAttribute.via !== newAttribute.targetAttribute
) {
this.unsetRelation(oldAttribute); this.unsetRelation(oldAttribute);
} }
newAttribute.autoPopulate = newAttribute.autoPopulate = newAttribute.autoPopulate || oldAttribute.autoPopulate;
newAttribute.autoPopulate || oldAttribute.autoPopulate;
return this.setRelation({ return this.setRelation({
key, key,
@ -239,16 +220,9 @@ module.exports = function createComponentBuilder() {
* @param {Object} options options * @param {Object} options options
* @param {string} options.name component name * @param {string} options.name component name
*/ */
const createContentTypeUID = ({ name }) => const createContentTypeUID = ({ name }) => `application::${nameToSlug(name)}.${nameToSlug(name)}`;
`application::${nameToSlug(name)}.${nameToSlug(name)}`;
const generateRelation = ({ const generateRelation = ({ key, attribute, plugin, modelName, targetAttribute = {} }) => {
key,
attribute,
plugin,
modelName,
targetAttribute = {},
}) => {
const opts = { const opts = {
via: key, via: key,
plugin, plugin,

View File

@ -1,7 +1,5 @@
'use strict'; 'use strict';
const slugify = require('@sindresorhus/slugify');
const escapeNewlines = (content = '', placeholder = '\n') => { const escapeNewlines = (content = '', placeholder = '\n') => {
return content.replace(/[\r\n]+/g, placeholder); return content.replace(/[\r\n]+/g, placeholder);
}; };
@ -26,13 +24,8 @@ const deepTrimObject = attribute => {
* Converts a name to a slug * Converts a name to a slug
* @param {string} name a name to convert * @param {string} name a name to convert
*/ */
const nameToSlug = name => slugify(name, { separator: '-' });
const nameToCollectionName = name => slugify(name, { separator: '_' });
module.exports = { module.exports = {
escapeNewlines, escapeNewlines,
deepTrimObject, deepTrimObject,
nameToSlug,
nameToCollectionName,
}; };

View File

@ -15,6 +15,7 @@ const models = require('./models');
const policy = require('./policy'); const policy = require('./policy');
const templateConfiguration = require('./templateConfiguration'); const templateConfiguration = require('./templateConfiguration');
const { yup, formatYupErrors } = require('./validators'); const { yup, formatYupErrors } = require('./validators');
const { nameToSlug, nameToCollectionName } = require('./stringFormatting');
module.exports = { module.exports = {
yup, yup,
@ -29,4 +30,6 @@ module.exports = {
parseMultipartData, parseMultipartData,
sanitizeEntity, sanitizeEntity,
parseType, parseType,
nameToSlug,
nameToCollectionName,
}; };

View File

@ -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,
};

View File

@ -14,6 +14,7 @@
}, },
"main": "./lib", "main": "./lib",
"dependencies": { "dependencies": {
"@sindresorhus/slugify": "^0.11.0",
"date-fns": "^2.8.1", "date-fns": "^2.8.1",
"lodash": "4.17.12", "lodash": "4.17.12",
"pino": "^4.7.1", "pino": "^4.7.1",

View File

@ -2408,6 +2408,22 @@
escape-string-regexp "^1.0.5" escape-string-regexp "^1.0.5"
lodash.deburr "^4.1.0" 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": "@snyk/cli-interface@1.5.0":
version "1.5.0" version "1.5.0"
resolved "https://registry.yarnpkg.com/@snyk/cli-interface/-/cli-interface-1.5.0.tgz#b9dbe6ebfb86e67ffabf29d4e0d28a52670ac456" resolved "https://registry.yarnpkg.com/@snyk/cli-interface/-/cli-interface-1.5.0.tgz#b9dbe6ebfb86e67ffabf29d4e0d28a52670ac456"
@ -6943,6 +6959,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" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= 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: escodegen@1.8.x:
version "1.8.1" version "1.8.1"
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018"