1 | "use strict";
|
---|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
---|
3 | exports.decorate = exports.getDecoratorsForClass = exports.directDecoratorSearch = exports.deepDecoratorSearch = void 0;
|
---|
4 | const util_1 = require("./util");
|
---|
5 | const mixin_tracking_1 = require("./mixin-tracking");
|
---|
6 | const mergeObjectsOfDecorators = (o1, o2) => {
|
---|
7 | var _a, _b;
|
---|
8 | const allKeys = (0, util_1.unique)([...Object.getOwnPropertyNames(o1), ...Object.getOwnPropertyNames(o2)]);
|
---|
9 | const mergedObject = {};
|
---|
10 | for (let key of allKeys)
|
---|
11 | mergedObject[key] = (0, util_1.unique)([...((_a = o1 === null || o1 === void 0 ? void 0 : o1[key]) !== null && _a !== void 0 ? _a : []), ...((_b = o2 === null || o2 === void 0 ? void 0 : o2[key]) !== null && _b !== void 0 ? _b : [])]);
|
---|
12 | return mergedObject;
|
---|
13 | };
|
---|
14 | const mergePropertyAndMethodDecorators = (d1, d2) => {
|
---|
15 | var _a, _b, _c, _d;
|
---|
16 | return ({
|
---|
17 | property: mergeObjectsOfDecorators((_a = d1 === null || d1 === void 0 ? void 0 : d1.property) !== null && _a !== void 0 ? _a : {}, (_b = d2 === null || d2 === void 0 ? void 0 : d2.property) !== null && _b !== void 0 ? _b : {}),
|
---|
18 | method: mergeObjectsOfDecorators((_c = d1 === null || d1 === void 0 ? void 0 : d1.method) !== null && _c !== void 0 ? _c : {}, (_d = d2 === null || d2 === void 0 ? void 0 : d2.method) !== null && _d !== void 0 ? _d : {}),
|
---|
19 | });
|
---|
20 | };
|
---|
21 | const mergeDecorators = (d1, d2) => {
|
---|
22 | var _a, _b, _c, _d, _e, _f;
|
---|
23 | return ({
|
---|
24 | class: (0, util_1.unique)([...(_a = d1 === null || d1 === void 0 ? void 0 : d1.class) !== null && _a !== void 0 ? _a : [], ...(_b = d2 === null || d2 === void 0 ? void 0 : d2.class) !== null && _b !== void 0 ? _b : []]),
|
---|
25 | static: mergePropertyAndMethodDecorators((_c = d1 === null || d1 === void 0 ? void 0 : d1.static) !== null && _c !== void 0 ? _c : {}, (_d = d2 === null || d2 === void 0 ? void 0 : d2.static) !== null && _d !== void 0 ? _d : {}),
|
---|
26 | instance: mergePropertyAndMethodDecorators((_e = d1 === null || d1 === void 0 ? void 0 : d1.instance) !== null && _e !== void 0 ? _e : {}, (_f = d2 === null || d2 === void 0 ? void 0 : d2.instance) !== null && _f !== void 0 ? _f : {}),
|
---|
27 | });
|
---|
28 | };
|
---|
29 | const decorators = new Map();
|
---|
30 | const findAllConstituentClasses = (...classes) => {
|
---|
31 | var _a;
|
---|
32 | const allClasses = new Set();
|
---|
33 | const frontier = new Set([...classes]);
|
---|
34 | while (frontier.size > 0) {
|
---|
35 | for (let clazz of frontier) {
|
---|
36 | const protoChainClasses = (0, util_1.protoChain)(clazz.prototype).map(proto => proto.constructor);
|
---|
37 | const mixinClasses = (_a = (0, mixin_tracking_1.getMixinsForClass)(clazz)) !== null && _a !== void 0 ? _a : [];
|
---|
38 | const potentiallyNewClasses = [...protoChainClasses, ...mixinClasses];
|
---|
39 | const newClasses = potentiallyNewClasses.filter(c => !allClasses.has(c));
|
---|
40 | for (let newClass of newClasses)
|
---|
41 | frontier.add(newClass);
|
---|
42 | allClasses.add(clazz);
|
---|
43 | frontier.delete(clazz);
|
---|
44 | }
|
---|
45 | }
|
---|
46 | return [...allClasses];
|
---|
47 | };
|
---|
48 | const deepDecoratorSearch = (...classes) => {
|
---|
49 | const decoratorsForClassChain = findAllConstituentClasses(...classes)
|
---|
50 | .map(clazz => decorators.get(clazz))
|
---|
51 | .filter(decorators => !!decorators);
|
---|
52 | if (decoratorsForClassChain.length == 0)
|
---|
53 | return {};
|
---|
54 | if (decoratorsForClassChain.length == 1)
|
---|
55 | return decoratorsForClassChain[0];
|
---|
56 | return decoratorsForClassChain.reduce((d1, d2) => mergeDecorators(d1, d2));
|
---|
57 | };
|
---|
58 | exports.deepDecoratorSearch = deepDecoratorSearch;
|
---|
59 | const directDecoratorSearch = (...classes) => {
|
---|
60 | const classDecorators = classes.map(clazz => (0, exports.getDecoratorsForClass)(clazz));
|
---|
61 | if (classDecorators.length === 0)
|
---|
62 | return {};
|
---|
63 | if (classDecorators.length === 1)
|
---|
64 | return classDecorators[0];
|
---|
65 | return classDecorators.reduce((d1, d2) => mergeDecorators(d1, d2));
|
---|
66 | };
|
---|
67 | exports.directDecoratorSearch = directDecoratorSearch;
|
---|
68 | const getDecoratorsForClass = (clazz) => {
|
---|
69 | let decoratorsForClass = decorators.get(clazz);
|
---|
70 | if (!decoratorsForClass) {
|
---|
71 | decoratorsForClass = {};
|
---|
72 | decorators.set(clazz, decoratorsForClass);
|
---|
73 | }
|
---|
74 | return decoratorsForClass;
|
---|
75 | };
|
---|
76 | exports.getDecoratorsForClass = getDecoratorsForClass;
|
---|
77 | const decorateClass = (decorator) => ((clazz) => {
|
---|
78 | const decoratorsForClass = (0, exports.getDecoratorsForClass)(clazz);
|
---|
79 | let classDecorators = decoratorsForClass.class;
|
---|
80 | if (!classDecorators) {
|
---|
81 | classDecorators = [];
|
---|
82 | decoratorsForClass.class = classDecorators;
|
---|
83 | }
|
---|
84 | classDecorators.push(decorator);
|
---|
85 | return decorator(clazz);
|
---|
86 | });
|
---|
87 | const decorateMember = (decorator) => ((object, key, ...otherArgs) => {
|
---|
88 | var _a, _b, _c;
|
---|
89 | const decoratorTargetType = typeof object === 'function' ? 'static' : 'instance';
|
---|
90 | const decoratorType = typeof object[key] === 'function' ? 'method' : 'property';
|
---|
91 | const clazz = decoratorTargetType === 'static' ? object : object.constructor;
|
---|
92 | const decoratorsForClass = (0, exports.getDecoratorsForClass)(clazz);
|
---|
93 | const decoratorsForTargetType = (_a = decoratorsForClass === null || decoratorsForClass === void 0 ? void 0 : decoratorsForClass[decoratorTargetType]) !== null && _a !== void 0 ? _a : {};
|
---|
94 | decoratorsForClass[decoratorTargetType] = decoratorsForTargetType;
|
---|
95 | let decoratorsForType = (_b = decoratorsForTargetType === null || decoratorsForTargetType === void 0 ? void 0 : decoratorsForTargetType[decoratorType]) !== null && _b !== void 0 ? _b : {};
|
---|
96 | decoratorsForTargetType[decoratorType] = decoratorsForType;
|
---|
97 | let decoratorsForKey = (_c = decoratorsForType === null || decoratorsForType === void 0 ? void 0 : decoratorsForType[key]) !== null && _c !== void 0 ? _c : [];
|
---|
98 | decoratorsForType[key] = decoratorsForKey;
|
---|
99 | // @ts-ignore: array is type `A[] | B[]` and item is type `A | B`, so technically a type error, but it's fine
|
---|
100 | decoratorsForKey.push(decorator);
|
---|
101 | // @ts-ignore
|
---|
102 | return decorator(object, key, ...otherArgs);
|
---|
103 | });
|
---|
104 | const decorate = (decorator) => ((...args) => {
|
---|
105 | if (args.length === 1)
|
---|
106 | return decorateClass(decorator)(args[0]);
|
---|
107 | return decorateMember(decorator)(...args);
|
---|
108 | });
|
---|
109 | exports.decorate = decorate;
|
---|