Skip to content

Commit

Permalink
Merge pull request #1 from daruk-framework/developer
Browse files Browse the repository at this point in the history
up to date
  • Loading branch information
KenyeeC authored May 10, 2019
2 parents 1a092c0 + 56b89ea commit f2e576e
Show file tree
Hide file tree
Showing 33 changed files with 405 additions and 52 deletions.
20 changes: 20 additions & 0 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,26 @@
"code",
"test"
]
},
{
"login": "Himself65",
"name": "扩散性百万甜面包",
"avatar_url": "https://avatars0.githubusercontent.com/u/14026360?v=4",
"profile": "https://www.himself65.com",
"contributions": [
"test",
"code"
]
},
{
"login": "myluluy",
"name": "arck.liu",
"avatar_url": "https://avatars2.githubusercontent.com/u/4242799?v=4",
"profile": "https://github.com/myluluy",
"contributions": [
"code",
"doc"
]
}
],
"contributorsPerLine": 7
Expand Down
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
"tslint.autoFixOnSave": true,
"workbench.iconTheme": "vscode-icons",
"editor.formatOnSave": true,
"javascript.implicitProjectConfig.experimentalDecorators": true
"javascript.implicitProjectConfig.experimentalDecorators": true,
"git.ignoreLimitWarning": true
}
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
![GitHub top language](https://img.shields.io/github/languages/top/daruk-framework/daruk.svg)
![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/daruk-framework/daruk.svg)
[![Package Quality](https://npm.packagequality.com/shield/daruk.svg)](https://packagequality.com/#?package=daruk)
[![All Contributors](https://img.shields.io/badge/all_contributors-3-orange.svg?style=flat-square)](#contributors)
[![All Contributors](https://img.shields.io/badge/all_contributors-5-orange.svg?style=flat-square)](#contributors)
![GitHub last commit (branch)](https://img.shields.io/github/last-commit/daruk-framework/daruk/master.svg)
[![Gitter](https://badges.gitter.im/daruk_framework/community.svg)](https://gitter.im/daruk_framework/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
[![start with why](https://img.shields.io/badge/start%20with-why%3F-brightgreen.svg?style=flat)](https://v.youku.com/v_show/id_XNDExMjA5MTI2NA==.html?spm=a2hzp.8244740.0.0)
Expand Down Expand Up @@ -69,7 +69,7 @@ const myApp = new Daruk('darukProject', {
debug: process.env.NODE_ENV === 'dev'
});

myApp.run(port);
myApp.listen(port);
```

`controllers/index.ts`:
Expand Down Expand Up @@ -122,7 +122,7 @@ Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/d

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore -->
<table><tr><td align="center"><a href="http://www.tuer.me"><img src="https://avatars3.githubusercontent.com/u/289225?v=4" width="40px;" alt="xiaojue"/><br /><sub><b>xiaojue</b></sub></a><br /><a href="https://github.com/daruk-framework/daruk/commits?author=xiaojue" title="Code">💻</a> <a href="#design-xiaojue" title="Design">🎨</a></td><td align="center"><a href="https://github.com/Youjingyu"><img src="https://avatars3.githubusercontent.com/u/15033260?v=4" width="40px;" alt="whale"/><br /><sub><b>whale</b></sub></a><br /><a href="https://github.com/daruk-framework/daruk/commits?author=Youjingyu" title="Code">💻</a> <a href="https://github.com/daruk-framework/daruk/commits?author=Youjingyu" title="Tests">⚠️</a></td><td align="center"><a href="https://github.com/dxil"><img src="https://avatars1.githubusercontent.com/u/17681925?v=4" width="40px;" alt="cuzz"/><br /><sub><b>cuzz</b></sub></a><br /><a href="https://github.com/daruk-framework/daruk/commits?author=dxil" title="Code">💻</a> <a href="https://github.com/daruk-framework/daruk/commits?author=dxil" title="Tests">⚠️</a></td></tr></table>
<table><tr><td align="center"><a href="http://www.tuer.me"><img src="https://avatars3.githubusercontent.com/u/289225?v=4" width="40px;" alt="xiaojue"/><br /><sub><b>xiaojue</b></sub></a><br /><a href="https://github.com/daruk-framework/daruk/commits?author=xiaojue" title="Code">💻</a> <a href="#design-xiaojue" title="Design">🎨</a></td><td align="center"><a href="https://github.com/Youjingyu"><img src="https://avatars3.githubusercontent.com/u/15033260?v=4" width="40px;" alt="whale"/><br /><sub><b>whale</b></sub></a><br /><a href="https://github.com/daruk-framework/daruk/commits?author=Youjingyu" title="Code">💻</a> <a href="https://github.com/daruk-framework/daruk/commits?author=Youjingyu" title="Tests">⚠️</a></td><td align="center"><a href="https://github.com/dxil"><img src="https://avatars1.githubusercontent.com/u/17681925?v=4" width="40px;" alt="cuzz"/><br /><sub><b>cuzz</b></sub></a><br /><a href="https://github.com/daruk-framework/daruk/commits?author=dxil" title="Code">💻</a> <a href="https://github.com/daruk-framework/daruk/commits?author=dxil" title="Tests">⚠️</a></td><td align="center"><a href="https://www.himself65.com"><img src="https://avatars0.githubusercontent.com/u/14026360?v=4" width="40px;" alt="扩散性百万甜面包"/><br /><sub><b>扩散性百万甜面包</b></sub></a><br /><a href="https://github.com/daruk-framework/daruk/commits?author=Himself65" title="Tests">⚠️</a> <a href="https://github.com/daruk-framework/daruk/commits?author=Himself65" title="Code">💻</a></td><td align="center"><a href="https://github.com/myluluy"><img src="https://avatars2.githubusercontent.com/u/4242799?v=4" width="40px;" alt="arck.liu"/><br /><sub><b>arck.liu</b></sub></a><br /><a href="https://github.com/daruk-framework/daruk/commits?author=myluluy" title="Code">💻</a> <a href="https://github.com/daruk-framework/daruk/commits?author=myluluy" title="Documentation">📖</a></td></tr></table>

<!-- ALL-CONTRIBUTORS-LIST:END -->

Expand Down
3 changes: 1 addition & 2 deletions example/01-helloWorld/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@ import { Daruk } from 'daruk';

const myApp = new Daruk('myapp', { rootPath: __dirname, debug: process.env.NODE_ENV === 'dev' });
const port = 3000;

myApp.run(port);
myApp.listen(port);
2 changes: 2 additions & 0 deletions example/07-graphql/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
yarn.lock
8 changes: 8 additions & 0 deletions example/07-graphql/controllers/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { BaseController, Context, get } from 'daruk';

export default class Index extends BaseController {
@get('/')
public index(ctx: Context, next: Function) {
ctx.body = 'hello world';
}
}
8 changes: 8 additions & 0 deletions example/07-graphql/graphQL/resolvers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Provide resolver functions for your schema fields
const resolvers = {
Query: {
hello: () => 'Hello world!'
}
};

export { resolvers };
9 changes: 9 additions & 0 deletions example/07-graphql/graphQL/typeDefs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { gql } from 'apollo-server-koa';
// Construct a schema, using GraphQL schema language
const typeDefs = gql`
type Query {
hello: String
}
`;

export { typeDefs };
15 changes: 15 additions & 0 deletions example/07-graphql/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ApolloServer } from 'apollo-server-koa';
import { Daruk } from 'daruk';
import { resolvers } from './graphQL/resolvers';
import { typeDefs } from './graphQL/typeDefs';

const server = new ApolloServer({ typeDefs, resolvers });

const myApp = new Daruk('myapp', { rootPath: __dirname, debug: process.env.NODE_ENV === 'dev' });

server.applyMiddleware({ app: myApp });

const port = 3000;
myApp.listen(port, () => {
myApp.logger.info(`🚀 Server ready at http://localhost:${port}${server.graphqlPath}`);
});
21 changes: 21 additions & 0 deletions example/07-graphql/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "01-graphql",
"version": "1.0.0",
"description": "daruk graphql",
"main": "index.js",
"scripts": {
"dev": "cross-env TS_NODE_FILES=true NODE_ENV=dev ts-node index.ts",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "xiaojue",
"license": "MIT",
"devDependencies": {
"cross-env": "^5.2.0",
"ts-node": "^8.1.0"
},
"dependencies": {
"apollo-server-koa": "^2.5.0",
"daruk": "file:./../../",
"graphql": "^14.3.0"
}
}
62 changes: 62 additions & 0 deletions example/07-graphql/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
{
"compileOnSave": true,
"compilerOptions": {
/* Basic Options */
"target": "es2017" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */,
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */,
// "lib": [], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
// "declaration": true, /* Generates corresponding '.d.ts' file. */
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
"sourceMap": true /* Generates corresponding '.map' file. */,
// "outFile": "./", /* Concatenate and emit output to single file. */
"outDir": "./build" /* Redirect output structure to the directory. */,
"rootDir": "./" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
// "composite": true, /* Enable project compilation */
"removeComments": true /* Do not emit comments to output. */,
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */

/* Strict Type-Checking Options */
//"strict": true, /* Enable all strict type-checking options. */
"noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */,
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */

/* Additional Checks */
// "noUnusedLocals": true, /* Report errors on unused locals. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */

/* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
//"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */

/* Source Map Options */
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */

/* Experimental Options */
"experimentalDecorators": true /* Enables experimental support for ES7 decorators. */,
"emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */
},
"exclude": ["node_modules", "dist"],
"include": ["./types/*.ts"]
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "daruk",
"version": "0.4.0",
"version": "0.5.33",
"description": "a node.js web framework",
"main": "build/index.js",
"scripts": {
Expand All @@ -10,7 +10,7 @@
"cov": "nyc report --reporter=text-lcov > coverage.lcov && codecov",
"test": "cross-env TS_NODE_FILES=true nyc --cache mocha --timeout 15000 --exit ./test/{,/**/}*.test.ts",
"tslint": "tslint --project . ./src/**/*.ts",
"publish": "npm run build && cnpm publish"
"prepublish": "npm run build"
},
"types": "./types/index.d.ts",
"repository": {
Expand Down
78 changes: 65 additions & 13 deletions src/core/daruk_core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Https = require('https');
import is = require('is');
import Koa = require('koa');
import Router = require('koa-router');
import { ListenOptions } from 'net';
import deepAssign = require('object-assign-deep');
import path = require('path');
import { Options, PartialOptions } from '../../types/daruk_options';
Expand Down Expand Up @@ -45,11 +46,10 @@ class DarukCore extends Koa {
// 覆写 koa 的 createContext 方法声明
public createContext: (req: any, res: any) => Daruk.Context;
public initEnv: () => void;

/**
* @desc 构造函数
* @param string name - app 名字,会用于日志输出、邮件报警等
* @param PartialOptions options - 项目配置
* @param {string} name - app 名字,会用于日志输出、邮件报警等
* @param {PartialOptions} options - 项目配置
*/
public constructor(name: string, options: PartialOptions) {
super();
Expand Down Expand Up @@ -173,7 +173,7 @@ class DarukCore extends Koa {
}
/**
* @desc 模拟 ctx,从而可以从非请求链路中得到 ctx
* @param Object req - 配置模拟请求的 headers、query、url 等
* @param {Object, undefined} req - 配置模拟请求的 headers、query、url 等
* @return Daruk.Context
*/
public mockContext(req?: {}) {
Expand All @@ -187,23 +187,64 @@ class DarukCore extends Koa {
/**
* @desc 启动服务
*/
public listen(...args: any[]): Http.Server {
// https://github.com/nodejs/node/blob/master/lib/net.js#L182
let arr: any;
let options: {
path?: string;
port?: number;
host?: string;
} = {};

const _cb = args[args.length - 1];
const cb = (...arg1: any) => {
this.serverReady(this.httpServer);
if (typeof _cb === 'function') _cb(...arg1);
this.prettyLog(
`${this.name} is starting at http://${options.host ? options.host : 'localhost'}:${
options.port
}`
);
};
const normalizedArgsSymbol: any = Symbol('normalizedArgs');

if (args.length === 0) {
arr = [{}, null];
arr[normalizedArgsSymbol] = true;
} else {
const arg0 = args[0];
if (typeof arg0 === 'object' && arg0 !== null) {
// (options[...][, cb])
options = arg0;
} else if (this.isPipeName(arg0)) {
// (path[...][, cb])
options.path = arg0;
} else {
// ([port][, host][...][, cb])
options.port = arg0;
if (args.length > 1 && typeof args[1] === 'string') {
options.host = args[1];
}
}
if (typeof _cb === 'function') {
args[args.length - 1] = cb;
} else {
args.push(cb);
}
}
this.httpServer = super.listen(...args);
return this.httpServer;
}
public run(port: number, host?: string | Function, cb?: Function) {
let _cb: any = cb;
let _host: any = host;
if (is.fn(host)) {
_cb = host;
_host = undefined;
}

const httpServer = this.listen(port, _host, () => {
this.serverReady(httpServer);
if (_cb) _cb();
this.prettyLog(`${this.name} is starting at http://${_host ? _host : 'localhost'}:${port}`);
});
// 保证在同步代码中也能访问到 server 实例
this.httpServer = httpServer;
return httpServer;
return this.listen(port, _host, _cb);
}

/**
* @desc 服务启动后的需要完成的剩余工作
* 如果用户不使用 run 方法启动,而是自定义启动(比如启动 https 服务)
Expand Down Expand Up @@ -240,6 +281,17 @@ class DarukCore extends Koa {
}
});
}

// https://github.com/nodejs/node/blob/master/lib/net.js#L1117
private toNumber(x: any) {
// tslint:disable-next-line:no-conditional-assignment
return Number(x) >= 0;
}

// https://github.com/nodejs/node/blob/master/lib/net.js#L137
private isPipeName(s: any) {
return typeof s === 'string' && this.toNumber(s) === false;
}
}

export default DarukCore;
22 changes: 19 additions & 3 deletions src/core/daruk_init_module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ import path = require('path');
import 'reflect-metadata';
import { join as ujoin } from 'upath';
import { Options } from '../../types/daruk_options';
import { CONTROLLER_FUNC_NAME, CONTROLLER_PATH, MIDDLEWARE_NAME } from '../decorators/constants';
import {
CONTROLLER_CLASS_PREFIX,
CONTROLLER_FUNC_NAME,
CONTROLLER_PATH,
CONTROLLER_REDIRECT_PATH,
MIDDLEWARE_NAME
} from '../decorators/constants';
import { Daruk } from '../typings/daruk';
import { filterBuiltInModule } from '../utils';
import Events from './daruk_event';
Expand Down Expand Up @@ -170,13 +176,19 @@ export default class DarukInitModule {
const ControllerClass = controllers[prefixPath];
// 获取类中定义了路由的方法名
const routeFuncs = Reflect.getMetadata(CONTROLLER_FUNC_NAME, ControllerClass) || [];

// 保存装饰器提供的路由信息
const prefix = Reflect.getMetadata(CONTROLLER_CLASS_PREFIX, ControllerClass) || '';
routeFuncs.forEach(function defineRoute(funcName: string) {
// 获取装饰器注入的路由信息
const { method, path } = Reflect.getMetadata(CONTROLLER_PATH, ControllerClass, funcName);
// 重定向信息
const redirectPath =
Reflect.getMetadata(CONTROLLER_REDIRECT_PATH, ControllerClass, funcName) || '';
// 避免解析出的路由没有 / 前缀
// 并保证前后都有 /,方便后续比对路由 key
const routePath = ujoin('/', prefixPath, path, '/');
let routePath = ujoin('/', prefixPath);
// 不转path,因为可能会把通配符转成unix path
routePath = join('/', prefix, routePath, path, '/');
// 将路由按照 http method 分组
routeMap[method] = routeMap[method] || [];
// 判断路由是否重复定义
Expand Down Expand Up @@ -219,6 +231,10 @@ export default class DarukInitModule {
controllerInstance._destroy();
}
controllerInstance = null;
// 增加重定向:
if (redirectPath) {
ctx.redirect(redirectPath);
}
});
});
});
Expand Down
2 changes: 2 additions & 0 deletions src/decorators/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ export const CONTROLLER_PREFIX_PATH = 'daruk:controller_prefix_path';
export const CONTROLLER_PATH = 'daruk:controller_path';
export const CONTROLLER_FUNC_NAME = 'daruk:controller_func_name';
export const MIDDLEWARE_NAME = 'daruk:middleware_name';
export const CONTROLLER_CLASS_PREFIX = 'daruk:controller_class_prefix';
export const CONTROLLER_REDIRECT_PATH = 'daruk:controller_redirect_path';
Loading

0 comments on commit f2e576e

Please sign in to comment.