chore(@strapi/strapi): build strapi core with pack-up

This commit is contained in:
Alexandre Bodin 2023-10-12 21:18:18 +02:00
parent a3d88f6f1d
commit 477ebe1b30
85 changed files with 202 additions and 204 deletions

View File

@ -34,7 +34,7 @@ describe('Role CRUD End to End', () => {
sortedData.conditions = sortedData.conditions.sort(); sortedData.conditions = sortedData.conditions.sort();
// eslint-disable-next-line node/no-extraneous-require // eslint-disable-next-line node/no-extraneous-require
const { features } = require('@strapi/strapi/dist/utils/ee').default; const { features } = require('@strapi/strapi/dist/utils/ee');
const hasSSO = features.isEnabled('sso'); const hasSSO = features.isEnabled('sso');
if (hasSSO) { if (hasSSO) {

View File

@ -54,7 +54,7 @@ describeOnCondition(edition === 'EE')('Provider Login', () => {
strapi = await createStrapiInstance(); strapi = await createStrapiInstance();
utils = createUtils(strapi); utils = createUtils(strapi);
// eslint-disable-next-line node/no-extraneous-require // eslint-disable-next-line node/no-extraneous-require
hasSSO = require('@strapi/strapi/dist/utils/ee').default.features.isEnabled('sso'); hasSSO = require('@strapi/strapi/dist/utils/ee').features.isEnabled('sso');
await createFixtures(); await createFixtures();

View File

@ -54,7 +54,7 @@ describeOnCondition(edition === 'EE')('SSO Provider Options', () => {
strapi = await createStrapiInstance(); strapi = await createStrapiInstance();
utils = createUtils(strapi); utils = createUtils(strapi);
// eslint-disable-next-line node/no-extraneous-require // eslint-disable-next-line node/no-extraneous-require
hasSSO = require('@strapi/strapi/dist/utils/ee').default.features.isEnabled('sso'); hasSSO = require('@strapi/strapi/dist/utils/ee').features.isEnabled('sso');
await createFixtures(); await createFixtures();

View File

@ -95,7 +95,7 @@ describeOnCondition(edition === 'EE')('Review workflows', () => {
beforeAll(async () => { beforeAll(async () => {
await builder.addContentTypes([model]).build(); await builder.addContentTypes([model]).build();
// eslint-disable-next-line node/no-extraneous-require // eslint-disable-next-line node/no-extraneous-require
hasRW = require('@strapi/strapi/dist/utils/ee').default.features.isEnabled('review-workflows'); hasRW = require('@strapi/strapi/dist/utils/ee').features.isEnabled('review-workflows');
strapi = await createStrapiInstance({ bypassAuth: false }); strapi = await createStrapiInstance({ bypassAuth: false });
requests.admin = await createAuthRequest({ strapi }); requests.admin = await createAuthRequest({ strapi });

View File

@ -1,7 +1,7 @@
'use strict'; 'use strict';
// eslint-disable-next-line node/no-extraneous-require // eslint-disable-next-line node/no-extraneous-require
const { features } = require('@strapi/strapi/dist/utils/ee').default; const { features } = require('@strapi/strapi/dist/utils/ee');
const executeCEBootstrap = require('../../server/bootstrap'); const executeCEBootstrap = require('../../server/bootstrap');
const { getService } = require('../../server/utils'); const { getService } = require('../../server/utils');
const actions = require('./config/admin-actions'); const actions = require('./config/admin-actions');

View File

@ -2,7 +2,7 @@
const { isNil } = require('lodash/fp'); const { isNil } = require('lodash/fp');
// eslint-disable-next-line node/no-extraneous-require // eslint-disable-next-line node/no-extraneous-require
const ee = require('@strapi/strapi/dist/utils/ee').default; const ee = require('@strapi/strapi/dist/utils/ee');
const { env } = require('@strapi/utils'); const { env } = require('@strapi/utils');
const { getService } = require('../../../server/utils'); const { getService } = require('../../../server/utils');

View File

@ -1,7 +1,7 @@
'use strict'; 'use strict';
// eslint-disable-next-line node/no-extraneous-require // eslint-disable-next-line node/no-extraneous-require
const ee = require('@strapi/strapi/dist/utils/ee').default; const ee = require('@strapi/strapi/dist/utils/ee');
const _ = require('lodash'); const _ = require('lodash');
const { pick, isNil } = require('lodash/fp'); const { pick, isNil } = require('lodash/fp');
const { ApplicationError, ForbiddenError } = require('@strapi/utils').errors; const { ApplicationError, ForbiddenError } = require('@strapi/utils').errors;

View File

@ -1,6 +1,6 @@
'use strict'; 'use strict';
const { features } = require('@strapi/strapi/dist/utils/ee').default; const { features } = require('@strapi/strapi/dist/utils/ee');
const executeCEDestroy = require('../../server/destroy'); const executeCEDestroy = require('../../server/destroy');
module.exports = async ({ strapi }) => { module.exports = async ({ strapi }) => {

View File

@ -1,6 +1,6 @@
'use strict'; 'use strict';
const { features } = require('@strapi/strapi/dist/utils/ee').default; const { features } = require('@strapi/strapi/dist/utils/ee');
const executeCERegister = require('../../server/register'); const executeCERegister = require('../../server/register');
const migrateAuditLogsTable = require('./migrations/audit-logs-table'); const migrateAuditLogsTable = require('./migrations/audit-logs-table');
const migrateReviewWorkflowStagesColor = require('./migrations/review-workflows-stages-color'); const migrateReviewWorkflowStagesColor = require('./migrations/review-workflows-stages-color');

View File

@ -1,6 +1,6 @@
'use strict'; 'use strict';
const { features } = require('@strapi/strapi/dist/utils/ee').default; const { features } = require('@strapi/strapi/dist/utils/ee');
const enableFeatureMiddleware = (featureName) => (ctx, next) => { const enableFeatureMiddleware = (featureName) => (ctx, next) => {
if (features.isEnabled(featureName)) { if (features.isEnabled(featureName)) {

View File

@ -4,14 +4,12 @@ jest.mock('@strapi/strapi/dist/utils/ee', () => {
const eeModule = () => true; const eeModule = () => true;
Object.assign(eeModule, { Object.assign(eeModule, {
default: { features: {
features: { isEnabled() {
isEnabled() { return true;
return true; },
}, getEnabled() {
getEnabled() { return ['review-workflows'];
return ['review-workflows'];
},
}, },
}, },
}); });

View File

@ -1,10 +1,10 @@
'use strict'; 'use strict';
const { features } = require('@strapi/strapi/dist/utils/ee').default; const { features } = require('@strapi/strapi/dist/utils/ee');
const { register } = require('@strapi/provider-audit-logs-local'); const { register } = require('@strapi/provider-audit-logs-local');
const { scheduleJob } = require('node-schedule'); const { scheduleJob } = require('node-schedule');
const createAuditLogsService = require('../audit-logs'); const createAuditLogsService = require('../audit-logs');
const createEventHub = require('../../../../../strapi/dist/services/event-hub').default; const createEventHub = require('../../../../../strapi/dist/services/event-hub');
jest.mock('../../../../server/register'); jest.mock('../../../../server/register');
@ -13,11 +13,9 @@ jest.mock('../../utils', () => ({
})); }));
jest.mock('@strapi/strapi/dist/utils/ee', () => ({ jest.mock('@strapi/strapi/dist/utils/ee', () => ({
default: { features: {
features: { isEnabled: jest.fn(),
isEnabled: jest.fn(), get: jest.fn(),
get: jest.fn(),
},
}, },
})); }));

View File

@ -20,11 +20,9 @@ describe('Passport', () => {
describe('Init (SSO disabled)', () => { describe('Init (SSO disabled)', () => {
beforeAll(() => { beforeAll(() => {
jest.mock('@strapi/strapi/dist/utils/ee', () => ({ jest.mock('@strapi/strapi/dist/utils/ee', () => ({
default: { features: {
features: { // Disable the SSO feature
// Disable the SSO feature isEnabled: (feature) => feature !== 'sso',
isEnabled: (feature) => feature !== 'sso',
},
}, },
})); }));
}); });
@ -60,11 +58,9 @@ describe('Passport', () => {
describe('Init (SSO enabled)', () => { describe('Init (SSO enabled)', () => {
beforeAll(() => { beforeAll(() => {
jest.mock('@strapi/strapi/dist/utils/ee', () => ({ jest.mock('@strapi/strapi/dist/utils/ee', () => ({
default: { features: {
features: { // Enable all the features (including SSO)
// Enable all the features (including SSO) isEnabled: () => true,
isEnabled: () => true,
},
}, },
})); }));
}); });

View File

@ -4,14 +4,12 @@ jest.mock('@strapi/strapi/dist/utils/ee', () => {
const eeModule = () => true; const eeModule = () => true;
Object.assign(eeModule, { Object.assign(eeModule, {
default: { features: {
features: { isEnabled() {
isEnabled() { return true;
return true; },
}, getEnabled() {
getEnabled() { return ['review-workflows'];
return ['review-workflows'];
},
}, },
}, },
}); });

View File

@ -1,14 +1,12 @@
'use strict'; 'use strict';
jest.mock('@strapi/strapi/dist/utils/ee', () => ({ jest.mock('@strapi/strapi/dist/utils/ee', () => ({
default: { features: {
features: { isEnabled() {
isEnabled() { return true;
return true; },
}, list() {
list() { return [{ name: 'sso' }];
return [{ name: 'sso' }];
},
}, },
}, },
})); }));

View File

@ -4,14 +4,12 @@ jest.mock('@strapi/strapi/dist/utils/ee', () => {
const eeModule = () => true; const eeModule = () => true;
Object.assign(eeModule, { Object.assign(eeModule, {
default: { features: {
features: { isEnabled() {
isEnabled() { return true;
return true; },
}, getEnabled() {
getEnabled() { return ['review-workflows'];
return ['review-workflows'];
},
}, },
}, },
}); });

View File

@ -4,14 +4,12 @@ jest.mock('@strapi/strapi/dist/utils/ee', () => {
const eeModule = () => true; const eeModule = () => true;
Object.assign(eeModule, { Object.assign(eeModule, {
default: { features: {
features: { isEnabled() {
isEnabled() { return true;
return true; },
}, getEnabled() {
getEnabled() { return ['review-workflows'];
return ['review-workflows'];
},
}, },
}, },
}); });

View File

@ -2,7 +2,7 @@
const localProvider = require('@strapi/provider-audit-logs-local'); const localProvider = require('@strapi/provider-audit-logs-local');
const { scheduleJob } = require('node-schedule'); const { scheduleJob } = require('node-schedule');
const { features } = require('@strapi/strapi/dist/utils/ee').default; const { features } = require('@strapi/strapi/dist/utils/ee');
const DEFAULT_RETENTION_DAYS = 90; const DEFAULT_RETENTION_DAYS = 90;

View File

@ -1,7 +1,7 @@
'use strict'; 'use strict';
// eslint-disable-next-line node/no-extraneous-require // eslint-disable-next-line node/no-extraneous-require
const { features } = require('@strapi/strapi/dist/utils/ee').default; const { features } = require('@strapi/strapi/dist/utils/ee');
const { UnauthorizedError } = require('@strapi/utils').errors; const { UnauthorizedError } = require('@strapi/utils').errors;
const createLocalStrategy = require('../../../server/services/passport/local-strategy'); const createLocalStrategy = require('../../../server/services/passport/local-strategy');

View File

@ -1,6 +1,6 @@
'use strict'; 'use strict';
const ee = require('@strapi/strapi/dist/utils/ee').default; const ee = require('@strapi/strapi/dist/utils/ee');
const { authEventsMapper } = require('../../../../server/services/passport'); const { authEventsMapper } = require('../../../../server/services/passport');
const createProviderRegistry = require('./provider-registry'); const createProviderRegistry = require('./provider-registry');

View File

@ -1,7 +1,7 @@
'use strict'; 'use strict';
// eslint-disable-next-line node/no-extraneous-require // eslint-disable-next-line node/no-extraneous-require
const ee = require('@strapi/strapi/dist/utils/ee').default; const ee = require('@strapi/strapi/dist/utils/ee');
const { take, drop, map, prop, pick, reverse, isNil } = require('lodash/fp'); const { take, drop, map, prop, pick, reverse, isNil } = require('lodash/fp');
const { getService } = require('../../../server/utils'); const { getService } = require('../../../server/utils');
const { SUPER_ADMIN_CODE } = require('../../../server/services/constants'); const { SUPER_ADMIN_CODE } = require('../../../server/services/constants');

View File

@ -7,11 +7,9 @@ let ssoEnabled = true;
jest.mock('@strapi/strapi/dist/utils/ee', () => { jest.mock('@strapi/strapi/dist/utils/ee', () => {
return { return {
default: { features: {
features: { isEnabled() {
isEnabled() { return ssoEnabled;
return ssoEnabled;
},
}, },
}, },
}; };

View File

@ -1,6 +1,6 @@
'use strict'; 'use strict';
const { features } = require('@strapi/strapi/dist/utils/ee').default; const { features } = require('@strapi/strapi/dist/utils/ee');
const { isEmpty } = require('lodash/fp'); const { isEmpty } = require('lodash/fp');
const isSsoLocked = async (user) => { const isSsoLocked = async (user) => {

View File

@ -2,7 +2,7 @@
const { yup, validateYupSchema } = require('@strapi/utils'); const { yup, validateYupSchema } = require('@strapi/utils');
// eslint-disable-next-line node/no-extraneous-require // eslint-disable-next-line node/no-extraneous-require
const { features } = require('@strapi/strapi/dist/utils/ee').default; const { features } = require('@strapi/strapi/dist/utils/ee');
const roleCreateSchema = yup const roleCreateSchema = yup
.object() .object()

View File

@ -2,7 +2,7 @@
const { yup, validateYupSchema } = require('@strapi/utils'); const { yup, validateYupSchema } = require('@strapi/utils');
// eslint-disable-next-line node/no-extraneous-require // eslint-disable-next-line node/no-extraneous-require
const { features } = require('@strapi/strapi/dist/utils/ee').default; const { features } = require('@strapi/strapi/dist/utils/ee');
const { schemas } = require('../../../server/validation/user'); const { schemas } = require('../../../server/validation/user');
const ssoUserCreationInputExtension = yup const ssoUserCreationInputExtension = yup

View File

@ -4,14 +4,12 @@ jest.mock('@strapi/strapi/dist/utils/ee', () => {
const eeModule = () => false; const eeModule = () => false;
Object.assign(eeModule, { Object.assign(eeModule, {
default: { features: {
features: { isEnabled() {
isEnabled() { return false;
return false; },
}, list() {
list() { return [];
return [];
},
}, },
}, },
}); });

View File

@ -8,7 +8,7 @@ const { exists } = require('fs-extra');
const { env } = require('@strapi/utils'); const { env } = require('@strapi/utils');
const { isUsingTypeScript } = require('@strapi/typescript-utils'); const { isUsingTypeScript } = require('@strapi/typescript-utils');
// eslint-disable-next-line node/no-extraneous-require // eslint-disable-next-line node/no-extraneous-require
const ee = require('@strapi/strapi/dist/utils/ee').default; const ee = require('@strapi/strapi/dist/utils/ee');
const { const {
validateUpdateProjectSettings, validateUpdateProjectSettings,

View File

@ -4,7 +4,7 @@ const _ = require('lodash');
const { merge } = require('lodash/fp'); const { merge } = require('lodash/fp');
const permissionService = require('../permission'); const permissionService = require('../permission');
const { toPermission } = require('../../domain/permission'); const { toPermission } = require('../../domain/permission');
const createEventHub = require('../../../../strapi/dist/services/event-hub').default; const createEventHub = require('../../../../strapi/dist/services/event-hub');
describe('Permission Service', () => { describe('Permission Service', () => {
beforeEach(() => { beforeEach(() => {

View File

@ -4,7 +4,7 @@ const _ = require('lodash');
const roleService = require('../role'); const roleService = require('../role');
const { SUPER_ADMIN_CODE } = require('../constants'); const { SUPER_ADMIN_CODE } = require('../constants');
const { create: createPermission, toPermission } = require('../../domain/permission'); const { create: createPermission, toPermission } = require('../../domain/permission');
const createEventHub = require('../../../../strapi/dist/services/event-hub').default; const createEventHub = require('../../../../strapi/dist/services/event-hub');
describe('Role', () => { describe('Role', () => {
describe('create', () => { describe('create', () => {

View File

@ -1,7 +1,2 @@
#!/usr/bin/env node #!/usr/bin/env node
require('../dist/cli');
'use strict';
const { runStrapiCommand } = require('../dist/commands');
runStrapiCommand(process.argv);

View File

@ -1,5 +0,0 @@
const strapi = require('./dist');
module.exports = strapi.default;
module.exports.factories = strapi.factories;
module.exports.compile = strapi.compile;

View File

@ -64,7 +64,9 @@
"url": "https://strapi.io" "url": "https://strapi.io"
} }
], ],
"main": "./index.js", "main": "./dist/index.js",
"module": "./dist/index.mjs",
"source": "./src/index.ts",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
"bin": "./bin/strapi.js", "bin": "./bin/strapi.js",
"files": [ "files": [
@ -75,16 +77,14 @@
"index.js" "index.js"
], ],
"scripts": { "scripts": {
"build": "run -T tsc -p tsconfig.build.json && run copy-files", "build": "run pack-up build && run copy-files",
"build:ts": "run build",
"clean": "run -T rimraf ./dist",
"copy-files": "copyfiles -u 1 -a 'src/**/*.html' 'src/**/*.png' dist", "copy-files": "copyfiles -u 1 -a 'src/**/*.html' 'src/**/*.png' dist",
"postinstall": "node ./scripts/postinstall.js", "postinstall": "node ./scripts/postinstall.js",
"lint": "run -T eslint .", "lint": "run -T eslint .",
"prepublishOnly": "yarn clean && yarn build", "prepublishOnly": "yarn clean && yarn build",
"test:unit": "run -T jest", "test:unit": "run -T jest",
"test:unit:watch": "run -T jest --watch", "test:unit:watch": "run -T jest --watch",
"watch": "run -T tsc -p tsconfig.build.json -w --preserveWatchOutput" "watch": "pack-up watch"
}, },
"dependencies": { "dependencies": {
"@koa/cors": "3.4.3", "@koa/cors": "3.4.3",
@ -142,7 +142,6 @@
"ora": "5.4.1", "ora": "5.4.1",
"package-json": "7.0.0", "package-json": "7.0.0",
"qs": "6.11.1", "qs": "6.11.1",
"resolve-cwd": "3.0.0",
"semver": "7.5.4", "semver": "7.5.4",
"statuses": "2.0.1", "statuses": "2.0.1",
"typescript": "5.2.2", "typescript": "5.2.2",
@ -150,6 +149,7 @@
"yup": "0.32.9" "yup": "0.32.9"
}, },
"devDependencies": { "devDependencies": {
"@strapi/pack-up": "workspace:*",
"@strapi/ts-zen": "^0.2.0", "@strapi/ts-zen": "^0.2.0",
"@types/bcryptjs": "2.4.3", "@types/bcryptjs": "2.4.3",
"@types/configstore": "5.0.1", "@types/configstore": "5.0.1",

View File

@ -0,0 +1,16 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import { defineConfig } from '@strapi/pack-up';
import { builtinModules } from 'node:module';
export default defineConfig({
bundles: [
{
source: './src/cli.ts',
require: './dist/cli.js',
runtime: 'node',
},
],
externals: [...builtinModules],
preserveModules: true,
runtime: 'node',
});

View File

@ -0,0 +1,3 @@
import { runStrapiCommand } from './commands';
runStrapiCommand(process.argv);

View File

@ -25,7 +25,7 @@ const mock = {
admin, admin,
}; };
jest.mock('../../../../../index', () => { jest.mock('../../../../../Strapi', () => {
const impl: any = jest.fn(() => mock); const impl: any = jest.fn(() => mock);
impl.compile = jest.fn(); impl.compile = jest.fn();

View File

@ -1,7 +1,7 @@
import { yup } from '@strapi/utils'; import { yup } from '@strapi/utils';
import _ from 'lodash'; import _ from 'lodash';
import inquirer from 'inquirer'; import inquirer from 'inquirer';
import strapi from '../../../../index'; import strapi from '../../../../Strapi';
interface CmdOptions { interface CmdOptions {
email?: string; email?: string;

View File

@ -1,5 +1,6 @@
import { getLocalScript } from '../../../utils/helpers'; import { runAction } from '../../../utils/helpers';
import type { StrapiCommand } from '../../../types'; import type { StrapiCommand } from '../../../types';
import action from './action';
/** /**
* `$ strapi admin:create-user` * `$ strapi admin:create-user`
@ -13,7 +14,7 @@ const command: StrapiCommand = ({ command }) => {
.option('-p, --password <password>', 'Password of the new admin') .option('-p, --password <password>', 'Password of the new admin')
.option('-f, --firstname <first name>', 'First name of the new admin') .option('-f, --firstname <first name>', 'First name of the new admin')
.option('-l, --lastname <last name>', 'Last name of the new admin') .option('-l, --lastname <last name>', 'Last name of the new admin')
.action(getLocalScript('admin/create-user')); .action(runAction('admin:create-user', action));
}; };
export default command; export default command;

View File

@ -16,7 +16,7 @@ const mock = {
admin, admin,
}; };
jest.mock('../../../../../index', () => { jest.mock('../../../../../Strapi', () => {
const impl = jest.fn(() => mock); const impl = jest.fn(() => mock);
Object.assign(impl, { Object.assign(impl, {

View File

@ -1,6 +1,6 @@
import _ from 'lodash'; import _ from 'lodash';
import inquirer from 'inquirer'; import inquirer from 'inquirer';
import strapi from '../../../../index'; import strapi from '../../../../Strapi';
interface CmdOptions { interface CmdOptions {
email?: string; email?: string;

View File

@ -1,5 +1,6 @@
import { getLocalScript } from '../../../utils/helpers';
import type { StrapiCommand } from '../../../types'; import type { StrapiCommand } from '../../../types';
import { runAction } from '../../../utils/helpers';
import action from './action';
/** /**
* `$ strapi admin:reset-user-password` * `$ strapi admin:reset-user-password`
@ -11,7 +12,7 @@ const command: StrapiCommand = ({ command }) => {
.description("Reset an admin user's password") .description("Reset an admin user's password")
.option('-e, --email <email>', 'The user email') .option('-e, --email <email>', 'The user email')
.option('-p, --password <password>', 'New password for the user') .option('-p, --password <password>', 'New password for the user')
.action(getLocalScript('admin/reset-user-password')); .action(runAction('admin:reset-user-password', action));
}; };
export default command; export default command;

View File

@ -1,4 +1,4 @@
import strapi from '../../..'; import strapi from '../../../Strapi';
import { buildAdmin } from '../../builders'; import { buildAdmin } from '../../builders';
interface CmdOptions { interface CmdOptions {

View File

@ -1,5 +1,6 @@
import { getLocalScript } from '../../utils/helpers';
import type { StrapiCommand } from '../../types'; import type { StrapiCommand } from '../../types';
import { runAction } from '../../utils/helpers';
import action from './action';
/** /**
* `$ strapi build` * `$ strapi build`
@ -9,7 +10,7 @@ const command: StrapiCommand = ({ command }) => {
.command('build') .command('build')
.option('--no-optimization', 'Build the admin app without optimizing assets') .option('--no-optimization', 'Build the admin app without optimizing assets')
.description('Build the strapi admin app') .description('Build the strapi admin app')
.action(getLocalScript('build-command')); // build-command dir to avoid problems with 'build' being commonly ignored .action(runAction('build', action)); // build-command dir to avoid problems with 'build' being commonly ignored
}; };
export default command; export default command;

View File

@ -1,7 +1,7 @@
import CLITable from 'cli-table3'; import CLITable from 'cli-table3';
import chalk from 'chalk'; import chalk from 'chalk';
import strapi from '../../../../index'; import strapi from '../../../../Strapi';
export default async () => { export default async () => {
const appContext = await strapi.compile(); const appContext = await strapi.compile();

View File

@ -1,5 +1,6 @@
import { getLocalScript } from '../../../utils/helpers';
import type { StrapiCommand } from '../../../types'; import type { StrapiCommand } from '../../../types';
import { runAction } from '../../../utils/helpers';
import action from './action';
/** /**
* `$ strapi components:list` * `$ strapi components:list`
@ -8,7 +9,7 @@ const command: StrapiCommand = ({ command }) => {
command command
.command('components:list') .command('components:list')
.description('List all the application components') .description('List all the application components')
.action(getLocalScript('components/list')); .action(runAction('components:list', action));
}; };
export default command; export default command;

View File

@ -1,5 +1,5 @@
import fs from 'fs'; import fs from 'fs';
import strapi from '../../../../index'; import strapi from '../../../../Strapi';
interface CmdOptions { interface CmdOptions {
file?: string; file?: string;

View File

@ -1,5 +1,6 @@
import { getLocalScript } from '../../../utils/helpers';
import type { StrapiCommand } from '../../../types'; import type { StrapiCommand } from '../../../types';
import { runAction } from '../../../utils/helpers';
import action from './action';
/** /**
* `$ strapi configuration:dump` * `$ strapi configuration:dump`
@ -11,7 +12,7 @@ const command: StrapiCommand = ({ command }) => {
.description('Dump configurations of your application') .description('Dump configurations of your application')
.option('-f, --file <file>', 'Output file, default output is stdout') .option('-f, --file <file>', 'Output file, default output is stdout')
.option('-p, --pretty', 'Format the output JSON with indentation and line breaks', false) .option('-p, --pretty', 'Format the output JSON with indentation and line breaks', false)
.action(getLocalScript('configuration/dump')); .action(runAction('configuration:dump', action));
}; };
export default command; export default command;

View File

@ -2,7 +2,7 @@ import fs from 'fs';
import _ from 'lodash'; import _ from 'lodash';
import type { Database } from '@strapi/database'; import type { Database } from '@strapi/database';
import strapi from '../../../../index'; import strapi from '../../../../Strapi';
type Strategy = 'replace' | 'merge' | 'keep'; type Strategy = 'replace' | 'merge' | 'keep';

View File

@ -1,5 +1,6 @@
import { getLocalScript } from '../../../utils/helpers';
import type { StrapiCommand } from '../../../types'; import type { StrapiCommand } from '../../../types';
import { runAction } from '../../../utils/helpers';
import action from './action';
/** /**
* `$ strapi configuration:restore` * `$ strapi configuration:restore`
@ -11,7 +12,7 @@ const command: StrapiCommand = ({ command }) => {
.description('Restore configurations of your application') .description('Restore configurations of your application')
.option('-f, --file <file>', 'Input file, default input is stdin') .option('-f, --file <file>', 'Input file, default input is stdin')
.option('-s, --strategy <strategy>', 'Strategy name, one of: "replace", "merge", "keep"') .option('-s, --strategy <strategy>', 'Strategy name, one of: "replace", "merge", "keep"')
.action(getLocalScript('configuration/restore')); .action(runAction('configuration:restore', action));
}; };
export default command; export default command;

View File

@ -1,5 +1,5 @@
import REPL from 'repl'; import REPL from 'repl';
import strapi from '../../../index'; import strapi from '../../../Strapi';
/** /**
* `$ strapi console` * `$ strapi console`

View File

@ -1,5 +1,6 @@
import { getLocalScript } from '../../utils/helpers';
import type { StrapiCommand } from '../../types'; import type { StrapiCommand } from '../../types';
import { runAction } from '../../utils/helpers';
import action from './action';
/** /**
* `$ strapi console` * `$ strapi console`
@ -8,7 +9,7 @@ const command: StrapiCommand = ({ command }) => {
command command
.command('console') .command('console')
.description('Open the Strapi framework console') .description('Open the Strapi framework console')
.action(getLocalScript('console')); .action(runAction('console', action));
}; };
export default command; export default command;

View File

@ -1,7 +1,7 @@
import CLITable from 'cli-table3'; import CLITable from 'cli-table3';
import chalk from 'chalk'; import chalk from 'chalk';
import strapi from '../../../../index'; import strapi from '../../../../Strapi';
export default async () => { export default async () => {
const appContext = await strapi.compile(); const appContext = await strapi.compile();

View File

@ -1,5 +1,6 @@
import { getLocalScript } from '../../../utils/helpers';
import type { StrapiCommand } from '../../../types'; import type { StrapiCommand } from '../../../types';
import { runAction } from '../../../utils/helpers';
import action from './action';
/** /**
* `$ strapi content-types:list` * `$ strapi content-types:list`
@ -8,7 +9,7 @@ const command: StrapiCommand = ({ command }) => {
command command
.command('content-types:list') .command('content-types:list')
.description('List all the application content-types') .description('List all the application content-types')
.action(getLocalScript('content-types/list')); .action(runAction('content-types:list', action));
}; };
export default command; export default command;

View File

@ -1,7 +1,7 @@
import CLITable from 'cli-table3'; import CLITable from 'cli-table3';
import chalk from 'chalk'; import chalk from 'chalk';
import strapi from '../../../../index'; import strapi from '../../../../Strapi';
export default async () => { export default async () => {
const appContext = await strapi.compile(); const appContext = await strapi.compile();

View File

@ -1,5 +1,6 @@
import { getLocalScript } from '../../../utils/helpers';
import type { StrapiCommand } from '../../../types'; import type { StrapiCommand } from '../../../types';
import { runAction } from '../../../utils/helpers';
import action from './action';
/** /**
* `$ strapi controllers:list` * `$ strapi controllers:list`
@ -8,7 +9,7 @@ const command: StrapiCommand = ({ command }) => {
command command
.command('controllers:list') .command('controllers:list')
.description('List all the application controllers') .description('List all the application controllers')
.action(getLocalScript('controllers/list')); .action(runAction('controllers:list', action));
}; };
export default command; export default command;

View File

@ -9,7 +9,7 @@ import tsUtils from '@strapi/typescript-utils';
import type { Strapi } from '@strapi/types'; import type { Strapi } from '@strapi/types';
import loadConfiguration from '../../../core/app-configuration'; import loadConfiguration from '../../../core/app-configuration';
import strapi from '../../../index'; import strapi from '../../../Strapi';
import { buildTypeScript, buildAdmin } from '../../builders'; import { buildTypeScript, buildAdmin } from '../../builders';
interface CmdOptions { interface CmdOptions {
@ -23,7 +23,7 @@ interface CmdOptions {
* `$ strapi develop` * `$ strapi develop`
* *
*/ */
export default async ({ build, watchAdmin, polling, browser }: CmdOptions) => { export default async ({ build, watchAdmin, polling, browser }: CmdOptions): Promise<void> => {
const appDir = process.cwd(); const appDir = process.cwd();
const isTSProject = await tsUtils.isUsingTypeScript(appDir); const isTSProject = await tsUtils.isUsingTypeScript(appDir);
@ -183,7 +183,7 @@ const workerProcess = async ({
} }
}); });
return strapiInstance.start(); strapiInstance.start();
}; };
/** /**

View File

@ -1,5 +1,6 @@
import { getLocalScript } from '../../utils/helpers';
import type { StrapiCommand } from '../../types'; import type { StrapiCommand } from '../../types';
import { runAction } from '../../utils/helpers';
import action from './action';
/** /**
* `$ strapi develop` * `$ strapi develop`
@ -13,7 +14,7 @@ const command: StrapiCommand = ({ command }) => {
.option('--polling', 'Watch for file changes in network directories', false) .option('--polling', 'Watch for file changes in network directories', false)
.option('--browser <name>', 'Open the browser', true) .option('--browser <name>', 'Open the browser', true)
.description('Start your Strapi application in development mode') .description('Start your Strapi application in development mode')
.action(getLocalScript('develop')); .action(runAction('develop', action));
}; };
export default command; export default command;

View File

@ -1,7 +1,7 @@
import CLITable from 'cli-table3'; import CLITable from 'cli-table3';
import chalk from 'chalk'; import chalk from 'chalk';
import strapi from '../../../../index'; import strapi from '../../../../Strapi';
export default async () => { export default async () => {
const appContext = await strapi.compile(); const appContext = await strapi.compile();

View File

@ -1,5 +1,6 @@
import { getLocalScript } from '../../../utils/helpers';
import type { StrapiCommand } from '../../../types'; import type { StrapiCommand } from '../../../types';
import { runAction } from '../../../utils/helpers';
import action from './action';
/** /**
* `$ strapi hooks:list` * `$ strapi hooks:list`
@ -8,7 +9,7 @@ const command: StrapiCommand = ({ command }) => {
command command
.command('hooks:list') .command('hooks:list')
.description('List all the application hooks') .description('List all the application hooks')
.action(getLocalScript('hooks/list')); .action(runAction('hooks:list', action));
}; };
export default command; export default command;

View File

@ -1,5 +1,6 @@
import { getLocalScript } from '../../utils/helpers';
import type { StrapiCommand } from '../../types'; import type { StrapiCommand } from '../../types';
import { runAction } from '../../utils/helpers';
import action from './action';
/** /**
* `$ strapi install` * `$ strapi install`
@ -8,7 +9,7 @@ const command: StrapiCommand = ({ command }) => {
command command
.command('install [plugins...]') .command('install [plugins...]')
.description('Install a Strapi plugin') .description('Install a Strapi plugin')
.action(getLocalScript('install')); .action(runAction('install', action));
}; };
export default command; export default command;

View File

@ -1,7 +1,7 @@
import CLITable from 'cli-table3'; import CLITable from 'cli-table3';
import chalk from 'chalk'; import chalk from 'chalk';
import strapi from '../../../../index'; import strapi from '../../../../Strapi';
export default async () => { export default async () => {
const appContext = await strapi.compile(); const appContext = await strapi.compile();

View File

@ -1,5 +1,6 @@
import { getLocalScript } from '../../../utils/helpers';
import type { StrapiCommand } from '../../../types'; import type { StrapiCommand } from '../../../types';
import { runAction } from '../../../utils/helpers';
import action from './action';
/** /**
* `$ strapi middlewares:list` * `$ strapi middlewares:list`
@ -8,7 +9,7 @@ const command: StrapiCommand = ({ command }) => {
command command
.command('middlewares:list') .command('middlewares:list')
.description('List all the application middlewares') .description('List all the application middlewares')
.action(getLocalScript('middlewares/list')); .action(runAction('middlewares:list', action));
}; };
export default command; export default command;

View File

@ -1,6 +1,7 @@
import { forceOption } from '../../../utils/commander'; import { forceOption } from '../../../utils/commander';
import { getLocalScript } from '../../../utils/helpers';
import type { StrapiCommand } from '../../../types'; import type { StrapiCommand } from '../../../types';
import { runAction } from '../../../utils/helpers';
import action from './action';
/** /**
* `$ strapi plugin:build` * `$ strapi plugin:build`
@ -11,7 +12,7 @@ const command: StrapiCommand = ({ command }) => {
.description('Bundle your strapi plugin for publishing.') .description('Bundle your strapi plugin for publishing.')
.addOption(forceOption) .addOption(forceOption)
.option('-d, --debug', 'Enable debugging mode with verbose logs', false) .option('-d, --debug', 'Enable debugging mode with verbose logs', false)
.action(getLocalScript('plugin/build-command')); .action(runAction('plugin:build', action));
}; };
export default command; export default command;

View File

@ -1,7 +1,7 @@
import CLITable from 'cli-table3'; import CLITable from 'cli-table3';
import chalk from 'chalk'; import chalk from 'chalk';
import strapi from '../../../../index'; import strapi from '../../../../Strapi';
export default async () => { export default async () => {
const appContext = await strapi.compile(); const appContext = await strapi.compile();

View File

@ -1,5 +1,6 @@
import { getLocalScript } from '../../../utils/helpers';
import type { StrapiCommand } from '../../../types'; import type { StrapiCommand } from '../../../types';
import { runAction } from '../../../utils/helpers';
import action from './action';
/** /**
* `$ strapi policies:list` * `$ strapi policies:list`
@ -8,7 +9,7 @@ const command: StrapiCommand = ({ command }) => {
command command
.command('policies:list') .command('policies:list')
.description('List all the application policies') .description('List all the application policies')
.action(getLocalScript('policies/list')); .action(runAction('policies:list', action));
}; };
export default command; export default command;

View File

@ -1,5 +1,5 @@
import { EOL } from 'os'; import { EOL } from 'os';
import strapi from '../../../index'; import strapi from '../../../Strapi';
interface CmdOptions { interface CmdOptions {
uuid: boolean; uuid: boolean;

View File

@ -1,5 +1,6 @@
import { getLocalScript } from '../../utils/helpers';
import type { StrapiCommand } from '../../types'; import type { StrapiCommand } from '../../types';
import { runAction } from '../../utils/helpers';
import action from './action';
/** /**
* `$ strapi report` * `$ strapi report`
@ -11,7 +12,7 @@ const command: StrapiCommand = ({ command }) => {
.option('-u, --uuid', 'Include Project UUID') .option('-u, --uuid', 'Include Project UUID')
.option('-d, --dependencies', 'Include Project Dependencies') .option('-d, --dependencies', 'Include Project Dependencies')
.option('--all', 'Include All Information') .option('--all', 'Include All Information')
.action(getLocalScript('report')); .action(runAction('report', action));
}; };
export default command; export default command;

View File

@ -2,7 +2,7 @@ import CLITable from 'cli-table3';
import chalk from 'chalk'; import chalk from 'chalk';
import { toUpper } from 'lodash/fp'; import { toUpper } from 'lodash/fp';
import strapi from '../../../../index'; import strapi from '../../../../Strapi';
export default async () => { export default async () => {
const appContext = await strapi.compile(); const appContext = await strapi.compile();

View File

@ -1,5 +1,6 @@
import { getLocalScript } from '../../../utils/helpers';
import type { StrapiCommand } from '../../../types'; import type { StrapiCommand } from '../../../types';
import { runAction } from '../../../utils/helpers';
import action from './action';
/** /**
* `$ strapi routes:list`` * `$ strapi routes:list``
@ -8,7 +9,7 @@ const command: StrapiCommand = ({ command }) => {
command command
.command('routes:list') .command('routes:list')
.description('List all the application routes') .description('List all the application routes')
.action(getLocalScript('routes/list')); .action(runAction('routes:list', action));
}; };
export default command; export default command;

View File

@ -1,7 +1,7 @@
import CLITable from 'cli-table3'; import CLITable from 'cli-table3';
import chalk from 'chalk'; import chalk from 'chalk';
import strapi from '../../../../index'; import strapi from '../../../../Strapi';
export default async () => { export default async () => {
const appContext = await strapi.compile(); const appContext = await strapi.compile();

View File

@ -1,5 +1,6 @@
import { getLocalScript } from '../../../utils/helpers';
import type { StrapiCommand } from '../../../types'; import type { StrapiCommand } from '../../../types';
import { runAction } from '../../../utils/helpers';
import action from './action';
/** /**
* `$ strapi services:list` * `$ strapi services:list`
@ -8,7 +9,7 @@ const command: StrapiCommand = ({ command }) => {
command command
.command('services:list') .command('services:list')
.description('List all the application services') .description('List all the application services')
.action(getLocalScript('services/list')); .action(runAction('services:list', action));
}; };
export default command; export default command;

View File

@ -1,6 +1,6 @@
import fs from 'fs'; import fs from 'fs';
import tsUtils from '@strapi/typescript-utils'; import tsUtils from '@strapi/typescript-utils';
import strapi from '../../../index'; import strapi from '../../../Strapi';
/** /**
* `$ strapi start` * `$ strapi start`
@ -19,5 +19,5 @@ export default async () => {
`${outDir} directory not found. Please run the build command before starting your application` `${outDir} directory not found. Please run the build command before starting your application`
); );
return strapi({ appDir, distDir }).start(); strapi({ appDir, distDir }).start();
}; };

View File

@ -1,5 +1,6 @@
import { getLocalScript } from '../../utils/helpers';
import type { StrapiCommand } from '../../types'; import type { StrapiCommand } from '../../types';
import { runAction } from '../../utils/helpers';
import action from './action';
/** /**
* `$ strapi start` * `$ strapi start`
@ -8,7 +9,7 @@ const command: StrapiCommand = ({ command }) => {
command command
.command('start') .command('start')
.description('Start your Strapi application') .description('Start your Strapi application')
.action(getLocalScript('start')); .action(runAction('start', action));
}; };
export default command; export default command;

View File

@ -1,5 +1,6 @@
import { getLocalScript } from '../../../utils/helpers';
import type { StrapiCommand } from '../../../types'; import type { StrapiCommand } from '../../../types';
import { runAction } from '../../../utils/helpers';
import action from './action';
/** /**
* `$ strapi telemetry:disable` * `$ strapi telemetry:disable`
@ -8,7 +9,7 @@ const command: StrapiCommand = ({ command }) => {
command command
.command('telemetry:disable') .command('telemetry:disable')
.description('Disable anonymous telemetry and metadata sending to Strapi analytics') .description('Disable anonymous telemetry and metadata sending to Strapi analytics')
.action(getLocalScript('telemetry/disable')); .action(runAction('telemetry:disable', action));
}; };
export default command; export default command;

View File

@ -1,5 +1,6 @@
import { getLocalScript } from '../../../utils/helpers';
import type { StrapiCommand } from '../../../types'; import type { StrapiCommand } from '../../../types';
import { runAction } from '../../../utils/helpers';
import action from './action';
/** /**
* `$ strapi telemetry:enable` * `$ strapi telemetry:enable`
@ -8,7 +9,7 @@ const command: StrapiCommand = ({ command }) => {
command command
.command('telemetry:enable') .command('telemetry:enable')
.description('Enable anonymous telemetry and metadata sending to Strapi analytics') .description('Enable anonymous telemetry and metadata sending to Strapi analytics')
.action(getLocalScript('telemetry/enable')); .action(runAction('telemetry:enable', action));
}; };
export default command; export default command;

View File

@ -1,5 +1,6 @@
import { getLocalScript } from '../../../utils/helpers';
import type { StrapiCommand } from '../../../types'; import type { StrapiCommand } from '../../../types';
import { runAction } from '../../../utils/helpers';
import action from './action';
/** /**
*`$ strapi templates:generate <directory>` *`$ strapi templates:generate <directory>`
@ -8,7 +9,7 @@ const command: StrapiCommand = ({ command }) => {
command command
.command('templates:generate <directory>') .command('templates:generate <directory>')
.description('Generate template from Strapi project') .description('Generate template from Strapi project')
.action(getLocalScript('templates/generate')); .action(runAction('templates:generate', action));
}; };
export default command; export default command;

View File

@ -1,5 +1,5 @@
import tsUtils from '@strapi/typescript-utils'; import tsUtils from '@strapi/typescript-utils';
import strapi from '../../../../index'; import strapi from '../../../../Strapi';
interface CmdOptions { interface CmdOptions {
debug?: boolean; debug?: boolean;

View File

@ -1,5 +1,6 @@
import { getLocalScript } from '../../../utils/helpers';
import type { StrapiCommand } from '../../../types'; import type { StrapiCommand } from '../../../types';
import { runAction } from '../../../utils/helpers';
import action from './action';
/** /**
* `$ strapi ts:generate-types` * `$ strapi ts:generate-types`
@ -15,7 +16,7 @@ const command: StrapiCommand = ({ command }) => {
'-o, --out-dir <outDir>', '-o, --out-dir <outDir>',
'Specify a relative root directory in which the definitions will be generated. Changing this value might break types exposed by Strapi that relies on generated types.' 'Specify a relative root directory in which the definitions will be generated. Changing this value might break types exposed by Strapi that relies on generated types.'
) )
.action(getLocalScript('ts/generate-types')); .action(runAction('ts:generate-types', action));
}; };
export default command; export default command;

View File

@ -1,5 +1,6 @@
import { getLocalScript } from '../../utils/helpers';
import type { StrapiCommand } from '../../types'; import type { StrapiCommand } from '../../types';
import { runAction } from '../../utils/helpers';
import action from './action';
/** /**
* `$ strapi uninstall` * `$ strapi uninstall`
@ -9,7 +10,7 @@ const command: StrapiCommand = ({ command }) => {
.command('uninstall [plugins...]') .command('uninstall [plugins...]')
.description('Uninstall a Strapi plugin') .description('Uninstall a Strapi plugin')
.option('-d, --delete-files', 'Delete files', false) .option('-d, --delete-files', 'Delete files', false)
.action(getLocalScript('uninstall')); .action(runAction('uninstall', action));
}; };
export default command; export default command;

View File

@ -3,7 +3,7 @@ import { getConfigUrls, getAbsoluteServerUrl } from '@strapi/utils';
import { getEnabledPlugins } from '../../../core/loaders/plugins/get-enabled-plugins'; import { getEnabledPlugins } from '../../../core/loaders/plugins/get-enabled-plugins';
import addSlash from '../../../utils/addSlash'; import addSlash from '../../../utils/addSlash';
import strapi from '../../../index'; import strapi from '../../../Strapi';
export default async ({ browser }: { browser: boolean }) => { export default async ({ browser }: { browser: boolean }) => {
const appContext = await strapi.compile(); const appContext = await strapi.compile();

View File

@ -1,5 +1,6 @@
import { getLocalScript } from '../../utils/helpers';
import type { StrapiCommand } from '../../types'; import type { StrapiCommand } from '../../types';
import { runAction } from '../../utils/helpers';
import action from './action';
/** /**
* `$ strapi watch-admin` * `$ strapi watch-admin`
@ -9,7 +10,7 @@ const command: StrapiCommand = ({ command }) => {
.command('watch-admin') .command('watch-admin')
.option('--browser <name>', 'Open the browser', true) .option('--browser <name>', 'Open the browser', true)
.description('Start the admin development server') .description('Start the admin development server')
.action(getLocalScript('watch-admin')); .action(runAction('watch-admin', action));
}; };
export default command; export default command;

View File

@ -5,7 +5,7 @@ import { getConfigUrls } from '@strapi/utils';
import ee from '../../utils/ee'; import ee from '../../utils/ee';
import addSlash from '../../utils/addSlash'; import addSlash from '../../utils/addSlash';
import strapi from '../../index'; import strapi from '../../Strapi';
import { getEnabledPlugins } from '../../core/loaders/plugins/get-enabled-plugins'; import { getEnabledPlugins } from '../../core/loaders/plugins/get-enabled-plugins';
export interface Options { export interface Options {

View File

@ -1,7 +1,6 @@
/* eslint-disable @typescript-eslint/no-var-requires */ /* eslint-disable @typescript-eslint/no-var-requires */
import chalk from 'chalk'; import chalk from 'chalk';
import { has, isString, isArray } from 'lodash/fp'; import { has, isString, isArray } from 'lodash/fp';
import resolveCwd from 'resolve-cwd';
import { prompt } from 'inquirer'; import { prompt } from 'inquirer';
import boxen from 'boxen'; import boxen from 'boxen';
import type { Command } from 'commander'; import type { Command } from 'commander';
@ -133,26 +132,14 @@ const assertCwdContainsStrapiProject = (name: string) => {
} }
}; };
const getLocalScript = const runAction =
(name: string) => (name: string, action: (...args: any[]) => Promise<void>) =>
(...args: unknown[]) => { (...args: unknown[]) => {
assertCwdContainsStrapiProject(name); assertCwdContainsStrapiProject(name);
const cmdPath = resolveCwd.silent(`@strapi/strapi/dist/commands/actions/${name}/action`);
if (!cmdPath) {
console.log(
`Error loading the local ${chalk.yellow(
name
)} command. Strapi might not be installed in your "node_modules". You may need to run "yarn install".`
);
process.exit(1);
}
const script = require(cmdPath).default;
Promise.resolve() Promise.resolve()
.then(() => { .then(() => {
return script(...args); return action(...args);
}) })
.catch((error) => { .catch((error) => {
console.error(error); console.error(error);
@ -210,7 +197,7 @@ export {
assertUrlHasProtocol, assertUrlHasProtocol,
ifOptions, ifOptions,
readableBytes, readableBytes,
getLocalScript, runAction,
assertCwdContainsStrapiProject, assertCwdContainsStrapiProject,
notifyExperimentalCommand, notifyExperimentalCommand,
}; };

View File

@ -2,7 +2,4 @@ import strapiFactory from './Strapi';
export type * from '@strapi/types'; export type * from '@strapi/types';
export * as factories from './factories';
export { default as compile } from './compile';
export default strapiFactory; export default strapiFactory;

View File

@ -3,6 +3,6 @@
"compilerOptions": { "compilerOptions": {
"noEmit": true "noEmit": true
}, },
"include": ["src"], "include": ["src", "packup.config.ts"],
"exclude": ["node_modules"] "exclude": ["node_modules"]
} }

View File

@ -8262,6 +8262,7 @@ __metadata:
"@strapi/generate-new": 4.14.4 "@strapi/generate-new": 4.14.4
"@strapi/generators": 4.14.4 "@strapi/generators": 4.14.4
"@strapi/logger": 4.14.4 "@strapi/logger": 4.14.4
"@strapi/pack-up": "workspace:*"
"@strapi/permissions": 4.14.4 "@strapi/permissions": 4.14.4
"@strapi/plugin-content-manager": 4.14.4 "@strapi/plugin-content-manager": 4.14.4
"@strapi/plugin-content-type-builder": 4.14.4 "@strapi/plugin-content-type-builder": 4.14.4
@ -8325,7 +8326,6 @@ __metadata:
ora: 5.4.1 ora: 5.4.1
package-json: 7.0.0 package-json: 7.0.0
qs: 6.11.1 qs: 6.11.1
resolve-cwd: 3.0.0
semver: 7.5.4 semver: 7.5.4
statuses: 2.0.1 statuses: 2.0.1
supertest: 6.3.3 supertest: 6.3.3