@milaboratories/pl-model-common 1.25.0 → 1.25.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/flags/flag_utils.cjs +21 -0
- package/dist/flags/flag_utils.cjs.map +1 -1
- package/dist/flags/flag_utils.d.ts +6 -0
- package/dist/flags/flag_utils.d.ts.map +1 -1
- package/dist/flags/flag_utils.js +21 -1
- package/dist/flags/flag_utils.js.map +1 -1
- package/dist/index.cjs +1 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +5 -5
- package/src/flags/flag_utils.ts +22 -0
|
@@ -29,6 +29,26 @@ function extractAllSupports(flags) {
|
|
|
29
29
|
.filter(([key, value]) => key.startsWith("supports") && value === true)
|
|
30
30
|
.map(([key]) => key));
|
|
31
31
|
}
|
|
32
|
+
/**
|
|
33
|
+
* Merges two feature flag objects with type-aware logic:
|
|
34
|
+
* - `supports*` (boolean): OR — `true` if either side is `true`
|
|
35
|
+
* - `requires*` (numeric): MAX — take the higher version requirement
|
|
36
|
+
*/
|
|
37
|
+
function mergeFeatureFlags(base, override) {
|
|
38
|
+
const result = { ...base };
|
|
39
|
+
for (const [key, value] of Object.entries(override)) {
|
|
40
|
+
if (value === undefined)
|
|
41
|
+
continue;
|
|
42
|
+
const existing = result[key];
|
|
43
|
+
if (typeof value === "boolean") {
|
|
44
|
+
result[key] = existing || value;
|
|
45
|
+
}
|
|
46
|
+
else if (typeof value === "number") {
|
|
47
|
+
result[key] = Math.max(existing ?? 0, value);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
32
52
|
class IncompatibleFlagsError extends Error {
|
|
33
53
|
incompatibleFlags;
|
|
34
54
|
name = "IncompatibleFlagsError";
|
|
@@ -99,4 +119,5 @@ exports.RuntimeCapabilities = RuntimeCapabilities;
|
|
|
99
119
|
exports.checkBlockFlag = checkBlockFlag;
|
|
100
120
|
exports.extractAllRequirements = extractAllRequirements;
|
|
101
121
|
exports.extractAllSupports = extractAllSupports;
|
|
122
|
+
exports.mergeFeatureFlags = mergeFeatureFlags;
|
|
102
123
|
//# sourceMappingURL=flag_utils.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flag_utils.cjs","sources":["../../src/flags/flag_utils.ts"],"sourcesContent":["import type { BlockCodeFeatureFlags, BlockCodeKnownFeatureFlags } from \"./block_flags\";\nimport type { FilterKeysByPrefix } from \"./type_utils\";\n\nexport function checkBlockFlag(\n flags: BlockCodeFeatureFlags | undefined,\n flag: keyof BlockCodeKnownFeatureFlags,\n flagValue: boolean | number = true,\n): boolean {\n if (flags === undefined) return false;\n return flags[flag] === flagValue;\n}\n\n/**\n * Extracts all requirements from the feature flags.\n * @param flags - The feature flags.\n * @returns A set of requirements.\n */\nexport function extractAllRequirements(\n flags: BlockCodeFeatureFlags | undefined,\n): Set<`requires${string}`> {\n if (flags === undefined) return new Set();\n return new Set(\n Object.entries(flags)\n .filter(([key, value]) => key.startsWith(\"requires\") && value === true)\n .map(([key]) => key as `requires${string}`),\n );\n}\n\n/**\n * Extracts all supports from the feature flags.\n * @param flags - The feature flags.\n * @returns A set of supports.\n */\nexport function extractAllSupports(\n flags: BlockCodeFeatureFlags | undefined,\n): Set<`supports${string}`> {\n if (flags === undefined) return new Set();\n return new Set(\n Object.entries(flags)\n .filter(([key, value]) => key.startsWith(\"supports\") && value === true)\n .map(([key]) => key as `supports${string}`),\n );\n}\n\nexport class IncompatibleFlagsError extends Error {\n name = \"IncompatibleFlagsError\";\n constructor(public readonly incompatibleFlags: Map<`requires${string}`, number | boolean>) {\n super(\n `Some of the block requirements are not supported by the runtime: ${Array.from(\n incompatibleFlags.entries(),\n )\n .map(([key, value]) => `${key}: ${value}`)\n .join(\", \")}`,\n );\n }\n}\n\n/**\n * A type that represents a supported requirement.\n * @remarks\n * This type is used to represent a supported requirement.\n * It is a subtype of `BlockCodeKnownFeatureFlags` and is used to represent a supported requirement.\n * It is used to represent a supported requirement.\n */\nexport type SupportedRequirement = FilterKeysByPrefix<BlockCodeKnownFeatureFlags, \"requires\">;\n\nexport class RuntimeCapabilities {\n private readonly supportedRequirements: Map<`requires${string}`, Set<number | boolean>> =\n new Map();\n\n /**\n * Adds a supported requirement to the runtime capabilities.\n * @param requirement - The requirement.\n * @param value - The value of the requirement. If not provided, defaults to true.\n */\n public addSupportedRequirement(\n requirement: SupportedRequirement,\n value: number | boolean = true,\n ): this {\n if (!this.supportedRequirements.has(requirement)) {\n this.supportedRequirements.set(requirement, new Set());\n }\n this.supportedRequirements.get(requirement)!.add(value);\n return this;\n }\n\n /**\n * Returns a map of incompatible flags. If the block flags are compatible, returns undefined.\n * @param blockFlags - The block flags.\n * @returns A map of incompatible flags, or undefined if the block flags are compatible.\n */\n public getIncompatibleFlags(\n blockFlags: BlockCodeFeatureFlags | undefined,\n ): Map<`requires${string}`, number | boolean> | undefined {\n if (blockFlags === undefined) return undefined;\n const incompatibleFlags = new Map<`requires${string}`, number | boolean>();\n for (const [key, value] of Object.entries(blockFlags)) {\n if (key.startsWith(\"requires\")) {\n if (value === undefined) continue;\n const supportedValues = this.supportedRequirements.get(key as `requires${string}`);\n if (supportedValues === undefined || !supportedValues.has(value as number | boolean)) {\n incompatibleFlags.set(key as `requires${string}`, value as number | boolean);\n }\n }\n }\n return incompatibleFlags.size === 0 ? undefined : incompatibleFlags;\n }\n\n /**\n * Checks if the block flags are compatible with the runtime capabilities.\n * @param blockFlags - The block flags.\n * @returns True if the block flags are compatible, false otherwise.\n */\n public checkCompatibility(blockFlags: BlockCodeFeatureFlags | undefined): boolean {\n return this.getIncompatibleFlags(blockFlags) === undefined;\n }\n\n /**\n * Throws an error if the block flags are incompatible with the runtime capabilities.\n * @param blockFlags - The block flags.\n * @throws IncompatibleFlagsError if the block flags are incompatible with the runtime capabilities.\n */\n public throwIfIncompatible(blockFlags: BlockCodeFeatureFlags | undefined) {\n const incompatibleFlags = this.getIncompatibleFlags(blockFlags);\n if (incompatibleFlags !== undefined) throw new IncompatibleFlagsError(incompatibleFlags);\n }\n}\n"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"flag_utils.cjs","sources":["../../src/flags/flag_utils.ts"],"sourcesContent":["import type { BlockCodeFeatureFlags, BlockCodeKnownFeatureFlags } from \"./block_flags\";\nimport type { FilterKeysByPrefix } from \"./type_utils\";\n\nexport function checkBlockFlag(\n flags: BlockCodeFeatureFlags | undefined,\n flag: keyof BlockCodeKnownFeatureFlags,\n flagValue: boolean | number = true,\n): boolean {\n if (flags === undefined) return false;\n return flags[flag] === flagValue;\n}\n\n/**\n * Extracts all requirements from the feature flags.\n * @param flags - The feature flags.\n * @returns A set of requirements.\n */\nexport function extractAllRequirements(\n flags: BlockCodeFeatureFlags | undefined,\n): Set<`requires${string}`> {\n if (flags === undefined) return new Set();\n return new Set(\n Object.entries(flags)\n .filter(([key, value]) => key.startsWith(\"requires\") && value === true)\n .map(([key]) => key as `requires${string}`),\n );\n}\n\n/**\n * Extracts all supports from the feature flags.\n * @param flags - The feature flags.\n * @returns A set of supports.\n */\nexport function extractAllSupports(\n flags: BlockCodeFeatureFlags | undefined,\n): Set<`supports${string}`> {\n if (flags === undefined) return new Set();\n return new Set(\n Object.entries(flags)\n .filter(([key, value]) => key.startsWith(\"supports\") && value === true)\n .map(([key]) => key as `supports${string}`),\n );\n}\n\n/**\n * Merges two feature flag objects with type-aware logic:\n * - `supports*` (boolean): OR — `true` if either side is `true`\n * - `requires*` (numeric): MAX — take the higher version requirement\n */\nexport function mergeFeatureFlags(\n base: BlockCodeKnownFeatureFlags,\n override: BlockCodeKnownFeatureFlags,\n): BlockCodeKnownFeatureFlags {\n const result: Record<string, boolean | number | undefined> = { ...base };\n for (const [key, value] of Object.entries(override)) {\n if (value === undefined) continue;\n const existing = result[key];\n if (typeof value === \"boolean\") {\n result[key] = (existing as boolean | undefined) || value;\n } else if (typeof value === \"number\") {\n result[key] = Math.max((existing as number) ?? 0, value);\n }\n }\n return result as BlockCodeKnownFeatureFlags;\n}\n\nexport class IncompatibleFlagsError extends Error {\n name = \"IncompatibleFlagsError\";\n constructor(public readonly incompatibleFlags: Map<`requires${string}`, number | boolean>) {\n super(\n `Some of the block requirements are not supported by the runtime: ${Array.from(\n incompatibleFlags.entries(),\n )\n .map(([key, value]) => `${key}: ${value}`)\n .join(\", \")}`,\n );\n }\n}\n\n/**\n * A type that represents a supported requirement.\n * @remarks\n * This type is used to represent a supported requirement.\n * It is a subtype of `BlockCodeKnownFeatureFlags` and is used to represent a supported requirement.\n * It is used to represent a supported requirement.\n */\nexport type SupportedRequirement = FilterKeysByPrefix<BlockCodeKnownFeatureFlags, \"requires\">;\n\nexport class RuntimeCapabilities {\n private readonly supportedRequirements: Map<`requires${string}`, Set<number | boolean>> =\n new Map();\n\n /**\n * Adds a supported requirement to the runtime capabilities.\n * @param requirement - The requirement.\n * @param value - The value of the requirement. If not provided, defaults to true.\n */\n public addSupportedRequirement(\n requirement: SupportedRequirement,\n value: number | boolean = true,\n ): this {\n if (!this.supportedRequirements.has(requirement)) {\n this.supportedRequirements.set(requirement, new Set());\n }\n this.supportedRequirements.get(requirement)!.add(value);\n return this;\n }\n\n /**\n * Returns a map of incompatible flags. If the block flags are compatible, returns undefined.\n * @param blockFlags - The block flags.\n * @returns A map of incompatible flags, or undefined if the block flags are compatible.\n */\n public getIncompatibleFlags(\n blockFlags: BlockCodeFeatureFlags | undefined,\n ): Map<`requires${string}`, number | boolean> | undefined {\n if (blockFlags === undefined) return undefined;\n const incompatibleFlags = new Map<`requires${string}`, number | boolean>();\n for (const [key, value] of Object.entries(blockFlags)) {\n if (key.startsWith(\"requires\")) {\n if (value === undefined) continue;\n const supportedValues = this.supportedRequirements.get(key as `requires${string}`);\n if (supportedValues === undefined || !supportedValues.has(value as number | boolean)) {\n incompatibleFlags.set(key as `requires${string}`, value as number | boolean);\n }\n }\n }\n return incompatibleFlags.size === 0 ? undefined : incompatibleFlags;\n }\n\n /**\n * Checks if the block flags are compatible with the runtime capabilities.\n * @param blockFlags - The block flags.\n * @returns True if the block flags are compatible, false otherwise.\n */\n public checkCompatibility(blockFlags: BlockCodeFeatureFlags | undefined): boolean {\n return this.getIncompatibleFlags(blockFlags) === undefined;\n }\n\n /**\n * Throws an error if the block flags are incompatible with the runtime capabilities.\n * @param blockFlags - The block flags.\n * @throws IncompatibleFlagsError if the block flags are incompatible with the runtime capabilities.\n */\n public throwIfIncompatible(blockFlags: BlockCodeFeatureFlags | undefined) {\n const incompatibleFlags = this.getIncompatibleFlags(blockFlags);\n if (incompatibleFlags !== undefined) throw new IncompatibleFlagsError(incompatibleFlags);\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -13,6 +13,12 @@ export declare function extractAllRequirements(flags: BlockCodeFeatureFlags | un
|
|
|
13
13
|
* @returns A set of supports.
|
|
14
14
|
*/
|
|
15
15
|
export declare function extractAllSupports(flags: BlockCodeFeatureFlags | undefined): Set<`supports${string}`>;
|
|
16
|
+
/**
|
|
17
|
+
* Merges two feature flag objects with type-aware logic:
|
|
18
|
+
* - `supports*` (boolean): OR — `true` if either side is `true`
|
|
19
|
+
* - `requires*` (numeric): MAX — take the higher version requirement
|
|
20
|
+
*/
|
|
21
|
+
export declare function mergeFeatureFlags(base: BlockCodeKnownFeatureFlags, override: BlockCodeKnownFeatureFlags): BlockCodeKnownFeatureFlags;
|
|
16
22
|
export declare class IncompatibleFlagsError extends Error {
|
|
17
23
|
readonly incompatibleFlags: Map<`requires${string}`, number | boolean>;
|
|
18
24
|
name: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flag_utils.d.ts","sourceRoot":"","sources":["../../src/flags/flag_utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AACvF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD,wBAAgB,cAAc,CAC5B,KAAK,EAAE,qBAAqB,GAAG,SAAS,EACxC,IAAI,EAAE,MAAM,0BAA0B,EACtC,SAAS,GAAE,OAAO,GAAG,MAAa,GACjC,OAAO,CAGT;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,qBAAqB,GAAG,SAAS,GACvC,GAAG,CAAC,WAAW,MAAM,EAAE,CAAC,CAO1B;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,qBAAqB,GAAG,SAAS,GACvC,GAAG,CAAC,WAAW,MAAM,EAAE,CAAC,CAO1B;AAED,qBAAa,sBAAuB,SAAQ,KAAK;aAEnB,iBAAiB,EAAE,GAAG,CAAC,WAAW,MAAM,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IADzF,IAAI,SAA4B;gBACJ,iBAAiB,EAAE,GAAG,CAAC,WAAW,MAAM,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;CAS1F;AAED;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,GAAG,kBAAkB,CAAC,0BAA0B,EAAE,UAAU,CAAC,CAAC;AAE9F,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAC1B;IAEZ;;;;OAIG;IACI,uBAAuB,CAC5B,WAAW,EAAE,oBAAoB,EACjC,KAAK,GAAE,MAAM,GAAG,OAAc,GAC7B,IAAI;IAQP;;;;OAIG;IACI,oBAAoB,CACzB,UAAU,EAAE,qBAAqB,GAAG,SAAS,GAC5C,GAAG,CAAC,WAAW,MAAM,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,SAAS;IAezD;;;;OAIG;IACI,kBAAkB,CAAC,UAAU,EAAE,qBAAqB,GAAG,SAAS,GAAG,OAAO;IAIjF;;;;OAIG;IACI,mBAAmB,CAAC,UAAU,EAAE,qBAAqB,GAAG,SAAS;CAIzE"}
|
|
1
|
+
{"version":3,"file":"flag_utils.d.ts","sourceRoot":"","sources":["../../src/flags/flag_utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,eAAe,CAAC;AACvF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAEvD,wBAAgB,cAAc,CAC5B,KAAK,EAAE,qBAAqB,GAAG,SAAS,EACxC,IAAI,EAAE,MAAM,0BAA0B,EACtC,SAAS,GAAE,OAAO,GAAG,MAAa,GACjC,OAAO,CAGT;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,qBAAqB,GAAG,SAAS,GACvC,GAAG,CAAC,WAAW,MAAM,EAAE,CAAC,CAO1B;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,qBAAqB,GAAG,SAAS,GACvC,GAAG,CAAC,WAAW,MAAM,EAAE,CAAC,CAO1B;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,0BAA0B,EAChC,QAAQ,EAAE,0BAA0B,GACnC,0BAA0B,CAY5B;AAED,qBAAa,sBAAuB,SAAQ,KAAK;aAEnB,iBAAiB,EAAE,GAAG,CAAC,WAAW,MAAM,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IADzF,IAAI,SAA4B;gBACJ,iBAAiB,EAAE,GAAG,CAAC,WAAW,MAAM,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;CAS1F;AAED;;;;;;GAMG;AACH,MAAM,MAAM,oBAAoB,GAAG,kBAAkB,CAAC,0BAA0B,EAAE,UAAU,CAAC,CAAC;AAE9F,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAC1B;IAEZ;;;;OAIG;IACI,uBAAuB,CAC5B,WAAW,EAAE,oBAAoB,EACjC,KAAK,GAAE,MAAM,GAAG,OAAc,GAC7B,IAAI;IAQP;;;;OAIG;IACI,oBAAoB,CACzB,UAAU,EAAE,qBAAqB,GAAG,SAAS,GAC5C,GAAG,CAAC,WAAW,MAAM,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,SAAS;IAezD;;;;OAIG;IACI,kBAAkB,CAAC,UAAU,EAAE,qBAAqB,GAAG,SAAS,GAAG,OAAO;IAIjF;;;;OAIG;IACI,mBAAmB,CAAC,UAAU,EAAE,qBAAqB,GAAG,SAAS;CAIzE"}
|
package/dist/flags/flag_utils.js
CHANGED
|
@@ -27,6 +27,26 @@ function extractAllSupports(flags) {
|
|
|
27
27
|
.filter(([key, value]) => key.startsWith("supports") && value === true)
|
|
28
28
|
.map(([key]) => key));
|
|
29
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Merges two feature flag objects with type-aware logic:
|
|
32
|
+
* - `supports*` (boolean): OR — `true` if either side is `true`
|
|
33
|
+
* - `requires*` (numeric): MAX — take the higher version requirement
|
|
34
|
+
*/
|
|
35
|
+
function mergeFeatureFlags(base, override) {
|
|
36
|
+
const result = { ...base };
|
|
37
|
+
for (const [key, value] of Object.entries(override)) {
|
|
38
|
+
if (value === undefined)
|
|
39
|
+
continue;
|
|
40
|
+
const existing = result[key];
|
|
41
|
+
if (typeof value === "boolean") {
|
|
42
|
+
result[key] = existing || value;
|
|
43
|
+
}
|
|
44
|
+
else if (typeof value === "number") {
|
|
45
|
+
result[key] = Math.max(existing ?? 0, value);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
30
50
|
class IncompatibleFlagsError extends Error {
|
|
31
51
|
incompatibleFlags;
|
|
32
52
|
name = "IncompatibleFlagsError";
|
|
@@ -92,5 +112,5 @@ class RuntimeCapabilities {
|
|
|
92
112
|
}
|
|
93
113
|
}
|
|
94
114
|
|
|
95
|
-
export { IncompatibleFlagsError, RuntimeCapabilities, checkBlockFlag, extractAllRequirements, extractAllSupports };
|
|
115
|
+
export { IncompatibleFlagsError, RuntimeCapabilities, checkBlockFlag, extractAllRequirements, extractAllSupports, mergeFeatureFlags };
|
|
96
116
|
//# sourceMappingURL=flag_utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flag_utils.js","sources":["../../src/flags/flag_utils.ts"],"sourcesContent":["import type { BlockCodeFeatureFlags, BlockCodeKnownFeatureFlags } from \"./block_flags\";\nimport type { FilterKeysByPrefix } from \"./type_utils\";\n\nexport function checkBlockFlag(\n flags: BlockCodeFeatureFlags | undefined,\n flag: keyof BlockCodeKnownFeatureFlags,\n flagValue: boolean | number = true,\n): boolean {\n if (flags === undefined) return false;\n return flags[flag] === flagValue;\n}\n\n/**\n * Extracts all requirements from the feature flags.\n * @param flags - The feature flags.\n * @returns A set of requirements.\n */\nexport function extractAllRequirements(\n flags: BlockCodeFeatureFlags | undefined,\n): Set<`requires${string}`> {\n if (flags === undefined) return new Set();\n return new Set(\n Object.entries(flags)\n .filter(([key, value]) => key.startsWith(\"requires\") && value === true)\n .map(([key]) => key as `requires${string}`),\n );\n}\n\n/**\n * Extracts all supports from the feature flags.\n * @param flags - The feature flags.\n * @returns A set of supports.\n */\nexport function extractAllSupports(\n flags: BlockCodeFeatureFlags | undefined,\n): Set<`supports${string}`> {\n if (flags === undefined) return new Set();\n return new Set(\n Object.entries(flags)\n .filter(([key, value]) => key.startsWith(\"supports\") && value === true)\n .map(([key]) => key as `supports${string}`),\n );\n}\n\nexport class IncompatibleFlagsError extends Error {\n name = \"IncompatibleFlagsError\";\n constructor(public readonly incompatibleFlags: Map<`requires${string}`, number | boolean>) {\n super(\n `Some of the block requirements are not supported by the runtime: ${Array.from(\n incompatibleFlags.entries(),\n )\n .map(([key, value]) => `${key}: ${value}`)\n .join(\", \")}`,\n );\n }\n}\n\n/**\n * A type that represents a supported requirement.\n * @remarks\n * This type is used to represent a supported requirement.\n * It is a subtype of `BlockCodeKnownFeatureFlags` and is used to represent a supported requirement.\n * It is used to represent a supported requirement.\n */\nexport type SupportedRequirement = FilterKeysByPrefix<BlockCodeKnownFeatureFlags, \"requires\">;\n\nexport class RuntimeCapabilities {\n private readonly supportedRequirements: Map<`requires${string}`, Set<number | boolean>> =\n new Map();\n\n /**\n * Adds a supported requirement to the runtime capabilities.\n * @param requirement - The requirement.\n * @param value - The value of the requirement. If not provided, defaults to true.\n */\n public addSupportedRequirement(\n requirement: SupportedRequirement,\n value: number | boolean = true,\n ): this {\n if (!this.supportedRequirements.has(requirement)) {\n this.supportedRequirements.set(requirement, new Set());\n }\n this.supportedRequirements.get(requirement)!.add(value);\n return this;\n }\n\n /**\n * Returns a map of incompatible flags. If the block flags are compatible, returns undefined.\n * @param blockFlags - The block flags.\n * @returns A map of incompatible flags, or undefined if the block flags are compatible.\n */\n public getIncompatibleFlags(\n blockFlags: BlockCodeFeatureFlags | undefined,\n ): Map<`requires${string}`, number | boolean> | undefined {\n if (blockFlags === undefined) return undefined;\n const incompatibleFlags = new Map<`requires${string}`, number | boolean>();\n for (const [key, value] of Object.entries(blockFlags)) {\n if (key.startsWith(\"requires\")) {\n if (value === undefined) continue;\n const supportedValues = this.supportedRequirements.get(key as `requires${string}`);\n if (supportedValues === undefined || !supportedValues.has(value as number | boolean)) {\n incompatibleFlags.set(key as `requires${string}`, value as number | boolean);\n }\n }\n }\n return incompatibleFlags.size === 0 ? undefined : incompatibleFlags;\n }\n\n /**\n * Checks if the block flags are compatible with the runtime capabilities.\n * @param blockFlags - The block flags.\n * @returns True if the block flags are compatible, false otherwise.\n */\n public checkCompatibility(blockFlags: BlockCodeFeatureFlags | undefined): boolean {\n return this.getIncompatibleFlags(blockFlags) === undefined;\n }\n\n /**\n * Throws an error if the block flags are incompatible with the runtime capabilities.\n * @param blockFlags - The block flags.\n * @throws IncompatibleFlagsError if the block flags are incompatible with the runtime capabilities.\n */\n public throwIfIncompatible(blockFlags: BlockCodeFeatureFlags | undefined) {\n const incompatibleFlags = this.getIncompatibleFlags(blockFlags);\n if (incompatibleFlags !== undefined) throw new IncompatibleFlagsError(incompatibleFlags);\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"flag_utils.js","sources":["../../src/flags/flag_utils.ts"],"sourcesContent":["import type { BlockCodeFeatureFlags, BlockCodeKnownFeatureFlags } from \"./block_flags\";\nimport type { FilterKeysByPrefix } from \"./type_utils\";\n\nexport function checkBlockFlag(\n flags: BlockCodeFeatureFlags | undefined,\n flag: keyof BlockCodeKnownFeatureFlags,\n flagValue: boolean | number = true,\n): boolean {\n if (flags === undefined) return false;\n return flags[flag] === flagValue;\n}\n\n/**\n * Extracts all requirements from the feature flags.\n * @param flags - The feature flags.\n * @returns A set of requirements.\n */\nexport function extractAllRequirements(\n flags: BlockCodeFeatureFlags | undefined,\n): Set<`requires${string}`> {\n if (flags === undefined) return new Set();\n return new Set(\n Object.entries(flags)\n .filter(([key, value]) => key.startsWith(\"requires\") && value === true)\n .map(([key]) => key as `requires${string}`),\n );\n}\n\n/**\n * Extracts all supports from the feature flags.\n * @param flags - The feature flags.\n * @returns A set of supports.\n */\nexport function extractAllSupports(\n flags: BlockCodeFeatureFlags | undefined,\n): Set<`supports${string}`> {\n if (flags === undefined) return new Set();\n return new Set(\n Object.entries(flags)\n .filter(([key, value]) => key.startsWith(\"supports\") && value === true)\n .map(([key]) => key as `supports${string}`),\n );\n}\n\n/**\n * Merges two feature flag objects with type-aware logic:\n * - `supports*` (boolean): OR — `true` if either side is `true`\n * - `requires*` (numeric): MAX — take the higher version requirement\n */\nexport function mergeFeatureFlags(\n base: BlockCodeKnownFeatureFlags,\n override: BlockCodeKnownFeatureFlags,\n): BlockCodeKnownFeatureFlags {\n const result: Record<string, boolean | number | undefined> = { ...base };\n for (const [key, value] of Object.entries(override)) {\n if (value === undefined) continue;\n const existing = result[key];\n if (typeof value === \"boolean\") {\n result[key] = (existing as boolean | undefined) || value;\n } else if (typeof value === \"number\") {\n result[key] = Math.max((existing as number) ?? 0, value);\n }\n }\n return result as BlockCodeKnownFeatureFlags;\n}\n\nexport class IncompatibleFlagsError extends Error {\n name = \"IncompatibleFlagsError\";\n constructor(public readonly incompatibleFlags: Map<`requires${string}`, number | boolean>) {\n super(\n `Some of the block requirements are not supported by the runtime: ${Array.from(\n incompatibleFlags.entries(),\n )\n .map(([key, value]) => `${key}: ${value}`)\n .join(\", \")}`,\n );\n }\n}\n\n/**\n * A type that represents a supported requirement.\n * @remarks\n * This type is used to represent a supported requirement.\n * It is a subtype of `BlockCodeKnownFeatureFlags` and is used to represent a supported requirement.\n * It is used to represent a supported requirement.\n */\nexport type SupportedRequirement = FilterKeysByPrefix<BlockCodeKnownFeatureFlags, \"requires\">;\n\nexport class RuntimeCapabilities {\n private readonly supportedRequirements: Map<`requires${string}`, Set<number | boolean>> =\n new Map();\n\n /**\n * Adds a supported requirement to the runtime capabilities.\n * @param requirement - The requirement.\n * @param value - The value of the requirement. If not provided, defaults to true.\n */\n public addSupportedRequirement(\n requirement: SupportedRequirement,\n value: number | boolean = true,\n ): this {\n if (!this.supportedRequirements.has(requirement)) {\n this.supportedRequirements.set(requirement, new Set());\n }\n this.supportedRequirements.get(requirement)!.add(value);\n return this;\n }\n\n /**\n * Returns a map of incompatible flags. If the block flags are compatible, returns undefined.\n * @param blockFlags - The block flags.\n * @returns A map of incompatible flags, or undefined if the block flags are compatible.\n */\n public getIncompatibleFlags(\n blockFlags: BlockCodeFeatureFlags | undefined,\n ): Map<`requires${string}`, number | boolean> | undefined {\n if (blockFlags === undefined) return undefined;\n const incompatibleFlags = new Map<`requires${string}`, number | boolean>();\n for (const [key, value] of Object.entries(blockFlags)) {\n if (key.startsWith(\"requires\")) {\n if (value === undefined) continue;\n const supportedValues = this.supportedRequirements.get(key as `requires${string}`);\n if (supportedValues === undefined || !supportedValues.has(value as number | boolean)) {\n incompatibleFlags.set(key as `requires${string}`, value as number | boolean);\n }\n }\n }\n return incompatibleFlags.size === 0 ? undefined : incompatibleFlags;\n }\n\n /**\n * Checks if the block flags are compatible with the runtime capabilities.\n * @param blockFlags - The block flags.\n * @returns True if the block flags are compatible, false otherwise.\n */\n public checkCompatibility(blockFlags: BlockCodeFeatureFlags | undefined): boolean {\n return this.getIncompatibleFlags(blockFlags) === undefined;\n }\n\n /**\n * Throws an error if the block flags are incompatible with the runtime capabilities.\n * @param blockFlags - The block flags.\n * @throws IncompatibleFlagsError if the block flags are incompatible with the runtime capabilities.\n */\n public throwIfIncompatible(blockFlags: BlockCodeFeatureFlags | undefined) {\n const incompatibleFlags = this.getIncompatibleFlags(blockFlags);\n if (incompatibleFlags !== undefined) throw new IncompatibleFlagsError(incompatibleFlags);\n }\n}\n"],"names":[],"mappings":"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"}
|
package/dist/index.cjs
CHANGED
|
@@ -145,6 +145,7 @@ exports.RuntimeCapabilities = flag_utils.RuntimeCapabilities;
|
|
|
145
145
|
exports.checkBlockFlag = flag_utils.checkBlockFlag;
|
|
146
146
|
exports.extractAllRequirements = flag_utils.extractAllRequirements;
|
|
147
147
|
exports.extractAllSupports = flag_utils.extractAllSupports;
|
|
148
|
+
exports.mergeFeatureFlags = flag_utils.mergeFeatureFlags;
|
|
148
149
|
exports.bigintReplacer = json.bigintReplacer;
|
|
149
150
|
exports.canonicalizeJson = json.canonicalizeJson;
|
|
150
151
|
exports.parseJson = json.parseJson;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/index.js
CHANGED
|
@@ -20,7 +20,7 @@ export { LinkerMap } from './drivers/pframe/linker_columns.js';
|
|
|
20
20
|
export { ChunkedStreamReader } from './drivers/ChunkedStreamReader.js';
|
|
21
21
|
export { AbortError, PFrameDriverError, PFrameError, UiError, deserializeError, deserializeResult, ensureError, hasAbortError, isAbortError, isAggregateError, isPFrameDriverError, isPFrameError, serializeError, serializeResult, unwrapResult, wrapAndSerialize, wrapAndSerializeAsync, wrapAsyncCallback, wrapCallback } from './errors.js';
|
|
22
22
|
export { AllRequiresFeatureFlags, AllSupportsFeatureFlags } from './flags/block_flags.js';
|
|
23
|
-
export { IncompatibleFlagsError, RuntimeCapabilities, checkBlockFlag, extractAllRequirements, extractAllSupports } from './flags/flag_utils.js';
|
|
23
|
+
export { IncompatibleFlagsError, RuntimeCapabilities, checkBlockFlag, extractAllRequirements, extractAllSupports, mergeFeatureFlags } from './flags/flag_utils.js';
|
|
24
24
|
export { bigintReplacer, canonicalizeJson, parseJson, stringifyJson } from './json.js';
|
|
25
25
|
export { DefaultNavigationState } from './navigation.js';
|
|
26
26
|
export { PlId, PlIdBytes, PlIdLength, digestPlId, plId, uniquePlId } from './plid.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milaboratories/pl-model-common",
|
|
3
|
-
"version": "1.25.
|
|
3
|
+
"version": "1.25.1",
|
|
4
4
|
"description": "Platforma SDK Model",
|
|
5
5
|
"files": [
|
|
6
6
|
"./dist/**/*",
|
|
@@ -22,12 +22,12 @@
|
|
|
22
22
|
"@milaboratories/pl-error-like": "1.12.8"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@vitest/coverage-istanbul": "^4.0.
|
|
25
|
+
"@vitest/coverage-istanbul": "^4.0.18",
|
|
26
26
|
"typescript": "~5.6.3",
|
|
27
|
-
"vitest": "^4.0.
|
|
28
|
-
"@milaboratories/
|
|
27
|
+
"vitest": "^4.0.18",
|
|
28
|
+
"@milaboratories/ts-builder": "1.2.11",
|
|
29
29
|
"@milaboratories/ts-configs": "1.2.1",
|
|
30
|
-
"@milaboratories/
|
|
30
|
+
"@milaboratories/build-configs": "1.5.0"
|
|
31
31
|
},
|
|
32
32
|
"scripts": {
|
|
33
33
|
"build": "ts-builder build --target node",
|
package/src/flags/flag_utils.ts
CHANGED
|
@@ -42,6 +42,28 @@ export function extractAllSupports(
|
|
|
42
42
|
);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
+
/**
|
|
46
|
+
* Merges two feature flag objects with type-aware logic:
|
|
47
|
+
* - `supports*` (boolean): OR — `true` if either side is `true`
|
|
48
|
+
* - `requires*` (numeric): MAX — take the higher version requirement
|
|
49
|
+
*/
|
|
50
|
+
export function mergeFeatureFlags(
|
|
51
|
+
base: BlockCodeKnownFeatureFlags,
|
|
52
|
+
override: BlockCodeKnownFeatureFlags,
|
|
53
|
+
): BlockCodeKnownFeatureFlags {
|
|
54
|
+
const result: Record<string, boolean | number | undefined> = { ...base };
|
|
55
|
+
for (const [key, value] of Object.entries(override)) {
|
|
56
|
+
if (value === undefined) continue;
|
|
57
|
+
const existing = result[key];
|
|
58
|
+
if (typeof value === "boolean") {
|
|
59
|
+
result[key] = (existing as boolean | undefined) || value;
|
|
60
|
+
} else if (typeof value === "number") {
|
|
61
|
+
result[key] = Math.max((existing as number) ?? 0, value);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return result as BlockCodeKnownFeatureFlags;
|
|
65
|
+
}
|
|
66
|
+
|
|
45
67
|
export class IncompatibleFlagsError extends Error {
|
|
46
68
|
name = "IncompatibleFlagsError";
|
|
47
69
|
constructor(public readonly incompatibleFlags: Map<`requires${string}`, number | boolean>) {
|