@fjall/util 2.11.1 → 2.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.minified +1 -1
- package/dist/Config.d.ts +109 -4
- package/dist/Config.js +1 -1
- package/dist/backupVault.d.ts +7 -0
- package/dist/backupVault.js +1 -0
- package/dist/connectionsWire.d.ts +30 -0
- package/dist/connectionsWire.js +1 -0
- package/dist/environments.d.ts +69 -22
- package/dist/environments.js +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +1 -1
- package/dist/mcpProtocol/index.d.ts +6 -7
- package/dist/mcpProtocol/index.js +1 -1
- package/dist/targets.d.ts +13 -1
- package/dist/targets.js +1 -1
- package/package.json +2 -2
package/dist/.minified
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
61 files minified at 2026-06-10T21:04:19.408Z
|
package/dist/Config.d.ts
CHANGED
|
@@ -1,14 +1,69 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { type Result } from "./docker/result.js";
|
|
3
|
+
import { type AccountTier } from "./environments.js";
|
|
2
4
|
/**
|
|
3
5
|
* Backup Vault Lock modes for an account's DisasterRecovery vault.
|
|
4
6
|
* See decisions/2026-06-03-backup-vault-lock-mode-by-intent.md.
|
|
5
7
|
*/
|
|
6
8
|
export declare const VAULT_LOCK_MODES: readonly ["compliance", "governance", "none"];
|
|
7
9
|
export type VaultLockMode = (typeof VAULT_LOCK_MODES)[number];
|
|
10
|
+
/**
|
|
11
|
+
* Account-level S3 Block Public Access posture. Fjall observes-and-flags public
|
|
12
|
+
* buckets through the posture layer rather than hard-blocking, so enforcement is
|
|
13
|
+
* off by default; "enforced" opts an account into all four account-level flags.
|
|
14
|
+
*/
|
|
15
|
+
export declare const S3_BPA_MODES: readonly ["enforced", "off"];
|
|
16
|
+
export type S3BpaMode = (typeof S3_BPA_MODES)[number];
|
|
17
|
+
/**
|
|
18
|
+
* Per-account management-events-trail lifecycle for the organisation-trail
|
|
19
|
+
* migration. Absent ⇒ legacy per-account trail, auto-eligible for migration
|
|
20
|
+
* once org-trail delivery is verified. "account" pins the per-account trail
|
|
21
|
+
* (the explicit reverse path). "draining" removes the trail resource while
|
|
22
|
+
* retaining its bucket + CMK. "org" is terminal: the organisation trail
|
|
23
|
+
* covers the account and local storage has been decommissioned.
|
|
24
|
+
*/
|
|
25
|
+
export declare const TRAIL_LIFECYCLE_STATES: readonly ["account", "draining", "org"];
|
|
26
|
+
export type TrailLifecycleState = (typeof TRAIL_LIFECYCLE_STATES)[number];
|
|
27
|
+
/**
|
|
28
|
+
* Trail names shared between the CDK constructs
|
|
29
|
+
* (@fjall/components-infrastructure) and the deploy-core org-trail migration —
|
|
30
|
+
* SDK probes (DescribeTrails) must match what the constructs synthesise.
|
|
31
|
+
*/
|
|
32
|
+
export declare const ACCOUNT_TRAIL_NAME = "managementEvents";
|
|
33
|
+
export declare const ORGANISATION_TRAIL_NAME = "organisationManagementEvents";
|
|
34
|
+
/**
|
|
35
|
+
* CDK-side trail-state vocabulary (the `fjallAccountTrailState` context
|
|
36
|
+
* value), shared between the CDK constructs and deploy-core's context
|
|
37
|
+
* builders. Distinct from TRAIL_LIFECYCLE_STATES: config intent
|
|
38
|
+
* ("account"/"draining"/"org") maps onto synth behaviour
|
|
39
|
+
* ("active"/"draining"/"removed").
|
|
40
|
+
*/
|
|
41
|
+
export declare const ACCOUNT_TRAIL_STATES: readonly ["active", "draining", "removed"];
|
|
42
|
+
export type AccountTrailState = (typeof ACCOUNT_TRAIL_STATES)[number];
|
|
43
|
+
/**
|
|
44
|
+
* Stack output keys (CfnOutput key + exportName) emitted by the Account /
|
|
45
|
+
* Organisation CDK patterns and read back by the deploy-core org-trail
|
|
46
|
+
* migration reconciler — both sides must use the same literals.
|
|
47
|
+
*/
|
|
48
|
+
export declare const TRAIL_BUCKET_OUTPUT_KEY = "FjallTrailBucketName";
|
|
49
|
+
export declare const TRAIL_KEY_ARN_OUTPUT_KEY = "FjallTrailKeyArn";
|
|
50
|
+
export declare const ORG_TRAIL_BUCKET_OUTPUT_KEY = "OrganisationTrailBucketName";
|
|
8
51
|
export type ProviderAccount = {
|
|
9
52
|
id: string;
|
|
10
53
|
name: string;
|
|
11
|
-
|
|
54
|
+
/**
|
|
55
|
+
* Workload STAGE — null for structural accounts (organisation/platform tiers
|
|
56
|
+
* carry no workload stage). Read the structural axis from `tier`, never from
|
|
57
|
+
* this field.
|
|
58
|
+
*/
|
|
59
|
+
environment: string | null;
|
|
60
|
+
/**
|
|
61
|
+
* Structural TIER (organisation/platform/account). Optional for wire
|
|
62
|
+
* back-compat: old configs omit it and readers fall back to decoding
|
|
63
|
+
* `environment` via `accountTier()`. Producers (webapp buildOrgConfigPayload)
|
|
64
|
+
* emit it explicitly so the tier no longer rides on the environment string.
|
|
65
|
+
*/
|
|
66
|
+
tier?: AccountTier;
|
|
12
67
|
managed?: boolean;
|
|
13
68
|
oidcRoleArn?: string;
|
|
14
69
|
/**
|
|
@@ -26,6 +81,23 @@ export type ProviderAccount = {
|
|
|
26
81
|
vaultLock?: VaultLockMode;
|
|
27
82
|
/** Explicit acknowledgement that vaultLock: "compliance" is irreversible. */
|
|
28
83
|
acknowledgeImmutableVaultLock?: boolean;
|
|
84
|
+
/**
|
|
85
|
+
* Account-level S3 Block Public Access posture. Absent ⇒ "off" — Fjall does
|
|
86
|
+
* not enforce account-level BPA (the posture layer flags exposed buckets
|
|
87
|
+
* instead). "enforced" sets all four account-level public-access flags true.
|
|
88
|
+
*/
|
|
89
|
+
s3BlockPublicAccess?: S3BpaMode;
|
|
90
|
+
/**
|
|
91
|
+
* Management-events-trail lifecycle for the org-trail migration. Absent ⇒
|
|
92
|
+
* legacy per-account trail (auto-eligible); see TRAIL_LIFECYCLE_STATES.
|
|
93
|
+
*/
|
|
94
|
+
trailLifecycle?: TrailLifecycleState;
|
|
95
|
+
/**
|
|
96
|
+
* Explicit acknowledgement that decommissioning the per-account trail
|
|
97
|
+
* discards its retained log history. Bucket deletion never proceeds without
|
|
98
|
+
* it — back up the bucket first if the history matters.
|
|
99
|
+
*/
|
|
100
|
+
acknowledgeTrailHistoryLoss?: boolean;
|
|
29
101
|
};
|
|
30
102
|
export type Profile = {
|
|
31
103
|
type: "sso" | "oidc";
|
|
@@ -74,17 +146,50 @@ export type RootConfig = z.infer<typeof RootConfigSchema>;
|
|
|
74
146
|
export declare class Config {
|
|
75
147
|
rootConfig: RootConfig;
|
|
76
148
|
private configPath;
|
|
149
|
+
/**
|
|
150
|
+
* True when the config file was FOUND on disk but could not be read.
|
|
151
|
+
* saveConfig refuses to write in that state — the in-memory config never
|
|
152
|
+
* included the real file's contents, so writing would clobber them.
|
|
153
|
+
*/
|
|
154
|
+
private loadFailed;
|
|
155
|
+
/**
|
|
156
|
+
* Top-level keys explicitly cleared this session (clearActiveTarget).
|
|
157
|
+
* The disk-preserving merge in saveConfig would otherwise resurrect them
|
|
158
|
+
* from the on-disk copy.
|
|
159
|
+
*/
|
|
160
|
+
private readonly clearedKeys;
|
|
77
161
|
constructor(rootConfig?: RootConfig, configPath?: string);
|
|
78
162
|
/**
|
|
79
163
|
* Find the config directory by walking up the directory tree.
|
|
80
164
|
* Looks for fjall/fjall-config.json or direct fjall-config.json.
|
|
165
|
+
* Walks up from `startDir` when provided, otherwise from process.cwd().
|
|
81
166
|
*/
|
|
82
167
|
private static findConfigDirectory;
|
|
83
168
|
private static loadConfigFile;
|
|
84
|
-
|
|
169
|
+
/**
|
|
170
|
+
* Load the config, walking up from `startDir` (default process.cwd()).
|
|
171
|
+
*/
|
|
172
|
+
static loadConfig(startDir?: string): Config;
|
|
85
173
|
private static formatZodError;
|
|
86
|
-
saveConfig(): void
|
|
87
|
-
|
|
174
|
+
saveConfig(): Result<void, Error>;
|
|
175
|
+
/**
|
|
176
|
+
* Writability is checked at save time, not load time: POSIX rename replaces
|
|
177
|
+
* a read-only destination whenever the directory is writable, so without
|
|
178
|
+
* this guard the tmp-plus-rename write would silently replace a chmod-444
|
|
179
|
+
* config.
|
|
180
|
+
*/
|
|
181
|
+
private static assertWritable;
|
|
182
|
+
/**
|
|
183
|
+
* Disk-preserving merge: re-reads the on-disk config immediately before
|
|
184
|
+
* writing so sibling top-level keys written by a concurrent process between
|
|
185
|
+
* this session's load and save survive. In-memory keys win at top-level-key
|
|
186
|
+
* granularity; keys explicitly cleared this session are removed even when
|
|
187
|
+
* the disk copy still carries them. Unreadable or invalid disk state falls
|
|
188
|
+
* back to the in-memory state with a warning rather than blocking the save.
|
|
189
|
+
*/
|
|
190
|
+
private mergeWithDisk;
|
|
191
|
+
private static readDiskConfigForMerge;
|
|
192
|
+
static getConfigDirectory(startDir?: string): string | null;
|
|
88
193
|
getActiveTarget(): string | undefined;
|
|
89
194
|
setActiveTarget(name: string): void;
|
|
90
195
|
clearActiveTarget(): void;
|
package/dist/Config.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import*as
|
|
1
|
+
import*as i from"fs";import*as f from"path";import{z as c}from"zod";import{failure as d,success as h}from"./docker/result.js";import{getErrorMessage as g}from"./errorUtils.js";import{logger as u}from"./logger.js";import{maskSensitiveOutput as l}from"./securityHelpers.js";const y=10,O=["compliance","governance","none"],$=["enforced","off"],_=["account","draining","org"],x="managementEvents",F="organisationManagementEvents",K=["active","draining","removed"],b="FjallTrailBucketName",k="FjallTrailKeyArn",L="OrganisationTrailBucketName",w=c.object({name:c.string(),type:c.enum(["apex","delegated"]),parentDomain:c.string().optional(),account:c.string().optional()}).strict(),m=c.object({activeTarget:c.string().optional(),domains:c.array(w).optional()}).strict(),T=m.keyof().options;function E(C,e,t){const n=e[t];n!==void 0&&(C[t]=n)}class s{rootConfig;configPath=null;loadFailed=!1;clearedKeys=new Set;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<y;n++){const o=f.join(t,"fjall"),a=f.join(o,"fjall-config.json");if(i.existsSync(a))return o;const r=f.join(t,"fjall-config.json");if(i.existsSync(r))return t;const p=f.dirname(t);if(p===t)break;t=p}return null}static loadConfigFile(e){try{return i.accessSync(e,i.constants.R_OK),i.readFileSync(e,{encoding:"utf8"})}catch(t){return u.warn("Config",`Config file at ${e} could not be read; using defaults`,{file:e,error:l(g(t))}),null}}static loadConfig(e){const t=s.findConfigDirectory(e);if(!t)return new s;const n=f.join(t,"fjall-config.json"),o=s.loadConfigFile(n);if(o===null){const r=new s(void 0,n);return r.loadFailed=!0,r}let a;if(o!=="")try{a=m.parse(JSON.parse(o))}catch(r){throw s.formatZodError(r,"fjall-config.json")}return new s(a,n)}static formatZodError(e,t){if(e instanceof c.ZodError&&e.issues.length>0){const a=e.issues.map(r=>`${r.path.join(".")}: ${r.message}`).join("; ");return new Error(`Failed to parse ${t}: ${a}`)}const o=(e instanceof Error?e.message:String(e)).replace(/\n/g," ").substring(0,500);return new Error(`Failed to parse ${t}: ${o}`)}saveConfig(){let e=this.configPath;if(!e){const r=s.findConfigDirectory()||f.join(process.cwd(),"fjall");e=f.join(r,"fjall-config.json")}if(this.loadFailed)return d(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=f.dirname(e);try{i.mkdirSync(t,{recursive:!0})}catch(r){return d(new Error(`Cannot create config directory ${t}: ${l(g(r))}`))}const n=s.assertWritable(e,t);if(!n.success)return n;const o=JSON.stringify(this.mergeWithDisk(e),null,2),a=`${e}.tmp-${process.pid}`;try{i.writeFileSync(a,o,{mode:384}),i.renameSync(a,e)}catch(r){return d(new Error(`Failed to save ${e}: ${l(g(r))}`))}return h(void 0)}static assertWritable(e,t){if(i.existsSync(e))try{i.accessSync(e,i.constants.W_OK)}catch{return d(new Error(`Cannot save ${e}: the file is read-only. Make it writable (e.g. chmod u+w ${e}) and retry.`))}try{i.accessSync(t,i.constants.W_OK)}catch{return d(new Error(`Cannot save ${e}: the directory ${t} is not writable. Make it writable (e.g. chmod u+w ${t}) and retry.`))}return h(void 0)}mergeWithDisk(e){const t=s.readDiskConfigForMerge(e);if(t===void 0)return this.rootConfig;const n={...t};for(const o of T)E(n,this.rootConfig,o);for(const o of this.clearedKeys)delete n[o];return n}static readDiskConfigForMerge(e){if(!i.existsSync(e))return;let t;try{t=JSON.parse(i.readFileSync(e,{encoding:"utf8"}))}catch(o){u.warn("Config",`Could not re-read ${e} before saving; writing in-memory state without merging`,{file:e,error:l(g(o))});return}const n=m.safeParse(t);if(!n.success){u.warn("Config",`On-disk ${e} failed validation before saving; writing in-memory state without merging`,{file:e,error:l(n.error.message)});return}return n.data}static getConfigDirectory(e){return s.findConfigDirectory(e)}getActiveTarget(){return this.rootConfig.activeTarget}setActiveTarget(e){this.rootConfig.activeTarget=e,this.clearedKeys.delete("activeTarget")}clearActiveTarget(){this.rootConfig.activeTarget=void 0,this.clearedKeys.add("activeTarget")}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{x as ACCOUNT_TRAIL_NAME,K as ACCOUNT_TRAIL_STATES,s as Config,F as ORGANISATION_TRAIL_NAME,L as ORG_TRAIL_BUCKET_OUTPUT_KEY,m as RootConfigSchema,$ as S3_BPA_MODES,b as TRAIL_BUCKET_OUTPUT_KEY,k as TRAIL_KEY_ARN_OUTPUT_KEY,_ as TRAIL_LIFECYCLE_STATES,O as VAULT_LOCK_MODES};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fixed name of the disaster-recovery backup vault. Single source of truth for
|
|
3
|
+
* the @fjall/components-infrastructure DisasterRecovery construct (which
|
|
4
|
+
* creates the vault under this name) and deploy-core's adopt-vs-create and
|
|
5
|
+
* survival probes (which look it up by the same name).
|
|
6
|
+
*/
|
|
7
|
+
export declare const BACKUP_VAULT_NAME = "backupVault";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const t="backupVault";export{t as BACKUP_VAULT_NAME};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire contract for `GET /api/connections/list` — the single shared shape
|
|
3
|
+
* between the webapp producer (`webapp/app/routes/api/connections/list.ts`)
|
|
4
|
+
* and the CLI consumer (`FjallApiClient.getConnectedAccounts`). Neither side
|
|
5
|
+
* may redeclare this record: the producer conforms at compile time via
|
|
6
|
+
* `satisfies ConnectionWire`, the consumer parses with `safeParse`.
|
|
7
|
+
*/
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
export declare const ConnectionWireSchema: z.ZodObject<{
|
|
10
|
+
awsAccountId: z.ZodString;
|
|
11
|
+
accountName: z.ZodNullable<z.ZodString>;
|
|
12
|
+
status: z.ZodString;
|
|
13
|
+
role: z.ZodString;
|
|
14
|
+
roleArn: z.ZodString;
|
|
15
|
+
environment: z.ZodOptional<z.ZodString>;
|
|
16
|
+
connectedAt: z.ZodString;
|
|
17
|
+
}, z.core.$strip>;
|
|
18
|
+
export type ConnectionWire = z.infer<typeof ConnectionWireSchema>;
|
|
19
|
+
export declare const ConnectionsListResponseSchema: z.ZodObject<{
|
|
20
|
+
accounts: z.ZodArray<z.ZodObject<{
|
|
21
|
+
awsAccountId: z.ZodString;
|
|
22
|
+
accountName: z.ZodNullable<z.ZodString>;
|
|
23
|
+
status: z.ZodString;
|
|
24
|
+
role: z.ZodString;
|
|
25
|
+
roleArn: z.ZodString;
|
|
26
|
+
environment: z.ZodOptional<z.ZodString>;
|
|
27
|
+
connectedAt: z.ZodString;
|
|
28
|
+
}, z.core.$strip>>;
|
|
29
|
+
}, z.core.$strip>;
|
|
30
|
+
export type ConnectionsListResponse = z.infer<typeof ConnectionsListResponseSchema>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{z as n}from"zod";const t=n.object({awsAccountId:n.string(),accountName:n.string().nullable(),status:n.string(),role:n.string(),roleArn:n.string(),environment:n.string().optional(),connectedAt:n.string()}),e=n.object({accounts:n.array(t)});export{t as ConnectionWireSchema,e as ConnectionsListResponseSchema};
|
package/dist/environments.d.ts
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* Environment + account-axis constants shared across CLI, webapp, and
|
|
3
|
+
* deploy-core. Two independent axes live here: the workload STAGE
|
|
4
|
+
* ([[ACCOUNT_STAGES]]) and the structural TIER ([[ACCOUNT_TIERS]]). "root" is
|
|
5
|
+
* NOT a stage and NOT a tier — it is the wire environment marker that decodes
|
|
6
|
+
* to tier "organisation" via [[environmentToTier]], and is never
|
|
7
|
+
* user-selectable.
|
|
6
8
|
*/
|
|
7
|
-
|
|
8
|
-
export
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
import { z } from "zod";
|
|
10
|
+
export declare const ACCOUNT_STAGES: readonly ["production", "staging", "development", "platform", "compliance"];
|
|
11
|
+
export type AccountStage = (typeof ACCOUNT_STAGES)[number];
|
|
12
|
+
/** Human-readable labels for each workload stage. */
|
|
13
|
+
export declare const ACCOUNT_STAGE_LABELS: Record<AccountStage, string>;
|
|
14
|
+
/** Type guard: checks whether a string is a user-selectable workload stage. */
|
|
15
|
+
export declare function isAccountStage(value: string): value is AccountStage;
|
|
11
16
|
/**
|
|
12
17
|
* Structural environments used for cascade account partitioning.
|
|
13
18
|
* These are not user-selectable — "root" is implicit (management account),
|
|
@@ -18,18 +23,36 @@ export declare const STRUCTURAL_ENVIRONMENTS: {
|
|
|
18
23
|
readonly PLATFORM: "platform";
|
|
19
24
|
};
|
|
20
25
|
/**
|
|
21
|
-
* Wire-
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
+
* Wire-tolerance vocabulary: the workload stages PLUS the structural "root"
|
|
27
|
+
* marker. Ingress schemas that face out-of-version CLIs or the org-config
|
|
28
|
+
* GET→PUT round-trip accept this superset, then decode "root" → null at
|
|
29
|
+
* PERSISTENCE via [[stageFromWireEnvironment]] (the DB never stores structural
|
|
30
|
+
* root). NOT a user-facing picker vocabulary — pickers use ACCOUNT_STAGES.
|
|
31
|
+
* PERMANENT ingest vocabulary, not a drain-gated shim: the separate-root
|
|
32
|
+
* connect deliberately carries environment:"root" as its intent marker
|
|
33
|
+
* (solo-to-org lifecycle ADR, decision 7), so wire-rejection of "root" is
|
|
34
|
+
* unreachable; only derived-EMIT of "root" retires, per-org, behind the CLI
|
|
35
|
+
* telemetry gate. See decisions/2026-06-07-account-tier-vs-stage-separation.md
|
|
36
|
+
* § "Wire back-compat (permanent, not transitional)".
|
|
26
37
|
*/
|
|
27
|
-
export declare const
|
|
28
|
-
export type
|
|
29
|
-
/** Human-readable labels for each standard environment. */
|
|
30
|
-
export declare const ENVIRONMENT_LABELS: Record<StandardEnvironment, string>;
|
|
38
|
+
export declare const ACCOUNT_STAGES_WITH_ROOT: readonly ["production", "staging", "development", "platform", "compliance", "root"];
|
|
39
|
+
export type AccountStageWithRoot = (typeof ACCOUNT_STAGES_WITH_ROOT)[number];
|
|
31
40
|
/** Returns the human-readable label for an environment, with capitalised fallback. */
|
|
32
41
|
export declare function getEnvironmentLabel(env: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* Structural TIER axis: an account's role in the organisation. Independent of
|
|
44
|
+
* the workload STAGE axis ([[ACCOUNT_STAGES]]) — a tier is never derived from a
|
|
45
|
+
* stage and vice versa. Same literals as [[ACCOUNT_ROLES]]: its `satisfies`
|
|
46
|
+
* clause rejects non-tier values, and [[ACCOUNT_ROLE_TIER_PRESENCE]] rejects a
|
|
47
|
+
* missing or duplicated tier, so the two cannot drift.
|
|
48
|
+
*/
|
|
49
|
+
export declare const ACCOUNT_TIERS: readonly ["organisation", "platform", "account"];
|
|
50
|
+
export type AccountTier = (typeof ACCOUNT_TIERS)[number];
|
|
51
|
+
export declare const AccountTierSchema: z.ZodEnum<{
|
|
52
|
+
platform: "platform";
|
|
53
|
+
organisation: "organisation";
|
|
54
|
+
account: "account";
|
|
55
|
+
}>;
|
|
33
56
|
/**
|
|
34
57
|
* AWS account roles in the wire format used across the CLI, webapp API
|
|
35
58
|
* responses, and the Prisma `AccountRole` enum. This is the SINGLE SOURCE
|
|
@@ -40,14 +63,38 @@ export declare function getEnvironmentLabel(env: string): string;
|
|
|
40
63
|
* a new role here without updating Prisma fails the parity test; renaming
|
|
41
64
|
* a value here propagates structurally to the webapp.
|
|
42
65
|
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
66
|
+
* Independence: `role` (TIER) and `environment` (STAGE) are independent axes.
|
|
67
|
+
* Inbound wire values that still carry a structural environment are decoded via
|
|
68
|
+
* [[environmentToTier]] / [[stageFromWireEnvironment]] — nothing derives one
|
|
69
|
+
* axis from the other on a write. See [[STRUCTURAL_ENVIRONMENTS]].
|
|
47
70
|
*/
|
|
48
71
|
export declare const ACCOUNT_ROLES: {
|
|
49
72
|
readonly ORGANISATION: "organisation";
|
|
50
73
|
readonly PLATFORM: "platform";
|
|
51
74
|
readonly ACCOUNT: "account";
|
|
52
75
|
};
|
|
53
|
-
|
|
76
|
+
/** Type guard: checks whether a string is a valid account tier. */
|
|
77
|
+
export declare function isAccountTier(value: string): value is AccountTier;
|
|
78
|
+
/**
|
|
79
|
+
* Decode an inbound wire `environment` to its structural TIER. The wire stays
|
|
80
|
+
* superset-tolerant: out-of-version CLIs and the post-`fjall create org`
|
|
81
|
+
* connect still submit "root"/"platform" as an environment. This is the only
|
|
82
|
+
* sanctioned environment→tier derivation — write paths must NOT re-derive a
|
|
83
|
+
* role from a stage. See decisions/2026-06-07-account-tier-vs-stage-separation.md.
|
|
84
|
+
*/
|
|
85
|
+
export declare function environmentToTier(environment: string | null | undefined): AccountTier;
|
|
86
|
+
/**
|
|
87
|
+
* Decode an inbound wire `environment` to its workload STAGE, or null. "root"
|
|
88
|
+
* (the management account — no workloads), empty, null, or any unknown string
|
|
89
|
+
* yields null. "platform" is a real stage and passes through unchanged.
|
|
90
|
+
*/
|
|
91
|
+
export declare function stageFromWireEnvironment(environment: string | null | undefined): AccountStage | null;
|
|
92
|
+
/**
|
|
93
|
+
* Canonical TIER accessor for deploy-core/CLI/MCP readers: prefer the explicit
|
|
94
|
+
* `tier` wire field, falling back to decoding a legacy structural environment.
|
|
95
|
+
* Replaces scattered `environment === STRUCTURAL_ENVIRONMENTS.*` comparisons.
|
|
96
|
+
*/
|
|
97
|
+
export declare function accountTier(acc: {
|
|
98
|
+
tier?: AccountTier | null;
|
|
99
|
+
environment?: string | null;
|
|
100
|
+
}): AccountTier;
|
package/dist/environments.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const
|
|
1
|
+
import{z as c}from"zod";const n=["production","staging","development","platform","compliance"],T={production:"Production",staging:"Staging",development:"Development",platform:"Platform",compliance:"Compliance"},i=new Set(n);function e(t){return i.has(t)}const o={ROOT:"root",PLATFORM:"platform"},C=[...n,o.ROOT];function s(t){return e(t)?T[t]:t.charAt(0).toUpperCase()+t.slice(1)}const u=["organisation","platform","account"],l=c.enum(u),r={ORGANISATION:"organisation",PLATFORM:"platform",ACCOUNT:"account"},O={[r.ORGANISATION]:!0,[r.PLATFORM]:!0,[r.ACCOUNT]:!0},a=new Set(Object.keys(O));function S(t){return a.has(t)}function p(t){return t===o.ROOT?"organisation":t===o.PLATFORM?"platform":"account"}function R(t){return t==null||t===""||t===o.ROOT?null:e(t)?t:null}function E(t){return t.tier??p(t.environment)}export{r as ACCOUNT_ROLES,n as ACCOUNT_STAGES,C as ACCOUNT_STAGES_WITH_ROOT,T as ACCOUNT_STAGE_LABELS,u as ACCOUNT_TIERS,l as AccountTierSchema,o as STRUCTURAL_ENVIRONMENTS,E as accountTier,p as environmentToTier,s as getEnvironmentLabel,e as isAccountStage,S as isAccountTier,R as stageFromWireEnvironment};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { DNS_APEX, getDomainExportNames, type ManagedDomainExports } from "./domainExports.js";
|
|
2
|
+
export { BACKUP_VAULT_NAME } from "./backupVault.js";
|
|
2
3
|
export { toPascalCase, toKebab, toValidDatabaseName, toScreamingSnake, capitalise, getSafeZoneName, accountConstructKey, hasAsciiStableConstructKey } from "./caseConversion.js";
|
|
3
4
|
export { findAccountNameCollision, type AccountNameCollision } from "./accountNameCollision.js";
|
|
4
5
|
export { normaliseError, getErrorMessage, hasErrorCode, getErrorCode, getErrorStack, formatErrorString } from "./errorUtils.js";
|
|
@@ -6,12 +7,13 @@ export { singleton } from "./singleton.js";
|
|
|
6
7
|
export { DANGEROUS_ENV_VARS, filterDangerousEnvVars, maskSensitiveOutput, parseShellArgs } from "./securityHelpers.js";
|
|
7
8
|
export { sleep } from "./sleep.js";
|
|
8
9
|
export { mapSettledWithConcurrency } from "./concurrency.js";
|
|
9
|
-
export {
|
|
10
|
+
export { ACCOUNT_STAGES_WITH_ROOT, STRUCTURAL_ENVIRONMENTS, ACCOUNT_STAGES, ACCOUNT_STAGE_LABELS, isAccountStage, ACCOUNT_TIERS, type AccountTier, AccountTierSchema, isAccountTier, environmentToTier, stageFromWireEnvironment, accountTier, type AccountStageWithRoot, type AccountStage, getEnvironmentLabel, ACCOUNT_ROLES } from "./environments.js";
|
|
10
11
|
export { RESOURCE_CATEGORIES, type ResourceCategory, categoriseResource, getExpectedDuration, getFriendlyResourceType } from "./resourceCategorisation.js";
|
|
11
12
|
export { parseGitRemoteUrl, type GitProvider, type ParsedGitRemote } from "./gitRemoteParser.js";
|
|
12
13
|
export { abbreviateRegion } from "./regions.js";
|
|
13
14
|
export { SCOPE_VALUES, type TokenScope } from "./tokenScopes.js";
|
|
14
|
-
export {
|
|
15
|
+
export { ConnectionWireSchema, type ConnectionWire, ConnectionsListResponseSchema, type ConnectionsListResponse } from "./connectionsWire.js";
|
|
16
|
+
export { deriveRegionsFromOrgConfig, deriveTargets, deriveAllTargets, environmentOrTier, findTarget, generateTargetName, type OrgConfigRegions, type TargetAccount, type DerivedTarget } from "./targets.js";
|
|
15
17
|
export { buildAppConfigPath } from "./appPath.js";
|
|
16
18
|
export { type ScanPath } from "./scanTypes.js";
|
|
17
19
|
export { findInfrastructurePaths, findBoundaryPath, isInfrastructureFile, type MarkerEntry, type FindInfrastructurePathsOptions } from "./findInfrastructurePaths.js";
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{DNS_APEX as o,getDomainExportNames as t}from"./domainExports.js";import{toPascalCase as
|
|
1
|
+
import{DNS_APEX as o,getDomainExportNames as t}from"./domainExports.js";import{BACKUP_VAULT_NAME as n}from"./backupVault.js";import{toPascalCase as i,toKebab as S,toValidDatabaseName as m,toScreamingSnake as s,capitalise as _,getSafeZoneName as A,accountConstructKey as C,hasAsciiStableConstructKey as p}from"./caseConversion.js";import{findAccountNameCollision as f}from"./accountNameCollision.js";import{normaliseError as R,getErrorMessage as c,hasErrorCode as g,getErrorCode as O,getErrorStack as x,formatErrorString as I}from"./errorUtils.js";import{singleton as l}from"./singleton.js";import{DANGEROUS_ENV_VARS as P,filterDangerousEnvVars as M,maskSensitiveOutput as V,parseShellArgs as U}from"./securityHelpers.js";import{sleep as v}from"./sleep.js";import{mapSettledWithConcurrency as H}from"./concurrency.js";import{ACCOUNT_STAGES_WITH_ROOT as G,STRUCTURAL_ENVIRONMENTS as b,ACCOUNT_STAGES as y,ACCOUNT_STAGE_LABELS as F,isAccountStage as K,ACCOUNT_TIERS as W,AccountTierSchema as X,isAccountTier as k,environmentToTier as B,stageFromWireEnvironment as Z,accountTier as j,getEnvironmentLabel as q,ACCOUNT_ROLES as w}from"./environments.js";import{RESOURCE_CATEGORIES as J,categoriseResource as Q,getExpectedDuration as Y,getFriendlyResourceType as $}from"./resourceCategorisation.js";import{parseGitRemoteUrl as re}from"./gitRemoteParser.js";import{abbreviateRegion as te}from"./regions.js";import{SCOPE_VALUES as ne}from"./tokenScopes.js";import{ConnectionWireSchema as ie,ConnectionsListResponseSchema as Se}from"./connectionsWire.js";import{deriveRegionsFromOrgConfig as se,deriveTargets as _e,deriveAllTargets as Ae,environmentOrTier as Ce,findTarget as pe,generateTargetName as Te}from"./targets.js";import{buildAppConfigPath as Ne}from"./appPath.js";import{findInfrastructurePaths as ce,findBoundaryPath as ge,isInfrastructureFile as Oe}from"./findInfrastructurePaths.js";import{inferContainerFromCandidates as Ie}from"./inferContainerFromCandidates.js";import{RESERVED_APP_NAMES as le,isReservedAppName as de}from"./reservedAppNames.js";import{deriveContentHashTag as Me}from"./deriveContentHashTag.js";import{MIGRATION_SNAPSHOT_NAME_PREFIX as Ue,EXPECTED_SCHEMA_VERSION_ENV as De,EXPECTED_SCHEMA_VERSION_TOOL_ENV as ve,EXPECTED_CH_SCHEMA_VERSION_ENV as he,SCHEMA_ADMIN_USER_ENV as He,SCHEMA_ADMIN_PASSWORD_ENV as Le,PRISMA_MIGRATION_DIR_RE as Ge,CLICKHOUSE_MIGRATION_SKIP_RE as be}from"./migration/constants.js";export{w as ACCOUNT_ROLES,y as ACCOUNT_STAGES,G as ACCOUNT_STAGES_WITH_ROOT,F as ACCOUNT_STAGE_LABELS,W as ACCOUNT_TIERS,X as AccountTierSchema,n as BACKUP_VAULT_NAME,be as CLICKHOUSE_MIGRATION_SKIP_RE,ie as ConnectionWireSchema,Se as ConnectionsListResponseSchema,P as DANGEROUS_ENV_VARS,o as DNS_APEX,he as EXPECTED_CH_SCHEMA_VERSION_ENV,De as EXPECTED_SCHEMA_VERSION_ENV,ve as EXPECTED_SCHEMA_VERSION_TOOL_ENV,Ue as MIGRATION_SNAPSHOT_NAME_PREFIX,Ge as PRISMA_MIGRATION_DIR_RE,le as RESERVED_APP_NAMES,J as RESOURCE_CATEGORIES,Le as SCHEMA_ADMIN_PASSWORD_ENV,He as SCHEMA_ADMIN_USER_ENV,ne as SCOPE_VALUES,b as STRUCTURAL_ENVIRONMENTS,te as abbreviateRegion,C as accountConstructKey,j as accountTier,Ne as buildAppConfigPath,_ as capitalise,Q as categoriseResource,Ae as deriveAllTargets,Me as deriveContentHashTag,se as deriveRegionsFromOrgConfig,_e as deriveTargets,Ce as environmentOrTier,B as environmentToTier,M as filterDangerousEnvVars,f as findAccountNameCollision,ge as findBoundaryPath,ce as findInfrastructurePaths,pe as findTarget,I as formatErrorString,Te as generateTargetName,t as getDomainExportNames,q as getEnvironmentLabel,O as getErrorCode,c as getErrorMessage,x as getErrorStack,Y as getExpectedDuration,$ as getFriendlyResourceType,A as getSafeZoneName,p as hasAsciiStableConstructKey,g as hasErrorCode,Ie as inferContainerFromCandidates,K as isAccountStage,k as isAccountTier,Oe as isInfrastructureFile,de as isReservedAppName,H as mapSettledWithConcurrency,V as maskSensitiveOutput,R as normaliseError,re as parseGitRemoteUrl,U as parseShellArgs,l as singleton,v as sleep,Z as stageFromWireEnvironment,S as toKebab,i as toPascalCase,s as toScreamingSnake,m as toValidDatabaseName};
|
|
@@ -147,10 +147,9 @@ export type McpProtocolFrame = z.infer<typeof McpProtocolFrameSchema>;
|
|
|
147
147
|
* Scaffold protocol schemas — wire types for the `plan_app_scaffold`,
|
|
148
148
|
* `apply_app_scaffold`, and dry-run helper paths in `@fjall/mcp`.
|
|
149
149
|
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
* is a wire-level bug; both sides MUST move together.
|
|
150
|
+
* These schemas are the single source of truth: the CLI imports them from
|
|
151
|
+
* `@fjall/util/mcpProtocol` and re-exports aliases in
|
|
152
|
+
* `cli/src/operations/types.ts`.
|
|
154
153
|
*/
|
|
155
154
|
export declare const FileToWriteSchema: z.ZodObject<{
|
|
156
155
|
path: z.ZodString;
|
|
@@ -173,7 +172,7 @@ export declare const RegistryActionSchema: z.ZodObject<{
|
|
|
173
172
|
export type ScaffoldRegistryAction = z.infer<typeof RegistryActionSchema>;
|
|
174
173
|
export declare const TargetAccountSchema: z.ZodObject<{
|
|
175
174
|
name: z.ZodString;
|
|
176
|
-
environment: z.ZodString
|
|
175
|
+
environment: z.ZodNullable<z.ZodString>;
|
|
177
176
|
source: z.ZodString;
|
|
178
177
|
}, z.core.$strict>;
|
|
179
178
|
export type TargetAccount = z.infer<typeof TargetAccountSchema>;
|
|
@@ -247,12 +246,12 @@ export declare const ScaffoldPlanSchema: z.ZodObject<{
|
|
|
247
246
|
}, z.core.$strict>;
|
|
248
247
|
targetAccount: z.ZodNullable<z.ZodObject<{
|
|
249
248
|
name: z.ZodString;
|
|
250
|
-
environment: z.ZodString
|
|
249
|
+
environment: z.ZodNullable<z.ZodString>;
|
|
251
250
|
source: z.ZodString;
|
|
252
251
|
}, z.core.$strict>>;
|
|
253
252
|
targetAccountCandidates: z.ZodArray<z.ZodObject<{
|
|
254
253
|
name: z.ZodString;
|
|
255
|
-
environment: z.ZodString
|
|
254
|
+
environment: z.ZodNullable<z.ZodString>;
|
|
256
255
|
source: z.ZodString;
|
|
257
256
|
}, z.core.$strict>>;
|
|
258
257
|
filesToWrite: z.ZodArray<z.ZodObject<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{z as t}from"zod";const
|
|
1
|
+
import{z as t}from"zod";const l=2,f={AUTHENTICATION_REQUIRED:"AUTHENTICATION_REQUIRED",VALIDATION_ERROR:"VALIDATION_ERROR",INTERNAL_ERROR:"INTERNAL_ERROR",INVALID_SUBCOMMAND:"INVALID_SUBCOMMAND",INVALID_FRAME:"INVALID_FRAME"},a=1e3,e=t.literal(l),p=t.enum(["completed","error","skipped"]),g=t.object({v:e,kind:t.literal("step.start"),stepId:t.string().min(1),name:t.string().min(1),index:t.number().int().min(0),total:t.number().int().min(1)}).strict(),u=t.object({v:e,kind:t.literal("step.complete"),stepId:t.string().min(1),name:t.string().min(1),status:p,index:t.number().int().min(0),total:t.number().int().min(1),errorMessage:t.string().optional()}).strict(),d=t.object({v:e,kind:t.literal("warning"),message:t.string().min(1)}).strict(),b=t.object({code:t.string().min(1),message:t.string().min(1),details:t.record(t.string(),t.unknown()).optional()}).strict(),h=t.object({v:e,kind:t.literal("error"),error:b}).strict(),R=t.object({v:e,kind:t.literal("result"),data:t.unknown()}).strict(),A=t.object({v:e,kind:t.literal("auth.browser.required"),url:t.string().url(),externalId:t.string().min(1),region:t.string().min(1),environment:t.string().min(1),reason:t.string().min(1)}).strict(),S=t.object({v:e,kind:t.literal("auth.browser.complete"),awsAccountId:t.string().min(1),accountName:t.string().min(1),roleArn:t.string().min(1)}).strict(),I=t.discriminatedUnion("kind",[g,u,d,h,R,A,S]),s=t.object({path:t.string().min(1),sizeBytes:t.number().int().nonnegative(),collisionMode:t.enum(["create","overwrite"])}).strict(),c=t.object({type:t.enum(["register-application","create-activity","auto-link-repository","writeback-config-path"]),description:t.string().min(1)}).strict(),x=t.enum(["tinkerer","lightweight","standard","resilient","enterprise"]),k=t.enum(["lightweight","standard","resilient","enterprise","none"]),m=t.object({name:t.string().min(1),environment:t.string().min(1).nullable(),source:t.string().min(1)}).strict(),E=t.object({name:t.string().min(1),pattern:t.string().min(1).optional(),patternTier:x.optional(),patternDomain:t.string().min(1).optional(),network:k.optional(),template:t.string().min(1).optional(),docker:t.object({path:t.string().min(1).optional(),context:t.string().min(1).optional(),target:t.string().min(1).optional()}).strict().optional(),git:t.boolean().optional(),github:t.boolean().optional(),repoVisibility:t.enum(["private","public"]).optional(),intent:t.string().max(a).optional()}).strict(),T=t.object({planId:t.string().regex(/^[0-9a-f]{32}$/),normalisedPath:t.string().min(1),resolvedInputs:E,targetAccount:m.nullable(),targetAccountCandidates:t.array(m),filesToWrite:t.array(s),npmPackages:t.array(t.string().min(1)),registryActions:t.array(c),patternUnsupportedForDryRun:t.boolean().optional(),intent:t.string().max(a).optional(),framework:t.string().min(1).optional(),summary:t.string().min(1)}).strict(),N=t.object({filesToWrite:t.array(s),npmPackages:t.array(t.string().min(1)),registryActions:t.array(c),patternUnsupportedForDryRun:t.boolean().optional()}).strict(),j=t.object({path:t.string().min(1),name:t.string().min(1),mode:t.enum(["application","pattern"]),dependenciesInstalled:t.boolean().optional(),warning:t.string().optional(),dryRunArtefacts:N.optional()}).strict(),v=t.object({step:t.string().min(1),current:t.number().int().nonnegative(),total:t.number().int().positive().optional(),message:t.string().min(1)}).strict();function w(n){let o;try{o=JSON.parse(n)}catch(i){return{ok:!1,reason:"json",raw:n,error:i instanceof Error?i.message:String(i)}}const r=I.safeParse(o);return r.success?{ok:!0,frame:r.data}:{ok:!1,reason:"schema",raw:n,error:r.error.message}}export{S as AuthBrowserCompleteFrameSchema,A as AuthBrowserRequiredFrameSchema,N as DryRunArtefactsSchema,h as ErrorFrameSchema,s as FileToWriteSchema,a as INTENT_MAX_LENGTH,f as MCP_ERROR_CODES,l as MCP_PROTOCOL_VERSION,I as McpProtocolFrameSchema,c as RegistryActionSchema,E as ResolvedInputsSchema,R as ResultFrameSchema,T as ScaffoldPlanSchema,v as ScaffoldProgressFrameSchema,j as ScaffoldResultDataSchema,u as StepCompleteFrameSchema,g as StepStartFrameSchema,m as TargetAccountSchema,d as WarningFrameSchema,w as parseFrame};
|
package/dist/targets.d.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* A "target" is a deployment destination: an account + region combination
|
|
5
5
|
* with a canonical name derived from org config at runtime.
|
|
6
6
|
*/
|
|
7
|
+
import { type AccountTier } from "./environments.js";
|
|
7
8
|
/** Structural interface for the region fields on OrgConfig. */
|
|
8
9
|
export interface OrgConfigRegions {
|
|
9
10
|
primaryRegion?: string;
|
|
@@ -18,7 +19,9 @@ export declare function deriveRegionsFromOrgConfig(config: OrgConfigRegions): st
|
|
|
18
19
|
export interface TargetAccount {
|
|
19
20
|
name: string;
|
|
20
21
|
id: string;
|
|
21
|
-
|
|
22
|
+
/** Workload STAGE — null for structural accounts; read tier from `tier`. */
|
|
23
|
+
environment: string | null;
|
|
24
|
+
tier?: AccountTier;
|
|
22
25
|
}
|
|
23
26
|
export interface DerivedTarget {
|
|
24
27
|
name: string;
|
|
@@ -27,6 +30,15 @@ export interface DerivedTarget {
|
|
|
27
30
|
environment: string;
|
|
28
31
|
region: string;
|
|
29
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Canonical stage-or-tier fallback. Structural accounts carry a null workload
|
|
35
|
+
* stage, so display/naming/OU derivation fall back to the structural tier to
|
|
36
|
+
* stay non-null. Single source for every `environment ?? tier` consumer.
|
|
37
|
+
*/
|
|
38
|
+
export declare function environmentOrTier(account: {
|
|
39
|
+
environment?: string | null;
|
|
40
|
+
tier?: AccountTier | null;
|
|
41
|
+
}): string;
|
|
30
42
|
/**
|
|
31
43
|
* Generate a canonical target name from account name and region.
|
|
32
44
|
* e.g. ("Production-US", "us-east-1") → "production-us-use1"
|
package/dist/targets.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{abbreviateRegion as
|
|
1
|
+
import{abbreviateRegion as m}from"./regions.js";import{accountTier as c}from"./environments.js";function s(e){const r=[e.primaryRegion,...e.secondaryRegions??[],e.disasterRecoveryRegion].filter(t=>t!==void 0);return[...new Set(r)]}function u(e){return e.environment??c(e)}function f(e,r){return`${e.toLowerCase()}-${m(r)}`}function p(e,r){const t=[];for(const n of e){if(c(n)==="organisation")continue;const o=u(n);for(const i of r)t.push({name:f(n.name,i),accountName:n.name,accountId:n.id,environment:o,region:i})}return t.sort((n,o)=>{const i=n.environment.localeCompare(o.environment);if(i!==0)return i;const a=n.accountName.localeCompare(o.accountName);return a!==0?a:n.region.localeCompare(o.region)})}function v(e){return p(e.providerAccounts,s(e))}function l(e,r){if(r.length===0)return e;const t=new Set([e.primaryRegion,e.disasterRecoveryRegion].filter(Boolean)),n=r.filter(o=>!t.has(o));return{...e,secondaryRegions:n.length>0?n:void 0}}function R(e,r){return e.find(t=>t.name===r)}export{v as deriveAllTargets,s as deriveRegionsFromOrgConfig,p as deriveTargets,u as environmentOrTier,R as findTarget,f as generateTargetName,l as mergeSecondaryRegions};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fjall/util",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.13.0",
|
|
4
4
|
"description": "Common utility methods",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -117,5 +117,5 @@
|
|
|
117
117
|
"engines": {
|
|
118
118
|
"node": ">=22.0.0"
|
|
119
119
|
},
|
|
120
|
-
"gitHead": "
|
|
120
|
+
"gitHead": "5b16c5731256628f829d4168c65cf165b3516f9a"
|
|
121
121
|
}
|