@decaf-ts/decoration 0.0.2

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 (41) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +385 -0
  3. package/dist/decoration.cjs +649 -0
  4. package/dist/decoration.esm.cjs +633 -0
  5. package/lib/constants.cjs +64 -0
  6. package/lib/constants.d.ts +58 -0
  7. package/lib/decoration/Decoration.cjs +270 -0
  8. package/lib/decoration/Decoration.d.ts +196 -0
  9. package/lib/decoration/index.cjs +19 -0
  10. package/lib/decoration/index.d.ts +2 -0
  11. package/lib/decoration/types.cjs +3 -0
  12. package/lib/decoration/types.d.ts +95 -0
  13. package/lib/decorators.cjs +97 -0
  14. package/lib/decorators.d.ts +57 -0
  15. package/lib/esm/constants.d.ts +58 -0
  16. package/lib/esm/constants.js +61 -0
  17. package/lib/esm/decoration/Decoration.d.ts +196 -0
  18. package/lib/esm/decoration/Decoration.js +266 -0
  19. package/lib/esm/decoration/index.d.ts +2 -0
  20. package/lib/esm/decoration/index.js +3 -0
  21. package/lib/esm/decoration/types.d.ts +95 -0
  22. package/lib/esm/decoration/types.js +2 -0
  23. package/lib/esm/decorators.d.ts +57 -0
  24. package/lib/esm/decorators.js +90 -0
  25. package/lib/esm/index.d.ts +21 -0
  26. package/lib/esm/index.js +22 -0
  27. package/lib/esm/metadata/Metadata.d.ts +99 -0
  28. package/lib/esm/metadata/Metadata.js +199 -0
  29. package/lib/esm/metadata/index.d.ts +2 -0
  30. package/lib/esm/metadata/index.js +3 -0
  31. package/lib/esm/metadata/types.d.ts +16 -0
  32. package/lib/esm/metadata/types.js +2 -0
  33. package/lib/index.cjs +39 -0
  34. package/lib/index.d.ts +21 -0
  35. package/lib/metadata/Metadata.cjs +203 -0
  36. package/lib/metadata/Metadata.d.ts +99 -0
  37. package/lib/metadata/index.cjs +19 -0
  38. package/lib/metadata/index.d.ts +2 -0
  39. package/lib/metadata/types.cjs +4 -0
  40. package/lib/metadata/types.d.ts +16 -0
  41. package/package.json +114 -0
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DefaultMetadata = exports.DecorationKeys = exports.ObjectKeySplitter = exports.DefaultFlavour = void 0;
4
+ /**
5
+ * @description Default flavour identifier for the decorator system
6
+ * @summary Defines the default flavour used by the Decoration class when no specific flavour is provided.
7
+ * This constant is used throughout the library as the fallback flavour for decorators.
8
+ * @const DefaultFlavour
9
+ * @memberOf module:decoration
10
+ */
11
+ exports.DefaultFlavour = "decaf";
12
+ /**
13
+ * @description Character used to split nested metadata keys
14
+ * @summary The delimiter used by the metadata store to traverse nested object paths when reading/writing values.
15
+ * @const ObjectKeySplitter
16
+ * @memberOf module:decoration
17
+ */
18
+ exports.ObjectKeySplitter = ".";
19
+ /**
20
+ * @description Enum containing metadata keys used for reflection in the model system
21
+ * @summary Defines the various Model keys used for reflection and metadata storage.
22
+ * These keys are used throughout the library to store and retrieve metadata about models,
23
+ * their properties, and their behavior.
24
+ * @readonly
25
+ * @enum {string}
26
+ * @readonly
27
+ * @memberOf module:decoration
28
+ */
29
+ var DecorationKeys;
30
+ (function (DecorationKeys) {
31
+ /** Storage key used on the constructor to mirror runtime metadata */
32
+ DecorationKeys["REFLECT"] = "__decaf";
33
+ /** Map of model property keys to their reflected design types */
34
+ DecorationKeys["PROPERTIES"] = "properties";
35
+ /** Key under which the model's constructor is stored */
36
+ DecorationKeys["CLASS"] = "class";
37
+ /** Container of human-friendly descriptions per class and property */
38
+ DecorationKeys["DESCRIPTION"] = "description";
39
+ /** Reflect metadata key for design time type of a property */
40
+ DecorationKeys["DESIGN_TYPE"] = "design:type";
41
+ /** Reflect metadata key for constructor parameter types */
42
+ DecorationKeys["DESIGN_PARAMS"] = "design:paramtypes";
43
+ /** Reflect metadata key for method return type */
44
+ DecorationKeys["DESIGN_RETURN"] = "design:returntype";
45
+ })(DecorationKeys || (exports.DecorationKeys = DecorationKeys = {}));
46
+ /**
47
+ * @description Typedef for the default metadata object shape
48
+ * @summary Describes the minimal structure persisted for a model before any metadata is recorded.
49
+ * @template M
50
+ * @typedef {object} DefaultMetadataType<M>
51
+ * @property {Record<string, Constructor | undefined>} properties - Mapping of property names to their design types
52
+ * @memberOf module:decoration
53
+ */
54
+ /**
55
+ * @description Default metadata instance
56
+ * @summary Concrete default metadata object used when initializing metadata for a model
57
+ * @type {DefaultMetadataType<any>}
58
+ * @const DefaultMetadata
59
+ * @memberOf module:decoration
60
+ */
61
+ exports.DefaultMetadata = {
62
+ [DecorationKeys.PROPERTIES]: [],
63
+ };
64
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RhbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NvbnN0YW50cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQTs7Ozs7O0dBTUc7QUFDVSxRQUFBLGNBQWMsR0FBRyxPQUFPLENBQUM7QUFFdEM7Ozs7O0dBS0c7QUFDVSxRQUFBLGlCQUFpQixHQUFHLEdBQUcsQ0FBQztBQUVyQzs7Ozs7Ozs7O0dBU0c7QUFDSCxJQUFZLGNBZVg7QUFmRCxXQUFZLGNBQWM7SUFDeEIscUVBQXFFO0lBQ3JFLHFDQUErQixDQUFBO0lBQy9CLGlFQUFpRTtJQUNqRSwyQ0FBeUIsQ0FBQTtJQUN6Qix3REFBd0Q7SUFDeEQsaUNBQWUsQ0FBQTtJQUNmLHNFQUFzRTtJQUN0RSw2Q0FBMkIsQ0FBQTtJQUMzQiw4REFBOEQ7SUFDOUQsNkNBQTJCLENBQUE7SUFDM0IsMkRBQTJEO0lBQzNELHFEQUFtQyxDQUFBO0lBQ25DLGtEQUFrRDtJQUNsRCxxREFBbUMsQ0FBQTtBQUNyQyxDQUFDLEVBZlcsY0FBYyw4QkFBZCxjQUFjLFFBZXpCO0FBRUQ7Ozs7Ozs7R0FPRztBQUVIOzs7Ozs7R0FNRztBQUNVLFFBQUEsZUFBZSxHQUF1QjtJQUNqRCxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsRUFBRSxFQUFFO0NBQ0MsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJhc2ljTWV0YWRhdGEgfSBmcm9tIFwiLi9tZXRhZGF0YS90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWZhdWx0IGZsYXZvdXIgaWRlbnRpZmllciBmb3IgdGhlIGRlY29yYXRvciBzeXN0ZW1cbiAqIEBzdW1tYXJ5IERlZmluZXMgdGhlIGRlZmF1bHQgZmxhdm91ciB1c2VkIGJ5IHRoZSBEZWNvcmF0aW9uIGNsYXNzIHdoZW4gbm8gc3BlY2lmaWMgZmxhdm91ciBpcyBwcm92aWRlZC5cbiAqIFRoaXMgY29uc3RhbnQgaXMgdXNlZCB0aHJvdWdob3V0IHRoZSBsaWJyYXJ5IGFzIHRoZSBmYWxsYmFjayBmbGF2b3VyIGZvciBkZWNvcmF0b3JzLlxuICogQGNvbnN0IERlZmF1bHRGbGF2b3VyXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRpb25cbiAqL1xuZXhwb3J0IGNvbnN0IERlZmF1bHRGbGF2b3VyID0gXCJkZWNhZlwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDaGFyYWN0ZXIgdXNlZCB0byBzcGxpdCBuZXN0ZWQgbWV0YWRhdGEga2V5c1xuICogQHN1bW1hcnkgVGhlIGRlbGltaXRlciB1c2VkIGJ5IHRoZSBtZXRhZGF0YSBzdG9yZSB0byB0cmF2ZXJzZSBuZXN0ZWQgb2JqZWN0IHBhdGhzIHdoZW4gcmVhZGluZy93cml0aW5nIHZhbHVlcy5cbiAqIEBjb25zdCBPYmplY3RLZXlTcGxpdHRlclxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBPYmplY3RLZXlTcGxpdHRlciA9IFwiLlwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBFbnVtIGNvbnRhaW5pbmcgbWV0YWRhdGEga2V5cyB1c2VkIGZvciByZWZsZWN0aW9uIGluIHRoZSBtb2RlbCBzeXN0ZW1cbiAqIEBzdW1tYXJ5IERlZmluZXMgdGhlIHZhcmlvdXMgTW9kZWwga2V5cyB1c2VkIGZvciByZWZsZWN0aW9uIGFuZCBtZXRhZGF0YSBzdG9yYWdlLlxuICogVGhlc2Uga2V5cyBhcmUgdXNlZCB0aHJvdWdob3V0IHRoZSBsaWJyYXJ5IHRvIHN0b3JlIGFuZCByZXRyaWV2ZSBtZXRhZGF0YSBhYm91dCBtb2RlbHMsXG4gKiB0aGVpciBwcm9wZXJ0aWVzLCBhbmQgdGhlaXIgYmVoYXZpb3IuXG4gKiBAcmVhZG9ubHlcbiAqIEBlbnVtIHtzdHJpbmd9XG4gKiBAcmVhZG9ubHlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdGlvblxuICovXG5leHBvcnQgZW51bSBEZWNvcmF0aW9uS2V5cyB7XG4gIC8qKiBTdG9yYWdlIGtleSB1c2VkIG9uIHRoZSBjb25zdHJ1Y3RvciB0byBtaXJyb3IgcnVudGltZSBtZXRhZGF0YSAqL1xuICBSRUZMRUNUID0gYF9fJHtEZWZhdWx0Rmxhdm91cn1gLFxuICAvKiogTWFwIG9mIG1vZGVsIHByb3BlcnR5IGtleXMgdG8gdGhlaXIgcmVmbGVjdGVkIGRlc2lnbiB0eXBlcyAqL1xuICBQUk9QRVJUSUVTID0gXCJwcm9wZXJ0aWVzXCIsXG4gIC8qKiBLZXkgdW5kZXIgd2hpY2ggdGhlIG1vZGVsJ3MgY29uc3RydWN0b3IgaXMgc3RvcmVkICovXG4gIENMQVNTID0gXCJjbGFzc1wiLFxuICAvKiogQ29udGFpbmVyIG9mIGh1bWFuLWZyaWVuZGx5IGRlc2NyaXB0aW9ucyBwZXIgY2xhc3MgYW5kIHByb3BlcnR5ICovXG4gIERFU0NSSVBUSU9OID0gXCJkZXNjcmlwdGlvblwiLFxuICAvKiogUmVmbGVjdCBtZXRhZGF0YSBrZXkgZm9yIGRlc2lnbiB0aW1lIHR5cGUgb2YgYSBwcm9wZXJ0eSAqL1xuICBERVNJR05fVFlQRSA9IFwiZGVzaWduOnR5cGVcIixcbiAgLyoqIFJlZmxlY3QgbWV0YWRhdGEga2V5IGZvciBjb25zdHJ1Y3RvciBwYXJhbWV0ZXIgdHlwZXMgKi9cbiAgREVTSUdOX1BBUkFNUyA9IFwiZGVzaWduOnBhcmFtdHlwZXNcIixcbiAgLyoqIFJlZmxlY3QgbWV0YWRhdGEga2V5IGZvciBtZXRob2QgcmV0dXJuIHR5cGUgKi9cbiAgREVTSUdOX1JFVFVSTiA9IFwiZGVzaWduOnJldHVybnR5cGVcIixcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gVHlwZWRlZiBmb3IgdGhlIGRlZmF1bHQgbWV0YWRhdGEgb2JqZWN0IHNoYXBlXG4gKiBAc3VtbWFyeSBEZXNjcmliZXMgdGhlIG1pbmltYWwgc3RydWN0dXJlIHBlcnNpc3RlZCBmb3IgYSBtb2RlbCBiZWZvcmUgYW55IG1ldGFkYXRhIGlzIHJlY29yZGVkLlxuICogQHRlbXBsYXRlIE1cbiAqIEB0eXBlZGVmIHtvYmplY3R9IERlZmF1bHRNZXRhZGF0YVR5cGU8TT5cbiAqIEBwcm9wZXJ0eSB7UmVjb3JkPHN0cmluZywgQ29uc3RydWN0b3IgfCB1bmRlZmluZWQ+fSBwcm9wZXJ0aWVzIC0gTWFwcGluZyBvZiBwcm9wZXJ0eSBuYW1lcyB0byB0aGVpciBkZXNpZ24gdHlwZXNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdGlvblxuICovXG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlZmF1bHQgbWV0YWRhdGEgaW5zdGFuY2VcbiAqIEBzdW1tYXJ5IENvbmNyZXRlIGRlZmF1bHQgbWV0YWRhdGEgb2JqZWN0IHVzZWQgd2hlbiBpbml0aWFsaXppbmcgbWV0YWRhdGEgZm9yIGEgbW9kZWxcbiAqIEB0eXBlIHtEZWZhdWx0TWV0YWRhdGFUeXBlPGFueT59XG4gKiBAY29uc3QgRGVmYXVsdE1ldGFkYXRhXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRpb25cbiAqL1xuZXhwb3J0IGNvbnN0IERlZmF1bHRNZXRhZGF0YTogQmFzaWNNZXRhZGF0YTxhbnk+ID0ge1xuICBbRGVjb3JhdGlvbktleXMuUFJPUEVSVElFU106IFtdLFxufSBhcyB1bmtub3duIGFzIEJhc2ljTWV0YWRhdGE8YW55PjtcbiJdfQ==
@@ -0,0 +1,58 @@
1
+ import { BasicMetadata } from "./metadata/types";
2
+ /**
3
+ * @description Default flavour identifier for the decorator system
4
+ * @summary Defines the default flavour used by the Decoration class when no specific flavour is provided.
5
+ * This constant is used throughout the library as the fallback flavour for decorators.
6
+ * @const DefaultFlavour
7
+ * @memberOf module:decoration
8
+ */
9
+ export declare const DefaultFlavour = "decaf";
10
+ /**
11
+ * @description Character used to split nested metadata keys
12
+ * @summary The delimiter used by the metadata store to traverse nested object paths when reading/writing values.
13
+ * @const ObjectKeySplitter
14
+ * @memberOf module:decoration
15
+ */
16
+ export declare const ObjectKeySplitter = ".";
17
+ /**
18
+ * @description Enum containing metadata keys used for reflection in the model system
19
+ * @summary Defines the various Model keys used for reflection and metadata storage.
20
+ * These keys are used throughout the library to store and retrieve metadata about models,
21
+ * their properties, and their behavior.
22
+ * @readonly
23
+ * @enum {string}
24
+ * @readonly
25
+ * @memberOf module:decoration
26
+ */
27
+ export declare enum DecorationKeys {
28
+ /** Storage key used on the constructor to mirror runtime metadata */
29
+ REFLECT = "__decaf",
30
+ /** Map of model property keys to their reflected design types */
31
+ PROPERTIES = "properties",
32
+ /** Key under which the model's constructor is stored */
33
+ CLASS = "class",
34
+ /** Container of human-friendly descriptions per class and property */
35
+ DESCRIPTION = "description",
36
+ /** Reflect metadata key for design time type of a property */
37
+ DESIGN_TYPE = "design:type",
38
+ /** Reflect metadata key for constructor parameter types */
39
+ DESIGN_PARAMS = "design:paramtypes",
40
+ /** Reflect metadata key for method return type */
41
+ DESIGN_RETURN = "design:returntype"
42
+ }
43
+ /**
44
+ * @description Typedef for the default metadata object shape
45
+ * @summary Describes the minimal structure persisted for a model before any metadata is recorded.
46
+ * @template M
47
+ * @typedef {object} DefaultMetadataType<M>
48
+ * @property {Record<string, Constructor | undefined>} properties - Mapping of property names to their design types
49
+ * @memberOf module:decoration
50
+ */
51
+ /**
52
+ * @description Default metadata instance
53
+ * @summary Concrete default metadata object used when initializing metadata for a model
54
+ * @type {DefaultMetadataType<any>}
55
+ * @const DefaultMetadata
56
+ * @memberOf module:decoration
57
+ */
58
+ export declare const DefaultMetadata: BasicMetadata<any>;
@@ -0,0 +1,270 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Decoration = void 0;
4
+ const constants_1 = require("./../constants.cjs");
5
+ /**
6
+ * @description Default resolver that returns the current default flavour
7
+ * @summary Resolves the flavour for a given target by always returning the library's DefaultFlavour value.
8
+ * @param {object} target The target object being decorated
9
+ * @return {string} The resolved flavour identifier
10
+ * @function defaultFlavourResolver
11
+ * @memberOf module:decoration
12
+ */
13
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
14
+ function defaultFlavourResolver(target) {
15
+ return constants_1.DefaultFlavour;
16
+ }
17
+ /**
18
+ * @description A decorator management class that handles flavoured decorators
19
+ * @summary The Decoration class provides a builder pattern for creating and managing decorators with different flavours.
20
+ * It supports registering, extending, and applying decorators with context-aware flavour resolution.
21
+ * The class implements a fluent interface for defining, extending, and applying decorators with different flavours,
22
+ * allowing for framework-specific decorator implementations while maintaining a consistent API.
23
+ * @template T Type of the decorator (ClassDecorator | PropertyDecorator | MethodDecorator)
24
+ * @param {string} [flavour] Optional flavour parameter for the decorator context
25
+ * @class
26
+ * @example
27
+ * ```typescript
28
+ * // Create a new decoration for 'component' with default flavour
29
+ * const componentDecorator = new Decoration()
30
+ * .for('component')
31
+ * .define(customComponentDecorator);
32
+ *
33
+ * // Create a flavoured decoration
34
+ * const vueComponent = new Decoration('vue')
35
+ * .for('component')
36
+ * .define(vueComponentDecorator);
37
+ *
38
+ * // Apply the decoration
39
+ * @componentDecorator
40
+ * class MyComponent {}
41
+ * ```
42
+ * @mermaid
43
+ * sequenceDiagram
44
+ * participant C as Client
45
+ * participant D as Decoration
46
+ * participant R as FlavourResolver
47
+ * participant F as DecoratorFactory
48
+ *
49
+ * C->>D: new Decoration(flavour)
50
+ * C->>D: for(key)
51
+ * C->>D: define(decorators)
52
+ * D->>D: register(key, flavour, decorators)
53
+ * D->>F: decoratorFactory(key, flavour)
54
+ * F->>R: resolve(target)
55
+ * R-->>F: resolved flavour
56
+ * F->>F: apply decorators
57
+ * F-->>C: decorated target
58
+ */
59
+ class Decoration {
60
+ /**
61
+ * @description Static map of registered decorators
62
+ * @summary Stores all registered decorators organized by key and flavour
63
+ */
64
+ static { this.decorators = {}; }
65
+ /**
66
+ * @description Function to resolve flavour from a target
67
+ * @summary Resolver function that determines the appropriate flavour for a given target
68
+ */
69
+ static { this.flavourResolver = defaultFlavourResolver; }
70
+ constructor(flavour = constants_1.DefaultFlavour) {
71
+ this.flavour = flavour;
72
+ }
73
+ /**
74
+ * @description Sets the key for the decoration builder
75
+ * @summary Initializes a new decoration chain with the specified key
76
+ * @param {string} key The identifier for the decorator
77
+ * @return {DecorationBuilderMid} Builder instance for method chaining
78
+ */
79
+ for(key) {
80
+ this.key = key;
81
+ return this;
82
+ }
83
+ /**
84
+ * @description Adds decorators to the current context
85
+ * @summary Internal method to add decorators with addon support
86
+ * @param {boolean} [addon=false] Whether the decorators are addons
87
+ * @param decorators Array of decorators
88
+ * @return {this} Current instance for chaining
89
+ */
90
+ decorate(addon = false, ...decorators) {
91
+ if (!this.key)
92
+ throw new Error("key must be provided before decorators can be added");
93
+ if ((!decorators || !decorators.length) &&
94
+ !addon &&
95
+ this.flavour !== constants_1.DefaultFlavour)
96
+ throw new Error("Must provide overrides or addons to override or extend decaf's decorators");
97
+ if (this.flavour === constants_1.DefaultFlavour && addon)
98
+ throw new Error("Default flavour cannot be extended");
99
+ this[addon ? "extras" : "decorators"] = new Set([
100
+ ...(this[addon ? "extras" : "decorators"] || new Set()).values(),
101
+ ...decorators,
102
+ ]);
103
+ return this;
104
+ }
105
+ /**
106
+ * @description Defines the base decorators
107
+ * @summary Sets the primary decorators for the current context
108
+ * @param decorators Decorators to define
109
+ * @return Builder instance for finishing the chain
110
+ */
111
+ define(...decorators) {
112
+ return this.decorate(false, ...decorators);
113
+ }
114
+ /**
115
+ * @description Extends existing decorators
116
+ * @summary Adds additional decorators to the current context
117
+ * @param decorators Additional decorators
118
+ * @return {DecorationBuilderBuild} Builder instance for building the decorator
119
+ */
120
+ extend(...decorators) {
121
+ return this.decorate(true, ...decorators);
122
+ }
123
+ /**
124
+ * @description Factory that creates a context-aware decorator for a key/flavour
125
+ * @summary Produces a decorator function bound to the provided key and flavour. The resulting decorator resolves the actual
126
+ * decorators to apply at invocation time based on the target's resolved flavour and the registered base and extra decorators.
127
+ * @param {string} key The decoration key used to look up registered decorators
128
+ * @param {string} [f=DefaultFlavour] Optional explicit flavour to bind the factory to
129
+ * @return {function(object, any, TypedPropertyDescriptor<any>): any} A decorator function that applies the resolved decorators
130
+ * @mermaid
131
+ * sequenceDiagram
132
+ * participant U as User Code
133
+ * participant B as Decoration (builder)
134
+ * participant F as decoratorFactory(key, f)
135
+ * participant R as flavourResolver
136
+ * participant A as Applied Decorators
137
+ * U->>B: define()/extend() and apply()
138
+ * B->>F: create context decorator
139
+ * F->>R: resolve(target)
140
+ * R-->>F: flavour
141
+ * F->>A: collect base + extras
142
+ * loop each decorator
143
+ * A->>U: invoke decorator(target, key?, desc?)
144
+ * end
145
+ */
146
+ decoratorFactory(key, f = constants_1.DefaultFlavour) {
147
+ function contextDecorator(target, propertyKey, descriptor) {
148
+ const flavour = Decoration.flavourResolver(target);
149
+ const cache = Decoration.decorators[key];
150
+ let decorators;
151
+ const extras = cache[flavour]
152
+ ? cache[flavour].extras
153
+ : cache[constants_1.DefaultFlavour].extras;
154
+ const extraArgs = [
155
+ ...(cache[constants_1.DefaultFlavour].extras
156
+ ? cache[constants_1.DefaultFlavour].extras.values()
157
+ : []),
158
+ ].reduce((accum, e, i) => {
159
+ if (e.args)
160
+ accum[i] = e.args;
161
+ return accum;
162
+ }, {});
163
+ if (cache &&
164
+ cache[flavour] &&
165
+ cache[flavour].decorators &&
166
+ cache[flavour].decorators.size) {
167
+ decorators = cache[flavour].decorators;
168
+ }
169
+ else {
170
+ decorators = cache[constants_1.DefaultFlavour].decorators;
171
+ }
172
+ const decoratorArgs = [
173
+ ...cache[constants_1.DefaultFlavour].decorators.values(),
174
+ ].reduce((accum, e, i) => {
175
+ if (e.args)
176
+ accum[i] = e.args;
177
+ return accum;
178
+ }, {});
179
+ const toApply = [
180
+ ...(decorators ? decorators.values() : []),
181
+ ...(extras ? extras.values() : []),
182
+ ];
183
+ return toApply.reduce((_, d, i) => {
184
+ switch (typeof d) {
185
+ case "object": {
186
+ const { decorator, args } = d;
187
+ const argz = args || i < (decorators ? decorators.size : 0)
188
+ ? decoratorArgs[i]
189
+ : extraArgs[i - (decorators ? decorators.size : 0)] ||
190
+ (decorators ? decoratorArgs[i - decorators.size] : []);
191
+ return decorator(...(argz || []))(target, propertyKey, descriptor);
192
+ }
193
+ case "function":
194
+ return d(target, propertyKey, descriptor);
195
+ default:
196
+ throw new Error(`Unexpected decorator type: ${typeof d}`);
197
+ }
198
+ }, { target, propertyKey, descriptor });
199
+ }
200
+ Object.defineProperty(contextDecorator, "name", {
201
+ value: [f, key].join("_decorator_for_"),
202
+ writable: false,
203
+ });
204
+ return contextDecorator;
205
+ }
206
+ /**
207
+ * @description Creates the final decorator function
208
+ * @summary Builds and returns the decorator factory function
209
+ * @return {function(any, any?, TypedPropertyDescriptor?): any} The generated decorator function
210
+ */
211
+ apply() {
212
+ if (!this.key)
213
+ throw new Error("No key provided for the decoration builder");
214
+ Decoration.register(this.key, this.flavour, this.decorators || new Set(), this.extras);
215
+ return this.decoratorFactory(this.key, this.flavour);
216
+ }
217
+ /**
218
+ * @description Registers decorators for a specific key and flavour
219
+ * @summary Internal method to store decorators in the static registry
220
+ * @param {string} key Decorator key
221
+ * @param {string} flavour Decorator flavour
222
+ * @param [decorators] Primary decorators
223
+ * @param [extras] Additional decorators
224
+ */
225
+ static register(key, flavour, decorators, extras) {
226
+ if (!key) {
227
+ throw new Error("No key provided for the decoration builder");
228
+ }
229
+ if (!decorators)
230
+ throw new Error("No decorators provided for the decoration builder");
231
+ if (!flavour)
232
+ throw new Error("No flavour provided for the decoration builder");
233
+ if (!Decoration.decorators[key])
234
+ Decoration.decorators[key] = {};
235
+ if (!Decoration.decorators[key][flavour])
236
+ Decoration.decorators[key][flavour] = {};
237
+ if (decorators)
238
+ Decoration.decorators[key][flavour].decorators = decorators;
239
+ if (extras)
240
+ Decoration.decorators[key][flavour].extras = extras;
241
+ }
242
+ /**
243
+ * @description Sets the global flavour resolver
244
+ * @summary Configures the function used to determine decorator flavours
245
+ * @param {FlavourResolver} resolver Function to resolve flavours
246
+ */
247
+ static setFlavourResolver(resolver) {
248
+ Decoration.flavourResolver = resolver;
249
+ }
250
+ /**
251
+ * @description Convenience static entry to start a decoration builder
252
+ * @summary Creates a new Decoration instance and initiates the builder chain with the provided key.
253
+ * @param {string} key The decoration key to configure
254
+ * @return {DecorationBuilderMid} A builder instance for chaining definitions
255
+ */
256
+ static for(key) {
257
+ return new Decoration().for(key);
258
+ }
259
+ /**
260
+ * @description Starts a builder for a specific flavour
261
+ * @summary Convenience method to begin a Decoration builder chain bound to the given flavour identifier, allowing registration of flavour-specific decorators.
262
+ * @param {string} flavour The flavour name to bind to the builder
263
+ * @return {DecorationBuilderStart} A builder start interface to continue configuration
264
+ */
265
+ static flavouredAs(flavour) {
266
+ return new Decoration(flavour);
267
+ }
268
+ }
269
+ exports.Decoration = Decoration;
270
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRGVjb3JhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kZWNvcmF0aW9uL0RlY29yYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBUUEsa0RBQThDO0FBRTlDOzs7Ozs7O0dBT0c7QUFDSCw2REFBNkQ7QUFDN0QsU0FBUyxzQkFBc0IsQ0FBQyxNQUFjO0lBQzVDLE9BQU8sMEJBQWMsQ0FBQztBQUN4QixDQUFDO0FBMkNEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXlDRztBQUNILE1BQWEsVUFBVTtJQUNyQjs7O09BR0c7YUFDWSxlQUFVLEdBU3JCLEVBQUUsQ0FBQztJQUVQOzs7T0FHRzthQUNZLG9CQUFlLEdBQW9CLHNCQUFzQixDQUFDO0lBaUJ6RSxZQUFvQixVQUFrQiwwQkFBYztRQUFoQyxZQUFPLEdBQVAsT0FBTyxDQUF5QjtJQUFHLENBQUM7SUFFeEQ7Ozs7O09BS0c7SUFDSCxHQUFHLENBQUMsR0FBVztRQUNiLElBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDO1FBQ2YsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ssUUFBUSxDQUNkLFFBQWlCLEtBQUssRUFDdEIsR0FBRyxVQUEyQjtRQUU5QixJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUc7WUFDWCxNQUFNLElBQUksS0FBSyxDQUFDLHFEQUFxRCxDQUFDLENBQUM7UUFDekUsSUFDRSxDQUFDLENBQUMsVUFBVSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQztZQUNuQyxDQUFDLEtBQUs7WUFDTixJQUFJLENBQUMsT0FBTyxLQUFLLDBCQUFjO1lBRS9CLE1BQU0sSUFBSSxLQUFLLENBQ2IsMkVBQTJFLENBQzVFLENBQUM7UUFDSixJQUFJLElBQUksQ0FBQyxPQUFPLEtBQUssMEJBQWMsSUFBSSxLQUFLO1lBQzFDLE1BQU0sSUFBSSxLQUFLLENBQUMsb0NBQW9DLENBQUMs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QUksS0FBSyxDQUFDLGdEQUFnRCxDQUFDLENBQUM7UUFFcEUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDO1lBQUUsVUFBVSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDakUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDO1lBQ3RDLFVBQVUsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQzNDLElBQUksVUFBVTtZQUFFLFVBQVUsQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQztRQUM1RSxJQUFJLE1BQU07WUFBRSxVQUFVLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFDbEUsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxNQUFNLENBQUMsa0JBQWtCLENBQUMsUUFBeUI7UUFDakQsVUFBVSxDQUFDLGVBQWUsR0FBRyxRQUFRLENBQUM7SUFDeEMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFXO1FBQ3BCLE9BQU8sSUFBSSxVQUFVLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsTUFBTSxDQUFDLFdBQVcsQ0FBQyxPQUFlO1FBQ2hDLE9BQU8sSUFBSSxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDakMsQ0FBQzs7QUF6UkgsZ0NBMFJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgRGVjb3JhdGlvbkJ1aWxkZXJCdWlsZCxcbiAgRGVjb3JhdGlvbkJ1aWxkZXJFbmQsXG4gIERlY29yYXRpb25CdWlsZGVyTWlkLFxuICBEZWNvcmF0aW9uQnVpbGRlclN0YXJ0LFxuICBGbGF2b3VyUmVzb2x2ZXIsXG4gIElEZWNvcmF0aW9uQnVpbGRlcixcbn0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IERlZmF1bHRGbGF2b3VyIH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWZhdWx0IHJlc29sdmVyIHRoYXQgcmV0dXJucyB0aGUgY3VycmVudCBkZWZhdWx0IGZsYXZvdXJcbiAqIEBzdW1tYXJ5IFJlc29sdmVzIHRoZSBmbGF2b3VyIGZvciBhIGdpdmVuIHRhcmdldCBieSBhbHdheXMgcmV0dXJuaW5nIHRoZSBsaWJyYXJ5J3MgRGVmYXVsdEZsYXZvdXIgdmFsdWUuXG4gKiBAcGFyYW0ge29iamVjdH0gdGFyZ2V0IFRoZSB0YXJnZXQgb2JqZWN0IGJlaW5nIGRlY29yYXRlZFxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgcmVzb2x2ZWQgZmxhdm91ciBpZGVudGlmaWVyXG4gKiBAZnVuY3Rpb24gZGVmYXVsdEZsYXZvdXJSZXNvbHZlclxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0aW9uXG4gKi9cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbmZ1bmN0aW9uIGRlZmF1bHRGbGF2b3VyUmVzb2x2ZXIodGFyZ2V0OiBvYmplY3QpIHtcbiAgcmV0dXJuIERlZmF1bHRGbGF2b3VyO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBVbmlvbiB0eXBlIGNvdmVyaW5nIHN1cHBvcnRlZCBkZWNvcmF0b3Iga2luZHNcbiAqIEBzdW1tYXJ5IFJlcHJlc2VudHMgYW55IG9mIHRoZSBzdGFuZGFyZCBUeXBlU2NyaXB0IGRlY29yYXRvciBzaWduYXR1cmVzIChjbGFzcywgcHJvcGVydHksIG9yIG1ldGhvZCksIGVuYWJsaW5nIGZsZXhpYmxlIHJlZ2lzdHJhdGlvbiBhbmQgYXBwbGljYXRpb24gd2l0aGluIHRoZSBEZWNvcmF0aW9uIHN5c3RlbS5cbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAdHlwZURlZiBEZWNvcmF0b3JUeXBlc1xuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0aW9uXG4gKi9cbmV4cG9ydCB0eXBlIERlY29yYXRvclR5cGVzID1cbiAgfCBDbGFzc0RlY29yYXRvclxuICB8IFByb3BlcnR5RGVjb3JhdG9yXG4gIHwgTWV0aG9kRGVjb3JhdG9yO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBUeXBlIGRlZmluaXRpb24gZm9yIGEgZGVjb3JhdG9yIGZhY3RvcnkgZnVuY3Rpb25cbiAqIEBzdW1tYXJ5IFJlcHJlc2VudHMgYSBmdW5jdGlvbiB0aGF0IGFjY2VwdHMgYXJiaXRyYXJ5IGFyZ3VtZW50cyBhbmQgcmV0dXJucyBhIGNvbmNyZXRlIGRlY29yYXRvciBmdW5jdGlvbiB0byBiZSBhcHBsaWVkIHRvIGEgdGFyZ2V0LlxuICogQHRlbXBsYXRlIEFcbiAqIEB0eXBlRGVmIERlY29yYXRvckZhY3RvcnlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdGlvblxuICovXG5leHBvcnQgdHlwZSBEZWNvcmF0b3JGYWN0b3J5ID0gKC4uLmFyZ3M6IGFueVtdKSA9PiBEZWNvcmF0b3JUeXBlcztcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQXJndW1lbnQgYnVuZGxlIGZvciBhIGRlY29yYXRvciBmYWN0b3J5XG4gKiBAc3VtbWFyeSBPYmplY3QgZm9ybSB1c2VkIHRvIGRlZmVyIGRlY29yYXRvciBjcmVhdGlvbiwgY2FycnlpbmcgYm90aCB0aGUgZmFjdG9yeSBmdW5jdGlvbiBhbmQgaXRzIGFyZ3VtZW50IGxpc3QgdG8gYmUgaW52b2tlZCBsYXRlciBkdXJpbmcgYXBwbGljYXRpb24uXG4gKiBAdHlwZURlZiBEZWNvcmF0b3JGYWN0b3J5QXJnc1xuICogQHByb3BlcnR5IHtEZWNvcmF0b3JGYWN0b3J5fSBkZWNvcmF0b3IgVGhlIGZhY3RvcnkgZnVuY3Rpb24gdGhhdCBwcm9kdWNlcyBhIGRlY29yYXRvciB3aGVuIGludm9rZWRcbiAqIEBwcm9wZXJ0eSB7YW55W119IFthcmdzXSBPcHRpb25hbCBsaXN0IG9mIGFyZ3VtZW50cyB0byBwYXNzIHRvIHRoZSBkZWNvcmF0b3IgZmFjdG9yeVxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0aW9uXG4gKi9cbmV4cG9ydCB0eXBlIERlY29yYXRvckZhY3RvcnlBcmdzID0ge1xuICBkZWNvcmF0b3I6IERlY29yYXRvckZhY3Rvcnk7XG4gIGFyZ3M/OiBhbnlbXTtcbn07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFVuaW9uIHRoYXQgcmVwcmVzZW50cyBlaXRoZXIgYSByZWFkeS10by1hcHBseSBkZWNvcmF0b3Igb3IgYSBmYWN0b3J5IHdpdGggYXJndW1lbnRzXG4gKiBAc3VtbWFyeSBBbGxvd3MgcmVnaXN0ZXJpbmcgZGVjb3JhdG9ycyBpbiB0d28gZm9ybXM6IGFzIGRpcmVjdCBkZWNvcmF0b3IgZnVuY3Rpb25zIG9yIGFzIGRlZmVycmVkIGZhY3RvcmllcyBwYWlyZWQgd2l0aCB0aGVpciBhcmd1bWVudCBsaXN0cyBmb3IgbGF0ZXIgaW5zdGFudGlhdGlvbi5cbiAqIEB0eXBlRGVmIERlY29yYXRvckRhdGFcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdGlvblxuICovXG5leHBvcnQgdHlwZSBEZWNvcmF0b3JEYXRhID0gRGVjb3JhdG9yVHlwZXMgfCBEZWNvcmF0b3JGYWN0b3J5QXJncztcbi8qKlxuICogQGRlc2NyaXB0aW9uIEEgZGVjb3JhdG9yIG1hbmFnZW1lbnQgY2xhc3MgdGhhdCBoYW5kbGVzIGZsYXZvdXJlZCBkZWNvcmF0b3JzXG4gKiBAc3VtbWFyeSBUaGUgRGVjb3JhdGlvbiBjbGFzcyBwcm92aWRlcyBhIGJ1aWxkZXIgcGF0dGVybiBmb3IgY3JlYXRpbmcgYW5kIG1hbmFnaW5nIGRlY29yYXRvcnMgd2l0aCBkaWZmZXJlbnQgZmxhdm91cnMuXG4gKiBJdCBzdXBwb3J0cyByZWdpc3RlcmluZywgZXh0ZW5kaW5nLCBhbmQgYXBwbHlpbmcgZGVjb3JhdG9ycyB3aXRoIGNvbnRleHQtYXdhcmUgZmxhdm91ciByZXNvbHV0aW9uLlxuICogVGhlIGNsYXNzIGltcGxlbWVudHMgYSBmbHVlbnQgaW50ZXJmYWNlIGZvciBkZWZpbmluZywgZXh0ZW5kaW5nLCBhbmQgYXBwbHlpbmcgZGVjb3JhdG9ycyB3aXRoIGRpZmZlcmVudCBmbGF2b3VycyxcbiAqIGFsbG93aW5nIGZvciBmcmFtZXdvcmstc3BlY2lmaWMgZGVjb3JhdG9yIGltcGxlbWVudGF0aW9ucyB3aGlsZSBtYWludGFpbmluZyBhIGNvbnNpc3RlbnQgQVBJLlxuICogQHRlbXBsYXRlIFQgVHlwZSBvZiB0aGUgZGVjb3JhdG9yIChDbGFzc0RlY29yYXRvciB8IFByb3BlcnR5RGVjb3JhdG9yIHwgTWV0aG9kRGVjb3JhdG9yKVxuICogQHBhcmFtIHtzdHJpbmd9IFtmbGF2b3VyXSBPcHRpb25hbCBmbGF2b3VyIHBhcmFtZXRlciBmb3IgdGhlIGRlY29yYXRvciBjb250ZXh0XG4gKiBAY2xhc3NcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBDcmVhdGUgYSBuZXcgZGVjb3JhdGlvbiBmb3IgJ2NvbXBvbmVudCcgd2l0aCBkZWZhdWx0IGZsYXZvdXJcbiAqIGNvbnN0IGNvbXBvbmVudERlY29yYXRvciA9IG5ldyBEZWNvcmF0aW9uKClcbiAqICAgLmZvcignY29tcG9uZW50JylcbiAqICAgLmRlZmluZShjdXN0b21Db21wb25lbnREZWNvcmF0b3IpO1xuICpcbiAqIC8vIENyZWF0ZSBhIGZsYXZvdXJlZCBkZWNvcmF0aW9uXG4gKiBjb25zdCB2dWVDb21wb25lbnQgPSBuZXcgRGVjb3JhdGlvbigndnVlJylcbiAqICAgLmZvcignY29tcG9uZW50JylcbiAqICAgLmRlZmluZSh2dWVDb21wb25lbnREZWNvcmF0b3IpO1xuICpcbiAqIC8vIEFwcGx5IHRoZSBkZWNvcmF0aW9uXG4gKiBAY29tcG9uZW50RGVjb3JhdG9yXG4gKiBjbGFzcyBNeUNvbXBvbmVudCB7fVxuICogYGBgXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IEMgYXMgQ2xpZW50XG4gKiAgIHBhcnRpY2lwYW50IEQgYXMgRGVjb3JhdGlvblxuICogICBwYXJ0aWNpcGFudCBSIGFzIEZsYXZvdXJSZXNvbHZlclxuICogICBwYXJ0aWNpcGFudCBGIGFzIERlY29yYXRvckZhY3RvcnlcbiAqXG4gKiAgIEMtPj5EOiBuZXcgRGVjb3JhdGlvbihmbGF2b3VyKVxuICogICBDLT4+RDogZm9yKGtleSlcbiAqICAgQy0+PkQ6IGRlZmluZShkZWNvcmF0b3JzKVxuICogICBELT4+RDogcmVnaXN0ZXIoa2V5LCBmbGF2b3VyLCBkZWNvcmF0b3JzKVxuICogICBELT4+RjogZGVjb3JhdG9yRmFjdG9yeShrZXksIGZsYXZvdXIpXG4gKiAgIEYtPj5SOiByZXNvbHZlKHRhcmdldClcbiAqICAgUi0tPj5GOiByZXNvbHZlZCBmbGF2b3VyXG4gKiAgIEYtPj5GOiBhcHBseSBkZWNvcmF0b3JzXG4gKiAgIEYtLT4+QzogZGVjb3JhdGVkIHRhcmdldFxuICovXG5leHBvcnQgY2xhc3MgRGVjb3JhdGlvbiBpbXBsZW1lbnRzIElEZWNvcmF0aW9uQnVpbGRlciB7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gU3RhdGljIG1hcCBvZiByZWdpc3RlcmVkIGRlY29yYXRvcnNcbiAgICogQHN1bW1hcnkgU3RvcmVzIGFsbCByZWdpc3RlcmVkIGRlY29yYXRvcnMgb3JnYW5pemVkIGJ5IGtleSBhbmQgZmxhdm91clxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgZGVjb3JhdG9yczogUmVjb3JkPFxuICAgIHN0cmluZyxcbiAgICBSZWNvcmQ8XG4gICAgICBzdHJpbmcsXG4gICAgICB7XG4gICAgICAgIGRlY29yYXRvcnM/OiBTZXQ8RGVjb3JhdG9yRGF0YT47XG4gICAgICAgIGV4dHJhcz86IFNldDxEZWNvcmF0b3JEYXRhPjtcbiAgICAgIH1cbiAgICA+XG4gID4gPSB7fTtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEZ1bmN0aW9uIHRvIHJlc29sdmUgZmxhdm91ciBmcm9tIGEgdGFyZ2V0XG4gICAqIEBzdW1tYXJ5IFJlc29sdmVyIGZ1bmN0aW9uIHRoYXQgZGV0ZXJtaW5lcyB0aGUgYXBwcm9wcmlhdGUgZmxhdm91ciBmb3IgYSBnaXZlbiB0YXJnZXRcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGZsYXZvdXJSZXNvbHZlcjogRmxhdm91clJlc29sdmVyID0gZGVmYXVsdEZsYXZvdXJSZXNvbHZlcjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNldCBvZiBkZWNvcmF0b3JzIGZvciB0aGUgY3VycmVudCBjb250ZXh0XG4gICAqL1xuICBwcml2YXRlIGRlY29yYXRvcnM/OiBTZXQ8RGVjb3JhdG9yRGF0YT47XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTZXQgb2YgYWRkaXRpb25hbCBkZWNvcmF0b3JzXG4gICAqL1xuICBwcml2YXRlIGV4dHJhcz86IFNldDxEZWNvcmF0b3JEYXRhPjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEN1cnJlbnQgZGVjb3JhdG9yIGtleVxuICAgKi9cbiAgcHJpdmF0ZSBrZXk/OiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBmbGF2b3VyOiBzdHJpbmcgPSBEZWZhdWx0Rmxhdm91cikge31cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNldHMgdGhlIGtleSBmb3IgdGhlIGRlY29yYXRpb24gYnVpbGRlclxuICAgKiBAc3VtbWFyeSBJbml0aWFsaXplcyBhIG5ldyBkZWNvcmF0aW9uIGNoYWluIHdpdGggdGhlIHNwZWNpZmllZCBrZXlcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUgaWRlbnRpZmllciBmb3IgdGhlIGRlY29yYXRvclxuICAgKiBAcmV0dXJuIHtEZWNvcmF0aW9uQnVpbGRlck1pZH0gQnVpbGRlciBpbnN0YW5jZSBmb3IgbWV0aG9kIGNoYWluaW5nXG4gICAqL1xuICBmb3Ioa2V5OiBzdHJpbmcpOiBEZWNvcmF0aW9uQnVpbGRlck1pZCB7XG4gICAgdGhpcy5rZXkgPSBrZXk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEFkZHMgZGVjb3JhdG9ycyB0byB0aGUgY3VycmVudCBjb250ZXh0XG4gICAqIEBzdW1tYXJ5IEludGVybmFsIG1ldGhvZCB0byBhZGQgZGVjb3JhdG9ycyB3aXRoIGFkZG9uIHN1cHBvcnRcbiAgICogQHBhcmFtIHtib29sZWFufSBbYWRkb249ZmFsc2VdIFdoZXRoZXIgdGhlIGRlY29yYXRvcnMgYXJlIGFkZG9uc1xuICAgKiBAcGFyYW0gZGVjb3JhdG9ycyBBcnJheSBvZiBkZWNvcmF0b3JzXG4gICAqIEByZXR1cm4ge3RoaXN9IEN1cnJlbnQgaW5zdGFuY2UgZm9yIGNoYWluaW5nXG4gICAqL1xuICBwcml2YXRlIGRlY29yYXRlKFxuICAgIGFkZG9uOiBib29sZWFuID0gZmFsc2UsXG4gICAgLi4uZGVjb3JhdG9yczogRGVjb3JhdG9yRGF0YVtdXG4gICk6IHRoaXMge1xuICAgIGlmICghdGhpcy5rZXkpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJrZXkgbXVzdCBiZSBwcm92aWRlZCBiZWZvcmUgZGVjb3JhdG9ycyBjYW4gYmUgYWRkZWRcIik7XG4gICAgaWYgKFxuICAgICAgKCFkZWNvcmF0b3JzIHx8ICFkZWNvcmF0b3JzLmxlbmd0aCkgJiZcbiAgICAgICFhZGRvbiAmJlxuICAgICAgdGhpcy5mbGF2b3VyICE9PSBEZWZhdWx0Rmxhdm91clxuICAgIClcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgXCJNdXN0IHByb3ZpZGUgb3ZlcnJpZGVzIG9yIGFkZG9ucyB0byBvdmVycmlkZSBvciBleHRlbmQgZGVjYWYncyBkZWNvcmF0b3JzXCJcbiAgICAgICk7XG4gICAgaWYgKHRoaXMuZmxhdm91ciA9PT0gRGVmYXVsdEZsYXZvdXIgJiYgYWRkb24pXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJEZWZhdWx0IGZsYXZvdXIgY2Fubm90IGJlIGV4dGVuZGVkXCIpO1xuXG4gICAgdGhpc1thZGRvbiA/IFwiZXh0cmFzXCIgOiBcImRlY29yYXRvcnNcIl0gPSBuZXcgU2V0KFtcbiAgICAgIC4uLih0aGlzW2FkZG9uID8gXCJleHRyYXNcIiA6IFwiZGVjb3JhdG9yc1wiXSB8fCBuZXcgU2V0KCkpLnZhbHVlcygpLFxuICAgICAgLi4uZGVjb3JhdG9ycyxcbiAgICBdKTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBEZWZpbmVzIHRoZSBiYXNlIGRlY29yYXRvcnNcbiAgICogQHN1bW1hcnkgU2V0cyB0aGUgcHJpbWFyeSBkZWNvcmF0b3JzIGZvciB0aGUgY3VycmVudCBjb250ZXh0XG4gICAqIEBwYXJhbSBkZWNvcmF0b3JzIERlY29yYXRvcnMgdG8gZGVmaW5lXG4gICAqIEByZXR1cm4gQnVpbGRlciBpbnN0YW5jZSBmb3IgZmluaXNoaW5nIHRoZSBjaGFpblxuICAgKi9cbiAgZGVmaW5lKFxuICAgIC4uLmRlY29yYXRvcnM6IERlY29yYXRvckRhdGFbXVxuICApOiBEZWNvcmF0aW9uQnVpbGRlckVuZCAmIERlY29yYXRpb25CdWlsZGVyQnVpbGQge1xuICAgIHJldHVybiB0aGlzLmRlY29yYXRlKGZhbHNlLCAuLi5kZWNvcmF0b3JzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRXh0ZW5kcyBleGlzdGluZyBkZWNvcmF0b3JzXG4gICAqIEBzdW1tYXJ5IEFkZHMgYWRkaXRpb25hbCBkZWNvcmF0b3JzIHRvIHRoZSBjdXJyZW50IGNvbnRleHRcbiAgICogQHBhcmFtIGRlY29yYXRvcnMgQWRkaXRpb25hbCBkZWNvcmF0b3JzXG4gICAqIEByZXR1cm4ge0RlY29yYXRpb25CdWlsZGVyQnVpbGR9IEJ1aWxkZXIgaW5zdGFuY2UgZm9yIGJ1aWxkaW5nIHRoZSBkZWNvcmF0b3JcbiAgICovXG4gIGV4dGVuZCguLi5kZWNvcmF0b3JzOiBEZWNvcmF0b3JEYXRhW10pOiBEZWNvcmF0aW9uQnVpbGRlckJ1aWxkIHtcbiAgICByZXR1cm4gdGhpcy5kZWNvcmF0ZSh0cnVlLCAuLi5kZWNvcmF0b3JzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRmFjdG9yeSB0aGF0IGNyZWF0ZXMgYSBjb250ZXh0LWF3YXJlIGRlY29yYXRvciBmb3IgYSBrZXkvZmxhdm91clxuICAgKiBAc3VtbWFyeSBQcm9kdWNlcyBhIGRlY29yYXRvciBmdW5jdGlvbiBib3VuZCB0byB0aGUgcHJvdmlkZWQga2V5IGFuZCBmbGF2b3VyLiBUaGUgcmVzdWx0aW5nIGRlY29yYXRvciByZXNvbHZlcyB0aGUgYWN0dWFsXG4gICAqIGRlY29yYXRvcnMgdG8gYXBwbHkgYXQgaW52b2NhdGlvbiB0aW1lIGJhc2VkIG9uIHRoZSB0YXJnZXQncyByZXNvbHZlZCBmbGF2b3VyIGFuZCB0aGUgcmVnaXN0ZXJlZCBiYXNlIGFuZCBleHRyYSBkZWNvcmF0b3JzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBkZWNvcmF0aW9uIGtleSB1c2VkIHRvIGxvb2sgdXAgcmVnaXN0ZXJlZCBkZWNvcmF0b3JzXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbZj1EZWZhdWx0Rmxhdm91cl0gT3B0aW9uYWwgZXhwbGljaXQgZmxhdm91ciB0byBiaW5kIHRoZSBmYWN0b3J5IHRvXG4gICAqIEByZXR1cm4ge2Z1bmN0aW9uKG9iamVjdCwgYW55LCBUeXBlZFByb3BlcnR5RGVzY3JpcHRvcjxhbnk+KTogYW55fSBBIGRlY29yYXRvciBmdW5jdGlvbiB0aGF0IGFwcGxpZXMgdGhlIHJlc29sdmVkIGRlY29yYXRvcnNcbiAgICogQG1lcm1haWRcbiAgICogc2VxdWVuY2VEaWFncmFtXG4gICAqICAgcGFydGljaXBhbnQgVSBhcyBVc2VyIENvZGVcbiAgICogICBwYXJ0aWNpcGFudCBCIGFzIERlY29yYXRpb24gKGJ1aWxkZXIpXG4gICAqICAgcGFydGljaXBhbnQgRiBhcyBkZWNvcmF0b3JGYWN0b3J5KGtleSwgZilcbiAgICogICBwYXJ0aWNpcGFudCBSIGFzIGZsYXZvdXJSZXNvbHZlclxuICAgKiAgIHBhcnRpY2lwYW50IEEgYXMgQXBwbGllZCBEZWNvcmF0b3JzXG4gICAqICAgVS0+PkI6IGRlZmluZSgpL2V4dGVuZCgpIGFuZCBhcHBseSgpXG4gICAqICAgQi0+PkY6IGNyZWF0ZSBjb250ZXh0IGRlY29yYXRvclxuICAgKiAgIEYtPj5SOiByZXNvbHZlKHRhcmdldClcbiAgICogICBSLS0+PkY6IGZsYXZvdXJcbiAgICogICBGLT4+QTogY29sbGVjdCBiYXNlICsgZXh0cmFzXG4gICAqICAgbG9vcCBlYWNoIGRlY29yYXRvclxuICAgKiAgICAgQS0+PlU6IGludm9rZSBkZWNvcmF0b3IodGFyZ2V0LCBrZXk/LCBkZXNjPylcbiAgICogICBlbmRcbiAgICovXG4gIHByb3RlY3RlZCBkZWNvcmF0b3JGYWN0b3J5KGtleTogc3RyaW5nLCBmOiBzdHJpbmcgPSBEZWZhdWx0Rmxhdm91cikge1xuICAgIGZ1bmN0aW9uIGNvbnRleHREZWNvcmF0b3IoXG4gICAgICB0YXJnZXQ6IG9iamVjdCxcbiAgICAgIHByb3BlcnR5S2V5PzogYW55LFxuICAgICAgZGVzY3JpcHRvcj86IFR5cGVkUHJvcGVydHlEZXNjcmlwdG9yPGFueT5cbiAgICApIHtcbiAgICAgIGNvbnN0IGZsYXZvdXIgPSBEZWNvcmF0aW9uLmZsYXZvdXJSZXNvbHZlcih0YXJnZXQpO1xuICAgICAgY29uc3QgY2FjaGUgPSBEZWNvcmF0aW9uLmRlY29yYXRvcnNba2V5XTtcbiAgICAgIGxldCBkZWNvcmF0b3JzO1xuICAgICAgY29uc3QgZXh0cmFzID0gY2FjaGVbZmxhdm91cl1cbiAgICAgICAgPyBjYWNoZVtmbGF2b3VyXS5leHRyYXNcbiAgICAgICAgOiBjYWNoZVtEZWZhdWx0Rmxhdm91cl0uZXh0cmFzO1xuICAgICAgY29uc3QgZXh0cmFBcmdzID0gW1xuICAgICAgICAuLi4oKGNhY2hlW0RlZmF1bHRGbGF2b3VyXSBhcyBhbnkpLmV4dHJhc1xuICAgICAgICAgID8gKGNhY2hlW0RlZmF1bHRGbGF2b3VyXSBhcyBhbnkpLmV4dHJhcy52YWx1ZXMoKVxuICAgICAgICAgIDogW10pLFxuICAgICAgXS5yZWR1Y2UoKGFjY3VtOiBSZWNvcmQ8bnVtYmVyLCBhbnk+LCBlLCBpKSA9PiB7XG4gICAgICAgIGlmIChlLmFyZ3MpIGFjY3VtW2ldID0gZS5hcmdzO1xuICAgICAgICByZXR1cm4gYWNjdW07XG4gICAgICB9LCB7fSk7XG5cbiAgICAgIGlmIChcbiAgICAgICAgY2FjaGUgJiZcbiAgICAgICAgY2FjaGVbZmxhdm91cl0gJiZcbiAgICAgICAgY2FjaGVbZmxhdm91cl0uZGVjb3JhdG9ycyAmJlxuICAgICAgICBjYWNoZVtmbGF2b3VyXS5kZWNvcmF0b3JzLnNpemVcbiAgICAgICkge1xuICAgICAgICBkZWNvcmF0b3JzID0gY2FjaGVbZmxhdm91cl0uZGVjb3JhdG9ycztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRlY29yYXRvcnMgPSBjYWNoZVtEZWZhdWx0Rmxhdm91cl0uZGVjb3JhdG9ycztcbiAgICAgIH1cblxuICAgICAgY29uc3QgZGVjb3JhdG9yQXJncyA9IFtcbiAgICAgICAgLi4uKGNhY2hlW0RlZmF1bHRGbGF2b3VyXSBhcyBhbnkpLmRlY29yYXRvcnMudmFsdWVzKCksXG4gICAgICBdLnJlZHVjZSgoYWNjdW06IFJlY29yZDxudW1iZXIsIGFueT4sIGUsIGkpID0+IHtcbiAgICAgICAgaWYgKGUuYXJncykgYWNjdW1baV0gPSBlLmFyZ3M7XG4gICAgICAgIHJldHVybiBhY2N1bTtcbiAgICAgIH0sIHt9KTtcblxuICAgICAgY29uc3QgdG9BcHBseSA9IFtcbiAgICAgICAgLi4uKGRlY29yYXRvcnMgPyBkZWNvcmF0b3JzLnZhbHVlcygpIDogW10pLFxuICAgICAgICAuLi4oZXh0cmFzID8gZXh0cmFzLnZhbHVlcygpIDogW10pLFxuICAgICAgXTtcblxuICAgICAgcmV0dXJuIHRvQXBwbHkucmVkdWNlKFxuICAgICAgICAoXywgZCwgaSkgPT4ge1xuICAgICAgICAgIHN3aXRjaCAodHlwZW9mIGQpIHtcbiAgICAgICAgICAgIGNhc2UgXCJvYmplY3RcIjoge1xuICAgICAgICAgICAgICBjb25zdCB7IGRlY29yYXRvciwgYXJncyB9ID0gZCBhcyBEZWNvcmF0b3JGYWN0b3J5QXJncztcbiAgICAgICAgICAgICAgY29uc3QgYXJneiA9XG4gICAgICAgICAgICAgICAgYXJncyB8fCBpIDwgKGRlY29yYXRvcnMgPyBkZWNvcmF0b3JzLnNpemUgOiAwKVxuICAgICAgICAgICAgICAgICAgPyBkZWNvcmF0b3JBcmdzW2ldXG4gICAgICAgICAgICAgICAgICA6IGV4dHJhQXJnc1tpIC0gKGRlY29yYXRvcnMgPyBkZWNvcmF0b3JzLnNpemUgOiAwKV0gfHxcbiAgICAgICAgICAgICAgICAgICAgKGRlY29yYXRvcnMgPyBkZWNvcmF0b3JBcmdzW2kgLSBkZWNvcmF0b3JzLnNpemVdIDogW10pO1xuXG4gICAgICAgICAgICAgIHJldHVybiAoZGVjb3JhdG9yKC4uLihhcmd6IHx8IFtdKSkgYXMgYW55KShcbiAgICAgICAgICAgICAgICB0YXJnZXQsXG4gICAgICAgICAgICAgICAgcHJvcGVydHlLZXksXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRvclxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcImZ1bmN0aW9uXCI6XG4gICAgICAgICAgICAgIHJldHVybiAoZCBhcyBhbnkpKHRhcmdldCwgcHJvcGVydHlLZXksIGRlc2NyaXB0b3IpO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmV4cGVjdGVkIGRlY29yYXRvciB0eXBlOiAke3R5cGVvZiBkfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgeyB0YXJnZXQsIHByb3BlcnR5S2V5LCBkZXNjcmlwdG9yIH1cbiAgICAgICk7XG4gICAgfVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb250ZXh0RGVjb3JhdG9yLCBcIm5hbWVcIiwge1xuICAgICAgdmFsdWU6IFtmLCBrZXldLmpvaW4oXCJfZGVjb3JhdG9yX2Zvcl9cIiksXG4gICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgfSk7XG4gICAgcmV0dXJuIGNvbnRleHREZWNvcmF0b3I7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgdGhlIGZpbmFsIGRlY29yYXRvciBmdW5jdGlvblxuICAgKiBAc3VtbWFyeSBCdWlsZHMgYW5kIHJldHVybnMgdGhlIGRlY29yYXRvciBmYWN0b3J5IGZ1bmN0aW9uXG4gICAqIEByZXR1cm4ge2Z1bmN0aW9uKGFueSwgYW55PywgVHlwZWRQcm9wZXJ0eURlc2NyaXB0b3I/KTogYW55fSBUaGUgZ2VuZXJhdGVkIGRlY29yYXRvciBmdW5jdGlvblxuICAgKi9cbiAgYXBwbHkoKTogKFxuICAgIHRhcmdldDogYW55LFxuICAgIHByb3BlcnR5S2V5PzogYW55LFxuICAgIGRlc2NyaXB0b3I/OiBUeXBlZFByb3BlcnR5RGVzY3JpcHRvcjxhbnk+XG4gICkgPT4gYW55IHtcbiAgICBpZiAoIXRoaXMua2V5KVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8ga2V5IHByb3ZpZGVkIGZvciB0aGUgZGVjb3JhdGlvbiBidWlsZGVyXCIpO1xuICAgIERlY29yYXRpb24ucmVnaXN0ZXIoXG4gICAgICB0aGlzLmtleSxcbiAgICAgIHRoaXMuZmxhdm91cixcbiAgICAgIHRoaXMuZGVjb3JhdG9ycyB8fCBuZXcgU2V0KCksXG4gICAgICB0aGlzLmV4dHJhc1xuICAgICk7XG4gICAgcmV0dXJuIHRoaXMuZGVjb3JhdG9yRmFjdG9yeSh0aGlzLmtleSwgdGhpcy5mbGF2b3VyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVnaXN0ZXJzIGRlY29yYXRvcnMgZm9yIGEgc3BlY2lmaWMga2V5IGFuZCBmbGF2b3VyXG4gICAqIEBzdW1tYXJ5IEludGVybmFsIG1ldGhvZCB0byBzdG9yZSBkZWNvcmF0b3JzIGluIHRoZSBzdGF0aWMgcmVnaXN0cnlcbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBEZWNvcmF0b3Iga2V5XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmbGF2b3VyIERlY29yYXRvciBmbGF2b3VyXG4gICAqIEBwYXJhbSBbZGVjb3JhdG9yc10gUHJpbWFyeSBkZWNvcmF0b3JzXG4gICAqIEBwYXJhbSBbZXh0cmFzXSBBZGRpdGlvbmFsIGRlY29yYXRvcnNcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHJlZ2lzdGVyKFxuICAgIGtleTogc3RyaW5nLFxuICAgIGZsYXZvdXI6IHN0cmluZyxcbiAgICBkZWNvcmF0b3JzPzogU2V0PERlY29yYXRvckRhdGE+LFxuICAgIGV4dHJhcz86IFNldDxEZWNvcmF0b3JEYXRhPlxuICApIHtcbiAgICBpZiAoIWtleSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiTm8ga2V5IHByb3ZpZGVkIGZvciB0aGUgZGVjb3JhdGlvbiBidWlsZGVyXCIpO1xuICAgIH1cbiAgICBpZiAoIWRlY29yYXRvcnMpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyBkZWNvcmF0b3JzIHByb3ZpZGVkIGZvciB0aGUgZGVjb3JhdGlvbiBidWlsZGVyXCIpO1xuICAgIGlmICghZmxhdm91cilcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIk5vIGZsYXZvdXIgcHJvdmlkZWQgZm9yIHRoZSBkZWNvcmF0aW9uIGJ1aWxkZXJcIik7XG5cbiAgICBpZiAoIURlY29yYXRpb24uZGVjb3JhdG9yc1trZXldKSBEZWNvcmF0aW9uLmRlY29yYXRvcnNba2V5XSA9IHt9O1xuICAgIGlmICghRGVjb3JhdGlvbi5kZWNvcmF0b3JzW2tleV1bZmxhdm91cl0pXG4gICAgICBEZWNvcmF0aW9uLmRlY29yYXRvcnNba2V5XVtmbGF2b3VyXSA9IHt9O1xuICAgIGlmIChkZWNvcmF0b3JzKSBEZWNvcmF0aW9uLmRlY29yYXRvcnNba2V5XVtmbGF2b3VyXS5kZWNvcmF0b3JzID0gZGVjb3JhdG9ycztcbiAgICBpZiAoZXh0cmFzKSBEZWNvcmF0aW9uLmRlY29yYXRvcnNba2V5XVtmbGF2b3VyXS5leHRyYXMgPSBleHRyYXM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFNldHMgdGhlIGdsb2JhbCBmbGF2b3VyIHJlc29sdmVyXG4gICAqIEBzdW1tYXJ5IENvbmZpZ3VyZXMgdGhlIGZ1bmN0aW9uIHVzZWQgdG8gZGV0ZXJtaW5lIGRlY29yYXRvciBmbGF2b3Vyc1xuICAgKiBAcGFyYW0ge0ZsYXZvdXJSZXNvbHZlcn0gcmVzb2x2ZXIgRnVuY3Rpb24gdG8gcmVzb2x2ZSBmbGF2b3Vyc1xuICAgKi9cbiAgc3RhdGljIHNldEZsYXZvdXJSZXNvbHZlcihyZXNvbHZlcjogRmxhdm91clJlc29sdmVyKSB7XG4gICAgRGVjb3JhdGlvbi5mbGF2b3VyUmVzb2x2ZXIgPSByZXNvbHZlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ29udmVuaWVuY2Ugc3RhdGljIGVudHJ5IHRvIHN0YXJ0IGEgZGVjb3JhdGlvbiBidWlsZGVyXG4gICAqIEBzdW1tYXJ5IENyZWF0ZXMgYSBuZXcgRGVjb3JhdGlvbiBpbnN0YW5jZSBhbmQgaW5pdGlhdGVzIHRoZSBidWlsZGVyIGNoYWluIHdpdGggdGhlIHByb3ZpZGVkIGtleS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUgZGVjb3JhdGlvbiBrZXkgdG8gY29uZmlndXJlXG4gICAqIEByZXR1cm4ge0RlY29yYXRpb25CdWlsZGVyTWlkfSBBIGJ1aWxkZXIgaW5zdGFuY2UgZm9yIGNoYWluaW5nIGRlZmluaXRpb25zXG4gICAqL1xuICBzdGF0aWMgZm9yKGtleTogc3RyaW5nKTogRGVjb3JhdGlvbkJ1aWxkZXJNaWQge1xuICAgIHJldHVybiBuZXcgRGVjb3JhdGlvbigpLmZvcihrZXkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTdGFydHMgYSBidWlsZGVyIGZvciBhIHNwZWNpZmljIGZsYXZvdXJcbiAgICogQHN1bW1hcnkgQ29udmVuaWVuY2UgbWV0aG9kIHRvIGJlZ2luIGEgRGVjb3JhdGlvbiBidWlsZGVyIGNoYWluIGJvdW5kIHRvIHRoZSBnaXZlbiBmbGF2b3VyIGlkZW50aWZpZXIsIGFsbG93aW5nIHJlZ2lzdHJhdGlvbiBvZiBmbGF2b3VyLXNwZWNpZmljIGRlY29yYXRvcnMuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmbGF2b3VyIFRoZSBmbGF2b3VyIG5hbWUgdG8gYmluZCB0byB0aGUgYnVpbGRlclxuICAgKiBAcmV0dXJuIHtEZWNvcmF0aW9uQnVpbGRlclN0YXJ0fSBBIGJ1aWxkZXIgc3RhcnQgaW50ZXJmYWNlIHRvIGNvbnRpbnVlIGNvbmZpZ3VyYXRpb25cbiAgICovXG4gIHN0YXRpYyBmbGF2b3VyZWRBcyhmbGF2b3VyOiBzdHJpbmcpOiBEZWNvcmF0aW9uQnVpbGRlclN0YXJ0IHtcbiAgICByZXR1cm4gbmV3IERlY29yYXRpb24oZmxhdm91cik7XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,196 @@
1
+ import { DecorationBuilderBuild, DecorationBuilderEnd, DecorationBuilderMid, DecorationBuilderStart, FlavourResolver, IDecorationBuilder } from "./types";
2
+ /**
3
+ * @description Union type covering supported decorator kinds
4
+ * @summary Represents any of the standard TypeScript decorator signatures (class, property, or method), enabling flexible registration and application within the Decoration system.
5
+ * @template T
6
+ * @typeDef DecoratorTypes
7
+ * @memberOf module:decoration
8
+ */
9
+ export type DecoratorTypes = ClassDecorator | PropertyDecorator | MethodDecorator;
10
+ /**
11
+ * @description Type definition for a decorator factory function
12
+ * @summary Represents a function that accepts arbitrary arguments and returns a concrete decorator function to be applied to a target.
13
+ * @template A
14
+ * @typeDef DecoratorFactory
15
+ * @memberOf module:decoration
16
+ */
17
+ export type DecoratorFactory = (...args: any[]) => DecoratorTypes;
18
+ /**
19
+ * @description Argument bundle for a decorator factory
20
+ * @summary Object form used to defer decorator creation, carrying both the factory function and its argument list to be invoked later during application.
21
+ * @typeDef DecoratorFactoryArgs
22
+ * @property {DecoratorFactory} decorator The factory function that produces a decorator when invoked
23
+ * @property {any[]} [args] Optional list of arguments to pass to the decorator factory
24
+ * @memberOf module:decoration
25
+ */
26
+ export type DecoratorFactoryArgs = {
27
+ decorator: DecoratorFactory;
28
+ args?: any[];
29
+ };
30
+ /**
31
+ * @description Union that represents either a ready-to-apply decorator or a factory with arguments
32
+ * @summary Allows registering decorators in two forms: as direct decorator functions or as deferred factories paired with their argument lists for later instantiation.
33
+ * @typeDef DecoratorData
34
+ * @memberOf module:decoration
35
+ */
36
+ export type DecoratorData = DecoratorTypes | DecoratorFactoryArgs;
37
+ /**
38
+ * @description A decorator management class that handles flavoured decorators
39
+ * @summary The Decoration class provides a builder pattern for creating and managing decorators with different flavours.
40
+ * It supports registering, extending, and applying decorators with context-aware flavour resolution.
41
+ * The class implements a fluent interface for defining, extending, and applying decorators with different flavours,
42
+ * allowing for framework-specific decorator implementations while maintaining a consistent API.
43
+ * @template T Type of the decorator (ClassDecorator | PropertyDecorator | MethodDecorator)
44
+ * @param {string} [flavour] Optional flavour parameter for the decorator context
45
+ * @class
46
+ * @example
47
+ * ```typescript
48
+ * // Create a new decoration for 'component' with default flavour
49
+ * const componentDecorator = new Decoration()
50
+ * .for('component')
51
+ * .define(customComponentDecorator);
52
+ *
53
+ * // Create a flavoured decoration
54
+ * const vueComponent = new Decoration('vue')
55
+ * .for('component')
56
+ * .define(vueComponentDecorator);
57
+ *
58
+ * // Apply the decoration
59
+ * @componentDecorator
60
+ * class MyComponent {}
61
+ * ```
62
+ * @mermaid
63
+ * sequenceDiagram
64
+ * participant C as Client
65
+ * participant D as Decoration
66
+ * participant R as FlavourResolver
67
+ * participant F as DecoratorFactory
68
+ *
69
+ * C->>D: new Decoration(flavour)
70
+ * C->>D: for(key)
71
+ * C->>D: define(decorators)
72
+ * D->>D: register(key, flavour, decorators)
73
+ * D->>F: decoratorFactory(key, flavour)
74
+ * F->>R: resolve(target)
75
+ * R-->>F: resolved flavour
76
+ * F->>F: apply decorators
77
+ * F-->>C: decorated target
78
+ */
79
+ export declare class Decoration implements IDecorationBuilder {
80
+ private flavour;
81
+ /**
82
+ * @description Static map of registered decorators
83
+ * @summary Stores all registered decorators organized by key and flavour
84
+ */
85
+ private static decorators;
86
+ /**
87
+ * @description Function to resolve flavour from a target
88
+ * @summary Resolver function that determines the appropriate flavour for a given target
89
+ */
90
+ private static flavourResolver;
91
+ /**
92
+ * @description Set of decorators for the current context
93
+ */
94
+ private decorators?;
95
+ /**
96
+ * @description Set of additional decorators
97
+ */
98
+ private extras?;
99
+ /**
100
+ * @description Current decorator key
101
+ */
102
+ private key?;
103
+ constructor(flavour?: string);
104
+ /**
105
+ * @description Sets the key for the decoration builder
106
+ * @summary Initializes a new decoration chain with the specified key
107
+ * @param {string} key The identifier for the decorator
108
+ * @return {DecorationBuilderMid} Builder instance for method chaining
109
+ */
110
+ for(key: string): DecorationBuilderMid;
111
+ /**
112
+ * @description Adds decorators to the current context
113
+ * @summary Internal method to add decorators with addon support
114
+ * @param {boolean} [addon=false] Whether the decorators are addons
115
+ * @param decorators Array of decorators
116
+ * @return {this} Current instance for chaining
117
+ */
118
+ private decorate;
119
+ /**
120
+ * @description Defines the base decorators
121
+ * @summary Sets the primary decorators for the current context
122
+ * @param decorators Decorators to define
123
+ * @return Builder instance for finishing the chain
124
+ */
125
+ define(...decorators: DecoratorData[]): DecorationBuilderEnd & DecorationBuilderBuild;
126
+ /**
127
+ * @description Extends existing decorators
128
+ * @summary Adds additional decorators to the current context
129
+ * @param decorators Additional decorators
130
+ * @return {DecorationBuilderBuild} Builder instance for building the decorator
131
+ */
132
+ extend(...decorators: DecoratorData[]): DecorationBuilderBuild;
133
+ /**
134
+ * @description Factory that creates a context-aware decorator for a key/flavour
135
+ * @summary Produces a decorator function bound to the provided key and flavour. The resulting decorator resolves the actual
136
+ * decorators to apply at invocation time based on the target's resolved flavour and the registered base and extra decorators.
137
+ * @param {string} key The decoration key used to look up registered decorators
138
+ * @param {string} [f=DefaultFlavour] Optional explicit flavour to bind the factory to
139
+ * @return {function(object, any, TypedPropertyDescriptor<any>): any} A decorator function that applies the resolved decorators
140
+ * @mermaid
141
+ * sequenceDiagram
142
+ * participant U as User Code
143
+ * participant B as Decoration (builder)
144
+ * participant F as decoratorFactory(key, f)
145
+ * participant R as flavourResolver
146
+ * participant A as Applied Decorators
147
+ * U->>B: define()/extend() and apply()
148
+ * B->>F: create context decorator
149
+ * F->>R: resolve(target)
150
+ * R-->>F: flavour
151
+ * F->>A: collect base + extras
152
+ * loop each decorator
153
+ * A->>U: invoke decorator(target, key?, desc?)
154
+ * end
155
+ */
156
+ protected decoratorFactory(key: string, f?: string): (target: object, propertyKey?: any, descriptor?: TypedPropertyDescriptor<any>) => {
157
+ target: object;
158
+ propertyKey: any;
159
+ descriptor: TypedPropertyDescriptor<any> | undefined;
160
+ };
161
+ /**
162
+ * @description Creates the final decorator function
163
+ * @summary Builds and returns the decorator factory function
164
+ * @return {function(any, any?, TypedPropertyDescriptor?): any} The generated decorator function
165
+ */
166
+ apply(): (target: any, propertyKey?: any, descriptor?: TypedPropertyDescriptor<any>) => any;
167
+ /**
168
+ * @description Registers decorators for a specific key and flavour
169
+ * @summary Internal method to store decorators in the static registry
170
+ * @param {string} key Decorator key
171
+ * @param {string} flavour Decorator flavour
172
+ * @param [decorators] Primary decorators
173
+ * @param [extras] Additional decorators
174
+ */
175
+ private static register;
176
+ /**
177
+ * @description Sets the global flavour resolver
178
+ * @summary Configures the function used to determine decorator flavours
179
+ * @param {FlavourResolver} resolver Function to resolve flavours
180
+ */
181
+ static setFlavourResolver(resolver: FlavourResolver): void;
182
+ /**
183
+ * @description Convenience static entry to start a decoration builder
184
+ * @summary Creates a new Decoration instance and initiates the builder chain with the provided key.
185
+ * @param {string} key The decoration key to configure
186
+ * @return {DecorationBuilderMid} A builder instance for chaining definitions
187
+ */
188
+ static for(key: string): DecorationBuilderMid;
189
+ /**
190
+ * @description Starts a builder for a specific flavour
191
+ * @summary Convenience method to begin a Decoration builder chain bound to the given flavour identifier, allowing registration of flavour-specific decorators.
192
+ * @param {string} flavour The flavour name to bind to the builder
193
+ * @return {DecorationBuilderStart} A builder start interface to continue configuration
194
+ */
195
+ static flavouredAs(flavour: string): DecorationBuilderStart;
196
+ }