@litert/typeguard 1.0.1 → 1.3.0-dev.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.
Files changed (76) hide show
  1. package/CHANGES.md +16 -0
  2. package/lib/BuiltInTypeCompiler.d.ts +4 -4
  3. package/lib/BuiltInTypeCompiler.d.ts.map +1 -1
  4. package/lib/BuiltInTypeCompiler.js +167 -166
  5. package/lib/BuiltInTypeCompiler.js.map +1 -1
  6. package/lib/BuiltInTypes.d.ts +1 -1
  7. package/lib/BuiltInTypes.js +37 -36
  8. package/lib/BuiltInTypes.js.map +1 -1
  9. package/lib/Common.d.ts +27 -10
  10. package/lib/Common.d.ts.map +1 -1
  11. package/lib/Common.js +1 -1
  12. package/lib/Compiler.d.ts +2 -2
  13. package/lib/Compiler.d.ts.map +1 -1
  14. package/lib/Compiler.js +159 -102
  15. package/lib/Compiler.js.map +1 -1
  16. package/lib/Context.d.ts +6 -5
  17. package/lib/Context.d.ts.map +1 -1
  18. package/lib/Context.js +11 -7
  19. package/lib/Context.js.map +1 -1
  20. package/lib/FilterCompiler.d.ts +5 -5
  21. package/lib/FilterCompiler.d.ts.map +1 -1
  22. package/lib/FilterCompiler.js +25 -24
  23. package/lib/FilterCompiler.js.map +1 -1
  24. package/lib/InlineCompiler.d.ts +12 -5
  25. package/lib/InlineCompiler.d.ts.map +1 -1
  26. package/lib/InlineCompiler.js +18 -6
  27. package/lib/InlineCompiler.js.map +1 -1
  28. package/lib/Internal.d.ts +6 -4
  29. package/lib/Internal.d.ts.map +1 -1
  30. package/lib/Internal.js +12 -10
  31. package/lib/Internal.js.map +1 -1
  32. package/lib/Modifiers.d.ts +1 -1
  33. package/lib/Modifiers.js +2 -1
  34. package/lib/Modifiers.js.map +1 -1
  35. package/lib/index.d.ts +5 -5
  36. package/lib/index.js +19 -7
  37. package/lib/index.js.map +1 -1
  38. package/lib/langs/JavaScript.d.ts +2 -2
  39. package/lib/langs/JavaScript.d.ts.map +1 -1
  40. package/lib/langs/JavaScript.js +55 -29
  41. package/lib/langs/JavaScript.js.map +1 -1
  42. package/package.json +17 -13
  43. package/src/examples/quick-start.ts +172 -0
  44. package/src/lib/BuiltInTypeCompiler.ts +171 -171
  45. package/src/lib/BuiltInTypes.ts +36 -36
  46. package/src/lib/Common.ts +49 -10
  47. package/src/lib/Compiler.ts +354 -247
  48. package/src/lib/Context.ts +11 -13
  49. package/src/lib/FilterCompiler.ts +84 -84
  50. package/src/lib/InlineCompiler.ts +41 -15
  51. package/src/lib/Internal.ts +17 -13
  52. package/src/lib/Modifiers.ts +2 -2
  53. package/src/lib/index.ts +5 -5
  54. package/src/lib/langs/JavaScript.ts +84 -31
  55. package/src/test/00-all.ts +10 -10
  56. package/src/test/01-elemental-types.ts +1111 -1110
  57. package/src/test/02-array-and-list.ts +75 -75
  58. package/src/test/03-tuple.ts +87 -87
  59. package/src/test/04-from-string.ts +849 -848
  60. package/src/test/05-string-asserts.ts +422 -422
  61. package/src/test/06-structure.ts +107 -107
  62. package/src/test/07-modifiers.ts +151 -42
  63. package/src/test/08-map-and-dict.ts +46 -46
  64. package/src/test/09-exceptions.ts +30 -9
  65. package/src/test/abstracts.ts +83 -45
  66. package/dist/typeguard.amd.d.ts +0 -588
  67. package/dist/typeguard.amd.d.ts.map +0 -1
  68. package/dist/typeguard.amd.js +0 -2069
  69. package/dist/typeguard.amd.js.map +0 -1
  70. package/dist/typeguard.system.d.ts +0 -588
  71. package/dist/typeguard.system.d.ts.map +0 -1
  72. package/dist/typeguard.system.js +0 -2185
  73. package/dist/typeguard.system.js.map +0 -1
  74. package/src/samples/quick-start.ts +0 -52
  75. package/tsconfig-amd.json +0 -72
  76. package/tsconfig-systemjs.json +0 -72
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2019 Angus.Fenying <fenying@litert.org>
2
+ * Copyright 2022 Angus Fenying <fenying@litert.org>
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -14,22 +14,22 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import * as i from "./Internal";
17
+ import * as i from './Internal';
18
18
 
19
19
  export class Context implements i.IContext {
20
20
 
21
- public trace: boolean;
22
-
23
- public tracePoint: number;
24
-
25
21
  public vCursor: number;
26
22
 
27
23
  public stack: i.IContextData[];
28
24
 
29
25
  public flags: Record<string, i.EFlagValue>;
30
26
 
27
+ public tracePath: string = '';
28
+
31
29
  public constructor(
32
30
  public vName: string,
31
+ public vTraceName: string,
32
+ public vTracePrefix: string,
33
33
  public readonly typeSlotName: string,
34
34
  public readonly referredTypes: Record<string, boolean>
35
35
  ) {
@@ -38,17 +38,14 @@ export class Context implements i.IContext {
38
38
  this.vCursor = 0;
39
39
 
40
40
  this.flags = {};
41
-
42
- this.tracePoint = 0;
43
-
44
- this.trace = false;
45
41
  }
46
42
 
47
43
  public trap(subjChanged: boolean = false): void {
48
44
 
49
45
  this.stack.push({
50
46
  vName: this.vName,
51
- flags: this.flags
47
+ flags: this.flags,
48
+ tracePath: this.tracePath,
52
49
  });
53
50
 
54
51
  const prevFlags = this.flags;
@@ -80,10 +77,11 @@ export class Context implements i.IContext {
80
77
 
81
78
  if (!prev) {
82
79
 
83
- throw new Error("Failed to pop stack.");
80
+ throw new Error('Failed to pop stack.');
84
81
  }
85
82
 
86
- this.vName = prev.vName;
87
83
  this.flags = prev.flags;
84
+ this.vName = prev.vName;
85
+ this.tracePath = prev.tracePath;
88
86
  }
89
87
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2019 Angus.Fenying <fenying@litert.org>
2
+ * Copyright 2022 Angus Fenying <fenying@litert.org>
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -14,143 +14,143 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import * as C from "./Common";
18
- import * as I from "./Internal";
17
+ import * as C from './Common';
18
+ import * as I from './Internal';
19
19
 
20
20
  export class FilterCompiler
21
21
  implements I.IFilterCompiler {
22
22
 
23
23
  public constructor(
24
- private _lang: C.ILanguageBuilder,
25
- private _bitc: I.IBuiltInTypeCompiler
24
+ private readonly _lang: C.ILanguageBuilder,
25
+ private readonly _bitc: I.IBuiltInTypeCompiler
26
26
  ) {}
27
27
 
28
28
  public compile(rule: string, ctx: I.IContext): string {
29
29
 
30
30
  let vName = ctx.vName;
31
31
 
32
- const filter = rule.slice(1).split(" ");
32
+ const filter = rule.slice(1).split(' ');
33
33
 
34
34
  if (filter.slice(2).length !== filter.slice(2).filter((x) => /^\d+(\.\d+)?$/.test(x)).length) {
35
35
 
36
- throw new TypeError("Only number is allowed as filter arguments.");
36
+ throw new TypeError('Only number is allowed as filter arguments.');
37
37
  }
38
38
 
39
- let ret: string[] = [];
39
+ const ret: string[] = [];
40
40
 
41
41
  switch (filter[0]) {
42
- case "array.length":
43
- ret.push(this._lang.isArray(vName, true));
44
- vName = this._lang.arrayLength(vName);
45
- break;
46
- case "string.length":
47
- ret.push(this._lang.isString(vName, true));
48
- vName = this._lang.stringLength(vName);
49
- break;
50
- case "value":
51
- ret.push(this._lang.isNumber(vName, true));
52
- break;
53
- default:
54
- ret.push(this._bitc.compile(filter[0], ctx, []));
55
- break;
42
+ case 'array.length':
43
+ ret.push(this._lang.isArray(vName, true));
44
+ vName = this._lang.arrayLength(vName);
45
+ break;
46
+ case 'string.length':
47
+ ret.push(this._lang.isString(vName, true));
48
+ vName = this._lang.stringLength(vName);
49
+ break;
50
+ case 'value':
51
+ ret.push(this._lang.isNumber(vName, true));
52
+ break;
53
+ default:
54
+ ret.push(this._bitc.compile(filter[0], ctx, []));
55
+ break;
56
56
  }
57
57
 
58
58
  switch (filter[1]) {
59
- case "between":
59
+ case 'between':
60
60
 
61
- if (filter.length !== 4) {
62
- throw new TypeError(`Filter ${filter[1]} require 2 arguments.`);
63
- }
61
+ if (filter.length !== 4) {
62
+ throw new TypeError(`Filter ${filter[1]} require 2 arguments.`);
63
+ }
64
64
 
65
- ret.push(this._lang.gte(vName, filter[2]));
66
- ret.push(this._lang.lte(vName, filter[3]));
65
+ ret.push(this._lang.gte(vName, filter[2]));
66
+ ret.push(this._lang.lte(vName, filter[3]));
67
67
 
68
- break;
68
+ break;
69
69
 
70
- case "gt":
71
- case ">":
70
+ case 'gt':
71
+ case '>':
72
72
 
73
- if (filter.length !== 3) {
74
- throw new TypeError(`Filter ${filter[1]} require 1 argument.`);
75
- }
73
+ if (filter.length !== 3) {
74
+ throw new TypeError(`Filter ${filter[1]} require 1 argument.`);
75
+ }
76
76
 
77
- ret.push(this._lang.gt(vName, filter[2]));
77
+ ret.push(this._lang.gt(vName, filter[2]));
78
78
 
79
- break;
79
+ break;
80
80
 
81
- case "ge":
82
- case "gte":
83
- case ">=":
81
+ case 'ge':
82
+ case 'gte':
83
+ case '>=':
84
84
 
85
- if (filter.length !== 3) {
86
- throw new TypeError(`Filter ${filter[1]} require 1 argument.`);
87
- }
85
+ if (filter.length !== 3) {
86
+ throw new TypeError(`Filter ${filter[1]} require 1 argument.`);
87
+ }
88
88
 
89
- ret.push(this._lang.gte(vName, filter[2]));
89
+ ret.push(this._lang.gte(vName, filter[2]));
90
90
 
91
- break;
91
+ break;
92
92
 
93
- case "lt":
94
- case "<":
93
+ case 'lt':
94
+ case '<':
95
95
 
96
- if (filter.length !== 3) {
97
- throw new TypeError(`Filter ${filter[1]} require 1 argument.`);
98
- }
96
+ if (filter.length !== 3) {
97
+ throw new TypeError(`Filter ${filter[1]} require 1 argument.`);
98
+ }
99
99
 
100
- ret.push(this._lang.lt(vName, filter[2]));
100
+ ret.push(this._lang.lt(vName, filter[2]));
101
101
 
102
- break;
102
+ break;
103
103
 
104
- case "le":
105
- case "lte":
106
- case "<=":
104
+ case 'le':
105
+ case 'lte':
106
+ case '<=':
107
107
 
108
- if (filter.length !== 3) {
109
- throw new TypeError(`Filter ${filter[1]} require 1 argument.`);
110
- }
108
+ if (filter.length !== 3) {
109
+ throw new TypeError(`Filter ${filter[1]} require 1 argument.`);
110
+ }
111
111
 
112
- ret.push(this._lang.lte(vName, filter[2]));
112
+ ret.push(this._lang.lte(vName, filter[2]));
113
113
 
114
- break;
114
+ break;
115
115
 
116
- case "eq":
117
- case "==":
116
+ case 'eq':
117
+ case '==':
118
118
 
119
- if (filter.length !== 3) {
120
- throw new TypeError(`Filter ${filter[1]} require 1 argument.`);
121
- }
119
+ if (filter.length !== 3) {
120
+ throw new TypeError(`Filter ${filter[1]} require 1 argument.`);
121
+ }
122
122
 
123
- ret.push(this._lang.eq(vName, filter[2]));
123
+ ret.push(this._lang.eq(vName, filter[2]));
124
124
 
125
- break;
125
+ break;
126
126
 
127
- case "ne":
128
- case "!=":
127
+ case 'ne':
128
+ case '!=':
129
129
 
130
- if (filter.length !== 3) {
131
- throw new TypeError(`Filter ${filter[1]} require 1 argument.`);
132
- }
130
+ if (filter.length !== 3) {
131
+ throw new TypeError(`Filter ${filter[1]} require 1 argument.`);
132
+ }
133
133
 
134
- ret.push(this._lang.ne(vName, filter[2]));
134
+ ret.push(this._lang.ne(vName, filter[2]));
135
135
 
136
- break;
136
+ break;
137
137
 
138
- case "timesof":
138
+ case 'timesof':
139
139
 
140
- if (filter.length !== 3) {
141
- throw new TypeError(`Filter ${filter[1]} require 1 argument.`);
142
- }
140
+ if (filter.length !== 3) {
141
+ throw new TypeError(`Filter ${filter[1]} require 1 argument.`);
142
+ }
143
143
 
144
- ret.push(this._lang.eq(
145
- this._lang.modOf(vName, filter[2]),
146
- "0"
147
- ));
144
+ ret.push(this._lang.eq(
145
+ this._lang.modOf(vName, filter[2]),
146
+ '0'
147
+ ));
148
148
 
149
- break;
149
+ break;
150
150
 
151
- default:
151
+ default:
152
152
 
153
- throw new TypeError(`Unknown filter type "${filter[1]}".`);
153
+ throw new TypeError(`Unknown filter type "${filter[1]}".`);
154
154
  }
155
155
 
156
156
  return this._lang.and(ret);
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2019 Angus.Fenying <fenying@litert.org>
2
+ * Copyright 2022 Angus Fenying <fenying@litert.org>
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -14,16 +14,17 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import { createCompiler } from "./Compiler";
18
- import { createJavaScriptLanguageBuilder } from "./langs/JavaScript";
19
- import * as C from "./Common";
17
+ import { createCompiler } from './Compiler';
18
+ import { createJavaScriptLanguageBuilder } from './langs/JavaScript';
19
+ import * as C from './Common';
20
+ import * as I from './Internal';
20
21
 
21
22
  export interface IInlineCompileOptions extends C.ICompileOptions {
22
23
 
23
24
  /**
24
25
  * Added `debugger` statement before executing checking code.
25
26
  */
26
- "stopOnEntry"?: boolean;
27
+ 'stopOnEntry'?: boolean;
27
28
  }
28
29
 
29
30
  export interface IInlineCompiler {
@@ -34,14 +35,22 @@ export interface IInlineCompiler {
34
35
  *
35
36
  * @param options The options of compilation.
36
37
  */
37
- compile<T>(options: IInlineCompileOptions): C.TypeChecker<T>;
38
+ compile<T>(options: IInlineCompileOptions): C.ITypeChecker<T>;
38
39
 
39
40
  /**
40
41
  * Get the type-checker of a pre-defined type.
41
42
  *
42
43
  * @param name The name of the pre-defined type.
43
44
  */
44
- getPredefinedType<T>(name: string): C.TypeChecker<T>;
45
+ getPredefinedType<T>(name: string): C.ITypeChecker<T>;
46
+
47
+ /**
48
+ * Register a pre-defined type checker.
49
+ *
50
+ * @param name The name of the pre-defined type (without prefix `@`)
51
+ * @param checker The checker callback of the pre-defined type.
52
+ */
53
+ addPredefinedType<T>(name: string, checker: C.ITypeChecker<T>): this;
45
54
 
46
55
  /**
47
56
  * Check if a pre-defined type is compiled.
@@ -59,11 +68,11 @@ export interface IInlineCompiler {
59
68
  class InlineCompiler
60
69
  implements IInlineCompiler {
61
70
 
62
- private _defTypes: Record<string, C.TypeChecker<any>>;
71
+ private _defTypes: Record<string, C.ITypeChecker<any>>;
63
72
 
64
73
  private _missingTypes: Record<string, boolean>;
65
74
 
66
- private _compiler: C.ICompiler;
75
+ private readonly _compiler: C.ICompiler;
67
76
 
68
77
  public constructor() {
69
78
 
@@ -78,7 +87,7 @@ implements IInlineCompiler {
78
87
  );
79
88
  }
80
89
 
81
- public compile<T>(options: IInlineCompileOptions): C.TypeChecker<T> {
90
+ public compile<T>(options: IInlineCompileOptions): C.ITypeChecker<T> {
82
91
 
83
92
  const result = this._compiler.compile(options);
84
93
 
@@ -92,7 +101,7 @@ implements IInlineCompiler {
92
101
  stopOnEntry?: boolean
93
102
  ): void {
94
103
 
95
- for (let x of types) {
104
+ for (const x of types) {
96
105
 
97
106
  if (this._defTypes[x]) {
98
107
 
@@ -115,6 +124,18 @@ implements IInlineCompiler {
115
124
  }
116
125
  }
117
126
 
127
+ public addPredefinedType(name: string, checker: C.ITypeChecker<any>): this {
128
+
129
+ if (!I.RE_VALID_CUSTOM_TYPE_NAME.test(name)) {
130
+
131
+ throw new TypeError(`Invalid name ${ JSON.stringify(name) } for a pre-defined type.`);
132
+ }
133
+
134
+ this._defTypes[name] = checker;
135
+
136
+ return this;
137
+ }
138
+
118
139
  public detectUndefinedTypes(): string[] {
119
140
 
120
141
  return Object.keys(this._missingTypes);
@@ -125,7 +146,7 @@ implements IInlineCompiler {
125
146
  return !!this._defTypes[name];
126
147
  }
127
148
 
128
- public getPredefinedType(name: string): C.TypeChecker<any> {
149
+ public getPredefinedType(name: string): C.ITypeChecker<any> {
129
150
 
130
151
  if (!this._defTypes[name]) {
131
152
 
@@ -138,13 +159,18 @@ implements IInlineCompiler {
138
159
  private _wrapCheckerCode(
139
160
  info: C.ICompileResult,
140
161
  stopOnEntry: boolean = false
141
- ): C.TypeChecker<any> {
162
+ ): C.ITypeChecker<any> {
142
163
 
143
- const soe = stopOnEntry ? "debugger;" : "";
164
+ const soe = stopOnEntry ? 'debugger;' : '';
144
165
 
145
166
  return (new Function(
146
167
  info.typeSlotName,
147
- `return function(${info.arguments[0].name}) {${soe}
168
+ `return function(${
169
+ info.arguments
170
+ .map((a) => a.initial ? `${a.name} = ${a.initial}` : a.name)
171
+ .join(',')
172
+ }) {
173
+ ${soe}
148
174
 
149
175
  return ${info.source};
150
176
  };`
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2019 Angus.Fenying <fenying@litert.org>
2
+ * Copyright 2022 Angus Fenying <fenying@litert.org>
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -14,19 +14,19 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- export const MAP_SUFFIX = "{}";
17
+ export const MAP_SUFFIX = '{}';
18
18
 
19
- export const LIST_SUFFIX = "[]";
19
+ export const LIST_SUFFIX = '[]';
20
20
 
21
- export const MODIFIER_PREFIX = "$.";
21
+ export const MODIFIER_PREFIX = '$.';
22
22
 
23
- export const FILTER_PREFIX = "|";
23
+ export const FILTER_PREFIX = '|';
24
24
 
25
- export const IMPLICIT_SYMBOL = "?";
25
+ export const IMPLICIT_SYMBOL = '?';
26
26
 
27
- export const PREDEF_TYPE_SYMBOL = "@";
27
+ export const PREDEF_TYPE_SYMBOL = '@';
28
28
 
29
- export const NEGATIVE_SYMBOL = "!";
29
+ export const NEGATIVE_SYMBOL = '!';
30
30
 
31
31
  export const KEY_MAP_SUFFIX = `->${MAP_SUFFIX}`;
32
32
 
@@ -34,9 +34,9 @@ export const KEY_LIST_SUFFIX = `->${LIST_SUFFIX}`;
34
34
 
35
35
  export const KEY_ARRAY_SUFFIX = /->\[\s*(\d+)(\s*,\s*(\d+)?)?\s*\]$/;
36
36
 
37
- export const KEY_STRICT_SUFFIX = "->()";
37
+ export const KEY_STRICT_SUFFIX = '->()';
38
38
 
39
- export const KEY_EQUAL_SUFFIX = "->(=)";
39
+ export const KEY_EQUAL_SUFFIX = '->(=)';
40
40
 
41
41
  export enum EFlags {
42
42
 
@@ -72,16 +72,18 @@ export enum EFlagValue {
72
72
 
73
73
  export interface IContextData {
74
74
 
75
+ flags: Record<string, EFlagValue>;
76
+
75
77
  vName: string;
76
78
 
77
- flags: Record<string, EFlagValue>;
79
+ tracePath: string;
78
80
  }
79
81
 
80
82
  export interface IContext extends IContextData {
81
83
 
82
- trace: boolean;
84
+ vTraceName: string;
83
85
 
84
- tracePoint: number;
86
+ vTracePrefix: string;
85
87
 
86
88
  vCursor: number;
87
89
 
@@ -123,3 +125,5 @@ export interface IBuiltInTypeCompiler {
123
125
 
124
126
  isElemental(type: string): boolean;
125
127
  }
128
+
129
+ export const RE_VALID_CUSTOM_TYPE_NAME = /^[-:.\w]+$/;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2019 Angus.Fenying <fenying@litert.org>
2
+ * Copyright 2022 Angus Fenying <fenying@litert.org>
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- import * as I from "./Internal";
17
+ import * as I from './Internal';
18
18
 
19
19
  export const PREFIX: string = I.MODIFIER_PREFIX;
20
20
 
package/src/lib/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Copyright 2019 Angus.Fenying <fenying@litert.org>
2
+ * Copyright 2022 Angus Fenying <fenying@litert.org>
3
3
  *
4
4
  * Licensed under the Apache License, Version 2.0 (the "License");
5
5
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
 
17
- export * from "./InlineCompiler";
18
- export * from "./langs/JavaScript";
19
- export * from "./Compiler";
20
- export * from "./Common";
17
+ export * from './InlineCompiler';
18
+ export * from './langs/JavaScript';
19
+ export * from './Compiler';
20
+ export * from './Common';