mutts 1.0.0 → 1.0.1
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/dist/chunks/{decorator-BXsign4Z.js → decorator-8qjFb7dw.js} +2 -2
- package/dist/chunks/decorator-8qjFb7dw.js.map +1 -0
- package/dist/chunks/{decorator-CPbZNnsX.esm.js → decorator-AbRkXM5O.esm.js} +2 -2
- package/dist/chunks/decorator-AbRkXM5O.esm.js.map +1 -0
- package/dist/decorator.d.ts +1 -1
- package/dist/decorator.esm.js +1 -1
- package/dist/decorator.js +1 -1
- package/dist/destroyable.esm.js +1 -1
- package/dist/destroyable.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.esm.js +2 -2
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/mutts.umd.js +1 -1
- package/dist/mutts.umd.js.map +1 -1
- package/dist/mutts.umd.min.js +1 -1
- package/dist/mutts.umd.min.js.map +1 -1
- package/dist/reactive.d.ts +4 -3
- package/dist/reactive.esm.js +61 -57
- package/dist/reactive.esm.js.map +1 -1
- package/dist/reactive.js +61 -56
- package/dist/reactive.js.map +1 -1
- package/dist/std-decorators.esm.js +1 -1
- package/dist/std-decorators.js +1 -1
- package/docs/reactive.md +616 -0
- package/package.json +1 -2
- package/dist/chunks/decorator-BXsign4Z.js.map +0 -1
- package/dist/chunks/decorator-CPbZNnsX.esm.js.map +0 -1
- package/src/decorator.test.ts +0 -495
- package/src/decorator.ts +0 -205
- package/src/destroyable.test.ts +0 -155
- package/src/destroyable.ts +0 -158
- package/src/eventful.test.ts +0 -380
- package/src/eventful.ts +0 -69
- package/src/index.ts +0 -7
- package/src/indexable.test.ts +0 -388
- package/src/indexable.ts +0 -124
- package/src/promiseChain.test.ts +0 -201
- package/src/promiseChain.ts +0 -99
- package/src/reactive/array.test.ts +0 -923
- package/src/reactive/array.ts +0 -352
- package/src/reactive/core.test.ts +0 -1663
- package/src/reactive/core.ts +0 -866
- package/src/reactive/index.ts +0 -28
- package/src/reactive/interface.test.ts +0 -1477
- package/src/reactive/interface.ts +0 -231
- package/src/reactive/map.test.ts +0 -866
- package/src/reactive/map.ts +0 -162
- package/src/reactive/set.test.ts +0 -289
- package/src/reactive/set.ts +0 -142
- package/src/std-decorators.test.ts +0 -679
- package/src/std-decorators.ts +0 -182
- package/src/utils.ts +0 -52
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"decorator-CPbZNnsX.esm.js","sources":["../../src/utils.ts","../../src/decorator.ts"],"sourcesContent":["type ElementTypes<T extends readonly unknown[]> = {\n\t[K in keyof T]: T[K] extends readonly (infer U)[] ? U : T[K]\n}\n\nexport function zip<T extends (readonly unknown[])[]>(...args: T): ElementTypes<T>[] {\n\tif (!args.length) return []\n\tconst minLength = Math.min(...args.map((arr) => arr.length))\n\tconst result: ElementTypes<T>[] = []\n\n\tfor (let i = 0; i < minLength; i++) {\n\t\tconst tuple = args.map((arr) => arr[i]) as ElementTypes<T>\n\t\tresult.push(tuple)\n\t}\n\n\treturn result\n}\n\nconst nativeConstructors = new Set<Function>([\n\tObject,\n\tArray,\n\tDate,\n\tFunction,\n\tSet,\n\tMap,\n\tWeakMap,\n\tWeakSet,\n\tPromise,\n\tError,\n\tTypeError,\n\tReferenceError,\n\tSyntaxError,\n\tRangeError,\n\tURIError,\n\tEvalError,\n\tReflect,\n\tProxy,\n\tRegExp,\n\tString,\n\tNumber,\n\tBoolean,\n] as Function[])\nexport function isConstructor(fn: Function): boolean {\n\treturn fn && (nativeConstructors.has(fn) || fn.toString().startsWith('class '))\n}\n\nexport function renamed<F extends Function>(fct: F, name: string): F {\n\treturn Object.defineProperties(fct, {\n\t\tname: {\n\t\t\tvalue: name,\n\t\t},\n\t})\n}\n","// biome-ignore-all lint/suspicious/noConfusingVoidType: We *love* voids\n// Standardized decorator system that works with both Legacy and Modern decorators\n\nimport { isConstructor } from './utils'\n\nexport class DecoratorError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message)\n\t\tthis.name = 'DecoratorException'\n\t}\n}\n//#region all decorator types\n\n// Used for get/set and method decorators\nexport type LegacyPropertyDecorator<T> = (\n\ttarget: T,\n\tname: string | symbol,\n\tdescriptor: PropertyDescriptor\n) => any\n\nexport type LegacyClassDecorator<T> = (target: T) => any\n\nexport type ModernMethodDecorator<T> = (target: T, context: ClassMethodDecoratorContext) => any\n\nexport type ModernGetterDecorator<T> = (target: T, context: ClassGetterDecoratorContext) => any\n\nexport type ModernSetterDecorator<T> = (target: T, context: ClassSetterDecoratorContext) => any\n\nexport type ModernAccessorDecorator<T> = (target: T, context: ClassAccessorDecoratorContext) => any\n\nexport type ModernClassDecorator<T> = (target: T, context: ClassDecoratorContext) => any\n\n//#endregion\n\ntype DDMethod<T> = (\n\toriginal: (this: T, ...args: any[]) => any,\n\tname: PropertyKey\n) => ((this: T, ...args: any[]) => any) | void\n\ntype DDGetter<T> = (original: (this: T) => any, name: PropertyKey) => ((this: T) => any) | void\n\ntype DDSetter<T> = (\n\toriginal: (this: T, value: any) => void,\n\tname: PropertyKey\n) => ((this: T, value: any) => void) | void\n\ntype DDClass<T> = <Ctor extends new (...args: any[]) => T = new (...args: any[]) => T>(\n\ttarget: Ctor\n) => Ctor | void\nexport interface DecoratorDescription<T> {\n\tmethod?: DDMethod<T>\n\tclass?: DDClass<T>\n\tgetter?: DDGetter<T>\n\tsetter?: DDSetter<T>\n\tdefault?: (...args: any[]) => any\n}\n\nexport type Decorator<T, Description extends DecoratorDescription<T>> = (Description extends {\n\tmethod: DDMethod<T>\n}\n\t? LegacyPropertyDecorator<T> & ModernMethodDecorator<T>\n\t: unknown) &\n\t(Description extends { class: DDClass<new (...args: any[]) => T> }\n\t\t? LegacyClassDecorator<new (...args: any[]) => T> &\n\t\t\t\tModernClassDecorator<new (...args: any[]) => T>\n\t\t: unknown) &\n\t(Description extends { getter: DDGetter<T> }\n\t\t? LegacyPropertyDecorator<T> & ModernGetterDecorator<T> & ModernAccessorDecorator<T>\n\t\t: unknown) &\n\t(Description extends { setter: DDSetter<T> }\n\t\t? LegacyPropertyDecorator<T> & ModernSetterDecorator<T> & ModernAccessorDecorator<T>\n\t\t: unknown) &\n\t(Description extends { default: infer Signature } ? Signature : unknown)\n\nexport type DecoratorFactory<T> = <Description extends DecoratorDescription<T>>(\n\tdescription: Description\n) => (Description extends { method: DDMethod<T> }\n\t? LegacyPropertyDecorator<T> & ModernMethodDecorator<T>\n\t: unknown) &\n\t(Description extends { class: DDClass<new (...args: any[]) => T> }\n\t\t? LegacyClassDecorator<new (...args: any[]) => T> &\n\t\t\t\tModernClassDecorator<new (...args: any[]) => T>\n\t\t: unknown) &\n\t(Description extends { getter: DDGetter<T> }\n\t\t? LegacyPropertyDecorator<T> & ModernGetterDecorator<T> & ModernAccessorDecorator<T>\n\t\t: unknown) &\n\t(Description extends { setter: DDSetter<T> }\n\t\t? LegacyPropertyDecorator<T> & ModernSetterDecorator<T> & ModernAccessorDecorator<T>\n\t\t: unknown) &\n\t(Description extends { default: infer Signature } ? Signature : unknown)\n\nexport function legacyDecorator<T = any>(description: DecoratorDescription<T>): any {\n\treturn function (\n\t\ttarget: any,\n\t\tpropertyKey?: PropertyKey,\n\t\tdescriptor?: PropertyDescriptor,\n\t\t...args: any[]\n\t) {\n\t\tif (propertyKey === undefined) {\n\t\t\tif (isConstructor(target)) {\n\t\t\t\tif (!('class' in description)) throw new Error('Decorator cannot be applied to a class')\n\t\t\t\treturn description.class?.(target)\n\t\t\t}\n\t\t} else if (typeof target === 'object' && ['string', 'symbol'].includes(typeof propertyKey)) {\n\t\t\tif (!descriptor) throw new Error('Decorator cannot be applied to a field')\n\t\t\telse if (typeof descriptor === 'object' && 'configurable' in descriptor) {\n\t\t\t\tif ('get' in descriptor || 'set' in descriptor) {\n\t\t\t\t\tif (!('getter' in description || 'setter' in description))\n\t\t\t\t\t\tthrow new Error('Decorator cannot be applied to a getter or setter')\n\t\t\t\t\tif ('getter' in description) {\n\t\t\t\t\t\tconst newGetter = description.getter?.(descriptor.get, propertyKey)\n\t\t\t\t\t\tif (newGetter) descriptor.get = newGetter\n\t\t\t\t\t}\n\t\t\t\t\tif ('setter' in description) {\n\t\t\t\t\t\tconst newSetter = description.setter?.(descriptor.set, propertyKey)\n\t\t\t\t\t\tif (newSetter) descriptor.set = newSetter\n\t\t\t\t\t}\n\t\t\t\t\treturn descriptor\n\t\t\t\t} else if (typeof descriptor.value === 'function') {\n\t\t\t\t\tif (!('method' in description)) throw new Error('Decorator cannot be applied to a method')\n\t\t\t\t\tconst newMethod = description.method?.(descriptor.value, propertyKey)\n\t\t\t\t\tif (newMethod) descriptor.value = newMethod\n\t\t\t\t\treturn descriptor\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!('default' in description))\n\t\t\tthrow new Error('Decorator do not have a default implementation')\n\t\treturn description.default.call(this, target, propertyKey, descriptor, ...args)\n\t}\n}\n\nexport function modernDecorator<T = any>(description: DecoratorDescription<T>): any {\n\treturn function (target: any, context?: DecoratorContext, ...args: any[]) {\n\t\tif (!context?.kind || typeof context.kind !== 'string') {\n\t\t\tif (!('default' in description))\n\t\t\t\tthrow new Error('Decorator do not have a default implementation')\n\t\t\treturn description.default.call(this, target, context, ...args)\n\t\t}\n\t\tswitch (context.kind) {\n\t\t\tcase 'class':\n\t\t\t\tif (!('class' in description)) throw new Error('Decorator cannot be applied to a class')\n\t\t\t\treturn description.class?.(target)\n\t\t\tcase 'field':\n\t\t\t\tthrow new Error('Decorator cannot be applied to a field')\n\t\t\tcase 'getter':\n\t\t\t\tif (!('getter' in description)) throw new Error('Decorator cannot be applied to a getter')\n\t\t\t\treturn description.getter?.(target, context.name)\n\t\t\tcase 'setter':\n\t\t\t\tif (!('setter' in description)) throw new Error('Decorator cannot be applied to a setter')\n\t\t\t\treturn description.setter?.(target, context.name)\n\t\t\tcase 'method':\n\t\t\t\tif (!('method' in description)) throw new Error('Decorator cannot be applied to a method')\n\t\t\t\treturn description.method?.(target, context.name)\n\t\t\tcase 'accessor': {\n\t\t\t\tif (!('getter' in description || 'setter' in description))\n\t\t\t\t\tthrow new Error('Decorator cannot be applied to a getter or setter')\n\t\t\t\tconst rv: Partial<ClassAccessorDecoratorResult<any, any>> = {}\n\t\t\t\tif ('getter' in description) {\n\t\t\t\t\tconst newGetter = description.getter?.(target.get, context.name)\n\t\t\t\t\tif (newGetter) rv.get = newGetter\n\t\t\t\t}\n\t\t\t\tif ('setter' in description) {\n\t\t\t\t\tconst newSetter = description.setter?.(target.set, context.name)\n\t\t\t\t\tif (newSetter) rv.set = newSetter\n\t\t\t\t}\n\t\t\t\treturn rv\n\t\t\t}\n\t\t\t//return description.accessor?.(target, context.name, target)\n\t\t}\n\t}\n}\n\n/**\n * Detects if the decorator is being called in modern (Modern) or legacy (Legacy) mode\n * based on the arguments passed to the decorator function\n */\nfunction detectDecoratorMode(\n\t_target: any,\n\tcontextOrKey?: any,\n\t_descriptor?: any\n): 'modern' | 'legacy' {\n\t// Modern decorators have a context object as the second parameter\n\t// Legacy decorators have a string/symbol key as the second parameter\n\tif (\n\t\ttypeof contextOrKey === 'object' &&\n\t\tcontextOrKey !== null &&\n\t\ttypeof contextOrKey.kind === 'string'\n\t) {\n\t\treturn 'modern'\n\t}\n\treturn 'legacy'\n}\n\nexport const decorator: DecoratorFactory<any> = (description: DecoratorDescription<any>) => {\n\treturn ((target: any, contextOrKey?: any, ...args: any[]) => {\n\t\tconst mode = detectDecoratorMode(target, contextOrKey, args[0])\n\t\treturn mode === 'modern'\n\t\t\t? modernDecorator(description)(target, contextOrKey, ...args)\n\t\t\t: legacyDecorator(description)(target, contextOrKey, ...args)\n\t}) as any\n}\n\nexport type GenericClassDecorator<T> = LegacyClassDecorator<new (...args: any[]) => T> &\n\tModernClassDecorator<new (...args: any[]) => T>\n"],"names":[],"mappings":"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"}
|
package/src/decorator.test.ts
DELETED
|
@@ -1,495 +0,0 @@
|
|
|
1
|
-
// Test the decorator system with all decorator types
|
|
2
|
-
import { decorator } from './decorator'
|
|
3
|
-
|
|
4
|
-
describe('Decorator System', () => {
|
|
5
|
-
describe('Method Decorators', () => {
|
|
6
|
-
it('should wrap method calls', () => {
|
|
7
|
-
const methodDecorator = decorator({
|
|
8
|
-
method(original, _name) {
|
|
9
|
-
return function (this: any, ...args: any[]) {
|
|
10
|
-
return `wrapped: ${original.apply(this, args)}`
|
|
11
|
-
}
|
|
12
|
-
},
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
class TestClass {
|
|
16
|
-
@methodDecorator
|
|
17
|
-
greet(name: string) {
|
|
18
|
-
return `Hello ${name}`
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const instance = new TestClass()
|
|
23
|
-
expect(instance.greet('World')).toBe('wrapped: Hello World')
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
it('should work with multiple methods', () => {
|
|
27
|
-
const methodDecorator = decorator({
|
|
28
|
-
method(original, name) {
|
|
29
|
-
return function (this: any, ...args: any[]) {
|
|
30
|
-
return `${String(name)}: ${original.apply(this, args)}`
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
})
|
|
34
|
-
|
|
35
|
-
class TestClass {
|
|
36
|
-
@methodDecorator
|
|
37
|
-
first() {
|
|
38
|
-
return 'first'
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
@methodDecorator
|
|
42
|
-
second() {
|
|
43
|
-
return 'second'
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const instance = new TestClass()
|
|
48
|
-
expect(instance.first()).toBe('first: first')
|
|
49
|
-
expect(instance.second()).toBe('second: second')
|
|
50
|
-
})
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
describe('Class Decorators', () => {
|
|
54
|
-
it('should modify class behavior', () => {
|
|
55
|
-
const classDecorator = decorator({
|
|
56
|
-
class: (target) => {
|
|
57
|
-
// Add a static property to the class
|
|
58
|
-
;(target as any).decorated = true
|
|
59
|
-
return target
|
|
60
|
-
},
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
@classDecorator
|
|
64
|
-
class TestClass {
|
|
65
|
-
static original = 'original'
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
expect((TestClass as any).decorated).toBe(true)
|
|
69
|
-
expect(TestClass.original).toBe('original')
|
|
70
|
-
})
|
|
71
|
-
|
|
72
|
-
it('should work with class inheritance', () => {
|
|
73
|
-
const classDecorator = decorator({
|
|
74
|
-
class: (target) => {
|
|
75
|
-
;(target as any).decorated = true
|
|
76
|
-
return target
|
|
77
|
-
},
|
|
78
|
-
})
|
|
79
|
-
|
|
80
|
-
@classDecorator
|
|
81
|
-
class BaseClass {}
|
|
82
|
-
|
|
83
|
-
class ExtendedClass extends BaseClass {}
|
|
84
|
-
|
|
85
|
-
expect((BaseClass as any).decorated).toBe(true)
|
|
86
|
-
// In legacy decorators, the decorator is applied to the class itself
|
|
87
|
-
// so ExtendedClass should also have the decorated property
|
|
88
|
-
expect((ExtendedClass as any).decorated).toBe(true)
|
|
89
|
-
})
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
describe('Getter Decorators', () => {
|
|
93
|
-
it('should wrap getter calls', () => {
|
|
94
|
-
const getterDecorator = decorator({
|
|
95
|
-
getter(original, _name) {
|
|
96
|
-
return function (this: any) {
|
|
97
|
-
return `wrapped: ${original.call(this)}`
|
|
98
|
-
}
|
|
99
|
-
},
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
class TestClass {
|
|
103
|
-
private _value = 'test'
|
|
104
|
-
|
|
105
|
-
@getterDecorator
|
|
106
|
-
get value() {
|
|
107
|
-
return this._value
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const instance = new TestClass()
|
|
112
|
-
expect(instance.value).toBe('wrapped: test')
|
|
113
|
-
})
|
|
114
|
-
|
|
115
|
-
it('should work with multiple getters', () => {
|
|
116
|
-
const getterDecorator = decorator({
|
|
117
|
-
getter(original, name) {
|
|
118
|
-
return function (this: any) {
|
|
119
|
-
return `${String(name)}: ${original.call(this)}`
|
|
120
|
-
}
|
|
121
|
-
},
|
|
122
|
-
})
|
|
123
|
-
|
|
124
|
-
class TestClass {
|
|
125
|
-
private _first = 'first'
|
|
126
|
-
private _second = 'second'
|
|
127
|
-
|
|
128
|
-
@getterDecorator
|
|
129
|
-
get first() {
|
|
130
|
-
return this._first
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
@getterDecorator
|
|
134
|
-
get second() {
|
|
135
|
-
return this._second
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const instance = new TestClass()
|
|
140
|
-
expect(instance.first).toBe('first: first')
|
|
141
|
-
expect(instance.second).toBe('second: second')
|
|
142
|
-
})
|
|
143
|
-
})
|
|
144
|
-
|
|
145
|
-
describe('Setter Decorators', () => {
|
|
146
|
-
it('should wrap setter calls', () => {
|
|
147
|
-
const setterDecorator = decorator({
|
|
148
|
-
setter(original, _name) {
|
|
149
|
-
return function (this: any, value: any) {
|
|
150
|
-
return original.call(this, `wrapped: ${value}`)
|
|
151
|
-
}
|
|
152
|
-
},
|
|
153
|
-
})
|
|
154
|
-
|
|
155
|
-
class TestClass {
|
|
156
|
-
private _value = ''
|
|
157
|
-
|
|
158
|
-
@setterDecorator
|
|
159
|
-
set value(v: string) {
|
|
160
|
-
this._value = v
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
get value() {
|
|
164
|
-
return this._value
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
const instance = new TestClass()
|
|
169
|
-
instance.value = 'test'
|
|
170
|
-
expect(instance.value).toBe('wrapped: test')
|
|
171
|
-
})
|
|
172
|
-
|
|
173
|
-
it('should work with multiple setters', () => {
|
|
174
|
-
const setterDecorator = decorator({
|
|
175
|
-
setter(original, name) {
|
|
176
|
-
return function (this: any, value: any) {
|
|
177
|
-
return original.call(this, `${String(name)}: ${value}`)
|
|
178
|
-
}
|
|
179
|
-
},
|
|
180
|
-
})
|
|
181
|
-
|
|
182
|
-
class TestClass {
|
|
183
|
-
private _first = ''
|
|
184
|
-
private _second = ''
|
|
185
|
-
|
|
186
|
-
@setterDecorator
|
|
187
|
-
set first(v: string) {
|
|
188
|
-
this._first = v
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
@setterDecorator
|
|
192
|
-
set second(v: string) {
|
|
193
|
-
this._second = v
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
get first() {
|
|
197
|
-
return this._first
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
get second() {
|
|
201
|
-
return this._second
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
const instance = new TestClass()
|
|
206
|
-
instance.first = 'test1'
|
|
207
|
-
instance.second = 'test2'
|
|
208
|
-
expect(instance.first).toBe('first: test1')
|
|
209
|
-
expect(instance.second).toBe('second: test2')
|
|
210
|
-
})
|
|
211
|
-
})
|
|
212
|
-
|
|
213
|
-
describe('Combined Decorators', () => {
|
|
214
|
-
it('should work with method and class decorators together', () => {
|
|
215
|
-
const myDecorator = decorator({
|
|
216
|
-
class: (target) => {
|
|
217
|
-
;(target as any).decorated = true
|
|
218
|
-
return target
|
|
219
|
-
},
|
|
220
|
-
method(original, _name) {
|
|
221
|
-
return function (this: any, ...args: any[]) {
|
|
222
|
-
return `method: ${original.apply(this, args)}`
|
|
223
|
-
}
|
|
224
|
-
},
|
|
225
|
-
})
|
|
226
|
-
|
|
227
|
-
@myDecorator
|
|
228
|
-
class TestClass {
|
|
229
|
-
@myDecorator
|
|
230
|
-
greet(name: string) {
|
|
231
|
-
return `Hello ${name}`
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
expect((TestClass as any).decorated).toBe(true)
|
|
236
|
-
const instance = new TestClass()
|
|
237
|
-
expect(instance.greet('World')).toBe('method: Hello World')
|
|
238
|
-
})
|
|
239
|
-
|
|
240
|
-
it('should work with getter and setter decorators on different properties', () => {
|
|
241
|
-
const myDecorator = decorator({
|
|
242
|
-
getter(original, _name) {
|
|
243
|
-
return function (this: any) {
|
|
244
|
-
return `get: ${original.call(this)}`
|
|
245
|
-
}
|
|
246
|
-
},
|
|
247
|
-
setter(original, _name) {
|
|
248
|
-
return function (this: any, value: any) {
|
|
249
|
-
return original.call(this, `set: ${value}`)
|
|
250
|
-
}
|
|
251
|
-
},
|
|
252
|
-
})
|
|
253
|
-
|
|
254
|
-
class TestClass {
|
|
255
|
-
private _value1 = ''
|
|
256
|
-
private _value2 = ''
|
|
257
|
-
|
|
258
|
-
@myDecorator
|
|
259
|
-
get value1() {
|
|
260
|
-
return this._value1
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
@myDecorator
|
|
264
|
-
set value2(v: string) {
|
|
265
|
-
this._value2 = v
|
|
266
|
-
}
|
|
267
|
-
//@ts-ignore: The end-user should put a decorator here if modern, and not if legacy
|
|
268
|
-
@myDecorator
|
|
269
|
-
get value2() {
|
|
270
|
-
return this._value2
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
const instance = new TestClass()
|
|
275
|
-
instance.value2 = 'test'
|
|
276
|
-
expect(instance.value1).toBe('get: ')
|
|
277
|
-
expect(instance.value2).toBe('get: set: test')
|
|
278
|
-
})
|
|
279
|
-
|
|
280
|
-
it('should work with all decorator types together', () => {
|
|
281
|
-
const myDecorator = decorator({
|
|
282
|
-
class: (target) => {
|
|
283
|
-
;(target as any).decorated = true
|
|
284
|
-
return target
|
|
285
|
-
},
|
|
286
|
-
method(original, _name) {
|
|
287
|
-
return function (this: any, ...args: any[]) {
|
|
288
|
-
return `method: ${original.apply(this, args)}`
|
|
289
|
-
}
|
|
290
|
-
},
|
|
291
|
-
getter(original, _name) {
|
|
292
|
-
return function (this: any) {
|
|
293
|
-
return `get: ${original.call(this)}`
|
|
294
|
-
}
|
|
295
|
-
},
|
|
296
|
-
default(...args) {
|
|
297
|
-
return args.length
|
|
298
|
-
},
|
|
299
|
-
})
|
|
300
|
-
|
|
301
|
-
@myDecorator
|
|
302
|
-
class TestClass {
|
|
303
|
-
value = 'initial'
|
|
304
|
-
|
|
305
|
-
@myDecorator
|
|
306
|
-
greet(name: string) {
|
|
307
|
-
return `Hello ${name}`
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
private _data = ''
|
|
311
|
-
|
|
312
|
-
@myDecorator
|
|
313
|
-
get data() {
|
|
314
|
-
return this._data
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
set data(v: string) {
|
|
318
|
-
this._data = v
|
|
319
|
-
}
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
// Test class decoration
|
|
323
|
-
expect((TestClass as any).decorated).toBe(true)
|
|
324
|
-
|
|
325
|
-
const instance = new TestClass()
|
|
326
|
-
|
|
327
|
-
// Test method decoration
|
|
328
|
-
expect(instance.greet('World')).toBe('method: Hello World')
|
|
329
|
-
|
|
330
|
-
// Test accessor decoration
|
|
331
|
-
instance.data = 'test'
|
|
332
|
-
expect(instance.data).toBe('get: test')
|
|
333
|
-
expect(myDecorator(1, 2, 3)).toBe(3)
|
|
334
|
-
})
|
|
335
|
-
|
|
336
|
-
it('should call all decorator types without changing behavior', () => {
|
|
337
|
-
const callLog: string[] = []
|
|
338
|
-
|
|
339
|
-
const noOpDecorator = decorator({
|
|
340
|
-
class(original) {
|
|
341
|
-
callLog.push('class decorator called')
|
|
342
|
-
return original // Return unchanged
|
|
343
|
-
},
|
|
344
|
-
method(original, name) {
|
|
345
|
-
callLog.push(`method decorator called for ${String(name)}`)
|
|
346
|
-
return original // Return unchanged
|
|
347
|
-
},
|
|
348
|
-
getter(original, name) {
|
|
349
|
-
callLog.push(`getter decorator called for ${String(name)}`)
|
|
350
|
-
return original // Return unchanged
|
|
351
|
-
},
|
|
352
|
-
setter(original, name) {
|
|
353
|
-
callLog.push(`setter decorator called for ${String(name)}`)
|
|
354
|
-
return original // Return unchanged
|
|
355
|
-
},
|
|
356
|
-
})
|
|
357
|
-
|
|
358
|
-
@noOpDecorator
|
|
359
|
-
class TestClass {
|
|
360
|
-
value = 'initial'
|
|
361
|
-
|
|
362
|
-
@noOpDecorator
|
|
363
|
-
greet(name: string) {
|
|
364
|
-
return `Hello ${name}`
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
private _data = ''
|
|
368
|
-
|
|
369
|
-
@noOpDecorator
|
|
370
|
-
get data() {
|
|
371
|
-
return this._data
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
set data(v: string) {
|
|
375
|
-
this._data = v
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
// Verify all decorators were called
|
|
380
|
-
expect(callLog).toContain('class decorator called')
|
|
381
|
-
expect(callLog).toContain('method decorator called for greet')
|
|
382
|
-
expect(callLog).toContain('getter decorator called for data')
|
|
383
|
-
|
|
384
|
-
const instance = new TestClass()
|
|
385
|
-
|
|
386
|
-
// Verify behavior is unchanged (no wrapping occurred)
|
|
387
|
-
expect(instance.greet('World')).toBe('Hello World') // No "method:" prefix
|
|
388
|
-
expect(instance.value).toBe('initial')
|
|
389
|
-
|
|
390
|
-
instance.data = 'test'
|
|
391
|
-
expect(instance.data).toBe('test') // No "get:" prefix
|
|
392
|
-
})
|
|
393
|
-
|
|
394
|
-
it('should call setter decorator without changing behavior', () => {
|
|
395
|
-
const callLog: string[] = []
|
|
396
|
-
|
|
397
|
-
const noOpDecorator = decorator({
|
|
398
|
-
setter(original, name) {
|
|
399
|
-
callLog.push(`setter decorator called for ${String(name)}`)
|
|
400
|
-
return original // Return unchanged
|
|
401
|
-
},
|
|
402
|
-
})
|
|
403
|
-
|
|
404
|
-
class TestClass {
|
|
405
|
-
private _value = ''
|
|
406
|
-
|
|
407
|
-
@noOpDecorator
|
|
408
|
-
set value(v: string) {
|
|
409
|
-
this._value = v
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
get value() {
|
|
413
|
-
return this._value
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
// Verify setter decorator was called
|
|
418
|
-
expect(callLog).toContain('setter decorator called for value')
|
|
419
|
-
|
|
420
|
-
const instance = new TestClass()
|
|
421
|
-
|
|
422
|
-
// Verify behavior is unchanged (no wrapping occurred)
|
|
423
|
-
instance.value = 'test'
|
|
424
|
-
expect(instance.value).toBe('test') // No wrapping
|
|
425
|
-
})
|
|
426
|
-
})
|
|
427
|
-
|
|
428
|
-
describe('Error Handling', () => {
|
|
429
|
-
it('should throw error when decorator is applied to wrong target', () => {
|
|
430
|
-
const methodOnlyDecorator = decorator({
|
|
431
|
-
method(original, _name) {
|
|
432
|
-
return original
|
|
433
|
-
},
|
|
434
|
-
})
|
|
435
|
-
|
|
436
|
-
expect(() => {
|
|
437
|
-
class TestClass {
|
|
438
|
-
// @ts-ignore
|
|
439
|
-
@methodOnlyDecorator
|
|
440
|
-
value = 'test'
|
|
441
|
-
}
|
|
442
|
-
void new TestClass()
|
|
443
|
-
}).toThrow('Decorator cannot be applied to a field')
|
|
444
|
-
})
|
|
445
|
-
|
|
446
|
-
it('should throw error when class decorator is applied to method', () => {
|
|
447
|
-
const classOnlyDecorator = decorator({
|
|
448
|
-
class: (target) => target,
|
|
449
|
-
})
|
|
450
|
-
|
|
451
|
-
expect(() => {
|
|
452
|
-
class TestClass {
|
|
453
|
-
// @ts-ignore
|
|
454
|
-
@classOnlyDecorator
|
|
455
|
-
method() {}
|
|
456
|
-
}
|
|
457
|
-
void new TestClass()
|
|
458
|
-
}).toThrow('Decorator cannot be applied to a method')
|
|
459
|
-
})
|
|
460
|
-
|
|
461
|
-
it('should throw error when getter decorator is applied to method', () => {
|
|
462
|
-
const getterOnlyDecorator = decorator({
|
|
463
|
-
getter(original, _name) {
|
|
464
|
-
return original
|
|
465
|
-
},
|
|
466
|
-
})
|
|
467
|
-
|
|
468
|
-
expect(() => {
|
|
469
|
-
class TestClass {
|
|
470
|
-
// @ts-ignore
|
|
471
|
-
@getterOnlyDecorator
|
|
472
|
-
method() {}
|
|
473
|
-
}
|
|
474
|
-
void new TestClass()
|
|
475
|
-
}).toThrow('Decorator cannot be applied to a method')
|
|
476
|
-
})
|
|
477
|
-
|
|
478
|
-
it('should throw error when decorating a field', () => {
|
|
479
|
-
const anyDecorator = decorator({
|
|
480
|
-
method(original, _name) {
|
|
481
|
-
return original
|
|
482
|
-
},
|
|
483
|
-
})
|
|
484
|
-
|
|
485
|
-
expect(() => {
|
|
486
|
-
class TestClass {
|
|
487
|
-
// @ts-ignore
|
|
488
|
-
@anyDecorator
|
|
489
|
-
field = 'value'
|
|
490
|
-
}
|
|
491
|
-
void new TestClass()
|
|
492
|
-
}).toThrow('Decorator cannot be applied to a field')
|
|
493
|
-
})
|
|
494
|
-
})
|
|
495
|
-
})
|