@azure/provisioning-core 0.1.0-alpha.20261014.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.
Files changed (152) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +62 -0
  3. package/dist/constructs/built-in-resources/resource-group.d.ts +50 -0
  4. package/dist/constructs/built-in-resources/resource-group.d.ts.map +1 -0
  5. package/dist/constructs/built-in-resources/resource-group.js +97 -0
  6. package/dist/constructs/built-in-resources/resource-group.js.map +1 -0
  7. package/dist/constructs/output.d.ts +80 -0
  8. package/dist/constructs/output.d.ts.map +1 -0
  9. package/dist/constructs/output.js +76 -0
  10. package/dist/constructs/output.js.map +1 -0
  11. package/dist/constructs/parameter.d.ts +77 -0
  12. package/dist/constructs/parameter.d.ts.map +1 -0
  13. package/dist/constructs/parameter.js +93 -0
  14. package/dist/constructs/parameter.js.map +1 -0
  15. package/dist/constructs/provisioning-component.d.ts +91 -0
  16. package/dist/constructs/provisioning-component.d.ts.map +1 -0
  17. package/dist/constructs/provisioning-component.js +150 -0
  18. package/dist/constructs/provisioning-component.js.map +1 -0
  19. package/dist/constructs/resource/resource-proxy.d.ts +134 -0
  20. package/dist/constructs/resource/resource-proxy.d.ts.map +1 -0
  21. package/dist/constructs/resource/resource-proxy.js +523 -0
  22. package/dist/constructs/resource/resource-proxy.js.map +1 -0
  23. package/dist/constructs/resource/resource-query.d.ts +23 -0
  24. package/dist/constructs/resource/resource-query.d.ts.map +1 -0
  25. package/dist/constructs/resource/resource-query.js +71 -0
  26. package/dist/constructs/resource/resource-query.js.map +1 -0
  27. package/dist/constructs/resource/resource-registry.d.ts +99 -0
  28. package/dist/constructs/resource/resource-registry.d.ts.map +1 -0
  29. package/dist/constructs/resource/resource-registry.js +51 -0
  30. package/dist/constructs/resource/resource-registry.js.map +1 -0
  31. package/dist/constructs/resource/resource-type-registry.d.ts +46 -0
  32. package/dist/constructs/resource/resource-type-registry.d.ts.map +1 -0
  33. package/dist/constructs/resource/resource-type-registry.js +156 -0
  34. package/dist/constructs/resource/resource-type-registry.js.map +1 -0
  35. package/dist/constructs/resource/resource-utils.d.ts +60 -0
  36. package/dist/constructs/resource/resource-utils.d.ts.map +1 -0
  37. package/dist/constructs/resource/resource-utils.js +77 -0
  38. package/dist/constructs/resource/resource-utils.js.map +1 -0
  39. package/dist/constructs/resource/resource.d.ts +460 -0
  40. package/dist/constructs/resource/resource.d.ts.map +1 -0
  41. package/dist/constructs/resource/resource.js +584 -0
  42. package/dist/constructs/resource/resource.js.map +1 -0
  43. package/dist/constructs/stack.d.ts +110 -0
  44. package/dist/constructs/stack.d.ts.map +1 -0
  45. package/dist/constructs/stack.js +110 -0
  46. package/dist/constructs/stack.js.map +1 -0
  47. package/dist/constructs/variable.d.ts +63 -0
  48. package/dist/constructs/variable.d.ts.map +1 -0
  49. package/dist/constructs/variable.js +74 -0
  50. package/dist/constructs/variable.js.map +1 -0
  51. package/dist/deployment-context/deployment-context.d.ts +27 -0
  52. package/dist/deployment-context/deployment-context.d.ts.map +1 -0
  53. package/dist/deployment-context/deployment-context.js +4 -0
  54. package/dist/deployment-context/deployment-context.js.map +1 -0
  55. package/dist/expression/ast-nodes.d.ts +100 -0
  56. package/dist/expression/ast-nodes.d.ts.map +1 -0
  57. package/dist/expression/ast-nodes.js +127 -0
  58. package/dist/expression/ast-nodes.js.map +1 -0
  59. package/dist/expression/expressions.d.ts +164 -0
  60. package/dist/expression/expressions.d.ts.map +1 -0
  61. package/dist/expression/expressions.js +211 -0
  62. package/dist/expression/expressions.js.map +1 -0
  63. package/dist/fn.d.ts +194 -0
  64. package/dist/fn.d.ts.map +1 -0
  65. package/dist/fn.js +353 -0
  66. package/dist/fn.js.map +1 -0
  67. package/dist/index.d.ts +25 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +19 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/internal-loop.d.ts +14 -0
  72. package/dist/internal-loop.d.ts.map +1 -0
  73. package/dist/internal-loop.js +16 -0
  74. package/dist/internal-loop.js.map +1 -0
  75. package/dist/internal.d.ts +13 -0
  76. package/dist/internal.d.ts.map +1 -0
  77. package/dist/internal.js +10 -0
  78. package/dist/internal.js.map +1 -0
  79. package/dist/naming/naming-policy.d.ts +56 -0
  80. package/dist/naming/naming-policy.d.ts.map +1 -0
  81. package/dist/naming/naming-policy.js +99 -0
  82. package/dist/naming/naming-policy.js.map +1 -0
  83. package/dist/naming/naming-rules.d.ts +15 -0
  84. package/dist/naming/naming-rules.d.ts.map +1 -0
  85. package/dist/naming/naming-rules.js +15 -0
  86. package/dist/naming/naming-rules.js.map +1 -0
  87. package/dist/serialization/contract/generated/ast.d.ts +508 -0
  88. package/dist/serialization/contract/generated/ast.d.ts.map +1 -0
  89. package/dist/serialization/contract/generated/ast.js +23 -0
  90. package/dist/serialization/contract/generated/ast.js.map +1 -0
  91. package/dist/serialization/contract/index.d.ts +2 -0
  92. package/dist/serialization/contract/index.d.ts.map +1 -0
  93. package/dist/serialization/contract/index.js +4 -0
  94. package/dist/serialization/contract/index.js.map +1 -0
  95. package/dist/serialization/index.d.ts +4 -0
  96. package/dist/serialization/index.d.ts.map +1 -0
  97. package/dist/serialization/index.js +5 -0
  98. package/dist/serialization/index.js.map +1 -0
  99. package/dist/serialization/json/deserialize.d.ts +24 -0
  100. package/dist/serialization/json/deserialize.d.ts.map +1 -0
  101. package/dist/serialization/json/deserialize.js +476 -0
  102. package/dist/serialization/json/deserialize.js.map +1 -0
  103. package/dist/serialization/json/encoding.d.ts +4 -0
  104. package/dist/serialization/json/encoding.d.ts.map +1 -0
  105. package/dist/serialization/json/encoding.js +323 -0
  106. package/dist/serialization/json/encoding.js.map +1 -0
  107. package/dist/serialization/json/expression.d.ts +32 -0
  108. package/dist/serialization/json/expression.d.ts.map +1 -0
  109. package/dist/serialization/json/expression.js +490 -0
  110. package/dist/serialization/json/expression.js.map +1 -0
  111. package/dist/serialization/json/lower.d.ts +41 -0
  112. package/dist/serialization/json/lower.d.ts.map +1 -0
  113. package/dist/serialization/json/lower.js +343 -0
  114. package/dist/serialization/json/lower.js.map +1 -0
  115. package/dist/serialization/json/pluralize-config.d.ts +3 -0
  116. package/dist/serialization/json/pluralize-config.d.ts.map +1 -0
  117. package/dist/serialization/json/pluralize-config.js +7 -0
  118. package/dist/serialization/json/pluralize-config.js.map +1 -0
  119. package/dist/serialization/json/serialize.d.ts +12 -0
  120. package/dist/serialization/json/serialize.d.ts.map +1 -0
  121. package/dist/serialization/json/serialize.js +399 -0
  122. package/dist/serialization/json/serialize.js.map +1 -0
  123. package/dist/serialization/json/util.d.ts +2 -0
  124. package/dist/serialization/json/util.d.ts.map +1 -0
  125. package/dist/serialization/json/util.js +19 -0
  126. package/dist/serialization/json/util.js.map +1 -0
  127. package/dist/serialization/utils.d.ts +3 -0
  128. package/dist/serialization/utils.d.ts.map +1 -0
  129. package/dist/serialization/utils.js +146 -0
  130. package/dist/serialization/utils.js.map +1 -0
  131. package/dist/shape/shape-registry.d.ts +51 -0
  132. package/dist/shape/shape-registry.d.ts.map +1 -0
  133. package/dist/shape/shape-registry.js +41 -0
  134. package/dist/shape/shape-registry.js.map +1 -0
  135. package/dist/shape/shape.d.ts +407 -0
  136. package/dist/shape/shape.d.ts.map +1 -0
  137. package/dist/shape/shape.js +425 -0
  138. package/dist/shape/shape.js.map +1 -0
  139. package/dist/shape/value-encoding.d.ts +121 -0
  140. package/dist/shape/value-encoding.d.ts.map +1 -0
  141. package/dist/shape/value-encoding.js +32 -0
  142. package/dist/shape/value-encoding.js.map +1 -0
  143. package/dist/tsconfig.tsbuildinfo +1 -0
  144. package/dist/types.d.ts +9 -0
  145. package/dist/types.d.ts.map +1 -0
  146. package/dist/types.js +4 -0
  147. package/dist/types.js.map +1 -0
  148. package/dist/util.d.ts +33 -0
  149. package/dist/util.d.ts.map +1 -0
  150. package/dist/util.js +78 -0
  151. package/dist/util.js.map +1 -0
  152. package/package.json +49 -0
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Global registry mapping a resource class's registry key to its
3
+ * constructor.
4
+ *
5
+ * Populated at module load by each class's `static {}` initializer
6
+ * (via {@link Resource.register}). The deserializer reads this
7
+ * registry to construct the correct class instance — preserving
8
+ * identity, prototype methods, and constructor-initialized child
9
+ * collections — instead of materialising a base `Resource`.
10
+ *
11
+ * Each `type@apiVersion` entry is either one flat constructor or a flat list
12
+ * of concrete constructors paired with ordered variant selectors. A selector
13
+ * can contain singleton `name`, model discriminators such as `kind`, and
14
+ * nested discriminator segments.
15
+ *
16
+ * Resolution has two modes:
17
+ *
18
+ * - **Best-effort (default).** Exact `(type, apiVersion)` first, then
19
+ * falls back to the highest registered `apiVersion` for the same
20
+ * selector. Enables
21
+ * deserializing older JSON against a newer package version without
22
+ * losing typed handles.
23
+ * - **Strict** (opt-in via `{ strict: true }`). Exact match only;
24
+ * returns `undefined` for any apiVersion the package doesn't ship.
25
+ *
26
+ * The shared registry tracks the highest `apiVersion` per `(type, selector)`.
27
+ * Best-effort lookups consult it in O(1); no scanning is needed.
28
+ *
29
+ * Keyed on a process-global symbol so multiple copies of `@azure/provisioning-core`
30
+ * in the same realm share one registry, mirroring the cross-realm
31
+ * strategy used by {@link isResource}'s brand symbol.
32
+ */
33
+ import type { Resource } from "./resource.js";
34
+ import { type FlatVariantSelector } from "./resource-type-registry.js";
35
+ /**
36
+ * A `Resource` class that's eligible to live in the registry.
37
+ *
38
+ * - The construct signature uses `any` for both `context` and `props`
39
+ * because concrete classes narrow these (child resources require a
40
+ * specific parent class as context; each resource has its own `Props`
41
+ * shape). TypeScript's parameter contravariance would reject any
42
+ * concrete parameter types here. The deserializer is the sole caller
43
+ * of resolved constructors and forwards already-correct values it
44
+ * built from the wire document.
45
+ * - The two static fields `resourceType` and `apiVersion` form the
46
+ * registry key and are always present on emitter-generated classes
47
+ * (and on the hand-maintained `ResourceGroup`).
48
+ * - The generic `T` propagates the instance type — used by the query
49
+ * API (`stack.getResources(KeyVault)` → `KeyVault[]`) to narrow
50
+ * return types without needing a separate descriptor object.
51
+ */
52
+ export type ResourceCtor<T extends Resource = Resource> = {
53
+ new (context: any, props: any, options?: any): T;
54
+ readonly resourceType: string;
55
+ readonly apiVersion: string;
56
+ };
57
+ /**
58
+ * Options controlling how {@link resolveResource} handles
59
+ * apiVersion mismatches.
60
+ */
61
+ export interface ResolveOptions {
62
+ /**
63
+ * When `true`, only an exact `(resourceType, apiVersion)` match is
64
+ * returned; the best-effort fallback to the highest registered
65
+ * version for the type is skipped. Defaults to `false`.
66
+ */
67
+ readonly strict?: boolean;
68
+ }
69
+ /**
70
+ * Register `ctor` as the canonical class for its
71
+ * `(resourceType, apiVersion[, variantSelector])` key.
72
+ *
73
+ * Pass an ordered selector for variants; omit it for ordinary resources.
74
+ * Re-registering the same constructor for the
75
+ * same key is a silent no-op so module-graph re-entry (test
76
+ * harnesses, dual-format builds) is safe. Registering a *different*
77
+ * constructor for an existing key throws — that's a genuine conflict
78
+ * (e.g. two packages claiming the same ARM type).
79
+ *
80
+ * A `(resourceType, apiVersion)` pair is either entirely flat or entirely
81
+ * variant-based. Attempting to mix both modes throws,
82
+ * preserving the invariant the deserializer relies on.
83
+ */
84
+ export declare function registerResource(ctor: ResourceCtor, variantSelector?: FlatVariantSelector): void;
85
+ /**
86
+ * Resolve the registered class for a wire resource.
87
+ *
88
+ * Default is best-effort:
89
+ * 1. Try the exact `(type, apiVersion)` entry and match its selectors
90
+ * against ARM-side keys in `state`.
91
+ * 2. On miss, retry with the highest registered version of each selector.
92
+ *
93
+ * Pass `{ strict: true }` to skip step 2 and require an exact match.
94
+ *
95
+ * Returns `undefined` when nothing matches — callers (notably the
96
+ * deserializer) then fall back to constructing a base `Resource`.
97
+ */
98
+ export declare function resolveResource(type: string, apiVersion: string, state?: Record<string, unknown>, options?: ResolveOptions): ResourceCtor | undefined;
99
+ //# sourceMappingURL=resource-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-registry.d.ts","sourceRoot":"","sources":["../../../src/constructs/resource/resource-registry.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,6BAA6B,CAAC;AAErC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,QAAQ,GAAG,QAAQ,IAAI;IACxD,KAAK,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC;IACjD,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEF;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;CAC3B;AAkBD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,YAAY,EAClB,eAAe,CAAC,EAAE,mBAAmB,GACpC,IAAI,CAON;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,CAAC,EAAE,cAAc,GACvB,YAAY,GAAG,SAAS,CAK1B"}
@@ -0,0 +1,51 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+ import { ResourceTypeRegistry, } from "./resource-type-registry.js";
4
+ const REGISTRY_SYMBOL = Symbol.for("@azure/provisioning-core.resourceRegistry");
5
+ function getRegistry() {
6
+ const host = globalThis;
7
+ let registry = host[REGISTRY_SYMBOL];
8
+ if (registry === undefined) {
9
+ registry = new ResourceTypeRegistry();
10
+ host[REGISTRY_SYMBOL] = registry;
11
+ }
12
+ return registry;
13
+ }
14
+ /**
15
+ * Register `ctor` as the canonical class for its
16
+ * `(resourceType, apiVersion[, variantSelector])` key.
17
+ *
18
+ * Pass an ordered selector for variants; omit it for ordinary resources.
19
+ * Re-registering the same constructor for the
20
+ * same key is a silent no-op so module-graph re-entry (test
21
+ * harnesses, dual-format builds) is safe. Registering a *different*
22
+ * constructor for an existing key throws — that's a genuine conflict
23
+ * (e.g. two packages claiming the same ARM type).
24
+ *
25
+ * A `(resourceType, apiVersion)` pair is either entirely flat or entirely
26
+ * variant-based. Attempting to mix both modes throws,
27
+ * preserving the invariant the deserializer relies on.
28
+ */
29
+ export function registerResource(ctor, variantSelector) {
30
+ getRegistry().register(ctor.resourceType, ctor.apiVersion, ctor, variantSelector);
31
+ }
32
+ /**
33
+ * Resolve the registered class for a wire resource.
34
+ *
35
+ * Default is best-effort:
36
+ * 1. Try the exact `(type, apiVersion)` entry and match its selectors
37
+ * against ARM-side keys in `state`.
38
+ * 2. On miss, retry with the highest registered version of each selector.
39
+ *
40
+ * Pass `{ strict: true }` to skip step 2 and require an exact match.
41
+ *
42
+ * Returns `undefined` when nothing matches — callers (notably the
43
+ * deserializer) then fall back to constructing a base `Resource`.
44
+ */
45
+ export function resolveResource(type, apiVersion, state, options) {
46
+ return getRegistry().resolve(type, apiVersion, state ?? {}, {
47
+ strict: options?.strict ?? false,
48
+ valueKeyedBy: "arm",
49
+ });
50
+ }
51
+ //# sourceMappingURL=resource-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-registry.js","sourceRoot":"","sources":["../../../src/constructs/resource/resource-registry.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAoClC,OAAO,EACL,oBAAoB,GAErB,MAAM,6BAA6B,CAAC;AAsCrC,MAAM,eAAe,GAAG,MAAM,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;AAMhF,SAAS,WAAW;IAClB,MAAM,IAAI,GAAG,UAAqC,CAAC;IACnD,IAAI,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC;IACrC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,QAAQ,GAAG,IAAI,oBAAoB,EAAgB,CAAC;QACpD,IAAI,CAAC,eAAe,CAAC,GAAG,QAAQ,CAAC;IACnC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAAkB,EAClB,eAAqC;IAErC,WAAW,EAAE,CAAC,QAAQ,CACpB,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,UAAU,EACf,IAAI,EACJ,eAAe,CAChB,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAY,EACZ,UAAkB,EAClB,KAA+B,EAC/B,OAAwB;IAExB,OAAO,WAAW,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,IAAI,EAAE,EAAE;QAC1D,MAAM,EAAE,OAAO,EAAE,MAAM,IAAI,KAAK;QAChC,YAAY,EAAE,KAAK;KACpB,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,46 @@
1
+ import type { DiscriminatorNames } from "../../shape/shape.js";
2
+ /** One discriminator pinned to a fixed value by a concrete flat variant. */
3
+ export interface FlatVariantPin {
4
+ readonly discriminator: DiscriminatorNames;
5
+ readonly value: string;
6
+ }
7
+ /** Pins selecting one concrete flat variant. */
8
+ export type FlatVariantSelector = readonly FlatVariantPin[];
9
+ /** One concrete variant together with a selector that chooses it. */
10
+ export interface FlatVariantSelection<T> {
11
+ readonly variant: T;
12
+ readonly selector: FlatVariantSelector;
13
+ }
14
+ /** One selector-to-target record stored in a variant registry bucket. */
15
+ export interface FlatVariantRegistryEntry<T> {
16
+ readonly selector: FlatVariantSelector;
17
+ readonly target: T;
18
+ }
19
+ /** One `(resourceType, apiVersion)` registry bucket. */
20
+ export type ResourceTypeRegistryEntry<T> = {
21
+ readonly kind: "flat";
22
+ readonly target: T;
23
+ } | {
24
+ readonly kind: "variants";
25
+ readonly variants: FlatVariantRegistryEntry<T>[];
26
+ };
27
+ export interface ResourceTypeRegistryResolveOptions {
28
+ readonly strict: boolean;
29
+ readonly valueKeyedBy: "js" | "arm";
30
+ }
31
+ /** Registry for versioned resource-type targets with optional variants. */
32
+ export declare class ResourceTypeRegistry<T> {
33
+ #private;
34
+ register(resourceType: string, apiVersion: string, target: T, variantSelector?: FlatVariantSelector): void;
35
+ resolve(resourceType: string, apiVersion: string, state: Record<string, unknown>, options: ResourceTypeRegistryResolveOptions): T | undefined;
36
+ }
37
+ /**
38
+ * Stable identity for duplicate detection and version indexes.
39
+ * Pins are sorted in the key because the matched state is flat and selector
40
+ * matching is a conjunction of discriminator/value pairs, independent of
41
+ * hierarchy order. The selector itself is not mutated.
42
+ */
43
+ export declare function flatVariantSelectorKey(selector: FlatVariantSelector): string;
44
+ /** Resolve the first registered selector exactly matched by `state`. */
45
+ export declare function resolveFlatVariant<T>(entries: readonly FlatVariantRegistryEntry<T>[], state: Record<string, unknown> | undefined, valueKeyedBy: "js" | "arm"): T | undefined;
46
+ //# sourceMappingURL=resource-type-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-type-registry.d.ts","sourceRoot":"","sources":["../../../src/constructs/resource/resource-type-registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE/D,4EAA4E;AAC5E,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,aAAa,EAAE,kBAAkB,CAAC;IAC3C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,gDAAgD;AAChD,MAAM,MAAM,mBAAmB,GAAG,SAAS,cAAc,EAAE,CAAC;AAE5D,qEAAqE;AACrE,MAAM,WAAW,oBAAoB,CAAC,CAAC;IACrC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;CACxC;AAED,yEAAyE;AACzE,MAAM,WAAW,wBAAwB,CAAC,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;CACpB;AAED,wDAAwD;AACxD,MAAM,MAAM,yBAAyB,CAAC,CAAC,IACnC;IACE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;CACpB,GACD;IACE,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,wBAAwB,CAAC,CAAC,CAAC,EAAE,CAAC;CAClD,CAAC;AAEN,MAAM,WAAW,kCAAkC;IACjD,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,IAAI,GAAG,KAAK,CAAC;CACrC;AAOD,2EAA2E;AAC3E,qBAAa,oBAAoB,CAAC,CAAC;;IAOjC,QAAQ,CACN,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,CAAC,EACT,eAAe,CAAC,EAAE,mBAAmB,GACpC,IAAI;IAYP,OAAO,CACL,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,OAAO,EAAE,kCAAkC,GAC1C,CAAC,GAAG,SAAS;CAiEjB;AAuFD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,MAAM,CAO5E;AAaD,wEAAwE;AACxE,wBAAgB,kBAAkB,CAAC,CAAC,EAClC,OAAO,EAAE,SAAS,wBAAwB,CAAC,CAAC,CAAC,EAAE,EAC/C,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC1C,YAAY,EAAE,IAAI,GAAG,KAAK,GACzB,CAAC,GAAG,SAAS,CASf"}
@@ -0,0 +1,156 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+ /** Registry for versioned resource-type targets with optional variants. */
4
+ export class ResourceTypeRegistry {
5
+ #exact = new Map();
6
+ #highest = new Map();
7
+ register(resourceType, apiVersion, target, variantSelector) {
8
+ const selector = variantSelector?.length ? variantSelector : undefined;
9
+ const exactKey = resourceTypeVersionKey(resourceType, apiVersion);
10
+ const exactEntry = this.#exact.get(exactKey);
11
+ const highestEntry = this.#highest.get(resourceType);
12
+ assertMode(exactEntry, selector, exactKey);
13
+ assertMode(highestEntry, selector, resourceType);
14
+ registerExact(this.#exact, exactKey, target, selector);
15
+ this.#updateHighest(resourceType, apiVersion, target, selector);
16
+ }
17
+ resolve(resourceType, apiVersion, state, options) {
18
+ const exact = resolveEntry(this.#exact.get(resourceTypeVersionKey(resourceType, apiVersion)), state, options.valueKeyedBy);
19
+ if (exact !== undefined || options.strict)
20
+ return exact;
21
+ const fallback = resolveEntry(this.#highest.get(resourceType), state, options.valueKeyedBy);
22
+ return fallback?.target;
23
+ }
24
+ #updateHighest(resourceType, apiVersion, target, selector) {
25
+ const entry = this.#highest.get(resourceType);
26
+ const versionedTarget = { apiVersion, target };
27
+ if (!entry) {
28
+ this.#highest.set(resourceType, selector
29
+ ? {
30
+ kind: "variants",
31
+ variants: [{ selector: [...selector], target: versionedTarget }],
32
+ }
33
+ : { kind: "flat", target: versionedTarget });
34
+ return;
35
+ }
36
+ if (entry.kind === "flat") {
37
+ if (apiVersionCompare(apiVersion, entry.target.apiVersion) > 0) {
38
+ this.#highest.set(resourceType, {
39
+ kind: "flat",
40
+ target: versionedTarget,
41
+ });
42
+ }
43
+ return;
44
+ }
45
+ const selectorKey = flatVariantSelectorKey(selector);
46
+ const priorIndex = entry.variants.findIndex((variant) => flatVariantSelectorKey(variant.selector) === selectorKey);
47
+ const prior = entry.variants[priorIndex];
48
+ if (!prior) {
49
+ entry.variants.push({
50
+ selector: [...selector],
51
+ target: versionedTarget,
52
+ });
53
+ }
54
+ else if (apiVersionCompare(apiVersion, prior.target.apiVersion) > 0) {
55
+ entry.variants[priorIndex] = {
56
+ selector: [...selector],
57
+ target: versionedTarget,
58
+ };
59
+ }
60
+ }
61
+ }
62
+ function assertMode(entry, selector, key) {
63
+ if (!entry)
64
+ return;
65
+ if (!selector && entry.kind === "variants") {
66
+ throw new Error(`Cannot register flat target for ${key}: variants are already registered.`);
67
+ }
68
+ if (selector && entry.kind === "flat") {
69
+ throw new Error(`Cannot register variant target for ${key}: a flat target is already registered.`);
70
+ }
71
+ }
72
+ function registerExact(entries, key, target, selector) {
73
+ const entry = entries.get(key);
74
+ if (!entry) {
75
+ entries.set(key, selector
76
+ ? {
77
+ kind: "variants",
78
+ variants: [{ selector: [...selector], target }],
79
+ }
80
+ : { kind: "flat", target });
81
+ return;
82
+ }
83
+ if (entry.kind === "flat") {
84
+ if (entry.target !== target) {
85
+ throw new Error(`Conflicting flat target registration for ${key}.`);
86
+ }
87
+ return;
88
+ }
89
+ const selectorKey = flatVariantSelectorKey(selector);
90
+ const existing = entry.variants.find((variant) => flatVariantSelectorKey(variant.selector) === selectorKey);
91
+ if (existing) {
92
+ if (existing.target !== target) {
93
+ throw new Error(`Conflicting variant target registration for ${key}@${selectorKey}.`);
94
+ }
95
+ return;
96
+ }
97
+ entry.variants.push({ selector: [...selector], target });
98
+ }
99
+ function resolveEntry(entry, state, valueKeyedBy) {
100
+ if (!entry)
101
+ return undefined;
102
+ if (entry.kind === "flat")
103
+ return entry.target;
104
+ return resolveFlatVariant(entry.variants, state, valueKeyedBy);
105
+ }
106
+ function resourceTypeVersionKey(resourceType, apiVersion) {
107
+ return `${resourceType}@${apiVersion}`;
108
+ }
109
+ /** Compare ARM API versions for best-effort fallback selection. */
110
+ function apiVersionCompare(left, right) {
111
+ if (left === right)
112
+ return 0;
113
+ if (right.startsWith(`${left}-`))
114
+ return 1;
115
+ if (left.startsWith(`${right}-`))
116
+ return -1;
117
+ return left < right ? -1 : 1;
118
+ }
119
+ /**
120
+ * Stable identity for duplicate detection and version indexes.
121
+ * Pins are sorted in the key because the matched state is flat and selector
122
+ * matching is a conjunction of discriminator/value pairs, independent of
123
+ * hierarchy order. The selector itself is not mutated.
124
+ */
125
+ export function flatVariantSelectorKey(selector) {
126
+ const pins = selector.map(({ discriminator, value }) => [discriminator.jsName, discriminator.armName, value]);
127
+ pins.sort(comparePinTuples);
128
+ return JSON.stringify(pins);
129
+ }
130
+ function comparePinTuples(left, right) {
131
+ for (let index = 0; index < left.length; index++) {
132
+ if (left[index] < right[index])
133
+ return -1;
134
+ if (left[index] > right[index])
135
+ return 1;
136
+ }
137
+ return 0;
138
+ }
139
+ /** Resolve the first registered selector exactly matched by `state`. */
140
+ export function resolveFlatVariant(entries, state, valueKeyedBy) {
141
+ if (!state)
142
+ return undefined;
143
+ for (const entry of entries) {
144
+ if (matchesSelector(entry.selector, state, valueKeyedBy)) {
145
+ return entry.target;
146
+ }
147
+ }
148
+ return undefined;
149
+ }
150
+ function matchesSelector(selector, state, valueKeyedBy) {
151
+ return selector.every(({ discriminator, value }) => {
152
+ const key = valueKeyedBy === "js" ? discriminator.jsName : discriminator.armName;
153
+ return state[key] === value;
154
+ });
155
+ }
156
+ //# sourceMappingURL=resource-type-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-type-registry.js","sourceRoot":"","sources":["../../../src/constructs/resource/resource-type-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import type { Resource, ResourceDeclaration, LoopedResource } from "./resource.js";
2
+ import type { ResourceCtor } from "./resource-registry.js";
3
+ /**
4
+ * Cross-realm-safe brand guards for resource declarations.
5
+ *
6
+ * These live in a standalone module — importing only the brand **symbols**
7
+ * (from `resource-proxy.ts`) and `resource.ts` **types** — so tree-walking
8
+ * utilities (e.g. the query layer, `ProvisioningComponent`) can identify resources
9
+ * WITHOUT a runtime import of `resource.ts`, which `extends ProvisioningComponent` and
10
+ * would otherwise create an eval-time import cycle
11
+ * (`ProvisioningComponent` → `query` → `resource` → `ProvisioningComponent`).
12
+ *
13
+ * The public guard API is these standalone functions (`isResource`,
14
+ * `isResourceDeclaration`, `isLoopedResource`, `isResourceOf`,
15
+ * `isLoopedResourceOf`) — there are no class-static guards, so a subclass
16
+ * like `Secret` never inherits a misleading `Secret.isResource(...)`.
17
+ */
18
+ /** Is `x` a scalar {@link Resource} (not a looped declaration)? */
19
+ export declare function isResource(x: unknown): x is Resource;
20
+ /**
21
+ * Is `x` a Bicep resource declaration — either a scalar {@link Resource} or
22
+ * a {@link LoopedResource}?
23
+ */
24
+ export declare function isResourceDeclaration(x: unknown): x is ResourceDeclaration;
25
+ /** Is `x` a {@link LoopedResource} (`Ctor.fromLoop(...)`)? */
26
+ export declare function isLoopedResource(x: unknown): x is LoopedResource<Resource>;
27
+ /**
28
+ * Type guard: is `x` an instance of the resource class `ctor`?
29
+ * Narrows `x` to the class's instance type, so callers can access
30
+ * subclass-specific accessors (e.g. `kv.secrets`) inside the guarded
31
+ * block.
32
+ *
33
+ * Accepts any value (`unknown`), like the other brand guards. A
34
+ * `LoopedResource<T>` is not a `Resource`, so `instanceof ctor` returns
35
+ * `false` for it — the narrowing is safe. `instanceof` alone is sufficient
36
+ * (and stricter than a brand + ARM-type-string check: a base-`Resource`
37
+ * impostor carrying the same `type`/`apiVersion` is correctly rejected), so
38
+ * no `isResource` pre-check is needed.
39
+ *
40
+ * Matches scalar resource **declarations** (from a constructor / query /
41
+ * collection). It does NOT match a `parent.at(i)` element reference of a
42
+ * looped declaration: that proxy intentionally keeps `LoopedResource`'s
43
+ * prototype (no `getPrototypeOf` trap), so `instanceof` is `false` for it
44
+ * even though its ARM reads work. If we ever need cross-realm subclass
45
+ * matching (per-subclass `Symbol.for` brands, mirroring the base
46
+ * `RESOURCE_BRAND`), this is the one place to swap.
47
+ */
48
+ export declare function isResourceOf<T extends Resource>(x: unknown, ctor: ResourceCtor<T>): x is T;
49
+ /**
50
+ * Type guard: is `x` a {@link LoopedResource} whose wrapped resource class is
51
+ * `ctor` (i.e. a `LoopedResource<T>` produced by `T.fromLoop(...)`)? Narrows
52
+ * `x` to `LoopedResource<T>`, the looped analogue of {@link isResourceOf}.
53
+ *
54
+ * Matches on the declaration's `wrappedCtor` identity — the concrete subclass
55
+ * passed to `fromLoop` — so `isLoopedResourceOf(x, StorageAccount)`
56
+ * replaces the `x.wrappedCtor === StorageAccount` checks scattered across the
57
+ * query / collection layers.
58
+ */
59
+ export declare function isLoopedResourceOf<T extends Resource>(x: unknown, ctor: ResourceCtor<T>): x is LoopedResource<T>;
60
+ //# sourceMappingURL=resource-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-utils.d.ts","sourceRoot":"","sources":["../../../src/constructs/resource/resource-utils.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,QAAQ,EACR,mBAAmB,EACnB,cAAc,EACf,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAE3D;;;;;;;;;;;;;;GAcG;AAEH,mEAAmE;AACnE,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,QAAQ,CAMpD;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,mBAAmB,CAM1E;AAED,8DAA8D;AAC9D,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,cAAc,CAAC,QAAQ,CAAC,CAM1E;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,QAAQ,EAC7C,CAAC,EAAE,OAAO,EACV,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,GACpB,CAAC,IAAI,CAAC,CAER;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,QAAQ,EACnD,CAAC,EAAE,OAAO,EACV,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,GACpB,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,CAExB"}
@@ -0,0 +1,77 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+ import { RESOURCE_BRAND, RESOURCE_DECLARATION_BRAND, LOOPED_RESOURCE_BRAND, } from "./resource-proxy.js";
4
+ /**
5
+ * Cross-realm-safe brand guards for resource declarations.
6
+ *
7
+ * These live in a standalone module — importing only the brand **symbols**
8
+ * (from `resource-proxy.ts`) and `resource.ts` **types** — so tree-walking
9
+ * utilities (e.g. the query layer, `ProvisioningComponent`) can identify resources
10
+ * WITHOUT a runtime import of `resource.ts`, which `extends ProvisioningComponent` and
11
+ * would otherwise create an eval-time import cycle
12
+ * (`ProvisioningComponent` → `query` → `resource` → `ProvisioningComponent`).
13
+ *
14
+ * The public guard API is these standalone functions (`isResource`,
15
+ * `isResourceDeclaration`, `isLoopedResource`, `isResourceOf`,
16
+ * `isLoopedResourceOf`) — there are no class-static guards, so a subclass
17
+ * like `Secret` never inherits a misleading `Secret.isResource(...)`.
18
+ */
19
+ /** Is `x` a scalar {@link Resource} (not a looped declaration)? */
20
+ export function isResource(x) {
21
+ return (typeof x === "object" &&
22
+ x !== null &&
23
+ x[RESOURCE_BRAND] === true);
24
+ }
25
+ /**
26
+ * Is `x` a Bicep resource declaration — either a scalar {@link Resource} or
27
+ * a {@link LoopedResource}?
28
+ */
29
+ export function isResourceDeclaration(x) {
30
+ return (typeof x === "object" &&
31
+ x !== null &&
32
+ x[RESOURCE_DECLARATION_BRAND] === true);
33
+ }
34
+ /** Is `x` a {@link LoopedResource} (`Ctor.fromLoop(...)`)? */
35
+ export function isLoopedResource(x) {
36
+ return (typeof x === "object" &&
37
+ x !== null &&
38
+ x[LOOPED_RESOURCE_BRAND] === true);
39
+ }
40
+ /**
41
+ * Type guard: is `x` an instance of the resource class `ctor`?
42
+ * Narrows `x` to the class's instance type, so callers can access
43
+ * subclass-specific accessors (e.g. `kv.secrets`) inside the guarded
44
+ * block.
45
+ *
46
+ * Accepts any value (`unknown`), like the other brand guards. A
47
+ * `LoopedResource<T>` is not a `Resource`, so `instanceof ctor` returns
48
+ * `false` for it — the narrowing is safe. `instanceof` alone is sufficient
49
+ * (and stricter than a brand + ARM-type-string check: a base-`Resource`
50
+ * impostor carrying the same `type`/`apiVersion` is correctly rejected), so
51
+ * no `isResource` pre-check is needed.
52
+ *
53
+ * Matches scalar resource **declarations** (from a constructor / query /
54
+ * collection). It does NOT match a `parent.at(i)` element reference of a
55
+ * looped declaration: that proxy intentionally keeps `LoopedResource`'s
56
+ * prototype (no `getPrototypeOf` trap), so `instanceof` is `false` for it
57
+ * even though its ARM reads work. If we ever need cross-realm subclass
58
+ * matching (per-subclass `Symbol.for` brands, mirroring the base
59
+ * `RESOURCE_BRAND`), this is the one place to swap.
60
+ */
61
+ export function isResourceOf(x, ctor) {
62
+ return x instanceof ctor;
63
+ }
64
+ /**
65
+ * Type guard: is `x` a {@link LoopedResource} whose wrapped resource class is
66
+ * `ctor` (i.e. a `LoopedResource<T>` produced by `T.fromLoop(...)`)? Narrows
67
+ * `x` to `LoopedResource<T>`, the looped analogue of {@link isResourceOf}.
68
+ *
69
+ * Matches on the declaration's `wrappedCtor` identity — the concrete subclass
70
+ * passed to `fromLoop` — so `isLoopedResourceOf(x, StorageAccount)`
71
+ * replaces the `x.wrappedCtor === StorageAccount` checks scattered across the
72
+ * query / collection layers.
73
+ */
74
+ export function isLoopedResourceOf(x, ctor) {
75
+ return isLoopedResource(x) && x.wrappedCtor === ctor;
76
+ }
77
+ //# sourceMappingURL=resource-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-utils.js","sourceRoot":"","sources":["../../../src/constructs/resource/resource-utils.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,EACL,cAAc,EACd,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,qBAAqB,CAAC;AAQ7B;;;;;;;;;;;;;;GAcG;AAEH,mEAAmE;AACnE,MAAM,UAAU,UAAU,CAAC,CAAU;IACnC,OAAO,CACL,OAAO,CAAC,KAAK,QAAQ;QACrB,CAAC,KAAK,IAAI;QACT,CAA6B,CAAC,cAAc,CAAC,KAAK,IAAI,CACxD,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CAAC,CAAU;IAC9C,OAAO,CACL,OAAO,CAAC,KAAK,QAAQ;QACrB,CAAC,KAAK,IAAI;QACT,CAA6B,CAAC,0BAA0B,CAAC,KAAK,IAAI,CACpE,CAAC;AACJ,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,gBAAgB,CAAC,CAAU;IACzC,OAAO,CACL,OAAO,CAAC,KAAK,QAAQ;QACrB,CAAC,KAAK,IAAI;QACT,CAA6B,CAAC,qBAAqB,CAAC,KAAK,IAAI,CAC/D,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,YAAY,CAC1B,CAAU,EACV,IAAqB;IAErB,OAAO,CAAC,YAAY,IAAI,CAAC;AAC3B,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAChC,CAAU,EACV,IAAqB;IAErB,OAAO,gBAAgB,CAAC,CAAC,CAAC,IAAK,CAAC,CAAC,WAAuB,KAAK,IAAI,CAAC;AACpE,CAAC"}