@fjall/util 2.19.3 → 2.19.4
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 → config.d.ts} +10 -0
- package/dist/config.js +1 -0
- package/dist/fsScan.d.ts +3 -3
- package/dist/fsScan.js +1 -1
- package/dist/index.d.ts +18 -18
- package/dist/index.js +1 -1
- package/dist/infra/imageTags.js +1 -0
- package/dist/targets.js +1 -1
- package/package.json +4 -4
- package/dist/Config.js +0 -1
- package/dist/imageTags.js +0 -1
- /package/dist/{concurrency.d.ts → async/concurrency.d.ts} +0 -0
- /package/dist/{concurrency.js → async/concurrency.js} +0 -0
- /package/dist/{singleton.d.ts → async/singleton.d.ts} +0 -0
- /package/dist/{singleton.js → async/singleton.js} +0 -0
- /package/dist/{sleep.d.ts → async/sleep.d.ts} +0 -0
- /package/dist/{sleep.js → async/sleep.js} +0 -0
- /package/dist/{backupVault.d.ts → infra/backupVault.d.ts} +0 -0
- /package/dist/{backupVault.js → infra/backupVault.js} +0 -0
- /package/dist/{connectionsWire.d.ts → infra/connectionsWire.d.ts} +0 -0
- /package/dist/{connectionsWire.js → infra/connectionsWire.js} +0 -0
- /package/dist/{deriveContentHashTag.d.ts → infra/deriveContentHashTag.d.ts} +0 -0
- /package/dist/{deriveContentHashTag.js → infra/deriveContentHashTag.js} +0 -0
- /package/dist/{domainExports.d.ts → infra/domainExports.d.ts} +0 -0
- /package/dist/{domainExports.js → infra/domainExports.js} +0 -0
- /package/dist/{imageTags.d.ts → infra/imageTags.d.ts} +0 -0
- /package/dist/{regions.d.ts → infra/regions.d.ts} +0 -0
- /package/dist/{regions.js → infra/regions.js} +0 -0
- /package/dist/{tokenScopes.d.ts → infra/tokenScopes.d.ts} +0 -0
- /package/dist/{tokenScopes.js → infra/tokenScopes.js} +0 -0
- /package/dist/{accountNameCollision.d.ts → naming/accountNameCollision.d.ts} +0 -0
- /package/dist/{accountNameCollision.js → naming/accountNameCollision.js} +0 -0
- /package/dist/{caseConversion.d.ts → naming/caseConversion.d.ts} +0 -0
- /package/dist/{caseConversion.js → naming/caseConversion.js} +0 -0
- /package/dist/{reservedAppNames.d.ts → naming/reservedAppNames.d.ts} +0 -0
- /package/dist/{reservedAppNames.js → naming/reservedAppNames.js} +0 -0
- /package/dist/{appPath.d.ts → repo/appPath.d.ts} +0 -0
- /package/dist/{appPath.js → repo/appPath.js} +0 -0
- /package/dist/{findInfrastructurePaths.d.ts → repo/findInfrastructurePaths.d.ts} +0 -0
- /package/dist/{findInfrastructurePaths.js → repo/findInfrastructurePaths.js} +0 -0
- /package/dist/{findRepoRoot.d.ts → repo/findRepoRoot.d.ts} +0 -0
- /package/dist/{findRepoRoot.js → repo/findRepoRoot.js} +0 -0
- /package/dist/{gitRemoteParser.d.ts → repo/gitRemoteParser.d.ts} +0 -0
- /package/dist/{gitRemoteParser.js → repo/gitRemoteParser.js} +0 -0
- /package/dist/{inferContainerFromCandidates.d.ts → repo/inferContainerFromCandidates.d.ts} +0 -0
- /package/dist/{inferContainerFromCandidates.js → repo/inferContainerFromCandidates.js} +0 -0
- /package/dist/{scanLocalRepository.d.ts → repo/scanLocalRepository.d.ts} +0 -0
- /package/dist/{scanLocalRepository.js → repo/scanLocalRepository.js} +0 -0
- /package/dist/{scanTypes.d.ts → repo/scanTypes.d.ts} +0 -0
- /package/dist/{scanTypes.js → repo/scanTypes.js} +0 -0
package/dist/.minified
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
65 files minified at 2026-06-
|
|
1
|
+
65 files minified at 2026-06-22T21:29:50.013Z
|
|
@@ -151,6 +151,16 @@ export declare const RootConfigSchema: z.ZodObject<{
|
|
|
151
151
|
}, z.core.$strict>>>;
|
|
152
152
|
}, z.core.$strict>;
|
|
153
153
|
export type RootConfig = z.infer<typeof RootConfigSchema>;
|
|
154
|
+
/**
|
|
155
|
+
* Canonical serialiser for the root fjall-config.json — the single source of
|
|
156
|
+
* truth for the file's on-disk shape. Both `Config.saveConfig` and the webapp
|
|
157
|
+
* scaffold MUST route through this rather than hand-rolling the JSON, so the
|
|
158
|
+
* two can never drift (a scaffold emitting a key the loader later rejects is
|
|
159
|
+
* exactly the bug this prevents). The `RootConfig` input type makes an unknown
|
|
160
|
+
* key unrepresentable at compile time; the round-trip test asserts the emitted
|
|
161
|
+
* default validates against RootConfigSchema.
|
|
162
|
+
*/
|
|
163
|
+
export declare function serialiseRootConfig(config?: RootConfig): string;
|
|
154
164
|
/**
|
|
155
165
|
* Config class for loading and saving the root fjall-config.json.
|
|
156
166
|
* Single config file at fjall/fjall-config.json (or fjall-config.json at cwd).
|
package/dist/config.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import*as i from"fs";import*as f from"path";import{z as s}from"zod";import{failure as l,success as y}from"./docker/result.js";import{getErrorMessage as m}from"./errorUtils.js";import{logger as p}from"./logger.js";import{maskSensitiveOutput as g}from"./securityHelpers.js";const T=10,$=["compliance","governance","none"],F=["enforced","off"],R=["centralised","off"],K=["account","draining","org"],b="managementEvents",k="organisationManagementEvents",M=["active","draining","removed"],L="FjallTrailBucketName",N="FjallTrailKeyArn",I="OrganisationTrailBucketName",w=s.object({name:s.string(),type:s.enum(["apex","delegated"]),parentDomain:s.string().optional(),account:s.string().optional()}).strict(),C=s.object({activeTarget:s.string().optional(),domains:s.array(w).optional()}).strict(),E=s.object({activeTarget:s.string().optional(),domains:s.array(w).optional()});function S(h={}){return JSON.stringify(h,null,2)}const v=C.keyof().options;function j(h,e,t){const n=e[t];n!==void 0&&(h[t]=n)}class a{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<T;n++){const r=f.join(t,"fjall"),c=f.join(r,"fjall-config.json");if(i.existsSync(c))return r;const o=f.join(t,"fjall-config.json");if(i.existsSync(o))return t;const d=f.dirname(t);if(d===t)break;t=d}return null}static loadConfigFile(e){try{return i.accessSync(e,i.constants.R_OK),i.readFileSync(e,{encoding:"utf8"})}catch(t){return p.warn("Config",`Config file at ${e} could not be read; using defaults`,{file:e,error:g(m(t))}),null}}static loadConfig(e){const t=a.findConfigDirectory(e);if(!t)return new a;const n=f.join(t,"fjall-config.json"),r=a.loadConfigFile(n);if(r===null){const o=new a(void 0,n);return o.loadFailed=!0,o}let c;if(r!==""){let o;try{o=JSON.parse(r)}catch(u){throw a.formatZodError(u,"fjall-config.json")}const d=C.safeParse(o);if(d.success)c=d.data;else{const u=E.safeParse(o);c=u.success?u.data:{},p.warn("Config","fjall-config.json contains keys this version does not recognise; they were ignored (only activeTarget and domains are read). If this is an old config, regenerate it with `fjall create ...` or re-run `fjall connect`.",{file:n})}}return new a(c,n)}static formatZodError(e,t){if(e instanceof s.ZodError&&e.issues.length>0){const c=e.issues.map(o=>`${o.path.join(".")}: ${o.message}`).join("; ");return new Error(`Failed to parse ${t}: ${c}`)}const r=(e instanceof Error?e.message:String(e)).replace(/\n/g," ").substring(0,500);return new Error(`Failed to parse ${t}: ${r}`)}saveConfig(){let e=this.configPath;if(!e){const o=a.findConfigDirectory()||f.join(process.cwd(),"fjall");e=f.join(o,"fjall-config.json")}if(this.loadFailed)return l(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(o){return l(new Error(`Cannot create config directory ${t}: ${g(m(o))}`))}const n=a.assertWritable(e,t);if(!n.success)return n;const r=S(this.mergeWithDisk(e)),c=`${e}.tmp-${process.pid}`;try{i.writeFileSync(c,r,{mode:384}),i.renameSync(c,e)}catch(o){return l(new Error(`Failed to save ${e}: ${g(m(o))}`))}return y(void 0)}static assertWritable(e,t){if(i.existsSync(e))try{i.accessSync(e,i.constants.W_OK)}catch{return l(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 l(new Error(`Cannot save ${e}: the directory ${t} is not writable. Make it writable (e.g. chmod u+w ${t}) and retry.`))}return y(void 0)}mergeWithDisk(e){const t=a.readDiskConfigForMerge(e);if(t===void 0)return this.rootConfig;const n={...t};for(const r of v)j(n,this.rootConfig,r);for(const r of this.clearedKeys)delete n[r];return n}static readDiskConfigForMerge(e){if(!i.existsSync(e))return;let t;try{t=JSON.parse(i.readFileSync(e,{encoding:"utf8"}))}catch(r){p.warn("Config",`Could not re-read ${e} before saving; writing in-memory state without merging`,{file:e,error:g(m(r))});return}const n=C.safeParse(t);if(!n.success){p.warn("Config",`On-disk ${e} failed validation before saving; writing in-memory state without merging`,{file:e,error:g(n.error.message)});return}return n.data}static getConfigDirectory(e){return a.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{b as ACCOUNT_TRAIL_NAME,M as ACCOUNT_TRAIL_STATES,a as Config,k as ORGANISATION_TRAIL_NAME,I as ORG_TRAIL_BUCKET_OUTPUT_KEY,R as ROOT_ACCESS_MANAGEMENT_MODES,C as RootConfigSchema,F as S3_BPA_MODES,L as TRAIL_BUCKET_OUTPUT_KEY,N as TRAIL_KEY_ARN_OUTPUT_KEY,K as TRAIL_LIFECYCLE_STATES,$ as VAULT_LOCK_MODES,S as serialiseRootConfig};
|
package/dist/fsScan.d.ts
CHANGED
|
@@ -10,6 +10,6 @@
|
|
|
10
10
|
* - CLI (`createAppHandler`) → both `scanLocalRepository` + `findRepoRoot`
|
|
11
11
|
* - Webapp server-side code may import here too; webapp client code MUST NOT.
|
|
12
12
|
*/
|
|
13
|
-
export { scanLocalRepository, type ScanLocalRepositoryResult } from "./scanLocalRepository.js";
|
|
14
|
-
export { findRepoRoot } from "./findRepoRoot.js";
|
|
15
|
-
export { type ScanPath } from "./scanTypes.js";
|
|
13
|
+
export { scanLocalRepository, type ScanLocalRepositoryResult } from "./repo/scanLocalRepository.js";
|
|
14
|
+
export { findRepoRoot } from "./repo/findRepoRoot.js";
|
|
15
|
+
export { type ScanPath } from "./repo/scanTypes.js";
|
package/dist/fsScan.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{scanLocalRepository as e}from"./scanLocalRepository.js";import{findRepoRoot as t}from"./findRepoRoot.js";export{t as findRepoRoot,e as scanLocalRepository};
|
|
1
|
+
import{scanLocalRepository as e}from"./repo/scanLocalRepository.js";import{findRepoRoot as t}from"./repo/findRepoRoot.js";export{t as findRepoRoot,e as scanLocalRepository};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
export { DNS_APEX, getDomainExportNames, type ManagedDomainExports } from "./domainExports.js";
|
|
2
|
-
export { BACKUP_VAULT_NAME } from "./backupVault.js";
|
|
3
|
-
export { imageTagParameterName } from "./imageTags.js";
|
|
4
|
-
export { toPascalCase, toKebab, toValidDatabaseName, toScreamingSnake, capitalise, getSafeZoneName, accountConstructKey, hasAsciiStableConstructKey } from "./caseConversion.js";
|
|
5
|
-
export { findAccountNameCollision, type AccountNameCollision } from "./accountNameCollision.js";
|
|
1
|
+
export { DNS_APEX, getDomainExportNames, type ManagedDomainExports } from "./infra/domainExports.js";
|
|
2
|
+
export { BACKUP_VAULT_NAME } from "./infra/backupVault.js";
|
|
3
|
+
export { imageTagParameterName } from "./infra/imageTags.js";
|
|
4
|
+
export { toPascalCase, toKebab, toValidDatabaseName, toScreamingSnake, capitalise, getSafeZoneName, accountConstructKey, hasAsciiStableConstructKey } from "./naming/caseConversion.js";
|
|
5
|
+
export { findAccountNameCollision, type AccountNameCollision } from "./naming/accountNameCollision.js";
|
|
6
6
|
export { normaliseError, getErrorMessage, hasErrorCode, getErrorCode, getErrorStack, formatErrorString } from "./errorUtils.js";
|
|
7
|
-
export { singleton } from "./singleton.js";
|
|
7
|
+
export { singleton } from "./async/singleton.js";
|
|
8
8
|
export { DANGEROUS_ENV_VARS, filterDangerousEnvVars, maskSensitiveOutput, parseShellArgs } from "./securityHelpers.js";
|
|
9
|
-
export { sleep } from "./sleep.js";
|
|
10
|
-
export { mapSettledWithConcurrency } from "./concurrency.js";
|
|
9
|
+
export { sleep } from "./async/sleep.js";
|
|
10
|
+
export { mapSettledWithConcurrency } from "./async/concurrency.js";
|
|
11
11
|
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";
|
|
12
12
|
export { RESOURCE_CATEGORIES, type ResourceCategory, categoriseResource, getExpectedDuration, getFriendlyResourceType } from "./resourceCategorisation.js";
|
|
13
|
-
export { parseGitRemoteUrl, type GitProvider, type ParsedGitRemote } from "./gitRemoteParser.js";
|
|
14
|
-
export { abbreviateRegion, AWS_REGIONS_METADATA, DEFAULT_REGION, getRegionInfo, MAX_SECONDARY_REGIONS, OPT_IN_REGION_CODES, optInRegionWarning, regions, suggestRegionForTimezone, type RegionCode, type RegionInfo } from "./regions.js";
|
|
15
|
-
export { SCOPE_VALUES, type TokenScope } from "./tokenScopes.js";
|
|
16
|
-
export { ConnectionWireSchema, type ConnectionWire, ConnectionsListResponseSchema, type ConnectionsListResponse } from "./connectionsWire.js";
|
|
13
|
+
export { parseGitRemoteUrl, type GitProvider, type ParsedGitRemote } from "./repo/gitRemoteParser.js";
|
|
14
|
+
export { abbreviateRegion, AWS_REGIONS_METADATA, DEFAULT_REGION, getRegionInfo, MAX_SECONDARY_REGIONS, OPT_IN_REGION_CODES, optInRegionWarning, regions, suggestRegionForTimezone, type RegionCode, type RegionInfo } from "./infra/regions.js";
|
|
15
|
+
export { SCOPE_VALUES, type TokenScope } from "./infra/tokenScopes.js";
|
|
16
|
+
export { ConnectionWireSchema, type ConnectionWire, ConnectionsListResponseSchema, type ConnectionsListResponse } from "./infra/connectionsWire.js";
|
|
17
17
|
export { deriveRegionsFromOrgConfig, deriveTargets, deriveAllTargets, environmentOrTier, findTarget, generateTargetName, type OrgConfigRegions, type TargetAccount, type DerivedTarget } from "./targets.js";
|
|
18
|
-
export { buildAppConfigPath } from "./appPath.js";
|
|
19
|
-
export { type ScanPath } from "./scanTypes.js";
|
|
20
|
-
export { findInfrastructurePaths, findBoundaryPath, isInfrastructureFile, type MarkerEntry, type FindInfrastructurePathsOptions } from "./findInfrastructurePaths.js";
|
|
21
|
-
export { inferContainerFromCandidates } from "./inferContainerFromCandidates.js";
|
|
22
|
-
export { RESERVED_APP_NAMES, type ReservedAppName, RESERVED_APP_NAME_MESSAGE, isReservedAppName } from "./reservedAppNames.js";
|
|
23
|
-
export { deriveContentHashTag } from "./deriveContentHashTag.js";
|
|
18
|
+
export { buildAppConfigPath } from "./repo/appPath.js";
|
|
19
|
+
export { type ScanPath } from "./repo/scanTypes.js";
|
|
20
|
+
export { findInfrastructurePaths, findBoundaryPath, isInfrastructureFile, type MarkerEntry, type FindInfrastructurePathsOptions } from "./repo/findInfrastructurePaths.js";
|
|
21
|
+
export { inferContainerFromCandidates } from "./repo/inferContainerFromCandidates.js";
|
|
22
|
+
export { RESERVED_APP_NAMES, type ReservedAppName, RESERVED_APP_NAME_MESSAGE, isReservedAppName } from "./naming/reservedAppNames.js";
|
|
23
|
+
export { deriveContentHashTag } from "./infra/deriveContentHashTag.js";
|
|
24
24
|
export { MIGRATION_SNAPSHOT_NAME_PREFIX, EXPECTED_SCHEMA_VERSION_ENV, EXPECTED_SCHEMA_VERSION_TOOL_ENV, EXPECTED_CH_SCHEMA_VERSION_ENV, SCHEMA_ADMIN_USER_ENV, SCHEMA_ADMIN_PASSWORD_ENV, PRISMA_MIGRATION_DIR_RE, CLICKHOUSE_MIGRATION_SKIP_RE } from "./migration/constants.js";
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{DNS_APEX as o,getDomainExportNames as t}from"./domainExports.js";import{BACKUP_VAULT_NAME as n}from"./backupVault.js";import{imageTagParameterName as i}from"./imageTags.js";import{toPascalCase as _,toKebab as A,toValidDatabaseName as m,toScreamingSnake as s,capitalise as R,getSafeZoneName as C,accountConstructKey as N,hasAsciiStableConstructKey as T}from"./caseConversion.js";import{findAccountNameCollision as p}from"./accountNameCollision.js";import{normaliseError as O,getErrorMessage as c,hasErrorCode as I,getErrorCode as x,getErrorStack as u,formatErrorString as P}from"./errorUtils.js";import{singleton as M}from"./singleton.js";import{DANGEROUS_ENV_VARS as D,filterDangerousEnvVars as V,maskSensitiveOutput as U,parseShellArgs as G}from"./securityHelpers.js";import{sleep as h}from"./sleep.js";import{mapSettledWithConcurrency as H}from"./concurrency.js";import{ACCOUNT_STAGES_WITH_ROOT as F,STRUCTURAL_ENVIRONMENTS as W,ACCOUNT_STAGES as y,ACCOUNT_STAGE_LABELS as K,isAccountStage as X,ACCOUNT_TIERS as k,AccountTierSchema as B,isAccountTier as z,environmentToTier as Y,stageFromWireEnvironment as Z,accountTier as j,getEnvironmentLabel as q,ACCOUNT_ROLES as w}from"./environments.js";import{RESOURCE_CATEGORIES as Q,categoriseResource as $,getExpectedDuration as ee,getFriendlyResourceType as re}from"./resourceCategorisation.js";import{parseGitRemoteUrl as te}from"./gitRemoteParser.js";import{abbreviateRegion as ne,AWS_REGIONS_METADATA as ae,DEFAULT_REGION as ie,getRegionInfo as Se,MAX_SECONDARY_REGIONS as _e,OPT_IN_REGION_CODES as Ae,optInRegionWarning as me,regions as se,suggestRegionForTimezone as Re}from"./regions.js";import{SCOPE_VALUES as Ne}from"./tokenScopes.js";import{ConnectionWireSchema as ge,ConnectionsListResponseSchema as pe}from"./connectionsWire.js";import{deriveRegionsFromOrgConfig as Oe,deriveTargets as ce,deriveAllTargets as Ie,environmentOrTier as xe,findTarget as ue,generateTargetName as Pe}from"./targets.js";import{buildAppConfigPath as Me}from"./appPath.js";import{findInfrastructurePaths as De,findBoundaryPath as Ve,isInfrastructureFile as Ue}from"./findInfrastructurePaths.js";import{inferContainerFromCandidates as ve}from"./inferContainerFromCandidates.js";import{RESERVED_APP_NAMES as Le,RESERVED_APP_NAME_MESSAGE as He,isReservedAppName as be}from"./reservedAppNames.js";import{deriveContentHashTag as We}from"./deriveContentHashTag.js";import{MIGRATION_SNAPSHOT_NAME_PREFIX as Ke,EXPECTED_SCHEMA_VERSION_ENV as Xe,EXPECTED_SCHEMA_VERSION_TOOL_ENV as ke,EXPECTED_CH_SCHEMA_VERSION_ENV as Be,SCHEMA_ADMIN_USER_ENV as ze,SCHEMA_ADMIN_PASSWORD_ENV as Ye,PRISMA_MIGRATION_DIR_RE as Ze,CLICKHOUSE_MIGRATION_SKIP_RE as je}from"./migration/constants.js";export{w as ACCOUNT_ROLES,y as ACCOUNT_STAGES,F as ACCOUNT_STAGES_WITH_ROOT,K as ACCOUNT_STAGE_LABELS,k as ACCOUNT_TIERS,ae as AWS_REGIONS_METADATA,B as AccountTierSchema,n as BACKUP_VAULT_NAME,je as CLICKHOUSE_MIGRATION_SKIP_RE,ge as ConnectionWireSchema,pe as ConnectionsListResponseSchema,D as DANGEROUS_ENV_VARS,ie as DEFAULT_REGION,o as DNS_APEX,Be as EXPECTED_CH_SCHEMA_VERSION_ENV,Xe as EXPECTED_SCHEMA_VERSION_ENV,ke as EXPECTED_SCHEMA_VERSION_TOOL_ENV,_e as MAX_SECONDARY_REGIONS,Ke as MIGRATION_SNAPSHOT_NAME_PREFIX,Ae as OPT_IN_REGION_CODES,Ze as PRISMA_MIGRATION_DIR_RE,Le as RESERVED_APP_NAMES,He as RESERVED_APP_NAME_MESSAGE,Q as RESOURCE_CATEGORIES,Ye as SCHEMA_ADMIN_PASSWORD_ENV,ze as SCHEMA_ADMIN_USER_ENV,Ne as SCOPE_VALUES,W as STRUCTURAL_ENVIRONMENTS,ne as abbreviateRegion,N as accountConstructKey,j as accountTier,Me as buildAppConfigPath,R as capitalise,$ as categoriseResource,Ie as deriveAllTargets,We as deriveContentHashTag,Oe as deriveRegionsFromOrgConfig,ce as deriveTargets,xe as environmentOrTier,Y as environmentToTier,V as filterDangerousEnvVars,p as findAccountNameCollision,Ve as findBoundaryPath,De as findInfrastructurePaths,ue as findTarget,P as formatErrorString,Pe as generateTargetName,t as getDomainExportNames,q as getEnvironmentLabel,x as getErrorCode,c as getErrorMessage,u as getErrorStack,ee as getExpectedDuration,re as getFriendlyResourceType,Se as getRegionInfo,C as getSafeZoneName,T as hasAsciiStableConstructKey,I as hasErrorCode,i as imageTagParameterName,ve as inferContainerFromCandidates,X as isAccountStage,z as isAccountTier,Ue as isInfrastructureFile,be as isReservedAppName,H as mapSettledWithConcurrency,U as maskSensitiveOutput,O as normaliseError,me as optInRegionWarning,te as parseGitRemoteUrl,G as parseShellArgs,se as regions,M as singleton,h as sleep,Z as stageFromWireEnvironment,Re as suggestRegionForTimezone,A as toKebab,_ as toPascalCase,s as toScreamingSnake,m as toValidDatabaseName};
|
|
1
|
+
import{DNS_APEX as o,getDomainExportNames as t}from"./infra/domainExports.js";import{BACKUP_VAULT_NAME as n}from"./infra/backupVault.js";import{imageTagParameterName as i}from"./infra/imageTags.js";import{toPascalCase as _,toKebab as A,toValidDatabaseName as m,toScreamingSnake as s,capitalise as R,getSafeZoneName as C,accountConstructKey as N,hasAsciiStableConstructKey as T}from"./naming/caseConversion.js";import{findAccountNameCollision as p}from"./naming/accountNameCollision.js";import{normaliseError as O,getErrorMessage as c,hasErrorCode as I,getErrorCode as x,getErrorStack as u,formatErrorString as P}from"./errorUtils.js";import{singleton as M}from"./async/singleton.js";import{DANGEROUS_ENV_VARS as D,filterDangerousEnvVars as V,maskSensitiveOutput as U,parseShellArgs as G}from"./securityHelpers.js";import{sleep as h}from"./async/sleep.js";import{mapSettledWithConcurrency as H}from"./async/concurrency.js";import{ACCOUNT_STAGES_WITH_ROOT as F,STRUCTURAL_ENVIRONMENTS as W,ACCOUNT_STAGES as y,ACCOUNT_STAGE_LABELS as K,isAccountStage as X,ACCOUNT_TIERS as k,AccountTierSchema as B,isAccountTier as z,environmentToTier as Y,stageFromWireEnvironment as Z,accountTier as j,getEnvironmentLabel as q,ACCOUNT_ROLES as w}from"./environments.js";import{RESOURCE_CATEGORIES as Q,categoriseResource as $,getExpectedDuration as ee,getFriendlyResourceType as re}from"./resourceCategorisation.js";import{parseGitRemoteUrl as te}from"./repo/gitRemoteParser.js";import{abbreviateRegion as ne,AWS_REGIONS_METADATA as ae,DEFAULT_REGION as ie,getRegionInfo as Se,MAX_SECONDARY_REGIONS as _e,OPT_IN_REGION_CODES as Ae,optInRegionWarning as me,regions as se,suggestRegionForTimezone as Re}from"./infra/regions.js";import{SCOPE_VALUES as Ne}from"./infra/tokenScopes.js";import{ConnectionWireSchema as ge,ConnectionsListResponseSchema as pe}from"./infra/connectionsWire.js";import{deriveRegionsFromOrgConfig as Oe,deriveTargets as ce,deriveAllTargets as Ie,environmentOrTier as xe,findTarget as ue,generateTargetName as Pe}from"./targets.js";import{buildAppConfigPath as Me}from"./repo/appPath.js";import{findInfrastructurePaths as De,findBoundaryPath as Ve,isInfrastructureFile as Ue}from"./repo/findInfrastructurePaths.js";import{inferContainerFromCandidates as ve}from"./repo/inferContainerFromCandidates.js";import{RESERVED_APP_NAMES as Le,RESERVED_APP_NAME_MESSAGE as He,isReservedAppName as be}from"./naming/reservedAppNames.js";import{deriveContentHashTag as We}from"./infra/deriveContentHashTag.js";import{MIGRATION_SNAPSHOT_NAME_PREFIX as Ke,EXPECTED_SCHEMA_VERSION_ENV as Xe,EXPECTED_SCHEMA_VERSION_TOOL_ENV as ke,EXPECTED_CH_SCHEMA_VERSION_ENV as Be,SCHEMA_ADMIN_USER_ENV as ze,SCHEMA_ADMIN_PASSWORD_ENV as Ye,PRISMA_MIGRATION_DIR_RE as Ze,CLICKHOUSE_MIGRATION_SKIP_RE as je}from"./migration/constants.js";export{w as ACCOUNT_ROLES,y as ACCOUNT_STAGES,F as ACCOUNT_STAGES_WITH_ROOT,K as ACCOUNT_STAGE_LABELS,k as ACCOUNT_TIERS,ae as AWS_REGIONS_METADATA,B as AccountTierSchema,n as BACKUP_VAULT_NAME,je as CLICKHOUSE_MIGRATION_SKIP_RE,ge as ConnectionWireSchema,pe as ConnectionsListResponseSchema,D as DANGEROUS_ENV_VARS,ie as DEFAULT_REGION,o as DNS_APEX,Be as EXPECTED_CH_SCHEMA_VERSION_ENV,Xe as EXPECTED_SCHEMA_VERSION_ENV,ke as EXPECTED_SCHEMA_VERSION_TOOL_ENV,_e as MAX_SECONDARY_REGIONS,Ke as MIGRATION_SNAPSHOT_NAME_PREFIX,Ae as OPT_IN_REGION_CODES,Ze as PRISMA_MIGRATION_DIR_RE,Le as RESERVED_APP_NAMES,He as RESERVED_APP_NAME_MESSAGE,Q as RESOURCE_CATEGORIES,Ye as SCHEMA_ADMIN_PASSWORD_ENV,ze as SCHEMA_ADMIN_USER_ENV,Ne as SCOPE_VALUES,W as STRUCTURAL_ENVIRONMENTS,ne as abbreviateRegion,N as accountConstructKey,j as accountTier,Me as buildAppConfigPath,R as capitalise,$ as categoriseResource,Ie as deriveAllTargets,We as deriveContentHashTag,Oe as deriveRegionsFromOrgConfig,ce as deriveTargets,xe as environmentOrTier,Y as environmentToTier,V as filterDangerousEnvVars,p as findAccountNameCollision,Ve as findBoundaryPath,De as findInfrastructurePaths,ue as findTarget,P as formatErrorString,Pe as generateTargetName,t as getDomainExportNames,q as getEnvironmentLabel,x as getErrorCode,c as getErrorMessage,u as getErrorStack,ee as getExpectedDuration,re as getFriendlyResourceType,Se as getRegionInfo,C as getSafeZoneName,T as hasAsciiStableConstructKey,I as hasErrorCode,i as imageTagParameterName,ve as inferContainerFromCandidates,X as isAccountStage,z as isAccountTier,Ue as isInfrastructureFile,be as isReservedAppName,H as mapSettledWithConcurrency,U as maskSensitiveOutput,O as normaliseError,me as optInRegionWarning,te as parseGitRemoteUrl,G as parseShellArgs,se as regions,M as singleton,h as sleep,Z as stageFromWireEnvironment,Re as suggestRegionForTimezone,A as toKebab,_ as toPascalCase,s as toScreamingSnake,m as toValidDatabaseName};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{toPascalCase as e}from"../naming/caseConversion.js";function m(a){return`${e(a)}ImageTag`}export{m as imageTagParameterName};
|
package/dist/targets.js
CHANGED
|
@@ -1 +1 @@
|
|
|
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};
|
|
1
|
+
import{abbreviateRegion as m}from"./infra/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.19.
|
|
3
|
+
"version": "2.19.4",
|
|
4
4
|
"description": "Common utility methods",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
"default": "./dist/index.js"
|
|
12
12
|
},
|
|
13
13
|
"./config": {
|
|
14
|
-
"types": "./dist/
|
|
15
|
-
"default": "./dist/
|
|
14
|
+
"types": "./dist/config.d.ts",
|
|
15
|
+
"default": "./dist/config.js"
|
|
16
16
|
},
|
|
17
17
|
"./constructMap": {
|
|
18
18
|
"types": "./dist/constructMap.d.ts",
|
|
@@ -117,5 +117,5 @@
|
|
|
117
117
|
"engines": {
|
|
118
118
|
"node": ">=22.0.0"
|
|
119
119
|
},
|
|
120
|
-
"gitHead": "
|
|
120
|
+
"gitHead": "269cdbb75bb3b35c5f2b393bd2a883f5ebbd4155"
|
|
121
121
|
}
|
package/dist/Config.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import*as i from"fs";import*as f from"path";import{z as c}from"zod";import{failure as d,success as C}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,D=["compliance","governance","none"],_=["enforced","off"],$=["centralised","off"],x=["account","draining","org"],F="managementEvents",K="organisationManagementEvents",M=["active","draining","removed"],R="FjallTrailBucketName",b="FjallTrailKeyArn",k="OrganisationTrailBucketName",T=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(T).optional()}).strict(),w=m.keyof().options;function E(h,e,t){const n=e[t];n!==void 0&&(h[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 C(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 C(void 0)}mergeWithDisk(e){const t=s.readDiskConfigForMerge(e);if(t===void 0)return this.rootConfig;const n={...t};for(const o of w)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{F as ACCOUNT_TRAIL_NAME,M as ACCOUNT_TRAIL_STATES,s as Config,K as ORGANISATION_TRAIL_NAME,k as ORG_TRAIL_BUCKET_OUTPUT_KEY,$ as ROOT_ACCESS_MANAGEMENT_MODES,m as RootConfigSchema,_ as S3_BPA_MODES,R as TRAIL_BUCKET_OUTPUT_KEY,b as TRAIL_KEY_ARN_OUTPUT_KEY,x as TRAIL_LIFECYCLE_STATES,D as VAULT_LOCK_MODES};
|
package/dist/imageTags.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{toPascalCase as e}from"./caseConversion.js";function m(a){return`${e(a)}ImageTag`}export{m as imageTagParameterName};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|