├── .eslintignore ├── test ├── fixtures │ ├── example │ │ ├── package.json │ │ ├── node_modules │ │ │ └── egg │ │ │ │ ├── package.json │ │ │ │ └── index.js │ │ ├── config │ │ │ └── config.default.js │ │ └── app │ │ │ └── router.js │ ├── ts │ │ ├── config │ │ │ └── config.default.js │ │ ├── tsconfig.json │ │ ├── package.json │ │ ├── node_modules │ │ │ └── aliyun-egg │ │ │ │ ├── package.json │ │ │ │ └── index.js │ │ └── test │ │ │ ├── a.test.js │ │ │ ├── sub.ts │ │ │ └── typescript.test.ts │ ├── example-port │ │ ├── package.json │ │ ├── app │ │ │ └── router.js │ │ └── config │ │ │ └── config.default.js │ ├── test-demo-app │ │ ├── node_modules │ │ │ └── egg │ │ ├── package.json │ │ ├── config │ │ │ └── config.default.js │ │ ├── app │ │ │ └── router.js │ │ └── test │ │ │ └── a.test.js │ ├── example-ts-simple │ │ ├── package.json │ │ ├── node_modules │ │ │ └── egg │ │ │ │ ├── package.json │ │ │ │ └── index.js │ │ └── config │ │ │ └── config.default.ts │ ├── setup-ts │ │ ├── tsconfig.json │ │ ├── package.json │ │ └── test │ │ │ ├── .setup.ts │ │ │ └── a.test.ts │ ├── test-files-glob │ │ ├── package.json │ │ └── test │ │ │ ├── no-load.js │ │ │ ├── fixtures │ │ │ ├── app │ │ │ │ └── node_modules │ │ │ │ │ └── no-load.test.js │ │ │ └── node_modules │ │ │ │ ├── no-load.test.js │ │ │ │ └── a-mod │ │ │ │ └── no-load.test.js │ │ │ ├── index.test.js │ │ │ └── lib │ │ │ └── sub.test.js │ ├── example-ts │ │ ├── node_modules │ │ │ └── egg │ │ │ │ ├── package.json │ │ │ │ └── index.js │ │ ├── tsconfig.json │ │ ├── package.json │ │ ├── typings │ │ │ ├── global.d.ts │ │ │ ├── index.d.ts │ │ │ └── app │ │ │ │ └── controller │ │ │ │ └── index.d.ts │ │ ├── config │ │ │ └── config.default.ts │ │ ├── app │ │ │ ├── router.ts │ │ │ └── controller │ │ │ │ └── home.ts │ │ ├── agent.js │ │ ├── app.ts │ │ └── test │ │ │ └── index.test.ts │ ├── require-script.js │ ├── test-files │ │ ├── config │ │ │ ├── proxy.js │ │ │ ├── plugin.js │ │ │ ├── config.default.js │ │ │ └── config.prod.js │ │ ├── docs │ │ │ └── home.js │ │ ├── example │ │ │ └── foo.js │ │ ├── examples │ │ │ └── foo.js │ │ ├── ignore │ │ │ └── a.js │ │ ├── mocks │ │ │ └── foo.js │ │ ├── app │ │ │ ├── assets │ │ │ │ ├── index.js │ │ │ │ └── subdir │ │ │ │ │ └── home.js │ │ │ ├── public │ │ │ │ ├── bar.js │ │ │ │ └── subdir │ │ │ │ │ └── home.js │ │ │ └── view │ │ │ │ └── subdir │ │ │ │ └── home.js │ │ ├── mocks_data │ │ │ └── foo │ │ │ │ └── foo.js │ │ ├── package.json │ │ ├── node_modules │ │ │ └── custom-egg-ts-helper │ │ │ │ ├── package.json │ │ │ │ └── register.js │ │ ├── test │ │ │ ├── b │ │ │ │ └── b.test.js │ │ │ ├── fail.js │ │ │ ├── a.js │ │ │ ├── no-timeouts.test.js │ │ │ ├── ignore.test.js │ │ │ └── a.test.js │ │ └── lib │ │ │ └── a.js │ ├── example-ts-cluster │ │ ├── tsconfig.json │ │ ├── node_modules │ │ │ └── egg │ │ │ │ ├── package.json │ │ │ │ └── index.js │ │ ├── typings │ │ │ ├── global.d.ts │ │ │ ├── index.d.ts │ │ │ └── app │ │ │ │ └── controller │ │ │ │ └── index.d.ts │ │ ├── package.json │ │ ├── config │ │ │ └── config.default.ts │ │ ├── app │ │ │ ├── router.ts │ │ │ └── controller │ │ │ │ └── home.ts │ │ ├── app.ts │ │ └── test │ │ │ └── index.test.ts │ ├── example-ts-pkg │ │ ├── node_modules │ │ │ └── egg │ │ │ │ ├── package.json │ │ │ │ └── index.js │ │ ├── tsconfig.json │ │ ├── package.json │ │ ├── config │ │ │ └── config.default.ts │ │ ├── agent.js │ │ ├── app.ts │ │ ├── app │ │ │ └── router.ts │ │ └── test │ │ │ └── index.test.ts │ ├── example-declarations │ │ ├── jsconfig.json │ │ ├── node_modules │ │ │ └── aliyun-egg │ │ │ │ ├── package.json │ │ │ │ └── index.js │ │ ├── config │ │ │ ├── plugin.js │ │ │ └── config.default.js │ │ ├── app │ │ │ ├── router.js │ │ │ └── controller │ │ │ │ └── home.js │ │ └── package.json │ ├── example-ts-custom-compiler │ │ ├── config │ │ │ └── config.default.ts │ │ ├── package.json │ │ └── test │ │ │ └── index.test.ts │ ├── example-ts-error-stack │ │ ├── node_modules │ │ │ └── egg │ │ │ │ ├── package.json │ │ │ │ └── index.js │ │ ├── tsconfig.json │ │ ├── package.json │ │ ├── config │ │ │ └── config.default.ts │ │ ├── app.ts │ │ └── test │ │ │ └── index.test.ts │ ├── custom-framework-app │ │ ├── node_modules │ │ │ └── yadan │ │ │ │ ├── package.json │ │ │ │ └── index.js │ │ └── package.json │ ├── example-ts-custom-compiler-2 │ │ ├── config │ │ │ └── config.default.ts │ │ └── package.json │ ├── example-ts-error-stack-mixed │ │ ├── tsconfig.json │ │ ├── package.json │ │ ├── config │ │ │ └── config.default.ts │ │ ├── app.ts │ │ └── test │ │ │ └── index.test.js │ ├── setup-js │ │ ├── package.json │ │ └── test │ │ │ ├── a.test.js │ │ │ └── .setup.js │ ├── demo-app │ │ ├── package.json │ │ └── node_modules │ │ │ └── aliyun-egg │ │ │ ├── package.json │ │ │ └── index.js │ ├── mocha-test-ts-esm │ │ ├── package.json │ │ ├── test │ │ │ ├── bar.test.ts │ │ │ └── foo.test.ts │ │ └── tsconfig.json │ ├── my-egg-bin │ │ ├── bin │ │ │ └── my-egg-bin.ts │ │ ├── config │ │ │ └── framework.ts │ │ ├── package.json │ │ └── cmd │ │ │ ├── nsp.ts │ │ │ └── dev.ts │ ├── test-unhandled-rejection │ │ ├── package.json │ │ └── test │ │ │ └── a.test.js │ ├── egg-require │ │ ├── node_modules │ │ │ └── aliyun-egg │ │ │ │ ├── package.json │ │ │ │ └── index.js │ │ └── package.json │ ├── egg-revert │ │ ├── node_modules │ │ │ └── aliyun-egg │ │ │ │ ├── package.json │ │ │ │ └── index.js │ │ ├── package.json │ │ └── test │ │ │ └── index.test.js │ ├── prerequire │ │ └── test │ │ │ └── index.test.js │ ├── mocha-test │ │ └── test │ │ │ ├── bar.test.js │ │ │ └── foo.test.js │ ├── bin │ │ └── fake_mocha.js │ └── no-exit │ │ └── test │ │ └── foo.test.js ├── coffee.ts ├── cmd │ ├── debug.test.ts │ ├── dev.test.ts │ ├── cov.test.ts │ └── test.test.ts ├── egg-bin.test.ts ├── my-egg-bin.test.ts └── ts.test.ts ├── scripts ├── .eslintrc ├── start-cluster.js └── postinstall.js ├── src ├── config │ ├── framework.ts │ └── plugin.ts ├── index.ts ├── bin │ └── cli.ts ├── cmd │ ├── debug.ts │ ├── cov.ts │ ├── dev.ts │ ├── base.ts │ └── test.ts ├── utils.ts └── middleware │ ├── handle_error.ts │ ├── inspect.ts │ └── global_options.ts ├── .eslintrc ├── tsconfig.json ├── .github ├── workflows │ ├── release.yml │ └── nodejs.yml └── PULL_REQUEST_TEMPLATE.md ├── .vscode └── launch.json ├── .gitignore ├── LICENSE ├── package.json ├── README.md └── CHANGELOG.md /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | coverage/ 3 | test/fixtures 4 | -------------------------------------------------------------------------------- /test/fixtures/example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example" 3 | } -------------------------------------------------------------------------------- /test/fixtures/ts/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.key = '12345'; 2 | -------------------------------------------------------------------------------- /test/fixtures/example-port/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example" 3 | } -------------------------------------------------------------------------------- /test/fixtures/test-demo-app/node_modules/egg: -------------------------------------------------------------------------------- 1 | ../../../../node_modules/egg -------------------------------------------------------------------------------- /test/fixtures/example-ts-simple/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example" 3 | } -------------------------------------------------------------------------------- /test/fixtures/test-demo-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-app" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/ts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@eggjs/tsconfig" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/example/node_modules/egg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egg" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/setup-ts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@eggjs/tsconfig" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/test-files-glob/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-files-glob" 3 | } -------------------------------------------------------------------------------- /scripts/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "extends": "eslint-config-egg" 4 | } 5 | -------------------------------------------------------------------------------- /test/fixtures/example-ts/node_modules/egg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egg" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/example-ts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@eggjs/tsconfig" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/require-script.js: -------------------------------------------------------------------------------- 1 | console.log('hey, you require me by --require'); 2 | -------------------------------------------------------------------------------- /test/fixtures/test-files/config/proxy.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/test-files/docs/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/test-files/example/foo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/test-files/examples/foo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/test-files/ignore/a.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/test-files/mocks/foo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = ''; 4 | -------------------------------------------------------------------------------- /src/config/framework.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | package: '@artus-cli/artus-cli', 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-cluster/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@eggjs/tsconfig" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-pkg/node_modules/egg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egg" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-pkg/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@eggjs/tsconfig" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-simple/node_modules/egg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egg" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/test-files/app/assets/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/test-files/app/public/bar.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/test-files/config/plugin.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/example-declarations/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": [ 3 | "**/*" 4 | ] 5 | } -------------------------------------------------------------------------------- /test/fixtures/example-ts-cluster/node_modules/egg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egg" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-custom-compiler/config/config.default.ts: -------------------------------------------------------------------------------- 1 | export const key = '12345'; 2 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-error-stack/node_modules/egg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egg" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-error-stack/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@eggjs/tsconfig" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/example/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.key = '12345'; 4 | -------------------------------------------------------------------------------- /test/fixtures/test-files-glob/test/no-load.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | throw 'should not load'; 4 | -------------------------------------------------------------------------------- /test/fixtures/test-files/app/assets/subdir/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/test-files/app/public/subdir/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/test-files/app/view/subdir/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/test-files/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/test-files/config/config.prod.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/test-files/mocks_data/foo/foo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = ''; 4 | -------------------------------------------------------------------------------- /test/fixtures/custom-framework-app/node_modules/yadan/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yadan" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-custom-compiler-2/config/config.default.ts: -------------------------------------------------------------------------------- 1 | export const key = '12345'; 2 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-error-stack-mixed/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@eggjs/tsconfig" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/test-demo-app/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = '123'; 4 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-custom-compiler-2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-ts-custom-compiler-2" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-simple/config/config.default.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | export const key = '12345'; 4 | -------------------------------------------------------------------------------- /test/fixtures/test-files/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-files", 3 | "files": [ 4 | "lib" 5 | ] 6 | } -------------------------------------------------------------------------------- /test/fixtures/ts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ts", 3 | "egg": { 4 | "framework": "aliyun-egg" 5 | } 6 | } -------------------------------------------------------------------------------- /test/fixtures/example-ts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-ts", 3 | "egg": { 4 | "typescript": true 5 | } 6 | } -------------------------------------------------------------------------------- /test/fixtures/example-ts/typings/global.d.ts: -------------------------------------------------------------------------------- 1 | interface PlainObject extends Object { 2 | [key: string]: any; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/setup-ts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ts", 3 | "egg": { 4 | "framework": "aliyun-egg" 5 | } 6 | } -------------------------------------------------------------------------------- /test/fixtures/test-files/node_modules/custom-egg-ts-helper/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "custom-egg-ts-helper" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/test-files/test/b/b.test.js: -------------------------------------------------------------------------------- 1 | describe('b/b.test.js', () => { 2 | it('should success', () => {}); 3 | }); 4 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-cluster/typings/global.d.ts: -------------------------------------------------------------------------------- 1 | interface PlainObject extends Object { 2 | [key: string]: any; 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/setup-js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "js", 3 | "egg": { 4 | "framework": "aliyun-egg" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/demo-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-app", 3 | "egg": { 4 | "framework": "aliyun-egg" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-cluster/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-ts", 3 | "egg": { 4 | "typescript": true 5 | } 6 | } -------------------------------------------------------------------------------- /test/fixtures/test-files/node_modules/custom-egg-ts-helper/register.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | console.log('custom egg-ts-helper'); 4 | -------------------------------------------------------------------------------- /test/fixtures/mocha-test-ts-esm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "module", 3 | "devDependencies": { 4 | "typescript": "*" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/my-egg-bin/bin/my-egg-bin.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import { start } from '@artus-cli/artus-cli'; 4 | 5 | start(); 6 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "eslint-config-egg/typescript", 4 | "eslint-config-egg/lib/rules/enforce-node-prefix" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-error-stack/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-ts-error-stack", 3 | "egg": { 4 | "typescript": true 5 | } 6 | } -------------------------------------------------------------------------------- /test/fixtures/setup-js/test/a.test.js: -------------------------------------------------------------------------------- 1 | describe('a.test.js', () => { 2 | it('test', () => { 3 | console.log('hello egg'); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /test/fixtures/test-unhandled-rejection/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-unhandled-rejection", 3 | "files": [ 4 | "lib" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/ts/node_modules/aliyun-egg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aliyun-egg", 3 | "dependencies": { 4 | "egg": "*" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/custom-framework-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "custom-framework-app", 3 | "egg": { 4 | "framework": "yadan" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/demo-app/node_modules/aliyun-egg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aliyun-egg", 3 | "dependencies": { 4 | "egg": "*" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/egg-require/node_modules/aliyun-egg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aliyun-egg", 3 | "dependencies": { 4 | "egg": "*" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/egg-revert/node_modules/aliyun-egg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aliyun-egg", 3 | "dependencies": { 4 | "egg": "*" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-error-stack-mixed/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-ts-error-stack", 3 | "egg": { 4 | "typescript": true 5 | } 6 | } -------------------------------------------------------------------------------- /test/fixtures/example-ts/typings/index.d.ts: -------------------------------------------------------------------------------- 1 | import 'egg'; 2 | 3 | // extend egg 4 | declare module 'egg' { 5 | interface Context { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/example-declarations/node_modules/aliyun-egg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aliyun-egg", 3 | "dependencies": { 4 | "egg": "*" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-cluster/typings/index.d.ts: -------------------------------------------------------------------------------- 1 | import 'egg'; 2 | 3 | // extend egg 4 | declare module 'egg' { 5 | interface Context { 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/example/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/', ctx => { 5 | ctx.body = 'hi, egg'; 6 | }); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/test-files/test/fail.js: -------------------------------------------------------------------------------- 1 | describe('fail.js', () => { 2 | it('should fail', () => { 3 | throw new Error('fail.js throw'); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /test/fixtures/ts/test/a.test.js: -------------------------------------------------------------------------------- 1 | describe('a.test.js', () => { 2 | it('should success', () => { 3 | throw 'should not load js files'; 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /test/fixtures/egg-revert/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-app", 3 | "egg": { 4 | "framework": "aliyun-egg", 5 | "revert": "CVE-2023-46809" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/example-port/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/', ctx => { 5 | ctx.body = 'hi, egg'; 6 | }); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/example-ts/config/config.default.ts: -------------------------------------------------------------------------------- 1 | export default () => { 2 | const config = {} as any; 3 | config.keys = '123456'; 4 | return config; 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/my-egg-bin/config/framework.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | 3 | export default { 4 | package: path.join(__dirname, '../../../../src'), 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/my-egg-bin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "my-egg-bin", 3 | "version": "2.3.4", 4 | "bin": { 5 | "my-egg-bin": "bin/my-egg-bin.js" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/prerequire/test/index.test.js: -------------------------------------------------------------------------------- 1 | console.log('EGG_BIN_PREREQUIRE', process.env.EGG_BIN_PREREQUIRE); 2 | console.log('NODE_ENV', process.env.NODE_ENV); 3 | -------------------------------------------------------------------------------- /test/fixtures/setup-js/test/.setup.js: -------------------------------------------------------------------------------- 1 | before(() => { 2 | console.log('this is a before function'); 3 | }); 4 | afterEach(() => { 5 | console.log('is end!'); 6 | }) -------------------------------------------------------------------------------- /test/fixtures/setup-ts/test/.setup.ts: -------------------------------------------------------------------------------- 1 | before(() => { 2 | console.log('this is a before function'); 3 | }); 4 | afterEach(() => { 5 | console.log('is end!'); 6 | }) -------------------------------------------------------------------------------- /test/fixtures/test-files/lib/a.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = condition => { 4 | if (condition) { 5 | return 'a'; 6 | } 7 | return 'b'; 8 | }; 9 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './cmd/dev'; 2 | export * from './cmd/debug'; 3 | export * from './cmd/test'; 4 | export * from './cmd/cov'; 5 | export * from './cmd/base'; 6 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-custom-compiler/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-ts-custom-compiler", 3 | "dependencies": { 4 | "ts-node": "10.9.2" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-pkg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-ts-pkg", 3 | "egg": { 4 | "typescript": true, 5 | "tscompiler": "esbuild-register" 6 | } 7 | } -------------------------------------------------------------------------------- /test/fixtures/setup-ts/test/a.test.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe('a.test.ts', () => { 4 | it('test', () => { 5 | console.log('hello egg'); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/fixtures/test-files/test/a.js: -------------------------------------------------------------------------------- 1 | const a = require('../lib/a'); 2 | 3 | describe('a.js', () => { 4 | it('should success', () => { 5 | a(true); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/fixtures/custom-framework-app/node_modules/yadan/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.startCluster = options => { 4 | console.log('yadan start: %j', options); 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-error-stack-mixed/config/config.default.ts: -------------------------------------------------------------------------------- 1 | export default () => { 2 | const config = {} as any; 3 | config.keys = '123456'; 4 | return config; 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/example-ts/app/router.ts: -------------------------------------------------------------------------------- 1 | import { Application } from 'egg'; 2 | 3 | export default (app: Application) => { 4 | app.router.get('/', app.controller.home.index); 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-pkg/config/config.default.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | export default () => { 4 | const config = {} as any; 5 | config.keys = '123456'; 6 | return config; 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/test-unhandled-rejection/test/a.test.js: -------------------------------------------------------------------------------- 1 | describe('a.test.js', () => { 2 | it('should success', () => { 3 | Promise.reject(new Error('mock error')); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /test/fixtures/example-declarations/config/plugin.js: -------------------------------------------------------------------------------- 1 | /** @type Egg.EggPlugin */ 2 | module.exports = { 3 | // had enabled by egg 4 | // static: { 5 | // enable: true, 6 | // } 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-cluster/config/config.default.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | export default () => { 4 | const config = {} as any; 5 | config.keys = '123456'; 6 | return config; 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/example-port/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.key = '12345'; 4 | 5 | exports.cluster = { 6 | listen: { 7 | port: 6001, 8 | }, 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-error-stack/config/config.default.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | export default () => { 4 | const config = {} as any; 5 | config.keys = '123456'; 6 | return config; 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/mocha-test/test/bar.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | 3 | describe('mocha-test bar.test.js', () => { 4 | it('should work', () => { 5 | assert(true); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/fixtures/mocha-test/test/foo.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | 3 | describe('mocha-test foo.test.js', () => { 4 | it('should work', () => { 5 | assert(true); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/fixtures/test-files/test/no-timeouts.test.js: -------------------------------------------------------------------------------- 1 | describe('no-timeouts.test.js', () => { 2 | it('should success', function() { 3 | console.log(`timeout: ${this.timeout()}`); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /test/fixtures/egg-require/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-app", 3 | "egg": { 4 | "framework": "aliyun-egg", 5 | "require": [ 6 | "../require-script" 7 | ] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/fixtures/mocha-test-ts-esm/test/bar.test.ts: -------------------------------------------------------------------------------- 1 | import assert from 'assert'; 2 | 3 | describe('mocha-test-ts-esm/bar.test.ts', () => { 4 | it('should work', () => { 5 | assert(true); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/fixtures/mocha-test-ts-esm/test/foo.test.ts: -------------------------------------------------------------------------------- 1 | import assert from 'assert'; 2 | 3 | describe('mocha-test-ts-esm/foo.test.ts', () => { 4 | it('should work', () => { 5 | assert(true); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-cluster/app/router.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { Application } from 'egg'; 4 | 5 | export default (app: Application) => { 6 | app.router.get('/', app.controller.home.index); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/test-files-glob/test/fixtures/app/node_modules/no-load.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe(__dirname, () => { 4 | it('should not load', () => { 5 | throw 'should not load this'; 6 | }); 7 | }); -------------------------------------------------------------------------------- /test/fixtures/test-files-glob/test/fixtures/node_modules/no-load.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe(__dirname, () => { 4 | it('should not load', () => { 5 | throw 'should not load this'; 6 | }); 7 | }); -------------------------------------------------------------------------------- /test/fixtures/test-files-glob/test/fixtures/node_modules/a-mod/no-load.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | describe(__dirname, () => { 4 | it('should not load', () => { 5 | throw 'should not load this'; 6 | }); 7 | }); -------------------------------------------------------------------------------- /test/fixtures/ts/test/sub.ts: -------------------------------------------------------------------------------- 1 | export default { name: 'egg from ts' }; 2 | 3 | function foo(bar?: string) { 4 | return bar ?? ''; 5 | } 6 | 7 | if (process.env.NOT_EXISTS) { 8 | console.log(foo()); 9 | } 10 | -------------------------------------------------------------------------------- /test/fixtures/example-ts/agent.js: -------------------------------------------------------------------------------- 1 | module.exports = agent => { 2 | console.log(`agent.options.typescript = ${agent.options.typescript}`); 3 | console.log(`agent.options.tscompiler = ${agent.options.tscompiler}`); 4 | }; 5 | -------------------------------------------------------------------------------- /test/fixtures/example-ts/app.ts: -------------------------------------------------------------------------------- 1 | import { Application } from 'egg'; 2 | 3 | export default (app: Application) => { 4 | console.log(`hi, egg, ${app.config.keys}`); 5 | console.log(`ts env: ${process.env.EGG_TYPESCRIPT}`); 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/test-files-glob/test/index.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('assert'); 4 | 5 | describe(__dirname, () => { 6 | it('should test index', () => { 7 | assert(true); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /test/fixtures/test-files-glob/test/lib/sub.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('assert'); 4 | 5 | describe(__dirname, () => { 6 | it('should test sub', () => { 7 | assert(true); 8 | }); 9 | }); 10 | -------------------------------------------------------------------------------- /test/fixtures/example-declarations/app/router.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {Egg.Application} app - egg application 3 | */ 4 | module.exports = app => { 5 | const { router, controller } = app; 6 | router.get('/', controller.home.index); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/test-files/test/ignore.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const a = require('../ignore/a'); 3 | 4 | describe('ignore.test.js', () => { 5 | it('should success', () => { 6 | assert(a === ''); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /test/fixtures/example/node_modules/egg/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('../../../../../node_modules/egg'); 4 | 5 | setTimeout(() => { 6 | console.log('exit by master test end'); 7 | process.exit(0); 8 | }, 10000); 9 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@eggjs/tsconfig", 3 | "compilerOptions": { 4 | "target": "ES2022", 5 | "outDir": "dist" 6 | }, 7 | "include": [ 8 | "src" 9 | ], 10 | "exclude": [ 11 | "test" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /src/config/plugin.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | autocomplete: { 3 | enable: true, 4 | package: '@artus-cli/plugin-autocomplete', 5 | }, 6 | version: { 7 | enable: true, 8 | package: '@artus-cli/plugin-version', 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-pkg/agent.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | 4 | module.exports = agent => { 5 | console.log(`agent.options.typescript = ${agent.options.typescript}`); 6 | console.log(`agent.options.tscompiler = ${agent.options.tscompiler}`); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-simple/node_modules/egg/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('../../../../../node_modules/egg'); 4 | 5 | setTimeout(() => { 6 | console.log('exit by master test end'); 7 | process.exit(0); 8 | }, 10000); 9 | -------------------------------------------------------------------------------- /test/fixtures/test-demo-app/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(app) { 4 | app.get('/', async function() { 5 | this.body = { 6 | fooPlugin: app.fooPlugin, 7 | foo: 'bar', 8 | }; 9 | }); 10 | }; 11 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-custom-compiler/test/index.test.ts: -------------------------------------------------------------------------------- 1 | describe('test', () => { 2 | it('should ok', () => { 3 | console.info(process.argv); 4 | console.info(process.execArgv); 5 | console.info(process.env.NODE_OPTIONS); 6 | }); 7 | }); 8 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-pkg/app.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { Application } from 'egg'; 4 | 5 | export default (app: Application) => { 6 | console.log(`hi, egg, ${app.config.keys}`); 7 | console.log(`ts env: ${process.env.EGG_TYPESCRIPT}`); 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/bin/fake_mocha.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | console.log('env.NODE_ENV: %s', process.env.NODE_ENV); 4 | console.log('env.AUTO_AGENT: %s', process.env.AUTO_AGENT); 5 | console.log('env.ENABLE_MOCHA_PARALLEL: %s', process.env.ENABLE_MOCHA_PARALLEL); 6 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-cluster/app.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { Application } from 'egg'; 4 | 5 | export default (app: Application) => { 6 | console.log(`hi, egg, ${app.config.keys}`); 7 | console.log(`ts env: ${process.env.EGG_TYPESCRIPT}`); 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/example-declarations/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-declarations", 3 | "version": "1.0.0", 4 | "description": "", 5 | "private": true, 6 | "egg": { 7 | "declarations": true, 8 | "framework": "aliyun-egg" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-pkg/app/router.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { Application, Context } from 'egg'; 4 | 5 | export default (app: Application) => { 6 | app.router.get('/', async (ctx: Context) => { 7 | ctx.body = 'hi, egg'; 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/egg-revert/test/index.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | 3 | describe('test/index.test.js', () => { 4 | it('should test', () => { 5 | // test 6 | assert(process.execArgv.includes('--security-revert=CVE-2023-46809')); 7 | }); 8 | }); 9 | -------------------------------------------------------------------------------- /scripts/start-cluster.js: -------------------------------------------------------------------------------- 1 | const debug = require('util').debuglog('egg-bin:lib:start-cluster'); 2 | 3 | debug('argv: %o', process.argv); 4 | const options = JSON.parse(process.argv[2]); 5 | debug('start cluster options: %o', options); 6 | require(options.framework).startCluster(options); 7 | -------------------------------------------------------------------------------- /test/fixtures/example-ts/node_modules/egg/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('../../../../../node_modules/egg'); 4 | 5 | setTimeout(() => { 6 | console.log('exit by master test end'); 7 | process.exit(0); 8 | }, require('os').platform() === 'win32' ? 11000 : 10000); 9 | -------------------------------------------------------------------------------- /test/fixtures/example-declarations/app/controller/home.js: -------------------------------------------------------------------------------- 1 | const { Controller } = require('egg'); 2 | 3 | class HomeController extends Controller { 4 | async index() { 5 | const { ctx } = this; 6 | ctx.body = 'hi, egg'; 7 | } 8 | } 9 | 10 | module.exports = HomeController; 11 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-cluster/node_modules/egg/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('../../../../../node_modules/egg'); 4 | 5 | setTimeout(() => { 6 | console.log('exit by master test end'); 7 | process.exit(0); 8 | }, require('os').platform() === 'win32' ? 14000 : 10000); 9 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-error-stack/app.ts: -------------------------------------------------------------------------------- 1 | export default function() { 2 | // placeholder comments 3 | // placeholder comments 4 | // placeholder comments 5 | // placeholder comments 6 | if (process.env.THROW_ERROR === 'true') { 7 | throw new Error('throw error'); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/fixtures/example-ts/app/controller/home.ts: -------------------------------------------------------------------------------- 1 | import { Controller } from 'egg'; 2 | 3 | export default class HomeController extends Controller { 4 | public async index() { 5 | const obj: PlainObject = {}; 6 | obj.text = 'hi, egg'; 7 | this.ctx.body = obj.text; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-error-stack-mixed/app.ts: -------------------------------------------------------------------------------- 1 | export default function() { 2 | // placeholder comments 3 | // placeholder comments 4 | // placeholder comments 5 | // placeholder comments 6 | if (process.env.THROW_ERROR === 'true') { 7 | throw new Error('throw error'); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-error-stack/node_modules/egg/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('../../../../../node_modules/egg'); 4 | 5 | setTimeout(() => { 6 | console.log('exit by master test end'); 7 | process.exit(0); 8 | }, require('os').platform() === 'win32' ? 11000 : 10000); 9 | -------------------------------------------------------------------------------- /test/fixtures/example-ts/test/index.test.ts: -------------------------------------------------------------------------------- 1 | import { app } from 'egg-mock/bootstrap'; 2 | 3 | describe('test/index.test.ts', () => { 4 | it('should work', async () => { 5 | await app.httpRequest() 6 | .get('/') 7 | .expect('hi, egg') 8 | .expect(200); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /test/fixtures/test-demo-app/test/a.test.js: -------------------------------------------------------------------------------- 1 | const { app } = require('egg-mock/bootstrap'); 2 | 3 | describe('a.test.js', () => { 4 | it('should work', async () => { 5 | await app.httpRequest() 6 | .get('/') 7 | .expect(200) 8 | .expect({ foo: 'bar' }); 9 | }); 10 | }); 11 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-pkg/node_modules/egg/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('../../../../../node_modules/egg'); 4 | 5 | setTimeout(() => { 6 | console.log('exit by master test end'); 7 | process.exit(0); 8 | }, require('os').platform() === 'win32' ? 11000 : 10000); 9 | 10 | -------------------------------------------------------------------------------- /test/fixtures/example-ts/typings/app/controller/index.d.ts: -------------------------------------------------------------------------------- 1 | // This file was auto created by egg-ts-helper 2 | // Do not modify this file!!!!!!!!! 3 | 4 | import Home from '../../../app/controller/home'; 5 | 6 | declare module 'egg' { 7 | interface IController { 8 | home: Home; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-cluster/typings/app/controller/index.d.ts: -------------------------------------------------------------------------------- 1 | // This file was auto created by egg-ts-helper 2 | // Do not modify this file!!!!!!!!! 3 | 4 | import Home from '../../../app/controller/home'; 5 | 6 | declare module 'egg' { 7 | interface IController { 8 | home: Home; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/fixtures/mocha-test-ts-esm/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@eggjs/tsconfig", 3 | "compileOnSave": true, 4 | "compilerOptions": { 5 | "strict": true, 6 | "noImplicitAny": true, 7 | "target": "ES2022", 8 | "module": "NodeNext", 9 | "moduleResolution": "NodeNext", 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-cluster/app/controller/home.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { Controller } from 'egg'; 4 | 5 | export default class HomeController extends Controller { 6 | public async index() { 7 | const obj: PlainObject = {}; 8 | obj.text = 'hi, egg'; 9 | this.ctx.body = obj.text; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | on: 3 | push: 4 | branches: [ master ] 5 | 6 | jobs: 7 | release: 8 | name: Node.js 9 | uses: eggjs/github-actions/.github/workflows/node-release.yml@master 10 | secrets: 11 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 12 | GIT_TOKEN: ${{ secrets.GIT_TOKEN }} 13 | -------------------------------------------------------------------------------- /src/bin/cli.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import { start } from '@artus-cli/artus-cli'; 4 | 5 | const isBuildJavascriptFile = __filename.endsWith('.js'); 6 | const exclude = [ 'scripts', 'bin', 'test', 'coverage' ]; 7 | if (isBuildJavascriptFile) { 8 | exclude.push('*.ts'); 9 | } else { 10 | exclude.push('dist'); 11 | } 12 | 13 | start({ exclude }); 14 | -------------------------------------------------------------------------------- /test/fixtures/test-files/test/a.test.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const a = require('../lib/a'); 3 | 4 | describe('a.test.js', () => { 5 | it('should success', () => { 6 | a(true); 7 | }); 8 | 9 | it('should show tmp', () => { 10 | const tmpdir = process.env.TMPDIR; 11 | console.log(tmpdir, fs.existsSync(tmpdir)); 12 | }); 13 | }); 14 | -------------------------------------------------------------------------------- /src/cmd/debug.ts: -------------------------------------------------------------------------------- 1 | import { DefineCommand, Command, Utils, Inject } from '@artus-cli/artus-cli'; 2 | 3 | @DefineCommand({ 4 | command: 'debug', 5 | description: 'Alias to `egg-bin dev --inspect`', 6 | }) 7 | export class DebugCommand extends Command { 8 | @Inject() 9 | utils: Utils; 10 | 11 | async run() { 12 | await this.utils.redirect([ 'dev', '--inspect' ]); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /.github/workflows/nodejs.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | 7 | pull_request: 8 | branches: [ master ] 9 | 10 | jobs: 11 | Job: 12 | name: Node.js 13 | uses: node-modules/github-actions/.github/workflows/node-test.yml@master 14 | with: 15 | os: 'ubuntu-latest, macos-latest, windows-latest' 16 | version: '16.19.0, 16, 18, 20, 22' 17 | -------------------------------------------------------------------------------- /test/fixtures/my-egg-bin/cmd/nsp.ts: -------------------------------------------------------------------------------- 1 | import { DefineCommand } from '@artus-cli/artus-cli'; 2 | import { BaseCommand } from '../../../../src/index'; 3 | 4 | @DefineCommand({ 5 | command: 'nsp', 6 | description: 'nsp check', 7 | }) 8 | export class NspCommand extends BaseCommand { 9 | async run() { 10 | console.log('run nsp check at baseDir: %s, with %o', this.base, this.ctx.args); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/fixtures/no-exit/test/foo.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const http = require('http'); 4 | const assert = require('assert'); 5 | 6 | describe('mocha-test', () => { 7 | it('should work', () => { 8 | assert(true); 9 | }); 10 | }); 11 | 12 | const server = http.createServer((req, res) => { 13 | res.writeHead(200, { 'Content-Type': 'text/plain' }); 14 | res.end('okay'); 15 | }); 16 | server.listen(); 17 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-error-stack/test/index.test.ts: -------------------------------------------------------------------------------- 1 | import assert from 'node:assert'; 2 | 3 | describe('test/index.test.ts', () => { 4 | // placeholder comments 5 | it('should throw error', async () => { 6 | throw new Error('error'); 7 | }); 8 | 9 | // placeholder comments 10 | it('should assert', async () => { 11 | const obj = { key: '111' }; 12 | assert.equal(obj.key, '222'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-error-stack-mixed/test/index.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | 3 | describe('test/index.test.js', () => { 4 | // placeholder comments 5 | it('should throw error', async () => { 6 | throw new Error('error'); 7 | }); 8 | 9 | // placeholder comments 10 | it('should assert', async () => { 11 | const obj = { key: '111' }; 12 | assert.equal(obj.key, '222'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /test/fixtures/ts/test/typescript.test.ts: -------------------------------------------------------------------------------- 1 | import assert from 'node:assert'; 2 | import obj from './sub'; 3 | 4 | describe('typescript.test.ts', () => { 5 | it('should success', () => { 6 | console.log('###', obj.name); 7 | assert.equal(obj.name, 'egg from ts'); 8 | }); 9 | 10 | it('should fail', () => { 11 | console.log('###', obj.name); 12 | assert.equal(obj.name, 'wrong assert ts'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /test/fixtures/my-egg-bin/cmd/dev.ts: -------------------------------------------------------------------------------- 1 | import { DefineCommand } from '@artus-cli/artus-cli'; 2 | import { DevCommand as BaseDevCommand } from '../../../../src/index'; 3 | 4 | @DefineCommand({ 5 | command: 'dev', 6 | description: 'Run the development server with my-egg-bin', 7 | }) 8 | export class DevCommand extends BaseDevCommand { 9 | async run() { 10 | super.run(); 11 | console.info('this is my-egg-bin dev, baseDir: %s', this.base); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/fixtures/demo-app/node_modules/aliyun-egg/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.startCluster = options => { 4 | console.log('options: %j', options); 5 | if (process.execArgv.length) { 6 | console.log('process.execArgv:', process.execArgv); 7 | } 8 | console.log('NODE_ENV: %s', process.env.NODE_ENV); 9 | 10 | // make sure exit 11 | setTimeout(function() { 12 | console.log('exist by setTimeout'); 13 | process.exit(0); 14 | }, 3000); 15 | }; 16 | -------------------------------------------------------------------------------- /test/fixtures/egg-require/node_modules/aliyun-egg/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.startCluster = options => { 4 | console.log('options: %j', options); 5 | if (process.execArgv.length) { 6 | console.log('process.execArgv:', process.execArgv); 7 | } 8 | console.log('NODE_ENV: %s', process.env.NODE_ENV); 9 | 10 | // make sure exit 11 | setTimeout(function() { 12 | console.log('exist by setTimeout'); 13 | process.exit(0); 14 | }, 3000); 15 | }; 16 | -------------------------------------------------------------------------------- /test/fixtures/egg-revert/node_modules/aliyun-egg/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.startCluster = options => { 4 | console.log('options: %j', options); 5 | if (process.execArgv.length) { 6 | console.log('process.execArgv:', process.execArgv); 7 | } 8 | console.log('NODE_ENV: %s', process.env.NODE_ENV); 9 | 10 | // make sure exit 11 | setTimeout(function() { 12 | console.log('exist by setTimeout'); 13 | process.exit(0); 14 | }, 3000); 15 | }; 16 | -------------------------------------------------------------------------------- /test/fixtures/example-declarations/node_modules/aliyun-egg/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.startCluster = options => { 4 | console.log('options: %j', options); 5 | if (process.execArgv.length) { 6 | console.log('process.execArgv:', process.execArgv); 7 | } 8 | console.log('NODE_ENV: %s', process.env.NODE_ENV); 9 | 10 | // make sure exit 11 | setTimeout(function() { 12 | console.log('exist by setTimeout'); 13 | process.exit(0); 14 | }, 3000); 15 | }; 16 | -------------------------------------------------------------------------------- /test/coffee.ts: -------------------------------------------------------------------------------- 1 | import { ForkOptions } from 'node:child_process'; 2 | import coffee from 'coffee'; 3 | 4 | export default { 5 | fork(modulePath: string, args: string[], options: ForkOptions = {}) { 6 | options.execArgv = [ 7 | '--require', 'ts-node/register/transpile-only', 8 | ...(options.execArgv ?? []), 9 | ]; 10 | options.env = { 11 | NODE_DEBUG: process.env.NODE_DEBUG, 12 | PATH: process.env.PATH, 13 | ...options.env, 14 | }; 15 | return coffee.fork(modulePath, args, options); 16 | }, 17 | }; 18 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "node", 9 | "request": "launch", 10 | "name": "Egg Test", 11 | "runtimeExecutable": "npm", 12 | "runtimeArgs": [ 13 | "run", 14 | "test-local", 15 | "--", 16 | "--inspect-brk" 17 | ], 18 | "autoAttachChildProcesses": true 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-pkg/test/index.test.ts: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | import { Application, Context } from 'egg'; 4 | import { default as mock, MockOption, BaseMockApplication } from 'egg-mock'; 5 | 6 | describe('test/index.test.ts', () => { 7 | let app: BaseMockApplication; 8 | before(() => { 9 | app = mock.app({ typescript: true } as MockOption); 10 | return app.ready(); 11 | }); 12 | after(() => app.close()); 13 | it('should work', async () => { 14 | await app 15 | .httpRequest() 16 | .get('/') 17 | .expect('hi, egg') 18 | .expect(200); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /test/fixtures/ts/node_modules/aliyun-egg/index.js: -------------------------------------------------------------------------------- 1 | const egg = require('egg'); 2 | 3 | module.exports = Object.assign({}, egg); 4 | 5 | module.exports.startCluster = options => { 6 | console.log('options.typescript=%s', options.typescript); 7 | console.log('options: %j', options); 8 | if (process.execArgv.length) { 9 | console.log('process.execArgv:', process.execArgv); 10 | } 11 | 12 | // make sure exit 13 | setTimeout(() => { 14 | console.log('exit by master test end'); 15 | process.exit(0); 16 | }, require('os').platform() === 'win32' ? 11000 : 5000); 17 | return egg.startCluster(options); 18 | }; 19 | -------------------------------------------------------------------------------- /test/fixtures/example-ts-cluster/test/index.test.ts: -------------------------------------------------------------------------------- 1 | import mm, { MockOption } from 'egg-mock'; 2 | import request from 'supertest'; 3 | 4 | describe('test/index.test.ts', () => { 5 | let app: any; 6 | before(() => { 7 | app = mm.cluster({ 8 | opt: { 9 | execArgv: [ '--require', require.resolve('ts-node/register') ], 10 | }, 11 | } as MockOption); 12 | // app.debug(); 13 | return app.ready(); 14 | }); 15 | 16 | after(() => app.close()); 17 | it('should work', async () => { 18 | const req = request(`http://127.0.0.1:${app.port}`); 19 | return req 20 | .get('/') 21 | .expect('hi, egg') 22 | .expect(200); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /test/fixtures/example-declarations/config/config.default.js: -------------------------------------------------------------------------------- 1 | /* eslint valid-jsdoc: "off" */ 2 | 3 | /** 4 | * @param {Egg.EggAppInfo} appInfo app info 5 | */ 6 | module.exports = appInfo => { 7 | /** 8 | * built-in config 9 | * @type {Egg.EggAppConfig} 10 | **/ 11 | const config = exports = {}; 12 | 13 | // use for cookie sign key, should change to your own and keep security 14 | config.keys = appInfo.name + '_1704604037320_6202'; 15 | 16 | // add your middleware config here 17 | config.middleware = []; 18 | 19 | // add your user config here 20 | const userConfig = { 21 | // myAppName: 'egg', 22 | }; 23 | 24 | return { 25 | ...config, 26 | ...userConfig, 27 | }; 28 | }; 29 | -------------------------------------------------------------------------------- /test/cmd/debug.test.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | import coffee from '../coffee'; 3 | 4 | describe('test/cmd/debug.test.ts', () => { 5 | const eggBin = path.join(__dirname, '../../src/bin/cli.ts'); 6 | const fixtures = path.join(__dirname, '../fixtures'); 7 | const cwd = path.join(fixtures, 'demo-app'); 8 | 9 | it('should startCluster success', () => { 10 | return coffee.fork(eggBin, [ 'debug' ], { cwd }) 11 | // .debug() 12 | .expect('stdout', /"workers":1/) 13 | .expect('stdout', /"baseDir":".*?demo-app"/) 14 | .expect('stdout', /"framework":".*?aliyun-egg"/) 15 | .expect('stdout', /NODE_ENV: development/) 16 | .expect('stderr', /Debugger listening/) 17 | .expect('code', 0) 18 | .end(); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 10 | 11 | ##### Checklist 12 | 13 | 14 | - [ ] `npm test` passes 15 | - [ ] tests and/or benchmarks are included 16 | - [ ] documentation is changed or added 17 | - [ ] commit message follows commit guidelines 18 | 19 | ##### Affected core subsystem(s) 20 | 21 | 22 | 23 | ##### Description of change 24 | 25 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | import fs from 'node:fs/promises'; 2 | import path from 'node:path'; 3 | 4 | export function addNodeOptionsToEnv(options: string, env: Record) { 5 | if (env.NODE_OPTIONS) { 6 | if (!env.NODE_OPTIONS.includes(options)) { 7 | env.NODE_OPTIONS = `${env.NODE_OPTIONS} ${options}`; 8 | } 9 | } else { 10 | env.NODE_OPTIONS = options; 11 | } 12 | } 13 | 14 | export async function readPackageJSON(baseDir: string) { 15 | const pkgFile = path.join(baseDir, 'package.json'); 16 | try { 17 | const pkgJSON = await fs.readFile(pkgFile, 'utf8'); 18 | return JSON.parse(pkgJSON); 19 | } catch { 20 | return {}; 21 | } 22 | } 23 | 24 | export async function hasTsConfig(baseDir: string) { 25 | const pkgFile = path.join(baseDir, 'tsconfig.json'); 26 | try { 27 | await fs.access(pkgFile); 28 | return true; 29 | } catch { 30 | return false; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/middleware/handle_error.ts: -------------------------------------------------------------------------------- 1 | import { debuglog } from 'node:util'; 2 | import { 3 | Inject, ApplicationLifecycle, LifecycleHook, LifecycleHookUnit, Program, 4 | ArtusCliError, 5 | } from '@artus-cli/artus-cli'; 6 | 7 | const debug = debuglog('egg-bin:midddleware:handle_error'); 8 | 9 | @LifecycleHookUnit() 10 | export default class implements ApplicationLifecycle { 11 | @Inject() 12 | private readonly program: Program; 13 | 14 | @LifecycleHook() 15 | async configDidLoad() { 16 | this.program.use(async (_, next) => { 17 | debug('enter next'); 18 | try { 19 | await next(); 20 | debug('after next'); 21 | } catch (err: any) { 22 | debug('next error: %o', err); 23 | // let artus cli to handle it 24 | if (err instanceof ArtusCliError) throw err; 25 | console.error(err); 26 | process.exit(typeof err.code === 'number' ? err.code : 1); 27 | } 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | coverage/ 3 | test/fixtures/custom-framework-app/node_modules/ 4 | 5 | test/fixtures/demo-app/node_modules/aliyun-egg/ 6 | !test/fixtures/demo-app/node_modules/aliyun-egg/node_modules/ 7 | 8 | test/fixtures/ts/node_modules/aliyun-egg/ 9 | !test/fixtures/ts/node_modules/aliyun-egg/node_modules/ 10 | 11 | !test/fixtures/test-files-glob/** 12 | !test/fixtures/example/node_modules/ 13 | !test/fixtures/example-ts-cluster/node_modules/ 14 | !test/fixtures/egg-revert/node_modules/ 15 | !test/fixtures/example-ts-error-stack/node_modules/ 16 | !test/fixtures/egg-require/node_modules/ 17 | !test/fixtures/example-ts-simple/node_modules/ 18 | !test/fixtures/test-files/node_modules/ 19 | !test/fixtures/test-demo-app/node_modules/ 20 | 21 | .mochawesome-reports 22 | run 23 | .tmp 24 | .cache 25 | *.log 26 | package-lock.json 27 | .nyc_output 28 | yarn.lock 29 | .c8_output 30 | .idea 31 | 32 | bin/*.js 33 | cmd/*.js 34 | !bin/postinstall.js 35 | .eslintcache 36 | dist 37 | test/fixtures/example-declarations/typings/ 38 | !test/fixtures/example-declarations/node_modules 39 | .package-lock.json 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017-present Alibaba Group Holding Limited and other contributors. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/middleware/inspect.ts: -------------------------------------------------------------------------------- 1 | import { debuglog } from 'node:util'; 2 | import { 3 | Inject, ApplicationLifecycle, LifecycleHook, LifecycleHookUnit, 4 | Program, CommandContext, 5 | } from '@artus-cli/artus-cli'; 6 | import { addNodeOptionsToEnv } from '../utils'; 7 | 8 | const debug = debuglog('egg-bin:midddleware:inspect'); 9 | 10 | @LifecycleHookUnit() 11 | export default class implements ApplicationLifecycle { 12 | @Inject() 13 | private readonly program: Program; 14 | 15 | @LifecycleHook() 16 | async configDidLoad() { 17 | // add global options 18 | // https://nodejs.org/dist/latest-v18.x/docs/api/cli.html#--inspect-brkhostport 19 | this.program.option({ 20 | 'inspect-brk': { 21 | description: 'Activate inspector and break at start of user script', 22 | type: 'boolean', 23 | }, 24 | inspect: { 25 | description: 'Activate inspector', 26 | type: 'boolean', 27 | }, 28 | }); 29 | 30 | this.program.use(async (ctx: CommandContext, next) => { 31 | debug('before next'); 32 | let hasInspectOption = false; 33 | if (ctx.args.inspect === true) { 34 | addNodeOptionsToEnv('--inspect', ctx.env); 35 | hasInspectOption = true; 36 | } 37 | if (ctx.args['inspect-brk'] === true) { 38 | addNodeOptionsToEnv('--inspect-brk', ctx.env); 39 | hasInspectOption = true; 40 | } 41 | if (hasInspectOption) { 42 | ctx.args.timeout = false; 43 | debug('set timeout = false when inspect enable, set env.NODE_OPTIONS=%o', ctx.env.NODE_OPTIONS); 44 | } else if (process.env.JB_DEBUG_FILE) { 45 | // others like WebStorm 2019 will pass NODE_OPTIONS, and egg-bin itself will be debug, so could detect `process.env.JB_DEBUG_FILE`. 46 | ctx.args.timeout = false; 47 | debug('set timeout = false when process.env.JB_DEBUG_FILE=%o', process.env.JB_DEBUG_FILE); 48 | } 49 | debug('enter next'); 50 | await next(); 51 | debug('after next'); 52 | }); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /scripts/postinstall.js: -------------------------------------------------------------------------------- 1 | const debug = require('node:util').debuglog('egg-bin:postinstall'); 2 | const path = require('node:path'); 3 | const fs = require('node:fs'); 4 | const { runScript } = require('runscript'); 5 | 6 | // node postintall.js 7 | const etsBinFile = process.argv[2] || require.resolve('egg-ts-helper/dist/bin'); 8 | const frameworkPackageName = process.argv[3] || 'egg'; 9 | 10 | // try to use INIT_CWD env https://docs.npmjs.com/cli/v9/commands/npm-run-script 11 | // npm_rootpath is npminstall 12 | const npmRunRoot = process.env.INIT_CWD || process.env.npm_rootpath; 13 | 14 | debug('process.argv: %o', process.argv); 15 | debug('process.env.INIT_CWD: %o', process.env.INIT_CWD); 16 | debug('process.env.npm_rootpath: %o', process.env.npm_rootpath); 17 | debug('etsBinFile: %o', etsBinFile); 18 | debug('frameworkPackageName: %o', frameworkPackageName); 19 | debug('npmRunRoot: %o', npmRunRoot); 20 | 21 | if (npmRunRoot) { 22 | const pkgFile = path.join(npmRunRoot, 'package.json'); 23 | const pkgFileExists = fs.existsSync(pkgFile); 24 | debug('pkgFile: %o exists: %o', pkgFile, pkgFileExists); 25 | if (pkgFileExists) { 26 | const pkg = require(pkgFile); 27 | // should set pkg.egg.declarations = true or pkg.egg.typescript = true 28 | if (!pkg.egg?.typescript && !pkg.egg?.declarations) return; 29 | // ignore eggModule and framework 30 | // framework package.json: 31 | // "egg": { 32 | // "isFramework": true, 33 | // "typescript": true 34 | // } 35 | if (pkg.eggModule) return; 36 | if (pkg.egg.isFramework) return; 37 | // ignore when the current app don't has a framework dependencies 38 | if (!pkg.dependencies || !pkg.dependencies[frameworkPackageName]) return; 39 | // set ETS_CWD 40 | process.env.ETS_CWD = npmRunRoot; 41 | // https://github.com/eggjs/egg-ts-helper/pull/104 42 | process.env.ETS_SCRIPT_FRAMEWORK = frameworkPackageName; 43 | console.log('[egg-bin:postinstall] run %s on %s', etsBinFile, npmRunRoot); 44 | runScript(`node ${etsBinFile}`); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /test/egg-bin.test.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | import coffee from './coffee'; 3 | 4 | describe('test/egg-bin.test.ts', () => { 5 | const eggBin = path.join(__dirname, '../src/bin/cli.ts'); 6 | const fixtures = path.join(__dirname, 'fixtures'); 7 | const cwd = path.join(fixtures, 'test-files'); 8 | 9 | describe('global options', () => { 10 | it('should show version', () => { 11 | return coffee.fork(eggBin, [ '--version' ], { cwd }) 12 | // .debug() 13 | .expect('stdout', /\d+\.\d+\.\d+/) 14 | .expect('code', 0) 15 | .end(); 16 | }); 17 | 18 | it('should main redirect to help', () => { 19 | return coffee.fork(eggBin, [], { cwd }) 20 | // .debug() 21 | .expect('stdout', /Usage: egg-bin/) 22 | .expect('stdout', /Available Commands/) 23 | .expect('stdout', /test \[files\.\.\.]\s+Run the test/) 24 | .expect('stdout', /-ts, --typescript\s+whether enable typescript support/) 25 | .expect('code', 0) 26 | .end(); 27 | }); 28 | 29 | it('should show help', () => { 30 | return coffee.fork(eggBin, [ '--help' ], { cwd }) 31 | // .debug() 32 | .expect('stdout', /Usage: egg-bin/) 33 | .expect('stdout', /Available Commands/) 34 | .expect('stdout', /test \[files\.\.\.]\s+Run the test/) 35 | .expect('stdout', /-ts, --typescript\s+whether enable typescript support/) 36 | .expect('code', 0) 37 | .end(); 38 | }); 39 | 40 | it('should show egg-bin test help', () => { 41 | return coffee.fork(eggBin, [ 'test', '-h', '--base', cwd ]) 42 | // .debug() 43 | .expect('stdout', /Usage: egg-bin test \[files\.\.\.]/) 44 | .expect('stdout', /-ts, --typescript\s+whether enable typescript support/) 45 | .expect('code', 0) 46 | .end(); 47 | }); 48 | 49 | it('should show help when command not exists', () => { 50 | return coffee.fork(eggBin, [ 'not-exists' ], { cwd }) 51 | // .debug() 52 | .expect('stderr', /Command is not found: 'egg-bin not-exists', try 'egg-bin --help' for more information/) 53 | .expect('code', 1) 54 | .end(); 55 | }); 56 | }); 57 | }); 58 | -------------------------------------------------------------------------------- /test/my-egg-bin.test.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | import coffee from './coffee'; 3 | 4 | describe('test/my-egg-bin.test.ts', () => { 5 | const fixtures = path.join(__dirname, 'fixtures'); 6 | const eggBin = path.join(fixtures, 'my-egg-bin/bin/my-egg-bin.ts'); 7 | const cwd = path.join(fixtures, 'test-files'); 8 | 9 | it('should my-egg-bin test success', () => { 10 | return coffee.fork(eggBin, [ 'test' ], { cwd, env: { TESTS: 'test/**/*.test.js' } }) 11 | // .debug() 12 | .expect('stdout', /should success/) 13 | .expect('stdout', /a.test.js/) 14 | .expect('stdout', /b\/b.test.js/) 15 | .notExpect('stdout', /a.js/) 16 | .expect('code', 0) 17 | .end(); 18 | }); 19 | 20 | it('should my-egg-bin nsp success', async () => { 21 | await coffee.fork(eggBin, [ 'nsp', '-h' ], { cwd }) 22 | // .debug() 23 | .expect('stdout', /-baseDir, --base string/) 24 | .expect('code', 0) 25 | .end(); 26 | 27 | await coffee.fork(eggBin, [ 'nsp' ], { cwd }) 28 | // .debug() 29 | .expect('stdout', /run nsp check at baseDir: .+test\-files, with/) 30 | .expect('code', 0) 31 | .end(); 32 | }); 33 | 34 | it('should show help', async () => { 35 | await coffee.fork(eggBin, [ '--help' ], { cwd }) 36 | // .debug() 37 | .expect('stdout', /Usage: my-egg-bin/) 38 | .expect('stdout', /Available Commands/) 39 | .expect('stdout', /test \[files\.\.\.]\s+Run the test/) 40 | .expect('stdout', /-ts, --typescript\s+whether enable typescript support/) 41 | .expect('stdout', /nsp\s+nsp check/) 42 | .expect('code', 0) 43 | .end(); 44 | 45 | await coffee.fork(eggBin, [ 'dev', '-h' ], { cwd }) 46 | // .debug() 47 | .expect('stdout', /Usage: my-egg-bin/) 48 | .expect('stdout', /dev\s+Run the development server with my-egg-bin/) 49 | .expect('stdout', /-p, --port number/) 50 | .expect('stdout', /-ts, --typescript\s+whether enable typescript support/) 51 | .expect('code', 0) 52 | .end(); 53 | }); 54 | 55 | it('should my-egg-bin dev success', () => { 56 | const baseDir = path.join(fixtures, 'custom-framework-app'); 57 | return coffee.fork(eggBin, [ 'dev' ], { cwd: baseDir }) 58 | // .debug() 59 | .expect('stdout', /yadan start/) 60 | .expect('stdout', /this is my-egg-bin dev/) 61 | .expect('code', 0) 62 | .end(); 63 | }); 64 | 65 | it('should show version 2.3.4', () => { 66 | return coffee.fork(eggBin, [ '--version' ], { cwd }) 67 | // .debug() 68 | .expect('stdout', '2.3.4\n') 69 | .expect('code', 0) 70 | .end(); 71 | }); 72 | }); 73 | -------------------------------------------------------------------------------- /src/cmd/cov.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | import fs from 'node:fs/promises'; 3 | import { DefineCommand, Option } from '@artus-cli/artus-cli'; 4 | import { TestCommand } from './test'; 5 | 6 | @DefineCommand({ 7 | command: 'cov [files...]', 8 | description: 'Run the test with coverage', 9 | alias: [ 'c' ], 10 | }) 11 | export class CovCommand extends TestCommand { 12 | // will use on egg-mock https://github.com/eggjs/egg-mock/blob/84a64bd19d0569ec94664c898fb1b28367b95d60/index.js#L7 13 | @Option({ 14 | description: 'prerequire files for coverage instrument', 15 | type: 'boolean', 16 | default: false, 17 | }) 18 | prerequire: boolean; 19 | 20 | @Option({ 21 | description: 'coverage ignore, one or more fileset patterns`', 22 | array: true, 23 | default: [], 24 | }) 25 | x: string[]; 26 | 27 | @Option({ 28 | description: 'c8 instruments passthrough`', 29 | default: '--temp-directory node_modules/.c8_output -r text-summary -r json-summary -r json -r lcov -r cobertura', 30 | }) 31 | c8: string; 32 | 33 | get defaultExcludes() { 34 | return [ 35 | 'example/', 36 | 'examples/', 37 | 'mocks**/', 38 | 'docs/', 39 | // https://github.com/JaKXz/test-exclude/blob/620a7be412d4fc2070d50f0f63e3228314066fc9/index.js#L73 40 | 'test/**', 41 | 'test{,-*}.js', 42 | '**/*.test.js', 43 | '**/__tests__/**', 44 | '**/node_modules/**', 45 | 'typings', 46 | '**/*.d.ts', 47 | ]; 48 | } 49 | 50 | protected async forkNode(modulePath: string, args: string[]) { 51 | if (this.prerequire) { 52 | this.ctx.env.EGG_BIN_PREREQUIRE = 'true'; 53 | } 54 | // append cobertura 55 | if (this.c8) { 56 | this.c8 += ' -r cobertura'; 57 | } 58 | 59 | // add c8 args 60 | // https://github.com/eggjs/egg/issues/3930 61 | const c8Args = [ 62 | // '--show-process-tree', 63 | ...this.c8.split(' ').filter(a => a.trim()), 64 | ]; 65 | if (this.ctx.args.typescript) { 66 | this.ctx.env.SPAWN_WRAP_SHIM_ROOT = path.join(this.base, 'node_modules'); 67 | c8Args.push('--extension'); 68 | c8Args.push('.ts'); 69 | } 70 | 71 | const excludes = new Set([ 72 | ...process.env.COV_EXCLUDES?.split(',') ?? [], 73 | ...this.defaultExcludes, 74 | ...this.x, 75 | ]); 76 | for (const exclude of excludes) { 77 | c8Args.push('-x'); 78 | c8Args.push(exclude); 79 | } 80 | const c8File = require.resolve('c8/bin/c8.js'); 81 | const outputDir = path.join(this.base, 'node_modules/.c8_output'); 82 | await fs.rm(outputDir, { force: true, recursive: true }); 83 | const coverageDir = path.join(this.base, 'coverage'); 84 | await fs.rm(coverageDir, { force: true, recursive: true }); 85 | 86 | await super.forkNode(c8File, [ ...c8Args, process.execPath, ...this.ctx.args.execArgv || [], modulePath, ...args ]); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egg-bin", 3 | "version": "6.13.0", 4 | "publishConfig": { 5 | "tag": "latest" 6 | }, 7 | "description": "egg developer tool", 8 | "files": [ 9 | "dist", 10 | "scripts" 11 | ], 12 | "main": "dist/index.js", 13 | "bin": { 14 | "egg-bin": "dist/bin/cli.js" 15 | }, 16 | "dependencies": { 17 | "@artus-cli/artus-cli": "^0.2.9", 18 | "@artus-cli/plugin-autocomplete": "^0.1.1", 19 | "@artus-cli/plugin-version": "^1.0.1", 20 | "@eggjs/utils": "^4.0.2", 21 | "c8": "^10.0.0", 22 | "detect-port": "^2.0.0", 23 | "egg-ts-helper": "^2.1.0", 24 | "globby": "^11.1.0", 25 | "jest-changed-files": "^29.4.2", 26 | "mocha": "^10.2.0", 27 | "mochawesome-with-mocha": "^7.1.3", 28 | "runscript": "^2.0.0", 29 | "ts-node": "^10.9.2", 30 | "tsconfig-paths": "^4.1.2" 31 | }, 32 | "peerDependencies": { 33 | "egg-mock": ">=5.10.2" 34 | }, 35 | "peerDependenciesMeta": { 36 | "egg-mock": { 37 | "optional": true 38 | } 39 | }, 40 | "devDependencies": { 41 | "@eggjs/tsconfig": "^1.3.0", 42 | "@swc-node/register": "^1.6.1", 43 | "@swc/core": "^1.3.35", 44 | "@types/mocha": "^10.0.1", 45 | "@types/node": "^22.10.1", 46 | "assert-file": "^1.0.0", 47 | "coffee": "^5.4.0", 48 | "cpy": "^8.1.2", 49 | "egg": "^3.9.1", 50 | "egg-mock": "^5.10.2", 51 | "esbuild": "^0.17.7", 52 | "esbuild-register": "^3.4.2", 53 | "eslint": "^8.16.0", 54 | "eslint-config-egg": "^13.1.0", 55 | "npminstall": "^7.5.0", 56 | "typescript": "^5.2.2" 57 | }, 58 | "repository": { 59 | "type": "git", 60 | "url": "git@github.com:eggjs/egg-bin.git" 61 | }, 62 | "bug": { 63 | "url": "https://github.com/eggjs/egg/issues" 64 | }, 65 | "homepage": "https://github.com/eggjs/egg-bin", 66 | "author": "fengmk2 (https://github.com/fengmk2)", 67 | "scripts": { 68 | "postinstall": "node scripts/postinstall.js", 69 | "contributor": "git-contributor", 70 | "lint": "eslint . --cache --ext ts", 71 | "test": "npm run lint -- --fix && npm run test-local", 72 | "test-local": "npm run tsc && node dist/bin/cli.js test", 73 | "test-local-with-ts-node-transpile-only": "node -r ts-node/register/transpile-only src/bin/cli.ts test", 74 | "test-local-with-swc": "node -r @swc-node/register src/bin/cli.ts test", 75 | "test-local-with-esbuild": "node -r esbuild-register src/bin/cli.ts test", 76 | "test-tsc": "npm run clean && npm run tsc && node dist/bin/cli.js && node dist/bin/cli.js test --base test/fixtures/example-ts && node dist/bin/cli.js dev --base test/fixtures/example-ts", 77 | "cov": "c8 -r lcov -r text-summary -x 'test/**' npm run test-local -- --timeout 120000", 78 | "ci": "npm run lint && npm run test-local && npm run test-tsc", 79 | "prepublishOnly": "npm run clean && npm run tsc", 80 | "tsc": "tsc", 81 | "clean": "rm -rf dist" 82 | }, 83 | "engines": { 84 | "node": ">= 16.19.0" 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/cmd/dev.ts: -------------------------------------------------------------------------------- 1 | import { debuglog } from 'node:util'; 2 | import path from 'node:path'; 3 | import { DefineCommand, Option } from '@artus-cli/artus-cli'; 4 | import utils from '@eggjs/utils'; 5 | import detect from 'detect-port'; 6 | import { BaseCommand } from './base'; 7 | 8 | const debug = debuglog('egg-bin:dev'); 9 | 10 | @DefineCommand({ 11 | command: 'dev', 12 | description: 'Start server at local dev mode', 13 | alias: [ 'd' ], 14 | }) 15 | export class DevCommand extends BaseCommand { 16 | @Option({ 17 | description: 'listening port, default to 7001', 18 | alias: 'p', 19 | }) 20 | port: number; 21 | 22 | @Option({ 23 | description: 'numbers of app workers, default to 1 at local mode', 24 | alias: [ 'c', 'cluster' ], 25 | default: 1, 26 | }) 27 | workers: number; 28 | 29 | @Option({ 30 | description: 'specify framework that can be absolute path or npm package, default is egg', 31 | }) 32 | framework: string; 33 | 34 | @Option({ 35 | description: 'start a sticky cluster server, default to false', 36 | type: 'boolean', 37 | default: false, 38 | }) 39 | sticky: boolean; 40 | 41 | async run() { 42 | debug('run dev: %o', this.ctx.args); 43 | this.ctx.env.NODE_ENV = this.ctx.env.NODE_ENV ?? 'development'; 44 | this.ctx.env.EGG_MASTER_CLOSE_TIMEOUT = '1000'; 45 | const serverBin = path.join(__dirname, '../../scripts/start-cluster.js'); 46 | const eggStartOptions = await this.formatEggStartOptions(); 47 | const args = [ JSON.stringify(eggStartOptions) ]; 48 | const requires = await this.formatRequires(); 49 | const execArgv: string[] = []; 50 | for (const r of requires) { 51 | execArgv.push('--require'); 52 | execArgv.push(r); 53 | } 54 | await this.forkNode(serverBin, args, { execArgv }); 55 | } 56 | 57 | protected async formatEggStartOptions() { 58 | this.framework = utils.getFrameworkPath({ 59 | framework: this.framework, 60 | baseDir: this.base, 61 | }); 62 | 63 | if (!this.port) { 64 | let configuredPort: number | undefined; 65 | try { 66 | const configuration = await utils.getConfig({ 67 | framework: this.framework, 68 | baseDir: this.base, 69 | env: 'local', 70 | }); 71 | configuredPort = configuration?.cluster?.listen?.port; 72 | } catch (err) { 73 | /** skip when failing to read the configuration */ 74 | debug('getConfig error: %s, framework: %o, baseDir: %o, env: local', 75 | err, this.framework, this.base); 76 | } 77 | if (configuredPort) { 78 | this.port = configuredPort; 79 | debug(`use port ${this.port} from configuration file`); 80 | } else { 81 | const defaultPort = process.env.EGG_BIN_DEFAULT_PORT ?? 7001; 82 | debug('detect available port'); 83 | this.port = await detect(defaultPort); 84 | if (this.port !== defaultPort) { 85 | console.warn('[egg-bin] server port %s is in use, now using port %o', 86 | defaultPort, this.port); 87 | } 88 | debug(`use available port ${this.port}`); 89 | } 90 | } 91 | 92 | return { 93 | baseDir: this.base, 94 | workers: this.workers, 95 | port: this.port, 96 | framework: this.framework, 97 | typescript: this.ctx.args.typescript, 98 | tscompiler: this.ctx.args.tscompiler, 99 | sticky: this.sticky, 100 | }; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/cmd/base.ts: -------------------------------------------------------------------------------- 1 | import { debuglog } from 'node:util'; 2 | import { fork, ForkOptions, ChildProcess } from 'node:child_process'; 3 | import { 4 | DefineCommand, 5 | Option, Command, 6 | CommandContext, 7 | Inject, 8 | Utils, 9 | } from '@artus-cli/artus-cli'; 10 | 11 | const debug = debuglog('egg-bin:base'); 12 | 13 | // only hook once and only when ever start any child. 14 | const childs = new Set(); 15 | let hadHook = false; 16 | function gracefull(proc: ChildProcess) { 17 | // save child ref 18 | childs.add(proc); 19 | 20 | // only hook once 21 | /* c8 ignore else */ 22 | if (!hadHook) { 23 | hadHook = true; 24 | let signal: NodeJS.Signals; 25 | [ 'SIGINT', 'SIGQUIT', 'SIGTERM' ].forEach(event => { 26 | process.once(event, () => { 27 | signal = event as NodeJS.Signals; 28 | process.exit(0); 29 | }); 30 | }); 31 | 32 | process.once('exit', (code: number) => { 33 | for (const child of childs) { 34 | debug('process exit code: %o, kill child %o with %o', code, child.pid, signal); 35 | child.kill(signal); 36 | } 37 | }); 38 | } 39 | } 40 | 41 | class ForkError extends Error { 42 | code: number | null; 43 | constructor(message: string, code: number | null) { 44 | super(message); 45 | this.code = code; 46 | } 47 | } 48 | 49 | @DefineCommand() 50 | export abstract class BaseCommand extends Command { 51 | @Option({ 52 | description: 'whether show full command script only, default is false', 53 | alias: 'd', 54 | type: 'boolean', 55 | default: false, 56 | }) 57 | dryRun: boolean; 58 | 59 | @Option({ 60 | description: 'require the given module', 61 | alias: 'r', 62 | array: true, 63 | default: [], 64 | }) 65 | require: string[]; 66 | 67 | @Inject() 68 | ctx: CommandContext; 69 | 70 | @Inject() 71 | utils: Utils; 72 | 73 | // FIXME: should has a better way to init global args default value 74 | protected get base() { 75 | return this.ctx.args.base; 76 | } 77 | 78 | async run() { 79 | await this.utils.redirect([ '--help' ]); 80 | } 81 | 82 | protected async formatRequires() { 83 | const requires = this.require ?? []; 84 | const eggRequire = this.ctx.args.pkgEgg.require; 85 | if (Array.isArray(eggRequire)) { 86 | for (const r of eggRequire) { 87 | requires.push(r); 88 | } 89 | } else if (typeof eggRequire === 'string' && eggRequire) { 90 | requires.push(eggRequire); 91 | } 92 | return requires; 93 | } 94 | 95 | protected async forkNode(modulePath: string, args: string[], options: ForkOptions = {}) { 96 | if (this.dryRun) { 97 | console.log('dry run: $ %o', `${process.execPath} ${modulePath} ${args.join(' ')}`); 98 | return; 99 | } 100 | const forkExecArgv = [ 101 | ...this.ctx.args.execArgv || [], 102 | ...options.execArgv || [], 103 | ]; 104 | 105 | options = { 106 | stdio: 'inherit', 107 | env: this.ctx.env, 108 | cwd: this.base, 109 | ...options, 110 | execArgv: forkExecArgv, 111 | }; 112 | const proc = fork(modulePath, args, options); 113 | debug('Run fork pid: %o, `%s %s %s`', 114 | proc.pid, process.execPath, modulePath, args.join(' ')); 115 | gracefull(proc); 116 | 117 | return new Promise((resolve, reject) => { 118 | proc.once('exit', code => { 119 | debug('fork pid: %o exit code %o', proc.pid, code); 120 | childs.delete(proc); 121 | if (code !== 0) { 122 | const err = new ForkError(modulePath + ' ' + args.join(' ') + ' exit with code ' + code, code); 123 | reject(err); 124 | } else { 125 | resolve(); 126 | } 127 | }); 128 | }); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/cmd/test.ts: -------------------------------------------------------------------------------- 1 | import { debuglog } from 'node:util'; 2 | import os from 'node:os'; 3 | import fs from 'node:fs/promises'; 4 | import path from 'node:path'; 5 | import { 6 | DefineCommand, Option, 7 | } from '@artus-cli/artus-cli'; 8 | import globby from 'globby'; 9 | import { getChangedFilesForRoots } from 'jest-changed-files'; 10 | import { BaseCommand } from './base'; 11 | 12 | const debug = debuglog('egg-bin:test'); 13 | 14 | @DefineCommand({ 15 | command: 'test [files...]', 16 | description: 'Run the test', 17 | alias: [ 't' ], 18 | }) 19 | export class TestCommand extends BaseCommand { 20 | @Option({ 21 | default: [], 22 | array: true, 23 | type: 'string', 24 | }) 25 | files: string[]; 26 | 27 | @Option({ 28 | description: 'set test-case timeout in milliseconds, default is 60000', 29 | alias: 't', 30 | default: process.env.TEST_TIMEOUT ?? 60000, 31 | }) 32 | timeout: number | boolean; 33 | 34 | @Option({ 35 | description: 'only run tests matching ', 36 | alias: 'g', 37 | type: 'string', 38 | array: true, 39 | default: [], 40 | }) 41 | grep: string[]; 42 | 43 | @Option({ 44 | description: 'only test with changed files and match test/**/*.test.(js|ts), default is false', 45 | alias: 'c', 46 | type: 'boolean', 47 | default: false, 48 | }) 49 | changed: boolean; 50 | 51 | @Option({ 52 | description: 'mocha parallel mode, default is false', 53 | alias: 'p', 54 | type: 'boolean', 55 | default: false, 56 | }) 57 | parallel: boolean; 58 | 59 | @Option({ 60 | description: 'number of jobs to run in parallel', 61 | type: 'number', 62 | default: os.cpus().length - 1, 63 | }) 64 | jobs: number; 65 | 66 | @Option({ 67 | description: 'auto bootstrap agent in mocha master process, default is true', 68 | type: 'boolean', 69 | default: true, 70 | }) 71 | autoAgent: boolean; 72 | 73 | @Option({ 74 | description: 'enable mochawesome reporter, default is true', 75 | type: 'boolean', 76 | default: true, 77 | }) 78 | mochawesome: boolean; 79 | 80 | @Option({ 81 | description: 'bbort ("bail") after first test failure', 82 | alias: 'b', 83 | type: 'boolean', 84 | default: false, 85 | }) 86 | bail: boolean; 87 | 88 | async run() { 89 | try { 90 | await fs.access(this.base); 91 | } catch (err) { 92 | console.error('baseDir: %o not exists', this.base); 93 | throw err; 94 | } 95 | 96 | const mochaFile = process.env.MOCHA_FILE || require.resolve('mocha/bin/_mocha'); 97 | if (this.parallel) { 98 | this.ctx.env.ENABLE_MOCHA_PARALLEL = 'true'; 99 | if (this.autoAgent) { 100 | this.ctx.env.AUTO_AGENT = 'true'; 101 | } 102 | } 103 | // set NODE_ENV=test, let egg application load unittest logic 104 | // https://eggjs.org/basics/env#difference-from-node_env 105 | this.ctx.env.NODE_ENV = 'test'; 106 | debug('run test: %s %o', mochaFile, this.ctx.args); 107 | 108 | const mochaArgs = await this.formatMochaArgs(); 109 | if (!mochaArgs) return; 110 | await this.forkNode(mochaFile, mochaArgs, { 111 | execArgv: [ 112 | ...process.execArgv, 113 | // https://github.com/mochajs/mocha/issues/2640#issuecomment-1663388547 114 | '--unhandled-rejections=strict', 115 | ], 116 | }); 117 | } 118 | 119 | protected async formatMochaArgs() { 120 | // collect require 121 | const requires = await this.formatRequires(); 122 | try { 123 | const eggMockRegister = require.resolve('egg-mock/register', { paths: [ this.base ] }); 124 | requires.push(eggMockRegister); 125 | debug('auto register egg-mock: %o', eggMockRegister); 126 | } catch (err) { 127 | // ignore egg-mock not exists 128 | debug('auto register egg-mock fail, can not require egg-mock on %o, error: %s', 129 | this.base, (err as Error).message); 130 | } 131 | 132 | // handle mochawesome enable 133 | let reporter = this.ctx.env.TEST_REPORTER; 134 | let reporterOptions = ''; 135 | if (!reporter && this.mochawesome) { 136 | // use https://github.com/node-modules/mochawesome/pull/1 instead 137 | reporter = require.resolve('mochawesome-with-mocha'); 138 | reporterOptions = 'reportDir=node_modules/.mochawesome-reports'; 139 | if (this.parallel) { 140 | // https://github.com/adamgruber/mochawesome#parallel-mode 141 | requires.push(require.resolve('mochawesome-with-mocha/register')); 142 | } 143 | } 144 | 145 | const ext = this.ctx.args.typescript ? 'ts' : 'js'; 146 | let pattern = this.files; 147 | // changed 148 | if (this.changed) { 149 | pattern = await this.getChangedTestFiles(this.base, ext); 150 | if (!pattern.length) { 151 | console.log('No changed test files'); 152 | return; 153 | } 154 | debug('changed files: %o', pattern); 155 | } 156 | 157 | if (!pattern.length && process.env.TESTS) { 158 | pattern = process.env.TESTS.split(','); 159 | } 160 | 161 | // collect test files when nothing is changed 162 | if (!pattern.length) { 163 | pattern = [ `test/**/*.test.${ext}` ]; 164 | } 165 | pattern = pattern.concat([ '!test/fixtures', '!test/node_modules' ]); 166 | 167 | // expand glob and skip node_modules and fixtures 168 | const files = globby.sync(pattern, { cwd: this.base }); 169 | files.sort(); 170 | 171 | if (files.length === 0) { 172 | console.log(`No test files found with ${pattern}`); 173 | return; 174 | } 175 | 176 | // auto add setup file as the first test file 177 | const setupFile = path.join(this.base, `test/.setup.${ext}`); 178 | try { 179 | await fs.access(setupFile); 180 | files.unshift(setupFile); 181 | } catch { 182 | // ignore 183 | } 184 | 185 | return [ 186 | this.dryRun ? '--dry-run' : '', 187 | // force exit 188 | '--exit', 189 | this.bail ? '--bail' : '', 190 | this.grep.map(pattern => `--grep='${pattern}'`).join(' '), 191 | this.timeout === false ? '--no-timeout' : `--timeout=${this.timeout}`, 192 | this.parallel ? '--parallel' : '', 193 | this.parallel && this.jobs ? `--jobs=${this.jobs}` : '', 194 | reporter ? `--reporter=${reporter}` : '', 195 | reporterOptions ? `--reporter-options=${reporterOptions}` : '', 196 | ...requires.map(r => `--require=${r}`), 197 | ...files, 198 | ].filter(a => a.trim()); 199 | } 200 | 201 | protected async getChangedTestFiles(dir: string, ext: string) { 202 | const res = await getChangedFilesForRoots([ path.join(dir, 'test') ], {}); 203 | const changedFiles = res.changedFiles; 204 | const files: string[] = []; 205 | for (let cf of changedFiles) { 206 | // only find test/**/*.test.(js|ts) 207 | if (cf.endsWith(`.test.${ext}`)) { 208 | // Patterns MUST use forward slashes (not backslashes) 209 | // This should be converted on Windows 210 | if (process.platform === 'win32') { 211 | cf = cf.replace(/\\/g, '/'); 212 | } 213 | files.push(cf); 214 | } 215 | } 216 | return files; 217 | } 218 | } 219 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # egg-bin 2 | 3 | [![NPM version][npm-image]][npm-url] 4 | [![build status][ci-image]][ci-url] 5 | [![Test coverage][codecov-image]][codecov-url] 6 | [![Known Vulnerabilities][snyk-image]][snyk-url] 7 | [![npm download][download-image]][download-url] 8 | [![Node.js Version][node-version-image]][node-version-url] 9 | 10 | [npm-image]: https://img.shields.io/npm/v/egg-bin.svg?style=flat-square 11 | [npm-url]: https://npmjs.org/package/egg-bin 12 | [ci-image]: https://github.com/eggjs/egg-bin/actions/workflows/nodejs.yml/badge.svg 13 | [ci-url]: https://github.com/eggjs/egg-bin/actions/workflows/nodejs.yml 14 | [codecov-image]: https://codecov.io/gh/eggjs/egg-bin/branch/master/graph/badge.svg 15 | [codecov-url]: https://codecov.io/gh/eggjs/egg-bin 16 | [snyk-image]: https://snyk.io/test/npm/egg-bin/badge.svg?style=flat-square 17 | [snyk-url]: https://snyk.io/test/npm/egg-bin 18 | [download-image]: https://img.shields.io/npm/dm/egg-bin.svg?style=flat-square 19 | [download-url]: https://npmjs.org/package/egg-bin 20 | [node-version-image]: https://img.shields.io/node/v/egg-bin.svg?style=flat-square 21 | [node-version-url]: https://nodejs.org/en/download/ 22 | 23 | egg developer tool, extends [@artus-cli/artus-cli]. 24 | 25 | --- 26 | 27 | ## Install 28 | 29 | ```bash 30 | npm i egg-bin --save-dev 31 | ``` 32 | 33 | ## Usage 34 | 35 | Add `egg-bin` to `package.json` scripts: 36 | 37 | ```json 38 | { 39 | "scripts": { 40 | "dev": "egg-bin dev", 41 | "test-local": "egg-bin test", 42 | "test": "npm run lint -- --fix && npm run test-local", 43 | "cov": "egg-bin cov", 44 | "lint": "eslint .", 45 | "ci": "npm run lint && npm run cov" 46 | } 47 | } 48 | ``` 49 | 50 | ## Command 51 | 52 | All the commands support these specific options: 53 | 54 | - `--inspect` 55 | - `--inspect-brk` 56 | - `--typescript` / `--ts` enable typescript support. Auto detect from `package.json`'s `pkg.egg.typescript`, 57 | or `pkg.dependencies.typescript`/`pkg.devDependencies.typescript`. 58 | - `--base` / `--baseDir` application's root path, default to `process.cwd()`. 59 | - `--require` will add to `execArgv`, support multiple. Also support read from `package.json`'s `pkg.egg.require` 60 | - `--dry-run` / `-d` whether dry-run the test command, just show the command 61 | 62 | ```bash 63 | egg-bin [command] --inspect 64 | egg-bin [command] --inspect-brk 65 | egg-bin [command] --typescript 66 | egg-bin [command] --base /foo/bar 67 | ``` 68 | 69 | ### dev 70 | 71 | Start dev cluster on `local` env, it will start a master, an agent and a worker. 72 | 73 | ```bash 74 | egg-bin dev 75 | ``` 76 | 77 | #### dev options 78 | 79 | - `--framework` egg web framework root path. 80 | - `--port` server port. If not specified, the port is obtained in the following order: [_egg.js_ configuration](https://www.eggjs.org/basics/config) `config/config.*.js` > `process.env.EGG_BIN_DEFAULT_PORT` > 7001 > other available ports. 81 | - `--workers` worker process number, default to `1` worker at local mode. 82 | - `--sticky` start a sticky cluster server, default to `false`. 83 | 84 | #### debug/inspect on VSCode 85 | 86 | Create `.vscode/launch.json` file: 87 | 88 | ```json 89 | { 90 | "version": "0.2.0", 91 | "configurations": [ 92 | { 93 | "type": "node", 94 | "request": "launch", 95 | "name": "Egg Debug", 96 | "runtimeExecutable": "npm", 97 | "runtimeArgs": [ 98 | "run", 99 | "dev", 100 | "--", 101 | "--inspect-brk" 102 | ], 103 | "console": "integratedTerminal", 104 | "restart": true, 105 | "protocol": "auto", 106 | "port": 9229, 107 | "autoAttachChildProcesses": true 108 | }, 109 | { 110 | "type": "node", 111 | "request": "launch", 112 | "name": "Egg Test", 113 | "runtimeExecutable": "npm", 114 | "runtimeArgs": [ 115 | "run", 116 | "test-local", 117 | "--", 118 | "--inspect-brk" 119 | ], 120 | "protocol": "auto", 121 | "port": 9229, 122 | "autoAttachChildProcesses": true 123 | } 124 | ] 125 | } 126 | ``` 127 | 128 | ### test 129 | 130 | Using [mocha] to run test. 131 | 132 | ```bash 133 | egg-bin test [...files] [options] 134 | ``` 135 | 136 | - `files` is optional, default to `test/**/*.test.ts` 137 | - `test/fixtures`, `test/node_modules` is always exclude. 138 | 139 | #### auto require `test/.setup.ts` 140 | 141 | If `test/.setup.ts` file exists, it will be auto require as the first test file. 142 | 143 | ```bash 144 | test 145 | ├── .setup.ts 146 | └── foo.test.ts 147 | ``` 148 | 149 | #### test options 150 | 151 | You can pass any mocha argv. 152 | 153 | - `--timeout` milliseconds, default to 60000 154 | - `--changed` / `-c` only test changed test files(test files means files that match `${pwd}/test/**/*.test.(js|ts)`) 155 | - `--parallel` enable mocha parallel mode, default to `false`. 156 | - `--auto-agent` auto start agent in mocha master agent. 157 | - `--jobs` number of jobs to run in parallel, default to `os.cpus().length - 1`. 158 | - `--mochawesome` enable [mochawesome](https://github.com/adamgruber/mochawesome) reporter, default to `true`. 159 | 160 | #### test environment 161 | 162 | Environment is also support, will use it if options not provide. 163 | 164 | You can set `TESTS` env to set the tests directory, it support [glob] grammar. 165 | 166 | ```bash 167 | TESTS=test/a.test.ts egg-bin test 168 | ``` 169 | 170 | And the reporter can set by the `TEST_REPORTER` env, default is `spec`. 171 | 172 | ```bash 173 | TEST_REPORTER=doc egg-bin test 174 | ``` 175 | 176 | The test timeout can set by `TEST_TIMEOUT` env, default is `60000` ms. 177 | 178 | ```bash 179 | TEST_TIMEOUT=2000 egg-bin test 180 | ``` 181 | 182 | ### cov 183 | 184 | Using [mocha] and [c8] to run code coverage, it support all test params above. 185 | 186 | Coverage reporter will output text-summary, json and lcov. 187 | 188 | #### cov options 189 | 190 | You can pass any mocha argv. 191 | 192 | - `-x` add dir ignore coverage, support multiple argv 193 | - `--prerequire` prerequire files for coverage instrument, you can use this options if load files slowly when call `mm.app` or `mm.cluster` 194 | - `--typescript` / `--ts` enable typescript support. If true, will auto add `.ts` extension and ignore `typings` and `d.ts`. 195 | - `--c8` c8 instruments passthrough. you can use this to overwrite egg-bin's default c8 instruments and add additional ones. 196 | > 197 | > - egg-bin have some default instruments passed to c8 like `-r` and `--temp-directory` 198 | > - `egg-bin cov --c8="-r teamcity -r text" --c8-report=true` 199 | > 200 | - also support all test params above. 201 | 202 | #### cov environment 203 | 204 | You can set `COV_EXCLUDES` env to add dir ignore coverage. 205 | 206 | ```bash 207 | COV_EXCLUDES="app/plugins/c*,app/autocreate/**" egg-bin cov 208 | ``` 209 | 210 | ## Custom egg-bin for your team 211 | 212 | See 213 | 214 | ## License 215 | 216 | [MIT](LICENSE) 217 | 218 | ## Contributors 219 | 220 | [![Contributors](https://contrib.rocks/image?repo=eggjs/egg-bin)](https://github.com/eggjs/egg-bin/graphs/contributors) 221 | 222 | Made with [contributors-img](https://contrib.rocks). 223 | 224 | [mocha]: https://mochajs.org 225 | [glob]: https://github.com/isaacs/node-glob 226 | [@artus-cli/artus-cli]: https://github.com/artus-cli/artus-cli 227 | -------------------------------------------------------------------------------- /src/middleware/global_options.ts: -------------------------------------------------------------------------------- 1 | import { debuglog } from 'node:util'; 2 | import path from 'node:path'; 3 | import { pathToFileURL } from 'node:url'; 4 | import { 5 | Inject, ApplicationLifecycle, LifecycleHook, LifecycleHookUnit, 6 | Program, CommandContext, 7 | } from '@artus-cli/artus-cli'; 8 | import { runScript } from 'runscript'; 9 | import { addNodeOptionsToEnv, readPackageJSON, hasTsConfig } from '../utils'; 10 | 11 | const debug = debuglog('egg-bin:midddleware:global_options'); 12 | 13 | @LifecycleHookUnit() 14 | export default class GlobalOptions implements ApplicationLifecycle { 15 | @Inject() 16 | private readonly program: Program; 17 | 18 | @LifecycleHook() 19 | async configDidLoad() { 20 | // add global options 21 | this.program.option({ 22 | base: { 23 | description: 'directory of application, default to `process.cwd()`', 24 | type: 'string', 25 | alias: 'baseDir', 26 | }, 27 | declarations: { 28 | description: 'whether create typings, will add `--require egg-ts-helper/register`', 29 | type: 'boolean', 30 | alias: 'dts', 31 | }, 32 | typescript: { 33 | description: 'whether enable typescript support', 34 | type: 'boolean', 35 | alias: 'ts', 36 | }, 37 | tscompiler: { 38 | description: 'ts compiler, like ts-node/register, ts-node/register/transpile-only, @swc-node/register, esbuild-register etc', 39 | type: 'string', 40 | alias: 'tsc', 41 | }, 42 | }); 43 | 44 | this.program.use(async (ctx: CommandContext, next) => { 45 | debug('before next'); 46 | if (!ctx.args.base) { 47 | ctx.args.base = ctx.cwd; 48 | debug('ctx.args.base not set, auto set it to cwd: %o', ctx.cwd); 49 | } 50 | if (!path.isAbsolute(ctx.args.base)) { 51 | ctx.args.base = path.join(ctx.cwd, ctx.args.base); 52 | } 53 | debug('matched cmd: %o, ctx.args.base: %o', ctx.matched?.cmd, ctx.args.base); 54 | const pkg = await readPackageJSON(ctx.args.base); 55 | ctx.args.pkgEgg = pkg.egg ?? {}; 56 | const tscompiler = ctx.args.tscompiler ?? ctx.env.TS_COMPILER ?? ctx.args.pkgEgg.tscompiler; 57 | if (ctx.args.typescript === undefined) { 58 | // try to ready EGG_TYPESCRIPT env first, only accept 'true' or 'false' string 59 | if (ctx.env.EGG_TYPESCRIPT === 'false') { 60 | ctx.args.typescript = false; 61 | debug('detect typescript=%o from EGG_TYPESCRIPT=%o', false, ctx.env.EGG_TYPESCRIPT); 62 | } else if (ctx.env.EGG_TYPESCRIPT === 'true') { 63 | ctx.args.typescript = true; 64 | debug('detect typescript=%o from EGG_TYPESCRIPT=%o', true, ctx.env.EGG_TYPESCRIPT); 65 | } else if (typeof ctx.args.pkgEgg.typescript === 'boolean') { 66 | // read `egg.typescript` from package.json if not pass argv 67 | ctx.args.typescript = ctx.args.pkgEgg.typescript; 68 | debug('detect typescript=%o from pkg.egg.typescript=%o', true, ctx.args.pkgEgg.typescript); 69 | } else if (pkg.dependencies?.typescript) { 70 | // auto detect pkg.dependencies.typescript or pkg.devDependencies.typescript 71 | ctx.args.typescript = true; 72 | debug('detect typescript=%o from pkg.dependencies.typescript=%o', true, pkg.dependencies.typescript); 73 | } else if (pkg.devDependencies?.typescript) { 74 | ctx.args.typescript = true; 75 | debug('detect typescript=%o from pkg.devDependencies.typescript=%o', true, pkg.devDependencies.typescript); 76 | } else if (await hasTsConfig(ctx.args.base)) { 77 | // tsconfig.json exists 78 | ctx.args.typescript = true; 79 | debug('detect typescript=%o cause tsconfig.json exists', true); 80 | } else if (tscompiler) { 81 | ctx.args.typescript = true; 82 | debug('detect typescript=%o from --tscompiler=%o', true, tscompiler); 83 | } 84 | } 85 | 86 | if (ctx.args.typescript) { 87 | const findPaths = [ path.dirname(__dirname) ]; 88 | if (tscompiler) { 89 | // try app baseDir first on custom tscompiler 90 | findPaths.unshift(ctx.args.base); 91 | } 92 | ctx.args.tscompiler = tscompiler ?? 'ts-node/register'; 93 | const tsNodeRegister = require.resolve(ctx.args.tscompiler, { 94 | paths: findPaths, 95 | }); 96 | // should require tsNodeRegister on current process, let it can require *.ts files 97 | // e.g.: dev command will execute egg loader to find configs and plugins 98 | require(tsNodeRegister); 99 | // let child process auto require ts-node too 100 | addNodeOptionsToEnv(`--require ${tsNodeRegister}`, ctx.env); 101 | // tell egg loader to load ts file 102 | // see https://github.com/eggjs/egg-core/blob/master/lib/loader/egg_loader.js#L443 103 | ctx.env.EGG_TYPESCRIPT = 'true'; 104 | // set current process.env.EGG_TYPESCRIPT too 105 | process.env.EGG_TYPESCRIPT = 'true'; 106 | // load files from tsconfig on startup 107 | ctx.env.TS_NODE_FILES = process.env.TS_NODE_FILES ?? 'true'; 108 | // keep same logic with egg-core, test cmd load files need it 109 | // see https://github.com/eggjs/egg-core/blob/master/lib/loader/egg_loader.js#L49 110 | addNodeOptionsToEnv(`--require ${require.resolve('tsconfig-paths/register')}`, ctx.env); 111 | } 112 | if (pkg.type === 'module') { 113 | // use ts-node/esm loader on esm 114 | let esmLoader = require.resolve('ts-node/esm'); 115 | if (process.platform === 'win32') { 116 | // ES Module loading with abolute path fails on windows 117 | // https://github.com/nodejs/node/issues/31710#issuecomment-583916239 118 | // https://nodejs.org/api/url.html#url_url_pathtofileurl_path 119 | esmLoader = pathToFileURL(esmLoader).href; 120 | } 121 | // wait for https://github.com/nodejs/node/issues/40940 122 | addNodeOptionsToEnv('--no-warnings', ctx.env); 123 | addNodeOptionsToEnv(`--loader ${esmLoader}`, ctx.env); 124 | } 125 | 126 | if (ctx.args.declarations === undefined) { 127 | if (typeof ctx.args.pkgEgg.declarations === 'boolean') { 128 | // read `egg.declarations` from package.json if not pass argv 129 | ctx.args.declarations = ctx.args.pkgEgg.declarations; 130 | debug('detect declarations from pkg.egg.declarations=%o', ctx.args.pkgEgg.declarations); 131 | } 132 | } 133 | if (ctx.args.declarations) { 134 | const etsBin = require.resolve('egg-ts-helper/dist/bin'); 135 | debug('run ets first: %o', etsBin); 136 | await runScript(`node ${etsBin}`); 137 | } 138 | 139 | if (ctx.args.pkgEgg.revert) { 140 | ctx.args.execArgv = ctx.args.execArgv || []; 141 | const reverts = Array.isArray(ctx.args.pkgEgg.revert) ? ctx.args.pkgEgg.revert : [ ctx.args.pkgEgg.revert ]; 142 | for (const revert of reverts) { 143 | ctx.args.execArgv.push(`--security-revert=${revert}`); 144 | } 145 | } 146 | 147 | debug('set NODE_OPTIONS: %o', ctx.env.NODE_OPTIONS); 148 | debug('ctx.args: %o', ctx.args); 149 | debug('enter next'); 150 | await next(); 151 | debug('after next'); 152 | }); 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /test/cmd/dev.test.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | import net from 'node:net'; 3 | import detect from 'detect-port'; 4 | import mm from 'mm'; 5 | import coffee from '../coffee'; 6 | 7 | const version = Number(process.version.substring(1, 3)); 8 | 9 | describe('test/cmd/dev.test.ts', () => { 10 | const eggBin = path.join(__dirname, '../../src/bin/cli.ts'); 11 | const fixtures = path.join(__dirname, '../fixtures'); 12 | const cwd = path.join(fixtures, 'demo-app'); 13 | 14 | it('should startCluster success', () => { 15 | return coffee.fork(eggBin, [ 'dev' ], { 16 | cwd, 17 | // env: { NODE_DEBUG: 'egg-bin*' }, 18 | }) 19 | // .debug() 20 | .expect('stdout', /"workers":1/) 21 | .expect('stdout', /"baseDir":".*?demo-app"/) 22 | .expect('stdout', /"framework":".*?aliyun-egg"/) 23 | .expect('stdout', /NODE_ENV: development/) 24 | .expect('code', 0) 25 | .end(); 26 | }); 27 | 28 | it('should dev start with custom NODE_ENV', () => { 29 | return coffee.fork(eggBin, [ 'dev' ], { cwd, env: { NODE_ENV: 'prod' } }) 30 | // .debug() 31 | .expect('stdout', /"workers":1/) 32 | .expect('stdout', /"baseDir":".*?demo-app"/) 33 | .expect('stdout', /"framework":".*?aliyun-egg"/) 34 | .expect('stdout', /NODE_ENV: prod/) 35 | .expect('code', 0) 36 | .end(); 37 | }); 38 | 39 | it('should dev start work with declarations = true', () => { 40 | const cwd = path.join(fixtures, 'example-declarations'); 41 | return coffee.fork(eggBin, [ 'dev' ], { cwd }) 42 | .debug() 43 | .expect('stdout', /"workers":1/) 44 | .expect('stdout', /"baseDir":".*?example-declarations"/) 45 | .expect('stdout', /"framework":".*?egg"/) 46 | .expect('stdout', /\[egg-ts-helper\] create typings/) 47 | .expect('code', 0) 48 | .end(); 49 | }); 50 | 51 | it('should startCluster with --port', () => { 52 | return coffee.fork(eggBin, [ 'dev', '--port', '6001' ], { cwd }) 53 | // .debug() 54 | .expect('stdout', /"workers":1/) 55 | .expect('stdout', /"port":6001/) 56 | .expect('stdout', /"baseDir":".*?demo-app"/) 57 | .expect('stdout', /"framework":".*?aliyun-egg"/) 58 | .expect('code', 0) 59 | .end(); 60 | }); 61 | 62 | it('should startCluster with --sticky', () => { 63 | return coffee.fork(eggBin, [ 'dev', '--port', '6001', '--sticky' ], { cwd }) 64 | // .debug() 65 | .expect('stdout', /"workers":1/) 66 | .expect('stdout', /"port":6001/) 67 | .expect('stdout', /"sticky":true/) 68 | .expect('stdout', /"baseDir":".*?demo-app"/) 69 | .expect('stdout', /"framework":".*?aliyun-egg"/) 70 | .expect('code', 0) 71 | .end(); 72 | }); 73 | 74 | it('should startCluster with -p', () => { 75 | return coffee.fork(eggBin, [ 'dev', '-p', '6001' ], { cwd }) 76 | // .debug() 77 | .expect('stdout', /"workers":1/) 78 | .expect('stdout', /"port":6001/) 79 | .expect('stdout', /"baseDir":".*?demo-app"/) 80 | .expect('stdout', /"framework":".*?aliyun-egg"/) 81 | .expect('code', 0) 82 | .end(); 83 | }); 84 | 85 | it('should startCluster with --cluster=2', () => { 86 | return coffee.fork(eggBin, [ 'dev', '--cluster=2' ], { cwd }) 87 | // .debug() 88 | .expect('stdout', /"workers":2/) 89 | .expect('stdout', /"baseDir":".*?demo-app"/) 90 | .expect('stdout', /"framework":".*?aliyun-egg"/) 91 | .notExpect('stdout', /"cluster"/) 92 | .expect('code', 0) 93 | .end(); 94 | }); 95 | 96 | it('should startCluster with --workers=2', () => { 97 | return coffee.fork(eggBin, [ 'dev', '--workers=2' ], { cwd }) 98 | // .debug() 99 | .expect('stdout', /"workers":2/) 100 | .expect('stdout', /"baseDir":".*?demo-app"/) 101 | .expect('stdout', /"framework":".*?aliyun-egg"/) 102 | .notExpect('stdout', /"cluster"/) 103 | .expect('code', 0) 104 | .end(); 105 | }); 106 | 107 | it('should startCluster with --baseDir=root', () => { 108 | return coffee.fork(eggBin, [ 'dev', `--baseDir=${cwd}` ]) 109 | // .debug() 110 | .expect('stdout', /"workers":1/) 111 | .expect('stdout', /"baseDir":".*?demo-app"/) 112 | .expect('stdout', /"framework":".*?aliyun-egg"/) 113 | .expect('code', 0) 114 | .end(); 115 | }); 116 | 117 | it('should startCluster with custom yadan framework', () => { 118 | const baseDir = path.join(fixtures, 'custom-framework-app'); 119 | return coffee.fork(eggBin, [ 'dev' ], { cwd: baseDir }) 120 | // .debug() 121 | .expect('stdout', /yadan start:/) 122 | .expect('stdout', /"workers":1/) 123 | .expect('stdout', /"baseDir":".*?custom-framework-app"/) 124 | .expect('stdout', /"framework":".*?yadan"/) 125 | .expect('code', 0) 126 | .end(); 127 | }); 128 | 129 | it('should startCluster with execArgv --inspect', () => { 130 | return coffee.fork(eggBin, [ 'dev', '--inspect' ], { cwd }) 131 | // .debug() 132 | .expect('stderr', /Debugger listening on ws:\/\/127.0.0.1:\d+/) 133 | .expect('code', 0) 134 | .end(); 135 | }); 136 | 137 | it('should support --require', () => { 138 | const script = path.join(fixtures, 'require-script'); 139 | return coffee.fork(eggBin, [ 'dev', '--require', script ], { cwd }) 140 | // .debug() 141 | .expect('stdout', /hey, you require me by --require/) 142 | .expect('code', 0) 143 | .end(); 144 | }); 145 | 146 | it('should support egg.require', () => { 147 | return coffee.fork(eggBin, [ 'dev' ], { 148 | cwd: path.join(fixtures, 'egg-require'), 149 | }) 150 | // .debug() 151 | .expect('stdout', /hey, you require me by --require/) 152 | .expect('code', 0) 153 | .end(); 154 | }); 155 | 156 | describe('auto detect available port', () => { 157 | let server; 158 | let serverPort; 159 | before(async () => { 160 | serverPort = await detect(7001); 161 | server = net.createServer(); 162 | await new Promise(resolve => { 163 | server.listen(serverPort, resolve); 164 | }); 165 | }); 166 | 167 | after(() => server.close()); 168 | 169 | it('should auto detect available port', done => { 170 | coffee.fork(eggBin, [ 'dev' ], { 171 | cwd, 172 | env: { EGG_BIN_DEFAULT_PORT: serverPort }, 173 | }) 174 | // .debug() 175 | .expect('stderr', /\[egg-bin] server port \d+ is in use, now using port \d+/) 176 | .expect('code', 0) 177 | .end(done); 178 | }); 179 | }); 180 | 181 | describe('obtain the port from config.*.js', () => { 182 | const cwd = path.join(fixtures, 'example-port'); 183 | it('should obtain the port from config.default.js', () => { 184 | coffee.fork(eggBin, [ 'dev' ], { 185 | cwd, 186 | }) 187 | .expect('stdout', /"port":6001/) 188 | .expect('code', 0) 189 | .end(); 190 | }); 191 | }); 192 | 193 | it('should support egg.revert', () => { 194 | if (version < 18 || version > 20) return; 195 | mm(process.env, 'NODE_ENV', 'development'); 196 | return coffee.fork(eggBin, [ 'dev' ], { 197 | cwd: path.join(__dirname, '../fixtures/egg-revert'), 198 | }) 199 | // .debug() 200 | .expect('stdout', /SECURITY WARNING: Reverting CVE-2023-46809: Marvin attack on PKCS#1 padding/) 201 | .expect('code', 0) 202 | .end(); 203 | }); 204 | }); 205 | -------------------------------------------------------------------------------- /test/cmd/cov.test.ts: -------------------------------------------------------------------------------- 1 | import assert from 'node:assert'; 2 | import path from 'node:path'; 3 | import fs from 'node:fs/promises'; 4 | import assertFile from 'assert-file'; 5 | import mm from 'mm'; 6 | 7 | import coffee from '../coffee'; 8 | 9 | const version = Number(process.version.substring(1, 3)); 10 | 11 | describe('test/cmd/cov.test.ts', () => { 12 | const eggBin = path.join(__dirname, '../../src/bin/cli.ts'); 13 | const fixtures = path.join(__dirname, '../fixtures'); 14 | const cwd = path.join(fixtures, 'test-files'); 15 | 16 | async function assertCoverage(baseDir: string) { 17 | assertFile(path.join(baseDir, 'coverage/coverage-final.json')); 18 | assertFile(path.join(baseDir, 'coverage/coverage-summary.json')); 19 | assertFile(path.join(baseDir, 'coverage/lcov-report/index.html')); 20 | assertFile(path.join(baseDir, 'coverage/lcov.info')); 21 | assertFile(path.join(baseDir, 'coverage/cobertura-coverage.xml')); 22 | } 23 | 24 | describe('egg-bin cov', () => { 25 | it('should success on js', async () => { 26 | await coffee.fork(eggBin, [ 'cov', '--ts=false' ], { cwd, env: { TESTS: 'test/**/*.test.js' } }) 27 | // .debug() 28 | .expect('stdout', /should success/) 29 | .expect('stdout', /a\.test\.js/) 30 | .expect('stdout', /b[\/|\\]b\.test\.js/) 31 | .notExpect('stdout', /\ba\.js/) 32 | .expect('stdout', /Statements {3}:/) 33 | .expect('code', 0) 34 | .end(); 35 | assertCoverage(cwd); 36 | const lcov = await fs.readFile(path.join(cwd, 'coverage/lcov.info'), 'utf8'); 37 | assert.match(lcov, /ignore[\/|\\]a.js/); 38 | }); 39 | 40 | it('should success on ts', async () => { 41 | const cwd = path.join(fixtures, 'example-ts'); 42 | await coffee.fork(eggBin, [ 'cov' ], { cwd }) 43 | // .debug() 44 | .expect('stdout', /should work/) 45 | .expect('stdout', /1 passing/) 46 | .expect('stdout', /Statements\s+: 100% \( \d+\/\d+ \)/) 47 | .expect('code', 0) 48 | .end(); 49 | assertCoverage(cwd); 50 | const lcov = await fs.readFile(path.join(cwd, 'coverage/lcov.info'), 'utf8'); 51 | assert.match(lcov, /SF:app\.ts/); 52 | }); 53 | 54 | it('should success with COV_EXCLUDES', async () => { 55 | await coffee.fork(eggBin, [ 'cov', '--ts=false' ], { 56 | cwd, 57 | env: { 58 | TESTS: 'test/**/*.test.js', 59 | COV_EXCLUDES: 'ignore/*', 60 | }, 61 | }) 62 | // .debug() 63 | .expect('stdout', /should success/) 64 | .expect('stdout', /a\.test\.js/) 65 | .expect('stdout', /b[\/|\\]b\.test\.js/) 66 | .notExpect('stdout', /a.js/) 67 | .expect('stdout', /Statements {3}:/) 68 | .expect('code', 0) 69 | .end(); 70 | assertCoverage(cwd); 71 | const lcov = await fs.readFile(path.join(cwd, 'coverage/lcov.info'), 'utf8'); 72 | assert.doesNotMatch(lcov, /ignore[\/|\\]a.js/); 73 | }); 74 | 75 | it('should success with -x to ignore one dirs', async () => { 76 | await coffee.fork(eggBin, [ 'cov', '-x', 'ignore/', 'test/**/*.test.js', '--ts=false' ], { cwd }) 77 | // .debug() 78 | .expect('stdout', /should success/) 79 | .expect('stdout', /a\.test\.js/) 80 | .expect('stdout', /b[\/|\\]b\.test\.js/) 81 | .notExpect('stdout', /a.js/) 82 | .expect('stdout', /Statements {3}:/) 83 | .expect('code', 0) 84 | .end(); 85 | assertCoverage(cwd); 86 | const lcov = await fs.readFile(path.join(cwd, 'coverage/lcov.info'), 'utf8'); 87 | assert.doesNotMatch(lcov, /ignore[\/|\\]a.js/); 88 | }); 89 | 90 | it('should success with -x to ignore multi dirs', async () => { 91 | await coffee.fork(eggBin, [ 92 | 'cov', 93 | '-x', 'ignore2/*', 94 | '-x', 'ignore/', 95 | '--ts=false', 96 | 'test/**/*.test.js', 97 | ], { cwd }) 98 | // .debug() 99 | .expect('stdout', /should success/) 100 | .expect('stdout', /a\.test\.js/) 101 | .expect('stdout', /b[\/|\\]b\.test\.js/) 102 | .notExpect('stdout', /a.js/) 103 | .expect('stdout', /Statements {3}:/) 104 | .expect('code', 0) 105 | .end(); 106 | assertCoverage(cwd); 107 | const lcov = await fs.readFile(path.join(cwd, 'coverage/lcov.info'), 'utf8'); 108 | assert.doesNotMatch(lcov, /ignore[\/|\\]a.js/); 109 | }); 110 | 111 | it('should exit when not test files', () => { 112 | return coffee.fork(eggBin, [ 'cov', 'test/**/*.nth.js', '--ts=false' ], { cwd }) 113 | // .debug() 114 | .expect('stdout', /No test files found/) 115 | .expect('code', 0) 116 | .end(); 117 | }); 118 | 119 | it('should grep pattern without error', () => { 120 | return coffee.fork(eggBin, [ 'cov', 'test/a.test.js', '--grep', 'should success' ], { 121 | cwd, 122 | }) 123 | // .debug() 124 | .expect('stdout', /should success/) 125 | .expect('stdout', /a\.test\.js/) 126 | .notExpect('stdout', /should show tmp/) 127 | .expect('code', 0) 128 | .end(); 129 | }); 130 | 131 | it('should fail when test fail', () => { 132 | return coffee.fork(eggBin, [ 'cov' ], { cwd, env: { TESTS: 'test/fail.js' } }) 133 | // .debug() 134 | .expect('stdout', /1\) should fail/) 135 | .expect('stdout', /1 failing/) 136 | .expect('stderr', /exit with code 1/) 137 | .expect('code', 1) 138 | .end(); 139 | }); 140 | 141 | it('should run cov when no test files', () => { 142 | const cwd = path.join(fixtures, 'prerequire'); 143 | return coffee.fork(eggBin, [ 'cov', '--ts=false' ], { cwd, env: { TESTS: 'noexist.js' } }) 144 | // .debug() 145 | .expect('code', 0) 146 | .end(); 147 | }); 148 | 149 | it('should set EGG_BIN_PREREQUIRE', async () => { 150 | const cwd = path.join(fixtures, 'prerequire'); 151 | await coffee.fork(eggBin, [ 'cov', '--ts=false' ], { cwd, env: { TESTS: 'test/**/*.test.js' } }) 152 | // .debug() 153 | .expect('stdout', /EGG_BIN_PREREQUIRE undefined/) 154 | .expect('stdout', /NODE_ENV test/) 155 | .expect('code', 0) 156 | .end(); 157 | 158 | await coffee.fork(eggBin, [ 'cov', '--prerequire', '--ts=false' ], { cwd }) 159 | // .debug() 160 | .expect('stdout', /EGG_BIN_PREREQUIRE true/) 161 | .expect('stdout', /NODE_ENV test/) 162 | .expect('code', 0) 163 | .end(); 164 | }); 165 | 166 | it('test parallel', () => { 167 | if (process.platform === 'win32') return; 168 | return coffee.fork(eggBin, [ 'cov', '--parallel', '--ts=false' ], { 169 | cwd: path.join(fixtures, 'test-demo-app'), 170 | env: { TESTS: 'test/**/*.test.js' }, 171 | }) 172 | // .debug() 173 | .expect('stdout', /should work/) 174 | .expect('stdout', /a\.test\.js/) 175 | .expect('code', 0) 176 | .end(); 177 | }); 178 | 179 | it('should run cov on ts-esm module', () => { 180 | const cwd = path.join(fixtures, 'mocha-test-ts-esm'); 181 | return coffee.fork(eggBin, [ 'cov' ], { 182 | cwd, 183 | }) 184 | .debug() 185 | .expect('stdout', /should work/) 186 | .expect('stdout', /2 passing/) 187 | .expect('code', 0) 188 | .end(); 189 | }); 190 | 191 | it('should support egg.revert', () => { 192 | if (version < 18 || version > 20) return; 193 | mm(process.env, 'NODE_ENV', 'development'); 194 | return coffee.fork(eggBin, [ 'cov' ], { 195 | cwd: path.join(__dirname, '../fixtures/egg-revert'), 196 | }) 197 | .debug() 198 | .expect('stdout', /SECURITY WARNING: Reverting CVE-2023-46809: Marvin attack on PKCS#1 padding/) 199 | .expect('stdout', /1 passing/) 200 | .expect('code', 0) 201 | .end(); 202 | }); 203 | }); 204 | }); 205 | -------------------------------------------------------------------------------- /test/cmd/test.test.ts: -------------------------------------------------------------------------------- 1 | import path from 'node:path'; 2 | import coffee from '../coffee'; 3 | 4 | const version = Number(process.version.substring(1, 3)); 5 | 6 | describe('test/cmd/test.test.ts', () => { 7 | const eggBin = path.join(__dirname, '../../src/bin/cli.ts'); 8 | const fixtures = path.join(__dirname, '../fixtures'); 9 | const cwd = path.join(fixtures, 'test-files'); 10 | 11 | describe('egg-bin test', () => { 12 | it('should success js', () => { 13 | return coffee.fork(eggBin, [ 'test' ], { cwd }) 14 | .debug() 15 | .expect('stdout', /should success/) 16 | .expect('stdout', /a\.test\.js/) 17 | .expect('stdout', /b\/b\.test\.js/) 18 | .notExpect('stdout', /\ba\.js/) 19 | .expect('code', 0) 20 | .end(); 21 | }); 22 | 23 | it('should success on ts', async () => { 24 | const cwd = path.join(fixtures, 'example-ts'); 25 | await coffee.fork(eggBin, [ 'test' ], { cwd }) 26 | // .debug() 27 | .expect('stdout', /should work/) 28 | .expect('stdout', /1 passing/) 29 | .expect('code', 0) 30 | .end(); 31 | }); 32 | 33 | it('should success with --mochawesome', () => { 34 | return coffee.fork(eggBin, [ 'test', '--mochawesome' ], { cwd }) 35 | // .debug() 36 | .expect('stdout', /should success/) 37 | .expect('stdout', /a\.test\.js/) 38 | .expect('stdout', /b\/b\.test\.js/) 39 | .expect('stdout', /\[mochawesome] Report JSON saved to/) 40 | .expect('stdout', /mochawesome\.json/) 41 | .notExpect('stdout', /\ba\.js/) 42 | .expect('code', 0) 43 | .end(); 44 | }); 45 | 46 | it('should success with --bail', () => { 47 | return coffee.fork(eggBin, [ 'test', '--bail' ], { cwd }) 48 | // .debug() 49 | .expect('stdout', /should success/) 50 | .expect('stdout', /a\.test\.js/) 51 | .expect('stdout', /b\/b\.test\.js/) 52 | .notExpect('stdout', /\ba\.js/) 53 | .expect('code', 0) 54 | .end(); 55 | }); 56 | 57 | it('should ignore node_modules and fixtures', () => { 58 | return coffee.fork(eggBin, [ 'test' ], { cwd: path.join(fixtures, 'test-files-glob') }) 59 | // .debug() 60 | .expect('stdout', /should test index/) 61 | .expect('stdout', /should test sub/) 62 | .notExpect('stdout', /no-load\.test\.js/) 63 | .expect('code', 0) 64 | .end(); 65 | }); 66 | 67 | it('should only test files specified by TESTS', () => { 68 | return coffee.fork(eggBin, [ 'test' ], { cwd, env: { TESTS: 'test/a.test.js' } }) 69 | .expect('stdout', /should success/) 70 | .expect('stdout', /a\.test\.js/) 71 | .notExpect('stdout', /b[\/\\]b.test.js/) 72 | .expect('code', 0) 73 | .end(); 74 | }); 75 | 76 | it('should only test files specified by TESTS with multi pattern', () => { 77 | return coffee.fork(eggBin, [ 'test' ], { 78 | cwd, 79 | env: { TESTS: 'test/a.test.js,test/b/b.test.js' }, 80 | }) 81 | .expect('stdout', /should success/) 82 | .expect('stdout', /a\.test\.js/) 83 | .expect('stdout', /b[\/\\]b.test.js/) 84 | .expect('code', 0) 85 | .end(); 86 | }); 87 | 88 | it('should only test files specified by TESTS argv', () => { 89 | return coffee.fork(eggBin, [ 'test', 'test/a.test.js' ], { 90 | cwd, 91 | env: { TESTS: 'test/**/*.test.js' }, 92 | }) 93 | .expect('stdout', /should success/) 94 | .expect('stdout', /a\.test\.js/) 95 | .notExpect('stdout', /b[\/\\]b.test.js/) 96 | .expect('code', 0) 97 | .end(); 98 | }); 99 | 100 | it('should grep pattern without error', () => { 101 | return coffee.fork(eggBin, [ 'test', 'test/a.test.js', '--grep', 'should success' ], { 102 | cwd, 103 | }) 104 | // .debug() 105 | .expect('stdout', /should success/) 106 | .expect('stdout', /a\.test\.js/) 107 | .notExpect('stdout', /should show tmp/) 108 | .expect('code', 0) 109 | .end(); 110 | }); 111 | 112 | it('should exit when not test files', () => { 113 | return coffee.fork(eggBin, [ 'test', 'test/**/*.nth.js' ], { cwd }) 114 | // .debug() 115 | .expect('stdout', /No test files found/) 116 | .expect('code', 0) 117 | .end(); 118 | }); 119 | 120 | it('should use process.env.TEST_REPORTER', () => { 121 | return coffee.fork(eggBin, [ 'test' ], { 122 | cwd, 123 | env: { 124 | TESTS: 'test/**/*.test.js', 125 | TEST_REPORTER: 'json', 126 | }, 127 | }) 128 | // .debug() 129 | .expect('stdout', /"stats":/) 130 | .expect('stdout', /"tests":/) 131 | .expect('code', 0) 132 | .end(); 133 | }); 134 | 135 | it('should use process.env.TEST_TIMEOUT', () => { 136 | return coffee.fork(eggBin, [ 'test' ], { 137 | cwd, 138 | env: { 139 | TEST_TIMEOUT: '60000', 140 | }, 141 | }) 142 | .expect('stdout', /should success/) 143 | .expect('code', 0) 144 | .end(); 145 | }); 146 | 147 | it('should force exit', () => { 148 | const cwd = path.join(fixtures, 'no-exit'); 149 | return coffee.fork(eggBin, [ 'test' ], { cwd }) 150 | // .debug() 151 | .expect('code', 0) 152 | .end(); 153 | }); 154 | 155 | it('run not test with dry-run option', () => { 156 | const cwd = path.join(fixtures, 'mocha-test'); 157 | return coffee.fork(eggBin, [ 'test', '--timeout=12345', '--dry-run' ], { 158 | cwd, 159 | env: { 160 | TESTS: 'test/foo.test.js', 161 | }, 162 | }) 163 | // .debug() 164 | .expect('stdout', /_mocha /) 165 | .expect('stdout', / --timeout=12345 /) 166 | .expect('stdout', / --exit /) 167 | .expect('stdout', /foo\.test\.js/) 168 | .expect('stdout', /--dry-run/) 169 | .expect('code', 0) 170 | .end(); 171 | }); 172 | 173 | it('should run test on ts-esm module', () => { 174 | const cwd = path.join(fixtures, 'mocha-test-ts-esm'); 175 | return coffee.fork(eggBin, [ 'test' ], { 176 | cwd, 177 | }) 178 | .debug() 179 | .expect('stdout', /should work/) 180 | .expect('stdout', /2 passing/) 181 | .notExpect('stderr', /ExperimentalWarning/) 182 | .expect('code', 0) 183 | .end(); 184 | }); 185 | 186 | it('should success js on unhandled-rejection', () => { 187 | if (version >= 20 && process.platform === 'win32') return; 188 | return coffee.fork(eggBin, [ 'test' ], { cwd: path.join(fixtures, 'test-unhandled-rejection') }) 189 | .debug() 190 | .expect('stdout', / Uncaught Error: mock error/) 191 | .expect('code', 1) 192 | .end(); 193 | }); 194 | 195 | it('test parallel', () => { 196 | if (process.platform === 'win32') return; 197 | return coffee.fork(eggBin, [ 'test', '--parallel' ], { 198 | cwd: path.join(fixtures, 'test-demo-app'), 199 | }) 200 | // .debug() 201 | .expect('stdout', /should work/) 202 | .expect('stdout', /a\.test\.js/) 203 | .expect('code', 0) 204 | .end(); 205 | }); 206 | 207 | it('env.MOCHA_FILE should work', () => { 208 | return coffee.fork(eggBin, [ 'test', '--parallel' ], { 209 | cwd: path.join(fixtures, 'test-demo-app'), 210 | env: { 211 | MOCHA_FILE: path.join(fixtures, 'bin/fake_mocha.js'), 212 | }, 213 | }) 214 | // .debug() 215 | .expect('stdout', /env\.NODE_ENV: test/) 216 | .expect('stdout', /env\.AUTO_AGENT: true/) 217 | .expect('stdout', /env\.ENABLE_MOCHA_PARALLEL: true/) 218 | .expect('code', 0) 219 | .end(); 220 | }); 221 | }); 222 | 223 | describe('run test/.setup.js|ts first', () => { 224 | it('should auto require test/.setup.js', () => { 225 | return coffee.fork(eggBin, [ 'test', '--no-typescript' ], { 226 | cwd: path.join(fixtures, 'setup-js'), 227 | env: { 228 | TESTS: 'test/a.test.js', 229 | }, 230 | }) 231 | // .debug() 232 | .expect('stdout', /this is a before function/) 233 | .expect('stdout', /hello egg/) 234 | .expect('stdout', /is end!/) 235 | .expect('code', 0) 236 | .end(); 237 | }); 238 | 239 | it('should auto require test/.setup.ts', () => { 240 | return coffee.fork(eggBin, [ 'test', '--typescript' ], { 241 | cwd: path.join(fixtures, 'setup-ts'), 242 | env: { 243 | TESTS: 'test/a.test.ts', 244 | }, 245 | }) 246 | // .debug() 247 | .expect('stdout', /this is a before function/) 248 | .expect('stdout', /hello egg/) 249 | .expect('stdout', /is end!/) 250 | .expect('code', 0) 251 | .end(); 252 | }); 253 | }); 254 | 255 | describe('no-timeouts', () => { 256 | it('should timeout', () => { 257 | return coffee.fork(eggBin, [ 'test' ], { 258 | cwd, 259 | env: { 260 | TEST_TIMEOUT: '5000', 261 | TESTS: 'test/**/no-timeouts.test.js', 262 | }, 263 | }) 264 | // .debug() 265 | .expect('stdout', /timeout: 5000/) 266 | .expect('code', 0) 267 | .end(); 268 | }); 269 | 270 | it('should support --no-timeout', () => { 271 | return coffee.fork(eggBin, [ 'test', '--no-timeout' ], { 272 | cwd, 273 | env: { 274 | TEST_TIMEOUT: '5000', 275 | TESTS: 'test/**/no-timeouts.test.js', 276 | }, 277 | }) 278 | // .debug() 279 | .expect('stdout', /timeout: 0/) 280 | .expect('code', 0) 281 | .end(); 282 | }); 283 | 284 | it('should no-timeout at inspect mode', () => { 285 | return coffee.fork(eggBin, [ 'test', '--inspect' ], { 286 | cwd, 287 | env: { 288 | TESTS: 'test/**/no-timeouts.test.js', 289 | }, 290 | }) 291 | // .debug() 292 | .expect('stdout', /timeout: 0/) 293 | .expect('code', 0) 294 | .end(); 295 | }); 296 | 297 | it('should no-timeout at WebStorm debug mode', () => { 298 | return coffee.fork(eggBin, [ 'test' ], { 299 | cwd, 300 | env: { 301 | TESTS: 'test/**/no-timeouts.test.js', 302 | JB_DEBUG_FILE: __filename, 303 | }, 304 | }) 305 | // .debug() 306 | .expect('stdout', /timeout: 0/) 307 | .expect('code', 0) 308 | .end(); 309 | }); 310 | 311 | it('should support egg.revert', () => { 312 | if (version < 18 || version > 20) return; 313 | return coffee.fork(eggBin, [ 'test' ], { 314 | cwd: path.join(__dirname, '../fixtures/egg-revert'), 315 | }) 316 | .debug() 317 | .expect('stdout', /SECURITY WARNING: Reverting CVE-2023-46809: Marvin attack on PKCS#1 padding/) 318 | .expect('code', 0) 319 | .end(); 320 | }); 321 | }); 322 | }); 323 | -------------------------------------------------------------------------------- /test/ts.test.ts: -------------------------------------------------------------------------------- 1 | import assert from 'node:assert'; 2 | import path from 'node:path'; 3 | import fs from 'node:fs/promises'; 4 | import _cpy from 'cpy'; 5 | import { runScript } from 'runscript'; 6 | import coffee from './coffee'; 7 | 8 | const version = Number(process.version.substring(1, 3)); 9 | 10 | async function cpy(src: string, target: string) { 11 | if (fs.cp) { 12 | await fs.cp(src, target, { force: true, recursive: true }); 13 | return; 14 | } 15 | await _cpy(src, target); 16 | } 17 | 18 | describe('test/ts.test.ts', () => { 19 | const eggBin = path.join(__dirname, '../src/bin/cli.ts'); 20 | const fixtures = path.join(__dirname, 'fixtures'); 21 | let cwd: string; 22 | 23 | it('should support ts', () => { 24 | cwd = path.join(fixtures, 'ts'); 25 | return coffee.fork(eggBin, [ 'dev' ], { cwd, env: { NODE_ENV: 'development' } }) 26 | // .debug() 27 | .expect('stdout', /options.typescript=true/) 28 | .expect('stdout', /started/) 29 | .expect('code', 0) 30 | .end(); 31 | }); 32 | 33 | it('should support ts test', () => { 34 | cwd = path.join(fixtures, 'ts'); 35 | return coffee.fork(eggBin, [ 'test', '--typescript' ], { cwd, env: { NODE_ENV: 'development' } }) 36 | // .debug() 37 | .expect('stdout', /'egg from ts' == 'wrong assert ts'/) 38 | .expect('stdout', /AssertionError/) 39 | .expect('code', 1) 40 | .end(); 41 | }); 42 | 43 | describe('real application', () => { 44 | before(() => { 45 | cwd = path.join(fixtures, 'example-ts'); 46 | }); 47 | 48 | it('should start app', () => { 49 | return coffee.fork(eggBin, [ 'dev' ], { cwd }) 50 | // .debug() 51 | .expect('stdout', /hi, egg, 12345/) 52 | .expect('stdout', /ts env: true/) 53 | .expect('stdout', /started/) 54 | .expect('code', 0) 55 | .end(); 56 | }); 57 | 58 | it('should test app', () => { 59 | return coffee.fork(eggBin, [ 'test' ], { cwd }) 60 | // .debug() 61 | .expect('stdout', /hi, egg, 123456/) 62 | .expect('stdout', /ts env: true/) 63 | .expect('stdout', /should work/) 64 | .expect('code', 0) 65 | .end(); 66 | }); 67 | 68 | it('should cov app', () => { 69 | return coffee.fork(eggBin, [ 'cov' ], { cwd }) 70 | // .debug() 71 | .expect('stdout', /hi, egg, 123456/) 72 | .expect('stdout', /ts env: true/) 73 | .expect('stdout', /should work/) 74 | .expect('code', 0) 75 | .end(); 76 | }); 77 | 78 | it('should cov app in cluster mod', () => { 79 | if (version > 20) return; 80 | // skip on darwin 81 | // https://github.com/eggjs/egg-bin/runs/6735190362?check_suite_focus=true 82 | // [agent_worker] receive disconnect event on child_process fork mode, exiting with code:110 83 | if (process.platform === 'darwin') return; 84 | cwd = path.join(fixtures, 'example-ts-cluster'); 85 | return coffee.fork(eggBin, [ 'cov' ], { cwd }) 86 | .debug() 87 | .expect('stdout', /Statements/) 88 | .expect('code', 0) 89 | .end(); 90 | }); 91 | }); 92 | 93 | describe('error stacks', () => { 94 | before(() => { 95 | cwd = path.join(fixtures, 'example-ts-error-stack'); 96 | }); 97 | 98 | it('should correct error stack line number in starting app', () => { 99 | return coffee.fork(eggBin, [ 'dev' ], { cwd, env: { THROW_ERROR: 'true' } }) 100 | .debug() 101 | .expect('stderr', /Error: throw error/) 102 | .expect('stderr', /at \w+ \(.+app\.ts:7:11\)/) 103 | .end(); 104 | }); 105 | 106 | it('should correct error stack line number in testing app', () => { 107 | return coffee.fork(eggBin, [ 'test' ], { cwd }) 108 | // .debug() 109 | .expect('stdout', /error/) 110 | .expect('stdout', /2 failing/) 111 | .expect('stdout', /test[\/\\]index\.test\.ts:\d+:\d+\)/) 112 | .expect('stdout', /AssertionError \[ERR_ASSERTION]: '111' == '222'/) 113 | .expect('code', 1) 114 | .end(); 115 | }); 116 | 117 | it('should correct error stack line number in testing app with tscompiler=esbuild-register', () => { 118 | return coffee.fork(eggBin, [ 'test', '--tscompiler=esbuild-register' ], { cwd }) 119 | // .debug() 120 | .expect('stdout', /error/) 121 | .expect('stdout', /2 failing/) 122 | .expect('stdout', /test[\/\\]index\.test\.ts:\d+:\d+\)/) 123 | .expect('stdout', /AssertionError \[ERR_ASSERTION]: '111' == '222'/) 124 | .expect('code', 1) 125 | .end(); 126 | }); 127 | 128 | it('should correct error stack line number in testing app with tscompiler=@swc-node/register', () => { 129 | return coffee.fork(eggBin, [ 'test', '--tscompiler=@swc-node/register' ], { cwd }) 130 | // .debug() 131 | .expect('stdout', /error/) 132 | .expect('stdout', /2 failing/) 133 | .expect('stdout', /test[\/\\]index\.test\.ts:\d+:\d+\)/) 134 | .expect('stdout', /AssertionError \[ERR_ASSERTION]: '111' == '222'/) 135 | .expect('code', 1) 136 | .end(); 137 | }); 138 | 139 | it('should support env.TS_COMPILER', () => { 140 | return coffee.fork(eggBin, [ 'test' ], { 141 | cwd, 142 | env: { 143 | TS_COMPILER: 'esbuild-register', 144 | NODE_DEBUG: 'egg-bin*', 145 | }, 146 | }) 147 | // .debug() 148 | .expect('stdout', /error/) 149 | .expect('stdout', /2 failing/) 150 | .expect('stdout', /test[\/\\]index\.test\.ts:\d+:\d+\)/) 151 | .expect('stdout', /AssertionError \[ERR_ASSERTION]: '111' == '222'/) 152 | .expect('code', 1) 153 | .end(); 154 | }); 155 | 156 | it('should correct error stack line number in covering app', () => { 157 | return coffee.fork(eggBin, [ 'test' ], { cwd }) 158 | // .debug() 159 | .expect('stdout', /error/) 160 | .expect('stdout', /2 failing/) 161 | .expect('stdout', /test[\/\\]index\.test\.ts:\d+:\d+\)/) 162 | .expect('stdout', /AssertionError \[ERR_ASSERTION]: '111' == '222'/) 163 | .end(); 164 | }); 165 | 166 | it('should correct error stack line number in mixed app', () => { 167 | const cwd = path.join(fixtures, 'example-ts-error-stack-mixed'); 168 | return coffee.fork(eggBin, [ 'test', '--ts', 'false' ], { cwd }) 169 | // .debug() 170 | .expect('stdout', /error/) 171 | .expect('stdout', /2 failing/) 172 | .expect('stdout', /test[\/\\]index\.test\.js:\d+:\d+\)/) 173 | .expect('stdout', /AssertionError \[ERR_ASSERTION]: '111' == '222'/) 174 | .end(); 175 | }); 176 | }); 177 | 178 | describe('egg.typescript = true', () => { 179 | const tempNodeModules = path.join(fixtures, 'node_modules'); 180 | const tempPackageJson = path.join(fixtures, 'package.json'); 181 | afterEach(async () => { 182 | await fs.rm(tempNodeModules, { force: true, recursive: true }); 183 | await fs.rm(tempPackageJson, { force: true, recursive: true }); 184 | }); 185 | 186 | before(() => { 187 | cwd = path.join(fixtures, 'example-ts-pkg'); 188 | }); 189 | 190 | it('should start app', () => { 191 | return coffee.fork(eggBin, [ 'dev' ], { cwd }) 192 | // .debug() 193 | .expect('stdout', /hi, egg, 12345/) 194 | .expect('stdout', /ts env: true/) 195 | .expect('stdout', /started/) 196 | .expect('code', 0) 197 | .end(); 198 | }); 199 | 200 | it('should fail start app with --no-ts', () => { 201 | return coffee.fork(eggBin, [ 'dev', '--no-ts' ], { cwd }) 202 | // .debug() 203 | .expect('stdout', /agent.options.typescript = false/) 204 | .expect('stdout', /started/) 205 | .expect('code', 0) 206 | .end(); 207 | }); 208 | 209 | it('should start app with flags in app without eggInfo', async () => { 210 | const cwd = path.join(fixtures, 'example-ts-simple'); 211 | await coffee.fork(eggBin, [ 'dev' ], { cwd }) 212 | // .debug() 213 | .expect('stdout', /started/) 214 | .expect('code', 0) 215 | .end(); 216 | 217 | await coffee.fork(eggBin, [ 'dev', '--tsc=esbuild-register' ], { cwd }) 218 | // .debug() 219 | .expect('stdout', /started/) 220 | .expect('code', 0) 221 | .end(); 222 | }); 223 | 224 | it('should load custom ts compiler', async () => { 225 | if (process.platform === 'win32') return; 226 | const cwd = path.join(fixtures, 'example-ts-custom-compiler'); 227 | 228 | // install custom ts-node 229 | await fs.rm(path.join(cwd, 'node_modules'), { force: true, recursive: true }); 230 | if (process.env.CI) { 231 | // don't use npmmirror.com on CI 232 | await runScript('npx npminstall', { cwd }); 233 | } else { 234 | await runScript('npx npminstall -c', { cwd }); 235 | } 236 | 237 | // copy egg to node_modules 238 | await cpy( 239 | path.join(fixtures, 'example-ts-cluster/node_modules/egg'), 240 | path.join(cwd, './node_modules/egg'), 241 | ); 242 | 243 | const { stderr, code } = await coffee.fork(eggBin, [ 'dev', '--tsc', 'ts-node/register' ], { 244 | cwd, 245 | env: { 246 | NODE_DEBUG: 'egg-bin*', 247 | }, 248 | }) 249 | // .debug() 250 | .end(); 251 | assert.match(stderr, /ts-node@10\.\d+\.\d+/); 252 | assert.equal(code, 0); 253 | }); 254 | 255 | it('should load custom ts compiler with tscompiler args', async () => { 256 | if (process.platform === 'win32') return; 257 | const cwd = path.join(fixtures, 'example-ts-custom-compiler-2'); 258 | 259 | // install custom ts-node 260 | await fs.rm(path.join(cwd, 'node_modules'), { force: true, recursive: true }); 261 | if (process.env.CI) { 262 | // dont use npmmirror.com on CI 263 | await runScript('npx npminstall ts-node@10.9.2 --no-save', { cwd }); 264 | } else { 265 | await runScript('npx npminstall -c ts-node@10.9.2 --no-save', { cwd }); 266 | } 267 | 268 | // copy egg to node_modules 269 | await cpy( 270 | path.join(fixtures, 'example-ts-cluster/node_modules/egg'), 271 | path.join(cwd, './node_modules/egg'), 272 | ); 273 | 274 | const { stderr, code } = await coffee.fork(eggBin, [ 275 | 'dev', '--ts', '--tscompiler=ts-node/register', 276 | ], { 277 | cwd, 278 | env: { 279 | NODE_DEBUG: 'egg-bin*', 280 | }, 281 | }) 282 | // .debug() 283 | .end(); 284 | assert.match(stderr, /ts-node@10\.9\.2/); 285 | assert.equal(code, 0); 286 | }); 287 | 288 | it('should not load custom ts compiler without tscompiler args', async () => { 289 | const cwd = path.join(fixtures, 'example-ts-custom-compiler-2'); 290 | 291 | // install custom ts-node 292 | await fs.rm(path.join(cwd, 'node_modules'), { force: true, recursive: true }); 293 | if (process.env.CI) { 294 | // don't use npmmirror.com on CI 295 | await runScript('npx npminstall ts-node@10.9.2 --no-save', { cwd }); 296 | } else { 297 | await runScript('npx npminstall -c ts-node@10.9.2 --no-save', { cwd }); 298 | } 299 | 300 | // copy egg to node_modules 301 | await cpy( 302 | path.join(fixtures, 'example-ts-cluster/node_modules/egg'), 303 | path.join(cwd, './node_modules/egg'), 304 | ); 305 | 306 | const { stderr, code } = await coffee.fork(eggBin, [ 'dev' ], { 307 | cwd, 308 | env: { 309 | NODE_DEBUG: 'egg-bin*', 310 | }, 311 | }) 312 | // .debug() 313 | .end(); 314 | assert.doesNotMatch(stderr, /ts-node@10\.9\.2/); 315 | assert.equal(code, 0); 316 | }); 317 | 318 | it('should start app with other tscompiler without error', () => { 319 | return coffee.fork(eggBin, [ 'dev', '--tscompiler=esbuild-register' ], { 320 | cwd: path.join(fixtures, 'example-ts'), 321 | }) 322 | // .debug() 323 | .expect('stdout', /agent.options.typescript = true/) 324 | .expect('stdout', /agent.options.tscompiler =/) 325 | .expect('stdout', /esbuild-register/) 326 | .expect('stdout', /started/) 327 | .expect('code', 0) 328 | .end(); 329 | }); 330 | 331 | it('should skip ts-node on env.EGG_TYPESCRIPT="false"', () => { 332 | return coffee.fork(eggBin, [ 'dev', '--tscompiler=esbuild-register' ], { 333 | cwd: path.join(fixtures, 'example-ts'), 334 | env: { 335 | EGG_TYPESCRIPT: 'false', 336 | }, 337 | }) 338 | // .debug() 339 | .expect('stdout', /agent.options.typescript = false/) 340 | .expect('stdout', /agent.options.tscompiler =/) 341 | .expect('stdout', /esbuild-register/) 342 | .expect('stdout', /started/) 343 | .expect('code', 0) 344 | .end(); 345 | }); 346 | 347 | it('should enable ts-node on env.EGG_TYPESCRIPT="true"', () => { 348 | return coffee.fork(eggBin, [ 'dev', '--tscompiler=esbuild-register' ], { 349 | cwd: path.join(fixtures, 'example-ts'), 350 | env: { 351 | EGG_TYPESCRIPT: 'true', 352 | }, 353 | }) 354 | // .debug() 355 | .expect('stdout', /agent.options.typescript = true/) 356 | .expect('stdout', /agent.options.tscompiler =/) 357 | .expect('stdout', /esbuild-register/) 358 | .expect('stdout', /started/) 359 | .expect('code', 0) 360 | .end(); 361 | }); 362 | 363 | it('should start app with other tscompiler in package.json without error', () => { 364 | return coffee.fork(eggBin, [ 'dev' ], { 365 | cwd: path.join(fixtures, 'example-ts-pkg'), 366 | }) 367 | // .debug() 368 | .expect('stdout', /agent.options.typescript = true/) 369 | .expect('stdout', /agent.options.tscompiler =/) 370 | .expect('stdout', /esbuild-register/) 371 | .expect('stdout', /started/) 372 | .expect('code', 0) 373 | .end(); 374 | }); 375 | 376 | it('should test app', () => { 377 | return coffee.fork(eggBin, [ 'test' ], { cwd }) 378 | // .debug() 379 | .expect('stdout', /hi, egg, 123456/) 380 | .expect('stdout', /ts env: true/) 381 | .expect('code', 0) 382 | .end(); 383 | }); 384 | 385 | it('should test with custom ts compiler without error', async () => { 386 | const cwd = path.join(fixtures, 'example-ts-custom-compiler'); 387 | 388 | // install custom ts-node 389 | await fs.rm(path.join(cwd, 'node_modules'), { force: true, recursive: true }); 390 | if (process.env.CI) { 391 | // dont use npmmirror.com on CI 392 | await runScript('npx npminstall', { cwd }); 393 | } else { 394 | await runScript('npx npminstall -c', { cwd }); 395 | } 396 | 397 | // copy egg to node_modules 398 | await cpy( 399 | path.join(__dirname, './fixtures/example-ts-cluster/node_modules/egg'), 400 | path.join(cwd, './node_modules/egg'), 401 | ); 402 | 403 | const { stdout, code } = await coffee.fork(eggBin, [ 'test', '--tsc', 'ts-node/register' ], { 404 | cwd, 405 | env: { 406 | NODE_DEBUG: 'egg-bin*', 407 | }, 408 | }) 409 | // .debug() 410 | .end(); 411 | assert.match(stdout, /ts-node@10\.\d+\.\d+/); 412 | assert.equal(code, 0); 413 | }); 414 | 415 | it('should cov app', () => { 416 | return coffee.fork(eggBin, [ 'cov' ], { cwd }) 417 | // .debug() 418 | .expect('stdout', /hi, egg, 123456/) 419 | .expect('stdout', /ts env: true/) 420 | .expect('code', 0) 421 | .end(); 422 | }); 423 | }); 424 | }); 425 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [6.13.0](https://github.com/eggjs/egg-bin/compare/v6.12.0...v6.13.0) (2024-12-11) 4 | 5 | 6 | ### Features 7 | 8 | * use @eggjs/utils v4 ([#278](https://github.com/eggjs/egg-bin/issues/278)) ([aedf803](https://github.com/eggjs/egg-bin/commit/aedf803a863b082dc41ee9f6ed41b500dbfc902e)) 9 | 10 | ## [6.12.0](https://github.com/eggjs/egg-bin/compare/v6.11.0...v6.12.0) (2024-12-10) 11 | 12 | 13 | ### Features 14 | 15 | * use runscript v2 ([#276](https://github.com/eggjs/egg-bin/issues/276)) ([8fac9ae](https://github.com/eggjs/egg-bin/commit/8fac9ae10380c5e768845e9ceb991549d1b3c4fe)) 16 | 17 | ## [6.11.0](https://github.com/eggjs/egg-bin/compare/v6.10.0...v6.11.0) (2024-12-08) 18 | 19 | 20 | ### Features 21 | 22 | * use detect-port v2 ([#275](https://github.com/eggjs/egg-bin/issues/275)) ([4816db4](https://github.com/eggjs/egg-bin/commit/4816db4d0e111d9f46d8547a17b6cf430a89d225)) 23 | 24 | ## [6.10.0](https://github.com/eggjs/egg-bin/compare/v6.9.0...v6.10.0) (2024-06-11) 25 | 26 | 27 | ### Features 28 | 29 | * [Snyk] Security upgrade c8 from 9.1.0 to 10.0.0 ([#272](https://github.com/eggjs/egg-bin/issues/272)) ([2535a8e](https://github.com/eggjs/egg-bin/commit/2535a8e57e2ae7482516bac2309d04cf69bac22d)) 30 | 31 | ## [6.9.0](https://github.com/eggjs/egg-bin/compare/v6.8.1...v6.9.0) (2024-05-08) 32 | 33 | 34 | ### Features 35 | 36 | * use @eggjs/utils@3 ([#268](https://github.com/eggjs/egg-bin/issues/268)) ([cac459c](https://github.com/eggjs/egg-bin/commit/cac459c183c9d66e45dcb8bb9afd849a8814fa82)) 37 | 38 | ## [6.8.1](https://github.com/eggjs/egg-bin/compare/v6.8.0...v6.8.1) (2024-03-06) 39 | 40 | 41 | ### Bug Fixes 42 | 43 | * fix execArgv not work in cov ([#255](https://github.com/eggjs/egg-bin/issues/255)) ([cc8c063](https://github.com/eggjs/egg-bin/commit/cc8c063df714a11bb5203a5c7ad84cb0b185229b)) 44 | 45 | ## [6.8.0](https://github.com/eggjs/egg-bin/compare/v6.7.0...v6.8.0) (2024-02-01) 46 | 47 | 48 | ### Features 49 | 50 | * supports retrieving the port from the configuration file ([#251](https://github.com/eggjs/egg-bin/issues/251)) ([07e150f](https://github.com/eggjs/egg-bin/commit/07e150f0f1cae2a75353428c9d10b4e9a16fd0db)) 51 | 52 | ## [6.7.0](https://github.com/eggjs/egg-bin/compare/v6.6.0...v6.7.0) (2024-01-09) 53 | 54 | 55 | ### Features 56 | 57 | * egg-ts-helper 1.30.3 to 2.1.0 ([#249](https://github.com/eggjs/egg-bin/issues/249)) ([34e3b92](https://github.com/eggjs/egg-bin/commit/34e3b928a2bb5114a8128429b29286d3dca5274d)) 58 | 59 | ## [6.6.0](https://github.com/eggjs/egg-bin/compare/v6.5.2...v6.6.0) (2024-01-07) 60 | 61 | 62 | ### Features 63 | 64 | * should run ets on pkg.egg.declarations = true ([#248](https://github.com/eggjs/egg-bin/issues/248)) ([018801a](https://github.com/eggjs/egg-bin/commit/018801a241324626748c0d9ea90573349cd3d2fa)) 65 | 66 | ## [6.5.2](https://github.com/eggjs/egg-bin/compare/v6.5.1...v6.5.2) (2023-09-16) 67 | 68 | 69 | ### Bug Fixes 70 | 71 | * ignore ExperimentalWarning on esm module ([#241](https://github.com/eggjs/egg-bin/issues/241)) ([6a2521a](https://github.com/eggjs/egg-bin/commit/6a2521a2c11ac9416a21b01b37aad50f50c9ff49)) 72 | 73 | ## [6.5.1](https://github.com/eggjs/egg-bin/compare/v6.5.0...v6.5.1) (2023-09-16) 74 | 75 | 76 | ### Bug Fixes 77 | 78 | * use ts-node inside the egg-bin deps ([#240](https://github.com/eggjs/egg-bin/issues/240)) ([f13df56](https://github.com/eggjs/egg-bin/commit/f13df56a1dfd4e69822392c4ad47c6aa785f1cac)) 79 | 80 | ## [6.5.0](https://github.com/eggjs/egg-bin/compare/v6.4.2...v6.5.0) (2023-09-15) 81 | 82 | 83 | ### Features 84 | 85 | * support run test/cov on esm package ([#239](https://github.com/eggjs/egg-bin/issues/239)) ([6ae1044](https://github.com/eggjs/egg-bin/commit/6ae10444af01cccfac19b2e4210f7fb06382e728)) 86 | 87 | ## [6.4.2](https://github.com/eggjs/egg-bin/compare/v6.4.1...v6.4.2) (2023-08-05) 88 | 89 | 90 | ### Bug Fixes 91 | 92 | * convert unhandled rejection to uncaught exception ([#235](https://github.com/eggjs/egg-bin/issues/235)) ([1e25880](https://github.com/eggjs/egg-bin/commit/1e25880848849cb5fee63fd7e9982afbf09301da)) 93 | 94 | ## [6.4.1](https://github.com/eggjs/egg-bin/compare/v6.4.0...v6.4.1) (2023-06-03) 95 | 96 | 97 | ### Bug Fixes 98 | 99 | * detect file changes on Windows ([#234](https://github.com/eggjs/egg-bin/issues/234)) ([38f1c6c](https://github.com/eggjs/egg-bin/commit/38f1c6ccc642e941f65f5b2b370116804827801b)) 100 | 101 | ## [6.4.0](https://github.com/eggjs/egg-bin/compare/v6.3.0...v6.4.0) (2023-04-18) 102 | 103 | 104 | ### Features 105 | 106 | * append cobertura to support diff line coverage ([#227](https://github.com/eggjs/egg-bin/issues/227)) ([ddf732f](https://github.com/eggjs/egg-bin/commit/ddf732fba211b2123da568bbb1ee6d84d046c083)) 107 | * output cobertura report by default ([#228](https://github.com/eggjs/egg-bin/issues/228)) ([8818a3d](https://github.com/eggjs/egg-bin/commit/8818a3ded5e40ced3c1f72f384a14beded595f35)) 108 | 109 | ## [6.3.0](https://github.com/eggjs/egg-bin/compare/v6.2.0...v6.3.0) (2023-04-06) 110 | 111 | 112 | ### Features 113 | 114 | * tsc target to ES2022 ([#225](https://github.com/eggjs/egg-bin/issues/225)) ([9d6f835](https://github.com/eggjs/egg-bin/commit/9d6f83549b78a1040230645eee9efe2ec2bdecb6)) 115 | 116 | ## [6.1.2](https://github.com/eggjs/egg-bin/compare/v6.1.1...v6.1.2) (2023-02-17) 117 | 118 | 119 | ### Bug Fixes 120 | 121 | * should support windows and Node.js 14 ([#223](https://github.com/eggjs/egg-bin/issues/223)) ([8f1b709](https://github.com/eggjs/egg-bin/commit/8f1b709961475c10dbbc4d8c51ed2c54af8a39ce)) 122 | 123 | ## [6.1.1](https://github.com/eggjs/egg-bin/compare/v6.1.0...v6.1.1) (2023-02-14) 124 | 125 | 126 | ### Bug Fixes 127 | 128 | * add scripts dir to exclude ([#219](https://github.com/eggjs/egg-bin/issues/219)) ([0fb74f7](https://github.com/eggjs/egg-bin/commit/0fb74f7bb85db47f6dd03697fd500d518e4907e5)) 129 | 130 | ## [6.1.0](https://github.com/eggjs/egg-bin/compare/v6.0.0...v6.1.0) (2023-02-14) 131 | 132 | 133 | ### Features 134 | 135 | * support grep pattern in 6.x ([#220](https://github.com/eggjs/egg-bin/issues/220)) ([7fedc6d](https://github.com/eggjs/egg-bin/commit/7fedc6d2fd2108b9b2aace04687a9bae03e634a6)) 136 | 137 | ## [6.0.0](https://github.com/eggjs/egg-bin/compare/v5.13.4...v6.0.0) (2023-02-12) 138 | 139 | 140 | ### ⚠ BREAKING CHANGES 141 | 142 | * drop Node.js 14 support and more deprecated features 143 | 144 | ### Features 145 | 146 | * use @artus-cli/artus-cli ([#217](https://github.com/eggjs/egg-bin/issues/217)) ([2b801e9](https://github.com/eggjs/egg-bin/commit/2b801e99d3be6b7dc27b46cc1992cec4089759ad)) 147 | 148 | ## [5.13.4](https://github.com/eggjs/egg-bin/compare/v5.13.3...v5.13.4) (2023-02-09) 149 | 150 | 151 | ### Bug Fixes 152 | 153 | * set ETS_SCRIPT_FRAMEWORK ([#216](https://github.com/eggjs/egg-bin/issues/216)) ([8614367](https://github.com/eggjs/egg-bin/commit/8614367f5b1c21d3ded9fb7f42d19d3189567d6d)) 154 | 155 | ## [5.13.3](https://github.com/eggjs/egg-bin/compare/v5.13.2...v5.13.3) (2023-02-06) 156 | 157 | 158 | ### Bug Fixes 159 | 160 | * not set ETS_FRAMEWORK ([#215](https://github.com/eggjs/egg-bin/issues/215)) ([b8f1c91](https://github.com/eggjs/egg-bin/commit/b8f1c914c9094c1f6e464fbee659f7a843f0b859)), closes [#214](https://github.com/eggjs/egg-bin/issues/214) 161 | 162 | ## [5.13.2](https://github.com/eggjs/egg-bin/compare/v5.13.1...v5.13.2) (2023-02-03) 163 | 164 | 165 | ### Bug Fixes 166 | 167 | * should set ETS_FRAMEWORK to real framework package name ([#214](https://github.com/eggjs/egg-bin/issues/214)) ([fb3eb6a](https://github.com/eggjs/egg-bin/commit/fb3eb6aa8b0b3cd02eda28e0abce0e688bfdb4b4)) 168 | 169 | ## [5.13.1](https://github.com/eggjs/egg-bin/compare/v5.13.0...v5.13.1) (2023-01-30) 170 | 171 | 172 | ### Bug Fixes 173 | 174 | * ignore ets when the current app don't has a framework dependencies ([#213](https://github.com/eggjs/egg-bin/issues/213)) ([666a342](https://github.com/eggjs/egg-bin/commit/666a342a28593942fb7e3de6648d4abf66c83ec1)) 175 | 176 | ## [5.13.0](https://github.com/eggjs/egg-bin/compare/v5.12.6...v5.13.0) (2023-01-18) 177 | 178 | 179 | ### Features 180 | 181 | * use util.debug instead of debug module ([#212](https://github.com/eggjs/egg-bin/issues/212)) ([33c95c2](https://github.com/eggjs/egg-bin/commit/33c95c20b44c7be267bb47399d2ce963214989d0)) 182 | 183 | ## [5.12.3](https://github.com/eggjs/egg-bin/compare/v5.12.2...v5.12.3) (2023-01-13) 184 | 185 | 186 | ### Bug Fixes 187 | 188 | * require tscompiler on current process ([#207](https://github.com/eggjs/egg-bin/issues/207)) ([3462835](https://github.com/eggjs/egg-bin/commit/3462835bf9060721a50e04cfeada601bb97cd0dc)) 189 | 190 | ## [5.12.2](https://github.com/eggjs/egg-bin/compare/v5.12.1...v5.12.2) (2023-01-11) 191 | 192 | 193 | ### Bug Fixes 194 | 195 | * dont auto require egg-mock ([#206](https://github.com/eggjs/egg-bin/issues/206)) ([e703507](https://github.com/eggjs/egg-bin/commit/e70350762f76372925c3c4cdbc50e17fa40383a4)), closes [/github.com/eggjs/egg-mock/pull/142#issuecomment-1377450602](https://github.com/eggjs//github.com/eggjs/egg-mock/pull/142/issues/issuecomment-1377450602) 196 | 197 | ## [5.12.1](https://github.com/eggjs/egg-bin/compare/v5.12.0...v5.12.1) (2023-01-10) 198 | 199 | 200 | ### Bug Fixes 201 | 202 | * use egg-mock/register instead ([#205](https://github.com/eggjs/egg-bin/issues/205)) ([c267288](https://github.com/eggjs/egg-bin/commit/c267288eb1610cd859be66d023d27e4d72671b58)) 203 | 204 | ## [5.12.0](https://github.com/eggjs/egg-bin/compare/v5.11.3...v5.12.0) (2023-01-09) 205 | 206 | 207 | ### Features 208 | 209 | * allow require mocha from outside ([#204](https://github.com/eggjs/egg-bin/issues/204)) ([6f59f6e](https://github.com/eggjs/egg-bin/commit/6f59f6effed71e898fe743fc1d29a6537029b1c7)) 210 | 211 | ## [5.11.3](https://github.com/eggjs/egg-bin/compare/v5.11.2...v5.11.3) (2023-01-06) 212 | 213 | 214 | ### Bug Fixes 215 | 216 | * ignore egg module on ets ([#203](https://github.com/eggjs/egg-bin/issues/203)) ([dda64a5](https://github.com/eggjs/egg-bin/commit/dda64a5f895aac9787b07f4a9c0285ac7701bdc1)) 217 | 218 | ## [5.11.2](https://github.com/eggjs/egg-bin/compare/v5.11.1...v5.11.2) (2023-01-05) 219 | 220 | 221 | ### Bug Fixes 222 | 223 | * use node to run postinstall script ([f17347b](https://github.com/eggjs/egg-bin/commit/f17347b670c8d39b32c5c7322e1e30d9c7823b72)) 224 | 225 | ## [5.11.1](https://github.com/eggjs/egg-bin/compare/v5.11.0...v5.11.1) (2023-01-05) 226 | 227 | 228 | ### Bug Fixes 229 | 230 | * should set ETS_CWD to INIT_CWD on postinstall ([#202](https://github.com/eggjs/egg-bin/issues/202)) ([a57c1d4](https://github.com/eggjs/egg-bin/commit/a57c1d4f5bfe229d1f6d3a6eb1957996d0b115ff)) 231 | 232 | ## [5.11.0](https://github.com/eggjs/egg-bin/compare/v5.10.0...v5.11.0) (2023-01-05) 233 | 234 | 235 | ### Features 236 | 237 | * auto run ets on postinstall ([#201](https://github.com/eggjs/egg-bin/issues/201)) ([3e30c3d](https://github.com/eggjs/egg-bin/commit/3e30c3d6842b9a94dd631b93956c8a2201816025)) 238 | 239 | ## [5.10.0](https://github.com/eggjs/egg-bin/compare/v5.9.0...v5.10.0) (2023-01-03) 240 | 241 | 242 | ### Features 243 | 244 | * use mochawesome-with-mocha and enable mochawesome by default ([#200](https://github.com/eggjs/egg-bin/issues/200)) ([efa6ef5](https://github.com/eggjs/egg-bin/commit/efa6ef58df4756216b7e80adad9fb1c852c8c9f4)) 245 | 246 | ## [5.9.0](https://github.com/eggjs/egg-bin/compare/v5.8.1...v5.9.0) (2022-12-18) 247 | 248 | 249 | ### Features 250 | 251 | * auto require tsconfig-paths/register on typescript command ([#199](https://github.com/eggjs/egg-bin/issues/199)) ([82e3e3e](https://github.com/eggjs/egg-bin/commit/82e3e3ededd68258c5878e728553894fbd001d6d)) 252 | 253 | ## [5.8.1](https://github.com/eggjs/egg-bin/compare/v5.8.0...v5.8.1) (2022-12-18) 254 | 255 | 256 | ### Bug Fixes 257 | 258 | * add missing custom require ([#198](https://github.com/eggjs/egg-bin/issues/198)) ([1348220](https://github.com/eggjs/egg-bin/commit/13482208f117d2d3fa7d70334b84ef2791847acd)) 259 | 260 | ## [5.8.0](https://github.com/eggjs/egg-bin/compare/v5.7.0...v5.8.0) (2022-12-18) 261 | 262 | 263 | ### Features 264 | 265 | * [BREAKING CHANGE] drop espower support ([#197](https://github.com/eggjs/egg-bin/issues/197)) ([1fc3624](https://github.com/eggjs/egg-bin/commit/1fc362449b69502deb87671a7c1aa21bd5070c51)) 266 | 267 | ## [5.7.0](https://github.com/eggjs/egg-bin/compare/v5.6.1...v5.7.0) (2022-12-18) 268 | 269 | 270 | ### Features 271 | 272 | * disable espower by default ([#196](https://github.com/eggjs/egg-bin/issues/196)) ([5e35438](https://github.com/eggjs/egg-bin/commit/5e3543812854066a72e6ff61fda001b23bf493ad)) 273 | 274 | ## [5.6.1](https://github.com/eggjs/egg-bin/compare/v5.6.0...v5.6.1) (2022-12-17) 275 | 276 | 277 | ### Bug Fixes 278 | 279 | * revert mochawesome to false by default ([#195](https://github.com/eggjs/egg-bin/issues/195)) ([9c48e10](https://github.com/eggjs/egg-bin/commit/9c48e10d48be54945dce7ce6b3b673f971302fae)) 280 | 281 | ## [5.6.0](https://github.com/eggjs/egg-bin/compare/v5.5.0...v5.6.0) (2022-12-17) 282 | 283 | 284 | ### Features 285 | 286 | * enable mochawesome by default ([#193](https://github.com/eggjs/egg-bin/issues/193)) ([6636e8f](https://github.com/eggjs/egg-bin/commit/6636e8f7cf3227e05a5b9acf1b1a0b4bd7291fb8)) 287 | 288 | 289 | 5.5.0 / 2022-11-19 290 | ================== 291 | 292 | **features** 293 | * [[`3c326b3`](http://github.com/eggjs/egg-bin/commit/3c326b3a5280a7272c84a248e387b590468500b7)] - 📦 NEW: Support mochawesome reporter (#192) (fengmk2 <>) 294 | 295 | 5.4.1 / 2022-11-15 296 | ================== 297 | 298 | **fixes** 299 | * [[`bfd7fab`](http://github.com/eggjs/egg-bin/commit/bfd7fabffa3ae795ab4ca6494bb3cdc0138d59ff)] - fix: --full-trace should be boolean (#191) (Haoliang Gao <>) 300 | 301 | **others** 302 | * [[`85581d2`](http://github.com/eggjs/egg-bin/commit/85581d2e77c9490fb196b1d844b57c4330539a5c)] - 🤖 TEST: Only test on Linux and macOS (#190) (fengmk2 <>) 303 | 304 | 5.4.0 / 2022-11-11 305 | ================== 306 | 307 | **features** 308 | * [[`72e925b`](http://github.com/eggjs/egg-bin/commit/72e925b490fa215432c76e46f6361bf52c169cc6)] - feat: default enable c8 report (#189) (killa <>) 309 | 310 | 5.3.3 / 2022-11-10 311 | ================== 312 | 313 | **fixes** 314 | * [[`e18ceda`](http://github.com/eggjs/egg-bin/commit/e18cedaf5482c1c58becc6674e3e7a512139f097)] - fix: fix cov env (#188) (killa <>) 315 | 316 | 5.3.2 / 2022-11-09 317 | ================== 318 | 319 | **fixes** 320 | * [[`88ba6d5`](http://github.com/eggjs/egg-bin/commit/88ba6d5b2d7dfd3d349d9687a57948d76b757885)] - fix: fix ENABLE_MOCHA_PARALLEL/AUTO_AGENT env (#187) (killa <>) 321 | 322 | 5.3.1 / 2022-11-05 323 | ================== 324 | 325 | **fixes** 326 | * [[`c5db00e`](http://github.com/eggjs/egg-bin/commit/c5db00eab9846c32d491487ac04cc4388565d9f8)] - fix: ignore eggTsHelper on node-test (#186) (fengmk2 <>) 327 | 328 | 5.3.0 / 2022-11-04 329 | ================== 330 | 331 | **features** 332 | * [[`78141e8`](http://github.com/eggjs/egg-bin/commit/78141e83a83f69f769470a100688c415a0ae1070)] - feat: impl parallel for mocha parallel mode (#185) (killa <>) 333 | 334 | 5.2.0 / 2022-07-15 335 | ================== 336 | 337 | **features** 338 | * [[`f564cbf`](http://github.com/eggjs/egg-bin/commit/f564cbf20be3b7eb7eed61b2fc95a2afa0b5936e)] - feat: support set eggTsHelper (#183) (mansonchor.github.com <>) 339 | 340 | 5.1.2 / 2022-07-05 341 | ================== 342 | 343 | **fixes** 344 | * [[`a1ec4f7`](http://github.com/eggjs/egg-bin/commit/a1ec4f7e4857bdbd15cc9a9f0e1948dd7f5c348a)] - fix: conflix source map support (#181) (吖猩 <>) 345 | 346 | 5.1.1 / 2022-06-23 347 | ================== 348 | 349 | **fixes** 350 | * [[`2e0fecd`](http://github.com/eggjs/egg-bin/commit/2e0fecd06e9c901d370d54542e1aa6dc7b183403)] - fix: fix espwoer-typescript inject logic (#178) (Yiyu He <>) 351 | 352 | 5.1.0 / 2022-06-04 353 | ================== 354 | 355 | **others** 356 | * [[`84489fe`](http://github.com/eggjs/egg-bin/commit/84489feb1341fad381e271efa39fe5d33317c776)] - 📦 NEW: Support run test with node:test (#177) (fengmk2 <>) 357 | 358 | 5.0.0 / 2022-06-04 359 | ================== 360 | 361 | **features** 362 | * [[`1e96da2`](http://github.com/eggjs/egg-bin/commit/1e96da2bb68203a5e972645df51ed0aa47ccaa8c)] - feat: support c8 report (#172) (羊鹿 <>) 363 | 364 | **others** 365 | * [[`6fb02f9`](http://github.com/eggjs/egg-bin/commit/6fb02f94b7d0f2b755a6b7c5eb780dca73cfc53e)] - 📦 NEW: [BREAKING] Only support Node.js 14 (#176) (fengmk2 <>) 366 | * [[`f32030b`](http://github.com/eggjs/egg-bin/commit/f32030b3b763e9f90c7b7f3d2f9f0f0b986051d3)] - Create codeql-analysis.yml (fengmk2 <>) 367 | * [[`c84671c`](http://github.com/eggjs/egg-bin/commit/c84671cc066f6ed7b26b070b4af688676beade2f)] - chore: update build status badge url (#174) (XiaoRui <>) 368 | 369 | 4.18.1 / 2022-02-18 370 | ================== 371 | 372 | **fixes** 373 | * [[`662b9e9`](http://github.com/eggjs/egg-bin/commit/662b9e924d8e83959ee44e2ef4b1ac7541378b33)] - fix: using ts-node in app should check tscompiler and deps (#170) (吖猩 <>), 374 | 375 | 4.18.0 / 2022-02-16 376 | ================== 377 | 378 | **features** 379 | * [[`4a54cec`](http://github.com/eggjs/egg-bin/commit/4a54cec8561595b33984e41982e8d1da96a6bd47)] - feat: allow loading ts compiler from cwd (#169) (Deng Ruoqi <>) 380 | 381 | 4.17.0 / 2022-01-21 382 | ================== 383 | 384 | **others** 385 | * [[`6403b4a`](http://github.com/eggjs/egg-bin/commit/6403b4aac8aa4cd872ecddbaf1ff118e98b0a192)] - support --intelli-espower-loader option (#168) (羊鹿 <>) 386 | 387 | 4.16.4 / 2021-07-09 388 | ================== 389 | 390 | **others** 391 | * [[`0765c4c`](http://github.com/eggjs/egg-bin/commit/0765c4cdc3abc1f4181dec2e31142ce5224a2cdf)] - ci: support node-v8.x (#164) (hyj1991 <>) 392 | 393 | 4.16.3 / 2021-07-08 394 | ================== 395 | 396 | **fixes** 397 | * [[`4a076e6`](http://github.com/eggjs/egg-bin/commit/4a076e606428b7eb80bdaa0e358cf4138a3ab0df)] - fix: ci failed (#162) (hyj1991 <>) 398 | 399 | **others** 400 | * [[`c915f1a`](http://github.com/eggjs/egg-bin/commit/c915f1a65340e1cfa04cf213a957f7ed9ac1c148)] - chore: update deps (#161) (hyj1991 <>) 401 | 402 | 4.16.2 / 2021-05-14 403 | ================== 404 | 405 | **fixes** 406 | * [[`563923a`](http://github.com/eggjs/egg-bin/commit/563923a68c0c0ae09075c4cedb855400deea623f)] - fix: remove espower typescript (#160) (吖猩 <>) 407 | 408 | 4.16.1 / 2021-04-25 409 | ================== 410 | 411 | **fixes** 412 | * [[`8666e9e`](http://github.com/eggjs/egg-bin/commit/8666e9eb9ce5016ac61af9f542b5518537a90a6b)] - fix: egginfo is not exists (#159) (吖猩 <>) 413 | 414 | 4.16.0 / 2021-04-23 415 | ================== 416 | 417 | **features** 418 | * [[`a74bae2`](http://github.com/eggjs/egg-bin/commit/a74bae2f604c13b50dadb8468a796867315120c7)] - feat: support switch ts compiler (#158) (吖猩 <>) 419 | 420 | 4.15.0 / 2020-07-03 421 | ================== 422 | 423 | **features** 424 | * [[`dcc9b25`](http://github.com/eggjs/egg-bin/commit/dcc9b256843815b6b4f1e505bfd1bf3aeffa4db0)] - feat: expose proc (#152) (TZ | 天猪 <>) 425 | 426 | 4.14.1 / 2020-01-02 427 | ================== 428 | 429 | **fixes** 430 | * [[`00afdf7`](http://github.com/eggjs/egg-bin/commit/00afdf7e0237a42360ffd40513cb0b11467efbb5)] - fix: auto add .setup.ts file (#147) (angleshe <<478647464@qq.com>>) 431 | 432 | 4.14.0 / 2019-10-12 433 | ================== 434 | 435 | **features** 436 | * [[`3cc3b0b`](http://github.com/eggjs/egg-bin/commit/3cc3b0bbc56553e66fdd3cc5b87716e61d859bdb)] - feat: test --dry-run (#145) (Shu Pengfei <>) 437 | 438 | **fixes** 439 | * [[`9cb8125`](http://github.com/eggjs/egg-bin/commit/9cb812537f1bc5e046186fe4f167742503a43abb)] - fix: revert nyc (#140) (Haoliang Gao <>) 440 | 441 | **others** 442 | * [[`26c7b59`](http://github.com/eggjs/egg-bin/commit/26c7b599c18dee30215f1ffe35e9b6ab03cd3dd7)] - chore(deps): update typescript to "^3" (#144) (waiting <>) 443 | * [[`979a1ae`](http://github.com/eggjs/egg-bin/commit/979a1aed424540451412a58e3181ae1e456a73f5)] - ci: fix timeout (#142) (waiting <>) 444 | 445 | 4.13.2 / 2019-09-27 446 | ================== 447 | 448 | **fixes** 449 | * [[`3b370ef`](http://github.com/eggjs/egg-bin/commit/3b370ef998b65e1a5f0390a7aa5f0fb4d2e96a7d)] - fix: nyc shim (#138) (dxd <>) 450 | 451 | 4.13.1 / 2019-04-28 452 | ================== 453 | 454 | **others** 455 | * [[`3665b0d`](http://github.com/eggjs/egg-bin/commit/3665b0d030258283bf8aa150019ae6214c9c85eb)] - deps: cleanup & fix high severity vulnerability (#133) (ZYSzys <<17367077526@163.com>>) 456 | 457 | 4.13.0 / 2019-04-23 458 | ================== 459 | 460 | **features** 461 | * [[`5c621f6`](http://github.com/eggjs/egg-bin/commit/5c621f6d6119fc0ac03b70e294e6cc18d2f88568)] - feat: should print error stack (#132) (TZ | 天猪 <>) 462 | 463 | 4.12.3 / 2019-04-09 464 | ================== 465 | 466 | **fixes** 467 | * [[`819d78f`](http://github.com/eggjs/egg-bin/commit/819d78fb4d8a1c13827f0e64c197e129777fe646)] - fix: debug mode detect (#130) (TZ | 天猪 <>) 468 | 469 | **others** 470 | * [[`f85aafb`](http://github.com/eggjs/egg-bin/commit/f85aafb8db6b5be1d1cf9cb88297747cafb96142)] - chore: update deps (#131) (TZ | 天猪 <>) 471 | 472 | 4.12.2 / 2019-04-04 473 | ================== 474 | 475 | **fixes** 476 | * [[`3b6819c`](http://github.com/eggjs/egg-bin/commit/3b6819ccdc1f2f6c81482f45097adfe544e6c874)] - fix: should not timeout when debugging (#129) (TZ | 天猪 <>) 477 | * [[`fcae123`](http://github.com/eggjs/egg-bin/commit/fcae1233518d094984aac0efe6890d679da533a0)] - fix: support --workers same as egg-scripts (#127) (TZ | 天猪 <>) 478 | 479 | 4.12.1 / 2019-03-26 480 | ================== 481 | 482 | **fixes** 483 | * [[`d802694`](http://github.com/eggjs/egg-bin/commit/d802694cc1039e0b0a3721917019c63b7599d59e)] - fix: downgrade ts-node (#126) (吖猩 <>) 484 | 485 | 4.12.0 / 2019-03-20 486 | ================== 487 | 488 | **others** 489 | * [[`44854f0`](http://github.com/eggjs/egg-bin/commit/44854f047823a0979b41bf7661e06be2dd5aef83)] - deps: bump ts-node version (#125) (吖猩 <>) 490 | 491 | 4.11.1 / 2019-03-06 492 | ================== 493 | 494 | **fixes** 495 | * [[`8f6135e`](http://github.com/eggjs/egg-bin/commit/8f6135edf46584f009633fa82436ed16037f6cc5)] - fix: ets not found (#124) (吖猩 <>) 496 | 497 | 4.11.0 / 2019-02-15 498 | =================== 499 | 500 | * feat: intergration with egg-ts-helper (#123) 501 | 502 | 4.10.0 / 2019-01-04 503 | =================== 504 | 505 | **features** 506 | * [[`904103f`](https://github.com/eggjs/egg-bin/commit/904103fe673e93bdf600f6eace4121cf4bf15d9b)] - feat: support read egg.require from package.json (#121) (吖猩 <>) 507 | 508 | **docs** 509 | * [[`0d553f6`](https://github.com/eggjs/egg-bin/commit/0d553f641155bc3ee9cc9d459a0ddff238c6c691)] - docs: test timeout is 6000ms (#115) (BiosSun <>) 510 | 511 | 4.9.0 / 2018-09-19 512 | ================== 513 | 514 | **features** 515 | * [[`51f93aa`](http://github.com/eggjs/egg-bin/commit/51f93aaa7506c9d0b90e3385c5bb6fa2cb488bc0)] - feat: support egg-bin test --changed (#111) (Yiyu He <>) 516 | 517 | **fixes** 518 | * [[`a82a87a`](http://github.com/eggjs/egg-bin/commit/a82a87a66939c327b65f394abd99a3d194c860bb)] - fix: debug-test invoke formatTestArgs (dead-horse <>) 519 | 520 | 4.8.5 / 2018-09-11 521 | ================== 522 | 523 | * feat: remove correct-source-map.js (#109) 524 | 525 | 4.8.4 / 2018-09-06 526 | ================== 527 | 528 | * fix: package.json to reduce vulnerabilities (#108) 529 | 530 | 4.8.3 / 2018-08-27 531 | ================== 532 | 533 | **fixes** 534 | * [[`ca4f78f`](http://github.com/eggjs/egg-bin/commit/ca4f78f5e7c608fbe9af37577c62a5b64bb2b45c)] - fix: fix source map line number incorrect (#107) (吖猩 <>) 535 | 536 | 4.8.2 / 2018-08-23 537 | ================== 538 | 539 | **features** 540 | * [[`35e89db`](http://github.com/eggjs/egg-bin/commit/35e89dbdbfcb6d2c6cd07f73145ead7c4c5421ce)] - feat: upgrade espower-typescript to 9.0 (#106) (吖猩 <>) 541 | 542 | 4.8.1 / 2018-08-01 543 | ================== 544 | 545 | * fix: fixed ts-node ignore files (#105) 546 | 547 | 4.8.0 / 2018-07-31 548 | ================== 549 | 550 | * chore: update deps (#104) 551 | * feat(cov): add nyc instrument passthrough (#103) 552 | 553 | 4.7.1 / 2018-06-29 554 | ================== 555 | 556 | * fix: should exit when no test files found (#100) 557 | 558 | 4.7.0 / 2018-04-18 559 | ================== 560 | 561 | * feat: add ts env in command (#98) 562 | 563 | 4.6.3 / 2018-04-05 564 | ================== 565 | 566 | * fix: should only read pkg if argv.typescript not pass (#97) 567 | 568 | 4.6.2 / 2018-04-02 569 | ================== 570 | 571 | **fixes** 572 | * [[`e73c569`](http://github.com/eggjs/egg-bin/commit/e73c56952cdbd0f925e8aea1ad1b3098e9ccc90e)] - fix: should ignore fixtures and node_modules (#96) (Haoliang Gao <>) 573 | * [[`7531faa`](http://github.com/eggjs/egg-bin/commit/7531faaae98e126ec0151721a5fbf7a73b6246b3)] - fix: support relative path (#95) (TZ | 天猪 <>) 574 | 575 | 4.6.1 / 2018-03-31 576 | ================== 577 | 578 | * fix: remove ts extensions by default (#94) 579 | 580 | 4.6.0 / 2018-03-30 581 | ================== 582 | 583 | * chore: don't need to log at vscode and webstorm (#93) 584 | * feat: support egg.typescript (#92) 585 | * feat: cov support typescript (#91) 586 | 587 | 4.5.0 / 2018-03-28 588 | ================== 589 | 590 | * feat: support typescript (#89) 591 | * feat: set EGG_MASTER_CLOSE_TIMEOUT when run dev (#88) 592 | 593 | 4.4.1 / 2018-03-26 594 | ================== 595 | 596 | * feat: revert egg-bin check (#90) 597 | 598 | 4.4.0 / 2018-02-24 599 | ================== 600 | 601 | * feat: egg-bin check (#87) 602 | 603 | 4.3.7 / 2017-12-13 604 | ================== 605 | 606 | **fixes** 607 | * [[`6689962`](http://github.com/eggjs/egg-bin/commit/6689962082fb86591adfcaf0d85687096cdb851d)] - fix: make sure files sort in all platforms (#86) (fengmk2 <>) 608 | 609 | 4.3.6 / 2017-11-30 610 | ================== 611 | 612 | * deps: autod@3.0 (#85) 613 | * test: Node 8.7.0 has improved stack for promise (#84) 614 | 615 | 4.3.5 / 2017-10-10 616 | ================== 617 | 618 | **fixes** 619 | * [[`7386194`](http://github.com/eggjs/egg-bin/commit/7386194d94ec8b0d0faee766fe98f0f4f2ece8a2)] - fix: force exit when runner complete (#83) (Haoliang Gao <>) 620 | 621 | **others** 622 | * [[`a7c4b53`](http://github.com/eggjs/egg-bin/commit/a7c4b53c3aab8ee4a7c3c65e39f6480de97a9ea1)] - chore: remove incorrect history (#82) (Haoliang Gao <>) 623 | 624 | 4.3.4 / 2017-10-09 625 | ================== 626 | 627 | Upgrade mocha@4, see https://boneskull.com/mocha-v4-nears-release 628 | 629 | **fixes** 630 | * [[`e3c33e9`](http://github.com/eggjs/egg-bin/commit/e3c33e9fbc8c67ce733237ff7c0c41f35654712f)] - fix: package.json to reduce vulnerabilities (#81) (Snyk bot <>) 631 | 632 | 633 | 4.3.3 / 2017-09-21 634 | ================== 635 | 636 | * chore: dont print devtools link at vscode (#75) 637 | 638 | 4.3.2 / 2017-09-14 639 | ================== 640 | 641 | **fixes** 642 | * [[`2e3498e`](http://github.com/eggjs/egg-bin/commit/2e3498e6ca1b81814a2d1a4db4a8a37fb0d6d880)] - fix: use inspector at 7.x+ (#74) (TZ | 天猪 <>) 643 | 644 | 4.3.1 / 2017-09-13 645 | ================== 646 | 647 | **features** 648 | * [[`678b83d`](http://github.com/eggjs/egg-bin/commit/678b83d64ad850ac390607ee281e5336473da808)] - feat: debug proxy support (TZ <>) 649 | * [[`c65a00d`](http://github.com/eggjs/egg-bin/commit/c65a00dc69fbca3924bcd848c94bc0b11a3ee17a)] - feat: revert to 4.2.0 (TZ <>) 650 | 651 | **fixes** 652 | * [[`469739f`](http://github.com/eggjs/egg-bin/commit/469739f1b494c647fcb06e0db432d435ed9e1805)] - fix: debug at 6.x (TZ <>) 653 | 654 | **others** 655 | * [[`2be5245`](http://github.com/eggjs/egg-bin/commit/2be52459ed22dd3c0a22b080f7e29ae876d2914f)] - docs: add readme (TZ <>) 656 | * [[`3e8ce0d`](http://github.com/eggjs/egg-bin/commit/3e8ce0d3aaaea793f466b768f45f77e4fcc7b001)] - refactor: use common-bin parse execArgv (TZ <>) 657 | 658 | 4.3.0 / 2017-09-07 659 | ================== 660 | 661 | **others** 662 | * [[`83afba3`](http://github.com/eggjs/egg-bin/commit/83afba3a43e9e7d233263f6deba792d1f4c1a1d9)] - deps: update common-bin (TZ <>) 663 | * [[`f7628b2`](http://github.com/eggjs/egg-bin/commit/f7628b22042168d522b9b69344c9a54ab1fa1305)] - refactor: egg-bin debug pass debugOptions to startCluster (TZ <>) 664 | * [[`831c77d`](http://github.com/eggjs/egg-bin/commit/831c77d3d0a269e1ab1243471ef34bb53df0fb80)] - refactor: use common-bin parse execArgv (TZ <>) 665 | 666 | 4.2.0 / 2017-08-30 667 | ================== 668 | 669 | * feat: support $NODE_DEBUG_OPTION (#71) 670 | 671 | 4.1.0 / 2017-08-02 672 | ================== 673 | 674 | * feat: add `egg-bin autod --check` command (#70) 675 | 676 | 4.0.5 / 2017-07-05 677 | ================== 678 | 679 | * fix: only hotfix spawn-wrap on windows (#69) 680 | 681 | 4.0.4 / 2017-06-21 682 | ================== 683 | 684 | * fix: remove temp excludes 685 | * feat(cov): add prerequire option (#53) 686 | 687 | 4.0.3 / 2017-06-21 688 | ================== 689 | 690 | * fix: There is a case sensitive issue from spawn-wrap on Windows (#67) 691 | 692 | 4.0.2 / 2017-06-20 693 | ================== 694 | 695 | * fix: should support multi exclude dirs (#66) 696 | 697 | 4.0.1 / 2017-06-20 698 | ================== 699 | 700 | * fix: ignore frontend files and document files (#65) 701 | 702 | 4.0.0 / 2017-06-20 703 | ================== 704 | 705 | * feat: use nyc instead of istanbul (#63) 706 | 707 | 3.7.0 / 2017-06-19 708 | ================== 709 | 710 | * feat: cov support output json-summary (#64) 711 | 712 | 3.6.0 / 2017-06-14 713 | ================== 714 | 715 | * feat: support cov command in win32 (#52) 716 | * test: skip assert error stack on node >= 7.0.0 (#61) 717 | * fix: clean more mocha error stack (#60) 718 | 719 | 3.5.0 / 2017-06-08 720 | ================== 721 | 722 | * feat: simplify mocha error stack (#59) 723 | 724 | 3.4.2 / 2017-06-04 725 | ================== 726 | 727 | * fix: use context.env instead of process.env (#58) 728 | 729 | 3.4.1 / 2017-06-01 730 | ================== 731 | 732 | * fix: don't pass prerequire (#57) 733 | 734 | 3.4.0 / 2017-05-18 735 | ================== 736 | 737 | * feat(cov): add prerequire option (#53) 738 | 739 | 3.3.2 / 2017-04-28 740 | ================== 741 | 742 | * feat: change default timeout to 60000 (#50) 743 | 744 | 3.3.1 / 2017-04-25 745 | ================== 746 | 747 | * fix: cov replaced warning at win (#49) 748 | 749 | 3.3.0 / 2017-04-17 750 | ================== 751 | 752 | * feat: pass --check to pkgfiles (#48) 753 | 754 | 3.2.1 / 2017-04-01 755 | ================== 756 | 757 | * fix: -x only support string (#47) 758 | 759 | 3.2.0 / 2017-03-29 760 | ================== 761 | 762 | * feat: extractArgv refactor & extract debug port 763 | * feat: extractArgv support expose_debug_as 764 | 765 | 3.1.0 / 2017-03-21 766 | ================== 767 | 768 | * feat: use unparseArgv from common-bin (#45) 769 | 770 | 3.0.1 / 2017-03-21 771 | ================== 772 | 773 | * fix(cov): istanbul path env (#44) 774 | 775 | 3.0.0 / 2017-03-21 776 | ================== 777 | 778 | * refactor: [BREAKING_CHANGE] use common-bin 2.x (#41) 779 | 780 | 2.4.0 / 2017-03-09 781 | ================== 782 | 783 | * deps: upgrade istanbul to 1.1.0-alpha.1 (#43) 784 | 785 | 2.3.0 / 2017-03-08 786 | ================== 787 | 788 | * fix: add missing deps (#42) 789 | * feat: update pkg.files that if file exists (#37) 790 | * refactor: use framework (#39) 791 | 792 | 2.2.3 / 2017-02-25 793 | ================== 794 | 795 | * fix: support egg-bin dev --cluster and --baseDir (#36) 796 | 797 | 2.2.2 / 2017-02-25 798 | ================== 799 | 800 | * fix: use co-mocha instead of thunk-mocha (#38) 801 | 802 | 2.2.1 / 2017-02-19 803 | ================== 804 | 805 | * fix: support node4 (#35) 806 | 807 | 2.2.0 / 2017-02-15 808 | ================== 809 | 810 | * feat: commands support specific execArgv(harmony) (#33) 811 | * docs: missing debug description for zh-cn (#34) 812 | 813 | 2.1.0 / 2017-02-14 814 | ================== 815 | 816 | * feat: add sticky mode support (#32) 817 | 818 | 2.0.2 / 2017-01-24 819 | ================== 820 | 821 | * fix: .setup.js should be the first test file (#30) 822 | 823 | 2.0.1 / 2017-01-17 824 | ================== 825 | 826 | * fix: should support -p (#27) 827 | * docs: use V8 Inspector Integration for debug 828 | 829 | 2.0.0 / 2017-01-16 830 | ================== 831 | 832 | * feat(debug): [BREAKING_CHANGE] remove iron-node (#26) 833 | 834 | 1.10.1 / 2017-01-16 835 | ================== 836 | 837 | * fix: should pass customEgg to startCluster (#25) 838 | 839 | 1.10.0 / 2016-12-28 840 | ================== 841 | 842 | * feat: auto require setup file (#24) 843 | 844 | 1.9.1 / 2016-12-16 845 | ================== 846 | 847 | * fix: make sure dev command eggPath can be override (#23) 848 | 849 | 1.9.0 / 2016-12-16 850 | ================== 851 | 852 | * feat: auto detect available port (#22) 853 | 854 | 1.8.1 / 2016-12-14 855 | ================== 856 | 857 | * fix: add power-assert to deps (#21) 858 | 859 | 1.8.0 / 2016-12-14 860 | ================== 861 | 862 | * feat: build-in intelli-espower-loader (#20) 863 | 864 | 1.7.0 / 2016-11-03 865 | ================== 866 | 867 | * feat: try to use --inspect first (#19) 868 | 869 | 1.6.0 / 2016-10-28 870 | ================== 871 | 872 | * feat: use test when run cov on Windows (#18) 873 | 874 | 1.5.3 / 2016-10-28 875 | ================== 876 | 877 | * fix: wait more time for Window :cry: (#17) 878 | 879 | 1.5.2 / 2016-10-26 880 | ================== 881 | 882 | * fix(cov): wait 1 second for Windows (#16) 883 | 884 | 1.5.1 / 2016-10-20 885 | ================== 886 | 887 | * fix: link mocha bin from inner file (#15) 888 | * docs:add egg-bin dev options doc (#14) 889 | 890 | 1.5.0 / 2016-10-16 891 | ================== 892 | 893 | * test: exports mocha bin (#13) 894 | 895 | 1.4.0 / 2016-09-29 896 | ================== 897 | 898 | * feat(dev): pass debug args to execArgv (#12) 899 | 900 | 1.3.0 / 2016-08-19 901 | ================== 902 | 903 | * feat: resolve istanbul path for coffee (#9) 904 | 905 | 1.2.1 / 2016-08-18 906 | ================== 907 | 908 | * fix: can not find iron-node in subprocess (#8) 909 | 910 | 1.2.0 / 2016-08-04 911 | ================== 912 | 913 | * feat: add COV_EXCLUDES for coverage excludes (#7) 914 | 915 | 1.1.1 / 2016-08-03 916 | ================== 917 | 918 | * chore(deps): upgrade mocha@3 and glob@7 (#6) 919 | 920 | 1.1.0 / 2016-07-29 921 | ================== 922 | 923 | * feat: support mocha custom require args (#5) 924 | * refactor: use common-bin (#4) 925 | 926 | 1.0.2 / 2016-07-12 927 | ================== 928 | 929 | * refactor: rename DevCommand.js to dev_command.js (#3) 930 | * chore: add security check badge (#2) 931 | * refactor: use egg-utils (#1) 932 | 933 | 1.0.1 / 2016-06-20 934 | ================== 935 | 936 | * fix: let sub class can override getFrameworkOrEggPath 937 | 938 | 1.0.0 / 2016-06-19 939 | ================== 940 | 941 | * init version 942 | --------------------------------------------------------------------------------