@fjall/util 21.0.0 → 21.1.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/.build-source-hash +16 -9
- package/dist/.minified +1 -1
- package/dist/atomicTempNaming.d.ts +26 -0
- package/dist/atomicTempNaming.js +1 -0
- package/dist/config.d.ts +28 -14
- package/dist/config.js +2 -2
- package/dist/configPaths.d.ts +22 -0
- package/dist/configPaths.js +1 -0
- package/dist/fjallHome.d.ts +78 -0
- package/dist/fjallHome.js +1 -0
- package/dist/fsHelpers.d.ts +9 -0
- package/dist/fsHelpers.js +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/index.js +1 -1
- package/dist/logRotation.d.ts +42 -0
- package/dist/logRotation.js +1 -0
- package/dist/patterns/frameworkPatterns.d.ts +151 -0
- package/dist/patterns/frameworkPatterns.js +1 -0
- package/dist/patterns/index.d.ts +2 -1
- package/dist/patterns/index.js +1 -1
- package/dist/patterns/patternTypes.d.ts +29 -0
- package/dist/patterns/patternTypes.js +1 -1
- package/dist/scaffold/ensureGitignore.d.ts +18 -0
- package/dist/scaffold/ensureGitignore.js +9 -0
- package/dist/scaffold/gitignore.d.ts +47 -0
- package/dist/scaffold/gitignore.js +35 -0
- package/package.json +9 -1
package/dist/.build-source-hash
CHANGED
|
@@ -9,11 +9,12 @@
|
|
|
9
9
|
"package.json",
|
|
10
10
|
"tsconfig.json"
|
|
11
11
|
],
|
|
12
|
-
"hash": "
|
|
12
|
+
"hash": "3cd4016b6ba53a403e092a115897c084755ae5791ecbb7812d771635c0e9bd67",
|
|
13
13
|
"files": {
|
|
14
14
|
"src/async/concurrency.ts": "3c7ebe0222a720f9",
|
|
15
15
|
"src/async/singleton.ts": "7bcc21b0fb920561",
|
|
16
16
|
"src/async/sleep.ts": "df52b17675ec3ed2",
|
|
17
|
+
"src/atomicTempNaming.ts": "d08f34bdb062be6f",
|
|
17
18
|
"src/aws/CloudFormationFailureAnalyser.ts": "4e68b353171edd31",
|
|
18
19
|
"src/aws/cloudformationTypes.ts": "e43bab9c96a21856",
|
|
19
20
|
"src/aws/costAllocationTags.ts": "8b60ac5b62a68a9d",
|
|
@@ -32,7 +33,8 @@
|
|
|
32
33
|
"src/cdkToolchain.ts": "a6b996c60b87d644",
|
|
33
34
|
"src/cfn/physicalNameProperties.ts": "35d3c6f28079c593",
|
|
34
35
|
"src/clickhouse.ts": "655c74cdba292c29",
|
|
35
|
-
"src/config.ts": "
|
|
36
|
+
"src/config.ts": "2c4174dabed881ed",
|
|
37
|
+
"src/configPaths.ts": "afcc2e4ceb6652a0",
|
|
36
38
|
"src/constructMap.ts": "b81fc8e90015467f",
|
|
37
39
|
"src/deploy/approvalTokenOutput.ts": "4be7b52825d88a37",
|
|
38
40
|
"src/devSubstrate/entrypoint.ts": "0526b88258174aa6",
|
|
@@ -66,10 +68,11 @@
|
|
|
66
68
|
"src/errors/absence.ts": "390fea350ffbb4e5",
|
|
67
69
|
"src/failure/deploymentFailure.ts": "5824db1d97d01838",
|
|
68
70
|
"src/failure/extractErrorWindow.ts": "ca41f90946fa939c",
|
|
69
|
-
"src/
|
|
71
|
+
"src/fjallHome.ts": "d7c48a6444e21699",
|
|
72
|
+
"src/fsHelpers.ts": "4dd3877b3953c6a9",
|
|
70
73
|
"src/fsScan.ts": "feb187758481443f",
|
|
71
74
|
"src/httpKeepAlive.ts": "c8fe4b118ef4c79f",
|
|
72
|
-
"src/index.ts": "
|
|
75
|
+
"src/index.ts": "7dd522de0cf1aca0",
|
|
73
76
|
"src/infra/backupVault.ts": "661678a6dfb0b648",
|
|
74
77
|
"src/infra/connectionsWire.ts": "e3afa3ba95a531d8",
|
|
75
78
|
"src/infra/deployArtefacts.ts": "235ac21dd3ccf0b2",
|
|
@@ -79,6 +82,7 @@
|
|
|
79
82
|
"src/infra/regions.ts": "26b80d7cea05454c",
|
|
80
83
|
"src/infra/tokenScopes.ts": "88c6a1f0da3fa491",
|
|
81
84
|
"src/insights/computePatternFingerprint.ts": "b5d3a4704f42cc1f",
|
|
85
|
+
"src/logRotation.ts": "4039ae64980f80b5",
|
|
82
86
|
"src/logger.ts": "865ec4ec62a9a588",
|
|
83
87
|
"src/manifest/index.ts": "bfa2930556c2f8ad",
|
|
84
88
|
"src/manifest/io.ts": "915ab602ac92d126",
|
|
@@ -102,8 +106,9 @@
|
|
|
102
106
|
"src/naming/targetExportNames.ts": "bab26b7c0243fafa",
|
|
103
107
|
"src/onboarding/index.ts": "7999117c5a7a18d1",
|
|
104
108
|
"src/onboarding/versionCurrency.ts": "19695f38b09cfc46",
|
|
105
|
-
"src/patterns/
|
|
106
|
-
"src/patterns/
|
|
109
|
+
"src/patterns/frameworkPatterns.ts": "0f843cb043eb11fc",
|
|
110
|
+
"src/patterns/index.ts": "41142efdd3b2711b",
|
|
111
|
+
"src/patterns/patternTypes.ts": "a50d9004645abc0c",
|
|
107
112
|
"src/patterns/staticSiteForms.ts": "86ffcf142d9a8eac",
|
|
108
113
|
"src/repo/appPath.ts": "9aa0d01262b88e65",
|
|
109
114
|
"src/repo/findInfrastructurePaths.ts": "dd1245f5d4004dd5",
|
|
@@ -114,13 +119,15 @@
|
|
|
114
119
|
"src/repo/scanLocalRepository.ts": "c7bc76201622a7a5",
|
|
115
120
|
"src/repo/scanTypes.ts": "1fda805a7d8de93b",
|
|
116
121
|
"src/resourceCategorisation.ts": "a140d1b3cb38be33",
|
|
122
|
+
"src/scaffold/ensureGitignore.ts": "230253a19bbf092c",
|
|
123
|
+
"src/scaffold/gitignore.ts": "87c66797a4bd05f2",
|
|
117
124
|
"src/secrets.ts": "50258d463e4e67c3",
|
|
118
125
|
"src/securityHelpers.ts": "81ba6146cf6fcefb",
|
|
119
126
|
"src/targets.ts": "126280f0a5762e21",
|
|
120
127
|
"../scripts/minify-dist.mjs": "6b2e4b0df8aec601",
|
|
121
|
-
"package.json": "
|
|
128
|
+
"package.json": "da75ad74e9acae9c",
|
|
122
129
|
"tsconfig.json": "db759831ad95f396"
|
|
123
130
|
},
|
|
124
|
-
"outputHash": "
|
|
125
|
-
"outputFileCount":
|
|
131
|
+
"outputHash": "6286cd5069962e57b14e7a8b535b6862c7e8d9618cc4d0395239e2fb5013ef8d",
|
|
132
|
+
"outputFileCount": 235
|
|
126
133
|
}
|
package/dist/.minified
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
117 files minified at 2026-08-28T12:40:07.188Z
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* How atomic-write temp files are named.
|
|
3
|
+
*
|
|
4
|
+
* Deliberately its own module with no imports: two very different consumers
|
|
5
|
+
* need it, and neither should have to drag the other's dependencies in.
|
|
6
|
+
* `fsHelpers` builds real temp paths from it; `scaffold/gitignore` derives
|
|
7
|
+
* the ignore globs that cover those paths after a hard kill. Putting the
|
|
8
|
+
* policy in `fsHelpers` makes every consumer of the ignore constants depend
|
|
9
|
+
* transitively on an I/O module — which breaks any test that mocks
|
|
10
|
+
* `fsHelpers` wholesale, for no reason connected to what it was testing.
|
|
11
|
+
*
|
|
12
|
+
* They must agree. A temp name the ignore rule does not match is a file
|
|
13
|
+
* that lands in a customer's `git status` and, with `git add -A`, in their
|
|
14
|
+
* history.
|
|
15
|
+
*/
|
|
16
|
+
/** The suffix every atomic-write temp file ends with. */
|
|
17
|
+
export declare const ATOMIC_TMP_SUFFIX = ".tmp";
|
|
18
|
+
/**
|
|
19
|
+
* The glob covering a file's atomic-write temp files, in `.gitignore`
|
|
20
|
+
* spelling.
|
|
21
|
+
*
|
|
22
|
+
* The `*` is not decoration: temp names carry a random infix so concurrent
|
|
23
|
+
* writers cannot collide on one, which means a literal `<name>.tmp` entry
|
|
24
|
+
* matches nothing the writers actually produce.
|
|
25
|
+
*/
|
|
26
|
+
export declare function atomicTmpGlob(fileGlob: string): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var p=Object.defineProperty;var o=(t,n)=>p(t,"name",{value:n,configurable:!0});const r=".tmp";function e(t){return`${t}.*${r}`}o(e,"atomicTmpGlob");export{r as ATOMIC_TMP_SUFFIX,e as atomicTmpGlob};
|
package/dist/config.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { type Result } from "./docker/result.js";
|
|
3
3
|
import { type AccountTier } from "./environments.js";
|
|
4
|
+
export { LOCAL_CONFIG_DIRNAME, LOCAL_CONFIG_FILENAME, ROOT_CONFIG_FILENAME } from "./configPaths.js";
|
|
4
5
|
/**
|
|
5
6
|
* The Fjall root config filename. Single source of truth — the repo-root marker
|
|
6
7
|
* in findRepoRoot.ts MUST match this exactly or root detection diverges. Only
|
|
7
8
|
* this exact name is discovered; sibling `.old` / `.backup` copies are inert.
|
|
8
9
|
*/
|
|
9
|
-
export declare const ROOT_CONFIG_FILENAME = "fjall-config.json";
|
|
10
10
|
/**
|
|
11
11
|
* Backup Vault Lock modes for an account's DisasterRecovery vault.
|
|
12
12
|
* See decisions/2026-06-03-backup-vault-lock-mode-by-intent.md.
|
|
@@ -196,17 +196,6 @@ export declare const RootConfigReadSchema: z.ZodObject<{
|
|
|
196
196
|
}, z.core.$strict>>>>>;
|
|
197
197
|
}, z.core.$strip>;
|
|
198
198
|
export type RootConfigRead = z.infer<typeof RootConfigReadSchema>;
|
|
199
|
-
/**
|
|
200
|
-
* Local, NON-COMMITTED per-checkout state (`.fjall/local.json`, gitignored),
|
|
201
|
-
* co-located with fjall-config.json. Holds the developer's active deployment
|
|
202
|
-
* target: it lives here rather than in the committed fjall-config.json so a
|
|
203
|
-
* committed value can never silently re-aim someone else's deploy or a CI
|
|
204
|
-
* pipeline (the ci-deploy misdeploy fix). A legacy `activeTarget` in
|
|
205
|
-
* fjall-config.json is read only to warn-and-migrate, never to resolve a
|
|
206
|
-
* target.
|
|
207
|
-
*/
|
|
208
|
-
export declare const LOCAL_CONFIG_DIRNAME = ".fjall";
|
|
209
|
-
export declare const LOCAL_CONFIG_FILENAME = "local.json";
|
|
210
199
|
/**
|
|
211
200
|
* Canonical serialiser for the root fjall-config.json - the single source of
|
|
212
201
|
* truth for the file's on-disk shape. Both `Config.saveConfig` and the webapp
|
|
@@ -330,13 +319,38 @@ export declare class Config {
|
|
|
330
319
|
* and hot-path resolution never re-hits disk; writes flush through it.
|
|
331
320
|
*/
|
|
332
321
|
private localConfigCache;
|
|
322
|
+
/**
|
|
323
|
+
* Directory of the project this instance is bound to, or null when it is
|
|
324
|
+
* bound to none. SINGLE SOURCE for every path derived from the project
|
|
325
|
+
* root.
|
|
326
|
+
*
|
|
327
|
+
* `fjall-config.json` and `.fjall/local.json` MUST resolve to the same
|
|
328
|
+
* root. They previously derived it independently and disagreed by one
|
|
329
|
+
* level — `saveConfig` defaulted to `<cwd>/fjall`, `localConfigFile` to
|
|
330
|
+
* `<cwd>` — so an unbound instance (first `fjall connect`, before the
|
|
331
|
+
* project marker exists) wrote them to different roots and the local
|
|
332
|
+
* write was invisible to every later read.
|
|
333
|
+
*/
|
|
334
|
+
private resolveProjectDirectory;
|
|
335
|
+
/**
|
|
336
|
+
* Absolute path of `.fjall/local.json`, or null when this instance is not
|
|
337
|
+
* bound to a project. Never falls back to `process.cwd()`: per-checkout
|
|
338
|
+
* state anchored to the shell's working directory lands somewhere no
|
|
339
|
+
* later read looks.
|
|
340
|
+
*/
|
|
333
341
|
private localConfigFile;
|
|
334
342
|
private loadLocalConfig;
|
|
343
|
+
/**
|
|
344
|
+
* Persist `.fjall/local.json`. Fails — rather than inventing a location —
|
|
345
|
+
* when the instance is not bound to a project: a write anchored to the
|
|
346
|
+
* shell's cwd is indistinguishable from success to the caller and
|
|
347
|
+
* invisible to every subsequent read.
|
|
348
|
+
*/
|
|
335
349
|
private writeLocalConfig;
|
|
336
350
|
private static warnLegacyActiveTargetOnce;
|
|
337
351
|
getActiveTarget(): string | undefined;
|
|
338
|
-
setActiveTarget(name: string): void
|
|
339
|
-
clearActiveTarget(): void
|
|
352
|
+
setActiveTarget(name: string): Result<void, Error>;
|
|
353
|
+
clearActiveTarget(): Result<void, Error>;
|
|
340
354
|
getDomains(): DomainConfig[];
|
|
341
355
|
setDomains(domains: DomainConfig[]): void;
|
|
342
356
|
addDomain(domain: DomainConfig): void;
|
package/dist/config.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
2
|
-
`,{encoding:"utf8"}),this.localConfigCache=e}static warnLegacyActiveTargetOnce(){
|
|
1
|
+
var F=Object.defineProperty;var p=(u,e)=>F(u,"name",{value:e,configurable:!0});import*as a from"fs";import*as d from"path";import{z as l}from"zod";import{CapacityIdentityConfigSchema as A}from"./capacityIdentity.js";import{failure as m,success as w}from"./docker/result.js";import{getErrorMessage as E}from"./errorUtils.js";import{logger as O}from"./logger.js";import{maskSensitiveOutput as y}from"./securityHelpers.js";import{ensureGitignoreEntries as I}from"./scaffold/ensureGitignore.js";import{FJALL_MANAGED_STATE_DIR_ENTRIES as D,FJALL_PROJECT_GITIGNORE_HEADER as R,LOCAL_CONFIG_GITIGNORE_ENTRY as b,LOCAL_STATE_GITIGNORE_MARKER as $}from"./scaffold/gitignore.js";import{LOCAL_CONFIG_DIRNAME as x,LOCAL_CONFIG_FILENAME as M,ROOT_CONFIG_FILENAME as T}from"./configPaths.js";import{LOCAL_CONFIG_DIRNAME as de,LOCAL_CONFIG_FILENAME as ge,ROOT_CONFIG_FILENAME as ue}from"./configPaths.js";const G=10,Q=["compliance","governance","none"],ee=["enforced","off"],te=["centralised","off"],ne=["account","draining","org"],oe="managementEvents",re="organisationManagementEvents",ie=["active","draining","removed"],se="FjallTrailBucketName",ae="FjallTrailKeyArn",ce="OrganisationTrailBucketName",j=l.object({name:l.string(),type:l.enum(["apex","delegated"]),parentDomain:l.string().optional(),account:l.string().optional(),region:l.string().optional()}).strict(),L=l.object({activeTarget:l.string().optional(),domains:l.array(j).optional(),capacityIdentity:A.optional()}).strict(),_=l.object({activeTarget:l.string().optional(),domains:l.array(j).optional(),capacityIdentity:A.optional()}),P=l.object({activeTarget:l.string().optional()});function K(u={}){return JSON.stringify(u,null,2)}p(K,"serialiseRootConfig");const N=L.keyof().options;function J(u,e,t){const n=e[t];n!==void 0&&(u[t]=n)}p(J,"copyDefinedKey");function k(u,e){if(e===void 0)return!1;const t=new Set([...Object.keys(u),...Object.keys(e)]);for(const n of t)if(u[n]!==e[n])return!1;return!0}p(k,"domainEntriesEqual");class f{static{p(this,"Config")}rootConfig;configPath=null;loadFailed=!1;parseDegraded=!1;loadedSnapshot={};constructor(e,t){this.rootConfig=e??{},this.configPath=t??null}static findConfigDirectory(e){let t=e!==void 0&&e!==""?e:process.cwd();for(let n=0;n<G;n++){const o=d.join(t,"fjall"),i=d.join(o,T);if(a.existsSync(i))return o;const r=d.join(t,T);if(a.existsSync(r))return t;const c=d.dirname(t);if(c===t)break;t=c}return null}static loadConfigFile(e){try{return a.accessSync(e,a.constants.R_OK),a.readFileSync(e,{encoding:"utf8"})}catch(t){return O.warn("Config",`Config file at ${e} could not be read; using defaults`,{file:e,error:y(E(t))}),null}}static loadConfig(e){const t=f.findConfigDirectory(e);if(!t)return new f;const n=d.join(t,T),o=f.loadConfigFile(n);if(o===null){const g=new f(void 0,n);return g.loadFailed=!0,g}let i,r=!1;if(o!==""){let g;try{g=JSON.parse(o)}catch(s){throw f.formatZodError(s,T)}const C=L.safeParse(g);if(C.success)i=C.data;else{const s=_.safeParse(g);i=s.success?s.data:{},r=!s.success,s.success?O.warn("Config","fjall-config.json contains keys this version does not recognise (only activeTarget, domains and capacityIdentity are read). They were most likely written by a newer fjall version \u2014 leave them in place; saves preserve them verbatim.",{file:n}):O.warn("Config","fjall-config.json has a malformed activeTarget, domains or capacityIdentity value, so its contents were ignored for this run \u2014 any capacity-identity pins it holds will NOT apply (a pinned stack deploys unpinned and is blocked by the rename gate). Fix the file by hand; do NOT regenerate it, which would discard the pins.",{file:n})}}const c=new f(i,n);return c.parseDegraded=r,c.loadedSnapshot=structuredClone(c.rootConfig),c}static formatZodError(e,t){if(e instanceof l.ZodError&&e.issues.length>0){const i=e.issues.map(r=>`${r.path.join(".")}: ${r.message}`).join("; ");return new Error(`Failed to parse ${t}: ${i}`)}const o=(e instanceof Error?e.message:String(e)).replace(/\n/g," ").substring(0,500);return new Error(`Failed to parse ${t}: ${o}`)}saveConfig(){const e=d.join(this.resolveProjectDirectory()??d.join(process.cwd(),"fjall"),T);if(this.loadFailed)return m(new Error(`Refusing to save ${e}: the file exists but could not be read when this config loaded, so saving would replace its contents with state that never included them. Fix the file permissions (e.g. chmod u+rw ${e}) and retry.`));const t=d.dirname(e);try{a.mkdirSync(t,{recursive:!0})}catch(c){return m(new Error(`Cannot create config directory ${t}: ${y(E(c))}`))}const n=f.assertWritable(e,t);if(!n.success)return n;const o=this.mergeWithDisk(e);if(!o.success)return o;const i=K(o.data),r=`${e}.tmp-${process.pid}`;try{a.writeFileSync(r,i,{mode:384}),a.renameSync(r,e)}catch(c){return m(new Error(`Failed to save ${e}: ${y(E(c))}`))}return this.configPath=e,w(void 0)}static assertWritable(e,t){if(a.existsSync(e))try{a.accessSync(e,a.constants.W_OK)}catch{return m(new Error(`Cannot save ${e}: the file is read-only. Make it writable (e.g. chmod u+w ${e}) and retry.`))}try{a.accessSync(t,a.constants.W_OK)}catch{return m(new Error(`Cannot save ${e}: the directory ${t} is not writable. Make it writable (e.g. chmod u+w ${t}) and retry.`))}return w(void 0)}mergeWithDisk(e){const t=f.readDiskConfigForMerge(e);if(t.kind==="unmergeable")return m(new Error(`Refusing to save ${e}: ${t.reason}. Writing now would keep only this session's state and drop everything else the file carries (including keys written by other fjall versions). Fix or remove the file and retry.`));if(t.kind==="absent")return w(this.rootConfig);const n=t.disk,o={...n.foreign,...n.known};for(const r of N)r!=="domains"&&this.sessionChangedKey(r)&&(this.rootConfig[r]===void 0?delete o[r]:J(o,this.rootConfig,r));const i=this.mergeDomains(n.known.domains);return i!==void 0?o.domains=i:delete o.domains,w(o)}sessionChangedKey(e){return JSON.stringify(this.rootConfig[e])!==JSON.stringify(this.loadedSnapshot[e])}mergeDomains(e){const t=this.rootConfig.domains,n=this.loadedSnapshot.domains??[];if(t===void 0&&n.length===0)return e;const o=p(s=>s.toLowerCase(),"norm"),i=t??[],r=new Map(n.map(s=>[o(s.name),s])),c=new Map(i.map(s=>[o(s.name),s])),g=[],C=new Set;for(const s of e??[]){const h=o(s.name);C.add(h);const v=c.get(h),S=r.get(h);if(v!==void 0&&!k(v,S)){g.push(v);continue}v===void 0&&S!==void 0||g.push(s)}for(const s of i){const h=o(s.name);C.has(h)||k(s,r.get(h))||g.push(s)}return g}static readDiskConfigForMerge(e){if(!a.existsSync(e))return{kind:"absent"};let t;try{const i=a.readFileSync(e,{encoding:"utf8"});if(i==="")return{kind:"absent"};t=JSON.parse(i)}catch(i){return{kind:"unmergeable",reason:`the existing file could not be read or parsed as JSON (${y(E(i))})`}}const n=_.safeParse(t);if(!n.success){const i=n.error.issues.map(r=>`${r.path.join(".")}: ${r.message}`).join("; ");return{kind:"unmergeable",reason:`a recognised key in the existing file is malformed (${y(i)})`}}const o={};if(typeof t=="object"&&t!==null){const i=N;for(const[r,c]of Object.entries(t))i.includes(r)||(o[r]=c)}return{kind:"ok",disk:{known:n.data,foreign:o}}}static getConfigDirectory(e){return f.findConfigDirectory(e)}getConfigPath(){return this.configPath}isContentUnavailable(){return this.loadFailed||this.parseDegraded}static warnedLegacyActiveTarget=!1;localConfigCache;resolveProjectDirectory(){return this.configPath!==null?d.dirname(this.configPath):f.findConfigDirectory()}localConfigFile(){const e=this.resolveProjectDirectory();return e===null?null:d.join(e,x,M)}loadLocalConfig(){if(this.localConfigCache===void 0){const e=this.localConfigFile();if(e===null)return this.localConfigCache={};try{const t=a.readFileSync(e,{encoding:"utf8"}),n=P.safeParse(JSON.parse(t));this.localConfigCache=n.success?n.data:{}}catch{this.localConfigCache={}}}return this.localConfigCache}writeLocalConfig(e){const t=this.localConfigFile();if(t===null)return m(new Error("Cannot persist local state: no fjall-config.json was found from this directory, so there is no project to anchor `.fjall/local.json` to. Run this from inside a fjall project, or run `fjall create account` / `fjall create app` first."));try{a.mkdirSync(d.dirname(t),{recursive:!0});const n=`${t}.tmp-${process.pid}`;a.writeFileSync(n,JSON.stringify(e,null,2)+`
|
|
2
|
+
`,{encoding:"utf8"}),a.renameSync(n,t),I(d.dirname(d.dirname(t)),[b,...D],{header:R,marker:$})}catch(n){return m(new Error(`Failed to write ${t}: ${y(E(n))}`))}return this.localConfigCache=e,w(void 0)}static warnLegacyActiveTargetOnce(){f.warnedLegacyActiveTarget||(f.warnedLegacyActiveTarget=!0,O.warn("Config","`activeTarget` in fjall-config.json is deprecated and ignored: a committed target must never re-aim a deploy or CI pipeline. Run `fjall target set <name>` to store it locally in .fjall/local.json, then remove `activeTarget` from the committed fjall-config.json."))}getActiveTarget(){const e=this.loadLocalConfig().activeTarget;if(e!==void 0)return e;this.rootConfig.activeTarget!==void 0&&f.warnLegacyActiveTargetOnce()}setActiveTarget(e){const t=this.loadLocalConfig();return t.activeTarget=e,this.writeLocalConfig(t)}clearActiveTarget(){const e=this.loadLocalConfig();return delete e.activeTarget,this.writeLocalConfig(e)}getDomains(){return this.rootConfig.domains??[]}setDomains(e){this.rootConfig.domains=e}addDomain(e){this.rootConfig.domains||(this.rootConfig.domains=[]),this.rootConfig.domains.push(e)}getDomain(e){return this.rootConfig.domains?.find(t=>t.name.toLowerCase()===e.toLowerCase())}removeDomain(e){if(!this.rootConfig.domains)return!1;const t=this.rootConfig.domains.findIndex(n=>n.name.toLowerCase()===e.toLowerCase());return t===-1?!1:(this.rootConfig.domains.splice(t,1),!0)}}export{oe as ACCOUNT_TRAIL_NAME,ie as ACCOUNT_TRAIL_STATES,f as Config,j as DomainConfigSchema,de as LOCAL_CONFIG_DIRNAME,ge as LOCAL_CONFIG_FILENAME,re as ORGANISATION_TRAIL_NAME,ce as ORG_TRAIL_BUCKET_OUTPUT_KEY,te as ROOT_ACCESS_MANAGEMENT_MODES,ue as ROOT_CONFIG_FILENAME,_ as RootConfigReadSchema,L as RootConfigSchema,ee as S3_BPA_MODES,se as TRAIL_BUCKET_OUTPUT_KEY,ae as TRAIL_KEY_ARN_OUTPUT_KEY,ne as TRAIL_LIFECYCLE_STATES,Q as VAULT_LOCK_MODES,K as serialiseRootConfig};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filesystem names for Fjall project state.
|
|
3
|
+
*
|
|
4
|
+
* A dependency-free leaf module on purpose: the scaffold's ignore policy
|
|
5
|
+
* derives its entries from these constants, and `config.ts` consumes that
|
|
6
|
+
* policy when it writes local state. Declaring them here breaks what would
|
|
7
|
+
* otherwise be an import cycle between the two — one that fails at module
|
|
8
|
+
* init with a TDZ `ReferenceError`, not at typecheck.
|
|
9
|
+
*/
|
|
10
|
+
/** Committed project marker + anchor. Never gitignored: it carries `capacityIdentity`. */
|
|
11
|
+
export declare const ROOT_CONFIG_FILENAME = "fjall-config.json";
|
|
12
|
+
/**
|
|
13
|
+
* Local, NON-COMMITTED per-checkout state (`.fjall/local.json`, gitignored),
|
|
14
|
+
* co-located with fjall-config.json. Holds the developer's active deployment
|
|
15
|
+
* target: it lives here rather than in the committed fjall-config.json so a
|
|
16
|
+
* committed value can never silently re-aim someone else's deploy or a CI
|
|
17
|
+
* pipeline (the ci-deploy misdeploy fix). A legacy `activeTarget` in
|
|
18
|
+
* fjall-config.json is read only to warn-and-migrate, never to resolve a
|
|
19
|
+
* target.
|
|
20
|
+
*/
|
|
21
|
+
export declare const LOCAL_CONFIG_DIRNAME = ".fjall";
|
|
22
|
+
export declare const LOCAL_CONFIG_FILENAME = "local.json";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const o="fjall-config.json",O=".fjall",l="local.json";export{O as LOCAL_CONFIG_DIRNAME,l as LOCAL_CONFIG_FILENAME,o as ROOT_CONFIG_FILENAME};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The root of Fjall's per-user state — credentials, caches, journals, logs.
|
|
3
|
+
*
|
|
4
|
+
* A dependency-free leaf module, like its project-local sibling
|
|
5
|
+
* `configPaths.ts`. That one names state that lives beside a checkout; this
|
|
6
|
+
* one names state that lives beside the *operator*.
|
|
7
|
+
*
|
|
8
|
+
* ## Why this is a seam and not a constant
|
|
9
|
+
*
|
|
10
|
+
* `~/.fjall/auth.json` holds exactly one API key, so the CLI can be logged
|
|
11
|
+
* into exactly one organisation at a time. Anyone who works across two — a
|
|
12
|
+
* platform operator with a production org and a sandbox, an agency with a
|
|
13
|
+
* client per org, or us dogfooding a fresh signup against our own production
|
|
14
|
+
* account — has to overwrite the credential to switch, and overwrite it back
|
|
15
|
+
* to switch again. There is no verb for that and no warning when it happens:
|
|
16
|
+
* `login` simply replaces the file. Concurrent shells make it worse, because
|
|
17
|
+
* the second login silently re-aims the first shell's next command.
|
|
18
|
+
*
|
|
19
|
+
* `FJALL_CONFIG_DIR` makes the whole state root relocatable, so two
|
|
20
|
+
* organisations are two directories and a shell decides which one it is in:
|
|
21
|
+
*
|
|
22
|
+
* ```sh
|
|
23
|
+
* FJALL_CONFIG_DIR=~/.fjall-sandbox fjall login
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* It is deliberately the *root*, not a per-file override. Credentials, the
|
|
27
|
+
* connection cache, the org-config cache, the app-id cache and the drift
|
|
28
|
+
* journals are all keyed to one organisation; letting them be redirected
|
|
29
|
+
* independently would allow a coherent-looking mix of two.
|
|
30
|
+
*/
|
|
31
|
+
/** Env var relocating the whole state root. Absolute or relative to cwd. */
|
|
32
|
+
export declare const FJALL_CONFIG_DIR_ENV = "FJALL_CONFIG_DIR";
|
|
33
|
+
/** Directory name under `$HOME` when the env var is unset. */
|
|
34
|
+
export declare const FJALL_HOME_DIRNAME = ".fjall";
|
|
35
|
+
/**
|
|
36
|
+
* Absolute path to the state root.
|
|
37
|
+
*
|
|
38
|
+
* Resolved on every call rather than captured at module load: the env var is
|
|
39
|
+
* read by a command that may have been imported long before the process
|
|
40
|
+
* decided which organisation it is acting for, and a module-level `const`
|
|
41
|
+
* would freeze the answer at import time — which is exactly why the three
|
|
42
|
+
* caches that used to capture it could never have honoured an override.
|
|
43
|
+
*
|
|
44
|
+
* An empty value is treated as unset. Shells, CI runners and compose
|
|
45
|
+
* env-files all export `X=` freely, and a path is a *data* env var: the empty
|
|
46
|
+
* string is invalid input, not a request to write state into `/`.
|
|
47
|
+
*/
|
|
48
|
+
export declare function fjallHomeDir(): string;
|
|
49
|
+
/** A path inside the state root — `fjallStatePath("auth.json")`. */
|
|
50
|
+
export declare function fjallStatePath(...segments: string[]): string;
|
|
51
|
+
/**
|
|
52
|
+
* The credential file.
|
|
53
|
+
*
|
|
54
|
+
* Named here rather than at each reader because there are two of them in
|
|
55
|
+
* different packages — the CLI writes it on `login`, the MCP server reads it
|
|
56
|
+
* to answer a tool call — and they used to agree about the path only by
|
|
57
|
+
* coincidence, each joining `homedir()` with the same two string literals.
|
|
58
|
+
* Nothing would have failed at typecheck if one of them had moved.
|
|
59
|
+
*/
|
|
60
|
+
export declare const FJALL_CREDENTIALS_FILENAME = "auth.json";
|
|
61
|
+
export declare function fjallCredentialsPath(): string;
|
|
62
|
+
/**
|
|
63
|
+
* Env var relocating logs alone, without moving the rest of the state root.
|
|
64
|
+
*
|
|
65
|
+
* The narrower override, and it wins: logs are routinely redirected on their
|
|
66
|
+
* own — a CI artefact path, a tmpdir in tests — by someone who does not mean
|
|
67
|
+
* to move the credential alongside them.
|
|
68
|
+
*/
|
|
69
|
+
export declare const FJALL_LOG_DIR_ENV = "FJALL_LOG_DIR";
|
|
70
|
+
/**
|
|
71
|
+
* The log directory.
|
|
72
|
+
*
|
|
73
|
+
* Two packages write here — the CLI's file logger and the infrastructure
|
|
74
|
+
* package's validation JSONL — and they each used to re-implement this exact
|
|
75
|
+
* precedence. Nothing linked them: a change to one would have split the log
|
|
76
|
+
* stream in half with nothing failing at typecheck.
|
|
77
|
+
*/
|
|
78
|
+
export declare function fjallLogDir(): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var i=Object.defineProperty;var r=(o,f)=>i(o,"name",{value:f,configurable:!0});import{homedir as L}from"node:os";import{join as t,resolve as e}from"node:path";const u="FJALL_CONFIG_DIR",c=".fjall";function s(){const o=process.env[u];return o!==void 0&&o!==""?e(o):t(L(),c)}r(s,"fjallHomeDir");function n(...o){return t(s(),...o)}r(n,"fjallStatePath");const _="auth.json";function F(){return n(_)}r(F,"fjallCredentialsPath");const l="FJALL_LOG_DIR";function I(){const o=process.env[l];return o!==void 0&&o!==""?e(o):n("logs")}r(I,"fjallLogDir");export{u as FJALL_CONFIG_DIR_ENV,_ as FJALL_CREDENTIALS_FILENAME,c as FJALL_HOME_DIRNAME,l as FJALL_LOG_DIR_ENV,F as fjallCredentialsPath,s as fjallHomeDir,I as fjallLogDir,n as fjallStatePath};
|
package/dist/fsHelpers.d.ts
CHANGED
|
@@ -17,3 +17,12 @@ export interface AtomicWriteOptions {
|
|
|
17
17
|
* never a partial write.
|
|
18
18
|
*/
|
|
19
19
|
export declare function atomicWrite(filePath: string, contents: string | Uint8Array, options?: AtomicWriteOptions): void;
|
|
20
|
+
/**
|
|
21
|
+
* `atomicWrite` for callers already on the async fs API.
|
|
22
|
+
*
|
|
23
|
+
* Exists so async writers do not hand-roll their own tmp+rename: before it,
|
|
24
|
+
* three writers of the per-checkout state file each invented a different
|
|
25
|
+
* temp-name shape, and both the `.gitignore` rule and the destroy-time
|
|
26
|
+
* cleanup sweep were written against only one of them.
|
|
27
|
+
*/
|
|
28
|
+
export declare function atomicWriteAsync(filePath: string, contents: string | Uint8Array, options?: AtomicWriteOptions): Promise<void>;
|
package/dist/fsHelpers.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var s=Object.defineProperty;var c=(r,t)=>s(r,"name",{value:t,configurable:!0});import{access as u,constants as p,rename as y,unlink as f,writeFile as h}from"fs/promises";import{renameSync as w,unlinkSync as l,writeFileSync as E}from"node:fs";import{randomBytes as d}from"node:crypto";import{ATOMIC_TMP_SUFFIX as x}from"./atomicTempNaming.js";async function _(r){try{return await u(r,p.F_OK),!0}catch(t){if(t instanceof Error&&"code"in t&&t.code==="ENOENT")return!1;throw t}}c(_,"fileExists");function m(r){return`${r}.${d(6).toString("hex")}${x}`}c(m,"atomicTmpPath");function $(r,t,o={}){const n=m(r),e=o.mode??420;try{E(n,t,{mode:e}),w(n,r)}catch(a){try{l(n)}catch(i){o.onCleanupError?.(i)}throw a}}c($,"atomicWrite");async function k(r,t,o={}){const n=m(r),e=o.mode??420;try{await h(n,t,{mode:e}),await y(n,r)}catch(a){try{await f(n)}catch(i){o.onCleanupError?.(i)}throw a}}c(k,"atomicWriteAsync");export{$ as atomicWrite,k as atomicWriteAsync,_ as fileExists};
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export { CAPACITY_SLOT_PATTERN, CAPACITY_SLOT_MAX_LENGTH, DEFAULT_CAPACITY_SLOT,
|
|
|
8
8
|
export { findAccountNameCollision, type AccountNameCollision } from "./naming/accountNameCollision.js";
|
|
9
9
|
export { defaultConnectedAccountName, suffixedAccountName, REGION_SHORT_CODES, findTrailingRegionShortCode, regionSuffixRejectionMessage } from "./naming/connectedAccountName.js";
|
|
10
10
|
export { normaliseError, getErrorMessage, hasErrorCode, getErrorCode, getErrorStack, formatErrorString } from "./errorUtils.js";
|
|
11
|
+
export { FJALL_CONFIG_DIR_ENV, FJALL_CREDENTIALS_FILENAME, FJALL_HOME_DIRNAME, FJALL_LOG_DIR_ENV, fjallCredentialsPath, fjallHomeDir, fjallLogDir, fjallStatePath } from "./fjallHome.js";
|
|
11
12
|
export { singleton } from "./async/singleton.js";
|
|
12
13
|
export { DANGEROUS_ENV_VARS, filterDangerousEnvVars, MASKED_VALUE_MARKER, maskSensitiveOutput, parseShellArgs, REDACTED_KEY_SENTINEL, SCOPED_TOKEN_REGEX } from "./securityHelpers.js";
|
|
13
14
|
export { sleep } from "./async/sleep.js";
|
|
@@ -32,10 +33,13 @@ export { MIGRATION_SNAPSHOT_NAME_PREFIX, EXPECTED_SCHEMA_VERSION_ENV, EXPECTED_S
|
|
|
32
33
|
export { SCHEMA_GATE_EXIT, SCHEMA_GATE_EXIT_HINTS, schemaGateExitKind, type SchemaGateExitKind, type SchemaGateExitCode } from "./migration/schemaGateExit.js";
|
|
33
34
|
export { FJALL_SCHEMA_GATE_USER, FJALL_MAINTENANCE_USER, FJALL_CLICKHOUSE_USERS, type FjallClickHouseUser } from "./migration/clickhouseFrameworkUsers.js";
|
|
34
35
|
export { PHYSICAL_NAME_FALLBACK_PROPERTIES } from "./cfn/physicalNameProperties.js";
|
|
35
|
-
export { PATTERN_TYPE_VALUES, type PatternType, PATTERN_TYPES, isPatternType, type PatternArtefact, type PatternStackPlacement, type PatternDescriptor, PATTERN_REGISTRY, patternConstructId, DEPLOYABLE_PATTERN_TYPES, type OpenNextPatternType, OPENNEXT_PATTERN_TYPES, isOpenNextPatternType, STATIC_SITE_ROUTING_VALUES, type StaticSiteRouting } from "./patterns/patternTypes.js";
|
|
36
|
+
export { PATTERN_TYPE_VALUES, type PatternType, PATTERN_TYPES, isPatternType, type PatternArtefact, type PatternStackPlacement, type PatternDescriptor, PATTERN_REGISTRY, patternConstructId, DEPLOYABLE_PATTERN_TYPES, type OpenNextPatternType, OPENNEXT_PATTERN_TYPES, isOpenNextPatternType, STATIC_SITE_ROUTING_VALUES, type StaticSiteRouting, PATTERN_CREATE_INPUT_VALUES, type PatternCreateInput, PATTERN_CREATE_INPUT_FLAGS } from "./patterns/patternTypes.js";
|
|
37
|
+
export { FRAMEWORK_VALUES, type Framework, FRAMEWORKS, isFramework, type DeployablePatternType, type UndeployablePatternType, type PatternRecommendation, FRAMEWORK_PATTERN_RECOMMENDATIONS, recommendPatternForFramework, CREATABLE_FRAMEWORKS, requiredInputsForFramework } from "./patterns/frameworkPatterns.js";
|
|
36
38
|
export { DEFAULT_FORMS_FROM_LOCAL_PART, defaultFormsFromAddress, defaultFormsCorsOrigin, isAddressAtDomain } from "./patterns/staticSiteForms.js";
|
|
37
39
|
export { DEV_SUBSTRATE_PARAMS_SCHEMA_VERSION, DEV_SUBSTRATE_PARAMS_FILENAME, DevSubstrateSynthPropsSchema, type DevSubstrateSynthProps, DevSubstrateParamsSchema, type DevSubstrateParams } from "./devSubstrate/params.js";
|
|
38
40
|
export { DEV_SUBSTRATE_ENTRYPOINT_SOURCE } from "./devSubstrate/entrypoint.js";
|
|
39
41
|
export { BLESSED_CDK_TOOLCHAIN, type BlessedCdkToolchain } from "./cdkToolchain.js";
|
|
40
42
|
export { DEPLOYMENT_FAILURE_PHASES, DeploymentFailurePhaseSchema, type DeploymentFailurePhase, DEPLOYMENT_FAULT_ATTRIBUTIONS, DeploymentFaultAttributionSchema, type DeploymentFaultAttribution, DEPLOYMENT_FAILURE_PROVIDER_SOURCES, DeploymentFailureProviderSourceSchema, type DeploymentFailureProviderSource, DEPLOYMENT_FAILURE_CODE_PATTERN, DEPLOYMENT_FAILURE_SCHEMA_VERSION, DEPLOYMENT_FAILURE_LIMITS, DeploymentFailureAnalysisSchema, type DeploymentFailureAnalysis, DeploymentFailureProviderSchema, type DeploymentFailureProvider, DeploymentFailureResourceSchema, type DeploymentFailureResource, DeploymentFailureSchema, type DeploymentFailure, parseDeploymentFailure, DEPLOYMENT_FAILURE_DOCS_BASE_URL, deploymentFailureDocsUrl, DEPLOYMENT_FAULT_COPY, DEPLOYMENT_PROVIDER_LABELS, deriveErrorMessageFromFailure, toDeploymentFailureAnalysis } from "./failure/deploymentFailure.js";
|
|
41
43
|
export { extractErrorWindow, ERROR_WINDOW_CONTEXT_LINES, type ExtractErrorWindowOptions } from "./failure/extractErrorWindow.js";
|
|
44
|
+
export { FJALL_COMPONENT_GITIGNORE, FJALL_PROJECT_GITIGNORE, FJALL_STATE_GITIGNORE_ENTRIES, FJALL_MANAGED_STATE_DIR_ENTRIES, LOCAL_CONFIG_GITIGNORE_ENTRY } from "./scaffold/gitignore.js";
|
|
45
|
+
export { ensureGitignoreEntries } from "./scaffold/ensureGitignore.js";
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{DNS_APEX as r,getDomainExportNames as _,getDomainStackName as t,getDomainUsEast1CertificatesStackName as o,hostsExportPartName as S,serialiseHostsChunks as A,HOSTS_OUTPUT_MAX_BYTES as T,isManagedDomainBinding as a,DOMAIN_DEPLOY_DEFAULT_PHASE as N}from"./infra/domainExports.js";import{BACKUP_VAULT_NAME as n}from"./infra/backupVault.js";import{APPROVAL_TOKEN_OUTPUT_PREFIX as m,TOKEN_STDERR_PREFIX as O}from"./deploy/approvalTokenOutput.js";import{imageTagParameterName as P}from"./infra/imageTags.js";import{toPascalCase as s,toKebab as p,toValidDatabaseName as L,toScreamingSnake as D,capitalise as c,getSafeZoneName as M,accountConstructKey as f,hasAsciiStableConstructKey as U}from"./naming/caseConversion.js";import{albDnsExportName as u,albHostedZoneIdExportName as d,cdnDomainExportName as g,bucketWebsiteEndpointExportName as x,bucketWebsiteHostedZoneIdExportName as F}from"./naming/targetExportNames.js";import{CAPACITY_SLOT_PATTERN as G,CAPACITY_SLOT_MAX_LENGTH as H,DEFAULT_CAPACITY_SLOT as V,CAPACITY_ANCHOR_PATTERN as Y,CAPACITY_ANCHOR_MAX_LENGTH as y,CAPACITY_IDENTITY_CONTEXT_KEY as v,CapacityIdentityPinSchema as K,CapacityIdentityWireSchema as X,CapacityIdentityConfigSchema as b,projectCapacityIdentityToTarget as B}from"./capacityIdentity.js";import{findAccountNameCollision as k}from"./naming/accountNameCollision.js";import{defaultConnectedAccountName as Z,suffixedAccountName as j,REGION_SHORT_CODES as w,findTrailingRegionShortCode as z,regionSuffixRejectionMessage as Q}from"./naming/connectedAccountName.js";import{normaliseError as $,getErrorMessage as ee,hasErrorCode as Ee,getErrorCode as re,getErrorStack as _e,formatErrorString as te}from"./errorUtils.js";import{singleton as Se}from"./async/singleton.js";import{DANGEROUS_ENV_VARS as Te,filterDangerousEnvVars as ae,MASKED_VALUE_MARKER as Ne,maskSensitiveOutput as Re,parseShellArgs as ne,REDACTED_KEY_SENTINEL as ie,SCOPED_TOKEN_REGEX as me}from"./securityHelpers.js";import{sleep as Ce}from"./async/sleep.js";import{mapSettledWithConcurrency as Ie}from"./async/concurrency.js";import{ACCOUNT_STAGES_WITH_ROOT as pe,STRUCTURAL_ENVIRONMENTS as Le,ACCOUNT_STAGES as De,ACCOUNT_STAGE_LABELS as ce,isAccountStage as Me,ACCOUNT_TIERS as fe,AccountTierSchema as Ue,isAccountTier as le,GOVERNANCE_ACCOUNT_TIERS as ue,isGovernanceTier as de,environmentToTier as ge,stageFromWireEnvironment as xe,accountTier as Fe,resolveSynthEnvironment as he,getEnvironmentLabel as Ge,ACCOUNT_ROLES as He}from"./environments.js";import{RESOURCE_CATEGORIES as Ye,categoriseResource as ye,getExpectedDuration as ve,getFriendlyResourceType as Ke}from"./resourceCategorisation.js";import{parseGitRemoteUrl as be}from"./repo/gitRemoteParser.js";import{abbreviateRegion as We,AWS_REGIONS_METADATA as ke,DEFAULT_REGION as Je,getRegionInfo as Ze,MAX_SECONDARY_REGIONS as je,OPT_IN_REGION_CODES as we,optInRegionWarning as ze,regions as Qe,suggestRegionForTimezone as qe}from"./infra/regions.js";import{SCOPE_VALUES as eE,MACHINE_ONLY_SCOPES as EE,USER_GRANTABLE_SCOPES as rE,GOVERNANCE_SCOPE_REQUIRED_CODE as _E}from"./infra/tokenScopes.js";import{SECRET_NAME_PATTERN as oE,SECRET_NAME_ERROR as SE,SSM_COMPONENT_PATTERN as AE,SSM_COMPONENT_ERROR as TE,SSM_STANDARD_MAX_VALUE_BYTES as aE,SecretNamespaceSchema as NE,buildNamespaceParts as RE,buildParameterPath as nE,parseParameterPath as iE,isManageablePath as mE,parseDotEnv as OE,escapeDotEnvValue as CE}from"./secrets.js";import{ConnectionWireSchema as IE,ConnectionsListResponseSchema as sE,CONNECTION_PHASES as pE,CONNECTION_TERMINAL_FAILURE_PHASES as LE,CONNECTION_FAILURE_REASONS as DE,EXTERNAL_ID_PATTERN as cE}from"./infra/connectionsWire.js";import{PUBLIC_PACKAGE_NAME as fE,INSTALL_SOURCES as UE,SETUP_COMMANDS as lE,upgradeCommand as uE,SETUP_MODES as dE,SETUP_STEP_IDS as gE,SETUP_STEPS as xE,AGENT_SETUP_PROMPTS as FE,AGENT_INSTALL_COMMAND as hE,SKILL_INSTALL_SEGMENTS as GE,SKILL_INSTALL_FILENAME as HE,SKILL_INSTALL_PATH as VE}from"./onboarding/index.js";import{deriveRegionsFromOrgConfig as yE,deriveTargets as vE,deriveAllTargets as KE,environmentOrTier as XE,findTarget as bE,generateTargetName as BE}from"./targets.js";import{buildAppConfigPath as kE}from"./repo/appPath.js";import{findInfrastructurePaths as ZE,findBoundaryPath as jE,isInfrastructureFile as wE}from"./repo/findInfrastructurePaths.js";import{inferContainerFromCandidates as QE}from"./repo/inferContainerFromCandidates.js";import{RESERVED_APP_NAMES as $E,RESERVED_APP_NAME_MESSAGE as er,isReservedAppName as Er,RESERVED_APP_NAME_SUFFIX as rr,RESERVED_APP_NAME_SUFFIX_MESSAGE as _r,hasReservedAppNameSuffix as tr}from"./naming/reservedAppNames.js";import{deriveContentHashTag as Sr,CONTENT_HASH_TAG_PATTERN as Ar}from"./infra/deriveContentHashTag.js";import{DEPLOY_MODES as ar,DeployModeSchema as Nr,IMAGE_TAG_PATTERN as Rr,ImageTagSchema as nr,ServiceArtefactSchema as ir,ServiceArtefactsSchema as mr,ARTEFACT_OUTPUT_FIELDS as Or,artefactOutputKey as Cr}from"./infra/deployArtefacts.js";import{MIGRATION_SNAPSHOT_NAME_PREFIX as Ir,EXPECTED_SCHEMA_VERSION_ENV as sr,EXPECTED_SCHEMA_VERSION_TOOL_ENV as pr,EXPECTED_CH_SCHEMA_VERSION_ENV as Lr,SCHEMA_ADMIN_USER_ENV as Dr,SCHEMA_ADMIN_PASSWORD_ENV as cr,PRISMA_MIGRATION_DIR_RE as Mr,CLICKHOUSE_MIGRATION_SKIP_RE as fr}from"./migration/constants.js";import{SCHEMA_GATE_EXIT as lr,SCHEMA_GATE_EXIT_HINTS as ur,schemaGateExitKind as dr}from"./migration/schemaGateExit.js";import{FJALL_SCHEMA_GATE_USER as xr,FJALL_MAINTENANCE_USER as Fr,FJALL_CLICKHOUSE_USERS as hr}from"./migration/clickhouseFrameworkUsers.js";import{PHYSICAL_NAME_FALLBACK_PROPERTIES as Hr}from"./cfn/physicalNameProperties.js";import{PATTERN_TYPE_VALUES as Yr,PATTERN_TYPES as yr,isPatternType as vr,PATTERN_REGISTRY as Kr,patternConstructId as Xr,DEPLOYABLE_PATTERN_TYPES as br,OPENNEXT_PATTERN_TYPES as Br,isOpenNextPatternType as Wr,STATIC_SITE_ROUTING_VALUES as kr}from"./patterns/patternTypes.js";import{DEFAULT_FORMS_FROM_LOCAL_PART as Zr,defaultFormsFromAddress as jr,defaultFormsCorsOrigin as wr,isAddressAtDomain as zr}from"./patterns/staticSiteForms.js";import{DEV_SUBSTRATE_PARAMS_SCHEMA_VERSION as qr,DEV_SUBSTRATE_PARAMS_FILENAME as $r,DevSubstrateSynthPropsSchema as e_,DevSubstrateParamsSchema as E_}from"./devSubstrate/params.js";import{DEV_SUBSTRATE_ENTRYPOINT_SOURCE as __}from"./devSubstrate/entrypoint.js";import{BLESSED_CDK_TOOLCHAIN as o_}from"./cdkToolchain.js";import{DEPLOYMENT_FAILURE_PHASES as A_,DeploymentFailurePhaseSchema as T_,DEPLOYMENT_FAULT_ATTRIBUTIONS as a_,DeploymentFaultAttributionSchema as N_,DEPLOYMENT_FAILURE_PROVIDER_SOURCES as R_,DeploymentFailureProviderSourceSchema as n_,DEPLOYMENT_FAILURE_CODE_PATTERN as i_,DEPLOYMENT_FAILURE_SCHEMA_VERSION as m_,DEPLOYMENT_FAILURE_LIMITS as O_,DeploymentFailureAnalysisSchema as C_,DeploymentFailureProviderSchema as P_,DeploymentFailureResourceSchema as I_,DeploymentFailureSchema as s_,parseDeploymentFailure as p_,DEPLOYMENT_FAILURE_DOCS_BASE_URL as L_,deploymentFailureDocsUrl as D_,DEPLOYMENT_FAULT_COPY as c_,DEPLOYMENT_PROVIDER_LABELS as M_,deriveErrorMessageFromFailure as f_,toDeploymentFailureAnalysis as U_}from"./failure/deploymentFailure.js";import{extractErrorWindow as u_,ERROR_WINDOW_CONTEXT_LINES as d_}from"./failure/extractErrorWindow.js";export{He as ACCOUNT_ROLES,De as ACCOUNT_STAGES,pe as ACCOUNT_STAGES_WITH_ROOT,ce as ACCOUNT_STAGE_LABELS,fe as ACCOUNT_TIERS,hE as AGENT_INSTALL_COMMAND,FE as AGENT_SETUP_PROMPTS,m as APPROVAL_TOKEN_OUTPUT_PREFIX,Or as ARTEFACT_OUTPUT_FIELDS,ke as AWS_REGIONS_METADATA,Ue as AccountTierSchema,n as BACKUP_VAULT_NAME,o_ as BLESSED_CDK_TOOLCHAIN,y as CAPACITY_ANCHOR_MAX_LENGTH,Y as CAPACITY_ANCHOR_PATTERN,v as CAPACITY_IDENTITY_CONTEXT_KEY,H as CAPACITY_SLOT_MAX_LENGTH,G as CAPACITY_SLOT_PATTERN,fr as CLICKHOUSE_MIGRATION_SKIP_RE,DE as CONNECTION_FAILURE_REASONS,pE as CONNECTION_PHASES,LE as CONNECTION_TERMINAL_FAILURE_PHASES,Ar as CONTENT_HASH_TAG_PATTERN,b as CapacityIdentityConfigSchema,K as CapacityIdentityPinSchema,X as CapacityIdentityWireSchema,IE as ConnectionWireSchema,sE as ConnectionsListResponseSchema,Te as DANGEROUS_ENV_VARS,V as DEFAULT_CAPACITY_SLOT,Zr as DEFAULT_FORMS_FROM_LOCAL_PART,Je as DEFAULT_REGION,br as DEPLOYABLE_PATTERN_TYPES,i_ as DEPLOYMENT_FAILURE_CODE_PATTERN,L_ as DEPLOYMENT_FAILURE_DOCS_BASE_URL,O_ as DEPLOYMENT_FAILURE_LIMITS,A_ as DEPLOYMENT_FAILURE_PHASES,R_ as DEPLOYMENT_FAILURE_PROVIDER_SOURCES,m_ as DEPLOYMENT_FAILURE_SCHEMA_VERSION,a_ as DEPLOYMENT_FAULT_ATTRIBUTIONS,c_ as DEPLOYMENT_FAULT_COPY,M_ as DEPLOYMENT_PROVIDER_LABELS,ar as DEPLOY_MODES,__ as DEV_SUBSTRATE_ENTRYPOINT_SOURCE,$r as DEV_SUBSTRATE_PARAMS_FILENAME,qr as DEV_SUBSTRATE_PARAMS_SCHEMA_VERSION,r as DNS_APEX,N as DOMAIN_DEPLOY_DEFAULT_PHASE,Nr as DeployModeSchema,C_ as DeploymentFailureAnalysisSchema,T_ as DeploymentFailurePhaseSchema,P_ as DeploymentFailureProviderSchema,n_ as DeploymentFailureProviderSourceSchema,I_ as DeploymentFailureResourceSchema,s_ as DeploymentFailureSchema,N_ as DeploymentFaultAttributionSchema,E_ as DevSubstrateParamsSchema,e_ as DevSubstrateSynthPropsSchema,d_ as ERROR_WINDOW_CONTEXT_LINES,Lr as EXPECTED_CH_SCHEMA_VERSION_ENV,sr as EXPECTED_SCHEMA_VERSION_ENV,pr as EXPECTED_SCHEMA_VERSION_TOOL_ENV,cE as EXTERNAL_ID_PATTERN,hr as FJALL_CLICKHOUSE_USERS,Fr as FJALL_MAINTENANCE_USER,xr as FJALL_SCHEMA_GATE_USER,ue as GOVERNANCE_ACCOUNT_TIERS,_E as GOVERNANCE_SCOPE_REQUIRED_CODE,T as HOSTS_OUTPUT_MAX_BYTES,Rr as IMAGE_TAG_PATTERN,UE as INSTALL_SOURCES,nr as ImageTagSchema,EE as MACHINE_ONLY_SCOPES,Ne as MASKED_VALUE_MARKER,je as MAX_SECONDARY_REGIONS,Ir as MIGRATION_SNAPSHOT_NAME_PREFIX,Br as OPENNEXT_PATTERN_TYPES,we as OPT_IN_REGION_CODES,Kr as PATTERN_REGISTRY,yr as PATTERN_TYPES,Yr as PATTERN_TYPE_VALUES,Hr as PHYSICAL_NAME_FALLBACK_PROPERTIES,Mr as PRISMA_MIGRATION_DIR_RE,fE as PUBLIC_PACKAGE_NAME,ie as REDACTED_KEY_SENTINEL,w as REGION_SHORT_CODES,$E as RESERVED_APP_NAMES,er as RESERVED_APP_NAME_MESSAGE,rr as RESERVED_APP_NAME_SUFFIX,_r as RESERVED_APP_NAME_SUFFIX_MESSAGE,Ye as RESOURCE_CATEGORIES,cr as SCHEMA_ADMIN_PASSWORD_ENV,Dr as SCHEMA_ADMIN_USER_ENV,lr as SCHEMA_GATE_EXIT,ur as SCHEMA_GATE_EXIT_HINTS,me as SCOPED_TOKEN_REGEX,eE as SCOPE_VALUES,SE as SECRET_NAME_ERROR,oE as SECRET_NAME_PATTERN,lE as SETUP_COMMANDS,dE as SETUP_MODES,xE as SETUP_STEPS,gE as SETUP_STEP_IDS,HE as SKILL_INSTALL_FILENAME,VE as SKILL_INSTALL_PATH,GE as SKILL_INSTALL_SEGMENTS,TE as SSM_COMPONENT_ERROR,AE as SSM_COMPONENT_PATTERN,aE as SSM_STANDARD_MAX_VALUE_BYTES,kr as STATIC_SITE_ROUTING_VALUES,Le as STRUCTURAL_ENVIRONMENTS,NE as SecretNamespaceSchema,ir as ServiceArtefactSchema,mr as ServiceArtefactsSchema,O as TOKEN_STDERR_PREFIX,rE as USER_GRANTABLE_SCOPES,We as abbreviateRegion,f as accountConstructKey,Fe as accountTier,u as albDnsExportName,d as albHostedZoneIdExportName,Cr as artefactOutputKey,x as bucketWebsiteEndpointExportName,F as bucketWebsiteHostedZoneIdExportName,kE as buildAppConfigPath,RE as buildNamespaceParts,nE as buildParameterPath,c as capitalise,ye as categoriseResource,g as cdnDomainExportName,Z as defaultConnectedAccountName,wr as defaultFormsCorsOrigin,jr as defaultFormsFromAddress,D_ as deploymentFailureDocsUrl,KE as deriveAllTargets,Sr as deriveContentHashTag,f_ as deriveErrorMessageFromFailure,yE as deriveRegionsFromOrgConfig,vE as deriveTargets,XE as environmentOrTier,ge as environmentToTier,CE as escapeDotEnvValue,u_ as extractErrorWindow,ae as filterDangerousEnvVars,k as findAccountNameCollision,jE as findBoundaryPath,ZE as findInfrastructurePaths,bE as findTarget,z as findTrailingRegionShortCode,te as formatErrorString,BE as generateTargetName,_ as getDomainExportNames,t as getDomainStackName,o as getDomainUsEast1CertificatesStackName,Ge as getEnvironmentLabel,re as getErrorCode,ee as getErrorMessage,_e as getErrorStack,ve as getExpectedDuration,Ke as getFriendlyResourceType,Ze as getRegionInfo,M as getSafeZoneName,U as hasAsciiStableConstructKey,Ee as hasErrorCode,tr as hasReservedAppNameSuffix,S as hostsExportPartName,P as imageTagParameterName,QE as inferContainerFromCandidates,Me as isAccountStage,le as isAccountTier,zr as isAddressAtDomain,de as isGovernanceTier,wE as isInfrastructureFile,mE as isManageablePath,a as isManagedDomainBinding,Wr as isOpenNextPatternType,vr as isPatternType,Er as isReservedAppName,Ie as mapSettledWithConcurrency,Re as maskSensitiveOutput,$ as normaliseError,ze as optInRegionWarning,p_ as parseDeploymentFailure,OE as parseDotEnv,be as parseGitRemoteUrl,iE as parseParameterPath,ne as parseShellArgs,Xr as patternConstructId,B as projectCapacityIdentityToTarget,Q as regionSuffixRejectionMessage,Qe as regions,he as resolveSynthEnvironment,dr as schemaGateExitKind,A as serialiseHostsChunks,Se as singleton,Ce as sleep,xe as stageFromWireEnvironment,j as suffixedAccountName,qe as suggestRegionForTimezone,U_ as toDeploymentFailureAnalysis,p as toKebab,s as toPascalCase,D as toScreamingSnake,L as toValidDatabaseName,uE as upgradeCommand};
|
|
1
|
+
import{DNS_APEX as r,getDomainExportNames as _,getDomainStackName as o,getDomainUsEast1CertificatesStackName as t,hostsExportPartName as A,serialiseHostsChunks as T,HOSTS_OUTPUT_MAX_BYTES as S,isManagedDomainBinding as a,DOMAIN_DEPLOY_DEFAULT_PHASE as N}from"./infra/domainExports.js";import{BACKUP_VAULT_NAME as i}from"./infra/backupVault.js";import{APPROVAL_TOKEN_OUTPUT_PREFIX as O,TOKEN_STDERR_PREFIX as m}from"./deploy/approvalTokenOutput.js";import{imageTagParameterName as I}from"./infra/imageTags.js";import{toPascalCase as L,toKebab as s,toValidDatabaseName as p,toScreamingSnake as D,capitalise as M,getSafeZoneName as c,accountConstructKey as f,hasAsciiStableConstructKey as F}from"./naming/caseConversion.js";import{albDnsExportName as l,albHostedZoneIdExportName as u,cdnDomainExportName as d,bucketWebsiteEndpointExportName as x,bucketWebsiteHostedZoneIdExportName as g}from"./naming/targetExportNames.js";import{CAPACITY_SLOT_PATTERN as h,CAPACITY_SLOT_MAX_LENGTH as H,DEFAULT_CAPACITY_SLOT as V,CAPACITY_ANCHOR_PATTERN as Y,CAPACITY_ANCHOR_MAX_LENGTH as y,CAPACITY_IDENTITY_CONTEXT_KEY as K,CapacityIdentityPinSchema as v,CapacityIdentityWireSchema as X,CapacityIdentityConfigSchema as b,projectCapacityIdentityToTarget as B}from"./capacityIdentity.js";import{findAccountNameCollision as J}from"./naming/accountNameCollision.js";import{defaultConnectedAccountName as j,suffixedAccountName as w,REGION_SHORT_CODES as Z,findTrailingRegionShortCode as q,regionSuffixRejectionMessage as z}from"./naming/connectedAccountName.js";import{normaliseError as $,getErrorMessage as ee,hasErrorCode as Ee,getErrorCode as re,getErrorStack as _e,formatErrorString as oe}from"./errorUtils.js";import{FJALL_CONFIG_DIR_ENV as Ae,FJALL_CREDENTIALS_FILENAME as Te,FJALL_HOME_DIRNAME as Se,FJALL_LOG_DIR_ENV as ae,fjallCredentialsPath as Ne,fjallHomeDir as Re,fjallLogDir as ie,fjallStatePath as ne}from"./fjallHome.js";import{singleton as me}from"./async/singleton.js";import{DANGEROUS_ENV_VARS as Ie,filterDangerousEnvVars as Pe,MASKED_VALUE_MARKER as Le,maskSensitiveOutput as se,parseShellArgs as pe,REDACTED_KEY_SENTINEL as De,SCOPED_TOKEN_REGEX as Me}from"./securityHelpers.js";import{sleep as fe}from"./async/sleep.js";import{mapSettledWithConcurrency as Ue}from"./async/concurrency.js";import{ACCOUNT_STAGES_WITH_ROOT as ue,STRUCTURAL_ENVIRONMENTS as de,ACCOUNT_STAGES as xe,ACCOUNT_STAGE_LABELS as ge,isAccountStage as Ge,ACCOUNT_TIERS as he,AccountTierSchema as He,isAccountTier as Ve,GOVERNANCE_ACCOUNT_TIERS as Ye,isGovernanceTier as ye,environmentToTier as Ke,stageFromWireEnvironment as ve,accountTier as Xe,resolveSynthEnvironment as be,getEnvironmentLabel as Be,ACCOUNT_ROLES as We}from"./environments.js";import{RESOURCE_CATEGORIES as ke,categoriseResource as je,getExpectedDuration as we,getFriendlyResourceType as Ze}from"./resourceCategorisation.js";import{parseGitRemoteUrl as ze}from"./repo/gitRemoteParser.js";import{abbreviateRegion as $e,AWS_REGIONS_METADATA as eE,DEFAULT_REGION as EE,getRegionInfo as rE,MAX_SECONDARY_REGIONS as _E,OPT_IN_REGION_CODES as oE,optInRegionWarning as tE,regions as AE,suggestRegionForTimezone as TE}from"./infra/regions.js";import{SCOPE_VALUES as aE,MACHINE_ONLY_SCOPES as NE,USER_GRANTABLE_SCOPES as RE,GOVERNANCE_SCOPE_REQUIRED_CODE as iE}from"./infra/tokenScopes.js";import{SECRET_NAME_PATTERN as OE,SECRET_NAME_ERROR as mE,SSM_COMPONENT_PATTERN as CE,SSM_COMPONENT_ERROR as IE,SSM_STANDARD_MAX_VALUE_BYTES as PE,SecretNamespaceSchema as LE,buildNamespaceParts as sE,buildParameterPath as pE,parseParameterPath as DE,isManageablePath as ME,parseDotEnv as cE,escapeDotEnvValue as fE}from"./secrets.js";import{ConnectionWireSchema as UE,ConnectionsListResponseSchema as lE,CONNECTION_PHASES as uE,CONNECTION_TERMINAL_FAILURE_PHASES as dE,CONNECTION_FAILURE_REASONS as xE,EXTERNAL_ID_PATTERN as gE}from"./infra/connectionsWire.js";import{PUBLIC_PACKAGE_NAME as hE,INSTALL_SOURCES as HE,SETUP_COMMANDS as VE,upgradeCommand as YE,SETUP_MODES as yE,SETUP_STEP_IDS as KE,SETUP_STEPS as vE,AGENT_SETUP_PROMPTS as XE,AGENT_INSTALL_COMMAND as bE,SKILL_INSTALL_SEGMENTS as BE,SKILL_INSTALL_FILENAME as WE,SKILL_INSTALL_PATH as JE}from"./onboarding/index.js";import{deriveRegionsFromOrgConfig as jE,deriveTargets as wE,deriveAllTargets as ZE,environmentOrTier as qE,findTarget as zE,generateTargetName as QE}from"./targets.js";import{buildAppConfigPath as er}from"./repo/appPath.js";import{findInfrastructurePaths as rr,findBoundaryPath as _r,isInfrastructureFile as or}from"./repo/findInfrastructurePaths.js";import{inferContainerFromCandidates as Ar}from"./repo/inferContainerFromCandidates.js";import{RESERVED_APP_NAMES as Sr,RESERVED_APP_NAME_MESSAGE as ar,isReservedAppName as Nr,RESERVED_APP_NAME_SUFFIX as Rr,RESERVED_APP_NAME_SUFFIX_MESSAGE as ir,hasReservedAppNameSuffix as nr}from"./naming/reservedAppNames.js";import{deriveContentHashTag as mr,CONTENT_HASH_TAG_PATTERN as Cr}from"./infra/deriveContentHashTag.js";import{DEPLOY_MODES as Pr,DeployModeSchema as Lr,IMAGE_TAG_PATTERN as sr,ImageTagSchema as pr,ServiceArtefactSchema as Dr,ServiceArtefactsSchema as Mr,ARTEFACT_OUTPUT_FIELDS as cr,artefactOutputKey as fr}from"./infra/deployArtefacts.js";import{MIGRATION_SNAPSHOT_NAME_PREFIX as Ur,EXPECTED_SCHEMA_VERSION_ENV as lr,EXPECTED_SCHEMA_VERSION_TOOL_ENV as ur,EXPECTED_CH_SCHEMA_VERSION_ENV as dr,SCHEMA_ADMIN_USER_ENV as xr,SCHEMA_ADMIN_PASSWORD_ENV as gr,PRISMA_MIGRATION_DIR_RE as Gr,CLICKHOUSE_MIGRATION_SKIP_RE as hr}from"./migration/constants.js";import{SCHEMA_GATE_EXIT as Vr,SCHEMA_GATE_EXIT_HINTS as Yr,schemaGateExitKind as yr}from"./migration/schemaGateExit.js";import{FJALL_SCHEMA_GATE_USER as vr,FJALL_MAINTENANCE_USER as Xr,FJALL_CLICKHOUSE_USERS as br}from"./migration/clickhouseFrameworkUsers.js";import{PHYSICAL_NAME_FALLBACK_PROPERTIES as Wr}from"./cfn/physicalNameProperties.js";import{PATTERN_TYPE_VALUES as kr,PATTERN_TYPES as jr,isPatternType as wr,PATTERN_REGISTRY as Zr,patternConstructId as qr,DEPLOYABLE_PATTERN_TYPES as zr,OPENNEXT_PATTERN_TYPES as Qr,isOpenNextPatternType as $r,STATIC_SITE_ROUTING_VALUES as e_,PATTERN_CREATE_INPUT_VALUES as E_,PATTERN_CREATE_INPUT_FLAGS as r_}from"./patterns/patternTypes.js";import{FRAMEWORK_VALUES as o_,FRAMEWORKS as t_,isFramework as A_,FRAMEWORK_PATTERN_RECOMMENDATIONS as T_,recommendPatternForFramework as S_,CREATABLE_FRAMEWORKS as a_,requiredInputsForFramework as N_}from"./patterns/frameworkPatterns.js";import{DEFAULT_FORMS_FROM_LOCAL_PART as i_,defaultFormsFromAddress as n_,defaultFormsCorsOrigin as O_,isAddressAtDomain as m_}from"./patterns/staticSiteForms.js";import{DEV_SUBSTRATE_PARAMS_SCHEMA_VERSION as I_,DEV_SUBSTRATE_PARAMS_FILENAME as P_,DevSubstrateSynthPropsSchema as L_,DevSubstrateParamsSchema as s_}from"./devSubstrate/params.js";import{DEV_SUBSTRATE_ENTRYPOINT_SOURCE as D_}from"./devSubstrate/entrypoint.js";import{BLESSED_CDK_TOOLCHAIN as c_}from"./cdkToolchain.js";import{DEPLOYMENT_FAILURE_PHASES as F_,DeploymentFailurePhaseSchema as U_,DEPLOYMENT_FAULT_ATTRIBUTIONS as l_,DeploymentFaultAttributionSchema as u_,DEPLOYMENT_FAILURE_PROVIDER_SOURCES as d_,DeploymentFailureProviderSourceSchema as x_,DEPLOYMENT_FAILURE_CODE_PATTERN as g_,DEPLOYMENT_FAILURE_SCHEMA_VERSION as G_,DEPLOYMENT_FAILURE_LIMITS as h_,DeploymentFailureAnalysisSchema as H_,DeploymentFailureProviderSchema as V_,DeploymentFailureResourceSchema as Y_,DeploymentFailureSchema as y_,parseDeploymentFailure as K_,DEPLOYMENT_FAILURE_DOCS_BASE_URL as v_,deploymentFailureDocsUrl as X_,DEPLOYMENT_FAULT_COPY as b_,DEPLOYMENT_PROVIDER_LABELS as B_,deriveErrorMessageFromFailure as W_,toDeploymentFailureAnalysis as J_}from"./failure/deploymentFailure.js";import{extractErrorWindow as j_,ERROR_WINDOW_CONTEXT_LINES as w_}from"./failure/extractErrorWindow.js";import{FJALL_COMPONENT_GITIGNORE as q_,FJALL_PROJECT_GITIGNORE as z_,FJALL_STATE_GITIGNORE_ENTRIES as Q_,FJALL_MANAGED_STATE_DIR_ENTRIES as $_,LOCAL_CONFIG_GITIGNORE_ENTRY as eo}from"./scaffold/gitignore.js";import{ensureGitignoreEntries as ro}from"./scaffold/ensureGitignore.js";export{We as ACCOUNT_ROLES,xe as ACCOUNT_STAGES,ue as ACCOUNT_STAGES_WITH_ROOT,ge as ACCOUNT_STAGE_LABELS,he as ACCOUNT_TIERS,bE as AGENT_INSTALL_COMMAND,XE as AGENT_SETUP_PROMPTS,O as APPROVAL_TOKEN_OUTPUT_PREFIX,cr as ARTEFACT_OUTPUT_FIELDS,eE as AWS_REGIONS_METADATA,He as AccountTierSchema,i as BACKUP_VAULT_NAME,c_ as BLESSED_CDK_TOOLCHAIN,y as CAPACITY_ANCHOR_MAX_LENGTH,Y as CAPACITY_ANCHOR_PATTERN,K as CAPACITY_IDENTITY_CONTEXT_KEY,H as CAPACITY_SLOT_MAX_LENGTH,h as CAPACITY_SLOT_PATTERN,hr as CLICKHOUSE_MIGRATION_SKIP_RE,xE as CONNECTION_FAILURE_REASONS,uE as CONNECTION_PHASES,dE as CONNECTION_TERMINAL_FAILURE_PHASES,Cr as CONTENT_HASH_TAG_PATTERN,a_ as CREATABLE_FRAMEWORKS,b as CapacityIdentityConfigSchema,v as CapacityIdentityPinSchema,X as CapacityIdentityWireSchema,UE as ConnectionWireSchema,lE as ConnectionsListResponseSchema,Ie as DANGEROUS_ENV_VARS,V as DEFAULT_CAPACITY_SLOT,i_ as DEFAULT_FORMS_FROM_LOCAL_PART,EE as DEFAULT_REGION,zr as DEPLOYABLE_PATTERN_TYPES,g_ as DEPLOYMENT_FAILURE_CODE_PATTERN,v_ as DEPLOYMENT_FAILURE_DOCS_BASE_URL,h_ as DEPLOYMENT_FAILURE_LIMITS,F_ as DEPLOYMENT_FAILURE_PHASES,d_ as DEPLOYMENT_FAILURE_PROVIDER_SOURCES,G_ as DEPLOYMENT_FAILURE_SCHEMA_VERSION,l_ as DEPLOYMENT_FAULT_ATTRIBUTIONS,b_ as DEPLOYMENT_FAULT_COPY,B_ as DEPLOYMENT_PROVIDER_LABELS,Pr as DEPLOY_MODES,D_ as DEV_SUBSTRATE_ENTRYPOINT_SOURCE,P_ as DEV_SUBSTRATE_PARAMS_FILENAME,I_ as DEV_SUBSTRATE_PARAMS_SCHEMA_VERSION,r as DNS_APEX,N as DOMAIN_DEPLOY_DEFAULT_PHASE,Lr as DeployModeSchema,H_ as DeploymentFailureAnalysisSchema,U_ as DeploymentFailurePhaseSchema,V_ as DeploymentFailureProviderSchema,x_ as DeploymentFailureProviderSourceSchema,Y_ as DeploymentFailureResourceSchema,y_ as DeploymentFailureSchema,u_ as DeploymentFaultAttributionSchema,s_ as DevSubstrateParamsSchema,L_ as DevSubstrateSynthPropsSchema,w_ as ERROR_WINDOW_CONTEXT_LINES,dr as EXPECTED_CH_SCHEMA_VERSION_ENV,lr as EXPECTED_SCHEMA_VERSION_ENV,ur as EXPECTED_SCHEMA_VERSION_TOOL_ENV,gE as EXTERNAL_ID_PATTERN,br as FJALL_CLICKHOUSE_USERS,q_ as FJALL_COMPONENT_GITIGNORE,Ae as FJALL_CONFIG_DIR_ENV,Te as FJALL_CREDENTIALS_FILENAME,Se as FJALL_HOME_DIRNAME,ae as FJALL_LOG_DIR_ENV,Xr as FJALL_MAINTENANCE_USER,$_ as FJALL_MANAGED_STATE_DIR_ENTRIES,z_ as FJALL_PROJECT_GITIGNORE,vr as FJALL_SCHEMA_GATE_USER,Q_ as FJALL_STATE_GITIGNORE_ENTRIES,t_ as FRAMEWORKS,T_ as FRAMEWORK_PATTERN_RECOMMENDATIONS,o_ as FRAMEWORK_VALUES,Ye as GOVERNANCE_ACCOUNT_TIERS,iE as GOVERNANCE_SCOPE_REQUIRED_CODE,S as HOSTS_OUTPUT_MAX_BYTES,sr as IMAGE_TAG_PATTERN,HE as INSTALL_SOURCES,pr as ImageTagSchema,eo as LOCAL_CONFIG_GITIGNORE_ENTRY,NE as MACHINE_ONLY_SCOPES,Le as MASKED_VALUE_MARKER,_E as MAX_SECONDARY_REGIONS,Ur as MIGRATION_SNAPSHOT_NAME_PREFIX,Qr as OPENNEXT_PATTERN_TYPES,oE as OPT_IN_REGION_CODES,r_ as PATTERN_CREATE_INPUT_FLAGS,E_ as PATTERN_CREATE_INPUT_VALUES,Zr as PATTERN_REGISTRY,jr as PATTERN_TYPES,kr as PATTERN_TYPE_VALUES,Wr as PHYSICAL_NAME_FALLBACK_PROPERTIES,Gr as PRISMA_MIGRATION_DIR_RE,hE as PUBLIC_PACKAGE_NAME,De as REDACTED_KEY_SENTINEL,Z as REGION_SHORT_CODES,Sr as RESERVED_APP_NAMES,ar as RESERVED_APP_NAME_MESSAGE,Rr as RESERVED_APP_NAME_SUFFIX,ir as RESERVED_APP_NAME_SUFFIX_MESSAGE,ke as RESOURCE_CATEGORIES,gr as SCHEMA_ADMIN_PASSWORD_ENV,xr as SCHEMA_ADMIN_USER_ENV,Vr as SCHEMA_GATE_EXIT,Yr as SCHEMA_GATE_EXIT_HINTS,Me as SCOPED_TOKEN_REGEX,aE as SCOPE_VALUES,mE as SECRET_NAME_ERROR,OE as SECRET_NAME_PATTERN,VE as SETUP_COMMANDS,yE as SETUP_MODES,vE as SETUP_STEPS,KE as SETUP_STEP_IDS,WE as SKILL_INSTALL_FILENAME,JE as SKILL_INSTALL_PATH,BE as SKILL_INSTALL_SEGMENTS,IE as SSM_COMPONENT_ERROR,CE as SSM_COMPONENT_PATTERN,PE as SSM_STANDARD_MAX_VALUE_BYTES,e_ as STATIC_SITE_ROUTING_VALUES,de as STRUCTURAL_ENVIRONMENTS,LE as SecretNamespaceSchema,Dr as ServiceArtefactSchema,Mr as ServiceArtefactsSchema,m as TOKEN_STDERR_PREFIX,RE as USER_GRANTABLE_SCOPES,$e as abbreviateRegion,f as accountConstructKey,Xe as accountTier,l as albDnsExportName,u as albHostedZoneIdExportName,fr as artefactOutputKey,x as bucketWebsiteEndpointExportName,g as bucketWebsiteHostedZoneIdExportName,er as buildAppConfigPath,sE as buildNamespaceParts,pE as buildParameterPath,M as capitalise,je as categoriseResource,d as cdnDomainExportName,j as defaultConnectedAccountName,O_ as defaultFormsCorsOrigin,n_ as defaultFormsFromAddress,X_ as deploymentFailureDocsUrl,ZE as deriveAllTargets,mr as deriveContentHashTag,W_ as deriveErrorMessageFromFailure,jE as deriveRegionsFromOrgConfig,wE as deriveTargets,ro as ensureGitignoreEntries,qE as environmentOrTier,Ke as environmentToTier,fE as escapeDotEnvValue,j_ as extractErrorWindow,Pe as filterDangerousEnvVars,J as findAccountNameCollision,_r as findBoundaryPath,rr as findInfrastructurePaths,zE as findTarget,q as findTrailingRegionShortCode,Ne as fjallCredentialsPath,Re as fjallHomeDir,ie as fjallLogDir,ne as fjallStatePath,oe as formatErrorString,QE as generateTargetName,_ as getDomainExportNames,o as getDomainStackName,t as getDomainUsEast1CertificatesStackName,Be as getEnvironmentLabel,re as getErrorCode,ee as getErrorMessage,_e as getErrorStack,we as getExpectedDuration,Ze as getFriendlyResourceType,rE as getRegionInfo,c as getSafeZoneName,F as hasAsciiStableConstructKey,Ee as hasErrorCode,nr as hasReservedAppNameSuffix,A as hostsExportPartName,I as imageTagParameterName,Ar as inferContainerFromCandidates,Ge as isAccountStage,Ve as isAccountTier,m_ as isAddressAtDomain,A_ as isFramework,ye as isGovernanceTier,or as isInfrastructureFile,ME as isManageablePath,a as isManagedDomainBinding,$r as isOpenNextPatternType,wr as isPatternType,Nr as isReservedAppName,Ue as mapSettledWithConcurrency,se as maskSensitiveOutput,$ as normaliseError,tE as optInRegionWarning,K_ as parseDeploymentFailure,cE as parseDotEnv,ze as parseGitRemoteUrl,DE as parseParameterPath,pe as parseShellArgs,qr as patternConstructId,B as projectCapacityIdentityToTarget,S_ as recommendPatternForFramework,z as regionSuffixRejectionMessage,AE as regions,N_ as requiredInputsForFramework,be as resolveSynthEnvironment,yr as schemaGateExitKind,T as serialiseHostsChunks,me as singleton,fe as sleep,ve as stageFromWireEnvironment,w as suffixedAccountName,TE as suggestRegionForTimezone,J_ as toDeploymentFailureAnalysis,s as toKebab,L as toPascalCase,D as toScreamingSnake,p as toValidDatabaseName,YE as upgradeCommand};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Size-bounded log files: rotate `x.jsonl` -> `x.1.jsonl` -> … -> delete.
|
|
3
|
+
*
|
|
4
|
+
* Lives in `@fjall/util` because three packages write persistent logs into
|
|
5
|
+
* the same state root and only one of them had a bound. The CLI's logger
|
|
6
|
+
* owned this class privately; `components/infrastructure` could not reach
|
|
7
|
+
* it across the package boundary, so its validation log had no cap at all
|
|
8
|
+
* and grew to hundreds of megabytes on a developer machine over one release
|
|
9
|
+
* cycle. A rotation policy that only one of several writers can reach is
|
|
10
|
+
* not a policy.
|
|
11
|
+
*/
|
|
12
|
+
/** Construction options. */
|
|
13
|
+
export interface FileRotatorOptions {
|
|
14
|
+
maxFiles: number;
|
|
15
|
+
}
|
|
16
|
+
export declare class FileRotator {
|
|
17
|
+
private maxFiles;
|
|
18
|
+
constructor(options: FileRotatorOptions);
|
|
19
|
+
/**
|
|
20
|
+
* Check if a file needs rotation based on size
|
|
21
|
+
*/
|
|
22
|
+
needsRotation(filePath: string, maxFileSize: number): boolean;
|
|
23
|
+
/** Rotate log files: current -> .1 -> .2 -> delete oldest */
|
|
24
|
+
rotate(filePath: string): void;
|
|
25
|
+
/** Check if rotation is needed and perform it if so */
|
|
26
|
+
rotateIfNeeded(filePath: string, maxFileSize: number): boolean;
|
|
27
|
+
/** Get all rotated file paths for a given log file */
|
|
28
|
+
getRotatedFiles(filePath: string): string[];
|
|
29
|
+
/** Clean up all log files (main and rotated) */
|
|
30
|
+
cleanAll(filePath: string): void;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* The bound every Fjall log file shares.
|
|
34
|
+
*
|
|
35
|
+
* Coupled values: the CLI's `LOGGER_DEFAULTS` and the infrastructure
|
|
36
|
+
* validation log both derive from here, so a change to the retention budget
|
|
37
|
+
* cannot apply to one writer and silently miss the other.
|
|
38
|
+
*/
|
|
39
|
+
export declare const LOG_ROTATION_DEFAULTS: {
|
|
40
|
+
readonly MAX_FILE_SIZE: number;
|
|
41
|
+
readonly MAX_FILES: 5;
|
|
42
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var S=Object.defineProperty;var l=(u,t)=>S(u,"name",{value:t,configurable:!0});import{existsSync as o,renameSync as $,unlinkSync as d,statSync as h,mkdirSync as R}from"fs";import{dirname as x,basename as f,extname as F,join as i}from"path";class _{static{l(this,"FileRotator")}maxFiles;constructor(t){this.maxFiles=t.maxFiles}needsRotation(t,s){try{return o(t)?h(t).size>s:!1}catch{return!1}}rotate(t){try{const s=x(t);if(!o(s)){R(s,{recursive:!0});return}if(!o(t))return;const e=F(t),r=f(t,e),a=i(s,`${r}.${this.maxFiles-1}${e}`);o(a)&&d(a);for(let n=this.maxFiles-2;n>=1;n--){const m=i(s,`${r}.${n}${e}`),y=i(s,`${r}.${n+1}${e}`);o(m)&&$(m,y)}const c=i(s,`${r}.1${e}`);$(t,c)}catch{}}rotateIfNeeded(t,s){return this.needsRotation(t,s)?(this.rotate(t),!0):!1}getRotatedFiles(t){const s=[],e=x(t),r=F(t),a=f(t,r);o(t)&&s.push(t);for(let c=1;c<this.maxFiles;c++){const n=i(e,`${a}.${c}${r}`);if(o(n))s.push(n);else break}return s}cleanAll(t){const s=this.getRotatedFiles(t);for(const e of s)try{d(e)}catch{}}}const b={MAX_FILE_SIZE:10*1024*1024,MAX_FILES:5};export{_ as FileRotator,b as LOG_ROTATION_DEFAULTS};
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The framework vocabulary and its bridge to the pattern vocabulary.
|
|
3
|
+
*
|
|
4
|
+
* Detection answers "what did the author build this with?" (`Framework`).
|
|
5
|
+
* Creation asks "which shape does Fjall deploy?" (`PatternType`). Those are
|
|
6
|
+
* different questions with different membership, and until this module nothing
|
|
7
|
+
* joined them: `apps detect` reported `astro`, the agent skill told the agent to
|
|
8
|
+
* feed what detect reported straight into `--pattern`, and `--pattern astro`
|
|
9
|
+
* reached `PATTERN_REGISTRY[...]` as an unchecked index and threw a `TypeError`
|
|
10
|
+
* that surfaced to the agent as `code: UNKNOWN`. Five of the seven framework
|
|
11
|
+
* values had no pattern at all; the join existed only in the skill's prose.
|
|
12
|
+
*
|
|
13
|
+
* `FRAMEWORK_PATTERN_RECOMMENDATIONS` is the compiler's checklist for that
|
|
14
|
+
* join. It is a `Record<Framework, PatternRecommendation>`, so an eighth
|
|
15
|
+
* framework fails to compile until someone states what it means for
|
|
16
|
+
* `--pattern` — the same discipline `PATTERN_REGISTRY` applies to patterns.
|
|
17
|
+
*
|
|
18
|
+
* The three verdicts are deliberately distinct, because they are three
|
|
19
|
+
* different instructions to hand an agent mid-onboarding:
|
|
20
|
+
*
|
|
21
|
+
* - `recommended` — a deployable pattern fits; proceed with it.
|
|
22
|
+
* - `blocked` — the pattern exists but cannot deploy yet; stop, and say why.
|
|
23
|
+
* - `unsupported` — no pattern shape fits this framework; stop, and say so.
|
|
24
|
+
*
|
|
25
|
+
* `recommended` and `blocked` are separated at the *type* level rather than by
|
|
26
|
+
* author discipline: their `pattern` fields are mapped types filtered on the
|
|
27
|
+
* registry's own `deployable` flag, in the same idiom as `OpenNextPatternType`.
|
|
28
|
+
* Flipping `nextjs` to `deployable: true` makes `UndeployablePatternType`
|
|
29
|
+
* uninhabited and breaks the `blocked` entry, forcing it to be moved rather
|
|
30
|
+
* than left behind as a lie. The reverse holds too: a pattern that loses its
|
|
31
|
+
* construct cannot stay in `recommended`.
|
|
32
|
+
*/
|
|
33
|
+
import { PATTERN_REGISTRY, type PatternType, type PatternCreateInput } from "./patternTypes.js";
|
|
34
|
+
/**
|
|
35
|
+
* Every framework the detector can name.
|
|
36
|
+
*
|
|
37
|
+
* This vocabulary lives here rather than in `@fjall/generator` because the
|
|
38
|
+
* bridge below needs both halves in one place, and `generator` already depends
|
|
39
|
+
* on `@fjall/util` (never the reverse). `generator/src/detection` re-exports
|
|
40
|
+
* these names and builds the Zod schema over them, exactly as it already does
|
|
41
|
+
* for `STATIC_SITE_ROUTING_VALUES`.
|
|
42
|
+
*
|
|
43
|
+
* - `nextjs+payload` is a strict superset of both its parts and must be
|
|
44
|
+
* matched before either: Payload v3 ships as a Next.js plugin, so both
|
|
45
|
+
* dependencies appear in a Payload app.
|
|
46
|
+
* - `unknown` is a real member, not an absence — a repository with a parseable
|
|
47
|
+
* `package.json` and no recognised signal is still a detection result.
|
|
48
|
+
*/
|
|
49
|
+
export declare const FRAMEWORK_VALUES: readonly ["nextjs", "payload", "nextjs+payload", "express", "remix", "astro", "unknown"];
|
|
50
|
+
export type Framework = (typeof FRAMEWORK_VALUES)[number];
|
|
51
|
+
export declare const FRAMEWORKS: ReadonlySet<string>;
|
|
52
|
+
export declare function isFramework(value: unknown): value is Framework;
|
|
53
|
+
/**
|
|
54
|
+
* The patterns that can deploy end-to-end, derived from the registry's own
|
|
55
|
+
* flag at the type level. `DEPLOYABLE_PATTERN_TYPES` is the value-level twin.
|
|
56
|
+
*/
|
|
57
|
+
export type DeployablePatternType = {
|
|
58
|
+
[K in PatternType]: (typeof PATTERN_REGISTRY)[K]["deployable"] extends true ? K : never;
|
|
59
|
+
}[PatternType];
|
|
60
|
+
/**
|
|
61
|
+
* The patterns the generator knows but cannot yet synthesise. Uninhabited once
|
|
62
|
+
* every pattern is deployable — at which point the `blocked` verdict below
|
|
63
|
+
* stops compiling, which is the intended signal, not a defect.
|
|
64
|
+
*/
|
|
65
|
+
export type UndeployablePatternType = {
|
|
66
|
+
[K in PatternType]: (typeof PATTERN_REGISTRY)[K]["deployable"] extends false ? K : never;
|
|
67
|
+
}[PatternType];
|
|
68
|
+
/**
|
|
69
|
+
* What a detected framework means for `--pattern`.
|
|
70
|
+
*
|
|
71
|
+
* Every arm carries prose because every arm is read aloud to a user by an
|
|
72
|
+
* agent. A verdict an agent cannot explain is a verdict it will second-guess,
|
|
73
|
+
* and second-guessing is what the "do not infer the pattern" instruction in the
|
|
74
|
+
* skill exists to prevent.
|
|
75
|
+
*/
|
|
76
|
+
export type PatternRecommendation = {
|
|
77
|
+
readonly kind: "recommended";
|
|
78
|
+
/** Constrained to deployable patterns by the registry's own flag. */
|
|
79
|
+
readonly pattern: DeployablePatternType;
|
|
80
|
+
/** Why this pattern fits, in the agent's own words to the user. */
|
|
81
|
+
readonly rationale: string;
|
|
82
|
+
} | {
|
|
83
|
+
readonly kind: "blocked";
|
|
84
|
+
/** Constrained to patterns the registry marks undeployable. */
|
|
85
|
+
readonly pattern: UndeployablePatternType;
|
|
86
|
+
/** What is missing, so the agent can say more than "no". */
|
|
87
|
+
readonly reason: string;
|
|
88
|
+
} | {
|
|
89
|
+
readonly kind: "unsupported";
|
|
90
|
+
/** Why no pattern fits this framework's shape. */
|
|
91
|
+
readonly reason: string;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* The framework → pattern join.
|
|
95
|
+
*
|
|
96
|
+
* This is the *evidence-free* verdict: it knows only the framework name. A
|
|
97
|
+
* detector holding more evidence (an Astro config declaring `output: "server"`,
|
|
98
|
+
* say) returns the same union with a different arm — that is a refinement of
|
|
99
|
+
* one contract, not a second framing path.
|
|
100
|
+
*/
|
|
101
|
+
export declare const FRAMEWORK_PATTERN_RECOMMENDATIONS: {
|
|
102
|
+
readonly astro: {
|
|
103
|
+
readonly kind: "recommended";
|
|
104
|
+
readonly pattern: "staticsite";
|
|
105
|
+
readonly rationale: "Astro builds to a directory of static assets, which is what the static-site pattern serves from S3 behind CloudFront.";
|
|
106
|
+
};
|
|
107
|
+
readonly payload: {
|
|
108
|
+
readonly kind: "recommended";
|
|
109
|
+
readonly pattern: "payload";
|
|
110
|
+
readonly rationale: "Payload CMS runs on OpenNext with a database and migrations, which the payload pattern provisions.";
|
|
111
|
+
};
|
|
112
|
+
readonly "nextjs+payload": {
|
|
113
|
+
readonly kind: "recommended";
|
|
114
|
+
readonly pattern: "payload";
|
|
115
|
+
readonly rationale: "Payload v3 ships as a Next.js plugin, so a repository carrying both dependencies is a Payload application and deploys as one.";
|
|
116
|
+
};
|
|
117
|
+
readonly nextjs: {
|
|
118
|
+
readonly kind: "blocked";
|
|
119
|
+
readonly pattern: "nextjs";
|
|
120
|
+
readonly reason: "The Next.js pattern has no CDK construct yet — IPatternProps omits it, so a generated app fails at synthesis. Deploy a Payload application, or supply a static export with --pattern staticsite.";
|
|
121
|
+
};
|
|
122
|
+
readonly remix: {
|
|
123
|
+
readonly kind: "unsupported";
|
|
124
|
+
readonly reason: "Remix serves from a Node server at request time; Fjall has no server-rendering pattern beyond OpenNext, and no static-export path from Remix.";
|
|
125
|
+
};
|
|
126
|
+
readonly express: {
|
|
127
|
+
readonly kind: "unsupported";
|
|
128
|
+
readonly reason: "Express is a long-running HTTP server. Fjall's patterns cover OpenNext applications and pre-built static sites; neither shape fits.";
|
|
129
|
+
};
|
|
130
|
+
readonly unknown: {
|
|
131
|
+
readonly kind: "unsupported";
|
|
132
|
+
readonly reason: "No framework signal was found in package.json. If this is a pre-built static site, pass --pattern staticsite explicitly with --source, --build-command and --output-dir.";
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* The evidence-free verdict for a framework. Total by construction — there is
|
|
137
|
+
* no undefined branch to guard, which is the whole point of the record above.
|
|
138
|
+
*/
|
|
139
|
+
export declare function recommendPatternForFramework(framework: Framework): PatternRecommendation;
|
|
140
|
+
/**
|
|
141
|
+
* The frameworks an agent can carry all the way to a deploy today, derived
|
|
142
|
+
* from the table rather than restated. Used by the skill's vocabulary block so
|
|
143
|
+
* its prose cannot drift from the join.
|
|
144
|
+
*/
|
|
145
|
+
export declare const CREATABLE_FRAMEWORKS: readonly Framework[];
|
|
146
|
+
/**
|
|
147
|
+
* The inputs a framework's recommended pattern still needs from the caller.
|
|
148
|
+
* Empty for anything not `recommended` — there is nothing to collect for a
|
|
149
|
+
* pattern that cannot be created.
|
|
150
|
+
*/
|
|
151
|
+
export declare function requiredInputsForFramework(framework: Framework): readonly PatternCreateInput[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var o=Object.defineProperty;var a=(e,t)=>o(e,"name",{value:t,configurable:!0});import{PATTERN_REGISTRY as s}from"./patternTypes.js";const r=["nextjs","payload","nextjs+payload","express","remix","astro","unknown"],i=new Set(r);function c(e){return typeof e=="string"&&i.has(e)}a(c,"isFramework");const n={astro:{kind:"recommended",pattern:"staticsite",rationale:"Astro builds to a directory of static assets, which is what the static-site pattern serves from S3 behind CloudFront."},payload:{kind:"recommended",pattern:"payload",rationale:"Payload CMS runs on OpenNext with a database and migrations, which the payload pattern provisions."},"nextjs+payload":{kind:"recommended",pattern:"payload",rationale:"Payload v3 ships as a Next.js plugin, so a repository carrying both dependencies is a Payload application and deploys as one."},nextjs:{kind:"blocked",pattern:"nextjs",reason:"The Next.js pattern has no CDK construct yet \u2014 IPatternProps omits it, so a generated app fails at synthesis. Deploy a Payload application, or supply a static export with --pattern staticsite."},remix:{kind:"unsupported",reason:"Remix serves from a Node server at request time; Fjall has no server-rendering pattern beyond OpenNext, and no static-export path from Remix."},express:{kind:"unsupported",reason:"Express is a long-running HTTP server. Fjall's patterns cover OpenNext applications and pre-built static sites; neither shape fits."},unknown:{kind:"unsupported",reason:"No framework signal was found in package.json. If this is a pre-built static site, pass --pattern staticsite explicitly with --source, --build-command and --output-dir."}};function l(e){return n[e]}a(l,"recommendPatternForFramework");const m=r.filter(e=>n[e].kind==="recommended");function u(e){const t=n[e];return t.kind==="recommended"?s[t.pattern].requiredCreateInputs:[]}a(u,"requiredInputsForFramework");export{m as CREATABLE_FRAMEWORKS,i as FRAMEWORKS,n as FRAMEWORK_PATTERN_RECOMMENDATIONS,r as FRAMEWORK_VALUES,c as isFramework,l as recommendPatternForFramework,u as requiredInputsForFramework};
|
package/dist/patterns/index.d.ts
CHANGED
|
@@ -7,5 +7,6 @@
|
|
|
7
7
|
* the webapp bundles) can take the vocabulary without depending on the root
|
|
8
8
|
* barrel's contents staying pure.
|
|
9
9
|
*/
|
|
10
|
-
export { PATTERN_TYPE_VALUES, type PatternType, PATTERN_TYPES, isPatternType, type PatternArtefact, type PatternStackPlacement, type PatternDescriptor, PATTERN_REGISTRY, patternConstructId, DEPLOYABLE_PATTERN_TYPES, type OpenNextPatternType, OPENNEXT_PATTERN_TYPES, isOpenNextPatternType, STATIC_SITE_ROUTING_VALUES, type StaticSiteRouting } from "./patternTypes.js";
|
|
10
|
+
export { PATTERN_TYPE_VALUES, type PatternType, PATTERN_TYPES, isPatternType, type PatternArtefact, type PatternStackPlacement, type PatternDescriptor, PATTERN_REGISTRY, patternConstructId, DEPLOYABLE_PATTERN_TYPES, type OpenNextPatternType, OPENNEXT_PATTERN_TYPES, isOpenNextPatternType, STATIC_SITE_ROUTING_VALUES, type StaticSiteRouting, PATTERN_CREATE_INPUT_VALUES, type PatternCreateInput, PATTERN_CREATE_INPUT_FLAGS } from "./patternTypes.js";
|
|
11
|
+
export { FRAMEWORK_VALUES, type Framework, FRAMEWORKS, isFramework, type DeployablePatternType, type UndeployablePatternType, type PatternRecommendation, FRAMEWORK_PATTERN_RECOMMENDATIONS, recommendPatternForFramework, CREATABLE_FRAMEWORKS, requiredInputsForFramework } from "./frameworkPatterns.js";
|
|
11
12
|
export { DEFAULT_FORMS_FROM_LOCAL_PART, defaultFormsFromAddress, defaultFormsCorsOrigin, isAddressAtDomain } from "./staticSiteForms.js";
|
package/dist/patterns/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{PATTERN_TYPE_VALUES as
|
|
1
|
+
import{PATTERN_TYPE_VALUES as A,PATTERN_TYPES as r,isPatternType as R,PATTERN_REGISTRY as _,patternConstructId as e,DEPLOYABLE_PATTERN_TYPES as P,OPENNEXT_PATTERN_TYPES as o,isOpenNextPatternType as t,STATIC_SITE_ROUTING_VALUES as F,PATTERN_CREATE_INPUT_VALUES as N,PATTERN_CREATE_INPUT_FLAGS as S}from"./patternTypes.js";import{FRAMEWORK_VALUES as s,FRAMEWORKS as m,isFramework as L,FRAMEWORK_PATTERN_RECOMMENDATIONS as a,recommendPatternForFramework as n,CREATABLE_FRAMEWORKS as d,requiredInputsForFramework as I}from"./frameworkPatterns.js";import{DEFAULT_FORMS_FROM_LOCAL_PART as p,defaultFormsFromAddress as C,defaultFormsCorsOrigin as M,isAddressAtDomain as U}from"./staticSiteForms.js";export{d as CREATABLE_FRAMEWORKS,p as DEFAULT_FORMS_FROM_LOCAL_PART,P as DEPLOYABLE_PATTERN_TYPES,m as FRAMEWORKS,a as FRAMEWORK_PATTERN_RECOMMENDATIONS,s as FRAMEWORK_VALUES,o as OPENNEXT_PATTERN_TYPES,S as PATTERN_CREATE_INPUT_FLAGS,N as PATTERN_CREATE_INPUT_VALUES,_ as PATTERN_REGISTRY,r as PATTERN_TYPES,A as PATTERN_TYPE_VALUES,F as STATIC_SITE_ROUTING_VALUES,M as defaultFormsCorsOrigin,C as defaultFormsFromAddress,U as isAddressAtDomain,L as isFramework,t as isOpenNextPatternType,R as isPatternType,e as patternConstructId,n as recommendPatternForFramework,I as requiredInputsForFramework};
|
|
@@ -31,6 +31,26 @@ export type PatternArtefact = "opennext-lambda" | "static-assets";
|
|
|
31
31
|
* Lambda (and usually a database) and belong in the compute stack.
|
|
32
32
|
*/
|
|
33
33
|
export type PatternStackPlacement = "compute" | "cdn";
|
|
34
|
+
/**
|
|
35
|
+
* Create-time inputs a pattern cannot invent for itself.
|
|
36
|
+
*
|
|
37
|
+
* A static site is built from someone else's repository, so Fjall cannot guess
|
|
38
|
+
* where the sources live, how they build, or which directory to upload — get
|
|
39
|
+
* `outputDir` wrong and the deploy succeeds onto an empty bucket. Declaring the
|
|
40
|
+
* set here rather than in the create handler's control flow is what lets the
|
|
41
|
+
* CLI refuse the command with a list of missing flags instead of surfacing a
|
|
42
|
+
* raw Zod issue array, and lets `apps detect` prefill exactly the values the
|
|
43
|
+
* chosen pattern will be asked for.
|
|
44
|
+
*/
|
|
45
|
+
export declare const PATTERN_CREATE_INPUT_VALUES: readonly ["source", "buildCommand", "outputDir"];
|
|
46
|
+
export type PatternCreateInput = (typeof PATTERN_CREATE_INPUT_VALUES)[number];
|
|
47
|
+
/** The CLI flag each input arrives on. Kept beside the vocabulary so error
|
|
48
|
+
* messages name a flag the user can actually type. */
|
|
49
|
+
export declare const PATTERN_CREATE_INPUT_FLAGS: {
|
|
50
|
+
readonly source: "--source";
|
|
51
|
+
readonly buildCommand: "--build-command";
|
|
52
|
+
readonly outputDir: "--output-dir";
|
|
53
|
+
};
|
|
34
54
|
export interface PatternDescriptor {
|
|
35
55
|
/** Human-facing name, used by the CLI picker and progress output. */
|
|
36
56
|
readonly label: string;
|
|
@@ -48,6 +68,12 @@ export interface PatternDescriptor {
|
|
|
48
68
|
* adding the construct.
|
|
49
69
|
*/
|
|
50
70
|
readonly deployable: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Inputs the caller must supply for this pattern; the create flow refuses
|
|
73
|
+
* the command when any are absent. Empty for patterns whose scaffold is
|
|
74
|
+
* generated wholesale and therefore knows its own layout.
|
|
75
|
+
*/
|
|
76
|
+
readonly requiredCreateInputs: readonly PatternCreateInput[];
|
|
51
77
|
}
|
|
52
78
|
export declare const PATTERN_REGISTRY: {
|
|
53
79
|
readonly payload: {
|
|
@@ -56,6 +82,7 @@ export declare const PATTERN_REGISTRY: {
|
|
|
56
82
|
readonly artefact: "opennext-lambda";
|
|
57
83
|
readonly stackPlacement: "compute";
|
|
58
84
|
readonly deployable: true;
|
|
85
|
+
readonly requiredCreateInputs: readonly [];
|
|
59
86
|
};
|
|
60
87
|
readonly nextjs: {
|
|
61
88
|
readonly label: "Next.js";
|
|
@@ -63,6 +90,7 @@ export declare const PATTERN_REGISTRY: {
|
|
|
63
90
|
readonly artefact: "opennext-lambda";
|
|
64
91
|
readonly stackPlacement: "compute";
|
|
65
92
|
readonly deployable: false;
|
|
93
|
+
readonly requiredCreateInputs: readonly [];
|
|
66
94
|
};
|
|
67
95
|
readonly staticsite: {
|
|
68
96
|
readonly label: "Static site";
|
|
@@ -70,6 +98,7 @@ export declare const PATTERN_REGISTRY: {
|
|
|
70
98
|
readonly artefact: "static-assets";
|
|
71
99
|
readonly stackPlacement: "cdn";
|
|
72
100
|
readonly deployable: true;
|
|
101
|
+
readonly requiredCreateInputs: readonly ["source", "buildCommand", "outputDir"];
|
|
73
102
|
};
|
|
74
103
|
};
|
|
75
104
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var n=Object.defineProperty;var e=(t,o)=>n(t,"name",{value:o,configurable:!0});import{toPascalCase as s}from"../naming/caseConversion.js";const a=["payload","nextjs","staticsite"],c=new Set(a);function l(t){return typeof t=="string"&&c.has(t)}e(l,"isPatternType");const d=["source","buildCommand","outputDir"],E={source:"--source",buildCommand:"--build-command",outputDir:"--output-dir"},r={payload:{label:"Payload CMS",constructIdSuffix:"Payload",artefact:"opennext-lambda",stackPlacement:"compute",deployable:!0,requiredCreateInputs:[]},nextjs:{label:"Next.js",constructIdSuffix:"Nextjs",artefact:"opennext-lambda",stackPlacement:"compute",deployable:!1,requiredCreateInputs:[]},staticsite:{label:"Static site",constructIdSuffix:"StaticSite",artefact:"static-assets",stackPlacement:"cdn",deployable:!0,requiredCreateInputs:["source","buildCommand","outputDir"]}};function P(t,o){return`${s(t)}${r[o].constructIdSuffix}`}e(P,"patternConstructId");const x=a.filter(t=>r[t].deployable),u=a.filter(t=>r[t].artefact==="opennext-lambda"),p=new Set(u);function f(t){return t!=null&&p.has(t)}e(f,"isOpenNextPatternType");const S=["multipage","spa"];export{x as DEPLOYABLE_PATTERN_TYPES,u as OPENNEXT_PATTERN_TYPES,E as PATTERN_CREATE_INPUT_FLAGS,d as PATTERN_CREATE_INPUT_VALUES,r as PATTERN_REGISTRY,c as PATTERN_TYPES,a as PATTERN_TYPE_VALUES,S as STATIC_SITE_ROUTING_VALUES,f as isOpenNextPatternType,l as isPatternType,P as patternConstructId};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Idempotently guarantee that a `.gitignore` in `directory` carries `entries`.
|
|
3
|
+
*
|
|
4
|
+
* Absent file → written with `header` followed by the entries. Existing file →
|
|
5
|
+
* only the missing entries are appended, under `marker` so the addition is
|
|
6
|
+
* attributable. An entry already present anywhere in the file (at any
|
|
7
|
+
* indentation) is left alone, so repeat calls are no-ops.
|
|
8
|
+
*
|
|
9
|
+
* Best-effort by design: this maintains repository hygiene, never correctness.
|
|
10
|
+
* The caller's real work — writing config or recording deploy state — must not
|
|
11
|
+
* fail because a `.gitignore` could not be written (read-only checkout, no
|
|
12
|
+
* repository at all, permissions). Returns whether the file now provably
|
|
13
|
+
* carries every entry, for callers that want to assert or log.
|
|
14
|
+
*/
|
|
15
|
+
export declare function ensureGitignoreEntries(directory: string, entries: readonly string[], options: {
|
|
16
|
+
header?: string;
|
|
17
|
+
marker: string;
|
|
18
|
+
}): boolean;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
var d=Object.defineProperty;var u=(o,e)=>d(o,"name",{value:e,configurable:!0});import i from"fs";import g from"path";function l(o,e,s){const t=g.join(o,".gitignore");try{const r=i.existsSync(t)?i.readFileSync(t,"utf8"):void 0;if(r===void 0){const n=s.header??"";return i.writeFileSync(t,`${n}${e.join(`
|
|
2
|
+
`)}
|
|
3
|
+
`,{encoding:"utf8"}),!0}const a=new Set(r.split(`
|
|
4
|
+
`).map(n=>n.trim())),c=e.filter(n=>!a.has(n));if(c.length===0)return!0;const f=r===""||r.endsWith(`
|
|
5
|
+
`)?"":`
|
|
6
|
+
`;return i.appendFileSync(t,`${f}${s.marker}
|
|
7
|
+
${c.join(`
|
|
8
|
+
`)}
|
|
9
|
+
`,"utf8"),!0}catch{return!1}}u(l,"ensureGitignoreEntries");export{l as ensureGitignoreEntries};
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
export declare const FJALL_STATE_GITIGNORE_ENTRIES: readonly [".fjall-state*.json", ".deploy-state.json", ...string[]];
|
|
2
|
+
/**
|
|
3
|
+
* Path of the per-checkout local-state file, relative to the project anchor
|
|
4
|
+
* directory, in `.gitignore` spelling. Derived from the constants that define
|
|
5
|
+
* the real write path (`Config.writeLocalConfig`) so the ignore rule cannot
|
|
6
|
+
* drift away from the file it is meant to cover.
|
|
7
|
+
*/
|
|
8
|
+
export declare const LOCAL_CONFIG_GITIGNORE_ENTRY = "/.fjall/local.json";
|
|
9
|
+
/**
|
|
10
|
+
* Fjall-managed state DIRECTORIES under `.fjall/` — drift baselines, codemod
|
|
11
|
+
* history, and reserved operator logs. Anchored with a leading slash, so each
|
|
12
|
+
* entry only covers the directory holding the `.gitignore` that carries it.
|
|
13
|
+
*/
|
|
14
|
+
export declare const FJALL_MANAGED_STATE_DIR_ENTRIES: readonly ["/.fjall/history/", "/.fjall/baseline/", "/.fjall/logs/"];
|
|
15
|
+
/**
|
|
16
|
+
* `.gitignore` for a scaffolded COMPONENT directory (`fjall/<component>/`):
|
|
17
|
+
* compiled output, CDK synth artefacts, per-machine deploy state, and codemod
|
|
18
|
+
* backups.
|
|
19
|
+
*
|
|
20
|
+
* Deliberately does NOT ignore `fjall-config.json`. Earlier copies of this
|
|
21
|
+
* content did, which is a data-loss hazard rather than a tidiness win: the file
|
|
22
|
+
* is committed project state, and its `capacityIdentity` block is load-bearing
|
|
23
|
+
* deployed state — losing it renames (replaces) every stateful resource in its
|
|
24
|
+
* slot on the next deploy. The entry was harmless only by accident, because it
|
|
25
|
+
* sat in component directories where no `fjall-config.json` exists AND because
|
|
26
|
+
* the packaging defects above meant it never reached a customer machine.
|
|
27
|
+
*/
|
|
28
|
+
export declare const FJALL_COMPONENT_GITIGNORE: string;
|
|
29
|
+
/**
|
|
30
|
+
* `.gitignore` for the PROJECT ANCHOR directory — the directory holding
|
|
31
|
+
* `fjall-config.json`, which is where `.fjall/` managed state is written.
|
|
32
|
+
*
|
|
33
|
+
* This is a separate policy from {@link FJALL_COMPONENT_GITIGNORE} because the
|
|
34
|
+
* two cover different directories. A component `.gitignore` at
|
|
35
|
+
* `fjall/<component>/` cannot reach `fjall/.fjall/local.json` one level up, so
|
|
36
|
+
* the local-state entries only do anything when written at the anchor.
|
|
37
|
+
*/
|
|
38
|
+
/** Attribution marker for entries appended to a pre-existing `.gitignore`. */
|
|
39
|
+
export declare const LOCAL_STATE_GITIGNORE_MARKER = "# fjall: managed local state (added by the fjall CLI)";
|
|
40
|
+
/**
|
|
41
|
+
* Explanatory preamble written when Fjall CREATES the anchor `.gitignore`.
|
|
42
|
+
* Not appended to an existing file — only the missing entries are, under
|
|
43
|
+
* {@link LOCAL_STATE_GITIGNORE_MARKER}.
|
|
44
|
+
*/
|
|
45
|
+
export declare const FJALL_PROJECT_GITIGNORE_HEADER = "# Fjall-managed local state.\n#\n# `fjall-config.json` beside this file is deliberately NOT ignored: it is\n# committed project state, and its `capacityIdentity` block is load-bearing\n# deployed state \u2014 losing it renames (replaces) every stateful resource in its\n# slot on the next deploy.\n\n# Per-checkout active deploy target. Never committed: a committed value\n# silently re-aims a teammate's deploy or a CI pipeline at the wrong target.\n";
|
|
46
|
+
/** Full anchor-directory `.gitignore` (header plus every managed entry). */
|
|
47
|
+
export declare const FJALL_PROJECT_GITIGNORE: string;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import{LOCAL_CONFIG_DIRNAME as e,LOCAL_CONFIG_FILENAME as s,ROOT_CONFIG_FILENAME as l}from"../configPaths.js";import{ATOMIC_TMP_SUFFIX as r,atomicTmpGlob as i}from"../atomicTempNaming.js";const t=[".fjall-state*.json",".deploy-state.json"],n=[...t,...t.map(i),...t.map(a=>`${a}${r}`)],c=`/${e}/${s}`,o=[`/${e}/history/`,`/${e}/baseline/`,`/${e}/logs/`],m=`*.js
|
|
2
|
+
*.d.ts
|
|
3
|
+
node_modules
|
|
4
|
+
.cdk.staging
|
|
5
|
+
**/**/cdk.out
|
|
6
|
+
|
|
7
|
+
.DS_Store
|
|
8
|
+
|
|
9
|
+
# Fjall-managed state directories. Kept here as well as at the project anchor
|
|
10
|
+
# because codemod runs resolve them against the working directory.
|
|
11
|
+
${o.join(`
|
|
12
|
+
`)}
|
|
13
|
+
|
|
14
|
+
# Fjall per-target deploy state \u2014 a per-machine cache, never a deploy oracle.
|
|
15
|
+
${n.join(`
|
|
16
|
+
`)}
|
|
17
|
+
|
|
18
|
+
# Fjall backup files (sibling \`.bak\` from codemod mutations + domain eject)
|
|
19
|
+
**/backup/
|
|
20
|
+
*.bak
|
|
21
|
+
`,E="# fjall: managed local state (added by the fjall CLI)",d=`# Fjall-managed local state.
|
|
22
|
+
#
|
|
23
|
+
# \`${l}\` beside this file is deliberately NOT ignored: it is
|
|
24
|
+
# committed project state, and its \`capacityIdentity\` block is load-bearing
|
|
25
|
+
# deployed state \u2014 losing it renames (replaces) every stateful resource in its
|
|
26
|
+
# slot on the next deploy.
|
|
27
|
+
|
|
28
|
+
# Per-checkout active deploy target. Never committed: a committed value
|
|
29
|
+
# silently re-aims a teammate's deploy or a CI pipeline at the wrong target.
|
|
30
|
+
`,I=`${d}${c}
|
|
31
|
+
|
|
32
|
+
# Drift baselines, codemod history, and operator logs.
|
|
33
|
+
${o.join(`
|
|
34
|
+
`)}
|
|
35
|
+
`;export{m as FJALL_COMPONENT_GITIGNORE,o as FJALL_MANAGED_STATE_DIR_ENTRIES,I as FJALL_PROJECT_GITIGNORE,d as FJALL_PROJECT_GITIGNORE_HEADER,n as FJALL_STATE_GITIGNORE_ENTRIES,c as LOCAL_CONFIG_GITIGNORE_ENTRY,E as LOCAL_STATE_GITIGNORE_MARKER};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fjall/util",
|
|
3
|
-
"version": "21.
|
|
3
|
+
"version": "21.1.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/fjall-tech/fjall.git",
|
|
@@ -15,6 +15,10 @@
|
|
|
15
15
|
"types": "./dist/index.d.ts",
|
|
16
16
|
"default": "./dist/index.js"
|
|
17
17
|
},
|
|
18
|
+
"./atomicTempNaming": {
|
|
19
|
+
"types": "./dist/atomicTempNaming.d.ts",
|
|
20
|
+
"default": "./dist/atomicTempNaming.js"
|
|
21
|
+
},
|
|
18
22
|
"./buildConcurrency": {
|
|
19
23
|
"types": "./dist/buildConcurrency.d.ts",
|
|
20
24
|
"default": "./dist/buildConcurrency.js"
|
|
@@ -35,6 +39,10 @@
|
|
|
35
39
|
"types": "./dist/docker/index.d.ts",
|
|
36
40
|
"default": "./dist/docker/index.js"
|
|
37
41
|
},
|
|
42
|
+
"./logRotation": {
|
|
43
|
+
"types": "./dist/logRotation.d.ts",
|
|
44
|
+
"default": "./dist/logRotation.js"
|
|
45
|
+
},
|
|
38
46
|
"./manifest": {
|
|
39
47
|
"types": "./dist/manifest/index.d.ts",
|
|
40
48
|
"default": "./dist/manifest/index.js"
|