@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.
- package/LICENSE.md +21 -0
- package/README.md +385 -0
- package/dist/decoration.cjs +649 -0
- package/dist/decoration.esm.cjs +633 -0
- package/lib/constants.cjs +64 -0
- package/lib/constants.d.ts +58 -0
- package/lib/decoration/Decoration.cjs +270 -0
- package/lib/decoration/Decoration.d.ts +196 -0
- package/lib/decoration/index.cjs +19 -0
- package/lib/decoration/index.d.ts +2 -0
- package/lib/decoration/types.cjs +3 -0
- package/lib/decoration/types.d.ts +95 -0
- package/lib/decorators.cjs +97 -0
- package/lib/decorators.d.ts +57 -0
- package/lib/esm/constants.d.ts +58 -0
- package/lib/esm/constants.js +61 -0
- package/lib/esm/decoration/Decoration.d.ts +196 -0
- package/lib/esm/decoration/Decoration.js +266 -0
- package/lib/esm/decoration/index.d.ts +2 -0
- package/lib/esm/decoration/index.js +3 -0
- package/lib/esm/decoration/types.d.ts +95 -0
- package/lib/esm/decoration/types.js +2 -0
- package/lib/esm/decorators.d.ts +57 -0
- package/lib/esm/decorators.js +90 -0
- package/lib/esm/index.d.ts +21 -0
- package/lib/esm/index.js +22 -0
- package/lib/esm/metadata/Metadata.d.ts +99 -0
- package/lib/esm/metadata/Metadata.js +199 -0
- package/lib/esm/metadata/index.d.ts +2 -0
- package/lib/esm/metadata/index.js +3 -0
- package/lib/esm/metadata/types.d.ts +16 -0
- package/lib/esm/metadata/types.js +2 -0
- package/lib/index.cjs +39 -0
- package/lib/index.d.ts +21 -0
- package/lib/metadata/Metadata.cjs +203 -0
- package/lib/metadata/Metadata.d.ts +99 -0
- package/lib/metadata/index.cjs +19 -0
- package/lib/metadata/index.d.ts +2 -0
- package/lib/metadata/types.cjs +4 -0
- package/lib/metadata/types.d.ts +16 -0
- 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
|
+
}
|