@fjall/util 4.1.0 → 4.3.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/.minified CHANGED
@@ -1 +1 @@
1
- 92 files minified at 2026-07-24T23:00:42.861Z
1
+ 92 files minified at 2026-07-27T09:34:35.409Z
@@ -6,5 +6,5 @@
6
6
  * pure CDK synth path) MUST import directly from `./schemas` instead of
7
7
  * the barrel — the package.json `exports` map exposes both subpaths.
8
8
  */
9
- export { DockerBuildSchema, DockerBuildArgValueSchema, DockerBuildSecretRefSchema, DockerBuildPartialSchema, mergeDockerBuild, ManifestServiceSchema, ManifestPatternSchema, ManifestEcrSchema, ManifestLambdaSchema, ManifestStackHashSchema, ResourceMapEntrySchema, FjallManifestSchema, FJALL_MANIFEST_FILENAME, MANIFEST_SCHEMA_VERSION, BUILDKIT_SECRET_ID_PATTERN, type DockerBuild, type DockerBuildArgValue, type DockerBuildSecretRef, type DockerBuildPartial, type ManifestService, type ManifestPattern, type ManifestEcr, type ManifestLambda, type ManifestStackHash, type ResourceMapEntry, type FjallManifest } from "./schemas.js";
10
- export { getManifestFilePath, readManifestFile, writeManifestFile, createEmptyManifest, readConstructMap, parseDockerServicesFromManifest, parseLambdaDockerServicesFromManifest, parseLambdaDockerEntriesFromManifest, parseDockerDeclarationsFromManifest, type ManifestDockerService, type ManifestLambdaDockerEntry, type ManifestDockerDeclarations } from "./io.js";
9
+ export { DockerBuildSchema, DockerBuildArgValueSchema, DockerBuildSecretRefSchema, DockerBuildPartialSchema, mergeDockerBuild, ManifestServiceSchema, ManifestPatternSchema, ManifestEcrSchema, ManifestLambdaSchema, ManifestStackHashSchema, ResourceMapEntrySchema, FjallManifestSchema, EngineCompatSchema, FJALL_MANIFEST_FILENAME, MANIFEST_SCHEMA_VERSION, MAX_SUPPORTED_MANIFEST_SCHEMA_VERSION, BUILDKIT_SECRET_ID_PATTERN, type DockerBuild, type DockerBuildArgValue, type DockerBuildSecretRef, type DockerBuildPartial, type ManifestService, type ManifestPattern, type ManifestEcr, type ManifestLambda, type ManifestStackHash, type ResourceMapEntry, type FjallManifest, type EngineCompat } from "./schemas.js";
10
+ export { getManifestFilePath, readManifestFile, writeManifestFile, createEmptyManifest, readConstructMap, parseDockerServicesFromManifest, parseLambdaDockerServicesFromManifest, parseLambdaDockerEntriesFromManifest, parseDockerDeclarationsFromManifest, readEngineCompatEnvelope, type ManifestDockerService, type ManifestLambdaDockerEntry, type ManifestDockerDeclarations, type EngineCompatEnvelope } from "./io.js";
@@ -1 +1 @@
1
- import{DockerBuildSchema as r,DockerBuildArgValueSchema as t,DockerBuildSecretRefSchema as c,DockerBuildPartialSchema as i,mergeDockerBuild as s,ManifestServiceSchema as m,ManifestPatternSchema as S,ManifestEcrSchema as o,ManifestLambdaSchema as M,ManifestStackHashSchema as n,ResourceMapEntrySchema as f,FjallManifestSchema as h,FJALL_MANIFEST_FILENAME as l,MANIFEST_SCHEMA_VERSION as E,BUILDKIT_SECRET_ID_PATTERN as D}from"./schemas.js";import{getManifestFilePath as d,readManifestFile as k,writeManifestFile as p,createEmptyManifest as u,readConstructMap as A,parseDockerServicesFromManifest as I,parseLambdaDockerServicesFromManifest as L,parseLambdaDockerEntriesFromManifest as _,parseDockerDeclarationsFromManifest as B}from"./io.js";export{D as BUILDKIT_SECRET_ID_PATTERN,t as DockerBuildArgValueSchema,i as DockerBuildPartialSchema,r as DockerBuildSchema,c as DockerBuildSecretRefSchema,l as FJALL_MANIFEST_FILENAME,h as FjallManifestSchema,E as MANIFEST_SCHEMA_VERSION,o as ManifestEcrSchema,M as ManifestLambdaSchema,S as ManifestPatternSchema,m as ManifestServiceSchema,n as ManifestStackHashSchema,f as ResourceMapEntrySchema,u as createEmptyManifest,d as getManifestFilePath,s as mergeDockerBuild,B as parseDockerDeclarationsFromManifest,I as parseDockerServicesFromManifest,_ as parseLambdaDockerEntriesFromManifest,L as parseLambdaDockerServicesFromManifest,A as readConstructMap,k as readManifestFile,p as writeManifestFile};
1
+ import{DockerBuildSchema as r,DockerBuildArgValueSchema as t,DockerBuildSecretRefSchema as c,DockerBuildPartialSchema as i,mergeDockerBuild as S,ManifestServiceSchema as m,ManifestPatternSchema as s,ManifestEcrSchema as n,ManifestLambdaSchema as o,ManifestStackHashSchema as M,ResourceMapEntrySchema as E,FjallManifestSchema as f,EngineCompatSchema as h,FJALL_MANIFEST_FILENAME as l,MANIFEST_SCHEMA_VERSION as D,MAX_SUPPORTED_MANIFEST_SCHEMA_VERSION as F,BUILDKIT_SECRET_ID_PATTERN as p}from"./schemas.js";import{getManifestFilePath as _,readManifestFile as k,writeManifestFile as A,createEmptyManifest as I,readConstructMap as u,parseDockerServicesFromManifest as T,parseLambdaDockerServicesFromManifest as L,parseLambdaDockerEntriesFromManifest as N,parseDockerDeclarationsFromManifest as R,readEngineCompatEnvelope as B}from"./io.js";export{p as BUILDKIT_SECRET_ID_PATTERN,t as DockerBuildArgValueSchema,i as DockerBuildPartialSchema,r as DockerBuildSchema,c as DockerBuildSecretRefSchema,h as EngineCompatSchema,l as FJALL_MANIFEST_FILENAME,f as FjallManifestSchema,D as MANIFEST_SCHEMA_VERSION,F as MAX_SUPPORTED_MANIFEST_SCHEMA_VERSION,n as ManifestEcrSchema,o as ManifestLambdaSchema,s as ManifestPatternSchema,m as ManifestServiceSchema,M as ManifestStackHashSchema,E as ResourceMapEntrySchema,I as createEmptyManifest,_ as getManifestFilePath,S as mergeDockerBuild,R as parseDockerDeclarationsFromManifest,T as parseDockerServicesFromManifest,N as parseLambdaDockerEntriesFromManifest,L as parseLambdaDockerServicesFromManifest,u as readConstructMap,B as readEngineCompatEnvelope,k as readManifestFile,A as writeManifestFile};
@@ -6,7 +6,7 @@
6
6
  * that need the docker-shape types without I/O (e.g. the generator) MUST
7
7
  * import from `./schemas` directly.
8
8
  */
9
- import { type DockerBuild, type FjallManifest, type LambdaArchitecture, type ResourceMapEntry } from "./schemas.js";
9
+ import { type DockerBuild, type EngineCompat, type FjallManifest, type LambdaArchitecture, type ResourceMapEntry } from "./schemas.js";
10
10
  /**
11
11
  * Get the manifest file path for a cdk.out directory.
12
12
  */
@@ -58,6 +58,47 @@ export interface ManifestDockerService {
58
58
  */
59
59
  readonly architecture?: LambdaArchitecture;
60
60
  }
61
+ /**
62
+ * The engine-compatibility envelope, hand-walked from the manifest rather than
63
+ * strict-parsed. The deploy-time chokepoint (`assertEngineCompatibleWithAssembly`
64
+ * in deploy-core) needs to distinguish three states a strict `FjallManifest`
65
+ * parse cannot express: manifest absent/malformed, manifest present with no
66
+ * constraint, and constraint present. It must also TOLERATE a same-major
67
+ * assembly carrying additive `engineCompat` sub-fields this build predates —
68
+ * `EngineCompatSchema` is `.strict()` (the write contract), so a full strict
69
+ * parse would reject such a manifest outright and turn a forward-compatible
70
+ * deploy into a hard refusal. Hand-walking reads only the fields this build
71
+ * understands and ignores the rest; breaking constraints always travel via
72
+ * `minimumEngineVersion`, which every reader understands.
73
+ */
74
+ export interface EngineCompatEnvelope {
75
+ /** The manifest's top-level `version`, or undefined if absent/non-numeric. */
76
+ readonly manifestVersion: number | undefined;
77
+ /**
78
+ * True when the manifest carries an `engineCompat` object — even a malformed
79
+ * one. Lets the verdict layer separate "present-but-malformed" (a contract
80
+ * violation to refuse) from genuinely absent (no constraint → proceed).
81
+ */
82
+ readonly engineCompatPresent: boolean;
83
+ /**
84
+ * The extracted constraint, or undefined when `engineCompat` is absent OR
85
+ * malformed (missing/empty `minimumEngineVersion` — the primary gate input,
86
+ * without which the constraint cannot be honoured).
87
+ */
88
+ readonly engineCompat: EngineCompat | undefined;
89
+ }
90
+ /**
91
+ * Read the engine-compatibility envelope from a cdk.out directory. Never
92
+ * throws: a missing/unreadable/non-JSON manifest yields an empty envelope
93
+ * (`manifestVersion: undefined, engineCompatPresent: false`), which the verdict
94
+ * layer classifies as "no constraint → proceed" — matching today's behaviour,
95
+ * where a manifest that can't be read simply produces no build declarations.
96
+ *
97
+ * Reads synchronously to match the deploy-core chokepoint's synchronous
98
+ * orchestration context; the file is small and sealed by CDK synth ahead of
99
+ * the deploy phase.
100
+ */
101
+ export declare function readEngineCompatEnvelope(cdkOutPath: string): EngineCompatEnvelope;
61
102
  /**
62
103
  * Extract services with a Docker build configuration from the Fjall manifest.
63
104
  *
@@ -1 +1 @@
1
- var y=Object.defineProperty;var i=(t,r)=>y(t,"name",{value:r,configurable:!0});import{readFile as M,writeFile as b,unlink as F,rename as k,mkdir as S}from"fs/promises";import{readFileSync as A}from"fs";import{dirname as w,join as u}from"path";import{logger as c}from"../logger.js";import{maskSensitiveOutput as E}from"../securityHelpers.js";import{fileExists as v}from"../fsHelpers.js";import{getErrorMessage as d}from"../errorUtils.js";import{recordToConstructMap as x}from"../constructMap.js";import{FjallManifestSchema as L,FJALL_MANIFEST_FILENAME as m,MANIFEST_SCHEMA_VERSION as D,normaliseDockerBuild as l,LAMBDA_ARCHITECTURE_VALUES as j}from"./schemas.js";function p(t){return u(t,m)}i(p,"getManifestFilePath");async function N(t){const r=p(t);if(!await v(r))return null;try{const n=await M(r,"utf-8"),e=JSON.parse(n),a=L.safeParse(e);return a.success||c.debug("FjallManifest","Manifest validation failed",{path:r,errors:a.error.issues.map(o=>`${o.path.join(".")}: ${o.message}`)}),a.success?a.data:null}catch(n){return c.debug("FjallManifest","Failed to read manifest file",{path:r,error:d(n)}),null}}i(N,"readManifestFile");async function H(t,r){const n=p(t),e=`${n}.${Date.now()}.tmp`;await S(w(n),{recursive:!0});try{await b(e,JSON.stringify(r,null,2),"utf-8"),await k(e,n)}catch(a){try{await F(e)}catch(o){c.debug("FjallManifest","Temp file cleanup failed (non-fatal)",{path:e,error:d(o)})}throw a}}i(H,"writeManifestFile");function U(t){return{version:D,generatedAt:new Date().toISOString(),appName:t,services:[],lambdas:[],stacks:{}}}i(U,"createEmptyManifest");async function V(t){const r=await N(t);return r?.resourceMap?x(r.resourceMap):new Map}i(V,"readConstructMap");function f(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}i(f,"isRecord");function g(t,r){const n=u(t,m);let e;try{e=A(n,"utf-8")}catch{c.debug("FjallManifest",`Manifest file not readable \u2014 no ${r} extracted`,{path:n});return}let a;try{a=JSON.parse(e)}catch{c.debug("FjallManifest",`Manifest is not valid JSON \u2014 no ${r} extracted`,{path:n});return}return f(a)?a:void 0}i(g,"readManifestRecord");function I(t){const r=g(t,"Docker services");if(r===void 0||!Array.isArray(r.services))return[];const n=[];for(const e of r.services){if(!f(e)||typeof e.name!="string")continue;const a=l(e.docker);a!==void 0&&n.push({name:e.name,docker:a,isLambda:!1})}return n}i(I,"parseDockerServicesFromManifest");function q(t){const r=new Map;for(const{name:n,imageKey:e,docker:a,architecture:o}of h(t)){const s=r.get(e);if(s===void 0){r.set(e,{name:e,docker:a,isLambda:!0,...o!==void 0&&{architecture:o}});continue}if(JSON.stringify(s.docker)!==JSON.stringify(a)||s.architecture!==o)throw new Error(`Lambda functions sharing image key "${e}" declare different \`docker\` configs or \`architecture\` \u2014 every Lambda function sharing an \`image\` must build from the identical Dockerfile/context/target/buildArgs and target the same architecture (offending function: "${n}").`)}return Array.from(r.values())}i(q,"parseLambdaDockerServicesFromManifest");function h(t){const r=g(t,"Lambda Docker entries");if(r===void 0||!Array.isArray(r.lambdas))return[];const n=[];for(const e of r.lambdas){if(!f(e)||typeof e.name!="string")continue;const a=l(e.docker);if(a===void 0)continue;const o=typeof e.imageKey=="string"&&e.imageKey.length>0?e.imageKey:e.name;let s;typeof e.architecture=="string"&&(j.includes(e.architecture)?s=e.architecture:c.debug("FjallManifest","Ignoring unrecognised Lambda architecture \u2014 build falls back to the default platform",{lambda:e.name,architecture:E(e.architecture)})),n.push({name:e.name,imageKey:o,docker:a,...s!==void 0&&{architecture:s}})}return n}i(h,"parseLambdaDockerEntriesFromManifest");function z(t){const r=I(t),n=h(t);return{ecsServices:r,lambdaEntries:n,declaresBuild:r.length>0||n.length>0}}i(z,"parseDockerDeclarationsFromManifest");export{U as createEmptyManifest,p as getManifestFilePath,z as parseDockerDeclarationsFromManifest,I as parseDockerServicesFromManifest,h as parseLambdaDockerEntriesFromManifest,q as parseLambdaDockerServicesFromManifest,V as readConstructMap,N as readManifestFile,H as writeManifestFile};
1
+ var h=Object.defineProperty;var a=(t,e)=>h(t,"name",{value:e,configurable:!0});import{readFile as M,writeFile as b,unlink as E,rename as k,mkdir as A}from"fs/promises";import{readFileSync as F}from"fs";import{dirname as w,join as m}from"path";import{logger as c}from"../logger.js";import{maskSensitiveOutput as C}from"../securityHelpers.js";import{fileExists as x}from"../fsHelpers.js";import{getErrorMessage as d}from"../errorUtils.js";import{recordToConstructMap as S}from"../constructMap.js";import{FjallManifestSchema as v,FJALL_MANIFEST_FILENAME as l,MANIFEST_SCHEMA_VERSION as j,normaliseDockerBuild as p,LAMBDA_ARCHITECTURE_VALUES as L}from"./schemas.js";function g(t){return m(t,l)}a(g,"getManifestFilePath");async function D(t){const e=g(t);if(!await x(e))return null;try{const r=await M(e,"utf-8"),n=JSON.parse(r),i=v.safeParse(n);return i.success||c.debug("FjallManifest","Manifest validation failed",{path:e,errors:i.error.issues.map(s=>`${s.path.join(".")}: ${s.message}`)}),i.success?i.data:null}catch(r){return c.debug("FjallManifest","Failed to read manifest file",{path:e,error:d(r)}),null}}a(D,"readManifestFile");async function H(t,e){const r=g(t),n=`${r}.${Date.now()}.tmp`;await A(w(r),{recursive:!0});try{await b(n,JSON.stringify(e,null,2),"utf-8"),await k(n,r)}catch(i){try{await E(n)}catch(s){c.debug("FjallManifest","Temp file cleanup failed (non-fatal)",{path:n,error:d(s)})}throw i}}a(H,"writeManifestFile");function U(t){return{version:j,generatedAt:new Date().toISOString(),appName:t,services:[],lambdas:[],stacks:{}}}a(U,"createEmptyManifest");async function q(t){const e=await D(t);return e?.resourceMap?S(e.resourceMap):new Map}a(q,"readConstructMap");function f(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}a(f,"isRecord");function u(t,e){const r=m(t,l);let n;try{n=F(r,"utf-8")}catch{c.debug("FjallManifest",`Manifest file not readable \u2014 no ${e} extracted`,{path:r});return}let i;try{i=JSON.parse(n)}catch{c.debug("FjallManifest",`Manifest is not valid JSON \u2014 no ${e} extracted`,{path:r});return}return f(i)?i:void 0}a(u,"readManifestRecord");function N(t){const e=t.engineCompat;if(!f(e))return;const r=e.minimumEngineVersion;if(typeof r!="string"||r.length===0)return;const n=typeof e.synthesisedBy=="string"&&e.synthesisedBy.length>0?e.synthesisedBy:"",i=typeof e.maximumEngineMajor=="number"&&Number.isInteger(e.maximumEngineMajor)&&e.maximumEngineMajor>=0?e.maximumEngineMajor:void 0,s=typeof e.minimumAwsCdkCli=="string"&&e.minimumAwsCdkCli.length>0?e.minimumAwsCdkCli:void 0;return{synthesisedBy:n,minimumEngineVersion:r,...i!==void 0&&{maximumEngineMajor:i},...s!==void 0&&{minimumAwsCdkCli:s}}}a(N,"extractEngineCompat");function z(t){const e=u(t,"engine compatibility");if(e===void 0)return{manifestVersion:void 0,engineCompatPresent:!1,engineCompat:void 0};const r=typeof e.version=="number"?e.version:void 0,n=f(e.engineCompat),i=N(e);return{manifestVersion:r,engineCompatPresent:n,engineCompat:i}}a(z,"readEngineCompatEnvelope");function I(t){const e=u(t,"Docker services");if(e===void 0||!Array.isArray(e.services))return[];const r=[];for(const n of e.services){if(!f(n)||typeof n.name!="string")continue;const i=p(n.docker);i!==void 0&&r.push({name:n.name,docker:i,isLambda:!1})}return r}a(I,"parseDockerServicesFromManifest");function G(t){const e=new Map;for(const{name:r,imageKey:n,docker:i,architecture:s}of y(t)){const o=e.get(n);if(o===void 0){e.set(n,{name:n,docker:i,isLambda:!0,...s!==void 0&&{architecture:s}});continue}if(JSON.stringify(o.docker)!==JSON.stringify(i)||o.architecture!==s)throw new Error(`Lambda functions sharing image key "${n}" declare different \`docker\` configs or \`architecture\` \u2014 every Lambda function sharing an \`image\` must build from the identical Dockerfile/context/target/buildArgs and target the same architecture (offending function: "${r}").`)}return Array.from(e.values())}a(G,"parseLambdaDockerServicesFromManifest");function y(t){const e=u(t,"Lambda Docker entries");if(e===void 0||!Array.isArray(e.lambdas))return[];const r=[];for(const n of e.lambdas){if(!f(n)||typeof n.name!="string")continue;const i=p(n.docker);if(i===void 0)continue;const s=typeof n.imageKey=="string"&&n.imageKey.length>0?n.imageKey:n.name;let o;typeof n.architecture=="string"&&(L.includes(n.architecture)?o=n.architecture:c.debug("FjallManifest","Ignoring unrecognised Lambda architecture \u2014 build falls back to the default platform",{lambda:n.name,architecture:C(n.architecture)})),r.push({name:n.name,imageKey:s,docker:i,...o!==void 0&&{architecture:o}})}return r}a(y,"parseLambdaDockerEntriesFromManifest");function Q(t){const e=I(t),r=y(t);return{ecsServices:e,lambdaEntries:r,declaresBuild:e.length>0||r.length>0}}a(Q,"parseDockerDeclarationsFromManifest");export{U as createEmptyManifest,g as getManifestFilePath,Q as parseDockerDeclarationsFromManifest,I as parseDockerServicesFromManifest,y as parseLambdaDockerEntriesFromManifest,G as parseLambdaDockerServicesFromManifest,q as readConstructMap,z as readEngineCompatEnvelope,D as readManifestFile,H as writeManifestFile};
@@ -22,6 +22,17 @@ import { z } from "zod";
22
22
  export declare const FJALL_MANIFEST_FILENAME = "fjall-manifest.json";
23
23
  /** Current manifest schema version. */
24
24
  export declare const MANIFEST_SCHEMA_VERSION: 1;
25
+ /**
26
+ * Highest manifest `version` this build knows how to consume. Distinct from
27
+ * {@link MANIFEST_SCHEMA_VERSION} (the version this build *emits*): the two
28
+ * coincide today, but the read ceiling is what the deploy-time compatibility
29
+ * chokepoint (`assertEngineCompatibleWithAssembly`) compares an assembly's
30
+ * `version` against to loudly refuse a structurally-newer manifest rather than
31
+ * silently drop unknown top-level sections. Bump this only when a build learns
32
+ * to read a newer structural schema. The `engineCompat` field added alongside
33
+ * this constant is additive-optional, so it does NOT bump either version.
34
+ */
35
+ export declare const MAX_SUPPORTED_MANIFEST_SCHEMA_VERSION: 1;
25
36
  /**
26
37
  * Allowed character set for a BuildKit secret id. Deliberately conservative —
27
38
  * NO comma, equals, or whitespace, all of which would break the
@@ -316,6 +327,40 @@ declare const ResourceMapEntrySchema: z.ZodObject<{
316
327
  resourceType: z.ZodString;
317
328
  }, z.core.$strict>;
318
329
  export type ResourceMapEntry = z.infer<typeof ResourceMapEntrySchema>;
330
+ /**
331
+ * Engine ↔ assembly compatibility contract, stamped into the manifest at synth
332
+ * by `@fjall/components-infrastructure` (the emitter is the constructs, so the
333
+ * declaration is self-honest — whatever synthesised the assembly is what
334
+ * records the engine floor it needs). The deploy-time chokepoint
335
+ * `assertEngineCompatibleWithAssembly` (deploy-core) reads this and refuses to
336
+ * build/push/deploy an assembly the running engine is too old — or structurally
337
+ * too new — to honour.
338
+ *
339
+ * This is the WRITE contract: `.strict()`, so the emitter cannot silently add a
340
+ * field readers were never told about. The deploy-time READ path deliberately
341
+ * hand-walks this shape instead (`readEngineCompatEnvelope` in ./io.ts) so a
342
+ * same-major engine tolerates an assembly carrying additive sub-fields it does
343
+ * not yet understand — breaking constraints always travel via
344
+ * `minimumEngineVersion`, which every reader since Phase 0 understands.
345
+ *
346
+ * - `synthesisedBy` — the `@fjall/components-infrastructure` version that
347
+ * stamped the assembly (audit/diagnostics; never a gate input).
348
+ * - `minimumEngineVersion` — the lowest engine (deploy-core) semver that can
349
+ * safely deploy this assembly. Under Lerna FIXED lockstep this derives as
350
+ * `${constructsMajor}.0.0`; it is the primary refuse-if-below gate.
351
+ * - `maximumEngineMajor` — optional upper bound; an engine whose major exceeds
352
+ * this is warned (engine-ahead), never refused, unless a future emitter needs
353
+ * a hard ceiling.
354
+ * - `minimumAwsCdkCli` — optional floor for the bundled aws-cdk CLI, guarding
355
+ * the cross-tree cloud-assembly schema-skew failure mode (FM1).
356
+ */
357
+ declare const EngineCompatSchema: z.ZodObject<{
358
+ synthesisedBy: z.ZodString;
359
+ minimumEngineVersion: z.ZodString;
360
+ maximumEngineMajor: z.ZodOptional<z.ZodNumber>;
361
+ minimumAwsCdkCli: z.ZodOptional<z.ZodString>;
362
+ }, z.core.$strict>;
363
+ export type EngineCompat = z.infer<typeof EngineCompatSchema>;
319
364
  /**
320
365
  * Fjall manifest schema — generated during CDK synth.
321
366
  * Location: `<cdk.out>/fjall-manifest.json`.
@@ -414,6 +459,12 @@ export declare const FjallManifestSchema: z.ZodObject<{
414
459
  group: z.ZodString;
415
460
  resourceType: z.ZodString;
416
461
  }, z.core.$strict>>>;
462
+ engineCompat: z.ZodOptional<z.ZodObject<{
463
+ synthesisedBy: z.ZodString;
464
+ minimumEngineVersion: z.ZodString;
465
+ maximumEngineMajor: z.ZodOptional<z.ZodNumber>;
466
+ minimumAwsCdkCli: z.ZodOptional<z.ZodString>;
467
+ }, z.core.$strict>>;
417
468
  }, z.core.$strict>;
418
469
  export type FjallManifest = z.infer<typeof FjallManifestSchema>;
419
- export { ManifestServiceSchema, ManifestPatternSchema, ManifestEcrSchema, ManifestLambdaSchema, ManifestStackHashSchema, ResourceMapEntrySchema };
470
+ export { ManifestServiceSchema, ManifestPatternSchema, ManifestEcrSchema, ManifestLambdaSchema, ManifestStackHashSchema, ResourceMapEntrySchema, EngineCompatSchema };
@@ -1 +1 @@
1
- var y=Object.defineProperty;var i=(t,n)=>y(t,"name",{value:n,configurable:!0});import{z as e}from"zod";import{PATTERN_TYPE_VALUES as S}from"../patterns/patternTypes.js";const I="fjall-manifest.json",h=1,x=/^[A-Za-z0-9_.-]+$/,A=e.object({id:e.string().min(1,"buildSecret id cannot be empty").regex(x,"buildSecret id may contain only letters, digits, '_', '.', and '-' (no comma, '=', or whitespace, which would break the buildx --secret argv)"),ssm:e.string().min(1,"ssm parameter name cannot be empty").optional(),secretsManager:e.object({name:e.string().min(1,"secret name cannot be empty").optional(),arn:e.string().min(1,"secret arn cannot be empty").optional(),field:e.string().min(1,"secret field cannot be empty").optional()}).strict().refine(t=>t.name===void 0!=(t.arn===void 0),"secretsManager requires exactly one of name or arn").optional(),env:e.string().min(1,"env variable name cannot be empty").optional()}).strict().superRefine((t,n)=>{[t.ssm,t.secretsManager,t.env].filter(r=>r!==void 0).length!==1&&n.addIssue({code:e.ZodIssueCode.custom,message:"buildSecret requires exactly one source (ssm, secretsManager, or env)"})}),M=e.union([e.string(),e.object({ssm:e.string().min(1,"ssm parameter name cannot be empty").optional(),secretsManager:e.object({name:e.string().min(1,"secret name cannot be empty").optional(),arn:e.string().min(1,"secret arn cannot be empty").optional(),field:e.string().min(1,"secret field cannot be empty").optional()}).strict().refine(t=>t.name===void 0!=(t.arn===void 0),"secretsManager requires exactly one of name or arn").optional(),env:e.string().min(1,"env variable name cannot be empty").optional(),acknowledgePublic:e.boolean().optional()}).strict().superRefine((t,n)=>{[t.ssm,t.secretsManager,t.env].filter(r=>r!==void 0).length!==1&&n.addIssue({code:e.ZodIssueCode.custom,message:"buildArg value requires exactly one source (ssm, secretsManager, or env)"})})]),c=e.object({path:e.string(),context:e.string().min(1,"context cannot be empty").optional(),target:e.string().min(1,"target cannot be empty").optional(),buildArgs:e.record(e.string(),M).optional(),buildSecrets:e.array(A).optional()}).strict(),N=c.partial();function B(t,n){if(n===void 0)return t;const o=n.context??t.context,r=n.target??t.target,s=n.buildArgs??t.buildArgs,a=n.buildSecrets??t.buildSecrets;return{path:n.path??t.path,...o!==void 0&&{context:o},...r!==void 0&&{target:r},...s!==void 0&&{buildArgs:s},...a!==void 0&&{buildSecrets:a}}}i(B,"mergeDockerBuild");function m(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}i(m,"isRecord");function j(t){if(!m(t)||typeof t.path!="string"||t.path.length===0)return;const n=typeof t.context=="string"&&t.context.length>0?t.context:void 0,o=typeof t.target=="string"&&t.target.length>0?t.target:void 0,r=m(t.buildArgs)&&Object.keys(t.buildArgs).length>0?t.buildArgs:void 0,s=Array.isArray(t.buildSecrets)&&t.buildSecrets.length>0?t.buildSecrets:void 0,a={path:t.path,...n!==void 0&&{context:n},...o!==void 0&&{target:o},...r!==void 0&&{buildArgs:r},...s!==void 0&&{buildSecrets:s}},d=c.safeParse(a);return d.success?d.data:void 0}i(j,"normaliseDockerBuild");function P(t){if(t===void 0)return;const n=j(t);return n===void 0?void 0:JSON.stringify(n)}i(P,"dockerBuildFingerprint");const p=e.object({name:e.string(),clusterName:e.string().optional(),docker:c.optional(),containerPort:e.number().optional(),secrets:e.array(e.string()).optional(),ssmSecretsPath:e.string().optional(),importedSecretNames:e.array(e.string()).optional()}).strict(),g=e.object({type:e.enum(S),name:e.string(),source:e.string()}).strict(),l=e.object({repositoryName:e.string()}).strict(),E=["x86_64","arm64"],u=e.object({name:e.string(),secrets:e.array(e.string()).optional(),ssmSecretsPath:e.string().optional(),importedSecretNames:e.array(e.string()).optional(),docker:c.optional(),imageKey:e.string().optional(),architecture:e.enum(E).optional()}).strict(),f=e.object({templateHash:e.string(),synthTimestamp:e.string()}).strict(),b=e.object({constructPath:e.string().max(512),group:e.string().max(128),resourceType:e.string().max(256)}).strict(),R=e.object({version:e.literal(h),generatedAt:e.string(),appName:e.string(),services:e.array(p),lambdas:e.array(u),pattern:g.optional(),ecr:l.optional(),stacks:e.record(e.string(),f),resourceMap:e.record(e.string(),b).optional()}).strict();export{x as BUILDKIT_SECRET_ID_PATTERN,M as DockerBuildArgValueSchema,N as DockerBuildPartialSchema,c as DockerBuildSchema,A as DockerBuildSecretRefSchema,I as FJALL_MANIFEST_FILENAME,R as FjallManifestSchema,E as LAMBDA_ARCHITECTURE_VALUES,h as MANIFEST_SCHEMA_VERSION,l as ManifestEcrSchema,u as ManifestLambdaSchema,g as ManifestPatternSchema,p as ManifestServiceSchema,f as ManifestStackHashSchema,b as ResourceMapEntrySchema,P as dockerBuildFingerprint,B as mergeDockerBuild,j as normaliseDockerBuild};
1
+ var S=Object.defineProperty;var s=(t,n)=>S(t,"name",{value:n,configurable:!0});import{z as e}from"zod";import{PATTERN_TYPE_VALUES as h}from"../patterns/patternTypes.js";const N="fjall-manifest.json",x=1,P=1,A=/^[A-Za-z0-9_.-]+$/,M=e.object({id:e.string().min(1,"buildSecret id cannot be empty").regex(A,"buildSecret id may contain only letters, digits, '_', '.', and '-' (no comma, '=', or whitespace, which would break the buildx --secret argv)"),ssm:e.string().min(1,"ssm parameter name cannot be empty").optional(),secretsManager:e.object({name:e.string().min(1,"secret name cannot be empty").optional(),arn:e.string().min(1,"secret arn cannot be empty").optional(),field:e.string().min(1,"secret field cannot be empty").optional()}).strict().refine(t=>t.name===void 0!=(t.arn===void 0),"secretsManager requires exactly one of name or arn").optional(),env:e.string().min(1,"env variable name cannot be empty").optional()}).strict().superRefine((t,n)=>{[t.ssm,t.secretsManager,t.env].filter(r=>r!==void 0).length!==1&&n.addIssue({code:e.ZodIssueCode.custom,message:"buildSecret requires exactly one source (ssm, secretsManager, or env)"})}),E=e.union([e.string(),e.object({ssm:e.string().min(1,"ssm parameter name cannot be empty").optional(),secretsManager:e.object({name:e.string().min(1,"secret name cannot be empty").optional(),arn:e.string().min(1,"secret arn cannot be empty").optional(),field:e.string().min(1,"secret field cannot be empty").optional()}).strict().refine(t=>t.name===void 0!=(t.arn===void 0),"secretsManager requires exactly one of name or arn").optional(),env:e.string().min(1,"env variable name cannot be empty").optional(),acknowledgePublic:e.boolean().optional()}).strict().superRefine((t,n)=>{[t.ssm,t.secretsManager,t.env].filter(r=>r!==void 0).length!==1&&n.addIssue({code:e.ZodIssueCode.custom,message:"buildArg value requires exactly one source (ssm, secretsManager, or env)"})})]),c=e.object({path:e.string(),context:e.string().min(1,"context cannot be empty").optional(),target:e.string().min(1,"target cannot be empty").optional(),buildArgs:e.record(e.string(),E).optional(),buildSecrets:e.array(M).optional()}).strict(),R=c.partial();function B(t,n){if(n===void 0)return t;const i=n.context??t.context,r=n.target??t.target,o=n.buildArgs??t.buildArgs,a=n.buildSecrets??t.buildSecrets;return{path:n.path??t.path,...i!==void 0&&{context:i},...r!==void 0&&{target:r},...o!==void 0&&{buildArgs:o},...a!==void 0&&{buildSecrets:a}}}s(B,"mergeDockerBuild");function m(t){return typeof t=="object"&&t!==null&&!Array.isArray(t)}s(m,"isRecord");function j(t){if(!m(t)||typeof t.path!="string"||t.path.length===0)return;const n=typeof t.context=="string"&&t.context.length>0?t.context:void 0,i=typeof t.target=="string"&&t.target.length>0?t.target:void 0,r=m(t.buildArgs)&&Object.keys(t.buildArgs).length>0?t.buildArgs:void 0,o=Array.isArray(t.buildSecrets)&&t.buildSecrets.length>0?t.buildSecrets:void 0,a={path:t.path,...n!==void 0&&{context:n},...i!==void 0&&{target:i},...r!==void 0&&{buildArgs:r},...o!==void 0&&{buildSecrets:o}},d=c.safeParse(a);return d.success?d.data:void 0}s(j,"normaliseDockerBuild");function C(t){if(t===void 0)return;const n=j(t);return n===void 0?void 0:JSON.stringify(n)}s(C,"dockerBuildFingerprint");const p=e.object({name:e.string(),clusterName:e.string().optional(),docker:c.optional(),containerPort:e.number().optional(),secrets:e.array(e.string()).optional(),ssmSecretsPath:e.string().optional(),importedSecretNames:e.array(e.string()).optional()}).strict(),g=e.object({type:e.enum(h),name:e.string(),source:e.string()}).strict(),l=e.object({repositoryName:e.string()}).strict(),_=["x86_64","arm64"],u=e.object({name:e.string(),secrets:e.array(e.string()).optional(),ssmSecretsPath:e.string().optional(),importedSecretNames:e.array(e.string()).optional(),docker:c.optional(),imageKey:e.string().optional(),architecture:e.enum(_).optional()}).strict(),f=e.object({templateHash:e.string(),synthTimestamp:e.string()}).strict(),b=e.object({constructPath:e.string().max(512),group:e.string().max(128),resourceType:e.string().max(256)}).strict(),y=e.object({synthesisedBy:e.string().min(1).max(128),minimumEngineVersion:e.string().min(1).max(32),maximumEngineMajor:e.number().int().min(0).optional(),minimumAwsCdkCli:e.string().min(1).max(32).optional()}).strict(),D=e.object({version:e.literal(x),generatedAt:e.string(),appName:e.string(),services:e.array(p),lambdas:e.array(u),pattern:g.optional(),ecr:l.optional(),stacks:e.record(e.string(),f),resourceMap:e.record(e.string(),b).optional(),engineCompat:y.optional()}).strict();export{A as BUILDKIT_SECRET_ID_PATTERN,E as DockerBuildArgValueSchema,R as DockerBuildPartialSchema,c as DockerBuildSchema,M as DockerBuildSecretRefSchema,y as EngineCompatSchema,N as FJALL_MANIFEST_FILENAME,D as FjallManifestSchema,_ as LAMBDA_ARCHITECTURE_VALUES,x as MANIFEST_SCHEMA_VERSION,P as MAX_SUPPORTED_MANIFEST_SCHEMA_VERSION,l as ManifestEcrSchema,u as ManifestLambdaSchema,g as ManifestPatternSchema,p as ManifestServiceSchema,f as ManifestStackHashSchema,b as ResourceMapEntrySchema,C as dockerBuildFingerprint,B as mergeDockerBuild,j as normaliseDockerBuild};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fjall/util",
3
- "version": "4.1.0",
3
+ "version": "4.3.0",
4
4
  "description": "Common utility methods",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -134,5 +134,5 @@
134
134
  "engines": {
135
135
  "node": ">=22.0.0"
136
136
  },
137
- "gitHead": "09dee795753839b82aedbb7d0cef1c5ef283df55"
137
+ "gitHead": "8a3ae096f9d15c47dc8c277c9bddfa40e4168c19"
138
138
  }