@xplane/core 0.9.2 → 0.11.0

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/index.js DELETED
@@ -1,682 +0,0 @@
1
- // src/core/index.ts
2
- import { Construct as Construct3 } from "constructs";
3
-
4
- // src/core/composition.ts
5
- import { Construct } from "constructs";
6
-
7
- // src/tracking/dependency-graph.ts
8
- var DependencyGraph = class {
9
- /** adjacency list: resource id → set of resource ids it depends on */
10
- _deps = /* @__PURE__ */ new Map();
11
- /** all registered resource refs by id */
12
- _resources = /* @__PURE__ */ new Map();
13
- /** raw edges for introspection */
14
- _edges = [];
15
- /** Register a resource node in the graph. */
16
- addResource(ref) {
17
- this._resources.set(ref.id, ref);
18
- if (!this._deps.has(ref.id)) {
19
- this._deps.set(ref.id, /* @__PURE__ */ new Set());
20
- }
21
- }
22
- /** Add dependency edges from the collector. */
23
- addEdges(edges) {
24
- for (const edge of edges) {
25
- this.addResource(edge.from);
26
- this.addResource(edge.to);
27
- const deps = this._deps.get(edge.to.id);
28
- if (deps) {
29
- deps.add(edge.from.id);
30
- }
31
- this._edges.push(edge);
32
- }
33
- }
34
- /** Add an explicit dependency: `dependent` depends on `dependency`. */
35
- addExplicitDependency(dependent, dependency) {
36
- this.addResource(dependent);
37
- this.addResource(dependency);
38
- const deps = this._deps.get(dependent.id);
39
- if (deps) {
40
- deps.add(dependency.id);
41
- }
42
- }
43
- /** Get all resource IDs that `resourceId` directly depends on. */
44
- getDependencies(resourceId) {
45
- return this._deps.get(resourceId) ?? /* @__PURE__ */ new Set();
46
- }
47
- /** Get all registered resource IDs. */
48
- get resourceIds() {
49
- return [...this._resources.keys()];
50
- }
51
- /** Get all raw edges. */
52
- get edges() {
53
- return this._edges;
54
- }
55
- /**
56
- * Returns resource IDs in topological order (dependencies first).
57
- * Throws if the graph contains cycles.
58
- */
59
- topologicalSort() {
60
- const visited = /* @__PURE__ */ new Set();
61
- const visiting = /* @__PURE__ */ new Set();
62
- const sorted = [];
63
- const visit = (id) => {
64
- if (visited.has(id)) return;
65
- if (visiting.has(id)) {
66
- const cycle = [...visiting, id].join(" \u2192 ");
67
- throw new Error(`Dependency cycle detected: ${cycle}`);
68
- }
69
- visiting.add(id);
70
- const deps = this._deps.get(id);
71
- if (deps) {
72
- for (const depId of deps) {
73
- visit(depId);
74
- }
75
- }
76
- visiting.delete(id);
77
- visited.add(id);
78
- sorted.push(id);
79
- };
80
- for (const id of this._resources.keys()) {
81
- visit(id);
82
- }
83
- return sorted;
84
- }
85
- };
86
-
87
- // src/tracking/types.ts
88
- var TRACKING_META = /* @__PURE__ */ Symbol.for("xplane.tracking.meta");
89
- var IS_TRACKED = /* @__PURE__ */ Symbol.for("xplane.tracking.isTracked");
90
-
91
- // src/tracking/proxy.ts
92
- var DependencyCollector = class {
93
- _edges = [];
94
- addEdge(edge) {
95
- const exists = this._edges.some(
96
- (e) => e.from.id === edge.from.id && e.fromPath === edge.fromPath && e.to.id === edge.to.id && e.toPath === edge.toPath
97
- );
98
- if (!exists) {
99
- this._edges.push(edge);
100
- }
101
- }
102
- get edges() {
103
- return this._edges;
104
- }
105
- clear() {
106
- this._edges.length = 0;
107
- }
108
- };
109
- function isTracked(value) {
110
- return typeof value === "object" && value !== null && value[IS_TRACKED] === true;
111
- }
112
- function getTrackingMeta(value) {
113
- if (isTracked(value)) {
114
- return value[TRACKING_META];
115
- }
116
- return void 0;
117
- }
118
- function createTrackedProxy(target, opts) {
119
- const meta = {
120
- owner: opts.owner,
121
- path: opts.path,
122
- observed: opts.observed
123
- };
124
- return new Proxy(target, {
125
- get(obj, prop, receiver) {
126
- if (prop === TRACKING_META) return meta;
127
- if (prop === IS_TRACKED) return true;
128
- if (prop === Symbol.toPrimitive) {
129
- if (opts.observed && Object.keys(obj).length === 0) {
130
- return () => {
131
- throw new Error(
132
- `Cannot coerce XR path '${opts.path}' to a primitive \u2014 the field does not exist in the composite resource`
133
- );
134
- };
135
- }
136
- return Reflect.get(obj, prop, receiver);
137
- }
138
- if (typeof prop === "symbol") {
139
- return Reflect.get(obj, prop, receiver);
140
- }
141
- if (prop === "toJSON") {
142
- return () => obj;
143
- }
144
- const existing = Reflect.get(obj, prop, receiver);
145
- if (isTracked(existing)) {
146
- return existing;
147
- }
148
- if (typeof existing === "object" && existing !== null) {
149
- const wrapped2 = createTrackedProxy(existing, {
150
- owner: opts.owner,
151
- path: opts.path ? `${opts.path}.${prop}` : String(prop),
152
- observed: opts.observed,
153
- collector: opts.collector
154
- });
155
- Reflect.set(obj, prop, wrapped2);
156
- return wrapped2;
157
- }
158
- if (existing !== void 0 || prop in obj) {
159
- return existing;
160
- }
161
- if (opts.observed) {
162
- const placeholder = {};
163
- const wrapped2 = createTrackedProxy(placeholder, {
164
- owner: opts.owner,
165
- path: opts.path ? `${opts.path}.${prop}` : String(prop),
166
- observed: true,
167
- collector: opts.collector
168
- });
169
- return wrapped2;
170
- }
171
- const autoCreated = {};
172
- const wrapped = createTrackedProxy(autoCreated, {
173
- owner: opts.owner,
174
- path: opts.path ? `${opts.path}.${prop}` : String(prop),
175
- observed: false,
176
- collector: opts.collector
177
- });
178
- Reflect.set(obj, prop, wrapped);
179
- return wrapped;
180
- },
181
- set(obj, prop, value) {
182
- if (typeof prop === "symbol") {
183
- return Reflect.set(obj, prop, value);
184
- }
185
- const targetPath = opts.path ? `${opts.path}.${prop}` : String(prop);
186
- if (isTracked(value)) {
187
- const sourceMeta = getTrackingMeta(value);
188
- if (sourceMeta && sourceMeta.owner.id === "__xr__") {
189
- const concrete2 = resolveTrackedValue(value);
190
- return Reflect.set(obj, prop, concrete2 === UNRESOLVED ? void 0 : concrete2);
191
- }
192
- if (sourceMeta && sourceMeta.owner.id !== opts.owner.id) {
193
- opts.collector.addEdge({
194
- from: sourceMeta.owner,
195
- fromPath: sourceMeta.path,
196
- to: opts.owner,
197
- toPath: targetPath
198
- });
199
- }
200
- const concrete = resolveTrackedValue(value);
201
- return Reflect.set(obj, prop, concrete);
202
- }
203
- if (typeof value === "object" && value !== null && !isTracked(value)) {
204
- const wrapped = createTrackedProxy(value, {
205
- owner: opts.owner,
206
- path: targetPath,
207
- observed: opts.observed,
208
- collector: opts.collector
209
- });
210
- return Reflect.set(obj, prop, wrapped);
211
- }
212
- return Reflect.set(obj, prop, value);
213
- },
214
- ownKeys(obj) {
215
- return Reflect.ownKeys(obj).filter((k) => typeof k === "string");
216
- },
217
- getOwnPropertyDescriptor(obj, prop) {
218
- const desc = Reflect.getOwnPropertyDescriptor(obj, prop);
219
- if (desc) return { ...desc, configurable: true, enumerable: true };
220
- if (opts.observed && typeof prop === "string") {
221
- return { configurable: true, enumerable: true, writable: true, value: void 0 };
222
- }
223
- return void 0;
224
- },
225
- has(obj, prop) {
226
- if (prop === IS_TRACKED || prop === TRACKING_META) return true;
227
- return Reflect.has(obj, prop);
228
- }
229
- });
230
- }
231
- var UNRESOLVED = /* @__PURE__ */ Symbol.for("xplane.unresolved");
232
- function resolveTrackedValue(tracked) {
233
- if (!isTracked(tracked)) return tracked;
234
- const obj = unwrapProxy(tracked);
235
- const keys = Object.keys(obj);
236
- const meta = getTrackingMeta(tracked);
237
- if (keys.length === 0 && meta?.observed) {
238
- return UNRESOLVED;
239
- }
240
- return obj;
241
- }
242
- function unwrapProxy(tracked) {
243
- const result = {};
244
- for (const key of Object.keys(tracked)) {
245
- result[key] = tracked[key];
246
- }
247
- return result;
248
- }
249
-
250
- // src/core/construct.ts
251
- var CONTEXT_COLLECTOR = "xplane:collector";
252
- var CONTEXT_GRAPH = "xplane:graph";
253
- var CONTEXT_XR_META = "xplane:xr-meta";
254
-
255
- // src/core/composition.ts
256
- var Composition = class _Composition extends Construct {
257
- /**
258
- * Pending XR data, set by the framework before instantiation.
259
- * @internal
260
- */
261
- static _pendingXR;
262
- /**
263
- * Pending environment data, set by the framework before instantiation.
264
- * Populated from the Crossplane context key `apiextensions.crossplane.io/environment`.
265
- * @internal
266
- */
267
- static _pendingEnvironment;
268
- /** The composite resource (XR) — proxy-wrapped for tracking. */
269
- xr;
270
- /** Environment data from function-environment-configs or other pipeline steps. */
271
- environment;
272
- /** Raw name from the XR metadata (not proxy-tracked). */
273
- xrName;
274
- /** Raw namespace from the XR metadata (not proxy-tracked). */
275
- xrNamespace;
276
- /** Dependency collector shared across all resources. */
277
- collector;
278
- /** Dependency graph built during compose(). */
279
- graph;
280
- /** Registered status output function. @internal */
281
- _statusFn;
282
- constructor() {
283
- super(void 0, "");
284
- this.collector = new DependencyCollector();
285
- this.graph = new DependencyGraph();
286
- this.node.setContext(CONTEXT_COLLECTOR, this.collector);
287
- this.node.setContext(CONTEXT_GRAPH, this.graph);
288
- const xrData = _Composition._pendingXR ?? {};
289
- _Composition._pendingXR = void 0;
290
- const envData = _Composition._pendingEnvironment ?? {};
291
- _Composition._pendingEnvironment = void 0;
292
- const xrMeta = xrData.metadata ?? {};
293
- this.xrName = typeof xrMeta.name === "string" ? xrMeta.name : void 0;
294
- this.xrNamespace = typeof xrMeta.namespace === "string" ? xrMeta.namespace : void 0;
295
- this.node.setContext(CONTEXT_XR_META, { name: this.xrName, namespace: this.xrNamespace });
296
- this.xr = createTrackedProxy(xrData, {
297
- owner: { id: "__xr__" },
298
- path: "",
299
- observed: true,
300
- collector: this.collector
301
- });
302
- this.environment = envData;
303
- }
304
- /**
305
- * Register a function that computes the desired XR status output.
306
- *
307
- * The function is called by the framework **after** observed state has been
308
- * fed into all resources, so `resource.observed` contains real data.
309
- *
310
- * @example
311
- * ```ts
312
- * this.setStatusOutput(() => ({
313
- * config: {
314
- * projectHostedZoneId: hostedZone.observed?.status?.atProvider?.id,
315
- * },
316
- * }));
317
- * ```
318
- */
319
- setStatusOutput(fn) {
320
- this._statusFn = fn;
321
- }
322
- /**
323
- * Compute and return the desired status output.
324
- * Returns an empty object if no status function was registered.
325
- * @internal
326
- */
327
- computeStatusOutput() {
328
- return this._statusFn?.() ?? {};
329
- }
330
- /**
331
- * Walk up the construct tree and return the root Composition.
332
- * Throws if the scope is not within a Composition.
333
- */
334
- static of(scope) {
335
- let current = scope;
336
- while (current !== void 0) {
337
- if (current instanceof _Composition) return current;
338
- current = current.node.scope;
339
- }
340
- throw new Error(
341
- "No Composition found in the scope chain. Ensure constructs are created within a Composition."
342
- );
343
- }
344
- /** Get all registered resources keyed by construct path. */
345
- get resources() {
346
- const map = /* @__PURE__ */ new Map();
347
- for (const construct of this.node.findAll()) {
348
- if (isResource(construct)) {
349
- map.set(construct.node.path, construct);
350
- }
351
- }
352
- return map;
353
- }
354
- };
355
- function isResource(construct) {
356
- return construct !== null && typeof construct === "object" && "apiVersion" in construct && "kind" in construct && "resourceRef" in construct;
357
- }
358
-
359
- // src/core/resource.ts
360
- import { Construct as Construct2 } from "constructs";
361
- var Resource = class extends Construct2 {
362
- apiVersion;
363
- kind;
364
- resourceRef;
365
- /** Proxy-wrapped desired spec — writes are tracked. */
366
- spec;
367
- /** Proxy-wrapped observed status — reads create dependency tracking. */
368
- status;
369
- /** Proxy-wrapped desired metadata. */
370
- metadata;
371
- /** Whether auto-ready is enabled for this resource. */
372
- autoReady;
373
- /** Extra top-level fields (e.g. data/stringData for Secret). Not proxy-tracked. */
374
- _extra;
375
- /** Observed state populated by the bridge before construction. */
376
- _observed;
377
- /** Backing object for the status proxy — populated by setObserved(). */
378
- _statusTarget;
379
- /** Backing object for the metadata proxy — populated by setObserved(). */
380
- _metaTarget;
381
- /** Keys the user explicitly declared in constructor metadata props. */
382
- _desiredMetaKeys;
383
- /** Explicit dependency refs. */
384
- _explicitDeps = [];
385
- /** @internal */
386
- _graph;
387
- constructor(scope, id, props, options) {
388
- super(scope, id);
389
- this.apiVersion = props.apiVersion;
390
- this.kind = props.kind;
391
- this.autoReady = options?.autoReady ?? true;
392
- const collector = this.node.tryGetContext(CONTEXT_COLLECTOR);
393
- const graph = this.node.tryGetContext(CONTEXT_GRAPH);
394
- if (!collector || !graph) {
395
- throw new Error("Resource must be created within a Composition tree");
396
- }
397
- this.resourceRef = { id: this.node.path };
398
- graph.addResource(this.resourceRef);
399
- const KNOWN_KEYS = /* @__PURE__ */ new Set(["apiVersion", "kind", "metadata", "spec"]);
400
- this._extra = {};
401
- for (const [k, v] of Object.entries(props)) {
402
- if (!KNOWN_KEYS.has(k)) this._extra[k] = v;
403
- }
404
- const specTarget = props.spec ?? {};
405
- resolveTrackedRefs(specTarget, this.resourceRef, "spec", collector);
406
- this.spec = createTrackedProxy(specTarget, {
407
- owner: this.resourceRef,
408
- path: "spec",
409
- observed: false,
410
- collector
411
- });
412
- this._metaTarget = props.metadata ?? {};
413
- this._desiredMetaKeys = new Set(Object.keys(this._metaTarget));
414
- this.metadata = createTrackedProxy(this._metaTarget, {
415
- owner: this.resourceRef,
416
- path: "metadata",
417
- observed: true,
418
- collector
419
- });
420
- this._statusTarget = {};
421
- this.status = createTrackedProxy(this._statusTarget, {
422
- owner: this.resourceRef,
423
- path: "status",
424
- observed: true,
425
- collector
426
- });
427
- this._graph = graph;
428
- }
429
- /** Fully qualified path in the construct tree. */
430
- get path() {
431
- return this.node.path;
432
- }
433
- /** Add an explicit dependency on another resource. */
434
- addDependency(other) {
435
- this._explicitDeps.push(other.resourceRef);
436
- this._graph.addExplicitDependency(this.resourceRef, other.resourceRef);
437
- }
438
- /** Get explicit dependency refs. */
439
- get explicitDependencies() {
440
- return this._explicitDeps;
441
- }
442
- /** Set observed state (called by the bridge before compose). */
443
- setObserved(observed) {
444
- this._observed = observed;
445
- for (const key of Object.keys(this._metaTarget)) {
446
- this._desiredMetaKeys.add(key);
447
- }
448
- if (observed.metadata && typeof observed.metadata === "object") {
449
- Object.assign(this._metaTarget, observed.metadata);
450
- }
451
- if (observed.status && typeof observed.status === "object") {
452
- Object.assign(this._statusTarget, observed.status);
453
- }
454
- }
455
- /** Get observed state. */
456
- get observed() {
457
- return this._observed;
458
- }
459
- /**
460
- * Compute a unique name for a resource based on its construct node path,
461
- * similar to `cdk.Names.uniqueResourceName`.
462
- *
463
- * The name is structured as:
464
- * `[namespace-]claimName-PathSegments[-extra]-hash8`
465
- *
466
- * - XR namespace (if present) and XR name are always prepended.
467
- * - Path segments (construct tree, root skipped) are appended next.
468
- * - An optional `extra` string is appended after the path.
469
- * - An 8-char hash of the full untruncated string is always appended for uniqueness.
470
- * - Whitespace in each segment is stripped (CDK convention).
471
- * - Disallowed characters are replaced by the separator; consecutive separators are collapsed.
472
- * - The result is truncated to `maxLength` while keeping the hash suffix.
473
- *
474
- * @param scope - The construct whose node path is used.
475
- * @param options - Optional tuning.
476
- */
477
- static uniqueName(scope, options = {}) {
478
- const maxLength = options.maxLength ?? 63;
479
- const separator = options.separator ?? "-";
480
- const allowedPattern = options.allowedPattern ?? /[^a-zA-Z0-9]/g;
481
- const escapedSep = separator.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
482
- const collapseRe = new RegExp(`${escapedSep}+`, "g");
483
- const clean = (s) => s.replace(/\s+/g, "").replace(allowedPattern, separator).replace(collapseRe, separator).replace(new RegExp(`^${escapedSep}|${escapedSep}$`, "g"), "");
484
- const xrMeta = scope.node.tryGetContext(CONTEXT_XR_META);
485
- const xrName = xrMeta?.name;
486
- const xrNamespace = xrMeta?.namespace;
487
- const parts = [];
488
- if (xrNamespace) parts.push(clean(xrNamespace));
489
- if (xrName) parts.push(clean(xrName));
490
- for (const s of scope.node.scopes.slice(1)) {
491
- const c = clean(s.node.id);
492
- if (c) parts.push(c);
493
- }
494
- if (options.extra) {
495
- const c = clean(options.extra);
496
- if (c) parts.push(c);
497
- }
498
- const full = parts.join(separator);
499
- const hash = shortHash(full);
500
- const withHash = `${full}${separator}${hash}`;
501
- if (withHash.length <= maxLength) return withHash;
502
- const prefix = full.slice(0, maxLength - hash.length - separator.length);
503
- return `${prefix}${separator}${hash}`;
504
- }
505
- /**
506
- * Serialize to a plain Kubernetes resource object for the desired state.
507
- * Strips proxy wrappers, UNRESOLVED sentinels, and server-managed metadata
508
- * fields (uid, resourceVersion, etc.) that must not appear in desired state.
509
- */
510
- toDesired() {
511
- const fullMeta = JSON.parse(JSON.stringify(this.metadata));
512
- const desiredMeta = {};
513
- for (const key of this._desiredMetaKeys) {
514
- if (key in fullMeta) {
515
- desiredMeta[key] = fullMeta[key];
516
- }
517
- }
518
- const cleanMeta = stripUnresolved(desiredMeta);
519
- const desired = {
520
- // Spread extra top-level fields first so spec/metadata take precedence
521
- ...this._extra,
522
- apiVersion: this.apiVersion,
523
- kind: this.kind,
524
- metadata: cleanMeta,
525
- spec: stripUnresolved(JSON.parse(JSON.stringify(this.spec)))
526
- };
527
- if (desired.spec && typeof desired.spec === "object" && Object.keys(desired.spec).length === 0) {
528
- delete desired.spec;
529
- }
530
- return desired;
531
- }
532
- };
533
- function shortHash(s) {
534
- let h = 5381;
535
- for (let i = 0; i < s.length; i++) {
536
- h = (h << 5) + h ^ s.charCodeAt(i);
537
- h = h >>> 0;
538
- }
539
- return h.toString(16).padStart(8, "0");
540
- }
541
- function stripUnresolved(obj) {
542
- if (obj === null || obj === void 0) return obj;
543
- if (typeof obj === "symbol" && obj === UNRESOLVED) return void 0;
544
- if (Array.isArray(obj)) {
545
- return obj.map(stripUnresolved);
546
- }
547
- if (typeof obj === "object") {
548
- const result = {};
549
- for (const [key, value] of Object.entries(obj)) {
550
- const cleaned = stripUnresolved(value);
551
- if (cleaned !== void 0) {
552
- result[key] = cleaned;
553
- }
554
- }
555
- return result;
556
- }
557
- return obj;
558
- }
559
- function resolveTrackedRefs(obj, owner, basePath, collector) {
560
- for (const [key, value] of Object.entries(obj)) {
561
- const path = basePath ? `${basePath}.${key}` : key;
562
- if (isTracked(value)) {
563
- const sourceMeta = getTrackingMeta(value);
564
- if (sourceMeta && sourceMeta.owner.id !== owner.id) {
565
- collector.addEdge({
566
- from: sourceMeta.owner,
567
- fromPath: sourceMeta.path,
568
- to: owner,
569
- toPath: path
570
- });
571
- obj[key] = UNRESOLVED;
572
- }
573
- continue;
574
- }
575
- if (Array.isArray(value)) {
576
- for (let i = 0; i < value.length; i++) {
577
- const item = value[i];
578
- if (isTracked(item)) {
579
- const sourceMeta = getTrackingMeta(item);
580
- if (sourceMeta && sourceMeta.owner.id !== owner.id) {
581
- collector.addEdge({
582
- from: sourceMeta.owner,
583
- fromPath: sourceMeta.path,
584
- to: owner,
585
- toPath: `${path}[${i}]`
586
- });
587
- value[i] = UNRESOLVED;
588
- }
589
- } else if (typeof item === "object" && item !== null) {
590
- resolveTrackedRefs(item, owner, `${path}[${i}]`, collector);
591
- }
592
- }
593
- continue;
594
- }
595
- if (typeof value === "object" && value !== null) {
596
- resolveTrackedRefs(value, owner, path, collector);
597
- }
598
- }
599
- }
600
-
601
- // src/ready/auto-ready.ts
602
- function isResourceReady(observed) {
603
- if (!observed) return false;
604
- const conditions = observed.status?.conditions;
605
- if (!Array.isArray(conditions) || conditions.length === 0) return true;
606
- const readyCondition = conditions.find((c) => c.type === "Ready");
607
- if (!readyCondition) return true;
608
- return readyCondition.status === "True";
609
- }
610
- function getReadyCondition(observed) {
611
- if (!observed?.status) return void 0;
612
- const conditions = observed.status.conditions;
613
- if (!Array.isArray(conditions)) return void 0;
614
- return conditions.find((c) => c.type === "Ready");
615
- }
616
-
617
- // src/sequencing/resolver.ts
618
- function resolveSequencing(resources, graph, observedResources) {
619
- const order = graph.topologicalSort();
620
- const emit = [];
621
- const blocked = [];
622
- for (const resourceId of order) {
623
- const resource = findResourceByRef(resources, resourceId);
624
- if (!resource) continue;
625
- const deps = graph.getDependencies(resourceId);
626
- let allDepsReady = true;
627
- for (const depId of deps) {
628
- const depResource = findResourceByRef(resources, depId);
629
- if (!depResource) {
630
- allDepsReady = false;
631
- continue;
632
- }
633
- const observed = observedResources.get(depResource.path);
634
- if (!observed) {
635
- allDepsReady = false;
636
- }
637
- }
638
- if (allDepsReady && hasUnresolvedFields(resource)) {
639
- allDepsReady = false;
640
- }
641
- if (allDepsReady) {
642
- emit.push(resource);
643
- } else {
644
- blocked.push(resource);
645
- }
646
- }
647
- return { emit, blocked, order };
648
- }
649
- function hasUnresolvedFields(resource) {
650
- return containsUnresolved(resource.spec) || containsUnresolved(resource.metadata);
651
- }
652
- function containsUnresolved(obj) {
653
- if (obj === UNRESOLVED) return true;
654
- if (obj === null || obj === void 0) return false;
655
- if (Array.isArray(obj)) {
656
- return obj.some(containsUnresolved);
657
- }
658
- if (typeof obj === "object") {
659
- return Object.values(obj).some(containsUnresolved);
660
- }
661
- return false;
662
- }
663
- function findResourceByRef(resources, refId) {
664
- return resources.get(refId);
665
- }
666
- export {
667
- Composition,
668
- Construct3 as Construct,
669
- DependencyCollector,
670
- DependencyGraph,
671
- IS_TRACKED,
672
- Resource,
673
- TRACKING_META,
674
- UNRESOLVED,
675
- createTrackedProxy,
676
- getReadyCondition,
677
- getTrackingMeta,
678
- isResourceReady,
679
- isTracked,
680
- resolveSequencing
681
- };
682
- //# sourceMappingURL=index.js.map