typespeed 2.4.11 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/typespeed.ts CHANGED
@@ -2,6 +2,7 @@ import "reflect-metadata";
2
2
  import * as fs from "fs";
3
3
  import * as path from "path";
4
4
  import * as walkSync from "walk-sync";
5
+ import { isStd, getStdArgs } from "./decorator-utils";
5
6
 
6
7
  let globalConfig = {};
7
8
  const corePath = __dirname;
@@ -18,7 +19,18 @@ if (fs.existsSync(configFile)) {
18
19
  globalConfig["MAIN_PATH"] = mainPath;
19
20
  globalConfig["CORE_PATH"] = corePath;
20
21
 
21
- function app<T extends { new(...args: any[]): {} }>(constructor: T) {
22
+ function app(...args: any[]): any {
23
+ if (isStd(args)) {
24
+ const [, ctx] = getStdArgs(args);
25
+ ctx.addInitializer(function (this: any) {
26
+ startApp(this.constructor);
27
+ });
28
+ return;
29
+ }
30
+ startApp(args[0]);
31
+ }
32
+
33
+ function startApp(constructor: any) {
22
34
  const coreFiles = walkSync(corePath, { globs: ['**/*.ts'], ignore: ['**/*.d.ts', 'scaffold/**'] });
23
35
  const mainFiles = walkSync(mainPath, { globs: ['**/*.ts'] });
24
36
 
@@ -47,7 +59,23 @@ function config(node: string) {
47
59
  }
48
60
 
49
61
  function value(configPath: string): any {
50
- return function (target: any, propertyKey: string) {
62
+ return function (...args: any[]): any {
63
+ if (isStd(args)) {
64
+ // 标准 field 装饰器:返回 initializer 注入配置值(标准模式下无 design:type)。
65
+ return (initialValue: any) => {
66
+ if (globalConfig === undefined) {
67
+ return initialValue;
68
+ }
69
+ let pathNodes = configPath.split(".");
70
+ let nodeValue = globalConfig;
71
+ for (let i = 0; i < pathNodes.length; i++) {
72
+ nodeValue = nodeValue[pathNodes[i]];
73
+ }
74
+ return nodeValue === undefined ? initialValue : nodeValue;
75
+ };
76
+ }
77
+ const target = args[0];
78
+ const propertyKey = args[1] as string;
51
79
  if (globalConfig === undefined) {
52
80
  Object.defineProperty(target, propertyKey, {
53
81
  get: () => {
@@ -94,6 +122,7 @@ export { app, value, config };
94
122
  export * from "./core.decorator";
95
123
  export * from "./route.decorator";
96
124
  export * from "./database.decorator";
125
+ export * from "./bind.decorator";
97
126
 
98
127
  export { default as LogFactory} from "./factory/log-factory.class";
99
128
  export { default as CacheFactory} from "./factory/cache-factory.class";
@@ -0,0 +1,28 @@
1
+ const chaiObj = require('chai');
2
+ chaiObj.use(require("chai-http"));
3
+ const expect = chaiObj.expect;
4
+
5
+ describe("Test @bind and token", () => {
6
+ const testAddr = `http://${process.env.LOCAL_HOST || "localhost"}:8081`;
7
+ it("/bind/param (route @bind)", (done) => {
8
+ chaiObj.request(testAddr).get("/bind/param/100?name=testname").end((err, res) => {
9
+ expect(JSON.parse(res.text)).to.deep.equal({ id: "100", name: "testname" });
10
+ done();
11
+ });
12
+ });
13
+ it("/bind/token (@bean(Token) + @autoware(Token) + @resource(Token, args))", (done) => {
14
+ chaiObj.request(testAddr).get("/bind/token").end((err, res) => {
15
+ expect(res.text).to.equal("test-bean|model-ok");
16
+ done();
17
+ });
18
+ });
19
+ it("/bind/db (database @bind scalar)", (done) => {
20
+ const id = Math.floor(Math.random() * 900000) + 100000;
21
+ chaiObj.request(testAddr).get(`/bind/db?id=${id}`).end((err, res) => {
22
+ expect(res.text).to.match(/^bind insert: \d+/);
23
+ done();
24
+ });
25
+ });
26
+ });
27
+
28
+ export {};
@@ -0,0 +1,42 @@
1
+ import { expect } from "chai";
2
+ import { isStd, getStdArgs } from "../src/decorator-utils";
3
+
4
+ describe("decorator-utils · isStd 双签名判据", () => {
5
+ it("legacy 类装饰器(1 参)→ false", () => {
6
+ expect(isStd([class Foo {}])).to.equal(false);
7
+ });
8
+
9
+ it("legacy 方法/属性装饰器(2 参,第 2 参是 string key)→ false", () => {
10
+ expect(isStd([{}, "methodName"])).to.equal(false);
11
+ });
12
+
13
+ it("legacy 带 descriptor 方法 / 参数装饰器(3 参)→ false", () => {
14
+ expect(isStd([{}, "methodName", {}])).to.equal(false);
15
+ expect(isStd([{}, "methodName", 0])).to.equal(false);
16
+ });
17
+
18
+ it("标准类/方法/field 装饰器(2 参,第 2 参带 string kind)→ true", () => {
19
+ expect(isStd([function () {}, { kind: "class" }])).to.equal(true);
20
+ expect(isStd([function () {}, { kind: "method" }])).to.equal(true);
21
+ expect(isStd([undefined, { kind: "field" }])).to.equal(true);
22
+ expect(isStd([{}, { kind: "accessor" }])).to.equal(true);
23
+ });
24
+
25
+ it("第 2 参是对象但无 kind → false", () => {
26
+ expect(isStd([{}, {}])).to.equal(false);
27
+ });
28
+
29
+ it("第 2 参是 null / 非对象 → false", () => {
30
+ expect(isStd([{}, null])).to.equal(false);
31
+ expect(isStd([{}, 42])).to.equal(false);
32
+ });
33
+
34
+ it("getStdArgs 解出 (value, context)", () => {
35
+ const ctx = { kind: "method", name: "foo" };
36
+ const [value, context] = getStdArgs([function bar() {}, ctx]);
37
+ expect(typeof value).to.equal("function");
38
+ expect(context).to.equal(ctx);
39
+ });
40
+ });
41
+
42
+ export {};