@fjall/deploy-core 17.0.0 → 18.0.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.
@@ -9,7 +9,7 @@
9
9
  "package.json",
10
10
  "tsconfig.json"
11
11
  ],
12
- "hash": "1eb6dbdb21e02490e85465beea05f034a4b93ab1bb17a0092e88652139ee1082",
12
+ "hash": "f2a79e32e6b413f4cba67fbc438909cf3edb04eb881e2d4dd27d0d1b40eaded2",
13
13
  "files": {
14
14
  "src/__test-utils__/awsMockHelpers.ts": "fea371c1b1869678",
15
15
  "src/__test-utils__/index.ts": "e03cf35821157dc4",
@@ -63,10 +63,10 @@
63
63
  "src/orchestration/application/buildArgResolver.ts": "47142177df453d9c",
64
64
  "src/orchestration/application/buildGroupValidator.ts": "0f0e1f142ee31fe0",
65
65
  "src/orchestration/application/buildSecretResolver.ts": "bdb48c28857188ba",
66
- "src/orchestration/application/buildSecretSession.ts": "b45265140a3a781a",
66
+ "src/orchestration/application/buildSecretSession.ts": "ff89426b0093bfd3",
67
67
  "src/orchestration/application/codeOnlyDeploy.ts": "062b0acdad1dcf08",
68
68
  "src/orchestration/application/databaseEndpointReconcile.ts": "27b14ee41524c632",
69
- "src/orchestration/application/deploySessionPolicy.ts": "e2653f4c0aae2ef2",
69
+ "src/orchestration/application/deploySessionPolicy.ts": "6b70e135dd6e71f4",
70
70
  "src/orchestration/application/destroyPreFlight.ts": "cc4978dec60b033e",
71
71
  "src/orchestration/application/destructionGate.ts": "5fbaa6ef69eb3ae1",
72
72
  "src/orchestration/application/detectionPipeline.ts": "69b7dfcedf22fe01",
@@ -113,7 +113,7 @@
113
113
  "src/orchestration/domain/delegatedDomainDeploy.ts": "b5e5c2db59250b8a",
114
114
  "src/orchestration/domain/delegationDestroyMirror.ts": "939f6c3cc3293d8b",
115
115
  "src/orchestration/domain/delegationResolution.ts": "f2b91a8aaf284dfa",
116
- "src/orchestration/domain/domainSessionPolicy.ts": "c8603d5ddf19d7ea",
116
+ "src/orchestration/domain/domainSessionPolicy.ts": "8dadfa02d5b5702e",
117
117
  "src/orchestration/domain/domainTakeoverGate.ts": "ecd9694cebc7be6c",
118
118
  "src/orchestration/domain/index.ts": "ec421e83dd0afbd6",
119
119
  "src/orchestration/domain/nsPropagationGate.ts": "c7a443e7048d4430",
@@ -271,9 +271,9 @@
271
271
  "src/util/sleepAbortable.ts": "f9cac3bf8a79a476",
272
272
  "src/version.ts": "1811a4475823b27e",
273
273
  "../scripts/minify-dist.mjs": "6b2e4b0df8aec601",
274
- "package.json": "6a0c4d8e8e7ba260",
274
+ "package.json": "2b7f5ea76b29ce09",
275
275
  "tsconfig.json": "1929cf3f99fe9b1e"
276
276
  },
277
- "outputHash": "54460fbb8d3a74d28c3e01b991ddc4c023d0d74fcff01d7b2d3f5f453e45df17",
277
+ "outputHash": "e50bbe5bd0e90989894ba721927cb0ab3bc05c735d02e1d7c94f41d2135d6c49",
278
278
  "outputFileCount": 511
279
279
  }
package/dist/.minified CHANGED
@@ -1 +1 @@
1
- 255 files minified at 2026-08-23T02:03:37.379Z
1
+ 255 files minified at 2026-08-23T08:32:09.587Z
@@ -17,13 +17,31 @@ export interface BuildSecretSessionContext {
17
17
  partition: string;
18
18
  }
19
19
  /**
20
- * The inline session policy must stay well under the AWS hard limit (2048 chars
21
- * for an AssumeRoleWithWebIdentity inline `Policy`). We fail closed before
22
- * minting a session whose policy would be rejected AWS-side, rather than ship a
23
- * silently-broadened or truncated policy. Shared with `deploySessionPolicy.ts`
24
- * both builders guard the same AWS limit.
20
+ * The binding STS limit on an inline session `Policy` is NOT the documented
21
+ * 2048-char plaintext cap it is the PACKED (compressed binary) budget that
22
+ * the policy shares with session tags, and for high-entropy ARN content it
23
+ * binds far earlier. Measured against STS on 2026-08-23 (dev account,
24
+ * us-east-2): 117 chars packed to 9%, 720 chars to 64%, and the
25
+ * `AssumeRoleWithWebIdentity` boundary for `buildDeploySessionPolicy` output
26
+ * sat between 1255 chars (accepted) and 1258 chars (PackedPolicyTooLarge).
27
+ * That knife edge is what silently killed every nightly deploy-test mint from
28
+ * 2026-08-10 — the policy passed the old 2048 plaintext guard and died at STS.
29
+ *
30
+ * 1190 leaves ~5% headroom under the measured boundary while admitting the
31
+ * maximal CANONICAL app name: the deploy policy serialises to BASE +
32
+ * pascalLen + 2 * kebabLen chars, and over the kebab namespace the generator
33
+ * scaffolds that maximises at the 50-char hyphen-free name (~1164 chars with
34
+ * the account-pinned ECR entries). Degenerate legacy-Pascal names whose kebab
35
+ * expansion overflows this (e.g. "aB" * 25 → ~1214) fail closed with the
36
+ * budget named — they could never deploy anyway (pre-fix they died at STS
37
+ * with an opaque PackedPolicyTooLarge), and admitting them would mean
38
+ * sailing ~3% under the measured cliff. We fail closed here, before minting
39
+ * a session whose policy STS would reject, rather than ship a
40
+ * silently-broadened or truncated policy. Shared by all three session-policy
41
+ * builders (`deploySessionPolicy.ts`, `domainSessionPolicy.ts`, and this one)
42
+ * — they guard the same STS budget.
25
43
  */
26
- export declare const MAX_INLINE_POLICY_CHARS = 2048;
44
+ export declare const MAX_PACKED_SAFE_POLICY_CHARS = 1190;
27
45
  /**
28
46
  * Derive the `aws` / `aws-cn` partition from a region. China regions use the
29
47
  * `aws-cn` partition; everything else (incl. GovCloud `us-gov-*`, which is
@@ -1 +1 @@
1
- var g=Object.defineProperty;var n=(s,m)=>g(s,"name",{value:m,configurable:!0});import{success as p,failure as S}from"@fjall/generator";import{toKebab as A}from"@fjall/util";const u=2048;function b(s){return s.startsWith("cn-")?"aws-cn":"aws"}n(b,"partitionForRegion");function x(s,m){const{region:r,accountId:a,partition:i}=s,c=A(s.appName),d=`arn:${i}:ssm:${r}:${a}:parameter/${c}/*`,f=`arn:${i}:secretsmanager:${r}:${a}:secret:fjall-${c}-*`,t=new Set;for(const e of m){if(e.ssm!==void 0&&e.ssm!==""){const o=e.ssm.startsWith("/")?e.ssm.slice(1):e.ssm;o.startsWith(`${c}/`)||t.add(`arn:${i}:ssm:${r}:${a}:parameter/${o}`)}if(e.secretsManagerArn!==void 0&&e.secretsManagerArn!==""){const o=f.replace(/\*$/,"");e.secretsManagerArn.startsWith(o)||t.add(e.secretsManagerArn)}e.secretsManagerName!==void 0&&e.secretsManagerName!==""&&!e.secretsManagerName.startsWith(`fjall-${c}-`)&&t.add(`arn:${i}:secretsmanager:${r}:${a}:secret:${e.secretsManagerName}-*`)}const $=[{Sid:"FjallBuildSsmRead",Effect:"Allow",Action:["ssm:GetParameter","ssm:GetParameters"],Resource:[d,...[...t].filter(h)]},{Sid:"FjallBuildSecretsManagerRead",Effect:"Allow",Action:["secretsmanager:GetSecretValue"],Resource:[f,...[...t].filter(M)]},{Sid:"FjallBuildKmsDecrypt",Effect:"Allow",Action:["kms:Decrypt"],Resource:"*",Condition:{StringEquals:{"kms:ViaService":[`ssm.${r}.amazonaws.com`,`secretsmanager.${r}.amazonaws.com`]}}}],l=JSON.stringify({Version:"2012-10-17",Statement:$});return l.length>u?S(new Error(`Build-secret session policy is ${l.length} chars, exceeding the ${u}-char AWS inline-policy limit. Reduce the number of out-of-prefix secret/parameter references for this build.`)):p(l)}n(x,"buildBuildSecretSessionPolicy");function h(s){return s.includes(":ssm:")}n(h,"isSsmArn");function M(s){return s.includes(":secretsmanager:")}n(M,"isSecretsArn");export{u as MAX_INLINE_POLICY_CHARS,x as buildBuildSecretSessionPolicy,b as partitionForRegion};
1
+ var g=Object.defineProperty;var a=(s,m)=>g(s,"name",{value:m,configurable:!0});import{success as p,failure as S}from"@fjall/generator";import{toKebab as A}from"@fjall/util";const u=1190;function x(s){return s.startsWith("cn-")?"aws-cn":"aws"}a(x,"partitionForRegion");function y(s,m){const{region:r,accountId:n,partition:c}=s,i=A(s.appName),d=`arn:${c}:ssm:${r}:${n}:parameter/${i}/*`,f=`arn:${c}:secretsmanager:${r}:${n}:secret:fjall-${i}-*`,t=new Set;for(const e of m){if(e.ssm!==void 0&&e.ssm!==""){const o=e.ssm.startsWith("/")?e.ssm.slice(1):e.ssm;o.startsWith(`${i}/`)||t.add(`arn:${c}:ssm:${r}:${n}:parameter/${o}`)}if(e.secretsManagerArn!==void 0&&e.secretsManagerArn!==""){const o=f.replace(/\*$/,"");e.secretsManagerArn.startsWith(o)||t.add(e.secretsManagerArn)}e.secretsManagerName!==void 0&&e.secretsManagerName!==""&&!e.secretsManagerName.startsWith(`fjall-${i}-`)&&t.add(`arn:${c}:secretsmanager:${r}:${n}:secret:${e.secretsManagerName}-*`)}const $=[{Sid:"FjallBuildSsmRead",Effect:"Allow",Action:["ssm:GetParameter","ssm:GetParameters"],Resource:[d,...[...t].filter(h)]},{Sid:"FjallBuildSecretsManagerRead",Effect:"Allow",Action:["secretsmanager:GetSecretValue"],Resource:[f,...[...t].filter(M)]},{Sid:"FjallBuildKmsDecrypt",Effect:"Allow",Action:["kms:Decrypt"],Resource:"*",Condition:{StringEquals:{"kms:ViaService":[`ssm.${r}.amazonaws.com`,`secretsmanager.${r}.amazonaws.com`]}}}],l=JSON.stringify({Version:"2012-10-17",Statement:$});return l.length>u?S(new Error(`Build-secret session policy is ${l.length} chars, exceeding the ${u}-char packed-safe STS session-policy budget. Reduce the number of out-of-prefix secret/parameter references for this build.`)):p(l)}a(y,"buildBuildSecretSessionPolicy");function h(s){return s.includes(":ssm:")}a(h,"isSsmArn");function M(s){return s.includes(":secretsmanager:")}a(M,"isSecretsArn");export{u as MAX_PACKED_SAFE_POLICY_CHARS,y as buildBuildSecretSessionPolicy,x as partitionForRegion};
@@ -2,7 +2,10 @@ import { type Result } from "@fjall/generator";
2
2
  /**
3
3
  * The AWS-account/region context a deploy session's inline policy is scoped to.
4
4
  * `appName` is the deploy target; `partition` is derived via `partitionForRegion`
5
- * (re-exported from `buildSecretSession.js`).
5
+ * (re-exported from `buildSecretSession.js`). `region` and `accountId` are
6
+ * deliberately NOT pinned into the policy's ARNs (see the packed-budget note on
7
+ * `buildDeploySessionPolicy`) — they remain in the context so call sites keep
8
+ * compiling and the caller's intent stays explicit.
6
9
  */
7
10
  export interface DeploySessionContext {
8
11
  appName: string;
@@ -62,6 +65,28 @@ export declare const ECR_MUTATION_ACTIONS: string[];
62
65
  * ECR repo is `toKebab(appName)` (matching the ECR construct at
63
66
  * components/infrastructure/lib/app.ts) — never a re-implemented `.toLowerCase()`.
64
67
  *
65
- * Fails closed when the serialised policy would exceed the AWS inline-policy limit.
68
+ * The REGION segment of every ARN is wildcarded, NOT pinned from `ctx` — a
69
+ * pinned region wrongly DENIED an app's own stacks in any second region, and
70
+ * every pinned segment spends packed budget: STS compresses the policy into a
71
+ * packed binary whose real ceiling sits near 1256 chars for this content class
72
+ * (measured 2026-08-23 — see MAX_PACKED_SAFE_POLICY_CHARS), and the fully
73
+ * pinned form crossed it for app names of 19+ chars, killing the mint with
74
+ * PackedPolicyTooLarge. The ACCOUNT segment is asymmetric by design:
75
+ * - CloudFormation entries wildcard it. CFN has no resource-based policies, so
76
+ * cross-account stack mutation would require an `sts:AssumeRole` this policy
77
+ * documentedly does not survive — pinning the account there restated what
78
+ * the role boundary already enforces, for 12 chars apiece.
79
+ * - ECR entries PIN it. ECR repositories carry resource-based policies: a
80
+ * foreign account's repo policy (e.g. an `aws:PrincipalOrgID` grant on a
81
+ * shared mirror) can admit this identity with NO AssumeRole, so an
82
+ * account-wildcarded NotResource would exempt same-named foreign repos —
83
+ * `cdk-*` would exempt every bootstrap asset repo in every account — from
84
+ * the one Deny whose job is fencing foreign ECR mutation. The account pin
85
+ * here is the load-bearing cross-account fence, worth 4 × 11 packed chars.
86
+ * Statements carry no Sids for the same budget reason — they are
87
+ * documentation, and this policy's documentation lives here.
88
+ *
89
+ * Fails closed when the serialised policy would exceed the packed-safe STS
90
+ * session-policy budget.
66
91
  */
67
92
  export declare function buildDeploySessionPolicy(ctx: DeploySessionContext): Result<string>;
@@ -1 +1 @@
1
- var s=Object.defineProperty;var i=(r,o)=>s(r,"name",{value:o,configurable:!0});import{success as m,failure as d}from"@fjall/generator";import{toKebab as u,toPascalCase as f}from"@fjall/util";import{buildCacheRepositoryName as y}from"@fjall/util/docker";import{SCHEMA_GATE_ECR_REPO_NAME as $}from"@fjall/util/migration";import{MAX_INLINE_POLICY_CHARS as n}from"./buildSecretSession.js";const S=["cloudformation:CreateStack","cloudformation:UpdateStack","cloudformation:DeleteStack","cloudformation:CreateChangeSet","cloudformation:ExecuteChangeSet","cloudformation:DeleteChangeSet","cloudformation:CancelUpdateStack","cloudformation:ContinueUpdateRollback","cloudformation:RollbackStack","cloudformation:SetStackPolicy","cloudformation:UpdateTerminationProtection"],C=["ecr:PutImage","ecr:InitiateLayerUpload","ecr:UploadLayerPart","ecr:CompleteLayerUpload","ecr:BatchDeleteImage","ecr:DeleteRepository","ecr:SetRepositoryPolicy","ecr:DeleteRepositoryPolicy"];function g(r){const{region:o,accountId:e,partition:t}=r,l=f(r.appName),c=u(r.appName),p=[{Sid:"FjallDeployInheritAdmin",Effect:"Allow",Action:"*",Resource:"*"},{Sid:"FjallDeployDenyForeignStackMutation",Effect:"Deny",Action:S,NotResource:[`arn:${t}:cloudformation:${o}:${e}:stack/${l}*/*`,`arn:${t}:cloudformation:${o}:${e}:stack/CDKToolkit/*`]},{Sid:"FjallDeployDenyForeignEcrMutation",Effect:"Deny",Action:C,NotResource:[`arn:${t}:ecr:${o}:${e}:repository/${c}`,`arn:${t}:ecr:${o}:${e}:repository/${y(c)}`,`arn:${t}:ecr:${o}:${e}:repository/cdk-*`,`arn:${t}:ecr:${o}:${e}:repository/${$}`]}],a=JSON.stringify({Version:"2012-10-17",Statement:p});return a.length>n?d(new Error(`Deploy session policy is ${a.length} chars, exceeding the ${n}-char AWS inline-policy limit.`)):m(a)}i(g,"buildDeploySessionPolicy");export{S as CFN_MUTATION_ACTIONS,C as ECR_MUTATION_ACTIONS,g as buildDeploySessionPolicy};
1
+ var s=Object.defineProperty;var c=(e,o)=>s(e,"name",{value:o,configurable:!0});import{success as p,failure as m}from"@fjall/generator";import{toKebab as f,toPascalCase as u}from"@fjall/util";import{buildCacheRepositoryName as d}from"@fjall/util/docker";import{SCHEMA_GATE_ECR_REPO_NAME as y}from"@fjall/util/migration";import{MAX_PACKED_SAFE_POLICY_CHARS as i}from"./buildSecretSession.js";const S=["cloudformation:CreateStack","cloudformation:UpdateStack","cloudformation:DeleteStack","cloudformation:CreateChangeSet","cloudformation:ExecuteChangeSet","cloudformation:DeleteChangeSet","cloudformation:CancelUpdateStack","cloudformation:ContinueUpdateRollback","cloudformation:RollbackStack","cloudformation:SetStackPolicy","cloudformation:UpdateTerminationProtection"],C=["ecr:PutImage","ecr:InitiateLayerUpload","ecr:UploadLayerPart","ecr:CompleteLayerUpload","ecr:BatchDeleteImage","ecr:DeleteRepository","ecr:SetRepositoryPolicy","ecr:DeleteRepositoryPolicy"];function P(e){const{partition:o,accountId:t}=e,n=u(e.appName),a=f(e.appName),l=[{Effect:"Allow",Action:"*",Resource:"*"},{Effect:"Deny",Action:S,NotResource:[`arn:${o}:cloudformation:*:*:stack/${n}*/*`,`arn:${o}:cloudformation:*:*:stack/CDKToolkit/*`]},{Effect:"Deny",Action:C,NotResource:[`arn:${o}:ecr:*:${t}:repository/${a}`,`arn:${o}:ecr:*:${t}:repository/${d(a)}`,`arn:${o}:ecr:*:${t}:repository/cdk-*`,`arn:${o}:ecr:*:${t}:repository/${y}`]}],r=JSON.stringify({Version:"2012-10-17",Statement:l});return r.length>i?m(new Error(`Deploy session policy is ${r.length} chars, exceeding the ${i}-char packed-safe STS session-policy budget.`)):p(r)}c(P,"buildDeploySessionPolicy");export{S as CFN_MUTATION_ACTIONS,C as ECR_MUTATION_ACTIONS,P as buildDeploySessionPolicy};
@@ -7,7 +7,8 @@ import { type Result } from "@fjall/generator";
7
7
  * case-sensitive, so a caller-normalised or user-typed variant would deny
8
8
  * the zone's own stack (fail-closed, but loud at deploy time instead of
9
9
  * here). Callers necessarily hold the record already: `accountId`/`region`
10
- * are its home pin.
10
+ * are its home pin — carried for caller-intent clarity, though the policy's
11
+ * ARNs deliberately wildcard both segments (see the builder body).
11
12
  */
12
13
  export interface DomainSessionContext {
13
14
  zoneName: string;
@@ -35,12 +36,13 @@ export interface DomainSessionContext {
35
36
  * Differences from the application builder, each derived from what a domain
36
37
  * deploy actually does:
37
38
  * - The CFN NotResource names the zone's stacks EXACTLY (no prefix wildcard):
38
- * `getDomainStackName(zone)` in the home region, plus its paired us-east-1
39
- * certificates stack (`getDomainUsEast1CertificatesStackName`) — CloudFront
40
- * viewer certificates only mint in us-east-1, so the pair spans two regions
41
- * by construction. CDKToolkit is exempted in BOTH regions for the same
42
- * reason. Exact names close the app builder's prefix-wildcard class of
43
- * over-grant across DISTINCT stacks. (getDomainStackName is not injective
39
+ * `getDomainStackName(zone)` plus its paired us-east-1 certificates stack
40
+ * (`getDomainUsEast1CertificatesStackName`) — CloudFront viewer certificates
41
+ * only mint in us-east-1, so the pair spans two regions by construction —
42
+ * plus CDKToolkit. The ARNs' region/account segments are wildcarded (see the
43
+ * builder body), so each stack needs exactly one entry regardless of which
44
+ * regions it spans. Exact names close the app builder's prefix-wildcard
45
+ * class of over-grant across DISTINCT stacks. (getDomainStackName is not injective
44
46
  * — it strips dots before PascalCasing, so `dev.fjall.io` and
45
47
  * `devfjall.io` share one stack name — but two such zones in one
46
48
  * account+region share the PHYSICAL stack too, which no ARN-scoped policy
@@ -56,7 +58,7 @@ export interface DomainSessionContext {
56
58
  * lookup before the session exists — accepted v1 limitation, same class as
57
59
  * the app builder's.
58
60
  *
59
- * Fails closed when the serialised policy would exceed the AWS inline-policy
60
- * limit.
61
+ * Fails closed when the serialised policy would exceed the packed-safe STS
62
+ * session-policy budget.
61
63
  */
62
64
  export declare function buildDomainSessionPolicy(ctx: DomainSessionContext): Result<string>;
@@ -1 +1 @@
1
- var D=Object.defineProperty;var i=(o,t)=>D(o,"name",{value:t,configurable:!0});import{success as S,failure as p}from"@fjall/generator";import{getDomainStackName as N,getDomainUsEast1CertificatesStackName as y}from"@fjall/util";import{MAX_INLINE_POLICY_CHARS as c}from"../application/buildSecretSession.js";import{CFN_MUTATION_ACTIONS as A,ECR_MUTATION_ACTIONS as k}from"../application/deploySessionPolicy.js";function h(o){const{region:t,accountId:r,partition:m}=o,a=N(o.zoneName),l=y(a),e=i((f,u)=>`arn:${m}:cloudformation:${f}:${r}:stack/${u}/*`,"stackArn"),s=[e(t,a),e("us-east-1",l),e(t,"CDKToolkit")];t!=="us-east-1"&&s.push(e("us-east-1","CDKToolkit"));const n=JSON.stringify({Version:"2012-10-17",Statement:[{Sid:"FjallDomainDeployInheritAdmin",Effect:"Allow",Action:"*",Resource:"*"},{Sid:"FjallDomainDeployDenyForeignStackMutation",Effect:"Deny",Action:A,NotResource:s},{Sid:"FjallDomainDeployDenyEcrMutation",Effect:"Deny",Action:k,Resource:"*"}]});return n.length>c?p(new Error(`Domain deploy session policy is ${n.length} chars, exceeding the ${c}-char AWS inline-policy limit.`)):S(n)}i(h,"buildDomainSessionPolicy");export{h as buildDomainSessionPolicy};
1
+ var f=Object.defineProperty;var s=(t,e)=>f(t,"name",{value:e,configurable:!0});import{success as l,failure as A}from"@fjall/generator";import{getDomainStackName as S,getDomainUsEast1CertificatesStackName as N}from"@fjall/util";import{MAX_PACKED_SAFE_POLICY_CHARS as i}from"../application/buildSecretSession.js";import{CFN_MUTATION_ACTIONS as p,ECR_MUTATION_ACTIONS as u}from"../application/deploySessionPolicy.js";function _(t){const{partition:e}=t,c=S(t.zoneName),r=N(c),o=s(m=>`arn:${e}:cloudformation:*:*:stack/${m}/*`,"stackArn"),a=[o(c),o(r),o("CDKToolkit")],n=JSON.stringify({Version:"2012-10-17",Statement:[{Effect:"Allow",Action:"*",Resource:"*"},{Effect:"Deny",Action:p,NotResource:a},{Effect:"Deny",Action:u,Resource:"*"}]});return n.length>i?A(new Error(`Domain deploy session policy is ${n.length} chars, exceeding the ${i}-char packed-safe STS session-policy budget.`)):l(n)}s(_,"buildDomainSessionPolicy");export{_ as buildDomainSessionPolicy};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fjall/deploy-core",
3
- "version": "17.0.0",
3
+ "version": "18.0.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/fjall-tech/fjall.git",
@@ -96,15 +96,15 @@
96
96
  "@aws-sdk/client-ssm": "^3.1098.0",
97
97
  "@aws-sdk/client-sso-admin": "^3.1098.0",
98
98
  "@aws-sdk/client-sts": "^3.1098.0",
99
- "@fjall/generator": "^17.0.0",
100
- "@fjall/util": "^17.0.0",
99
+ "@fjall/generator": "^18.0.0",
100
+ "@fjall/util": "^18.0.0",
101
101
  "@smithy/node-http-handler": "^4.9.13",
102
102
  "aws-cdk": "^2.1134.0",
103
103
  "tsx": "^4.23.1",
104
104
  "zod": "^4.4.3"
105
105
  },
106
106
  "peerDependencies": {
107
- "@fjall/components-infrastructure": ">=17.0.0 <18.0.0"
107
+ "@fjall/components-infrastructure": ">=18.0.0 <19.0.0"
108
108
  },
109
109
  "peerDependenciesMeta": {
110
110
  "@fjall/components-infrastructure": {