@epsilon-asi/foundation 0.0.1-testing
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/.npm/_logs/2026-05-02T22_04_53_277Z-debug-0.log +22 -0
- package/.npm/_logs/2026-05-02T22_04_53_601Z-debug-0.log +18 -0
- package/.npm/_logs/2026-05-02T22_04_58_522Z-debug-0.log +18 -0
- package/.npm/_logs/2026-05-02T22_05_00_812Z-debug-0.log +19 -0
- package/.npm/_logs/2026-05-02T22_05_00_961Z-debug-0.log +14 -0
- package/build/decorators/factory/clone.d.ts +3 -0
- package/build/decorators/factory/clone.js +85 -0
- package/build/decorators/factory/decoratorRegistry.d.ts +2 -0
- package/build/decorators/factory/decoratorRegistry.js +213 -0
- package/build/decorators/factory/examples/accessors.d.ts +25 -0
- package/build/decorators/factory/examples/accessors.js +87 -0
- package/build/decorators/factory/examples/crud.d.ts +50 -0
- package/build/decorators/factory/examples/crud.js +120 -0
- package/build/decorators/factory/examples/orm.d.ts +45 -0
- package/build/decorators/factory/examples/orm.js +107 -0
- package/build/decorators/factory/examples/routing.d.ts +43 -0
- package/build/decorators/factory/examples/routing.js +112 -0
- package/build/decorators/factory/examples/runExamples.d.ts +1 -0
- package/build/decorators/factory/examples/runExamples.js +22 -0
- package/build/decorators/factory/examples/serialization.d.ts +24 -0
- package/build/decorators/factory/examples/serialization.js +79 -0
- package/build/decorators/factory/index.d.ts +3 -0
- package/build/decorators/factory/index.js +8 -0
- package/build/decorators/factory/snapshot.d.ts +2 -0
- package/build/decorators/factory/snapshot.js +75 -0
- package/build/decorators/factory/symbolMetadata.d.ts +2 -0
- package/build/decorators/factory/symbolMetadata.js +17 -0
- package/build/decorators/factory/types.d.ts +123 -0
- package/build/decorators/factory/types.js +2 -0
- package/build/decorators/validation/validatable.d.ts +0 -0
- package/build/decorators/validation/validatable.js +64 -0
- package/build/index.d.ts +5 -0
- package/build/index.js +12 -0
- package/build/package.json +49 -0
- package/coverage/clover.xml +220 -0
- package/coverage/coverage-final.json +6 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/clone.ts.html +352 -0
- package/coverage/lcov-report/decoratorRegistry.ts.html +1183 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +176 -0
- package/coverage/lcov-report/index.ts.html +145 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/snapshot.ts.html +370 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov-report/symbolMetadata.ts.html +145 -0
- package/coverage/lcov.info +490 -0
- package/package.json +47 -0
- package/src/decorators/factory/__tests__/cloneAndSnapshot.test.ts +223 -0
- package/src/decorators/factory/__tests__/decoratorRegistry.test.ts +292 -0
- package/src/decorators/factory/__tests__/decoratorRegistryEdges.test.ts +262 -0
- package/src/decorators/factory/clone.ts +89 -0
- package/src/decorators/factory/decoratorRegistry.ts +366 -0
- package/src/decorators/factory/examples/accessors.ts +38 -0
- package/src/decorators/factory/examples/crud.ts +82 -0
- package/src/decorators/factory/examples/orm.ts +83 -0
- package/src/decorators/factory/examples/routing.ts +70 -0
- package/src/decorators/factory/examples/runExamples.ts +22 -0
- package/src/decorators/factory/examples/serialization.ts +47 -0
- package/src/decorators/factory/index.ts +20 -0
- package/src/decorators/factory/snapshot.ts +95 -0
- package/src/decorators/factory/symbolMetadata.ts +20 -0
- package/src/decorators/factory/type-tests/decoratorRegistry.type-test.ts +302 -0
- package/src/decorators/factory/types.ts +259 -0
- package/src/decorators/validation/validatable.ts +63 -0
- package/src/index.ts +9 -0
- package/tsconfig.json +19 -0
- package/tsconfig.type-tests.json +8 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
0 verbose cli /usr/local/bin/node /usr/local/bin/npm
|
|
2
|
+
1 info using npm@10.9.2
|
|
3
|
+
2 info using node@v22.17.1
|
|
4
|
+
3 silly config load:file:/usr/local/lib/node_modules/npm/npmrc
|
|
5
|
+
4 silly config load:file:/builds/epsilon-asi/foundations/packages/foundation/.npmrc
|
|
6
|
+
5 silly config load:file:/root/.npmrc
|
|
7
|
+
6 silly config load:file:/usr/local/etc/npmrc
|
|
8
|
+
7 verbose title npm ci
|
|
9
|
+
8 verbose argv "ci"
|
|
10
|
+
9 verbose logfile logs-max:10 dir:/builds/epsilon-asi/foundations/packages/foundation/.npm/_logs/2026-05-02T22_04_53_277Z-
|
|
11
|
+
10 verbose logfile /builds/epsilon-asi/foundations/packages/foundation/.npm/_logs/2026-05-02T22_04_53_277Z-debug-0.log
|
|
12
|
+
11 silly logfile done cleaning log files
|
|
13
|
+
12 silly packumentCache heap:2197815296 maxSize:549453824 maxEntrySize:274726912
|
|
14
|
+
13 silly idealTree buildDeps
|
|
15
|
+
14 silly reify moves {}
|
|
16
|
+
15 silly audit report null
|
|
17
|
+
16 verbose cwd /builds/epsilon-asi/foundations/packages/foundation
|
|
18
|
+
17 verbose os Linux 5.15.154+
|
|
19
|
+
18 verbose node v22.17.1
|
|
20
|
+
19 verbose npm v10.9.2
|
|
21
|
+
20 verbose exit 0
|
|
22
|
+
21 info ok
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
0 verbose cli /usr/local/bin/node /usr/local/bin/npm
|
|
2
|
+
1 info using npm@10.9.2
|
|
3
|
+
2 info using node@v22.17.1
|
|
4
|
+
3 silly config load:file:/usr/local/lib/node_modules/npm/npmrc
|
|
5
|
+
4 silly config load:file:/builds/epsilon-asi/foundations/packages/foundation/.npmrc
|
|
6
|
+
5 silly config load:file:/root/.npmrc
|
|
7
|
+
6 silly config load:file:/usr/local/etc/npmrc
|
|
8
|
+
7 verbose title npm run test
|
|
9
|
+
8 verbose argv "run" "test"
|
|
10
|
+
9 verbose logfile logs-max:10 dir:/builds/epsilon-asi/foundations/packages/foundation/.npm/_logs/2026-05-02T22_04_53_601Z-
|
|
11
|
+
10 verbose logfile /builds/epsilon-asi/foundations/packages/foundation/.npm/_logs/2026-05-02T22_04_53_601Z-debug-0.log
|
|
12
|
+
11 silly logfile done cleaning log files
|
|
13
|
+
12 verbose cwd /builds/epsilon-asi/foundations/packages/foundation
|
|
14
|
+
13 verbose os Linux 5.15.154+
|
|
15
|
+
14 verbose node v22.17.1
|
|
16
|
+
15 verbose npm v10.9.2
|
|
17
|
+
16 verbose exit 0
|
|
18
|
+
17 info ok
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
0 verbose cli /usr/local/bin/node /usr/local/bin/npm
|
|
2
|
+
1 info using npm@10.9.2
|
|
3
|
+
2 info using node@v22.17.1
|
|
4
|
+
3 silly config load:file:/usr/local/lib/node_modules/npm/npmrc
|
|
5
|
+
4 silly config load:file:/builds/epsilon-asi/foundations/packages/foundation/.npmrc
|
|
6
|
+
5 silly config load:file:/root/.npmrc
|
|
7
|
+
6 silly config load:file:/usr/local/etc/npmrc
|
|
8
|
+
7 verbose title npm run build
|
|
9
|
+
8 verbose argv "run" "build"
|
|
10
|
+
9 verbose logfile logs-max:10 dir:/builds/epsilon-asi/foundations/packages/foundation/.npm/_logs/2026-05-02T22_04_58_522Z-
|
|
11
|
+
10 verbose logfile /builds/epsilon-asi/foundations/packages/foundation/.npm/_logs/2026-05-02T22_04_58_522Z-debug-0.log
|
|
12
|
+
11 silly logfile done cleaning log files
|
|
13
|
+
12 verbose cwd /builds/epsilon-asi/foundations/packages/foundation
|
|
14
|
+
13 verbose os Linux 5.15.154+
|
|
15
|
+
14 verbose node v22.17.1
|
|
16
|
+
15 verbose npm v10.9.2
|
|
17
|
+
16 verbose exit 0
|
|
18
|
+
17 info ok
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
0 verbose cli /usr/local/bin/node /usr/local/bin/npm
|
|
2
|
+
1 info using npm@10.9.2
|
|
3
|
+
2 info using node@v22.17.1
|
|
4
|
+
3 silly config load:file:/usr/local/lib/node_modules/npm/npmrc
|
|
5
|
+
4 silly config load:file:/builds/epsilon-asi/foundations/packages/foundation/.npmrc
|
|
6
|
+
5 silly config load:file:/root/.npmrc
|
|
7
|
+
6 silly config load:file:/usr/local/etc/npmrc
|
|
8
|
+
7 verbose title npm version 0.0.1-testing
|
|
9
|
+
8 verbose argv "version" "0.0.1-testing" "--no-git-tag-version"
|
|
10
|
+
9 verbose logfile logs-max:10 dir:/builds/epsilon-asi/foundations/packages/foundation/.npm/_logs/2026-05-02T22_05_00_812Z-
|
|
11
|
+
10 verbose logfile /builds/epsilon-asi/foundations/packages/foundation/.npm/_logs/2026-05-02T22_05_00_812Z-debug-0.log
|
|
12
|
+
11 silly logfile done cleaning log files
|
|
13
|
+
12 verbose version Not tagging: not in a git repo or no git cmd
|
|
14
|
+
13 verbose cwd /builds/epsilon-asi/foundations/packages/foundation
|
|
15
|
+
14 verbose os Linux 5.15.154+
|
|
16
|
+
15 verbose node v22.17.1
|
|
17
|
+
16 verbose npm v10.9.2
|
|
18
|
+
17 verbose exit 0
|
|
19
|
+
18 info ok
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
0 verbose cli /usr/local/bin/node /usr/local/bin/npm
|
|
2
|
+
1 info using npm@10.9.2
|
|
3
|
+
2 info using node@v22.17.1
|
|
4
|
+
3 silly config load:file:/usr/local/lib/node_modules/npm/npmrc
|
|
5
|
+
4 silly config load:file:/builds/epsilon-asi/foundations/packages/foundation/.npmrc
|
|
6
|
+
5 silly config load:file:/root/.npmrc
|
|
7
|
+
6 silly config load:file:/usr/local/etc/npmrc
|
|
8
|
+
7 verbose title npm publish
|
|
9
|
+
8 verbose argv "publish"
|
|
10
|
+
9 verbose logfile logs-max:10 dir:/builds/epsilon-asi/foundations/packages/foundation/.npm/_logs/2026-05-02T22_05_00_961Z-
|
|
11
|
+
10 verbose logfile /builds/epsilon-asi/foundations/packages/foundation/.npm/_logs/2026-05-02T22_05_00_961Z-debug-0.log
|
|
12
|
+
11 silly logfile done cleaning log files
|
|
13
|
+
12 verbose publish [ '.' ]
|
|
14
|
+
13 silly packumentCache heap:2197815296 maxSize:549453824 maxEntrySize:274726912
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.cloneDeep = cloneDeep;
|
|
4
|
+
exports.deepFreeze = deepFreeze;
|
|
5
|
+
exports.immutableClone = immutableClone;
|
|
6
|
+
function isObjectLike(value) {
|
|
7
|
+
return (typeof value === 'object' && value !== null) || typeof value === 'function';
|
|
8
|
+
}
|
|
9
|
+
function cloneDeep(value, seen = new WeakMap()) {
|
|
10
|
+
if (!isObjectLike(value))
|
|
11
|
+
return value;
|
|
12
|
+
if (typeof value === 'function')
|
|
13
|
+
return value;
|
|
14
|
+
const existing = seen.get(value);
|
|
15
|
+
if (existing !== undefined)
|
|
16
|
+
return existing;
|
|
17
|
+
if (value instanceof Date) {
|
|
18
|
+
return new Date(value.getTime());
|
|
19
|
+
}
|
|
20
|
+
if (value instanceof RegExp) {
|
|
21
|
+
return new RegExp(value.source, value.flags);
|
|
22
|
+
}
|
|
23
|
+
if (value instanceof Map) {
|
|
24
|
+
const cloned = new Map();
|
|
25
|
+
seen.set(value, cloned);
|
|
26
|
+
for (const [key, mapValue] of value.entries()) {
|
|
27
|
+
cloned.set(cloneDeep(key, seen), cloneDeep(mapValue, seen));
|
|
28
|
+
}
|
|
29
|
+
return cloned;
|
|
30
|
+
}
|
|
31
|
+
if (value instanceof Set) {
|
|
32
|
+
const cloned = new Set();
|
|
33
|
+
seen.set(value, cloned);
|
|
34
|
+
for (const setValue of value.values()) {
|
|
35
|
+
cloned.add(cloneDeep(setValue, seen));
|
|
36
|
+
}
|
|
37
|
+
return cloned;
|
|
38
|
+
}
|
|
39
|
+
if (Array.isArray(value)) {
|
|
40
|
+
const cloned = [];
|
|
41
|
+
seen.set(value, cloned);
|
|
42
|
+
for (const item of value)
|
|
43
|
+
cloned.push(cloneDeep(item, seen));
|
|
44
|
+
return cloned;
|
|
45
|
+
}
|
|
46
|
+
const cloned = Object.create(Object.getPrototypeOf(value));
|
|
47
|
+
seen.set(value, cloned);
|
|
48
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
49
|
+
const descriptor = Object.getOwnPropertyDescriptor(value, key);
|
|
50
|
+
if (descriptor === undefined)
|
|
51
|
+
continue;
|
|
52
|
+
if ('value' in descriptor) {
|
|
53
|
+
descriptor.value = cloneDeep(descriptor.value, seen);
|
|
54
|
+
}
|
|
55
|
+
Object.defineProperty(cloned, key, descriptor);
|
|
56
|
+
}
|
|
57
|
+
return cloned;
|
|
58
|
+
}
|
|
59
|
+
function deepFreeze(value, seen = new WeakSet()) {
|
|
60
|
+
if (!isObjectLike(value))
|
|
61
|
+
return value;
|
|
62
|
+
if (seen.has(value))
|
|
63
|
+
return value;
|
|
64
|
+
seen.add(value);
|
|
65
|
+
if (value instanceof Map) {
|
|
66
|
+
for (const [key, mapValue] of value.entries()) {
|
|
67
|
+
deepFreeze(key, seen);
|
|
68
|
+
deepFreeze(mapValue, seen);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else if (value instanceof Set) {
|
|
72
|
+
for (const setValue of value.values()) {
|
|
73
|
+
deepFreeze(setValue, seen);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
78
|
+
deepFreeze(value[key], seen);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return Object.freeze(value);
|
|
82
|
+
}
|
|
83
|
+
function immutableClone(value) {
|
|
84
|
+
return deepFreeze(cloneDeep(value));
|
|
85
|
+
}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createDecoratorRegistry = createDecoratorRegistry;
|
|
4
|
+
const clone_1 = require("./clone");
|
|
5
|
+
const snapshot_1 = require("./snapshot");
|
|
6
|
+
const symbolMetadata_1 = require("./symbolMetadata");
|
|
7
|
+
function isPropertyKey(value) {
|
|
8
|
+
return typeof value === 'string' || typeof value === 'symbol';
|
|
9
|
+
}
|
|
10
|
+
function assertPropertyKey(value, decoratorName) {
|
|
11
|
+
if (isPropertyKey(value))
|
|
12
|
+
return value;
|
|
13
|
+
throw new TypeError(`Decorator "${decoratorName}" expected a string or symbol member key, but received ${typeof value}.`);
|
|
14
|
+
}
|
|
15
|
+
function parseDirectArgs(args, decoratorName) {
|
|
16
|
+
if (args.length === 0) {
|
|
17
|
+
return { metadata: undefined };
|
|
18
|
+
}
|
|
19
|
+
if (args.length === 1) {
|
|
20
|
+
return { metadata: args[0] };
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
key: assertPropertyKey(args[0], decoratorName),
|
|
24
|
+
metadata: args[1],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function parseOnArgs(args, decoratorName) {
|
|
28
|
+
if (args.length === 0) {
|
|
29
|
+
throw new TypeError(`Decorator "${decoratorName}.on" requires a member key.`);
|
|
30
|
+
}
|
|
31
|
+
return {
|
|
32
|
+
key: assertPropertyKey(args[0], `${decoratorName}.on`),
|
|
33
|
+
metadata: args.length > 1 ? args[1] : undefined,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function assertContextKind(expectedKind, decoratorName, context) {
|
|
37
|
+
if (expectedKind === 'class' && context.kind === 'class')
|
|
38
|
+
return;
|
|
39
|
+
if (expectedKind === 'property' && context.kind === 'field')
|
|
40
|
+
return;
|
|
41
|
+
if (expectedKind === 'method' && context.kind === 'method')
|
|
42
|
+
return;
|
|
43
|
+
if (expectedKind === 'accessor' &&
|
|
44
|
+
(context.kind === 'accessor' || context.kind === 'getter' || context.kind === 'setter')) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
throw new TypeError(`Decorator "${decoratorName}" can only be used on ${expectedKind} targets, but was used on ${context.kind}.`);
|
|
48
|
+
}
|
|
49
|
+
function getTargetConstructor(target) {
|
|
50
|
+
if (typeof target === 'function') {
|
|
51
|
+
return target;
|
|
52
|
+
}
|
|
53
|
+
const constructor = target.constructor;
|
|
54
|
+
return typeof constructor === 'function' ? constructor : undefined;
|
|
55
|
+
}
|
|
56
|
+
function getConstructorChain(constructor, includeInherited) {
|
|
57
|
+
if (!includeInherited)
|
|
58
|
+
return [constructor];
|
|
59
|
+
const chain = [];
|
|
60
|
+
let current = constructor;
|
|
61
|
+
while (typeof current === 'function' && current !== Function.prototype) {
|
|
62
|
+
chain.push(current);
|
|
63
|
+
current = Object.getPrototypeOf(current);
|
|
64
|
+
}
|
|
65
|
+
return chain.reverse();
|
|
66
|
+
}
|
|
67
|
+
function getOwnMetadataObject(constructor) {
|
|
68
|
+
if (!Object.prototype.hasOwnProperty.call(constructor, symbolMetadata_1.symbolMetadata)) {
|
|
69
|
+
return undefined;
|
|
70
|
+
}
|
|
71
|
+
const metadata = constructor[symbolMetadata_1.symbolMetadata];
|
|
72
|
+
return typeof metadata === 'object' && metadata !== null ? metadata : undefined;
|
|
73
|
+
}
|
|
74
|
+
function samePropertyKey(left, right) {
|
|
75
|
+
return left === right;
|
|
76
|
+
}
|
|
77
|
+
class ModernDecoratorRegistry {
|
|
78
|
+
constructor(options = {}) {
|
|
79
|
+
var _a, _b;
|
|
80
|
+
this.nextOrder = 0;
|
|
81
|
+
this.recordsByMetadata = new WeakMap();
|
|
82
|
+
this.namespace = (_a = options.namespace) !== null && _a !== void 0 ? _a : 'default';
|
|
83
|
+
this.allowPrivateMembers = (_b = options.allowPrivateMembers) !== null && _b !== void 0 ? _b : false;
|
|
84
|
+
}
|
|
85
|
+
class(name) {
|
|
86
|
+
return this.createClassFactory(String(name));
|
|
87
|
+
}
|
|
88
|
+
for() {
|
|
89
|
+
return Object.freeze({
|
|
90
|
+
class: (name) => this.createScopedClassFactory(String(name)),
|
|
91
|
+
property: (name) => this.createPropertyFactory(String(name)),
|
|
92
|
+
method: (name) => this.createMethodFactory(String(name)),
|
|
93
|
+
accessor: (name) => this.createAccessorFactory(String(name)),
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
read(target, options = {}) {
|
|
97
|
+
var _a;
|
|
98
|
+
const constructor = getTargetConstructor(target);
|
|
99
|
+
if (constructor === undefined) {
|
|
100
|
+
return (0, snapshot_1.createSnapshot)([]);
|
|
101
|
+
}
|
|
102
|
+
const includeInherited = (_a = options.includeInherited) !== null && _a !== void 0 ? _a : true;
|
|
103
|
+
const constructors = getConstructorChain(constructor, includeInherited);
|
|
104
|
+
const records = [];
|
|
105
|
+
for (const current of constructors) {
|
|
106
|
+
const metadata = getOwnMetadataObject(current);
|
|
107
|
+
if (metadata === undefined)
|
|
108
|
+
continue;
|
|
109
|
+
const ownRecords = this.recordsByMetadata.get(metadata);
|
|
110
|
+
if (ownRecords !== undefined)
|
|
111
|
+
records.push(...ownRecords);
|
|
112
|
+
}
|
|
113
|
+
return (0, snapshot_1.createSnapshot)(records);
|
|
114
|
+
}
|
|
115
|
+
createClassFactory(decoratorName) {
|
|
116
|
+
const factory = ((...args) => {
|
|
117
|
+
const metadata = args.length === 0 ? undefined : args[0];
|
|
118
|
+
return (_value, context) => {
|
|
119
|
+
assertContextKind('class', decoratorName, context);
|
|
120
|
+
this.register(context.metadata, {
|
|
121
|
+
kind: 'class',
|
|
122
|
+
decorator: decoratorName,
|
|
123
|
+
metadata,
|
|
124
|
+
static: false,
|
|
125
|
+
private: false,
|
|
126
|
+
});
|
|
127
|
+
};
|
|
128
|
+
});
|
|
129
|
+
return factory;
|
|
130
|
+
}
|
|
131
|
+
createScopedClassFactory(decoratorName) {
|
|
132
|
+
return ((...args) => {
|
|
133
|
+
const metadata = args.length === 0 ? undefined : args[0];
|
|
134
|
+
return (_value, context) => {
|
|
135
|
+
assertContextKind('class', decoratorName, context);
|
|
136
|
+
this.register(context.metadata, {
|
|
137
|
+
kind: 'class',
|
|
138
|
+
decorator: decoratorName,
|
|
139
|
+
metadata,
|
|
140
|
+
static: false,
|
|
141
|
+
private: false,
|
|
142
|
+
});
|
|
143
|
+
};
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
createPropertyFactory(decoratorName) {
|
|
147
|
+
const factory = ((...args) => {
|
|
148
|
+
const parsed = parseDirectArgs(args, decoratorName);
|
|
149
|
+
return this.createMemberDecorator('property', decoratorName, parsed);
|
|
150
|
+
});
|
|
151
|
+
factory.on = ((...args) => {
|
|
152
|
+
const parsed = parseOnArgs(args, decoratorName);
|
|
153
|
+
return this.createMemberDecorator('property', decoratorName, parsed);
|
|
154
|
+
});
|
|
155
|
+
return factory;
|
|
156
|
+
}
|
|
157
|
+
createMethodFactory(decoratorName) {
|
|
158
|
+
const factory = ((...args) => {
|
|
159
|
+
const parsed = parseDirectArgs(args, decoratorName);
|
|
160
|
+
return this.createMemberDecorator('method', decoratorName, parsed);
|
|
161
|
+
});
|
|
162
|
+
factory.on = ((...args) => {
|
|
163
|
+
const parsed = parseOnArgs(args, decoratorName);
|
|
164
|
+
return this.createMemberDecorator('method', decoratorName, parsed);
|
|
165
|
+
});
|
|
166
|
+
return factory;
|
|
167
|
+
}
|
|
168
|
+
createAccessorFactory(decoratorName) {
|
|
169
|
+
const factory = ((...args) => {
|
|
170
|
+
const parsed = parseDirectArgs(args, decoratorName);
|
|
171
|
+
return this.createMemberDecorator('accessor', decoratorName, parsed);
|
|
172
|
+
});
|
|
173
|
+
factory.on = ((...args) => {
|
|
174
|
+
const parsed = parseOnArgs(args, decoratorName);
|
|
175
|
+
return this.createMemberDecorator('accessor', decoratorName, parsed);
|
|
176
|
+
});
|
|
177
|
+
return factory;
|
|
178
|
+
}
|
|
179
|
+
createMemberDecorator(kind, decoratorName, parsed) {
|
|
180
|
+
return (_value, context) => {
|
|
181
|
+
assertContextKind(kind, decoratorName, context);
|
|
182
|
+
if (context.private && !this.allowPrivateMembers) {
|
|
183
|
+
throw new Error(`Decorator "${decoratorName}" cannot be used on private member "${String(context.name)}" unless allowPrivateMembers is true.`);
|
|
184
|
+
}
|
|
185
|
+
if (parsed.key !== undefined && !samePropertyKey(parsed.key, context.name)) {
|
|
186
|
+
throw new Error(`Decorator "${decoratorName}" was keyed for "${String(parsed.key)}" but applied to "${String(context.name)}".`);
|
|
187
|
+
}
|
|
188
|
+
this.register(context.metadata, {
|
|
189
|
+
kind,
|
|
190
|
+
decorator: decoratorName,
|
|
191
|
+
metadata: parsed.metadata,
|
|
192
|
+
memberName: context.name,
|
|
193
|
+
static: context.static,
|
|
194
|
+
private: context.private,
|
|
195
|
+
});
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
register(metadataObject, record) {
|
|
199
|
+
const order = this.nextOrder;
|
|
200
|
+
this.nextOrder += 1;
|
|
201
|
+
const immutableRecord = Object.freeze(Object.assign(Object.assign({}, record), { id: `${this.namespace}:${record.kind}:${record.decorator}:${order}`, order, metadata: (0, clone_1.immutableClone)(record.metadata) }));
|
|
202
|
+
const existing = this.recordsByMetadata.get(metadataObject);
|
|
203
|
+
if (existing === undefined) {
|
|
204
|
+
this.recordsByMetadata.set(metadataObject, [immutableRecord]);
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
existing.push(immutableRecord);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
function createDecoratorRegistry(options = {}) {
|
|
212
|
+
return new ModernDecoratorRegistry(options);
|
|
213
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
type ViewDecorators = {
|
|
2
|
+
class: {};
|
|
3
|
+
property: {};
|
|
4
|
+
method: {};
|
|
5
|
+
accessor: {
|
|
6
|
+
cached: {
|
|
7
|
+
metadata: {
|
|
8
|
+
ttlMs?: number;
|
|
9
|
+
};
|
|
10
|
+
target: string;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
type UserViewContract = {
|
|
15
|
+
displayName: string;
|
|
16
|
+
};
|
|
17
|
+
declare const registry: import("../types").DecoratorRegistry<ViewDecorators>;
|
|
18
|
+
declare class UserView implements UserViewContract {
|
|
19
|
+
accessor displayName: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function readAccessorMetadata(): {
|
|
22
|
+
memberName: string | symbol;
|
|
23
|
+
ttlMs: number | undefined;
|
|
24
|
+
}[];
|
|
25
|
+
export { UserView, registry as accessorRegistry };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
3
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
4
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
5
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
6
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
7
|
+
var _, done = false;
|
|
8
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
9
|
+
var context = {};
|
|
10
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
11
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
12
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
13
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
14
|
+
if (kind === "accessor") {
|
|
15
|
+
if (result === void 0) continue;
|
|
16
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
17
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
18
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
19
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
20
|
+
}
|
|
21
|
+
else if (_ = accept(result)) {
|
|
22
|
+
if (kind === "field") initializers.unshift(_);
|
|
23
|
+
else descriptor[key] = _;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
27
|
+
done = true;
|
|
28
|
+
};
|
|
29
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
30
|
+
var useValue = arguments.length > 2;
|
|
31
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
32
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
33
|
+
}
|
|
34
|
+
return useValue ? value : void 0;
|
|
35
|
+
};
|
|
36
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
37
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
38
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
39
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
40
|
+
};
|
|
41
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
42
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
43
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
44
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
45
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
46
|
+
};
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
exports.accessorRegistry = exports.UserView = void 0;
|
|
49
|
+
exports.readAccessorMetadata = readAccessorMetadata;
|
|
50
|
+
const index_1 = require("../index");
|
|
51
|
+
const registry = (0, index_1.createDecoratorRegistry)({ namespace: 'accessor-example' });
|
|
52
|
+
exports.accessorRegistry = registry;
|
|
53
|
+
const View = registry.for();
|
|
54
|
+
const Cached = View.accessor('cached');
|
|
55
|
+
let UserView = (() => {
|
|
56
|
+
var _a, _UserView_displayName_accessor_storage;
|
|
57
|
+
let _displayName_decorators;
|
|
58
|
+
let _displayName_initializers = [];
|
|
59
|
+
let _displayName_extraInitializers = [];
|
|
60
|
+
return _a = class UserView {
|
|
61
|
+
get displayName() { return __classPrivateFieldGet(this, _UserView_displayName_accessor_storage, "f"); }
|
|
62
|
+
set displayName(value) { __classPrivateFieldSet(this, _UserView_displayName_accessor_storage, value, "f"); }
|
|
63
|
+
constructor() {
|
|
64
|
+
_UserView_displayName_accessor_storage.set(this, __runInitializers(this, _displayName_initializers, 'Ray'));
|
|
65
|
+
__runInitializers(this, _displayName_extraInitializers);
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
_UserView_displayName_accessor_storage = new WeakMap(),
|
|
69
|
+
(() => {
|
|
70
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
71
|
+
_displayName_decorators = [Cached('displayName', { ttlMs: 1000 })];
|
|
72
|
+
__esDecorate(_a, null, _displayName_decorators, { kind: "accessor", name: "displayName", static: false, private: false, access: { has: obj => "displayName" in obj, get: obj => obj.displayName, set: (obj, value) => { obj.displayName = value; } }, metadata: _metadata }, _displayName_initializers, _displayName_extraInitializers);
|
|
73
|
+
if (_metadata) Object.defineProperty(_a, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
74
|
+
})(),
|
|
75
|
+
_a;
|
|
76
|
+
})();
|
|
77
|
+
exports.UserView = UserView;
|
|
78
|
+
function readAccessorMetadata() {
|
|
79
|
+
return registry.read(UserView).accessorRecords('cached').map((record) => {
|
|
80
|
+
if (record.memberName === undefined)
|
|
81
|
+
throw new Error('Missing member name.');
|
|
82
|
+
return {
|
|
83
|
+
memberName: record.memberName,
|
|
84
|
+
ttlMs: record.metadata.ttlMs,
|
|
85
|
+
};
|
|
86
|
+
});
|
|
87
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
type CrudController<TEntity, TCreateInput> = {
|
|
2
|
+
id: string;
|
|
3
|
+
get(id: string): Promise<TEntity>;
|
|
4
|
+
create(input: TCreateInput): Promise<TEntity>;
|
|
5
|
+
};
|
|
6
|
+
type UserDto = {
|
|
7
|
+
id: string;
|
|
8
|
+
email: string;
|
|
9
|
+
};
|
|
10
|
+
type CreateUserInput = {
|
|
11
|
+
email: string;
|
|
12
|
+
};
|
|
13
|
+
type UserCrudController = CrudController<UserDto, CreateUserInput>;
|
|
14
|
+
type CrudDecorators = {
|
|
15
|
+
class: {
|
|
16
|
+
resource: {
|
|
17
|
+
metadata: {
|
|
18
|
+
name: string;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
property: {
|
|
23
|
+
idField: {
|
|
24
|
+
metadata: undefined;
|
|
25
|
+
target: string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
method: {
|
|
29
|
+
route: {
|
|
30
|
+
metadata: {
|
|
31
|
+
method: 'GET' | 'POST';
|
|
32
|
+
path: string;
|
|
33
|
+
};
|
|
34
|
+
target: (...args: any[]) => Promise<unknown>;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
accessor: {};
|
|
38
|
+
};
|
|
39
|
+
declare const registry: import("../types").DecoratorRegistry<CrudDecorators>;
|
|
40
|
+
declare class UserCrud implements UserCrudController {
|
|
41
|
+
id: string;
|
|
42
|
+
get(id: string): Promise<UserDto>;
|
|
43
|
+
create(input: CreateUserInput): Promise<UserDto>;
|
|
44
|
+
}
|
|
45
|
+
export declare function buildCrudSummary(): {
|
|
46
|
+
resource: string;
|
|
47
|
+
routes: string[];
|
|
48
|
+
idFields: Array<string | symbol>;
|
|
49
|
+
};
|
|
50
|
+
export { UserCrud, registry as crudRegistry };
|