├── test ├── lib │ ├── plugins │ │ ├── empty.txt │ │ ├── static.test.js │ │ ├── depd.test.js │ │ ├── onerror.test.js │ │ ├── logrotator.test.js │ │ └── schedule.test.js │ ├── core │ │ ├── config │ │ │ └── config.test.js │ │ ├── loader │ │ │ ├── load_router.test.js │ │ │ └── load_app.test.js │ │ ├── context_httpclient.test.js │ │ └── httpclient_tracer_demo.test.js │ └── cluster │ │ ├── cluster-client-error.test.js │ │ └── app_worker.test.js ├── fixtures │ ├── apps │ │ ├── view-render │ │ │ ├── app │ │ │ │ ├── a.js │ │ │ │ ├── view │ │ │ │ │ ├── a.html │ │ │ │ │ ├── shtml.html │ │ │ │ │ ├── sjs.html │ │ │ │ │ ├── xss.html │ │ │ │ │ ├── index.html │ │ │ │ │ ├── inject.html │ │ │ │ │ ├── form_csrf.html │ │ │ │ │ ├── locals.html │ │ │ │ │ └── nonce.html │ │ │ │ ├── controller │ │ │ │ │ ├── csrf.js │ │ │ │ │ ├── empty.js │ │ │ │ │ ├── nonce.js │ │ │ │ │ ├── home.js │ │ │ │ │ ├── inject.js │ │ │ │ │ ├── sjs.js │ │ │ │ │ ├── context.js │ │ │ │ │ ├── locals.js │ │ │ │ │ ├── string.js │ │ │ │ │ ├── xss.js │ │ │ │ │ ├── shtml.js │ │ │ │ │ └── async.js │ │ │ │ ├── extend │ │ │ │ │ └── helper.js │ │ │ │ └── router.js │ │ │ ├── package.json │ │ │ └── config │ │ │ │ ├── plugin.js │ │ │ │ └── config.default.js │ │ ├── i18n │ │ │ ├── config │ │ │ │ ├── locales │ │ │ │ │ ├── xx.txt │ │ │ │ │ ├── zh-CN.js │ │ │ │ │ └── de.json │ │ │ │ ├── config.default.js │ │ │ │ └── plugin.js │ │ │ ├── package.json │ │ │ └── app │ │ │ │ ├── router.js │ │ │ │ ├── view │ │ │ │ └── home.html │ │ │ │ └── controller │ │ │ │ ├── home.js │ │ │ │ └── message.js │ │ ├── middlewares │ │ │ ├── app │ │ │ │ ├── crossdomain.xml │ │ │ │ ├── robots.txt │ │ │ │ ├── controller │ │ │ │ │ ├── error.js │ │ │ │ │ └── home.js │ │ │ │ └── router.js │ │ │ ├── server.conf │ │ │ ├── package.json │ │ │ └── config │ │ │ │ └── config.default.js │ │ ├── watcher-development-app │ │ │ ├── tmp.txt │ │ │ ├── tmp │ │ │ │ └── tmp.txt │ │ │ ├── tmp-agent.txt │ │ │ ├── tmp-agent │ │ │ │ └── tmp.txt │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.unittest.js │ │ │ ├── agent.js │ │ │ └── app │ │ │ │ └── router.js │ │ ├── app-ts │ │ │ ├── .gitignore │ │ │ ├── config │ │ │ │ └── config.ts │ │ │ ├── package.json │ │ │ ├── app │ │ │ │ ├── router.ts │ │ │ │ ├── service │ │ │ │ │ └── foo.ts │ │ │ │ └── controller │ │ │ │ │ └── foo.ts │ │ │ └── tsconfig.json │ │ ├── loader-plugin │ │ │ ├── config │ │ │ │ ├── map.json │ │ │ │ ├── config.default.js │ │ │ │ └── plugin.js │ │ │ ├── node_modules │ │ │ │ ├── d │ │ │ │ │ ├── .gitkeep │ │ │ │ │ ├── package.json │ │ │ │ │ └── config │ │ │ │ │ │ └── config.js │ │ │ │ ├── rds │ │ │ │ │ ├── .gitkeep │ │ │ │ │ └── package.json │ │ │ │ ├── a │ │ │ │ │ ├── app │ │ │ │ │ │ ├── proxy │ │ │ │ │ │ │ └── a.js │ │ │ │ │ │ └── service │ │ │ │ │ │ │ └── bar1.js │ │ │ │ │ ├── config │ │ │ │ │ │ └── config.js │ │ │ │ │ ├── package.json │ │ │ │ │ └── app.js │ │ │ │ ├── b │ │ │ │ │ ├── config │ │ │ │ │ │ ├── antx.dev.properties │ │ │ │ │ │ ├── antx.test.properties │ │ │ │ │ │ ├── antx.prod.properties │ │ │ │ │ │ ├── antx.unittest.properties │ │ │ │ │ │ └── antx.default.properties │ │ │ │ │ ├── package.json │ │ │ │ │ ├── app.js │ │ │ │ │ └── app │ │ │ │ │ │ └── service │ │ │ │ │ │ └── bar2.js │ │ │ │ ├── c │ │ │ │ │ ├── package.json │ │ │ │ │ ├── config │ │ │ │ │ │ └── config.js │ │ │ │ │ └── app.js │ │ │ │ └── a1 │ │ │ │ │ └── package.json │ │ │ ├── package.json │ │ │ ├── app │ │ │ │ ├── service │ │ │ │ │ ├── foo2.js │ │ │ │ │ ├── foo3 │ │ │ │ │ │ └── foo3.js │ │ │ │ │ ├── foo.js │ │ │ │ │ ├── Foo4.js │ │ │ │ │ └── fooDir │ │ │ │ │ │ └── Foo5.js │ │ │ │ └── router.js │ │ │ ├── plugins │ │ │ │ ├── f │ │ │ │ │ └── package.json │ │ │ │ ├── g │ │ │ │ │ └── package.json │ │ │ │ └── e │ │ │ │ │ └── package.json │ │ │ └── app.js │ │ ├── multiple-view-engine │ │ │ ├── app │ │ │ │ ├── view │ │ │ │ │ ├── ext │ │ │ │ │ │ ├── a.ejs │ │ │ │ │ │ └── a.nj │ │ │ │ │ └── loader │ │ │ │ │ │ ├── a.ejs │ │ │ │ │ │ ├── a.html │ │ │ │ │ │ ├── a.noext │ │ │ │ │ │ └── a.nj.ejs │ │ │ │ ├── view2 │ │ │ │ │ └── loader │ │ │ │ │ │ ├── a.nj │ │ │ │ │ │ └── from-view2.ejs │ │ │ │ ├── router.js │ │ │ │ └── controller │ │ │ │ │ └── view.js │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ ├── config.unittest.js │ │ │ │ └── config.default.js │ │ │ ├── app.js │ │ │ ├── nunjucks.js │ │ │ └── ejs.js │ │ ├── logger-output-json │ │ │ ├── config │ │ │ │ ├── map.json │ │ │ │ └── config.default.js │ │ │ └── package.json │ │ ├── worker-die │ │ │ ├── app.js │ │ │ ├── package.json │ │ │ └── config │ │ │ │ └── config.default.js │ │ ├── development │ │ │ ├── app │ │ │ │ ├── public │ │ │ │ │ └── foo.js │ │ │ │ └── router.js │ │ │ ├── config │ │ │ │ ├── plugin.js │ │ │ │ └── config.default.js │ │ │ └── package.json │ │ ├── static-server │ │ │ ├── app │ │ │ │ └── public │ │ │ │ │ └── foo.js │ │ │ ├── config │ │ │ │ ├── plugin.js │ │ │ │ └── config.default.js │ │ │ └── package.json │ │ ├── demo │ │ │ ├── package.json │ │ │ ├── app │ │ │ │ ├── controller │ │ │ │ │ ├── home.js │ │ │ │ │ ├── hello.js │ │ │ │ │ ├── foo.js │ │ │ │ │ ├── ip.js │ │ │ │ │ └── logger.js │ │ │ │ └── router.js │ │ │ └── config │ │ │ │ └── config.default.js │ │ ├── docapp │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ └── app │ │ │ │ └── middleware │ │ │ │ └── koastatic.js │ │ ├── empty │ │ │ ├── package.json │ │ │ └── config │ │ │ │ └── config.default.js │ │ ├── helper │ │ │ ├── package.json │ │ │ ├── app │ │ │ │ ├── controller │ │ │ │ │ └── home.js │ │ │ │ └── router.js │ │ │ └── config │ │ │ │ └── config.default.js │ │ ├── locals │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ ├── app │ │ │ │ └── helper.js │ │ │ └── app.js │ │ ├── logger │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ ├── config.unittest.js │ │ │ │ ├── config.local.js │ │ │ │ └── config.default.js │ │ │ ├── agent.js │ │ │ └── app.js │ │ ├── mock-production-app │ │ │ ├── config │ │ │ │ ├── map.json │ │ │ │ ├── config.unittest.js │ │ │ │ └── config.js │ │ │ └── package.json │ │ ├── router-app │ │ │ ├── app │ │ │ │ ├── view │ │ │ │ │ └── locals │ │ │ │ │ │ └── router.html │ │ │ │ ├── controller │ │ │ │ │ ├── locals.js │ │ │ │ │ ├── members.js │ │ │ │ │ └── posts.js │ │ │ │ └── router.js │ │ │ ├── package.json │ │ │ └── config │ │ │ │ └── config.default.js │ │ ├── app-die │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ ├── package.json │ │ │ └── app │ │ │ │ └── router.js │ │ ├── favicon │ │ │ ├── package.json │ │ │ ├── app │ │ │ │ ├── controller │ │ │ │ │ └── home.js │ │ │ │ └── router.js │ │ │ └── config │ │ │ │ └── config.default.js │ │ ├── notfound │ │ │ ├── package.json │ │ │ └── config │ │ │ │ └── config.default.js │ │ ├── notready │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ ├── config.default.js │ │ │ │ └── plugin.js │ │ │ └── a │ │ │ │ ├── package.json │ │ │ │ └── app.js │ │ ├── onerror │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ ├── config.unittest.js │ │ │ │ └── config.default.js │ │ │ └── app │ │ │ │ ├── router.js │ │ │ │ └── controller │ │ │ │ ├── user.js │ │ │ │ └── home.js │ │ ├── response │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ ├── package.json │ │ │ └── app │ │ │ │ └── router.js │ │ ├── schedule │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ └── app │ │ │ │ └── schedule │ │ │ │ └── sub │ │ │ │ └── cron.js │ │ ├── secure-app │ │ │ ├── config │ │ │ │ ├── plugin.js │ │ │ │ ├── config.default.js │ │ │ │ └── config.unittest.js │ │ │ ├── package.json │ │ │ └── app │ │ │ │ ├── router.js │ │ │ │ └── controller │ │ │ │ └── index.js │ │ ├── agent-app │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ ├── config.default.js │ │ │ │ └── plugin.js │ │ │ ├── plugins │ │ │ │ └── mock-client │ │ │ │ │ ├── config │ │ │ │ │ └── config.default.js │ │ │ │ │ └── agent.js │ │ │ ├── app.js │ │ │ └── app │ │ │ │ └── router.js │ │ ├── agent-die │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ ├── agent.js │ │ │ └── start.js │ │ ├── agent-throw │ │ │ ├── config │ │ │ │ ├── config.default.js │ │ │ │ └── config.unittest.js │ │ │ ├── package.json │ │ │ ├── agent.js │ │ │ └── app │ │ │ │ └── router.js │ │ ├── aliyun-egg │ │ │ ├── package.json │ │ │ ├── agent.js │ │ │ ├── config │ │ │ │ ├── config.default.js │ │ │ │ └── plugin.js │ │ │ ├── app.js │ │ │ ├── index.js │ │ │ └── lib │ │ │ │ ├── plugins │ │ │ │ └── custom │ │ │ │ │ ├── agent.js │ │ │ │ │ └── app.js │ │ │ │ ├── agent.js │ │ │ │ └── aliyun-egg.js │ │ ├── app-router │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ └── app │ │ │ │ ├── controller │ │ │ │ └── home.js │ │ │ │ └── router.js │ │ ├── app-server │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ ├── app │ │ │ │ └── router.js │ │ │ └── app.js │ │ ├── app-throw │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ ├── config.default.js │ │ │ │ └── config.unittest.js │ │ │ └── app │ │ │ │ └── router.js │ │ ├── async-app │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ ├── app │ │ │ │ ├── router.js │ │ │ │ ├── middleware │ │ │ │ │ ├── async.js │ │ │ │ │ └── router.js │ │ │ │ ├── schedule │ │ │ │ │ └── async.js │ │ │ │ ├── controller │ │ │ │ │ └── api.js │ │ │ │ └── service │ │ │ │ │ └── api.js │ │ │ └── app.js │ │ ├── csrf-enable │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ ├── config.default.js │ │ │ │ └── config.unittest.js │ │ │ └── app │ │ │ │ ├── controller │ │ │ │ └── api.js │ │ │ │ └── router.js │ │ ├── csrf-ignore │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ ├── config.unittest.js │ │ │ │ └── config.default.js │ │ │ └── app │ │ │ │ ├── controller │ │ │ │ └── api.js │ │ │ │ └── router.js │ │ ├── dumpconfig │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ └── app.js │ │ ├── encrypt-cookies │ │ │ ├── config │ │ │ │ ├── plugin.js │ │ │ │ └── config.default.js │ │ │ ├── package.json │ │ │ └── app │ │ │ │ ├── router.js │ │ │ │ └── controller │ │ │ │ └── home.js │ │ ├── get-logger │ │ │ ├── package.json │ │ │ ├── app │ │ │ │ └── router.js │ │ │ └── config │ │ │ │ └── config.js │ │ ├── koa-session │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ ├── package.json │ │ │ └── app │ │ │ │ ├── controller │ │ │ │ ├── clear.js │ │ │ │ └── home.js │ │ │ │ └── router.js │ │ ├── logger-level-debug │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ └── app │ │ │ │ └── router.js │ │ ├── messenger │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ ├── app.js │ │ │ └── agent.js │ │ ├── mock-dev-app │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ └── package.json │ │ ├── multipart │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ └── app │ │ │ │ ├── controller │ │ │ │ ├── home.js │ │ │ │ └── upload.js │ │ │ │ ├── router.js │ │ │ │ └── view │ │ │ │ └── home.html │ │ ├── service-app │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ └── app │ │ │ │ ├── router.js │ │ │ │ ├── controller │ │ │ │ └── user.js │ │ │ │ └── service │ │ │ │ └── user.js │ │ ├── tracer-demo │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ ├── app.js │ │ │ ├── agent.js │ │ │ ├── app │ │ │ │ ├── router.js │ │ │ │ └── controller │ │ │ │ │ └── home.js │ │ │ └── tracer.js │ │ ├── agent-restart │ │ │ ├── package.json │ │ │ ├── client.js │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ ├── app.js │ │ │ └── agent.js │ │ ├── aliyun-egg-app │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ ├── package.json │ │ │ └── app │ │ │ │ ├── router.js │ │ │ │ └── controller │ │ │ │ └── home.js │ │ ├── app-locals-getter │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ ├── package.json │ │ │ └── app │ │ │ │ └── router.js │ │ ├── csrf-disable │ │ │ ├── package.json │ │ │ ├── app │ │ │ │ ├── router.js │ │ │ │ └── controller │ │ │ │ │ └── api.js │ │ │ └── config │ │ │ │ └── config.default.js │ │ ├── custom-logger │ │ │ ├── package.json │ │ │ └── config │ │ │ │ └── config.default.js │ │ ├── keys-exists │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ └── package.json │ │ ├── keys-missing │ │ │ └── package.json │ │ ├── loader-plugin-dep │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ ├── config.default.js │ │ │ │ └── plugin.js │ │ │ └── plugins │ │ │ │ ├── d │ │ │ │ └── package.json │ │ │ │ ├── e │ │ │ │ └── package.json │ │ │ │ ├── f │ │ │ │ └── package.json │ │ │ │ ├── a │ │ │ │ └── package.json │ │ │ │ ├── b │ │ │ │ └── package.json │ │ │ │ └── c │ │ │ │ └── package.json │ │ ├── logger-reload │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ └── app │ │ │ │ ├── router.js │ │ │ │ └── controller │ │ │ │ └── home.js │ │ ├── mock-production-app-do-not-force │ │ │ ├── config │ │ │ │ ├── map.json │ │ │ │ ├── config.unittest.js │ │ │ │ └── config.js │ │ │ └── package.json │ │ ├── override_method │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ ├── package.json │ │ │ └── app │ │ │ │ └── router.js │ │ ├── reload-worker │ │ │ ├── package.json │ │ │ ├── app │ │ │ │ ├── controller │ │ │ │ │ ├── home.js │ │ │ │ │ └── home1.js │ │ │ │ └── router.js │ │ │ └── config │ │ │ │ └── config.default.js │ │ ├── agent-app-sync │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ ├── app │ │ │ │ └── router.js │ │ │ ├── agent.js │ │ │ └── app.js │ │ ├── agent-client-app │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ ├── app.js │ │ │ ├── agent.js │ │ │ └── app │ │ │ │ └── router.js │ │ ├── aliyun-egg-biz │ │ │ ├── package.json │ │ │ └── index.js │ │ ├── cluster_mod_app │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ ├── lib │ │ │ │ ├── api_client.js │ │ │ │ └── api_client_2.js │ │ │ ├── app │ │ │ │ ├── router.js │ │ │ │ └── controller │ │ │ │ │ └── home.js │ │ │ ├── agent.js │ │ │ └── app.js │ │ ├── ctx-background │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ ├── config.default.js │ │ │ │ └── config.unittest.js │ │ │ └── app │ │ │ │ ├── router.js │ │ │ │ └── controller │ │ │ │ ├── home.js │ │ │ │ ├── app.js │ │ │ │ └── error.js │ │ ├── custom-env-app │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ └── app │ │ │ │ └── router.js │ │ ├── logrotator-app │ │ │ ├── package.json │ │ │ ├── app │ │ │ │ └── router.js │ │ │ └── config │ │ │ │ └── config.default.js │ │ ├── messenger-random │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ ├── app.js │ │ │ └── agent.js │ │ ├── nobuffer-logger │ │ │ ├── package.json │ │ │ └── config │ │ │ │ └── config.default.js │ │ ├── singleton-demo │ │ │ ├── package.json │ │ │ ├── app.js │ │ │ ├── agent.js │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ └── create.js │ │ ├── subdir-services │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ └── app │ │ │ │ ├── router.js │ │ │ │ ├── service │ │ │ │ ├── old_style.js │ │ │ │ ├── ok.js │ │ │ │ ├── user.js │ │ │ │ ├── foo │ │ │ │ │ ├── subdir2 │ │ │ │ │ │ └── sub2.js │ │ │ │ │ ├── bar.js │ │ │ │ │ ├── subdir1 │ │ │ │ │ │ └── subdir11 │ │ │ │ │ │ │ └── bar.js │ │ │ │ │ └── subdir │ │ │ │ │ │ └── bar.js │ │ │ │ ├── cif │ │ │ │ │ └── user.js │ │ │ │ └── certify-personal │ │ │ │ │ └── mobile-hi │ │ │ │ │ └── do_certify.js │ │ │ │ └── controller │ │ │ │ └── home.js │ │ ├── app-start-timeout │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ ├── config.default.js │ │ │ │ └── config.unittest.js │ │ │ └── app.js │ │ ├── base-context-class │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ └── app │ │ │ │ ├── router.js │ │ │ │ ├── service │ │ │ │ └── home.js │ │ │ │ └── controller │ │ │ │ └── home.js │ │ ├── close-watcher-logrotator │ │ │ ├── config │ │ │ │ ├── config.default.js │ │ │ │ └── plugin.js │ │ │ └── package.json │ │ ├── context-config-app │ │ │ ├── package.json │ │ │ ├── app │ │ │ │ ├── router.js │ │ │ │ ├── extend │ │ │ │ │ └── context.js │ │ │ │ └── controller │ │ │ │ │ └── home.js │ │ │ └── config │ │ │ │ ├── config.js │ │ │ │ └── config.local.js │ │ ├── context_httpclient │ │ │ ├── package.json │ │ │ └── config │ │ │ │ └── config.default.js │ │ ├── dump-ignore-error │ │ │ ├── package.json │ │ │ └── config │ │ │ │ └── config.default.js │ │ ├── httpclient-tracer │ │ │ ├── package.json │ │ │ ├── app.js │ │ │ └── config │ │ │ │ └── plugin.js │ │ ├── watcher-type-default │ │ │ ├── package.json │ │ │ └── config │ │ │ │ └── config.unittest.js │ │ ├── body_parser_testapp │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ └── app │ │ │ │ └── router.js │ │ ├── cluster-client-error │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ └── app.js │ │ ├── dnscache_httpclient │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ ├── config.unittest.js │ │ │ │ └── config.default.js │ │ │ └── app │ │ │ │ ├── router.js │ │ │ │ └── controller │ │ │ │ └── home.js │ │ ├── httpclient-overwrite │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ └── app.js │ │ ├── loader-plugin-noexist │ │ │ ├── package.json │ │ │ └── config │ │ │ │ ├── config.default.js │ │ │ │ └── plugin.js │ │ ├── master-worker-started │ │ │ ├── node_modules │ │ │ │ └── egg │ │ │ │ │ ├── package.json │ │ │ │ │ └── index.js │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ └── dispatch.js │ │ ├── messenger-app-agent │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ ├── app.js │ │ │ └── agent.js │ │ ├── messenger-broadcast │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ ├── app.js │ │ │ └── agent.js │ │ ├── notfound-custom-404 │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ └── app │ │ │ │ └── router.js │ │ ├── querystring-extended │ │ │ ├── package.json │ │ │ ├── app │ │ │ │ ├── router.js │ │ │ │ └── controller │ │ │ │ │ └── home.js │ │ │ └── config │ │ │ │ └── config.default.js │ │ ├── confused-configuration │ │ │ ├── package.json │ │ │ └── config │ │ │ │ └── config.default.js │ │ ├── loader-plugin-dep-missing │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ ├── config.default.js │ │ │ │ └── plugin.js │ │ │ └── plugins │ │ │ │ ├── a │ │ │ │ └── package.json │ │ │ │ ├── b │ │ │ │ └── package.json │ │ │ │ └── c │ │ │ │ └── package.json │ │ ├── loader-plugin-dep-recursive │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ ├── config.default.js │ │ │ │ └── plugin.js │ │ │ └── plugins │ │ │ │ ├── a │ │ │ │ └── package.json │ │ │ │ ├── b │ │ │ │ └── package.json │ │ │ │ └── c │ │ │ │ └── package.json │ │ ├── services_loader_verify │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ └── app │ │ │ │ └── service │ │ │ │ └── foo.js │ │ ├── app-server-with-hostname │ │ │ ├── package.json │ │ │ ├── app │ │ │ │ └── router.js │ │ │ └── config │ │ │ │ └── config.default.js │ │ ├── body_parser_testapp_ignore │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ └── app │ │ │ │ └── router.js │ │ ├── body_parser_testapp_match │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ └── app │ │ │ │ └── router.js │ │ ├── custom-context-getlogger │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ └── app │ │ │ │ ├── router.js │ │ │ │ ├── extend │ │ │ │ └── context.js │ │ │ │ └── controller │ │ │ │ └── home.js │ │ ├── body_parser_testapp_disable │ │ │ ├── package.json │ │ │ ├── config │ │ │ │ └── config.default.js │ │ │ └── app │ │ │ │ └── router.js │ │ ├── httpclient-agent-timeout-3000 │ │ │ ├── package.json │ │ │ └── config │ │ │ │ └── config.default.js │ │ └── httpclient-request-timeout-100 │ │ │ ├── package.json │ │ │ └── config │ │ │ └── config.default.js │ └── custom-egg │ │ ├── package.json │ │ └── index.js ├── async │ ├── index.test.js │ └── _async.js ├── index.test.js ├── app │ ├── middleware │ │ └── meta.test.js │ └── extend │ │ └── agent.test.js ├── doc.test.js └── ts │ └── index.test.js ├── docs ├── source │ ├── zh-cn │ │ ├── index.md │ │ ├── plugins │ │ │ └── index.md │ │ ├── resource.md │ │ ├── basics │ │ │ └── app-start.md │ │ └── tutorials │ │ │ └── index.md │ ├── en │ │ └── plugins │ │ │ └── index.md │ └── _data │ │ ├── menu.yml │ │ └── links.yml ├── assets │ ├── egg-logo.png │ ├── egg-framework.png │ ├── communication-seq.png │ ├── quickstart-index.png │ └── quickstart-coverage.png └── _config.yml ├── config ├── favicon.png ├── config.local.js └── config.unittest.js ├── .eslintignore ├── scripts ├── deploy_key.enc ├── commits.sh └── doc_travis.sh ├── app ├── middleware │ ├── body_parser.js │ ├── override_method.js │ ├── meta.js │ ├── site_file.js │ └── notfound.js └── extend │ └── helper.js ├── .eslintrc ├── lib ├── jsdoc │ ├── response.jsdoc │ ├── request.jsdoc │ └── context.jsdoc ├── loader │ ├── index.js │ ├── agent_worker_loader.js │ └── app_worker_loader.js └── core │ ├── base_context_class.js │ ├── logger.js │ └── context_httpclient.js ├── appveyor.yml ├── .travis.yml ├── .gitignore ├── .autod.conf.js ├── .github ├── PULL_REQUEST_TEMPLATE.md └── ISSUE_TEMPLATE.md └── LICENSE /test/lib/plugins/empty.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/app/a.js: -------------------------------------------------------------------------------- 1 | aaa -------------------------------------------------------------------------------- /docs/source/zh-cn/index.md: -------------------------------------------------------------------------------- 1 | layout: index 2 | --- 3 | -------------------------------------------------------------------------------- /test/fixtures/apps/i18n/config/locales/xx.txt: -------------------------------------------------------------------------------- 1 | foo 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/middlewares/app/crossdomain.xml: -------------------------------------------------------------------------------- 1 | xxx -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/app/view/a.html: -------------------------------------------------------------------------------- 1 | aaa -------------------------------------------------------------------------------- /test/fixtures/apps/watcher-development-app/tmp.txt: -------------------------------------------------------------------------------- 1 | aaa -------------------------------------------------------------------------------- /test/fixtures/apps/app-ts/.gitignore: -------------------------------------------------------------------------------- 1 | *.js 2 | node_modules -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/config/map.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/node_modules/d/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/node_modules/rds/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/apps/multiple-view-engine/app/view/ext/a.ejs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/apps/multiple-view-engine/app/view/ext/a.nj: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/apps/watcher-development-app/tmp/tmp.txt: -------------------------------------------------------------------------------- 1 | aaa -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/node_modules/a/app/proxy/a.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/apps/logger-output-json/config/map.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/middlewares/server.conf: -------------------------------------------------------------------------------- 1 | zone = RZ01B 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/multiple-view-engine/app/view/loader/a.ejs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/apps/multiple-view-engine/app/view/loader/a.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/apps/multiple-view-engine/app/view/loader/a.noext: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/apps/multiple-view-engine/app/view2/loader/a.nj: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/apps/watcher-development-app/tmp-agent.txt: -------------------------------------------------------------------------------- 1 | bbb -------------------------------------------------------------------------------- /test/fixtures/apps/watcher-development-app/tmp-agent/tmp.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/apps/worker-die/app.js: -------------------------------------------------------------------------------- 1 | throw new Error('dddd'); -------------------------------------------------------------------------------- /test/fixtures/apps/development/app/public/foo.js: -------------------------------------------------------------------------------- 1 | alert('bar'); 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/node_modules/a/app/service/bar1.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/apps/multiple-view-engine/app/view/loader/a.nj.ejs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/apps/static-server/app/public/foo.js: -------------------------------------------------------------------------------- 1 | alert('bar'); 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/docapp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docapp" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/empty/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "empty" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/helper/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "helper" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/i18n/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "i18n" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/locals/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "locals" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/logger/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "logger" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/mock-production-app/config/map.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/multiple-view-engine/app/view2/loader/from-view2.ejs: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/apps/router-app/app/view/locals/router.html: -------------------------------------------------------------------------------- 1 | posts: /posts -------------------------------------------------------------------------------- /test/fixtures/apps/app-die/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.keys = 'foo'; 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-die/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app-die" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/development/config/plugin.js: -------------------------------------------------------------------------------- 1 | exports.static = true; 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/favicon/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "favicon" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/locals/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.keys = 'foo'; 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/notfound/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "notfound" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/notready/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "notready" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/onerror/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "onerror" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/response/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.keys = 'f' 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/response/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "response" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/router-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "router-app" 3 | } -------------------------------------------------------------------------------- /test/fixtures/apps/schedule/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "schedule" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/secure-app/config/plugin.js: -------------------------------------------------------------------------------- 1 | exports.security = false; 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/static-server/config/plugin.js: -------------------------------------------------------------------------------- 1 | exports.static = true; 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/app/view/shtml.html: -------------------------------------------------------------------------------- 1 | {{helper.shtml(foo)}} 2 | -------------------------------------------------------------------------------- /test/fixtures/custom-egg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "custom-egg" 3 | } 4 | -------------------------------------------------------------------------------- /docs/source/en/plugins/index.md: -------------------------------------------------------------------------------- 1 | layout: plugin 2 | title: Plugin List 3 | --- 4 | -------------------------------------------------------------------------------- /docs/source/zh-cn/plugins/index.md: -------------------------------------------------------------------------------- 1 | layout: plugin 2 | title: 内置插件列表 3 | --- 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/agent-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "agent-app" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/agent-die/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "agent-die" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/agent-throw/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.keys = 'foo'; 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/agent-throw/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "agent-throw" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/aliyun-egg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aliyun-egg" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-router/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app-router" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app-server" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-throw/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app-throw" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/async-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "async-app" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/csrf-enable/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "csrf-enable" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/csrf-ignore/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "csrf-ignore" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/development/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.keys = 'foo'; 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/development/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "development" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/dumpconfig/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dumpconfig" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/encrypt-cookies/config/plugin.js: -------------------------------------------------------------------------------- 1 | exports.security = false; 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/get-logger/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "get-logger" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/koa-session/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.keys = 'foo'; 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/koa-session/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "koa-session" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/logger-level-debug/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "foo" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/messenger/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "messenger" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/middlewares/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "middlewares" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/mock-dev-app/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.keys = 'd'; 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/multipart/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "multipart" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/secure-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "secure-app" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/service-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "service-app" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/static-server/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.keys = 'foo'; 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/tracer-demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tracer-demo" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "view-render" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/worker-die/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "worker-die" 3 | } 4 | -------------------------------------------------------------------------------- /config/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/egg/master/config/favicon.png -------------------------------------------------------------------------------- /test/fixtures/apps/agent-restart/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "agent-restart" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/aliyun-egg-app/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.keys = 'foo'; 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-locals-getter/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.keys = 'foo'; 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-server/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.keys = 'my keys'; 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-ts/config/config.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | keys: 'foo', 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/csrf-disable/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "csrf-disable" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-logger/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "custom-logger" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/encrypt-cookies/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.keys = 'foo'; 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/keys-exists/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.keys = 'my keys'; 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/keys-missing/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "keys-missing" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin-dep/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "plugin-dep" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "loader-plugin" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/logger-reload/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "logger-reload" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/mock-dev-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mock-dev-app" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/mock-production-app-do-not-force/config/map.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/override_method/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.keys = 'foo'; 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/reload-worker/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "reload-worker" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/app/view/sjs.html: -------------------------------------------------------------------------------- 1 | var foo = "{{ helper.sjs(foo) }}"; 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/agent-app-sync/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "agent-app-sync" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/agent-client-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "agent-client-app" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/aliyun-egg-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aliyun-egg-app" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/aliyun-egg-biz/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aliyun-egg-biz" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/cluster_mod_app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cluster_mod_app" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/ctx-background/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ctx-background" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-env-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "custom-env-app" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/encrypt-cookies/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "encrypt-cookies" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/keys-exists/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "keys-missing-local" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/node_modules/a/config/config.js: -------------------------------------------------------------------------------- 1 | exports.pluginA = 1; 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/logrotator-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "logrotator-app" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/messenger-random/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "messenger-random" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/nobuffer-logger/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nobuffer-logger" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/override_method/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "override_method" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/singleton-demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "singleton-demo" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/subdir-services/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "subdir-services" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/watcher-development-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "watcher-app" 3 | } -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | test/fixtures 2 | examples/**/app/public 3 | logs 4 | run 5 | docs/node_modules 6 | -------------------------------------------------------------------------------- /scripts/deploy_key.enc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/egg/master/scripts/deploy_key.enc -------------------------------------------------------------------------------- /test/fixtures/apps/agent-restart/client.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | ready: cb => cb(), 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-locals-getter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app-locals-getter" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-start-timeout/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app-start-timeout" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-ts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app-ts", 3 | "version": "1.0.0" 4 | } -------------------------------------------------------------------------------- /test/fixtures/apps/base-context-class/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "base-context-class" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/close-watcher-logrotator/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.keys = 'foo'; 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/context-config-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "context-config-app" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/context_httpclient/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "context_httpclient" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/dump-ignore-error/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dump-ignore-error" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/httpclient-tracer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "httpclient-tracer" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/logger-output-json/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "logger-output-json" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/watcher-type-default/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "watcher-type-default" 3 | } -------------------------------------------------------------------------------- /app/middleware/body_parser.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('koa-bodyparser'); 4 | -------------------------------------------------------------------------------- /app/middleware/override_method.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('koa-override'); 4 | -------------------------------------------------------------------------------- /docs/assets/egg-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/egg/master/docs/assets/egg-logo.png -------------------------------------------------------------------------------- /test/fixtures/apps/body_parser_testapp/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "body_parser_testapp" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/cluster-client-error/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cluster-client-error" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/dnscache_httpclient/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dnscache_httpclient-app" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/empty/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/httpclient-overwrite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "httpclient-overwrite" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin-noexist/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "loader-plugin-noexist" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/node_modules/b/config/antx.dev.properties: -------------------------------------------------------------------------------- 1 | key.name = pluginDev 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/node_modules/b/config/antx.test.properties: -------------------------------------------------------------------------------- 1 | key.name = pluginTest 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/master-worker-started/node_modules/egg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "egg" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/master-worker-started/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "master-worker-started" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/messenger-app-agent/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "messenger-app-agent" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/messenger-broadcast/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "messenger-broadcast" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/mock-production-app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mock-production-app" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/multiple-view-engine/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "multiple-view-engine" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/notfound-custom-404/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "notfound-custom-404" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/querystring-extended/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "querystring-extended" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/agent-app/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/agent-die/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/aliyun-egg/agent.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = agent => { 4 | 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/aliyun-egg/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-router/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-throw/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/confused-configuration/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "confused-configuration" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/csrf-enable/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'foo'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/ctx-background/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'foo'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-env-app/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'foo'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin-dep-missing/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "plugin-dep-missing" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin-dep-recursive/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "plugin-dep-recursive" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/messenger/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/notready/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/schedule/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/secure-app/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.keys = 'foo'; 2 | exports.proxy = true; 3 | -------------------------------------------------------------------------------- /test/fixtures/apps/services_loader_verify/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "services_loader_verify" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/worker-die/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/custom-egg/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('../../../index'); 4 | -------------------------------------------------------------------------------- /docs/assets/egg-framework.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/egg/master/docs/assets/egg-framework.png -------------------------------------------------------------------------------- /test/fixtures/apps/agent-app-sync/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/agent-restart/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/aliyun-egg-biz/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('../aliyun-egg'); 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-server-with-hostname/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "app-server-with-hostname" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/body_parser_testapp_ignore/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "body_parser_testapp_ignore" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/body_parser_testapp_match/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "body_parser_testapp_match" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/close-watcher-logrotator/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "close-watcher-logrotator" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-context-getlogger/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "custom-context-getlogger" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/node_modules/b/config/antx.prod.properties: -------------------------------------------------------------------------------- 1 | key.name = pluginProd 2 | a = 1 3 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/node_modules/b/config/antx.unittest.properties: -------------------------------------------------------------------------------- 1 | key.name = pluginUnittest 2 | -------------------------------------------------------------------------------- /test/fixtures/apps/logger-reload/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/nobuffer-logger/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/reload-worker/app/controller/home.js: -------------------------------------------------------------------------------- 1 | module.exports = function*() { this.body = 'change'; }; -------------------------------------------------------------------------------- /test/fixtures/apps/reload-worker/app/controller/home1.js: -------------------------------------------------------------------------------- 1 | module.exports = function*() { this.body = 'change'; }; -------------------------------------------------------------------------------- /test/fixtures/apps/reload-worker/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/service-app/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/subdir-services/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /docs/assets/communication-seq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/egg/master/docs/assets/communication-seq.png -------------------------------------------------------------------------------- /docs/assets/quickstart-index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/egg/master/docs/assets/quickstart-index.png -------------------------------------------------------------------------------- /test/fixtures/apps/agent-client-app/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/base-context-class/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test keys'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/body_parser_testapp_disable/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "body_parser_testapp_disable" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/cluster-client-error/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/context_httpclient/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-context-getlogger/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'foo'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/dumpconfig/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.dynamic = 0; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin-dep/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/app/service/foo2.js: -------------------------------------------------------------------------------- 1 | module.exports = function*() { 2 | return 'foo2'; 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/messenger-app-agent/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/messenger-broadcast/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/messenger-random/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/tracer-demo/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'tracer-demo keys'; 4 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint-config-egg", 3 | "parserOptions": { 4 | "ecmaVersion": 2017 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /docs/assets/quickstart-coverage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/functions/egg/master/docs/assets/quickstart-coverage.png -------------------------------------------------------------------------------- /test/fixtures/apps/agent-die/agent.js: -------------------------------------------------------------------------------- 1 | 2 | setTimeout(() => { 3 | throw new Error('app worker throw'); 4 | }, 5000); 5 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-router/app/controller/home.js: -------------------------------------------------------------------------------- 1 | module.exports = function* () { 2 | this.body = 'hello'; 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-start-timeout/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.workerStartTimeout = 1000; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/close-watcher-logrotator/config/plugin.js: -------------------------------------------------------------------------------- 1 | exports.logrotator = false; 2 | exports.watcher = false; 3 | -------------------------------------------------------------------------------- /test/fixtures/apps/dump-ignore-error/config/config.default.js: -------------------------------------------------------------------------------- 1 | 2 | exports.dump = null; 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/helper/app/controller/home.js: -------------------------------------------------------------------------------- 1 | module.exports = function* () { 2 | this.body = 'hello home'; 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/httpclient-agent-timeout-3000/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "httpclient-agent-timeout-3000" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/httpclient-request-timeout-100/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "httpclient-request-timeout-100" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin-dep-missing/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin-dep/plugins/d/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "eggPlugin": { 3 | "name": "d" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin-dep/plugins/e/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "eggPlugin": { 3 | "name": "e" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin-dep/plugins/f/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "eggPlugin": { 3 | "name": "f" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin-noexist/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/app/service/foo3/foo3.js: -------------------------------------------------------------------------------- 1 | module.exports = function*() { 2 | return 'foo3'; 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/node_modules/a/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "eggPlugin": { 3 | "name": "a" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/node_modules/b/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "eggPlugin": { 3 | "name": "b" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/node_modules/c/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "eggPlugin": { 3 | "name": "c" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/node_modules/d/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "eggPlugin": { 3 | "name": "d1" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/master-worker-started/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/notready/a/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "a", 3 | "eggPlugin": { 4 | "name": "a" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/service-app/app/router.js: -------------------------------------------------------------------------------- 1 | module.exports = app => { 2 | app.get('user', '/user', 'user'); 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/services_loader_verify/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /lib/jsdoc/response.jsdoc: -------------------------------------------------------------------------------- 1 | /** 2 | * 继承 koa 的 Response 3 | * @class Response 4 | * @see http://koajs.com/#response 5 | */ 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/aliyun-egg/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app['aliyun-egg'] = {}; 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/encrypt-cookies/app/router.js: -------------------------------------------------------------------------------- 1 | module.exports = app => { 2 | app.get('/', app.controller.home); 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin-dep-missing/plugins/a/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "eggPlugin": { 3 | "name": "a" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin-dep-missing/plugins/b/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "eggPlugin": { 3 | "name": "b" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin-dep-missing/plugins/c/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "eggPlugin": { 3 | "name": "c" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin-dep-recursive/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'test key'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/node_modules/rds/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "eggPlugin": { 3 | "name": "rds" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/locals/app/helper.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.test = () => { 4 | return 'test-helper'; 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/logger-reload/app/router.js: -------------------------------------------------------------------------------- 1 | module.exports = app => { 2 | app.get('/', app.controller.home); 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/mock-production-app-do-not-force/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mock-production-app-do-not-force" 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/notready/a/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.readyCallback('a'); 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/subdir-services/app/router.js: -------------------------------------------------------------------------------- 1 | module.exports = app => { 2 | app.get('/', app.controller.home); 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/subdir-services/app/service/old_style.js: -------------------------------------------------------------------------------- 1 | exports.url = function* (ctx) { 2 | return ctx.url; 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/app/view/xss.html: -------------------------------------------------------------------------------- 1 | {{ url }} 2 | {{ url | safe }} 3 | {{ helper.surl(url) }} 4 | {{ html }} 5 | -------------------------------------------------------------------------------- /test/fixtures/apps/context-config-app/app/router.js: -------------------------------------------------------------------------------- 1 | module.exports = app => { 2 | app.get('home', '/', 'home.index'); 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin-dep-recursive/plugins/a/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "eggPlugin": { 3 | "name": "a" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin-dep-recursive/plugins/b/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "eggPlugin": { 3 | "name": "b" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin-dep-recursive/plugins/c/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "eggPlugin": { 3 | "name": "c" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin-noexist/config/plugin.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | noexist: true 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/logger/config/config.unittest.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.logger = { 4 | consoleLevel: 'NONE', 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/middlewares/app/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: Baiduspider 2 | Disallow: / 3 | 4 | User-agent: baiduspider 5 | Disallow: / -------------------------------------------------------------------------------- /test/fixtures/apps/onerror/config/config.unittest.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.logger = { 4 | consoleLevel: 'NONE', 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/querystring-extended/app/router.js: -------------------------------------------------------------------------------- 1 | module.exports = app => { 2 | app.get('/', app.controller.home); 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/static-server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "static-server", 3 | "spm": { 4 | "less": true 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/tracer-demo/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | require('./tracer')(app); 5 | }; 6 | -------------------------------------------------------------------------------- /config/config.local.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.logger = { 4 | coreLogger: { 5 | consoleLevel: 'WARN', 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/agent-throw/config/config.unittest.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.logger = { 4 | consoleLevel: 'NONE', 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-throw/config/config.unittest.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.logger = { 4 | consoleLevel: 'NONE', 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/context-config-app/config/config.js: -------------------------------------------------------------------------------- 1 | exports.security = { 2 | csrf: false 3 | } 4 | 5 | exports.keys = 'foo'; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/csrf-enable/config/config.unittest.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.logger = { 4 | consoleLevel: 'NONE', 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/csrf-ignore/config/config.unittest.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.logger = { 4 | consoleLevel: 'NONE', 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/plugins/f/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "f", 3 | "eggPlugin": { 4 | "name": "f" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/middlewares/app/controller/error.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function*() { 4 | foo.bar; 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/secure-app/config/config.unittest.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.logger = { 4 | consoleLevel: 'NONE', 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/tracer-demo/agent.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = agent => { 4 | require('./tracer')(agent); 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/tracer-demo/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/', 'home.index'); 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/app/controller/csrf.js: -------------------------------------------------------------------------------- 1 | module.exports = function*() { 2 | yield this.render('form_csrf.html'); 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/app/controller/empty.js: -------------------------------------------------------------------------------- 1 | module.exports = function* () { 2 | yield this.render('index.html'); 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/app/controller/nonce.js: -------------------------------------------------------------------------------- 1 | module.exports = function*() { 2 | yield this.render('nonce.html'); 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-start-timeout/config/config.unittest.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.logger = { 4 | consoleLevel: 'NONE', 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/async-app/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'key'; 4 | exports.middleware = [ 'async' ]; 5 | -------------------------------------------------------------------------------- /test/fixtures/apps/context-config-app/config/config.local.js: -------------------------------------------------------------------------------- 1 | 'use stirct'; 2 | 3 | exports.logger = { 4 | stdoutLevel: 'NONE', 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/ctx-background/config/config.unittest.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.logger = { 4 | consoleLevel: 'NONE', 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/favicon/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function*() { 4 | this.body = 'home'; 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/favicon/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/', app.controller.home); 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin-dep/plugins/a/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "a", 3 | "eggPlugin": { 4 | "name": "a" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin-dep/plugins/b/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "b", 3 | "eggPlugin": { 4 | "name": "b" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin-dep/plugins/c/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "c1", 3 | "eggPlugin": { 4 | "name": "c1" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/plugins/g/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "eggPlugin": { 3 | "name": "g", 4 | "dep": [ "f" ] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/master-worker-started/node_modules/egg/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = require('../../../../../..'); 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/aliyun-egg-app/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/', app.controller.home); 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/context-config-app/app/extend/context.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | foo: 1, 3 | bar: function() { 4 | return 2; 5 | } 6 | }; -------------------------------------------------------------------------------- /test/fixtures/apps/custom-context-getlogger/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/', 'home'); 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/dnscache_httpclient/config/config.unittest.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.logger = { 4 | consoleLevel: 'NONE', 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/node_modules/d/config/config.js: -------------------------------------------------------------------------------- 1 | // exports.proxy = { 2 | // 3 | // }; 4 | // 5 | // exports.middleware = ['d']; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/logger-output-json/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.logger = { 2 | outputJSON: true, 3 | }; 4 | 5 | exports.keys = 'f'; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/middlewares/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function*() { 4 | this.body = 'home'; 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/mock-production-app/config/config.unittest.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.logger = { 4 | consoleLevel: 'NONE', 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/multiple-view-engine/config/config.unittest.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.logger = { 4 | consoleLevel: 'NONE', 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/reload-worker/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/', app.controller.home); 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/demo/app/controller/home.js: -------------------------------------------------------------------------------- 1 | module.exports = function* () { 2 | this.body = { 3 | workerTitle: process.title 4 | }; 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/dnscache_httpclient/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/', app.controller.home); 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/i18n/config/locales/zh-CN.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 'Email': '邮箱', 3 | 'Hello %s, how are you today?': '%s,今天过得如何?', 4 | }; 5 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.date = Date.now(); 5 | app.app = 'app'; 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/node_modules/b/config/antx.default.properties: -------------------------------------------------------------------------------- 1 | key.name = pluginDefault 2 | ; 覆盖默认的 3 | app.protocol = http 4 | a = 1 5 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/node_modules/c/config/config.js: -------------------------------------------------------------------------------- 1 | exports.name = 'override default'; 2 | 3 | exports.plugin = 'overridden by app'; 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/plugins/e/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "eggPlugin": { 3 | "name": "wrong-name", 4 | "dep": [ "f" ] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/notfound-custom-404/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.notfound = { 2 | pageUrl: '/404', 3 | }; 4 | 5 | exports.keys = 'foo'; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/app/controller/home.js: -------------------------------------------------------------------------------- 1 | module.exports = function* () { 2 | yield this.render('index.html', {name: 'mk・2'}); 3 | }; 4 | -------------------------------------------------------------------------------- /config/config.unittest.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | logger: { 5 | consoleLevel: 'WARN', 6 | buffer: false, 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/apps/koa-session/app/controller/clear.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function* () { 3 | this.session = null; 4 | this.body = 'clear'; 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/logger/config/config.local.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | logger: { 5 | consoleLevel: 'INFO', 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/mock-production-app-do-not-force/config/config.unittest.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.logger = { 4 | consoleLevel: 'NONE', 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/notfound/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.notfound = { 2 | pageUrl: 'https://eggjs.org/404', 3 | }; 4 | 5 | exports.keys = 'foo'; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/app/controller/inject.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function *(){ 4 | yield this.render('inject.html'); 5 | }; -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/config/plugin.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.nunjucks = { 4 | enable: true, 5 | package: 'egg-view-nunjucks', 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-router/app/router.js: -------------------------------------------------------------------------------- 1 | module.exports = app => { 2 | app.get('home', '/', 'home'); 3 | app.get('/home', app.controller.home); 4 | }; 5 | -------------------------------------------------------------------------------- /test/fixtures/apps/csrf-disable/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.post('/api/user', app.controller.api.user); 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/router-app/app/controller/locals.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.router = function* () { 4 | yield this.render('locals/router.html'); 5 | }; -------------------------------------------------------------------------------- /test/fixtures/apps/app-server/app/router.js: -------------------------------------------------------------------------------- 1 | module.exports = app => { 2 | app.get('/', function* () { 3 | this.body = this.app.serverEmit; 4 | }); 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/async-app/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/api', app.middlewares.router(), 'api.index'); 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/cluster_mod_app/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.keys = 'foo'; 2 | 3 | exports.security = { 4 | csrf: { 5 | enable: false, 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/favicon/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.siteFile = { 2 | '/favicon.ico': 'https://eggjs.org/favicon.ico', 3 | } 4 | 5 | exports.keys = 'foo'; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.plugin = 'override plugin'; 2 | 3 | exports.middleware = []; 4 | 5 | exports.keys = 'test key'; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/app/view/index.html: -------------------------------------------------------------------------------- 1 | Hi, {{name}} 2 | test-app-helper: {{helper.test('bar')}} 3 | raw: {{helper.test_safe('dar')}} 4 | {{copyright}} 5 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-server/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.on('server', server => { 5 | app.serverEmit = true; 6 | }); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/httpclient-overwrite/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.httpclient = { 4 | request: { 5 | timeout: 100, 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/i18n/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.view = { 4 | defaultViewEngine: 'nunjucks', 5 | }; 6 | 7 | exports.keys = 'test key'; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/logger-level-debug/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.logger = { 4 | level: 'DEBUG', 5 | }; 6 | 7 | exports.keys = 'test key'; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/secure-app/app/router.js: -------------------------------------------------------------------------------- 1 | module.exports = app => { 2 | app.get('/user.json', app.jsonp(), 'index.getUser'); 3 | app.get('/', 'index.home'); 4 | }; 5 | -------------------------------------------------------------------------------- /test/fixtures/apps/demo/app/controller/hello.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function*() { 4 | this.cookies.set('hi', 'foo'); 5 | this.body = 'hello'; 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/httpclient-tracer/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | const done = app.readyCallback('ready'); 5 | setTimeout(done, 5000); 6 | }; -------------------------------------------------------------------------------- /test/fixtures/apps/koa-session/app/router.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = app => { 3 | app.get('/', app.controller.home); 4 | app.get('/clear', app.controller.clear); 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/node_modules/a/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(app) { 4 | app.dateA = Date.now(); 5 | app.a = 'plugin a'; 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/node_modules/b/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(app) { 4 | app.dateB = Date.now(); 5 | app.b = 'plugin b'; 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/node_modules/c/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(app) { 4 | app.dateC = Date.now(); 5 | app.c = 'plugin c'; 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/logrotator-app/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/', function*() { 5 | this.body = 123; 6 | }); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/multipart/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.multipart = { 4 | fileExtensions: ['.foo'], 5 | }; 6 | 7 | exports.keys = 'foo,key'; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/notfound-custom-404/app/router.js: -------------------------------------------------------------------------------- 1 | module.exports = app => { 2 | app.get('/404', function*() { 3 | this.body = 'Hi, this is 404'; 4 | }); 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/service-app/app/controller/user.js: -------------------------------------------------------------------------------- 1 | module.exports = function* () { 2 | this.body = { 3 | user: yield this.service.user.get('123'), 4 | }; 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/watcher-type-default/config/config.unittest.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.watcher = { 4 | type: 'default', 5 | }; 6 | 7 | exports.keys = 'test key'; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/agent-app-sync/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/', function*() { 5 | this.body = this.app.arg; 6 | }) 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/body_parser_testapp/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.bodyParser = { 2 | queryString: { 3 | arrayLimit: 5 4 | } 5 | }; 6 | 7 | exports.keys = 'foo'; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/cluster-client-error/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | const err = Error(); 5 | err.name = 'MockError'; 6 | throw err; 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/httpclient-request-timeout-100/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.httpclient = { 4 | request: { 5 | timeout: 100, 6 | }, 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/httpclient-tracer/config/plugin.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | tracer: { 5 | enable: true, 6 | package: 'egg-tracer', 7 | }, 8 | } 9 | -------------------------------------------------------------------------------- /test/fixtures/apps/onerror/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.onerror = { 4 | errorPageUrl: 'http://eggjs.org/500', 5 | }; 6 | 7 | exports.keys = 'foo'; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/dnscache_httpclient/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.httpclient = { 4 | enableDNSCache: true, 5 | }; 6 | 7 | exports.keys = 'test key'; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/node_modules/a1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "eggPlugin": { 3 | "name": "a1", 4 | "dep": [ "d1" ], 5 | "env": [ "local", "prod" ] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/logger/agent.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = agent => { 4 | agent.logger.info('agent info'); 5 | agent.logger.error(new Error('agent error')); 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-server-with-hostname/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/', function* () { 5 | this.body = 'done'; 6 | }); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/csrf-disable/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'fo'; 4 | 5 | exports.security = { 6 | csrf: false, 7 | debug: 'csrf-disable', 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/apps/i18n/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/', app.controller.home); 5 | app.get('/message', app.controller.message); 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/middlewares/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/', app.controller.home); 5 | app.get('/error', app.controller.error); 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/notready/config/plugin.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | exports.a = { 6 | enable: true, 7 | path: path.join(__dirname, '../a'), 8 | } 9 | -------------------------------------------------------------------------------- /test/fixtures/apps/querystring-extended/app/controller/home.js: -------------------------------------------------------------------------------- 1 | module.exports = function* () { 2 | this.body = { 3 | query: this.query, 4 | queries: this.queries, 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/app/controller/sjs.js: -------------------------------------------------------------------------------- 1 | module.exports = function* () { 2 | var view = 'sjs.html'; 3 | yield this.render(view, { 4 | foo: '"hello"' 5 | }); 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-start-timeout/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(app) { 4 | const done = app.readyCallback('app-timeout'); 5 | setTimeout(done, 30000); 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/router-app/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'my'; 4 | 5 | exports.security = { 6 | csrf: { 7 | enable: false, 8 | }, 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/csrf-enable/app/controller/api.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.user = function* () { 4 | this.body = { 5 | url: this.url, 6 | name: this.query.name, 7 | }; 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/apps/csrf-ignore/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.keys = 'foo'; 4 | 5 | exports.security = { 6 | csrf: { 7 | ignore: /^\/api\//, 8 | }, 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/docapp/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | module.exports = { 6 | keys: 'test key', 7 | middleware: [ 'koastatic' ], 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/app/service/foo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function (app) { 4 | class Foo extends app.Service { 5 | 6 | } 7 | 8 | return Foo; 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/app/view/inject.html: -------------------------------------------------------------------------------- 1 | ctx: {{ ctx != undefined }} 2 | request: {{ request != undefined }} 3 | helper: {{ helper != undefined }} 4 | helperFn: {{ helper.test != undefined }} -------------------------------------------------------------------------------- /test/fixtures/apps/csrf-disable/app/controller/api.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.user = function* () { 4 | this.body = { 5 | url: this.url, 6 | name: this.request.body.name, 7 | }; 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/apps/csrf-ignore/app/controller/api.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.user = function* () { 4 | this.body = { 5 | url: this.url, 6 | name: this.request.body.name, 7 | }; 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/apps/i18n/app/view/home.html: -------------------------------------------------------------------------------- 1 |
  • {{ __('Email') }}: {{ user.email }}
  • 2 |
  • {{ gettext('Hello %s, how are you today?', user.name) }}
  • 3 |
  • {{ __('%s %s', 'foo', 'bar') }}
  • 4 | -------------------------------------------------------------------------------- /test/fixtures/apps/i18n/config/plugin.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | i18n: true, 5 | nunjucks: { 6 | enable: true, 7 | package: 'egg-view-nunjucks', 8 | } 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/app/service/Foo4.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function (app) { 4 | class Foo4 extends app.Service { 5 | 6 | } 7 | 8 | return Foo4; 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/multiple-view-engine/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.view.use('ejs', require('./ejs')); 5 | app.view.use('nunjucks', require('./nunjucks')); 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/app/controller/context.js: -------------------------------------------------------------------------------- 1 | module.exports = function* () { 2 | yield this.render('js.html', { 3 | context: { 4 | a: this.request.body.a 5 | } 6 | }); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/app/service/fooDir/Foo5.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function (app) { 4 | class Foo5 extends app.Service { 5 | 6 | } 7 | 8 | return Foo5; 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/agent-app/plugins/mock-client/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = () => { 4 | return { 5 | mock: { 6 | name: 'mock', 7 | }, 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/csrf-enable/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/api/user.json', app.controller.api.user); 5 | app.post('/api/user', app.controller.api.user); 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/csrf-ignore/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.post('/api/user', app.controller.api.user); 5 | app.post('/api/user.json', app.controller.api.user); 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/messenger-random/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(app) { 4 | let count = 1; 5 | app.messenger.on('agent2app', () => console.log('%s=%s', process.pid, count++)); 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/singleton-demo/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const createDataService = require('./create'); 4 | 5 | module.exports = app => { 6 | app.addSingleton('dataService', createDataService); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/body_parser_testapp_disable/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.bodyParser = { 2 | enable: false, 3 | }; 4 | 5 | exports.security = { 6 | csrf: false, 7 | }; 8 | 9 | exports.keys = 'foo'; 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/node_modules/b/app/service/bar2.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function (app) { 4 | class Bar2 extends app.Service { 5 | 6 | } 7 | 8 | return Bar2; 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/multipart/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function* () { 4 | this.set('x-csrf', this.csrf); 5 | this.body = 'hi'; 6 | // yield this.render('home.html'); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/querystring-extended/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.querystring = { 2 | mode: 'extended' 3 | }; 4 | 5 | exports.security = { 6 | ctoken: false 7 | }; 8 | 9 | exports.keys = 'foo'; 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/singleton-demo/agent.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const createDataService = require('./create'); 4 | 5 | module.exports = agent => { 6 | agent.addSingleton('dataService', createDataService); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/app/controller/locals.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function*() { 4 | this.state.foo = 'foo'; 5 | this.locals.bar = 'bar'; 6 | yield this.render('locals.html'); 7 | }; 8 | -------------------------------------------------------------------------------- /docs/source/_data/menu.yml: -------------------------------------------------------------------------------- 1 | guide: intro/ 2 | api: /api/ 3 | tutorials: tutorials/index.html 4 | plugins: https://github.com/search?q=topic%3Aegg-plugin&type=Repositories 5 | release: https://github.com/eggjs/egg/releases 6 | -------------------------------------------------------------------------------- /lib/loader/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.EggLoader = require('egg-core').EggLoader; 4 | exports.AppWorkerLoader = require('./app_worker_loader'); 5 | exports.AgentWorkerLoader = require('./agent_worker_loader'); 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/i18n/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function* () { 4 | yield this.render('home.html', { 5 | user: { 6 | name: 'fengmk2', 7 | }, 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/locals/app.js: -------------------------------------------------------------------------------- 1 | module.exports = app => { 2 | app.locals = { 3 | 'app.global' : { 4 | 'id': '12306', 5 | 'version': '1.0' 6 | }, 7 | a: 1, 8 | b: 1, 9 | }; 10 | }; 11 | -------------------------------------------------------------------------------- /test/fixtures/apps/watcher-development-app/config/config.unittest.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.env = 'local'; 4 | 5 | exports.watcher = { 6 | type: 'development', 7 | }; 8 | 9 | exports.keys = 'test key'; 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/confused-configuration/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.middlewares = []; 4 | exports.bodyparser = {}; 5 | exports.sitefile = {}; 6 | exports.notFound = {}; 7 | exports.httpClient = {}; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-env-app/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/', function*() { 5 | this.body = { 6 | env: this.app.config.env, 7 | }; 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/logrotator-app/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.logrotator = { 4 | maxFileSize: 1024, 5 | maxFiles: 2, 6 | rotateDuration: 30000 7 | }; 8 | 9 | exports.keys = 'test key'; 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/master-worker-started/dispatch.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const egg = require('../../../..'); 4 | const utils = require('../../../utils'); 5 | const baseDir = __dirname; 6 | 7 | egg.startCluster({ baseDir }); 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/multipart/app/router.js: -------------------------------------------------------------------------------- 1 | module.exports = function (app) { 2 | app.get('/', app.controller.home); 3 | app.post('/upload', app.controller.upload); 4 | app.post('/upload.json', app.controller.upload); 5 | }; 6 | -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/app/controller/string.js: -------------------------------------------------------------------------------- 1 | module.exports = function* () { 2 | this.body = yield this.renderString('{{ context.a }}', { 3 | context: { 4 | a: 'templateString' 5 | } 6 | }); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/base-context-class/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/', 'home.show'); 5 | app.get('/pathName', 'home.getPathName'); 6 | app.get('/config', 'home.getConfig'); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/docapp/app/middleware/koastatic.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | module.exports = () => { 6 | return require('koa-static')(path.join(process.cwd(), 'run/doctools/public')); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/app/controller/xss.js: -------------------------------------------------------------------------------- 1 | module.exports = function* () { 2 | yield this.render('xss.html', { 3 | url: 'http://alipay.com/index.html?a=
    ', 4 | html: '
    \'a\'
    ' 5 | }); 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/body_parser_testapp_match/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.bodyParser = { 2 | match: '/test/body_parser/foo.json', 3 | }; 4 | 5 | exports.security = { 6 | csrf: false, 7 | }; 8 | 9 | exports.keys = 'foo'; 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/demo/app/controller/foo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | return class Foo extends app.Controller { 5 | * bar() { 6 | this.ctx.body = 'this is bar!'; 7 | } 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /test/async/index.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const nodeVersion = Number(process.version.match(/^v(\d+\.\d+)\./)[1]); 4 | // only node >= 7.6 support async function without flags 5 | if (nodeVersion >= 7.6) { 6 | require('./_async'); 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/aliyun-egg/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const egg = require('../../../..'); 4 | 5 | module.exports = egg; 6 | module.exports.Application = require('./lib/aliyun-egg'); 7 | module.exports.Agent = require('./lib/agent'); 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/async-app/app/middleware/async.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = () => { 4 | return async (ctx, next) => { 5 | ctx.body = []; 6 | await next(); 7 | ctx.body.push('middleware'); 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/async-app/app/middleware/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = () => { 4 | return async (ctx, next) => { 5 | ctx.body = []; 6 | await next(); 7 | ctx.body.push('router'); 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/body_parser_testapp_ignore/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.bodyParser = { 2 | ignore: '/test/body_parser/foo.json', 3 | }; 4 | 5 | exports.security = { 6 | csrf: false, 7 | }; 8 | 9 | exports.keys = 'foo'; 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/demo/app/controller/ip.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function* () { 4 | if (this.query.set_ip) { 5 | this.ip = this.query.set_ip; 6 | } 7 | this.body = { 8 | ip: this.ip, 9 | }; 10 | }; 11 | -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/app/controller/shtml.js: -------------------------------------------------------------------------------- 1 | module.exports = function* () { 2 | var view = this.query.vm ? 'shtml.vm' : 'shtml.html'; 3 | yield this.render(view, { 4 | foo: '

    foo

    ', 5 | }); 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/ctx-background/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/', app.controller.home); 5 | app.get('/app_background', app.controller.app); 6 | app.get('/error', app.controller.error); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/schedule/app/schedule/sub/cron.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.schedule = { 4 | type: 'worker', 5 | cron: '*/5 * * * * *', 6 | }; 7 | 8 | exports.task = function* (ctx) { 9 | ctx.logger.warn('cron'); 10 | }; 11 | -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.security = { 2 | csp: { 3 | enable: true, 4 | }, 5 | }; 6 | 7 | exports.view = { 8 | defaultViewEngine: 'nunjucks', 9 | }; 10 | 11 | exports.keys = 'test key'; 12 | -------------------------------------------------------------------------------- /test/fixtures/apps/agent-app-sync/agent.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = agent => { 4 | agent.startAgent({ 5 | name: 'test', 6 | client: { ready: cb => cb() }, 7 | subscribe: (info, cb) => cb('test'), 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/agent-app/config/plugin.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | module.exports = { 6 | mock: { 7 | enable: true, 8 | path: path.join(__dirname, '../plugins/mock-client'), 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /test/fixtures/apps/aliyun-egg/config/plugin.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | module.exports = { 6 | custom: { 7 | enable: true, 8 | path: path.join(__dirname, '../lib/plugins/custom'), 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /test/fixtures/apps/context-config-app/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.index = function* () { 4 | this.body = { 5 | path: this.router.pathFor('home'), 6 | foo: this.foo, 7 | bar: this.bar() 8 | }; 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/app/extend/helper.js: -------------------------------------------------------------------------------- 1 | exports.test = function(name) { 2 | return 'test-' + name + '@' + this.app.config.baseDir; 3 | }; 4 | 5 | exports.test_safe = function(name) { 6 | return this.safe('
    ' + name + '
    '); 7 | }; -------------------------------------------------------------------------------- /test/fixtures/apps/aliyun-egg/lib/plugins/custom/agent.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = agent => { 4 | agent.messenger.on('custom-aliyun-egg-worker', data => { 5 | agent.messenger.broadcast('custom-aliyun-egg-agent', data); 6 | }) 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-context-getlogger/app/extend/context.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = { 4 | getLogger(name) { 5 | console.log('get custom %s logger', name); 6 | return new this.app.ContextLogger(this, console); 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/app/view/form_csrf.html: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 |
    5 | 6 |
    7 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-server-with-hostname/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const address = require('address'); 4 | 5 | exports.keys = 'my keys'; 6 | exports.cluster = { 7 | listen: { 8 | hostname: address.ip(), 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-ts/app/router.ts: -------------------------------------------------------------------------------- 1 | import { Application } from 'egg'; 2 | 3 | export default (app: Application) => { 4 | const controller = app.controller; 5 | app.get('/foo', controller.foo.getData); 6 | app.post('/', controller.foo.getData); 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/dumpconfig/app.js: -------------------------------------------------------------------------------- 1 | const sleep = require('mz-modules/sleep'); 2 | 3 | module.exports = app => { 4 | app.config.dynamic = 1; 5 | app.beforeStart(function*() { 6 | yield sleep(500); 7 | app.config.dynamic = 2; 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-context-getlogger/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function* () { 4 | const logger = this.getLogger('foo'); 5 | logger.info('hello'); 6 | this.body = 'work, logger: ' + (logger ? 'exists' : 'not exists'); 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/apps/development/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/foo.js', function* () { 5 | this.body = 'foo.js'; 6 | }); 7 | 8 | app.get('/foo', function* () { 9 | this.body = 'foo'; 10 | }); 11 | }; 12 | -------------------------------------------------------------------------------- /test/fixtures/apps/logger/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.logger.info('app info'); 5 | app.logger.error(new Error('app error')); 6 | 7 | app.ready(() => { 8 | app.logger.info('app info after ready'); 9 | }); 10 | }; 11 | -------------------------------------------------------------------------------- /test/fixtures/apps/messenger-random/agent.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(agent) { 4 | agent.messenger.on('egg-ready', () => { 5 | for (const i of Array(20)) { 6 | agent.messenger.sendRandom('agent2app'); 7 | } 8 | }); 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/onerror/app/router.js: -------------------------------------------------------------------------------- 1 | module.exports = app => { 2 | app.get('/', app.controller.home.index); 3 | app.get('/csrf', app.controller.home.csrf); 4 | app.post('/test', app.controller.home.test); 5 | app.get('/user.json', app.controller.user); 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/async-app/app/schedule/async.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.schedule = { 4 | type: 'worker', 5 | interval: 1000000, 6 | }; 7 | 8 | exports.task = async (ctx) => { 9 | await Promise.resolve(); 10 | ctx.app.scheduleExecuted = true; 11 | }; 12 | -------------------------------------------------------------------------------- /test/fixtures/apps/logger-reload/app/controller/home.js: -------------------------------------------------------------------------------- 1 | module.exports = function*() { 2 | this.logger.warn('%s %s', this.method, this.path); 3 | this.logger.error(new Error('error')); 4 | this.body = { 5 | method: this.method, 6 | path: this.path, 7 | }; 8 | }; 9 | -------------------------------------------------------------------------------- /test/fixtures/apps/multipart/app/view/home.html: -------------------------------------------------------------------------------- 1 |
    2 | title: 3 | file: 4 | 5 |
    6 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-ts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "baseUrl": ".", 5 | "paths": { 6 | "egg": ["../../../../index"] 7 | }, 8 | "module": "commonjs", 9 | "lib": ["es7"], 10 | "strict": true 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/fixtures/apps/mock-production-app/config/config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.watcher = { 4 | // watcher 在 prod 中默认没有设置 type,防止框架开发者忘记设置,这里设置一下,避免报错 5 | type: 'development', 6 | }; 7 | 8 | exports.logger = { 9 | level: 'DEBUG', 10 | }; 11 | 12 | exports.keys = 'foo'; 13 | -------------------------------------------------------------------------------- /test/fixtures/apps/tracer-demo/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.index = function* () { 4 | const r = yield this.curl(this.query.url, { 5 | dataType: 'json', 6 | }); 7 | this.body = { 8 | url: this.query.url, 9 | data: r.data, 10 | }; 11 | }; 12 | -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/app/view/locals.html: -------------------------------------------------------------------------------- 1 | name: {{ ctx.app.config.name }} 2 | ctx.request: {{ true if ctx.request else false }} 3 | request.querystring: {{ request.querystring }} 4 | helper.lower: {{ helper.lower('Hello World') }} 5 | ctx.state.foo: {{foo}} 6 | ctx.locals.bar: {{bar}} 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/aliyun-egg-app/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function*() { 4 | this.body = { 5 | 'aliyun-egg-core': !!this.app['aliyun-egg'], 6 | 'aliyun-egg-plugin': !!this.app.custom, 7 | 'aliyun-egg-agent': !!this.app.agent, 8 | } 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/aliyun-egg/lib/plugins/custom/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.custom = {}; 5 | app.messenger.broadcast('custom-aliyun-egg-worker', 123); 6 | app.messenger.on('custom-aliyun-egg-agent', data => { 7 | app.agent = data; 8 | }) 9 | }; 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-locals-getter/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/test', function* () { 5 | this.app.locals.foo = 'bar'; 6 | this.locals.abc = '123'; 7 | this.body = { 8 | locals: this.locals, 9 | }; 10 | }); 11 | }; 12 | -------------------------------------------------------------------------------- /test/fixtures/apps/singleton-demo/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.dataService = { 4 | clients: { 5 | first: { foo1: 'bar1' }, 6 | second: { foo2: 'bar2' }, 7 | }, 8 | 9 | default: { 10 | foo: 'bar', 11 | } 12 | }; 13 | 14 | exports.keys = 'test key'; 15 | -------------------------------------------------------------------------------- /test/fixtures/apps/agent-client-app/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function initApp(app) { 4 | app.subClient = app.createAppWorkerClient('sub-client', { 5 | subscribe(info, listener) { 6 | this._subscribe(info, listener); 7 | return this; 8 | }, 9 | }); 10 | }; 11 | -------------------------------------------------------------------------------- /test/fixtures/apps/agent-die/start.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const utils = require('../../../utils'); 4 | 5 | require('../../../../index').startCluster({ 6 | baseDir: __dirname, 7 | workers: 1 8 | }) 9 | 10 | setTimeout(() => { 11 | process.exit(); 12 | // coverage will be slow 13 | }, 5000); 14 | -------------------------------------------------------------------------------- /test/fixtures/apps/agent-throw/agent.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = agent => { 4 | agent.messenger.on('agent-throw', () => { 5 | throw new Error('agent error'); 6 | }); 7 | 8 | agent.messenger.on('agent-throw-string', () => { 9 | throw 'agent error string'; 10 | }); 11 | }; 12 | -------------------------------------------------------------------------------- /test/fixtures/apps/onerror/app/controller/user.js: -------------------------------------------------------------------------------- 1 | module.exports = function* () { 2 | var err = new Error('test error'); 3 | if (this.query.status) { 4 | err.status = Number(this.query.status) 5 | } 6 | if(this.query.errors) { 7 | err.errors = this.query.errors 8 | } 9 | throw err; 10 | } -------------------------------------------------------------------------------- /test/fixtures/apps/koa-session/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = function* () { 3 | if (!this.session.uid) { 4 | this.session.uid = this.query.uid; 5 | } 6 | this.body = { 7 | sessionUid: this.session.uid, 8 | uid: this.query.uid, 9 | userId: this.userId, 10 | }; 11 | }; 12 | -------------------------------------------------------------------------------- /test/fixtures/apps/subdir-services/app/service/ok.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | return class OK extends app.Service { 5 | constructor(ctx) { 6 | super(ctx); 7 | } 8 | 9 | * get() { 10 | return { 11 | ok: true, 12 | }; 13 | } 14 | }; 15 | }; 16 | -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/app/view/nonce.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 9 | -------------------------------------------------------------------------------- /app/middleware/meta.js: -------------------------------------------------------------------------------- 1 | /** 2 | * meta middleware, should be the first middleware 3 | */ 4 | 5 | 'use strict'; 6 | 7 | module.exports = () => { 8 | return function* meta(next) { 9 | yield next; 10 | // total response time header 11 | this.set('x-readtime', Date.now() - this.starttime); 12 | }; 13 | }; 14 | -------------------------------------------------------------------------------- /test/fixtures/apps/router-app/app/router.js: -------------------------------------------------------------------------------- 1 | module.exports = function (app) { 2 | app.get('/locals/router', app.controller.locals.router); 3 | app.get('member_index', '/members/index', 'members.index'); 4 | app.resources('posts', '/posts', 'posts'); 5 | app.resources('members', '/members', app.controller.members); 6 | }; 7 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/', function*() { 5 | const foo2 = yield this.service.foo2(); 6 | const foo3 = yield this.service.foo3.foo3(); 7 | this.body = { 8 | foo2: foo2, 9 | foo3: foo3, 10 | }; 11 | }); 12 | }; 13 | -------------------------------------------------------------------------------- /test/fixtures/apps/mock-production-app-do-not-force/config/config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.watcher = { 4 | // watcher 在 prod 中默认没有设置 type,防止框架开发者忘记设置,这里设置一下,避免报错 5 | type: 'development', 6 | }; 7 | 8 | exports.logger = { 9 | level: 'DEBUG', 10 | allowDebugAtProd: false, 11 | }; 12 | 13 | exports.keys = 'foo'; 14 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-die/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/exit', function*() { 5 | process.exit(1); 6 | }); 7 | 8 | app.get('/uncaughtException', function*() { 9 | setTimeout(() => { 10 | throw new Error('get uncaughtException'); 11 | }, 100); 12 | }); 13 | }; 14 | -------------------------------------------------------------------------------- /test/fixtures/apps/helper/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.helpers = { 4 | shtml: { 5 | domainWhiteList: ['.shaoshuai.me'], 6 | whiteList: { 7 | a: [/*'target'*/, 'href', 'title'], 8 | img: ['src', 'alt', 'title', 'width', 'height'], 9 | } 10 | }, 11 | }; 12 | 13 | exports.keys = 'test key'; 14 | -------------------------------------------------------------------------------- /test/fixtures/apps/httpclient-agent-timeout-3000/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.httpclient = { 4 | // agent timeout 5 | timeout: '3s', 6 | freeSocketKeepAliveTimeout: '2s', 7 | maxSockets: 100, 8 | maxFreeSockets: 100, 9 | keepAlive: false, 10 | 11 | request: { 12 | timeout: '10s', 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /test/fixtures/apps/services_loader_verify/app/service/foo.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = () => { 4 | return { 5 | *bar(ctx) { 6 | console.log(ctx); 7 | }, 8 | 9 | * bar1(ctx) { 10 | console.log(ctx); 11 | }, 12 | 13 | aa: function*(ctx) { 14 | console.log(ctx); 15 | } 16 | }; 17 | }; 18 | -------------------------------------------------------------------------------- /test/fixtures/apps/subdir-services/app/service/user.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function (app) { 4 | class User extends app.Service { 5 | constructor(ctx) { 6 | super(ctx); 7 | } 8 | 9 | * get(uid) { 10 | return { 11 | uid: uid 12 | }; 13 | } 14 | } 15 | 16 | return User; 17 | }; 18 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-ts/app/service/foo.ts: -------------------------------------------------------------------------------- 1 | import { Service } from 'egg'; 2 | 3 | // add user controller and service 4 | declare module 'egg' { 5 | interface IService { 6 | foo: FooService; 7 | } 8 | } 9 | 10 | export default class FooService extends Service { 11 | async bar() { 12 | return { env: this.config.env }; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/fixtures/apps/async-app/app/controller/api.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | return class ApiController extends app.Controller { 5 | async index() { 6 | const result = await this.service.api.getName(); 7 | this.ctx.body.push(result); 8 | this.ctx.body.push('controller'); 9 | } 10 | }; 11 | }; 12 | -------------------------------------------------------------------------------- /test/fixtures/apps/get-logger/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(app) { 4 | app.get('/logger', function* () { 5 | this.getLogger('aLogger').info('aaa'); 6 | this.body = 'done'; 7 | }); 8 | 9 | app.get('/noExistLogger', function* () { 10 | this.body = this.app.getLogger('noexist') + ''; 11 | }); 12 | }; 13 | -------------------------------------------------------------------------------- /test/fixtures/apps/get-logger/config/config.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | module.exports = appInfo => { 6 | return { 7 | customLogger: { 8 | aLogger: { 9 | file: path.join(appInfo.baseDir, 'logs', appInfo.name, 'a.log'), 10 | }, 11 | }, 12 | 13 | keys: 'secret key', 14 | }; 15 | }; 16 | -------------------------------------------------------------------------------- /test/fixtures/apps/service-app/app/service/user.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function (app) { 4 | class User extends app.Service { 5 | constructor(ctx) { 6 | super(ctx); 7 | } 8 | 9 | * get(uid) { 10 | return { 11 | userId: '123mock', 12 | }; 13 | } 14 | } 15 | 16 | return User; 17 | }; 18 | -------------------------------------------------------------------------------- /test/fixtures/apps/agent-app-sync/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | const done = app.readyCallback(); 5 | const test = app.createAppWorkerClient('test', { 6 | listen(cb) { 7 | this._subscribe('listening', cb); 8 | }, 9 | }); 10 | test.listen(arg => { 11 | app.arg = arg; 12 | done(); 13 | }) 14 | }; 15 | -------------------------------------------------------------------------------- /test/fixtures/apps/async-app/app/service/api.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | return class ApiService extends app.Service { 5 | async getName() { 6 | await sleep(100); 7 | return 'service'; 8 | } 9 | }; 10 | }; 11 | 12 | function sleep(ms) { 13 | return new Promise(resolve => setTimeout(resolve, ms)); 14 | } 15 | -------------------------------------------------------------------------------- /test/fixtures/apps/i18n/config/locales/de.json: -------------------------------------------------------------------------------- 1 | { 2 | "Hello": "Hallo", 3 | "Hello %s, how are you today?": "Hallo %s, wie geht es dir heute?", 4 | "weekend": "Wochenende", 5 | "Hello %s, how are you today? How was your %s.": "Hallo %s, wie geht es dir heute? Wie war dein %s.", 6 | "Hi": "Hi", 7 | "Howdy": "Hallöchen", 8 | "tree": "Baum" 9 | } 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/logger-level-debug/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const sleep = require('mz-modules/sleep'); 4 | 5 | module.exports = app => { 6 | app.get('/', function*() { 7 | this.logger.debug('hi %s %s', this.method, this.url); 8 | // wait for writing to file 9 | yield sleep(1000); 10 | this.body = 'ok'; 11 | }); 12 | }; 13 | -------------------------------------------------------------------------------- /test/fixtures/apps/subdir-services/app/service/foo/subdir2/sub2.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | return class Sub2 extends app.Service { 5 | constructor(ctx) { 6 | super(ctx); 7 | } 8 | 9 | * get(name) { 10 | return { 11 | name: name, 12 | bar: 'bar3', 13 | }; 14 | } 15 | }; 16 | }; 17 | -------------------------------------------------------------------------------- /test/fixtures/apps/router-app/app/controller/members.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | // 测试 app.resources 遇到 controller 没有足够的 action 的场景 4 | 5 | exports.index = function* () { 6 | this.body = 'index'; 7 | }; 8 | 9 | exports.new = function* () { 10 | this.body = 'new'; 11 | }; 12 | 13 | exports.show = function* () { 14 | this.body = 'show - ' + this.params.id; 15 | }; -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | matrix: 3 | - nodejs_version: '6' 4 | - nodejs_version: '7' 5 | - nodejs_version: '8' 6 | 7 | install: 8 | - ps: Install-Product node $env:nodejs_version 9 | - npm i npminstall && node_modules\.bin\npminstall 10 | 11 | test_script: 12 | - node --version 13 | - npm --version 14 | - npm run ci 15 | 16 | build: off 17 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - '6' 5 | - '7' 6 | - '8' 7 | install: 8 | - npm i npminstall && npminstall 9 | script: 10 | - npm run ci 11 | after_script: 12 | - npminstall codecov && codecov 13 | - test $TRAVIS_NODE_VERSION = 8 && travis_wait scripts/doc_travis.sh 14 | env: 15 | global: 16 | - ENCRYPTION_LABEL: a62186272189 17 | -------------------------------------------------------------------------------- /docs/source/_data/links.yml: -------------------------------------------------------------------------------- 1 | Github: 2 | Organization: https://github.com/eggjs 3 | Examples: https://github.com/eggjs/examples 4 | Community: 5 | Changelog: https://github.com/eggjs/egg/releases 6 | FAQ: https://eggjs.org/zh-cn/faq.html 7 | Issues: https://github.com/eggjs/egg/issues 8 | Links: 9 | Ant Design: https://ant.design 10 | Enclose.IO: http://enclose.io 11 | -------------------------------------------------------------------------------- /test/fixtures/apps/ctx-background/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('mz/fs'); 4 | 5 | module.exports = function* () { 6 | this.body = 'hello'; 7 | this.runInBackground(function* saveUserInfo(ctx) { 8 | const buf = yield fs.readFile(__filename); 9 | ctx.logger.warn('background run result file size: %s', buf.length); 10 | }); 11 | }; 12 | -------------------------------------------------------------------------------- /test/fixtures/apps/subdir-services/app/service/foo/bar.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function (app) { 4 | class Bar extends app.Service { 5 | constructor(ctx) { 6 | super(ctx); 7 | } 8 | 9 | * get(name) { 10 | return { 11 | name: name, 12 | bar: 'bar1', 13 | }; 14 | } 15 | } 16 | 17 | return Bar; 18 | }; 19 | -------------------------------------------------------------------------------- /test/fixtures/apps/subdir-services/app/service/foo/subdir1/subdir11/bar.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function (app) { 4 | class Bar111 extends app.Service { 5 | constructor(ctx) { 6 | super(ctx); 7 | } 8 | 9 | * get(name) { 10 | return { 11 | bar: 'bar111', 12 | }; 13 | } 14 | } 15 | 16 | return Bar111; 17 | }; 18 | -------------------------------------------------------------------------------- /test/fixtures/apps/agent-throw/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/agent-throw', function*() { 5 | app.messenger.broadcast('agent-throw'); 6 | this.body = 'done'; 7 | }); 8 | 9 | app.get('/agent-throw-string', function*() { 10 | app.messenger.broadcast('agent-throw-string'); 11 | this.body = 'done'; 12 | }); 13 | }; 14 | -------------------------------------------------------------------------------- /test/fixtures/apps/async-app/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.beforeStart(async () => { 5 | await Promise.resolve(); 6 | await app.runSchedule('async'); 7 | app.beforeStartExectuted = true; 8 | }); 9 | 10 | app.beforeClose(async () => { 11 | await Promise.resolve(); 12 | app.beforeCloseExecuted = true; 13 | }); 14 | }; 15 | -------------------------------------------------------------------------------- /test/fixtures/apps/custom-logger/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | module.exports = info => { 6 | return { 7 | customLogger: { 8 | myLogger: { 9 | file: path.join(info.baseDir, 'logs/my.log'), 10 | formatter: meta => meta.message, 11 | }, 12 | }, 13 | keys: 'test key', 14 | }; 15 | }; 16 | -------------------------------------------------------------------------------- /test/fixtures/apps/subdir-services/app/service/cif/user.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function (app) { 4 | class UserCif extends app.Service { 5 | constructor(ctx) { 6 | super(ctx); 7 | } 8 | 9 | * get(uid) { 10 | return { 11 | uid: uid, 12 | cif: true, 13 | }; 14 | } 15 | } 16 | 17 | return UserCif; 18 | }; 19 | -------------------------------------------------------------------------------- /test/fixtures/apps/subdir-services/app/service/foo/subdir/bar.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function (app) { 4 | class Bar2 extends app.Service { 5 | constructor(ctx) { 6 | super(ctx); 7 | } 8 | 9 | * get(name) { 10 | return { 11 | name: name, 12 | bar: 'bar2', 13 | }; 14 | } 15 | } 16 | 17 | return Bar2; 18 | }; 19 | -------------------------------------------------------------------------------- /test/fixtures/apps/agent-restart/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const client = require('./client'); 4 | 5 | module.exports = app => { 6 | const mock = app.createAppWorkerClient('mock', { 7 | subscribe: function(info, listener) { 8 | this._subscribe(info, listener); 9 | return this; 10 | }, 11 | }); 12 | 13 | mock.subscribe('aaa', data => console.log(data)); 14 | }; 15 | -------------------------------------------------------------------------------- /test/fixtures/apps/logger/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | module.exports = info => { 6 | return { 7 | logger: { 8 | buffer: false, 9 | }, 10 | customLogger: { 11 | customLogger: { 12 | file: path.join(info.baseDir, 'logs/custom.log'), 13 | }, 14 | }, 15 | keys: 'test key', 16 | }; 17 | }; 18 | -------------------------------------------------------------------------------- /test/fixtures/apps/ctx-background/app/controller/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('mz/fs'); 4 | 5 | module.exports = function* () { 6 | this.body = 'hello app'; 7 | this.app.runInBackground(function* saveUserInfo(ctx) { 8 | const buf = yield fs.readFile(__filename); 9 | ctx.logger.warn('mock background run at app result file size: %s', buf.length); 10 | }); 11 | }; 12 | -------------------------------------------------------------------------------- /test/fixtures/apps/ctx-background/app/controller/error.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('mz/fs'); 4 | 5 | module.exports = function* () { 6 | this.body = 'hello error'; 7 | this.runInBackground(function* mockError(ctx) { 8 | const buf = yield fs.readFile(__filename + '-not-exists'); 9 | ctx.logger.warn('background run result file size: %s', buf.length); 10 | }); 11 | }; 12 | -------------------------------------------------------------------------------- /scripts/commits.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | 3 | REPO=$(git config --get remote.origin.url | sed 's/git@\(.*\):\(.*\)\.git/http:\/\/\1\/\2/g') 4 | LAST_TAG=$(git describe --tags --abbrev=0) 5 | LAST_TAG_DATE=$(git show -s --format=%cd $LAST_TAG) 6 | FORMAT=" * [[\`%h\`]($REPO/commit/%H)] - %s (%aN <<%ae>>)" 7 | 8 | git fetch 9 | git log --pretty=format:"$FORMAT" --since="$LAST_TAG_DATE" --no-merges 10 | -------------------------------------------------------------------------------- /test/fixtures/apps/messenger-app-agent/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(app) { 4 | app.messenger.on('agent2app', data => console.log(data)); 5 | app.messenger.on('app2app', data => console.log(data)); 6 | 7 | app.messenger.once('egg-ready', () => { 8 | app.messenger.sendToApp('app2app', 'app2app'); 9 | app.messenger.sendToAgent('app2agent', 'app2agent'); 10 | }); 11 | }; 12 | -------------------------------------------------------------------------------- /test/fixtures/apps/agent-restart/agent.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const client = require('./client'); 4 | 5 | module.exports = agent => { 6 | agent.startAgent({ 7 | name: 'mock', 8 | client: client, 9 | subscribe: function(reg, listener) { 10 | console.log('agent subscribe', reg); 11 | }, 12 | }); 13 | 14 | agent.messenger.on('die', () => { 15 | process.exit(1); 16 | }); 17 | }; 18 | -------------------------------------------------------------------------------- /test/fixtures/apps/multiple-view-engine/nunjucks.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const sleep = require('mz-modules/sleep'); 4 | 5 | class NunjucksView { 6 | * render(filename, locals, options) { 7 | yield sleep(10); 8 | return { 9 | filename, 10 | locals, 11 | options, 12 | type: 'nunjucks', 13 | }; 14 | } 15 | 16 | * renderString() {} 17 | } 18 | 19 | module.exports = NunjucksView; 20 | -------------------------------------------------------------------------------- /test/fixtures/apps/base-context-class/app/service/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | return class HomeController extends app.Service { 5 | * show() { 6 | this.ctx.body = 'hello'; 7 | this.logger.debug('debug'); 8 | this.logger.info('appname: %s', this.config.name); 9 | this.logger.warn('warn'); 10 | this.logger.error(new Error('some error')); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /test/fixtures/apps/messenger-broadcast/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(app) { 4 | app.messenger.on('egg-ready', () => { 5 | app.messenger.broadcast('broadcast', { 6 | from: 'app', 7 | pid: process.pid, 8 | }); 9 | }); 10 | 11 | app.messenger.on('broadcast', info => { 12 | console.log('app %s receive message from %s pid %s', process.pid, info.from, info.pid); 13 | }); 14 | }; 15 | -------------------------------------------------------------------------------- /test/fixtures/apps/multiple-view-engine/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/render-ejs', 'view.renderEjs'); 5 | app.get('/render-nunjucks', 'view.renderNunjucks'); 6 | app.get('/render-with-options', 'view.renderWithOptions'); 7 | 8 | app.get('/render-string', 'view.renderString'); 9 | app.get('/render-string-without-view-engine', 'view.renderStringWithoutViewEngine'); 10 | }; 11 | -------------------------------------------------------------------------------- /test/fixtures/apps/override_method/app/router.js: -------------------------------------------------------------------------------- 1 | module.exports = app => { 2 | app.get('/test', function* () { 3 | this.body = "test-get"; 4 | }); 5 | 6 | app.put('/test', function* () { 7 | this.body = "test-put"; 8 | }); 9 | 10 | app.delete('/test', function* () { 11 | this.body = 'test-delete'; 12 | }); 13 | 14 | app.patch('/test', function* () { 15 | this.body = 'test-patch'; 16 | }); 17 | }; 18 | -------------------------------------------------------------------------------- /test/fixtures/apps/messenger-broadcast/agent.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(agent) { 4 | agent.messenger.on('egg-ready', () => { 5 | agent.messenger.broadcast('broadcast', { 6 | from: 'agent', 7 | pid: process.pid, 8 | }); 9 | }); 10 | 11 | agent.messenger.on('broadcast', info => { 12 | console.log('agent %s receive message from %s pid %s', process.pid, info.from, info.pid); 13 | }); 14 | }; 15 | -------------------------------------------------------------------------------- /test/fixtures/apps/agent-client-app/agent.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function initAgent(agent) { 4 | const client = { 5 | 'mock-data': 'mock-data', 6 | 'not-exist-data': null, 7 | ready(cb) { 8 | setImmediate(cb); 9 | }, 10 | }; 11 | 12 | agent.startAgent({ 13 | name: 'sub-client', 14 | client, 15 | subscribe(info, listener) { 16 | listener(client[info]); 17 | }, 18 | }); 19 | }; 20 | -------------------------------------------------------------------------------- /test/fixtures/apps/subdir-services/app/service/certify-personal/mobile-hi/do_certify.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function (app) { 4 | class Certify extends app.Service { 5 | constructor(ctx) { 6 | super(ctx); 7 | } 8 | 9 | * exec(cmd) { 10 | return { 11 | cmd: cmd, 12 | method: this.ctx.method, 13 | url: this.ctx.url, 14 | }; 15 | } 16 | } 17 | 18 | return Certify; 19 | }; 20 | -------------------------------------------------------------------------------- /test/fixtures/apps/messenger-app-agent/agent.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(agent) { 4 | agent.messenger.on('agent2agent', data => console.log(data)); 5 | agent.messenger.on('app2agent', data => console.log(data)); 6 | 7 | agent.messenger.once('egg-ready', () => { 8 | // wait egg ready 9 | agent.messenger.sendToApp('agent2app', 'agent2app'); 10 | agent.messenger.sendToAgent('agent2agent', 'agent2agent'); 11 | }); 12 | }; 13 | -------------------------------------------------------------------------------- /test/fixtures/apps/aliyun-egg/lib/agent.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const egg = require('../../../../..'); 5 | const Agent = egg.Agent; 6 | const AppWorkerLoader = egg.AppWorkerLoader; 7 | 8 | class MyAgent extends Agent { 9 | 10 | constructor(options) { 11 | super(options); 12 | } 13 | 14 | get [Symbol.for('egg#eggPath')]() { 15 | return path.join(__dirname, '..'); 16 | } 17 | } 18 | 19 | module.exports = MyAgent; 20 | -------------------------------------------------------------------------------- /test/fixtures/apps/middlewares/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | const path = require('path'); 5 | 6 | exports.security = { 7 | csrf: false, 8 | }; 9 | 10 | exports.siteFile = { 11 | '/robots.txt': fs.readFileSync(path.join(__dirname, '../app/robots.txt')), 12 | '/crossdomain.xml': fs.readFileSync(path.join(__dirname, '../app/crossdomain.xml')), 13 | '/fake.txt': 123, // wrong config 14 | }; 15 | 16 | exports.keys = 'foo'; 17 | -------------------------------------------------------------------------------- /test/lib/plugins/static.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const utils = require('../../utils'); 4 | 5 | describe('test/lib/plugins/static.test.js', () => { 6 | let app; 7 | before(() => { 8 | app = utils.app('apps/static-server'); 9 | return app.ready(); 10 | }); 11 | 12 | it('should get exists js file', () => { 13 | return app.httpRequest() 14 | .get('/public/foo.js') 15 | .expect('alert(\'bar\');\n') 16 | .expect(200); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /test/fixtures/apps/demo/app/router.js: -------------------------------------------------------------------------------- 1 | module.exports = app => { 2 | app.get('home', '/', 'home'); 3 | app.get('/hello', app.controller.hello); 4 | app.get('/logger', app.controller.logger); 5 | app.get('/protocol', function*() { 6 | this.body = this.protocol; 7 | }); 8 | 9 | app.get('/user.json', app.jsonp(), function*() { 10 | this.body = { name: 'fengmk2' }; 11 | }); 12 | app.get('/ip', app.controller.ip); 13 | 14 | app.get('/class-controller', 'foo.bar'); 15 | }; 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | coverage 3 | *.log 4 | npm-debug.log 5 | .logs 6 | logs 7 | *.swp 8 | run 9 | *-run 10 | .idea 11 | .DS_Store 12 | .tmp 13 | docs/CONTRIBUTING.md 14 | docs/node_modules 15 | docs/README.md 16 | docs/db.json 17 | docs/source/release/index.md 18 | docs/source/member_guide.md 19 | docs/source/_data/versions.yml 20 | docs/**/contributing.md 21 | docs/public 22 | docs/plugins.png 23 | 24 | package-lock.json 25 | yarn.lock 26 | !test/fixtures/apps/loader-plugin/node_modules 27 | -------------------------------------------------------------------------------- /test/fixtures/apps/cluster_mod_app/lib/api_client.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const APIClientBase = require('cluster-client').APIClientBase; 4 | 5 | class ApiClient extends APIClientBase { 6 | get DataClient() { 7 | return require('./registry_client'); 8 | } 9 | 10 | get clusterOptions() { 11 | return { 12 | name: 'ApiClient', 13 | }; 14 | } 15 | 16 | * getResponseTimeout() { 17 | return this._client.options.responseTimeout; 18 | } 19 | } 20 | 21 | module.exports = ApiClient; 22 | -------------------------------------------------------------------------------- /test/fixtures/apps/dnscache_httpclient/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function* () { 4 | let args; 5 | if (this.query.host) { 6 | args = {}; 7 | args.headers = { host: this.query.host }; 8 | } 9 | if (this.query.Host) { 10 | args = {}; 11 | args.headers = { Host: this.query.Host }; 12 | } 13 | const result = yield this.curl(this.query.url, args); 14 | this.status = result.status; 15 | this.set(result.headers); 16 | this.body = result.data; 17 | }; 18 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin-dep-missing/config/plugin.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | a: { 5 | enable: true, 6 | dependencies: ['b'], 7 | path: path.join(__dirname, '../plugins/a') 8 | }, 9 | 10 | b: { 11 | enable: true, 12 | dependencies: ['c'], 13 | path: path.join(__dirname, '../plugins/b') 14 | }, 15 | 16 | c: { 17 | enable: true, 18 | dependencies: ['a1'], 19 | path: path.join(__dirname, '../plugins/c') 20 | }, 21 | 22 | }; 23 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin-dep-recursive/config/plugin.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | a: { 5 | enable: true, 6 | dependencies: ['b'], 7 | path: path.join(__dirname, '../plugins/a') 8 | }, 9 | 10 | b: { 11 | enable: true, 12 | dependencies: ['c'], 13 | path: path.join(__dirname, '../plugins/b') 14 | }, 15 | 16 | c: { 17 | enable: true, 18 | dependencies: ['a'], 19 | path: path.join(__dirname, '../plugins/c') 20 | }, 21 | 22 | }; 23 | -------------------------------------------------------------------------------- /test/index.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('assert'); 4 | const egg = require('..'); 5 | 6 | describe('test/index.test.js', () => { 7 | it('should expose properties', () => { 8 | assert.deepEqual(Object.keys(egg).sort(), [ 9 | 'Agent', 10 | 'AgentWorkerLoader', 11 | 'AppWorkerLoader', 12 | 'Application', 13 | 'BaseContextClass', 14 | 'Controller', 15 | 'Service', 16 | 'Subscription', 17 | 'startCluster', 18 | ]); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /test/fixtures/apps/messenger/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(app) { 4 | app.messenger.on('egg-ready', () => { 5 | app.messenger.on('app-to-agent', function(msg) { 6 | console.log('[app] app-to-agent', msg); 7 | }); 8 | app.messenger.on('agent-to-app', function(msg) { 9 | console.log('[app] agent-to-app', msg); 10 | }); 11 | app.messenger.send('app-to-agent', 'app msg'); 12 | app.messenger.send('pid', process.pid); 13 | app.messenger.send('ready'); 14 | }); 15 | }; 16 | -------------------------------------------------------------------------------- /test/fixtures/apps/response/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('assert'); 4 | 5 | module.exports = app => { 6 | app.get('/', function* () { 7 | this.body = 'hello'; 8 | assert.equal(this.response.length, 5); 9 | this.body = new Buffer(3); 10 | assert.equal(this.response.length, 3); 11 | this.body = {}; 12 | assert.equal(this.response.length, 2); 13 | this.body = 'ok'; 14 | this.type = 'text'; 15 | this.response.type = 'plain/text'; 16 | }); 17 | } 18 | -------------------------------------------------------------------------------- /test/fixtures/apps/cluster_mod_app/lib/api_client_2.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const APIClientBase = require('cluster-client').APIClientBase; 4 | 5 | class ApiClient2 extends APIClientBase { 6 | get DataClient() { 7 | return require('./registry_client'); 8 | } 9 | 10 | get clusterOptions() { 11 | return { 12 | name: 'ApiClient2', 13 | responseTimeout: 1000, 14 | }; 15 | } 16 | 17 | * getResponseTimeout() { 18 | return this._client.options.responseTimeout; 19 | } 20 | } 21 | 22 | module.exports = ApiClient2; 23 | -------------------------------------------------------------------------------- /test/fixtures/apps/singleton-demo/create.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class DataService { 4 | constructor(config) { 5 | this.config = config; 6 | } 7 | 8 | * getConfig() { 9 | return this.config; 10 | } 11 | 12 | ready(done) { 13 | setTimeout(done, 1000); 14 | } 15 | } 16 | 17 | let count = 0; 18 | module.exports = function create(config, app) { 19 | const done = app.readyCallback(`DataService-${count++}`); 20 | const dataService = new DataService(config); 21 | dataService.ready(done); 22 | return dataService; 23 | }; 24 | -------------------------------------------------------------------------------- /lib/loader/agent_worker_loader.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const EggLoader = require('egg-core').EggLoader; 4 | 5 | /** 6 | * Agent worker process loader 7 | * @see https://github.com/eggjs/egg-loader 8 | */ 9 | class AgentWorkerLoader extends EggLoader { 10 | 11 | /** 12 | * loadPlugin first, then loadConfig 13 | */ 14 | loadConfig() { 15 | this.loadPlugin(); 16 | super.loadConfig(); 17 | } 18 | 19 | load() { 20 | this.loadAgentExtend(); 21 | this.loadCustomAgent(); 22 | } 23 | } 24 | 25 | module.exports = AgentWorkerLoader; 26 | -------------------------------------------------------------------------------- /test/fixtures/apps/multiple-view-engine/config/config.default.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | module.exports = appInfo => { 6 | const root = [ 7 | path.join(appInfo.baseDir, 'app/view'), 8 | path.join(appInfo.baseDir, 'app/view2'), 9 | ]; 10 | return { 11 | view: { 12 | root: root.join(', '), 13 | defaultExt: '.ejs', 14 | mapping: { 15 | '.ejs': 'ejs', 16 | '.nj': 'nunjucks', 17 | '.html': 'html', 18 | }, 19 | }, 20 | 21 | keys: 'test key', 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /test/fixtures/apps/multiple-view-engine/ejs.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const sleep = require('mz-modules/sleep'); 4 | 5 | class EjsView { 6 | * render(filename, locals, options) { 7 | yield sleep(10); 8 | return { 9 | filename, 10 | locals, 11 | options, 12 | type: 'ejs', 13 | }; 14 | } 15 | 16 | * renderString(tpl, locals, options) { 17 | yield sleep(10); 18 | return { 19 | tpl, 20 | locals, 21 | options, 22 | type: 'ejs', 23 | }; 24 | } 25 | } 26 | 27 | module.exports = EjsView; 28 | -------------------------------------------------------------------------------- /test/app/middleware/meta.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const mm = require('egg-mock'); 4 | const utils = require('../../utils'); 5 | 6 | describe('test/app/middleware/meta.test.js', () => { 7 | let app; 8 | before(() => { 9 | app = utils.app('apps/middlewares'); 10 | return app.ready(); 11 | }); 12 | 13 | after(() => app.close()); 14 | 15 | afterEach(mm.restore); 16 | 17 | it('should get X-Readtime header', () => { 18 | return app.httpRequest() 19 | .get('/') 20 | .expect('X-Readtime', /\d+/) 21 | .expect(200); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /test/fixtures/apps/body_parser_testapp_match/app/router.js: -------------------------------------------------------------------------------- 1 | module.exports = app => { 2 | app.get('/test/body_parser/user', function* () { 3 | this.body = { 4 | url: this.url, 5 | csrf: this.csrf 6 | }; 7 | }); 8 | 9 | app.post('/test/body_parser/user', function* () { 10 | this.body = this.request.body; 11 | }); 12 | 13 | app.post('/test/body_parser/foo.json', function* () { 14 | this.body = this.request.body; 15 | }); 16 | app.post('/test/body_parser/form.json', function* () { 17 | this.body = this.request.body; 18 | }); 19 | }; 20 | -------------------------------------------------------------------------------- /test/fixtures/apps/body_parser_testapp_disable/app/router.js: -------------------------------------------------------------------------------- 1 | module.exports = app => { 2 | app.get('/test/body_parser/user', function* () { 3 | this.body = { 4 | url: this.url, 5 | csrf: this.csrf 6 | }; 7 | }); 8 | 9 | app.post('/test/body_parser/user', function* () { 10 | this.body = this.request.body; 11 | }); 12 | 13 | app.post('/test/body_parser/foo.json', function* () { 14 | this.body = this.request.body; 15 | }); 16 | app.post('/test/body_parser/form.json', function* () { 17 | this.body = this.request.body; 18 | }); 19 | }; 20 | -------------------------------------------------------------------------------- /test/fixtures/apps/body_parser_testapp_ignore/app/router.js: -------------------------------------------------------------------------------- 1 | module.exports = app => { 2 | app.get('/test/body_parser/user', function* () { 3 | this.body = { 4 | url: this.url, 5 | csrf: this.csrf 6 | }; 7 | }); 8 | 9 | app.post('/test/body_parser/user', function* () { 10 | this.body = this.request.body; 11 | }); 12 | 13 | app.post('/test/body_parser/foo.json', function* () { 14 | this.body = this.request.body; 15 | }); 16 | app.post('/test/body_parser/form.json', function* () { 17 | this.body = this.request.body; 18 | }); 19 | }; 20 | -------------------------------------------------------------------------------- /test/fixtures/apps/encrypt-cookies/app/controller/home.js: -------------------------------------------------------------------------------- 1 | module.exports = function* () { 2 | var encrypt = this.cookies.get('foo', { 3 | encrypt: true 4 | }); 5 | var encryptWrong = this.cookies.get('foo', { signed: false }); 6 | var plain = this.cookies.get('plain', { signed: false }); 7 | this.cookies.set('foo', 'bar 中文', { 8 | encrypt: true 9 | }); 10 | this.cookies.set('plain', 'text ok', { signed: false }); 11 | this.body = { 12 | set: 'bar 中文', 13 | encrypt: encrypt, 14 | encryptWrong: encryptWrong, 15 | plain: plain, 16 | }; 17 | }; 18 | -------------------------------------------------------------------------------- /test/fixtures/apps/cluster_mod_app/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/', app.controller.home.index); 5 | app.get('/clusterPort', app.controller.home.getClusterPort); 6 | app.post('/publish', app.controller.home.publish); 7 | app.get('/getHosts', app.controller.home.getHosts); 8 | 9 | app.get('/getDefaultTimeout', function*() { 10 | this.body = yield app.apiClient.getResponseTimeout(); 11 | }); 12 | app.get('/getOverwriteTimeout', function*() { 13 | this.body = yield app.apiClient2.getResponseTimeout(); 14 | }); 15 | }; 16 | -------------------------------------------------------------------------------- /test/fixtures/apps/onerror/app/controller/home.js: -------------------------------------------------------------------------------- 1 | exports.index = function* () { 2 | var err = new Error('test error'); 3 | if(this.query.code) { 4 | err.code = this.query.code 5 | } 6 | if (this.query.status) { 7 | err.status = Number(this.query.status) 8 | } 9 | throw err; 10 | }; 11 | exports.csrf = function* () { 12 | this.set('x-csrf', this.csrf); 13 | this.body = 'test'; 14 | } 15 | exports.test = function* () { 16 | var err = new SyntaxError('syntax error'); 17 | if (this.query.status) { 18 | err.status = Number(this.query.status) 19 | } 20 | throw err; 21 | } 22 | -------------------------------------------------------------------------------- /test/fixtures/apps/httpclient-overwrite/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('assert'); 4 | 5 | module.exports = app => { 6 | class CustomHttpClient extends app.HttpClient { 7 | request(url, opt) { 8 | return new Promise(resolve => { 9 | assert(/^http/.test(url), 'url should start with http, but got ' + url); 10 | resolve(); 11 | }).then(() => { 12 | return super.request(url, opt); 13 | }); 14 | } 15 | 16 | curl(url, opt) { 17 | return this.request(url, opt); 18 | } 19 | } 20 | app.HttpClient = CustomHttpClient; 21 | }; 22 | -------------------------------------------------------------------------------- /test/lib/core/config/config.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('assert'); 4 | const mm = require('egg-mock'); 5 | const utils = require('../../../utils'); 6 | 7 | describe('test/lib/core/config/config.test.js', () => { 8 | let app; 9 | before(() => { 10 | app = utils.app('apps/demo'); 11 | return app.ready(); 12 | }); 13 | after(() => app.close()); 14 | 15 | afterEach(mm.restore); 16 | 17 | it('should return config.name', () => { 18 | assert(app.config.name === 'demo'); 19 | assert(app.config.logger.disableConsoleAfterReady === false); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /test/fixtures/apps/demo/app/controller/logger.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function*() { 4 | const message = this.query.message; 5 | 6 | this.logger.debug('debug %s', message); 7 | this.logger.info('info %s', message); 8 | this.logger.warn('warn %s', message); 9 | this.logger.error(new Error('error ' + message)); 10 | 11 | this.coreLogger.debug('core debug %s', message); 12 | this.coreLogger.info('core info %s', message); 13 | this.coreLogger.warn('core warn %s', message); 14 | this.coreLogger.error(new Error('core error ' + message)); 15 | 16 | this.body = 'logger'; 17 | }; 18 | -------------------------------------------------------------------------------- /test/fixtures/apps/body_parser_testapp/app/router.js: -------------------------------------------------------------------------------- 1 | module.exports = app => { 2 | app.get('/test/body_parser/user', function* () { 3 | this.body = { 4 | url: this.url, 5 | csrf: this.csrf 6 | }; 7 | }); 8 | 9 | app.post('/test/body_parser/user', function* () { 10 | this.logger.info('request body %s', this.request.body); 11 | this.body = this.request.body; 12 | }); 13 | 14 | app.post('/test/body_parser/foo.json', function* () { 15 | this.body = this.request.body; 16 | }); 17 | app.post('/test/body_parser/form.json', function* () { 18 | this.body = this.request.body; 19 | }); 20 | }; 21 | -------------------------------------------------------------------------------- /docs/source/zh-cn/resource.md: -------------------------------------------------------------------------------- 1 | title: 资源 2 | --- 3 | 4 | - [awesome-egg](https://github.com/eggjs/awesome-egg) 5 | 6 | ## 框架列表 7 | 8 | - [aliyun-egg](https://github.com/eggjs/aliyun-egg) 9 | 10 | ## 社区文章 11 | 12 | - [如何评价阿里开源的企业级 Node.js 框架 Egg?](https://www.zhihu.com/question/50526101/answer/144952130) 13 | by [@天猪](https://github.com/atian25) 14 | 15 | - 你也可以到[知乎专栏](https://zhuanlan.zhihu.com/eggjs)看我们的文章 16 | 17 | ## 工具 18 | 19 | - [vscode plugin - eggjs](https://marketplace.visualstudio.com/items?itemName=atian25.eggjs) 20 | - [vscode plugin - eggjs-dev-tools](https://marketplace.visualstudio.com/items?itemName=yuzukwok.eggjs-dev-tools) -------------------------------------------------------------------------------- /test/fixtures/apps/base-context-class/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | return class HomeController extends app.Controller { 5 | * show() { 6 | yield this.service.home.show(); 7 | this.ctx.body = 'hello'; 8 | this.logger.debug('debug'); 9 | this.logger.info('appname: %s', this.config.name); 10 | this.logger.warn('warn'); 11 | this.logger.error(new Error('some error')); 12 | } 13 | 14 | getPathName() { 15 | this.ctx.body = this.pathName; 16 | } 17 | 18 | getConfig() { 19 | this.ctx.body = this.config.name; 20 | } 21 | }; 22 | } 23 | -------------------------------------------------------------------------------- /.autod.conf.js: -------------------------------------------------------------------------------- 1 | 'ues strict'; 2 | 3 | module.exports = { 4 | write: true, 5 | plugin: 'autod-egg', 6 | prefix: '^', 7 | devprefix: '^', 8 | exclude: [ 9 | 'test/fixtures', 10 | 'examples', 11 | 'docs', 12 | 'run', 13 | ], 14 | devdep: [ 15 | 'autod', 16 | 'autod-egg', 17 | 'eslint', 18 | 'eslint-config-egg', 19 | 'egg-bin', 20 | 'egg-doctools', 21 | 'egg-plugin-puml', 22 | 'egg-view-nunjucks', 23 | ], 24 | dep: [ 25 | '@types/accepts', 26 | '@types/koa', 27 | '@types/koa-router', 28 | ], 29 | semver: [ 30 | 'koa-bodyparser@2', 31 | ], 32 | test: 'scripts', 33 | }; 34 | -------------------------------------------------------------------------------- /test/fixtures/apps/demo/config/config.default.js: -------------------------------------------------------------------------------- 1 | exports.keys = 'foo'; 2 | exports.proxy = true; 3 | exports.buffer = Buffer.from('test'); 4 | 5 | exports.pass = 'this is pass'; 6 | exports.pwd = 'this is pwd'; 7 | exports.password = 'this is password'; 8 | exports.passwordNew = 'this is passwordNew'; 9 | exports.mysql = { 10 | passd: 'this is passd', 11 | passwd: 'this is passwd', 12 | secret: 'secret 123', 13 | secretNumber: 123, 14 | secretBoolean: true, 15 | masterKey: 'this is masterKey', 16 | accessKey: 'this is accessKey', 17 | accessId: 'this is accessId', 18 | consumerSecret: 'this is consumerSecret', 19 | someSecret: null, 20 | }; 21 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | title: Egg.js 2 | subtitle: "Born to build better enterprise frameworks and apps" 3 | description: "Born to build better enterprise frameworks and apps" 4 | language: 5 | - zh-cn 6 | - en 7 | timezone: UTC 8 | url: https://eggjs.org 9 | root: / 10 | archive_dir: news 11 | permalink: news/:year/:month/:day/:title/ 12 | new_post_name: :year-:month-:day-:title.md # File name of new posts 13 | post_asset_folder: true 14 | highlight: 15 | enable: true 16 | line_number: false 17 | per_page: 0 18 | 19 | # Extensions 20 | ## Plugins: https://hexo.io/plugins/ 21 | ## Themes: https://hexo.io/themes/ 22 | theme: egg 23 | 24 | less: 25 | compress: true 26 | -------------------------------------------------------------------------------- /test/fixtures/apps/router-app/app/controller/posts.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.index = function* () { 4 | this.body = 'index'; 5 | }; 6 | 7 | exports.new = function* () { 8 | this.body = 'new'; 9 | }; 10 | 11 | exports.create = function* () { 12 | this.body = 'create'; 13 | }; 14 | 15 | exports.show = function* () { 16 | this.body = 'show - ' + this.params.id; 17 | }; 18 | 19 | exports.edit = function* () { 20 | this.body = 'edit - ' + this.params.id; 21 | }; 22 | 23 | exports.update = function* () { 24 | this.body = 'update - ' + this.params.id; 25 | }; 26 | 27 | exports.destroy = function* () { 28 | this.body = 'destroy - ' + this.params.id; 29 | }; -------------------------------------------------------------------------------- /test/lib/plugins/depd.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('assert'); 4 | 5 | const mm = require('egg-mock'); 6 | const utils = require('../../utils'); 7 | 8 | describe('test/lib/plugins/depd.test.js', () => { 9 | afterEach(mm.restore); 10 | 11 | let app; 12 | before(() => { 13 | app = utils.app('apps/demo'); 14 | return app.ready(); 15 | }); 16 | after(() => app.close()); 17 | 18 | it('should use this.locals instead of this.state', () => { 19 | const ctx = app.mockContext(); 20 | ctx.locals.test = 'aaa'; 21 | assert.deepEqual(ctx.locals, ctx.state); 22 | assert.deepEqual(ctx.locals.test, ctx.state.test); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /lib/core/base_context_class.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const EggCoreBaseContextClass = require('egg-core').BaseContextClass; 4 | const BaseContextLogger = require('./base_context_logger'); 5 | 6 | const LOGGER = Symbol('BaseContextClass#logger'); 7 | 8 | /** 9 | * BaseContextClass is a base class that can be extended, 10 | * it's instantiated in context level, 11 | * {@link Helper}, {@link Service} is extending it. 12 | */ 13 | class BaseContextClass extends EggCoreBaseContextClass { 14 | get logger() { 15 | if (!this[LOGGER]) this[LOGGER] = new BaseContextLogger(this.ctx, this.pathName); 16 | return this[LOGGER]; 17 | } 18 | } 19 | 20 | module.exports = BaseContextClass; 21 | -------------------------------------------------------------------------------- /test/fixtures/apps/cluster_mod_app/agent.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const ApiClient = require('./lib/api_client'); 4 | const ApiClient2 = require('./lib/api_client_2'); 5 | const RegistryClient = require('./lib/registry_client'); 6 | 7 | module.exports = function(agent) { 8 | agent.registryClient = agent.cluster(RegistryClient).create(); 9 | agent.apiClient = new ApiClient({ 10 | cluster: agent.cluster, 11 | }); 12 | agent.apiClient2 = new ApiClient2({ 13 | cluster: agent.cluster, 14 | }); 15 | 16 | agent.beforeStart(function*() { 17 | yield agent.registryClient.ready(); 18 | yield agent.apiClient.ready(); 19 | yield agent.apiClient2.ready(); 20 | }); 21 | }; 22 | -------------------------------------------------------------------------------- /test/lib/core/loader/load_router.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const pedding = require('pedding'); 4 | const utils = require('../../../utils'); 5 | 6 | describe('test/lib/core/loader/load_router.test.js', () => { 7 | let app; 8 | before(() => { 9 | app = utils.app('apps/app-router'); 10 | return app.ready(); 11 | }); 12 | after(() => app.close()); 13 | 14 | it('should load app/router.js', done => { 15 | done = pedding(2, done); 16 | app.httpRequest() 17 | .get('/') 18 | .expect(200) 19 | .expect('hello', done); 20 | 21 | app.httpRequest() 22 | .get('/home') 23 | .expect(200) 24 | .expect('hello', done); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /test/fixtures/apps/multiple-view-engine/app/controller/view.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.renderEjs = ctx => ctx.render('ext/a.ejs', { data: 1 }, { opt: 1 }); 4 | exports.renderNunjucks = ctx => ctx.render('ext/a.nj', { data: 1 }, { opt: 1 }); 5 | exports.renderWithOptions = ctx => ctx.render('ext/a.nj', {}, { viewEngine: 'ejs' }); 6 | 7 | const tpl = 'hello world'; 8 | const opt = { viewEngine: 'ejs' }; 9 | exports.renderString = ctx => ctx.renderString(tpl, { data: 1 }, opt).then(data => ctx.body = data); 10 | exports.renderStringWithoutViewEngine = ctx => { 11 | try { 12 | return ctx.renderString(tpl) 13 | } catch (err) { 14 | return Promise.reject(err.message); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /test/fixtures/apps/view-render/app/router.js: -------------------------------------------------------------------------------- 1 | module.exports = app => { 2 | app.get('home', '/', app.controller.home); 3 | app.get('async', '/async', 'async.index'); 4 | app.get('empty', '/empty', app.controller.empty); 5 | // app.get('/only_require', app.controller.onlyRequire); 6 | app.get('/xss', app.controller.xss); 7 | app.post('/context', app.controller.context); 8 | app.get('/sjs', app.controller.sjs); 9 | app.get('/shtml', app.controller.shtml); 10 | app.get('/locals', app.controller.locals); 11 | app.get('/string', app.controller.string); 12 | app.get('/form_csrf', app.controller.csrf); 13 | app.get('/nonce', app.controller.nonce); 14 | app.get('/inject', app.controller.inject); 15 | }; 16 | -------------------------------------------------------------------------------- /test/fixtures/apps/i18n/app/controller/message.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function* () { 4 | this.body = { 5 | message: this.__('Hello %s, how are you today? How was your %s.', 'fengmk2', 18), 6 | empty: this.__(), 7 | notexists_key: this.__('key not exists'), 8 | empty_string: this.__(''), 9 | novalue: this.__('key %s ok'), 10 | // __ 别名 gettext 也可以使用 11 | arguments3: this.gettext('%s %s %s', 1, 2, 3), 12 | arguments4: this.gettext('%s %s %s %s', 1, 2, 3, 4), 13 | arguments5: this.__('%s %s %s %s %s', 1, 2, 3, 4, 5), 14 | arguments6: this.__('%s %s %s %s %s.', 1, 2, 3, 4, 5, 6), 15 | values: this.__('{0} {1} {0} {1} {2} {100}', ['foo', 'bar']), 16 | }; 17 | }; 18 | -------------------------------------------------------------------------------- /test/lib/plugins/onerror.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const mm = require('egg-mock'); 4 | const utils = require('../../utils'); 5 | 6 | describe('test/lib/plugins/onerror.test.js', () => { 7 | let app; 8 | before(() => { 9 | mm.env('local'); 10 | mm(process.env, 'EGG_LOG', 'none'); 11 | app = utils.app('apps/onerror'); 12 | return app.ready(); 13 | }); 14 | 15 | after(() => app.close()); 16 | 17 | afterEach(mm.restore); 18 | 19 | it('should redirect to error page', () => { 20 | mm(app.config, 'env', 'test'); 21 | return app.httpRequest() 22 | .get('/?status=500') 23 | .expect('Location', 'http://eggjs.org/500?real_status=500') 24 | .expect(302); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /test/fixtures/apps/agent-app/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | const fooDone = app.readyCallback('foo_sub_done'); 5 | const saveDone = app.readyCallback('mock_save_done'); 6 | 7 | function listener(value) { 8 | app.foo = value; 9 | app.mockClient.subscribe({ id: 'foo' }, value => { 10 | if (value < app.foo) { 11 | throw new Error('subscribe error'); 12 | } 13 | setImmediate(() => { app.mockClient.unSubscribe({ id: 'foo' }) }); 14 | }); 15 | app.mockClient.unSubscribe({ id: 'foo' }, listener); 16 | fooDone(); 17 | } 18 | 19 | app.mockClient.subscribe({ id: 'foo' }, listener); 20 | app.mockClient.saveCallback('hello', 'world', saveDone); 21 | }; 22 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin/config/plugin.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | module.exports = { 6 | // 插件简写 7 | a: false, 8 | 9 | a1: true, 10 | 11 | // 标准写法 12 | b: { 13 | enable: true 14 | }, 15 | 16 | // 会自动补全信息 17 | c: {}, 18 | 19 | // 别名,app.plugins.d1 20 | d1: { 21 | package: 'd' 22 | }, 23 | 24 | e: { 25 | path: path.join(__dirname, '../plugins/e') 26 | }, 27 | 28 | f: { 29 | path: path.join(__dirname, '../plugins/f') 30 | }, 31 | 32 | g: { 33 | path: path.join(__dirname, '../plugins/g') 34 | }, 35 | 36 | // 覆盖内置的 37 | rds: { 38 | enable: true, 39 | dependencies: ['session'], 40 | package: 'rds', 41 | }, 42 | }; 43 | -------------------------------------------------------------------------------- /docs/source/zh-cn/basics/app-start.md: -------------------------------------------------------------------------------- 1 | title: 启动自定义 2 | --- 3 | 4 | 我们常常需要在应用启动期间进行一些初始化工作,等初始化完成后应用才可以启动成功,并开始对外提供服务。 5 | 6 | 框架提供了统一的入口文件(`app.js`)进行启动过程自定义,这个文件只返回一个函数。例如,我们需要在应用启动期间从远程接口加载一份全国城市列表,以便于后续在 Controller 中使用: 7 | 8 | ```js 9 | // app.js 10 | module.exports = app => { 11 | app.beforeStart(function* () { 12 | // 应用会等待这个函数执行完成才启动 13 | app.cities = yield app.curl('http://example.com/city.json', { 14 | method: 'GET', 15 | dataType: 'json', 16 | }); 17 | }); 18 | }; 19 | ``` 20 | 21 | 在 Controller 中就可以使用了: 22 | 23 | ```js 24 | // app/controller/city.js 25 | module.exports = function* (ctx) { 26 | // ctx.app.cities 在上面启动期间已经加载,可以直接使用 27 | } 28 | ``` 29 | 30 | **注意:在 `beforeStart` 中不建议做太耗时的操作,框架会有启动的超时检测。** 31 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-ts/app/controller/foo.ts: -------------------------------------------------------------------------------- 1 | import { Controller, RequestObjectBody } from 'egg'; 2 | 3 | // add user controller and service 4 | declare module 'egg' { 5 | interface IController { 6 | foo: FooController; 7 | } 8 | } 9 | 10 | // controller 11 | export default class FooController extends Controller { 12 | async getData() { 13 | try { 14 | this.ctx.body = await this.ctx.service.foo.bar(); 15 | } catch (e) { 16 | const body: RequestObjectBody = this.ctx.request.body; 17 | this.app.logger.info(e.name, body.foo); 18 | } 19 | } 20 | async getBar() { 21 | try { 22 | this.ctx.body = await this.service.foo.bar(); 23 | } catch (e) { 24 | this.ctx.logger.error(e); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /test/fixtures/apps/subdir-services/app/controller/home.js: -------------------------------------------------------------------------------- 1 | module.exports = function* () { 2 | this.body = { 3 | user: yield this.service.user.get('123'), 4 | cif: yield this.service.cif.user.get('123cif'), 5 | bar1: yield this.service.foo.bar.get('bar1name'), 6 | bar2: yield this.service.foo.subdir.bar.get('bar2name'), 7 | 'foo.subdir2.sub2': yield this.service.foo.subdir2.sub2.get('bar3name'), 8 | subdir11bar: yield this.service.foo.subdir1.subdir11.bar.get(), 9 | ok: yield this.service.ok.get(), 10 | cmd: yield this.service.certifyPersonal.mobileHi.doCertify.exec('hihi'), 11 | serviceIsSame: this.service.certifyPersonal === this.service.certifyPersonal, 12 | oldStyle: yield this.service.oldStyle.url(this), 13 | }; 14 | }; 15 | -------------------------------------------------------------------------------- /test/fixtures/apps/cluster_mod_app/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const ApiClient = require('./lib/api_client'); 4 | const ApiClient2 = require('./lib/api_client_2'); 5 | const RegistryClient = require('./lib/registry_client'); 6 | 7 | module.exports = function(app) { 8 | const cluster = app.cluster; 9 | app.registryClient = cluster(RegistryClient).create(); 10 | 11 | app.registryClient.subscribe({ 12 | dataId: 'demo.DemoService', 13 | }, val => { 14 | app.val = val; 15 | }); 16 | 17 | app.apiClient = new ApiClient({ cluster }); 18 | app.apiClient2 = new ApiClient2({ cluster }); 19 | 20 | app.beforeStart(function*() { 21 | yield app.registryClient.ready(); 22 | yield app.apiClient.ready(); 23 | yield app.apiClient2.ready(); 24 | }); 25 | }; 26 | -------------------------------------------------------------------------------- /test/fixtures/apps/watcher-development-app/agent.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const utils = require('../../../utils'); 4 | const file_path1 = utils.getFilepath('apps/watcher-development-app/tmp-agent.txt'); 5 | const dir_path = utils.getFilepath('apps/watcher-development-app/tmp-agent'); 6 | 7 | module.exports = function(agent) { 8 | let count = 0; 9 | function listener() { 10 | count++; 11 | } 12 | 13 | agent.messenger.on('i-want-agent-file-changed-count', function() { 14 | agent.messenger.broadcast('agent-file-changed-count', count); 15 | }); 16 | 17 | agent.messenger.on('agent-watch', function() { 18 | agent.watcher.watch([file_path1, dir_path], listener); 19 | agent.messenger.broadcast('agent-watch-success', 'agent watch success'); 20 | }); 21 | }; 22 | -------------------------------------------------------------------------------- /test/fixtures/apps/multipart/app/controller/upload.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const fs = require('fs'); 5 | 6 | module.exports = function* () { 7 | var parts = this.multipart(); 8 | var part; 9 | var fields = {}; 10 | while (part = yield parts) { 11 | if (Array.isArray(part)) { 12 | fields[part[0]] = part[1]; 13 | continue; 14 | } else { 15 | break; 16 | } 17 | } 18 | 19 | if (!part || !part.filename) { 20 | this.body = { 21 | message: 'no file', 22 | }; 23 | return; 24 | } 25 | 26 | const ws = fs.createWriteStream(path.join(this.app.config.logger.dir, 'multipart-test-file')); 27 | part.pipe(ws); 28 | this.body = { 29 | filename: part.filename, 30 | fields, 31 | }; 32 | }; 33 | -------------------------------------------------------------------------------- /test/lib/core/loader/load_app.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('assert'); 4 | const utils = require('../../../utils'); 5 | 6 | describe('test/lib/core/loader/load_app.test.js', () => { 7 | let app; 8 | before(() => { 9 | app = utils.app('apps/loader-plugin'); 10 | return app.ready(); 11 | }); 12 | after(() => app.close()); 13 | 14 | it('should load app.js', () => { 15 | assert(app.b === 'plugin b'); 16 | assert(app.c === 'plugin c'); 17 | assert(app.app === 'app'); 18 | }); 19 | 20 | it('should load plugin app.js first', () => { 21 | assert(app.dateB <= app.date === true); 22 | assert(app.dateC <= app.date === true); 23 | }); 24 | 25 | it('should not load disable plugin', () => { 26 | assert(!app.a); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /lib/core/logger.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const Loggers = require('egg-logger').EggLoggers; 4 | 5 | module.exports = function createLoggers(app) { 6 | const loggerConfig = app.config.logger; 7 | loggerConfig.type = app.type; 8 | 9 | if (app.config.env === 'prod' && loggerConfig.level === 'DEBUG' && loggerConfig.allowDebugAtProd === true) { 10 | loggerConfig.level = 'INFO'; 11 | } 12 | 13 | const loggers = new Loggers(app.config); 14 | 15 | // won't print to console after started, except for local and unittest 16 | app.ready(() => { 17 | if (loggerConfig.disableConsoleAfterReady) { 18 | loggers.disableConsole(); 19 | } 20 | }); 21 | loggers.coreLogger.info('[egg:logger] init all loggers with options: %j', loggerConfig); 22 | 23 | return loggers; 24 | }; 25 | -------------------------------------------------------------------------------- /test/async/_async.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('assert'); 4 | const mm = require('egg-mock'); 5 | const utils = require('../utils'); 6 | 7 | describe('test/async.test.js', () => { 8 | afterEach(mm.restore); 9 | let app; 10 | before(async () => { 11 | app = utils.app('apps/async-app'); 12 | await app.ready(); 13 | assert(app.beforeStartExectuted); 14 | assert(app.scheduleExecuted); 15 | }); 16 | after(async () => { 17 | await app.close(); 18 | assert(app.beforeCloseExecuted); 19 | }); 20 | 21 | it('middleware, controller and service support async functions', async () => { 22 | await app.httpRequest() 23 | .get('/api') 24 | .expect(200) 25 | .expect([ 'service', 'controller', 'router', 'middleware' ]); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /lib/core/context_httpclient.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | class ContextHttpClient { 4 | constructor(ctx) { 5 | this.ctx = ctx; 6 | this.app = ctx.app; 7 | } 8 | 9 | /** 10 | * http request helper base on {@link HttpClient}, it will auto save httpclient log. 11 | * Keep the same api with {@link Application#curl}. 12 | * 13 | * @param {String|Object} url - request url address. 14 | * @param {Object} [options] - options for request. 15 | * @return {Object} see {@link Application#curl} 16 | */ 17 | curl(url, options) { 18 | options = options || {}; 19 | options.ctx = this.ctx; 20 | return this.app.curl(url, options); 21 | } 22 | 23 | request(url, options) { 24 | return this.curl(url, options); 25 | } 26 | } 27 | 28 | module.exports = ContextHttpClient; 29 | -------------------------------------------------------------------------------- /test/fixtures/apps/aliyun-egg/lib/aliyun-egg.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const egg = require('../../../../..'); 5 | const Application = egg.Application; 6 | const AppWorkerLoader = egg.AppWorkerLoader; 7 | 8 | class Loader extends AppWorkerLoader { 9 | 10 | constructor(options) { 11 | super(options); 12 | } 13 | 14 | loadConfig() { 15 | this.loadServerConf(); 16 | super.loadConfig(); 17 | } 18 | 19 | loadServerConf() {} 20 | } 21 | 22 | class ChairApplication extends Application { 23 | 24 | constructor(options) { 25 | super(options); 26 | } 27 | 28 | get [Symbol.for('egg#eggPath')]() { 29 | return path.join(__dirname, '..'); 30 | } 31 | 32 | get [Symbol.for('egg#loader')]() { 33 | return Loader; 34 | } 35 | } 36 | 37 | module.exports = ChairApplication; 38 | -------------------------------------------------------------------------------- /test/fixtures/apps/cluster_mod_app/app/controller/home.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.index = function*() { 4 | this.body = 'hi cluster'; 5 | }; 6 | 7 | exports.getClusterPort = function*() { 8 | this.body = this.app._options.clusterPort; 9 | }; 10 | 11 | exports.getHosts = function*() { 12 | this.body = this.app.val && this.app.val.map(url => url.host).join(','); 13 | }; 14 | 15 | exports.publish = function*() { 16 | const val = this.request.body.value; 17 | this.app.registryClient.publish({ 18 | dataId: 'demo.DemoService', 19 | publishData: `dubbo://${val}:20880/demo.DemoService?anyhost=true&application=demo-provider&dubbo=2.0.0&generic=false&interface=demo.DemoService&loadbalance=roundrobin&methods=sayHello&owner=william&pid=81281&side=provider×tamp=1481613276143`, 20 | }); 21 | this.body = 'ok'; 22 | }; 23 | -------------------------------------------------------------------------------- /test/lib/plugins/logrotator.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('assert'); 4 | 5 | const path = require('path'); 6 | const glob = require('glob'); 7 | const utils = require('../../utils'); 8 | 9 | describe('test/lib/plugins/logrotator.test.js', () => { 10 | let app; 11 | before(() => { 12 | app = utils.app('apps/logrotator-app'); 13 | return app.ready(); 14 | }); 15 | 16 | after(() => app.close()); 17 | 18 | it('should rotate log file default', function* () { 19 | const file = require.resolve('egg-logrotator/app/schedule/rotate_by_file.js'); 20 | yield app.runSchedule(file); 21 | const files = glob.sync(path.join(app.config.logger.dir, '*.log.*')); 22 | assert(files.length > 0); 23 | files.forEach(file => { 24 | assert(/\.log\.\d{4}-\d{2}-\d{2}$/.test(file)); 25 | }); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /test/doc.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const findlinks = require('findlinks'); 5 | const assert = require('assert'); 6 | const runscript = require('runscript'); 7 | const utils = require('./utils'); 8 | 9 | describe('test/doc.test.js', () => { 10 | 11 | if (process.platform === 'win32') return; 12 | 13 | let app; 14 | before(function* () { 15 | yield runscript('doctools build', { cwd: path.dirname(__dirname) }); 16 | }); 17 | before(function* () { 18 | app = utils.cluster({ 19 | baseDir: 'apps/docapp', 20 | }); 21 | app.coverage(false); 22 | yield app.ready(); 23 | }); 24 | after(() => app.close()); 25 | 26 | it('should no broken url', function* () { 27 | const result = yield findlinks({ src: app.url, logger: console }); 28 | assert(result.fail === 0); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /test/fixtures/apps/agent-app/plugins/mock-client/agent.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const MockClient = require('./mock_client'); 4 | 5 | module.exports = agent => { 6 | const done = agent.readyCallback('agent_configclient'); 7 | const options = agent.config.mock; 8 | 9 | agent.mockClient = new MockClient(); 10 | 11 | let count = 0; 12 | // 启动 agent 任务 13 | agent.startAgent({ 14 | client: agent.mockClient, 15 | name: 'mock', 16 | subscribe(info, listener) { 17 | agent.mockClient.on(info.id, listener); 18 | if (info.id === 'foo') { 19 | setInterval(() => { 20 | agent.mockClient.emit('foo', ++count); 21 | }, 100); 22 | } 23 | }, 24 | }); 25 | 26 | agent.mockClient.ready(() => { 27 | agent.logger.info('[agent] %s started mockClient', agent.config.name); 28 | done(); 29 | }); 30 | }; 31 | -------------------------------------------------------------------------------- /test/fixtures/apps/loader-plugin-dep/config/plugin.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | a: { 5 | enable: true, 6 | dependencies: ['b', 'f'], 7 | path: path.join(__dirname, '../plugins/a') 8 | }, 9 | 10 | b: { 11 | enable: true, 12 | path: path.join(__dirname, '../plugins/b') 13 | }, 14 | 15 | c1: { 16 | enable: true, 17 | dependencies: ['b'], 18 | path: path.join(__dirname, '../plugins/c') 19 | }, 20 | 21 | d: { 22 | enable: true, 23 | dependencies: ['a'], 24 | path: path.join(__dirname, '../plugins/d') 25 | }, 26 | 27 | e: { 28 | enable: true, 29 | dependencies: ['f'], 30 | path: path.join(__dirname, '../plugins/e') 31 | }, 32 | 33 | f: { 34 | enable: true, 35 | dependencies: ['c1'], 36 | path: path.join(__dirname, '../plugins/f') 37 | }, 38 | 39 | }; 40 | -------------------------------------------------------------------------------- /test/app/extend/agent.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('assert'); 4 | 5 | const mm = require('egg-mock'); 6 | const utils = require('../../utils'); 7 | 8 | describe('test/app/extend/agent.test.js', () => { 9 | afterEach(mm.restore); 10 | 11 | describe('agent.addSingleton()', () => { 12 | let app; 13 | before(() => { 14 | app = utils.app('apps/singleton-demo'); 15 | return app.ready(); 16 | }); 17 | after(() => app.close()); 18 | 19 | it('should add singleton success', function* () { 20 | let config = yield app.agent.dataService.get('second').getConfig(); 21 | assert(config.foo === 'bar'); 22 | assert(config.foo2 === 'bar2'); 23 | 24 | const ds = app.agent.dataService.createInstance({ foo: 'barrr' }); 25 | config = yield ds.getConfig(); 26 | assert(config.foo === 'barrr'); 27 | }); 28 | }); 29 | 30 | }); 31 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /lib/jsdoc/request.jsdoc: -------------------------------------------------------------------------------- 1 | /** 2 | * 继承 koa 的 Request 3 | * @class Request 4 | * @see http://koajs.com/#request 5 | */ 6 | 7 | 8 | // 文档注释 9 | /** 10 | * Request header 11 | * @member {Object} Request#header 12 | */ 13 | 14 | /** 15 | * Request headers 16 | * @member {Object} Request#headers 17 | */ 18 | 19 | /** 20 | * Request HTTP Method, 比如: GET, POST, PATCH, PUT, DELETE 21 | * @member {String} Request#method 22 | */ 23 | 24 | /** 25 | * 完整的请求 URL 地址 26 | * @member {String} Request#url 27 | */ 28 | 29 | /** 30 | * 完整的请求 URL 地址 31 | * @member {String} Request#originalUrl 32 | */ 33 | 34 | /** 35 | * 完整的请求 URL 地址,的路径部分(不包含域名) 36 | * @member {String} Request#path 37 | */ 38 | 39 | /** 40 | * 请求的 GET 参数 41 | * @member {String} Request#querystring 42 | * @example 43 | * GET http://127.0.0.1:7001?name=Foo&age=20 44 | * ```js 45 | * this.request.querystring 46 | * => 'name=Foo&age=20' 47 | * ``` 48 | */ 49 | -------------------------------------------------------------------------------- /test/fixtures/apps/messenger/agent.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(agent) { 4 | agent.messenger.on('egg-ready', () => { 5 | agent.messenger.on('app-to-agent', function(msg) { 6 | console.log('[agent] app-to-agent', msg); 7 | }); 8 | agent.messenger.on('agent-to-app', function(msg) { 9 | console.log('[agent] agent-to-app', msg); 10 | }); 11 | 12 | agent.messenger.on('pid', pid => { 13 | agent.messenger.sendTo(pid, 'agent-to-app', 'agent msg ' + pid); 14 | }); 15 | agent.messenger.on('ready', () => { 16 | agent.messenger.send('agent-to-app', 'agent msg'); 17 | }); 18 | }); 19 | 20 | // it'll warn 21 | agent.messenger.sendTo(12345, 'warn-message'); 22 | agent.messenger.sendToApp('warn-message'); 23 | agent.messenger.sendToAgent('warn-message'); 24 | agent.messenger.sendRandom('warn-message'); 25 | agent.messenger.broadcast('warn-message'); 26 | }; 27 | -------------------------------------------------------------------------------- /app/middleware/site_file.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const MAX_AGE = 'public, max-age=2592000'; // 30 days 5 | 6 | module.exports = options => { 7 | return function* siteFile(next) { 8 | if (this.method !== 'HEAD' && this.method !== 'GET') return yield next; 9 | /* istanbul ignore if */ 10 | if (this.path[0] !== '/') return yield next; 11 | 12 | const content = options[this.path]; 13 | if (!content) return yield next; 14 | 15 | // '/favicon.ico': 'https://eggjs.org/favicon.ico', 16 | // content is url 17 | if (typeof content === 'string') return this.redirect(content); 18 | 19 | // '/robots.txt': Buffer { 11 | return class AsyncController extends app.Controller { 12 | index() { 13 | const ctx = this.ctx; 14 | return __awaiter(this, void 0, void 0, function* () { 15 | yield ctx.render('index.html', {name: 'mk・2'}); 16 | }); 17 | } 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /app/middleware/notfound.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = options => { 4 | return function* notfound(next) { 5 | yield next; 6 | 7 | if (this.status !== 404 || this.body) { 8 | return; 9 | } 10 | 11 | // set status first, make sure set body not set status 12 | this.status = 404; 13 | 14 | if (this.acceptJSON) { 15 | this.body = { 16 | message: 'Not Found', 17 | }; 18 | return; 19 | } 20 | 21 | const notFoundHtml = '

    404 Not Found

    '; 22 | 23 | // notfound handler is unimplemented 24 | if (options.pageUrl && this.path === options.pageUrl) { 25 | this.body = `${notFoundHtml}

    config.notfound.pageUrl(${options.pageUrl})
    is unimplemented

    `; 26 | return; 27 | } 28 | 29 | if (options.pageUrl) { 30 | this.realStatus = 404; 31 | this.redirect(options.pageUrl); 32 | return; 33 | } 34 | this.body = notFoundHtml; 35 | }; 36 | }; 37 | -------------------------------------------------------------------------------- /test/lib/cluster/cluster-client-error.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | const path = require('path'); 5 | const assert = require('assert'); 6 | const sleep = require('mz-modules/sleep'); 7 | const utils = require('../../utils'); 8 | 9 | describe('test/lib/cluster/cluster-client-error.test.js', () => { 10 | let app; 11 | before(function* () { 12 | app = utils.app('apps/cluster-client-error'); 13 | 14 | let err; 15 | try { 16 | yield app.ready(); 17 | } catch (e) { 18 | err = e; 19 | } 20 | assert(err); 21 | }); 22 | 23 | it('should close even if app throw error', () => { 24 | return app.close(); 25 | }); 26 | 27 | it('should follower not throw error', function* () { 28 | yield sleep(1000); 29 | const cnt = fs.readFileSync(path.join(__dirname, '../../fixtures/apps/cluster-client-error/logs/cluster-client-error/common-error.log'), 'utf8'); 30 | assert(!cnt.includes('ECONNRESET')); 31 | }); 32 | 33 | }); 34 | -------------------------------------------------------------------------------- /test/lib/core/context_httpclient.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('assert'); 4 | const utils = require('../../utils'); 5 | 6 | describe('test/lib/core/context_httpclient.test.js', () => { 7 | let url; 8 | let app; 9 | 10 | before(() => { 11 | app = utils.app('apps/context_httpclient'); 12 | return app.ready(); 13 | }); 14 | before(function* () { 15 | url = yield utils.startLocalServer(); 16 | }); 17 | 18 | it('should send request with ctx.httpclient', function* () { 19 | const ctx = app.mockContext(); 20 | const httpclient = ctx.httpclient; 21 | assert(ctx.httpclient === httpclient); 22 | assert(httpclient.ctx === ctx); 23 | assert(typeof httpclient.request === 'function'); 24 | assert(typeof httpclient.curl === 'function'); 25 | const result = yield ctx.httpclient.request(url); 26 | assert(result.status === 200); 27 | const result2 = yield ctx.httpclient.curl(url); 28 | assert(result2.status === 200); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /test/fixtures/apps/agent-client-app/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(app) { 4 | const done = app.readyCallback('app_subscribe_data'); 5 | app.subClient.subscribe('mock-data', val => { 6 | app.mockData = val; 7 | done(); 8 | }); 9 | 10 | const done1 = app.readyCallback('app_subscribe_not_exist_data'); 11 | app.subClient.subscribe('not-exist-data', val => { 12 | app.notExistData = val; 13 | done1(); 14 | }); 15 | 16 | app.get('/', function*() { 17 | const val = yield cb => app.subClient.subscribe('mock-data', val => { 18 | cb(null, val); 19 | }); 20 | 21 | this.body = { 22 | 'mock-data': val, 23 | 'app-mock-data': app.mockData, 24 | }; 25 | }); 26 | 27 | app.get('/not-exist', function*() { 28 | const val = yield cb => app.subClient.subscribe('not-exist-data', val => { 29 | cb(null, val); 30 | }); 31 | 32 | this.body = { 33 | 'not-exist-data': null, 34 | 'app-not-exist-data': null, 35 | }; 36 | }); 37 | }; 38 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 18 | 19 | * **Node Version**: 20 | * **Egg Version**: 21 | * **Plugin Name**: 22 | * **Plugin Version**: 23 | * **Platform**: 24 | * **Mini Showcase Repository**: 25 | 26 | 27 | -------------------------------------------------------------------------------- /lib/jsdoc/context.jsdoc: -------------------------------------------------------------------------------- 1 | /** 2 | * 继承 koa 的 Context 3 | * @class Context 4 | * @see http://koajs.com/#context 5 | */ 6 | 7 | /** 8 | * 实现页面跳转 9 | * @see Response#redirect 10 | * @method Context#redirect 11 | * @param {String} url 需要跳转的地址 12 | */ 13 | 14 | /** 15 | * 开启 {@link Rest} 功能后,将会有 `this.params` 对象 16 | * @member {Object} Context#params 17 | * @example 18 | * ##### ctx.params.id {String} 19 | * 20 | * 资源 id,如 `GET /api/users/1` => `'1'` 21 | * 22 | * ##### ctx.params.ids {Array} 23 | * 24 | * 一组资源 id,如 `GET /api/users/1,2,3` => `['1', '2', '3']` 25 | * 26 | * ##### ctx.params.fields {Array} 27 | * 28 | * 期待返回的资源字段,如 `GET /api/users/1?fields=name,title` => `['name', 'title']`. 29 | * 即使应用 Controller 实现返回了全部字段,[REST] 处理器会根据 `fields` 筛选只需要的字段。 30 | * 31 | * ##### ctx.params.data {Object} 32 | * 33 | * 请求数据对象 34 | * 35 | * ##### ctx.params.page {Number} 36 | * 37 | * 分页码,如 `GET /api/users?page=10` => `10` 38 | * 39 | * ##### ctx.params.per_page {Number} 40 | * 41 | * 每页资源数目,如 `GET /api/users?per_page=20` => `20` 42 | */ 43 | -------------------------------------------------------------------------------- /test/lib/plugins/schedule.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('assert'); 4 | const path = require('path'); 5 | const fs = require('fs'); 6 | const sleep = require('mz-modules/sleep'); 7 | const utils = require('../../utils'); 8 | 9 | describe('test/lib/plugins/schedule.test.js', () => { 10 | it('should schedule work', function* () { 11 | const app = utils.cluster('apps/schedule', { 12 | workers: 2, 13 | }); 14 | app.debug(); 15 | app.coverage(false); 16 | yield app.ready(); 17 | yield sleep(7000); 18 | yield app.close(); 19 | const log = getLogContent('schedule'); 20 | const count = contains(log, 'cron'); 21 | assert(count >= 1); 22 | assert(count <= 2); 23 | }); 24 | }); 25 | 26 | function getLogContent(name) { 27 | const logPath = path.join(__dirname, '../../fixtures/apps', name, 'logs', name, `${name}-web.log`); 28 | return fs.readFileSync(logPath, 'utf8'); 29 | } 30 | 31 | function contains(content, match) { 32 | return content.split('\n').filter(line => line.indexOf(match) >= 0).length; 33 | } 34 | -------------------------------------------------------------------------------- /test/fixtures/apps/app-throw/app/router.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = app => { 4 | app.get('/throw', function* () { 5 | this.body = 'foo'; 6 | setTimeout(() => { 7 | a.b = c; 8 | }, 1); 9 | }); 10 | 11 | app.get('/throw-unhandledRejection', function* () { 12 | this.body = 'foo'; 13 | new Promise((resolve, reject) => { 14 | reject(new Error('foo reject error')); 15 | }); 16 | }); 17 | 18 | app.get('/throw-unhandledRejection-string', function* () { 19 | this.body = 'foo'; 20 | new Promise((resolve, reject) => { 21 | reject('foo reject string error'); 22 | }); 23 | }); 24 | 25 | app.get('/throw-unhandledRejection-obj', function* () { 26 | this.body = 'foo'; 27 | new Promise((resolve, reject) => { 28 | const err = { 29 | name: 'TypeError', 30 | message: 'foo reject obj error', 31 | stack: new Error().stack, 32 | toString() { 33 | return this.name + ': ' + this.message; 34 | }, 35 | }; 36 | reject(err); 37 | }); 38 | }); 39 | }; 40 | -------------------------------------------------------------------------------- /lib/loader/app_worker_loader.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const EggLoader = require('egg-core').EggLoader; 4 | 5 | /** 6 | * App worker process Loader, will load plugins 7 | * @see https://github.com/eggjs/egg-loader 8 | */ 9 | class AppWorkerLoader extends EggLoader { 10 | 11 | /** 12 | * loadPlugin first, then loadConfig 13 | * @since 1.0.0 14 | */ 15 | loadConfig() { 16 | this.loadPlugin(); 17 | super.loadConfig(); 18 | } 19 | 20 | /** 21 | * 开始加载所有约定目录 22 | * @since 1.0.0 23 | */ 24 | load() { 25 | // app > plugin > core 26 | this.loadApplicationExtend(); 27 | this.loadRequestExtend(); 28 | this.loadResponseExtend(); 29 | this.loadContextExtend(); 30 | this.loadHelperExtend(); 31 | 32 | // app > plugin 33 | this.loadCustomApp(); 34 | // app > plugin 35 | this.loadService(); 36 | // app > plugin > core 37 | this.loadMiddleware(); 38 | // app 39 | this.loadController(); 40 | // app 41 | this.loadRouter(); // 依赖 controller 42 | } 43 | 44 | } 45 | 46 | module.exports = AppWorkerLoader; 47 | -------------------------------------------------------------------------------- /test/fixtures/apps/tracer-demo/tracer.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const uuid = require('uuid'); 4 | 5 | module.exports = app => { 6 | app.httpclient.on('request', req => { 7 | if (!req.ctx) { 8 | // auto set anonymous context 9 | req.ctx = req.args.ctx = app.createAnonymousContext(); 10 | req.ctx.traceId = 'anonymous-' + uuid.v1(); 11 | } 12 | // set tracer id 13 | if (!req.ctx.traceId) { 14 | req.ctx.traceId = uuid.v1(); 15 | } 16 | req.starttime = Date.now(); 17 | req.args.headers = req.args.headers || {}; 18 | req.args.headers['x-request-id'] = req.ctx.traceId; 19 | req.args.method = req.args.method || 'GET'; 20 | app.logger.info('[httpclient] [%s] %s %s start', 21 | req.ctx.traceId, req.args.method, req.url); 22 | }); 23 | 24 | app.httpclient.on('response', response => { 25 | const req = response.req; 26 | const res = response.res; 27 | app.logger.info('[httpclient] [%s] %s %s end, status: %s, use: %s', 28 | req.ctx.traceId, req.args.method, req.url, 29 | res.status, Date.now() - req.starttime); 30 | }); 31 | }; 32 | -------------------------------------------------------------------------------- /test/fixtures/apps/secure-app/app/controller/index.js: -------------------------------------------------------------------------------- 1 | exports.home = function*() { 2 | if (this.query.cookiedel) { 3 | if (!this.query.opts) { 4 | this.cookies.set('cookiedel', null); 5 | } else { 6 | const options = { 7 | path: '/hello', 8 | domain: 'eggjs.org', 9 | }; 10 | this.cookies.set('cookiedel', null, options); 11 | } 12 | } 13 | if (this.query.setCookieValue) { 14 | this.cookies.set('foo-cookie', this.query.setCookieValue); 15 | } 16 | 17 | if (this.query.hasOwnProperty('cookiepath')) { 18 | const opts = { 19 | path: this.query.cookiepath, 20 | }; 21 | if (this.query.cookiedomain) { 22 | opts.domain = this.query.cookiedomain; 23 | } 24 | this.cookies.set('cookiepath', this.query.cookiepath, opts); 25 | } 26 | if (this.query.notSetPath) { 27 | this.cookies.set('notSetPath', this.query.notSetPath, { 28 | path: null, 29 | domain: null, 30 | }); 31 | } 32 | this.body = 'hello mock secure app'; 33 | }; 34 | 35 | exports.getUser = function*() { 36 | this.body = { name: 'fengmk2' }; 37 | }; 38 | -------------------------------------------------------------------------------- /test/ts/index.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const request = require('supertest'); 4 | const mm = require('egg-mock'); 5 | const runscript = require('runscript'); 6 | const path = require('path'); 7 | const utils = require('../utils'); 8 | const baseDir = path.join(__dirname, '../fixtures/apps/app-ts'); 9 | 10 | describe('test/ts/index.test.js', () => { 11 | before(function* () { 12 | if (process.env.CI) { 13 | yield runscript('tsc && npmlink ../../../../', { cwd: baseDir }); 14 | } else { 15 | yield runscript('tsc && npm link ../../../../', { cwd: baseDir }); 16 | } 17 | }); 18 | 19 | describe('compiler code', () => { 20 | 21 | afterEach(mm.restore); 22 | let app; 23 | before(function* () { 24 | app = utils.app('apps/app-ts'); 25 | yield app.ready(); 26 | }); 27 | after(function* () { 28 | yield app.close(); 29 | }); 30 | 31 | it('controller run ok', done => { 32 | request(app.callback()) 33 | .get('/foo') 34 | .expect(200) 35 | .expect({ env: 'unittest' }) 36 | .end(done); 37 | }); 38 | }); 39 | 40 | }); 41 | 42 | -------------------------------------------------------------------------------- /scripts/doc_travis.sh: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | 3 | # https://gist.github.com/domenic/ec8b0fc8ab45f39403dd#sign-up-for-travis-and-add-your-project 4 | 5 | # Only deply on master branch 6 | SOURCE_BRANCH="master" 7 | 8 | # Pull requests and commits to other branches shouldn't try to deploy, just build to verify 9 | if [ "$TRAVIS_PULL_REQUEST" != "false" -o "$TRAVIS_BRANCH" != "$SOURCE_BRANCH" -o "$TRAVIS_EVENT_TYPE" = "cron" ]; then 10 | echo "Skip deploy, TRAVIS_PULL_REQUEST=$TRAVIS_PULL_REQUEST, TRAVIS_BRANCH=$TRAVIS_BRANCH" 11 | exit 0 12 | fi 13 | 14 | # Get the deploy key by using Travis's stored variables to decrypt deploy_key.enc 15 | ENCRYPTED_KEY_VAR="encrypted_${ENCRYPTION_LABEL}_key" 16 | ENCRYPTED_IV_VAR="encrypted_${ENCRYPTION_LABEL}_iv" 17 | ENCRYPTED_KEY=${!ENCRYPTED_KEY_VAR} 18 | ENCRYPTED_IV=${!ENCRYPTED_IV_VAR} 19 | # echo "key: $ENCRYPTED_KEY, iv: $ENCRYPTED_IV" 20 | openssl aes-256-cbc -K $ENCRYPTED_KEY -iv $ENCRYPTED_IV -in scripts/deploy_key.enc -out deploy_key -d 21 | chmod 600 deploy_key 22 | eval `ssh-agent -s` 23 | ssh-add deploy_key 24 | 25 | npm run doc-deploy 26 | echo 'Done.' 27 | 28 | # kill ssh-agent 29 | ssh-agent -k 30 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 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 | -------------------------------------------------------------------------------- /test/lib/core/httpclient_tracer_demo.test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('assert'); 4 | const utils = require('../../utils'); 5 | 6 | describe('test/lib/core/httpclient_tracer_demo.test.js', () => { 7 | let url; 8 | let app; 9 | 10 | before(() => { 11 | app = utils.app('apps/tracer-demo'); 12 | return app.ready(); 13 | }); 14 | before(function* () { 15 | url = yield utils.startLocalServer(); 16 | }); 17 | 18 | after(() => app.close()); 19 | 20 | it('should send request with ctx.httpclient', function* () { 21 | const r = yield app.curl(url + '/get_headers', { 22 | dataType: 'json', 23 | }); 24 | assert(r.status === 200); 25 | assert(r.data['x-request-id'].startsWith('anonymous-')); 26 | }); 27 | 28 | it('should work with context httpclient', () => { 29 | return app.httpRequest() 30 | .get('/?url=' + encodeURIComponent(url + '/get_headers')) 31 | .expect(res => { 32 | assert(res.body.url === url + '/get_headers'); 33 | assert(res.body.data['x-request-id']); 34 | assert(!res.body.data['x-request-id'].startsWith('anonymous-')); 35 | }) 36 | .expect(200); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /test/fixtures/apps/helper/app/router.js: -------------------------------------------------------------------------------- 1 | module.exports = app => { 2 | app.get('home', '/home', 'home'); 3 | 4 | app.get('/pathFor', function* () { 5 | this.body = this.helper.pathFor('home', this.query); 6 | }); 7 | 8 | app.get('/urlFor', function* () { 9 | this.body = this.helper.urlFor('home', this.query); 10 | }); 11 | 12 | app.get('/escape', function* () { 13 | this.body = this.helper.escape('