@intentius/chant 0.18.15 → 0.18.17

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.
@@ -1 +1 @@
1
- {"version":3,"file":"cloud-executor.d.ts","sourceRoot":"","sources":["../../../src/components/verbs/cloud-executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAI1C,eAAO,MAAM,aAAa,2BAAkB,CAAC;AAI7C,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gGAAgG;IAChG,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,cAAc;IAC7B,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,kFAAkF;IAClF,KAAK,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1D,uDAAuD;IACvD,IAAI,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,4FAA4F;IAC5F,IAAI,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,yEAAyE;IACzE,GAAG,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,uFAAuF;IACvF,IAAI,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,mGAAmG;IACnG,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC9C;AAID,MAAM,WAAW,cAAc;IAC7B,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,8EAA8E;IAC9E,KAAK,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/E;AAID,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,kBAAkB,CAAC;CAC3B;AAcD,eAAO,MAAM,UAAU,EAAE,YA+BxB,CAAC;AA6BF,wHAAwH;AACxH,wBAAgB,iBAAiB,IAAI,aAAa,CAEjD;AAKD,+FAA+F;AAC/F,wBAAgB,oBAAoB,IAAI,aAAa,CAGpD;AAED,sFAAsF;AACtF,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C"}
1
+ {"version":3,"file":"cloud-executor.d.ts","sourceRoot":"","sources":["../../../src/components/verbs/cloud-executor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAK1C,eAAO,MAAM,aAAa,2BAAkB,CAAC;AAI7C,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gGAAgG;IAChG,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,cAAc;IAC7B,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,4BAA4B;IAC5B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC7B,mEAAmE;IACnE,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,kFAAkF;IAClF,KAAK,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC1D,uDAAuD;IACvD,IAAI,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,4FAA4F;IAC5F,IAAI,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,yEAAyE;IACzE,GAAG,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,uFAAuF;IACvF,IAAI,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,mGAAmG;IACnG,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC9C;AAID,MAAM,WAAW,cAAc;IAC7B,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,8EAA8E;IAC9E,KAAK,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/E;AAID,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,kBAAkB,CAAC;CAC3B;AAcD,eAAO,MAAM,UAAU,EAAE,YAmCxB,CAAC;AA6BF,wHAAwH;AACxH,wBAAgB,iBAAiB,IAAI,aAAa,CAEjD;AAKD,+FAA+F;AAC/F,wBAAgB,oBAAoB,IAAI,aAAa,CAGpD;AAED,sFAAsF;AACtF,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C"}
@@ -68,6 +68,8 @@ export declare const waitEndpointCapability: Capability<WaitEndpointInput, WaitE
68
68
  export interface HealthGateInput {
69
69
  /** Health check path or full URL. */
70
70
  path: string;
71
+ /** Optional base URL (scheme + host) composed with `path` via `new URL(path, host)`. May be a cross-stack Wiring value; a bare host gets `http://` prepended. */
72
+ host?: string;
71
73
  /** Number of consecutive successes required. Default: 1. */
72
74
  consecutiveSuccesses?: number;
73
75
  /** Poll interval in ms. Default: 5000. */
@@ -1 +1 @@
1
- {"version":3,"file":"wait-verify.d.ts","sourceRoot":"","sources":["../../../src/components/verbs/wait-verify.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAA+B,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEnF,yGAAyG;AACzG,KAAK,OAAO,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAKzE,MAAM,WAAW,uBAAuB;IACtC;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uGAAuG;IACvG,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,wBAAwB;IACvC,0CAA0C;IAC1C,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;GAMG;AACH,wBAAgB,kCAAkC,CAChD,QAAQ,GAAE,aAAsC,GAC/C,UAAU,CAAC,uBAAuB,EAAE,wBAAwB,CAAC,CAoB/D;AAED,qFAAqF;AACrF,eAAO,MAAM,4BAA4B,EAAE,UAAU,CAAC,uBAAuB,EAAE,wBAAwB,CACjE,CAAC;AAIvC,MAAM,WAAW,iBAAiB;IAChC,mBAAmB;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,kDAAkD;IAClD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,0FAA0F;AAC1F,wBAAgB,4BAA4B,CAAC,OAAO,GAAE,OAAwB,GAAG,UAAU,CAAC,iBAAiB,EAAE,kBAAkB,CAAC,CAsBjI;AAED,wEAAwE;AACxE,eAAO,MAAM,sBAAsB,EAAE,UAAU,CAAC,iBAAiB,EAAE,kBAAkB,CAAkC,CAAC;AAIxH,MAAM,WAAW,eAAe;IAC9B,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,wEAAwE;IACxE,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,iHAAiH;AACjH,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,OAAwB,GAAG,UAAU,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAyB3H;AAED,sEAAsE;AACtE,eAAO,MAAM,oBAAoB,EAAE,UAAU,CAAC,eAAe,EAAE,gBAAgB,CAAgC,CAAC"}
1
+ {"version":3,"file":"wait-verify.d.ts","sourceRoot":"","sources":["../../../src/components/verbs/wait-verify.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAA+B,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEnF,yGAAyG;AACzG,KAAK,OAAO,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAKzE,MAAM,WAAW,uBAAuB;IACtC;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uGAAuG;IACvG,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iDAAiD;IACjD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,wBAAwB;IACvC,0CAA0C;IAC1C,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;GAMG;AACH,wBAAgB,kCAAkC,CAChD,QAAQ,GAAE,aAAsC,GAC/C,UAAU,CAAC,uBAAuB,EAAE,wBAAwB,CAAC,CAoB/D;AAED,qFAAqF;AACrF,eAAO,MAAM,4BAA4B,EAAE,UAAU,CAAC,uBAAuB,EAAE,wBAAwB,CACjE,CAAC;AAIvC,MAAM,WAAW,iBAAiB;IAChC,mBAAmB;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,kDAAkD;IAClD,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6BAA6B;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,uCAAuC;IACvC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,0FAA0F;AAC1F,wBAAgB,4BAA4B,CAAC,OAAO,GAAE,OAAwB,GAAG,UAAU,CAAC,iBAAiB,EAAE,kBAAkB,CAAC,CAsBjI;AAED,wEAAwE;AACxE,eAAO,MAAM,sBAAsB,EAAE,UAAU,CAAC,iBAAiB,EAAE,kBAAkB,CAAkC,CAAC;AAIxH,MAAM,WAAW,eAAe;IAC9B,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,iKAAiK;IACjK,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,wEAAwE;IACxE,OAAO,EAAE,OAAO,CAAC;CAClB;AASD,iHAAiH;AACjH,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,OAAwB,GAAG,UAAU,CAAC,eAAe,EAAE,gBAAgB,CAAC,CAyB3H;AAED,sEAAsE;AACtE,eAAO,MAAM,oBAAoB,EAAE,UAAU,CAAC,eAAe,EAAE,gBAAgB,CAAgC,CAAC"}
@@ -6,7 +6,8 @@
6
6
  * it via `nestedStack().outputs.name`.
7
7
  */
8
8
  import { DECLARABLE_MARKER, type Declarable } from "./declarable.js";
9
- import type { AttrRef } from "./attrref.js";
9
+ import { AttrRef } from "./attrref.js";
10
+ import { type Intrinsic } from "./intrinsic.js";
10
11
  /**
11
12
  * Marker symbol for stack output identification.
12
13
  */
@@ -21,7 +22,9 @@ export interface StackOutput extends Declarable {
21
22
  readonly lexicon: string;
22
23
  readonly entityType: string;
23
24
  readonly kind: "output";
24
- readonly sourceRef: AttrRef;
25
+ /** The exported value: a bare attribute reference, or an intrinsic wrapping
26
+ * one (e.g. `Join(",", zone.NameServers)`). */
27
+ readonly sourceRef: AttrRef | Intrinsic;
25
28
  readonly description?: string;
26
29
  }
27
30
  /**
@@ -46,7 +49,7 @@ export declare function isStackOutput(value: unknown): value is StackOutput;
46
49
  * });
47
50
  * ```
48
51
  */
49
- export declare function stackOutput(ref: AttrRef, options?: {
52
+ export declare function stackOutput(ref: AttrRef | Intrinsic, options?: {
50
53
  description?: string;
51
54
  }): StackOutput;
52
55
  //# sourceMappingURL=stack-output.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stack-output.d.ts","sourceRoot":"","sources":["../src/stack-output.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzC;;GAEG;AACH,eAAO,MAAM,mBAAmB,eAAkC,CAAC;AAEnE;;;GAGG;AACH,MAAM,WAAW,WAAY,SAAQ,UAAU;IAC7C,QAAQ,CAAC,CAAC,mBAAmB,CAAC,EAAE,IAAI,CAAC;IACrC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,EAAE,IAAI,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,WAAW,CAOlE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,OAAO,EACZ,OAAO,CAAC,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GACjC,WAAW,CAkBb"}
1
+ {"version":3,"file":"stack-output.d.ts","sourceRoot":"","sources":["../src/stack-output.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,aAAa,CAAC;AAE1D;;GAEG;AACH,eAAO,MAAM,mBAAmB,eAAkC,CAAC;AAEnE;;;GAGG;AACH,MAAM,WAAW,WAAY,SAAQ,UAAU;IAC7C,QAAQ,CAAC,CAAC,mBAAmB,CAAC,EAAE,IAAI,CAAC;IACrC,QAAQ,CAAC,CAAC,iBAAiB,CAAC,EAAE,IAAI,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB;mDAC+C;IAC/C,QAAQ,CAAC,SAAS,EAAE,OAAO,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAgBD;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,WAAW,CAOlE;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,OAAO,GAAG,SAAS,EACxB,OAAO,CAAC,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GACjC,WAAW,CAuBb"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentius/chant",
3
- "version": "0.18.15",
3
+ "version": "0.18.17",
4
4
  "description": "Declarative infrastructure-as-code toolkit — TypeScript on Node.js",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://intentius.io/chant",
@@ -19,6 +19,7 @@
19
19
  import { exec } from "node:child_process";
20
20
  import { createConnection } from "node:net";
21
21
  import { promisify } from "node:util";
22
+ import { isAbsolute, join } from "node:path";
22
23
 
23
24
  export const execFileAsync = promisify(exec);
24
25
 
@@ -104,7 +105,11 @@ function q(value: string): string {
104
105
  export const realDocker: DockerClient = {
105
106
  async build(args) {
106
107
  const parts = [`docker build`, `-t ${q(args.tag)}`];
107
- if (args.dockerfile) parts.push(`-f ${q(args.dockerfile)}`);
108
+ if (args.dockerfile) {
109
+ // dockerfile is relative to `context` (its documented contract); docker's `-f` resolves a relative path against cwd, not the context dir, so join them here (chant#936).
110
+ const dockerfilePath = isAbsolute(args.dockerfile) ? args.dockerfile : join(args.context, args.dockerfile);
111
+ parts.push(`-f ${q(dockerfilePath)}`);
112
+ }
108
113
  if (args.target) parts.push(`--target ${q(args.target)}`);
109
114
  for (const [k, v] of Object.entries(args.buildArgs ?? {})) parts.push(`--build-arg ${q(`${k}=${v}`)}`);
110
115
  parts.push(q(args.context));
@@ -128,6 +128,8 @@ export const waitEndpointCapability: Capability<WaitEndpointInput, WaitEndpointO
128
128
  export interface HealthGateInput {
129
129
  /** Health check path or full URL. */
130
130
  path: string;
131
+ /** Optional base URL (scheme + host) composed with `path` via `new URL(path, host)`. May be a cross-stack Wiring value; a bare host gets `http://` prepended. */
132
+ host?: string;
131
133
  /** Number of consecutive successes required. Default: 1. */
132
134
  consecutiveSuccesses?: number;
133
135
  /** Poll interval in ms. Default: 5000. */
@@ -139,6 +141,13 @@ export interface HealthGateOutput {
139
141
  healthy: boolean;
140
142
  }
141
143
 
144
+ /** Compose the fetchable URL: `host` set → resolve `path` against it (bare host → `http://` prepended); else `path` as-is. */
145
+ function healthGateUrl(input: HealthGateInput): string {
146
+ if (!input.host) return input.path;
147
+ const base = /^https?:\/\//.test(input.host) ? input.host : `http://${input.host}`;
148
+ return new URL(input.path, base).toString();
149
+ }
150
+
142
151
  /** Block progression until a health check passes — the generic post-deploy verification gate. Cloud-agnostic. */
143
152
  export function createHealthGateCapability(fetcher: Fetcher = defaultFetcher): Capability<HealthGateInput, HealthGateOutput> {
144
153
  return {
@@ -152,14 +161,14 @@ export function createHealthGateCapability(fetcher: Fetcher = defaultFetcher): C
152
161
  for (;;) {
153
162
  let ok = false;
154
163
  try {
155
- ok = (await fetcher(input.path)).ok;
164
+ ok = (await fetcher(healthGateUrl(input))).ok;
156
165
  } catch {
157
166
  ok = false;
158
167
  }
159
168
  streak = ok ? streak + 1 : 0;
160
169
  if (streak >= need) return { healthy: true };
161
170
  if (Date.now() >= deadline) {
162
- throw new Error(`health-gate: ${input.path} did not reach ${need} consecutive healthy check(s) within 300000ms`);
171
+ throw new Error(`health-gate: ${healthGateUrl(input)} did not reach ${need} consecutive healthy check(s) within 300000ms`);
163
172
  }
164
173
  await sleep(intervalMs);
165
174
  }
@@ -7,7 +7,8 @@
7
7
  */
8
8
 
9
9
  import { DECLARABLE_MARKER, type Declarable } from "./declarable";
10
- import type { AttrRef } from "./attrref";
10
+ import { AttrRef } from "./attrref";
11
+ import { isIntrinsic, type Intrinsic } from "./intrinsic";
11
12
 
12
13
  /**
13
14
  * Marker symbol for stack output identification.
@@ -24,10 +25,26 @@ export interface StackOutput extends Declarable {
24
25
  readonly lexicon: string;
25
26
  readonly entityType: string;
26
27
  readonly kind: "output";
27
- readonly sourceRef: AttrRef;
28
+ /** The exported value: a bare attribute reference, or an intrinsic wrapping
29
+ * one (e.g. `Join(",", zone.NameServers)`). */
30
+ readonly sourceRef: AttrRef | Intrinsic;
28
31
  readonly description?: string;
29
32
  }
30
33
 
34
+ /** Find the first AttrRef anywhere inside a value (walking intrinsics/objects/
35
+ * arrays), so a wrapping intrinsic can still borrow its parent's lexicon. */
36
+ function firstAttrRef(value: unknown, seen = new Set<unknown>()): AttrRef | undefined {
37
+ if (value === null || typeof value !== "object" || seen.has(value)) return undefined;
38
+ if (value instanceof AttrRef) return value;
39
+ seen.add(value);
40
+ const children = Array.isArray(value) ? value : Object.values(value as Record<string, unknown>);
41
+ for (const child of children) {
42
+ const found = firstAttrRef(child, seen);
43
+ if (found) return found;
44
+ }
45
+ return undefined;
46
+ }
47
+
31
48
  /**
32
49
  * Type guard for StackOutput.
33
50
  */
@@ -59,11 +76,16 @@ export function isStackOutput(value: unknown): value is StackOutput {
59
76
  * ```
60
77
  */
61
78
  export function stackOutput(
62
- ref: AttrRef,
79
+ ref: AttrRef | Intrinsic,
63
80
  options?: { description?: string },
64
81
  ): StackOutput {
65
- // Derive lexicon from the AttrRef's parent entity
66
- const parent = ref.parent.deref();
82
+ if (!(ref instanceof AttrRef) && !isIntrinsic(ref)) {
83
+ throw new Error("stackOutput(ref): ref must be an attribute reference or an intrinsic wrapping one");
84
+ }
85
+ // Derive lexicon from the referenced entity — for a bare AttrRef, its parent;
86
+ // for an intrinsic (Join etc.), the first AttrRef nested inside it.
87
+ const anchor = ref instanceof AttrRef ? ref : firstAttrRef(ref);
88
+ const parent = anchor?.parent.deref();
67
89
  const lexicon = parent && typeof (parent as Record<string, unknown>).lexicon === "string"
68
90
  ? (parent as Record<string, unknown>).lexicon as string
69
91
  : "unknown";