@fjall/util 35.0.0 → 37.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/.minified +1 -1
- package/dist/aws/index.d.ts +1 -1
- package/dist/aws/index.js +1 -1
- package/dist/aws/infraTags.d.ts +18 -0
- package/dist/aws/infraTags.js +1 -1
- package/dist/backupTiers.d.ts +26 -2
- package/dist/backupTiers.js +1 -1
- package/dist/codemod/statementTypes.d.ts +16 -0
- package/dist/codemod/statementTypes.js +1 -0
- package/dist/deploy/approvalTokenOutput.d.ts +6 -4
- package/dist/fjallHome.d.ts +4 -3
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/infra/tokenScopes.d.ts +15 -0
- package/dist/infra/tokenScopes.js +1 -1
- package/dist/patterns/patternTypes.d.ts +13 -0
- package/dist/patterns/patternTypes.js +1 -1
- package/dist/posturePolicy/index.d.ts +15 -0
- package/dist/posturePolicy/index.js +1 -0
- package/dist/posturePolicy/issueStatusLabels.d.ts +83 -0
- package/dist/posturePolicy/issueStatusLabels.js +1 -0
- package/dist/posturePolicy/machineLane.d.ts +13 -0
- package/dist/posturePolicy/machineLane.js +1 -0
- package/dist/posturePolicy/registry.d.ts +271 -0
- package/dist/posturePolicy/registry.js +1 -0
- package/dist/posturePolicy/resourceKinds.d.ts +27 -0
- package/dist/posturePolicy/resourceKinds.js +1 -0
- package/dist/posturePolicy/tierConsent.d.ts +69 -0
- package/dist/posturePolicy/tierConsent.js +1 -0
- package/dist/scaffold/ensureGitignore.js +6 -6
- package/dist/securityHelpers.js +1 -1
- package/package.json +6 -2
package/dist/.minified
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
131 files minified at 2026-09-14T08:49:14.213Z
|
package/dist/aws/index.d.ts
CHANGED
|
@@ -6,6 +6,6 @@ export { FAILURE_ANALYSIS_CATEGORIES, type FailureAnalysisCategory } from "./fai
|
|
|
6
6
|
export { maskFailureAnalysis } from "./maskFailureAnalysis.js";
|
|
7
7
|
export { classifyDriftSuspectEvents, findCurrentOperationStart, isDriftSuspectReason, isOperationOpeningEvent, type DriftSuspectEvent } from "./driftSuspects.js";
|
|
8
8
|
export { IPAM_OPERATIONS_POOL_TAG_KEY, formatIpamPairTagValue } from "./ipamTags.js";
|
|
9
|
-
export { FJALL_RESOURCE_TYPE_TAG_KEY, FJALL_RESOURCE_TYPES, type FjallResourceType, KMS_RETENTION_TAG_KEY, S3_VERSIONING_EXEMPT_TAG_KEY, S3_VERSIONING_EXEMPTIONS, SDK_PRE_EMPTY_TAG_KEY, type S3VersioningExemption } from "./infraTags.js";
|
|
9
|
+
export { FJALL_RESOURCE_TYPE_TAG_KEY, FJALL_RESOURCE_TYPES, type FjallResourceType, KMS_ALIAS_TAG_KEY, KMS_RETENTION_TAG_KEY, S3_VERSIONING_EXEMPT_TAG_KEY, S3_VERSIONING_EXEMPTIONS, SDK_PRE_EMPTY_TAG_KEY, type S3VersioningExemption } from "./infraTags.js";
|
|
10
10
|
export { COST_ALLOCATION_TAGS, DEFAULT_COST_ALLOCATION_ENVIRONMENT, DEFAULT_COST_ALLOCATION_OWNER, ecrCreateRepositoryTags, rdsPreMigrationSnapshotTags, type AwsSdkTag, type EcrCreateTag } from "./costAllocationTags.js";
|
|
11
11
|
export { ACCOUNT_MONITORING_ROLE_NAME } from "./monitoringRole.js";
|
package/dist/aws/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AWSError as E,NoRolesFoundError as e,InvalidCredentialsError as _,SSOTokenExpiredError as T,MissingRegionError as
|
|
1
|
+
import{AWSError as E,NoRolesFoundError as e,InvalidCredentialsError as _,SSOTokenExpiredError as T,MissingRegionError as A,ProfileNotFoundError as t,CommandError as O,isAWSError as S,isNoRolesFoundError as s,isSSOUnauthorizedError as i}from"./errors.js";import{STACK_NOT_FOUND_PATTERN as N,CDK_NO_STACKS_MATCH as n,isResourceEvent as R}from"./cloudformationTypes.js";import{countResourceProgress as C,formatElapsed as I}from"./deployProgress.js";import{CloudFormationFailureAnalyser as m}from"./CloudFormationFailureAnalyser.js";import{FAILURE_ANALYSIS_CATEGORIES as u}from"./failureAnalysisCategories.js";import{maskFailureAnalysis as l}from"./maskFailureAnalysis.js";import{classifyDriftSuspectEvents as x,findCurrentOperationStart as F,isDriftSuspectReason as K,isOperationOpeningEvent as M}from"./driftSuspects.js";import{IPAM_OPERATIONS_POOL_TAG_KEY as Y,formatIpamPairTagValue as g}from"./ipamTags.js";import{FJALL_RESOURCE_TYPE_TAG_KEY as c,FJALL_RESOURCE_TYPES as D,KMS_ALIAS_TAG_KEY as v,KMS_RETENTION_TAG_KEY as y,S3_VERSIONING_EXEMPT_TAG_KEY as V,S3_VERSIONING_EXEMPTIONS as W,SDK_PRE_EMPTY_TAG_KEY as h}from"./infraTags.js";import{COST_ALLOCATION_TAGS as J,DEFAULT_COST_ALLOCATION_ENVIRONMENT as X,DEFAULT_COST_ALLOCATION_OWNER as z,ecrCreateRepositoryTags as H,rdsPreMigrationSnapshotTags as b}from"./costAllocationTags.js";import{ACCOUNT_MONITORING_ROLE_NAME as q}from"./monitoringRole.js";export{q as ACCOUNT_MONITORING_ROLE_NAME,E as AWSError,n as CDK_NO_STACKS_MATCH,J as COST_ALLOCATION_TAGS,m as CloudFormationFailureAnalyser,O as CommandError,X as DEFAULT_COST_ALLOCATION_ENVIRONMENT,z as DEFAULT_COST_ALLOCATION_OWNER,u as FAILURE_ANALYSIS_CATEGORIES,D as FJALL_RESOURCE_TYPES,c as FJALL_RESOURCE_TYPE_TAG_KEY,Y as IPAM_OPERATIONS_POOL_TAG_KEY,_ as InvalidCredentialsError,v as KMS_ALIAS_TAG_KEY,y as KMS_RETENTION_TAG_KEY,A as MissingRegionError,e as NoRolesFoundError,t as ProfileNotFoundError,W as S3_VERSIONING_EXEMPTIONS,V as S3_VERSIONING_EXEMPT_TAG_KEY,h as SDK_PRE_EMPTY_TAG_KEY,T as SSOTokenExpiredError,N as STACK_NOT_FOUND_PATTERN,x as classifyDriftSuspectEvents,C as countResourceProgress,H as ecrCreateRepositoryTags,F as findCurrentOperationStart,I as formatElapsed,g as formatIpamPairTagValue,S as isAWSError,K as isDriftSuspectReason,s as isNoRolesFoundError,M as isOperationOpeningEvent,R as isResourceEvent,i as isSSOUnauthorizedError,l as maskFailureAnalysis,b as rdsPreMigrationSnapshotTags};
|
package/dist/aws/infraTags.d.ts
CHANGED
|
@@ -32,6 +32,24 @@ export declare const SDK_PRE_EMPTY_TAG_KEY = "fjall:sdk-pre-empty";
|
|
|
32
32
|
* `__tests__/infraTags.test.ts` guards against casual renames.
|
|
33
33
|
*/
|
|
34
34
|
export declare const KMS_RETENTION_TAG_KEY = "fjall:kms:retention";
|
|
35
|
+
/**
|
|
36
|
+
* The KMS alias marker tag, stamped beside [[KMS_RETENTION_TAG_KEY]] on every
|
|
37
|
+
* retained key and valued with the key's alias name as `kms list-aliases`
|
|
38
|
+
* reports it (`alias/cmk/<stack>/FjallStackEncryptionKey`).
|
|
39
|
+
*
|
|
40
|
+
* A retained key outlives its stack; its `AWS::KMS::Alias` does not — the
|
|
41
|
+
* alias is an ordinary stack resource and goes with the stack delete — and
|
|
42
|
+
* CloudFormation stamps none of its `aws:cloudformation:*` tags on KMS keys.
|
|
43
|
+
* So once the stack is gone nothing but this tag says which key a stack's
|
|
44
|
+
* `FjallStackEncryptionKey` was. The deploy-test harness reads it back
|
|
45
|
+
* (`deploy-tests/lib/releaseStackKeys.mts`) to find the stack keys a
|
|
46
|
+
* torn-down suite retained, and a posture scan can name a stray key's
|
|
47
|
+
* origin by it.
|
|
48
|
+
*
|
|
49
|
+
* Deployed infrastructure state, pinned like its sibling: a rename would
|
|
50
|
+
* strip every retained key of its origin until the next deploy.
|
|
51
|
+
*/
|
|
52
|
+
export declare const KMS_ALIAS_TAG_KEY = "fjall:kms:alias";
|
|
35
53
|
/**
|
|
36
54
|
* The Fjall resource-type marker tag key, shared by producers and consumers:
|
|
37
55
|
*
|
package/dist/aws/infraTags.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e="fjall:sdk-pre-empty",t="fjall:kms:retention",r="fjall:resource:type",p={vpcPeering:"vpc-peering",vpcPeeringAccepter:"vpc-peering-accepter",deployTimeWriter:"deploy-time-writer"},
|
|
1
|
+
const e="fjall:sdk-pre-empty",t="fjall:kms:retention",r="fjall:kms:alias",o="fjall:resource:type",p={vpcPeering:"vpc-peering",vpcPeeringAccepter:"vpc-peering-accepter",deployTimeWriter:"deploy-time-writer"},_="fjall:s3:versioning-exempt",c=["build-output","isr-cache","cold-tier","access-logs"];export{p as FJALL_RESOURCE_TYPES,o as FJALL_RESOURCE_TYPE_TAG_KEY,r as KMS_ALIAS_TAG_KEY,t as KMS_RETENTION_TAG_KEY,c as S3_VERSIONING_EXEMPTIONS,_ as S3_VERSIONING_EXEMPT_TAG_KEY,e as SDK_PRE_EMPTY_TAG_KEY};
|
package/dist/backupTiers.d.ts
CHANGED
|
@@ -88,7 +88,31 @@ export interface BackupTierDefaults {
|
|
|
88
88
|
*/
|
|
89
89
|
export declare const BACKUP_TIER_DEFAULTS: Readonly<Record<BackupTier, BackupTierDefaults>>;
|
|
90
90
|
/**
|
|
91
|
-
* The
|
|
92
|
-
*
|
|
91
|
+
* The column an app with no tier (no `backup` on the App, or `backup: false`)
|
|
92
|
+
* runs. Declaring it is free by construction — the same defaults plus the DR
|
|
93
|
+
* tag — which is why the webapp's posture cure proposes exactly this tier.
|
|
94
|
+
*/
|
|
95
|
+
export declare const DEFAULT_BACKUP_TIER = "standard";
|
|
96
|
+
/**
|
|
97
|
+
* The tier-owned default for one knob. An undefined tier reads the
|
|
98
|
+
* [[DEFAULT_BACKUP_TIER]] column.
|
|
93
99
|
*/
|
|
94
100
|
export declare function tierDefault<K extends keyof BackupTierDefaults>(tier: BackupTier | undefined, knob: K): BackupTierDefaults[K];
|
|
101
|
+
/**
|
|
102
|
+
* The tag key AWS Backup plan selection rules match on. The constructs stamp
|
|
103
|
+
* it (`App.applyBackupTier()` app-wide, `StandardTagsAspect` per resource,
|
|
104
|
+
* `BackupPlan` as the selection key). The webapp's posture rules
|
|
105
|
+
* (`assetParser`, `missing-dr-tier-tag`) read it back from discovered
|
|
106
|
+
* resources and re-spell it until they import this — TODO 2026-09-14,
|
|
107
|
+
* owner: paul — tracked in the 2026-09-05 remediation-raises build
|
|
108
|
+
* prompt, § 10 Train E-webapp record ("util fold").
|
|
109
|
+
*/
|
|
110
|
+
export declare const BACKUP_TIER_TAG_KEY = "fjall:disasterRecovery:tier";
|
|
111
|
+
/**
|
|
112
|
+
* Application backup tier → AWS Backup plan tag VALUE. `standard` maps to
|
|
113
|
+
* `default` (the plan every untiered resource joins), the other tiers to
|
|
114
|
+
* their own name. `Record<BackupTier, string>` is the presence guard: a new
|
|
115
|
+
* tier without a row fails typecheck here. The webapp's tag-value vocabulary
|
|
116
|
+
* re-spells these until it imports this map — same TODO as the key above.
|
|
117
|
+
*/
|
|
118
|
+
export declare const BACKUP_TIER_TAG_MAP: Readonly<Record<BackupTier, string>>;
|
package/dist/backupTiers.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var a=Object.defineProperty;var s=(e,t)=>a(e,"name",{value:t,configurable:!0});import{z as n}from"zod";const r=["standard","resilient","enterprise"],u=n.enum(r),o=new Set(r);function g(e){return o.has(e)}s(g,"isBackupTier");const i=Object.freeze({standard:Object.freeze({s3Versioned:!1,rdsBackupRetentionDays:14,deletionProtection:!1,customerManagedKeys:!1,containerInsights:!1,albAccessLogs:!1,cloudFrontLogging:!1,lambdaTracing:!1,databaseInsightsMode:"standard"}),resilient:Object.freeze({s3Versioned:!0,rdsBackupRetentionDays:30,deletionProtection:!0,customerManagedKeys:!1,containerInsights:!1,albAccessLogs:!1,cloudFrontLogging:!1,lambdaTracing:!1,databaseInsightsMode:"standard"}),enterprise:Object.freeze({s3Versioned:!0,rdsBackupRetentionDays:35,deletionProtection:!0,customerManagedKeys:!0,containerInsights:!0,albAccessLogs:!0,cloudFrontLogging:!0,lambdaTracing:!0,databaseInsightsMode:"advanced"})}),c="standard";function f(e,t){return i[e??c][t]}s(f,"tierDefault");const p="fjall:disasterRecovery:tier",T=Object.freeze({standard:"default",resilient:"resilient",enterprise:"enterprise"});export{r as BACKUP_TIERS,i as BACKUP_TIER_DEFAULTS,p as BACKUP_TIER_TAG_KEY,T as BACKUP_TIER_TAG_MAP,u as BackupTierSchema,c as DEFAULT_BACKUP_TIER,g as isBackupTier,f as tierDefault};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The codemod's statement-type vocabulary: the factory-built statements
|
|
3
|
+
* `fjall add | modify | remove <type>` address in `infrastructure.ts`, one
|
|
4
|
+
* per `XFactory.build` family. Declared here, beside the posture policy
|
|
5
|
+
* that keys its cure column by it, so the registry's "where the user writes
|
|
6
|
+
* the cure" and the codemod's "which statement it edits" are one tuple: a
|
|
7
|
+
* cure keyed by a family the codemod cannot address fails typecheck, and
|
|
8
|
+
* `@fjall/generator`'s `StatementTypeSchema` is `z.enum` over this tuple.
|
|
9
|
+
*
|
|
10
|
+
* The wider AST vocabulary (`AstStatementTypeSchema` in the generator's base
|
|
11
|
+
* schemas) also carries non-factory kinds — import, app-init, tags, custom —
|
|
12
|
+
* that no codemod verb locates by factory shape; they are not cure families.
|
|
13
|
+
*/
|
|
14
|
+
export declare const CODEMOD_STATEMENT_TYPES: readonly ["database", "storage", "compute", "messaging", "cdn", "network", "pattern", "vpc-peer", "vpc-peer-accepter", "cross-plan-connection", "organisation", "buildkite"];
|
|
15
|
+
export type CodemodStatementType = (typeof CODEMOD_STATEMENT_TYPES)[number];
|
|
16
|
+
export declare function isCodemodStatementType(value: unknown): value is CodemodStatementType;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var o=Object.defineProperty;var t=(e,n)=>o(e,"name",{value:n,configurable:!0});const r=["database","storage","compute","messaging","cdn","network","pattern","vpc-peer","vpc-peer-accepter","cross-plan-connection","organisation","buildkite"],c=new Set(r);function s(e){return typeof e=="string"&&c.has(e)}t(s,"isCodemodStatementType");export{r as CODEMOD_STATEMENT_TYPES,s as isCodemodStatementType};
|
|
@@ -10,9 +10,11 @@
|
|
|
10
10
|
*/
|
|
11
11
|
export declare const APPROVAL_TOKEN_OUTPUT_PREFIX = "Approval token: ";
|
|
12
12
|
/**
|
|
13
|
-
* The exact stderr prefix the CLI prints minted
|
|
14
|
-
* (`fjall
|
|
15
|
-
*
|
|
16
|
-
*
|
|
13
|
+
* The exact stderr prefix the CLI prints a minted user token under
|
|
14
|
+
* (`fjall user token create`). Deploy tokens are minted in the web app only
|
|
15
|
+
* — `fjall ci setup` prints no token and the MCP `apply_ci_setup` handler
|
|
16
|
+
* parses none — so this is a CLI-side print contract, single-sourced here
|
|
17
|
+
* because it is the one place a minted credential is ever written to a
|
|
18
|
+
* stream.
|
|
17
19
|
*/
|
|
18
20
|
export declare const TOKEN_STDERR_PREFIX = "Token: ";
|
package/dist/fjallHome.d.ts
CHANGED
|
@@ -13,9 +13,10 @@
|
|
|
13
13
|
* the package raw — evaluates every barrel module, and a static
|
|
14
14
|
* `import { homedir } from "node:os"` throws at evaluation time against the
|
|
15
15
|
* browser-external stub, killing hydration on every page. `process
|
|
16
|
-
* .getBuiltinModule` (Node ≥ 22.3
|
|
17
|
-
* runtime-agnostic form: nothing is referenced at
|
|
18
|
-
* functions below only ever run in Node. The
|
|
16
|
+
* .getBuiltinModule` (Node ≥ 22.3.0 — the engines floor every published
|
|
17
|
+
* package declares) is the runtime-agnostic form: nothing is referenced at
|
|
18
|
+
* module scope, and the functions below only ever run in Node. The
|
|
19
|
+
* barrel-reachability test
|
|
19
20
|
* (`__tests__/barrelBrowserSafety.test.ts`) pins the class for the whole
|
|
20
21
|
* package.
|
|
21
22
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -15,11 +15,12 @@ export { DANGEROUS_ENV_VARS, filterDangerousEnvVars, MASKED_VALUE_MARKER, maskSe
|
|
|
15
15
|
export { sleep } from "./async/sleep.js";
|
|
16
16
|
export { mapSettledWithConcurrency } from "./async/concurrency.js";
|
|
17
17
|
export { ACCOUNT_STAGES_WITH_ROOT, STRUCTURAL_ENVIRONMENTS, ACCOUNT_STAGES, ACCOUNT_STAGE_LABELS, isAccountStage, ACCOUNT_TIERS, type AccountTier, AccountTierSchema, isAccountTier, GOVERNANCE_ACCOUNT_TIERS, isGovernanceTier, environmentToTier, type AccountStageEffect, accountStageEffect, ACCOUNT_STAGE_EFFECTS, formatAccountStageList, stageFromWireEnvironment, accountTier, resolveSynthEnvironment, type AccountStageWithRoot, type AccountStage, getEnvironmentLabel, ACCOUNT_ROLES } from "./environments.js";
|
|
18
|
-
export { BACKUP_TIERS, BACKUP_TIER_DEFAULTS, type BackupTier, type BackupTierDefaults, BackupTierSchema, isBackupTier, tierDefault } from "./backupTiers.js";
|
|
18
|
+
export { BACKUP_TIERS, BACKUP_TIER_DEFAULTS, BACKUP_TIER_TAG_KEY, BACKUP_TIER_TAG_MAP, type BackupTier, type BackupTierDefaults, BackupTierSchema, isBackupTier, tierDefault } from "./backupTiers.js";
|
|
19
|
+
export { CODEMOD_STATEMENT_TYPES, type CodemodStatementType, isCodemodStatementType } from "./codemod/statementTypes.js";
|
|
19
20
|
export { RESOURCE_CATEGORIES, type ResourceCategory, categoriseResource, getExpectedDuration, getFriendlyResourceType } from "./resourceCategorisation.js";
|
|
20
21
|
export { parseGitRemoteUrl, type GitProvider, type ParsedGitRemote } from "./repo/gitRemoteParser.js";
|
|
21
22
|
export { abbreviateRegion, AWS_REGIONS_METADATA, DEFAULT_REGION, getRegionInfo, MAX_SECONDARY_REGIONS, OPT_IN_REGION_CODES, optInRegionWarning, regions, RETIRED_REGION_ABBREVIATIONS, suggestRegionForTimezone, type RegionCode, type RegionInfo } from "./infra/regions.js";
|
|
22
|
-
export { SCOPE_VALUES, MACHINE_ONLY_SCOPES, USER_GRANTABLE_SCOPES, GOVERNANCE_SCOPE_REQUIRED_CODE, type TokenScope } from "./infra/tokenScopes.js";
|
|
23
|
+
export { SCOPE_VALUES, MACHINE_ONLY_SCOPES, USER_GRANTABLE_SCOPES, GOVERNANCE_SCOPE_REQUIRED_CODE, SESSION_ONLY_API_ROUTES, type TokenScope } from "./infra/tokenScopes.js";
|
|
23
24
|
export { SECRET_NAME_PATTERN, SECRET_NAME_ERROR, SSM_COMPONENT_PATTERN, SSM_COMPONENT_ERROR, SSM_STANDARD_MAX_VALUE_BYTES, SecretNamespaceSchema, type SecretNamespace, buildNamespaceParts, buildParameterPath, parseParameterPath, isManageablePath, parseDotEnv, escapeDotEnvValue } from "./secrets.js";
|
|
24
25
|
export { ConnectionWireSchema, type ConnectionWire, ConnectionsListResponseSchema, type ConnectionsListResponse, CONNECTION_PHASES, type ConnectionPhase, CONNECTION_TERMINAL_FAILURE_PHASES, type ConnectionTerminalFailurePhase, CONNECTION_FAILURE_REASONS, type ConnectionFailureReason, EXTERNAL_ID_PATTERN } from "./infra/connectionsWire.js";
|
|
25
26
|
export { COMPLIANCE_ISSUE_STATUSES, type ComplianceIssueStatus, isComplianceIssueStatus } from "./complianceIssue.js";
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{DNS_APEX as _,getDomainExportNames as r,getDomainStackName as T,getDomainUsEast1CertificatesStackName as A,hostsExportPartName as S,serialiseHostsChunks as t,HOSTS_OUTPUT_MAX_BYTES as o,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 i,TOKEN_STDERR_PREFIX as C}from"./deploy/approvalTokenOutput.js";import{imageTagParameterName as n}from"./infra/imageTags.js";import{toPascalCase as L,toKebab as s,toValidDatabaseName as p,toScreamingSnake as D,capitalise as c,getSafeZoneName as M,accountConstructKey as f,hasAsciiStableConstructKey as F}from"./naming/caseConversion.js";import{albDnsExportName as l,albHostedZoneIdExportName as u,cdnDomainExportName as x,bucketWebsiteEndpointExportName as d,bucketWebsiteHostedZoneIdExportName as G}from"./naming/targetExportNames.js";import{ec2ServiceName as h,mintedEc2KeyPairName as H}from"./naming/ec2Naming.js";import{CAPACITY_SLOT_PATTERN as Y,CAPACITY_SLOT_MAX_LENGTH as K,DEFAULT_CAPACITY_SLOT as y,CAPACITY_ANCHOR_PATTERN as v,CAPACITY_ANCHOR_MAX_LENGTH as B,CAPACITY_IDENTITY_CONTEXT_KEY as X,CapacityIdentityPinSchema as b,CapacityIdentityWireSchema as W,CapacityIdentityConfigSchema as k,projectCapacityIdentityToTarget as J}from"./capacityIdentity.js";import{findAccountNameCollision as w}from"./naming/accountNameCollision.js";import{defaultConnectedAccountName as q,suffixedAccountName as z,REGION_SHORT_CODES as Q,findTrailingRegionShortCode as $,regionSuffixRejectionMessage as ee}from"./naming/connectedAccountName.js";import{normaliseError as _e,getErrorMessage as re,hasErrorCode as Te,getErrorCode as Ae,getErrorStack as Se,formatErrorString as te}from"./errorUtils.js";import{FJALL_CONFIG_DIR_ENV as ae,FJALL_CREDENTIALS_FILENAME as Ne,FJALL_HOME_DIRNAME as Re,FJALL_LOG_DIR_ENV as Ie,fjallCredentialsPath as Oe,fjallHomeDir as ie,fjallLogDir as Ce,fjallStatePath as me}from"./fjallHome.js";import{singleton as Pe}from"./async/singleton.js";import{DANGEROUS_ENV_VARS as se,filterDangerousEnvVars as pe,MASKED_VALUE_MARKER as De,maskSensitiveOutput as ce,parseShellArgs as Me,REDACTED_KEY_SENTINEL as fe,SCOPED_TOKEN_REGEX as Fe}from"./securityHelpers.js";import{sleep as le}from"./async/sleep.js";import{mapSettledWithConcurrency as xe}from"./async/concurrency.js";import{ACCOUNT_STAGES_WITH_ROOT as Ge,STRUCTURAL_ENVIRONMENTS as ge,ACCOUNT_STAGES as he,ACCOUNT_STAGE_LABELS as He,isAccountStage as Ve,ACCOUNT_TIERS as Ye,AccountTierSchema as Ke,isAccountTier as ye,GOVERNANCE_ACCOUNT_TIERS as ve,isGovernanceTier as Be,environmentToTier as Xe,accountStageEffect as be,ACCOUNT_STAGE_EFFECTS as We,formatAccountStageList as ke,stageFromWireEnvironment as Je,accountTier as je,resolveSynthEnvironment as we,getEnvironmentLabel as Ze,ACCOUNT_ROLES as qe}from"./environments.js";import{BACKUP_TIERS as Qe,BACKUP_TIER_DEFAULTS as $e,BackupTierSchema as eE,isBackupTier as EE,tierDefault as _E}from"./backupTiers.js";import{RESOURCE_CATEGORIES as TE,categoriseResource as AE,getExpectedDuration as SE,getFriendlyResourceType as tE}from"./resourceCategorisation.js";import{parseGitRemoteUrl as aE}from"./repo/gitRemoteParser.js";import{abbreviateRegion as RE,AWS_REGIONS_METADATA as IE,DEFAULT_REGION as OE,getRegionInfo as iE,MAX_SECONDARY_REGIONS as CE,OPT_IN_REGION_CODES as mE,optInRegionWarning as nE,regions as PE,RETIRED_REGION_ABBREVIATIONS as LE,suggestRegionForTimezone as sE}from"./infra/regions.js";import{SCOPE_VALUES as DE,MACHINE_ONLY_SCOPES as cE,USER_GRANTABLE_SCOPES as ME,GOVERNANCE_SCOPE_REQUIRED_CODE as fE}from"./infra/tokenScopes.js";import{SECRET_NAME_PATTERN as UE,SECRET_NAME_ERROR as lE,SSM_COMPONENT_PATTERN as uE,SSM_COMPONENT_ERROR as xE,SSM_STANDARD_MAX_VALUE_BYTES as dE,SecretNamespaceSchema as GE,buildNamespaceParts as gE,buildParameterPath as hE,parseParameterPath as HE,isManageablePath as VE,parseDotEnv as YE,escapeDotEnvValue as KE}from"./secrets.js";import{ConnectionWireSchema as vE,ConnectionsListResponseSchema as BE,CONNECTION_PHASES as XE,CONNECTION_TERMINAL_FAILURE_PHASES as bE,CONNECTION_FAILURE_REASONS as WE,EXTERNAL_ID_PATTERN as kE}from"./infra/connectionsWire.js";import{COMPLIANCE_ISSUE_STATUSES as jE,isComplianceIssueStatus as wE}from"./complianceIssue.js";import{PUBLIC_PACKAGE_NAME as qE,INSTALL_SOURCES as zE,SETUP_COMMANDS as QE,upgradeCommand as $E,SETUP_MODES as e_,SETUP_STEP_IDS as E_,SETUP_STEPS as __,AGENT_SETUP_PROMPTS as r_,AGENT_INSTALL_COMMAND as T_,SKILL_INSTALL_SEGMENTS as A_,SKILL_INSTALL_FILENAME as S_,SKILL_INSTALL_PATH as t_}from"./onboarding/index.js";import{deriveRegionsFromOrgConfig as a_,deriveTargets as N_,deriveAllTargets as R_,environmentOrTier as I_,explainRetiredTargetName as O_,findTarget as i_,generateTargetName as C_}from"./targets.js";import{buildAppConfigPath as n_}from"./repo/appPath.js";import{findInfrastructurePaths as L_,findBoundaryPath as s_,isInfrastructureFile as p_}from"./repo/findInfrastructurePaths.js";import{inferContainerFromCandidates as c_}from"./repo/inferContainerFromCandidates.js";import{RESERVED_APP_NAMES as f_,RESERVED_APP_NAME_MESSAGE as F_,isReservedAppName as U_,RESERVED_APP_NAME_SUFFIX as l_,RESERVED_APP_NAME_SUFFIX_MESSAGE as u_,hasReservedAppNameSuffix as x_}from"./naming/reservedAppNames.js";import{deriveContentHashTag as G_,CONTENT_HASH_TAG_PATTERN as g_}from"./infra/deriveContentHashTag.js";import{DEPLOY_MODES as H_,DeployModeSchema as V_,IMAGE_TAG_PATTERN as Y_,ImageTagSchema as K_,ServiceArtefactSchema as y_,ServiceArtefactsSchema as v_,ARTEFACT_OUTPUT_FIELDS as B_,artefactOutputKey as X_}from"./infra/deployArtefacts.js";import{MIGRATION_SNAPSHOT_NAME_PREFIX as W_,MIGRATION_SNAPSHOT_RETENTION_DAYS_ENV as k_,MIGRATION_SNAPSHOT_KIND_TAG_KEY as J_,MIGRATION_SNAPSHOT_KIND_PREMIGRATE as j_,EXPECTED_SCHEMA_VERSION_ENV as w_,EXPECTED_SCHEMA_VERSION_TOOL_ENV as Z_,EXPECTED_CH_SCHEMA_VERSION_ENV as q_,SCHEMA_ADMIN_USER_ENV as z_,SCHEMA_ADMIN_PASSWORD_ENV as Q_,PRISMA_MIGRATION_DIR_RE as $_,CLICKHOUSE_MIGRATION_SKIP_RE as er}from"./migration/constants.js";import{SCHEMA_GATE_EXIT as _r,SCHEMA_GATE_EXIT_HINTS as rr,schemaGateExitKind as Tr}from"./migration/schemaGateExit.js";import{FJALL_SCHEMA_GATE_USER as Sr,FJALL_MAINTENANCE_USER as tr,FJALL_CLICKHOUSE_USERS as or}from"./migration/clickhouseFrameworkUsers.js";import{PHYSICAL_NAME_FALLBACK_PROPERTIES as Nr}from"./cfn/physicalNameProperties.js";import{PATTERN_TYPE_VALUES as Ir,PATTERN_TYPES as Or,isPatternType as ir,PATTERN_REGISTRY as Cr,patternConstructId as mr,DEPLOYABLE_PATTERN_TYPES as nr,OPENNEXT_PATTERN_TYPES as Pr,isOpenNextPatternType as Lr,CLOUDFRONT_PRICE_CLASS_VALUES as sr,STATIC_SITE_CONFIG_KEYS as pr,STATIC_SITE_DEPLOY_INJECTED_KEYS as Dr,STATIC_SITE_CDN_CONFIG_KEYS as cr,STATIC_SITE_ROUTING_VALUES as Mr,STATIC_SITE_ROUTING_INFO as fr,PATTERN_CREATE_INPUT_VALUES as Fr,PATTERN_CREATE_INPUT_FLAGS as Ur}from"./patterns/patternTypes.js";import{FRAMEWORK_VALUES as ur,FRAMEWORKS as xr,isFramework as dr,FRAMEWORK_PATTERN_RECOMMENDATIONS as Gr,recommendPatternForFramework as gr,CREATABLE_FRAMEWORKS as hr,requiredInputsForFramework as Hr}from"./patterns/frameworkPatterns.js";import{DEFAULT_FORMS_FROM_LOCAL_PART as Yr,defaultFormsFromAddress as Kr,defaultFormsCorsOrigin as yr,isAddressAtDomain as vr}from"./patterns/staticSiteForms.js";import{DEV_SUBSTRATE_PARAMS_SCHEMA_VERSION as Xr,DEV_SUBSTRATE_PARAMS_FILENAME as br,DevSubstrateSynthPropsSchema as Wr,DevSubstrateParamsSchema as kr}from"./devSubstrate/params.js";import{DEV_SUBSTRATE_ENTRYPOINT_SOURCE as jr}from"./devSubstrate/entrypoint.js";import{BLESSED_CDK_TOOLCHAIN as Zr}from"./cdkToolchain.js";import{DEPLOYMENT_FAILURE_PHASES as zr,DeploymentFailurePhaseSchema as Qr,DEPLOYMENT_FAULT_ATTRIBUTIONS as $r,DeploymentFaultAttributionSchema as eT,DEPLOYMENT_FAILURE_PROVIDER_SOURCES as ET,DeploymentFailureProviderSourceSchema as _T,DEPLOYMENT_FAILURE_CODE_PATTERN as rT,DEPLOYMENT_FAILURE_SCHEMA_VERSION as TT,DEPLOYMENT_FAILURE_LIMITS as AT,DeploymentFailureAnalysisSchema as ST,DeploymentFailureProviderSchema as tT,DeploymentFailureResourceSchema as oT,DeploymentFailureSchema as aT,parseDeploymentFailure as NT,DEPLOYMENT_FAILURE_DOCS_BASE_URL as RT,deploymentFailureDocsUrl as IT,DEPLOYMENT_FAULT_COPY as OT,DEPLOYMENT_PROVIDER_LABELS as iT,deriveErrorMessageFromFailure as CT,toDeploymentFailureAnalysis as mT}from"./failure/deploymentFailure.js";import{extractErrorWindow as PT,ERROR_WINDOW_CONTEXT_LINES as LT}from"./failure/extractErrorWindow.js";import{FJALL_COMPONENT_GITIGNORE as pT,FJALL_PROJECT_GITIGNORE as DT,FJALL_STATE_GITIGNORE_ENTRIES as cT,FJALL_MANAGED_STATE_DIR_ENTRIES as MT,LOCAL_CONFIG_GITIGNORE_ENTRY as fT}from"./scaffold/gitignore.js";import{ensureGitignoreEntries as UT}from"./scaffold/ensureGitignore.js";export{qe as ACCOUNT_ROLES,he as ACCOUNT_STAGES,Ge as ACCOUNT_STAGES_WITH_ROOT,We as ACCOUNT_STAGE_EFFECTS,He as ACCOUNT_STAGE_LABELS,Ye as ACCOUNT_TIERS,T_ as AGENT_INSTALL_COMMAND,r_ as AGENT_SETUP_PROMPTS,i as APPROVAL_TOKEN_OUTPUT_PREFIX,B_ as ARTEFACT_OUTPUT_FIELDS,IE as AWS_REGIONS_METADATA,Ke as AccountTierSchema,Qe as BACKUP_TIERS,$e as BACKUP_TIER_DEFAULTS,I as BACKUP_VAULT_NAME,Zr as BLESSED_CDK_TOOLCHAIN,eE as BackupTierSchema,B as CAPACITY_ANCHOR_MAX_LENGTH,v as CAPACITY_ANCHOR_PATTERN,X as CAPACITY_IDENTITY_CONTEXT_KEY,K as CAPACITY_SLOT_MAX_LENGTH,Y as CAPACITY_SLOT_PATTERN,er as CLICKHOUSE_MIGRATION_SKIP_RE,sr as CLOUDFRONT_PRICE_CLASS_VALUES,jE as COMPLIANCE_ISSUE_STATUSES,WE as CONNECTION_FAILURE_REASONS,XE as CONNECTION_PHASES,bE as CONNECTION_TERMINAL_FAILURE_PHASES,g_ as CONTENT_HASH_TAG_PATTERN,hr as CREATABLE_FRAMEWORKS,k as CapacityIdentityConfigSchema,b as CapacityIdentityPinSchema,W as CapacityIdentityWireSchema,vE as ConnectionWireSchema,BE as ConnectionsListResponseSchema,se as DANGEROUS_ENV_VARS,y as DEFAULT_CAPACITY_SLOT,Yr as DEFAULT_FORMS_FROM_LOCAL_PART,OE as DEFAULT_REGION,nr as DEPLOYABLE_PATTERN_TYPES,rT as DEPLOYMENT_FAILURE_CODE_PATTERN,RT as DEPLOYMENT_FAILURE_DOCS_BASE_URL,AT as DEPLOYMENT_FAILURE_LIMITS,zr as DEPLOYMENT_FAILURE_PHASES,ET as DEPLOYMENT_FAILURE_PROVIDER_SOURCES,TT as DEPLOYMENT_FAILURE_SCHEMA_VERSION,$r as DEPLOYMENT_FAULT_ATTRIBUTIONS,OT as DEPLOYMENT_FAULT_COPY,iT as DEPLOYMENT_PROVIDER_LABELS,H_ as DEPLOY_MODES,jr as DEV_SUBSTRATE_ENTRYPOINT_SOURCE,br as DEV_SUBSTRATE_PARAMS_FILENAME,Xr as DEV_SUBSTRATE_PARAMS_SCHEMA_VERSION,_ as DNS_APEX,N as DOMAIN_DEPLOY_DEFAULT_PHASE,V_ as DeployModeSchema,ST as DeploymentFailureAnalysisSchema,Qr as DeploymentFailurePhaseSchema,tT as DeploymentFailureProviderSchema,_T as DeploymentFailureProviderSourceSchema,oT as DeploymentFailureResourceSchema,aT as DeploymentFailureSchema,eT as DeploymentFaultAttributionSchema,kr as DevSubstrateParamsSchema,Wr as DevSubstrateSynthPropsSchema,LT as ERROR_WINDOW_CONTEXT_LINES,q_ as EXPECTED_CH_SCHEMA_VERSION_ENV,w_ as EXPECTED_SCHEMA_VERSION_ENV,Z_ as EXPECTED_SCHEMA_VERSION_TOOL_ENV,kE as EXTERNAL_ID_PATTERN,or as FJALL_CLICKHOUSE_USERS,pT as FJALL_COMPONENT_GITIGNORE,ae as FJALL_CONFIG_DIR_ENV,Ne as FJALL_CREDENTIALS_FILENAME,Re as FJALL_HOME_DIRNAME,Ie as FJALL_LOG_DIR_ENV,tr as FJALL_MAINTENANCE_USER,MT as FJALL_MANAGED_STATE_DIR_ENTRIES,DT as FJALL_PROJECT_GITIGNORE,Sr as FJALL_SCHEMA_GATE_USER,cT as FJALL_STATE_GITIGNORE_ENTRIES,xr as FRAMEWORKS,Gr as FRAMEWORK_PATTERN_RECOMMENDATIONS,ur as FRAMEWORK_VALUES,ve as GOVERNANCE_ACCOUNT_TIERS,fE as GOVERNANCE_SCOPE_REQUIRED_CODE,o as HOSTS_OUTPUT_MAX_BYTES,Y_ as IMAGE_TAG_PATTERN,zE as INSTALL_SOURCES,K_ as ImageTagSchema,fT as LOCAL_CONFIG_GITIGNORE_ENTRY,cE as MACHINE_ONLY_SCOPES,De as MASKED_VALUE_MARKER,CE as MAX_SECONDARY_REGIONS,j_ as MIGRATION_SNAPSHOT_KIND_PREMIGRATE,J_ as MIGRATION_SNAPSHOT_KIND_TAG_KEY,W_ as MIGRATION_SNAPSHOT_NAME_PREFIX,k_ as MIGRATION_SNAPSHOT_RETENTION_DAYS_ENV,Pr as OPENNEXT_PATTERN_TYPES,mE as OPT_IN_REGION_CODES,Ur as PATTERN_CREATE_INPUT_FLAGS,Fr as PATTERN_CREATE_INPUT_VALUES,Cr as PATTERN_REGISTRY,Or as PATTERN_TYPES,Ir as PATTERN_TYPE_VALUES,Nr as PHYSICAL_NAME_FALLBACK_PROPERTIES,$_ as PRISMA_MIGRATION_DIR_RE,qE as PUBLIC_PACKAGE_NAME,fe as REDACTED_KEY_SENTINEL,Q as REGION_SHORT_CODES,f_ as RESERVED_APP_NAMES,F_ as RESERVED_APP_NAME_MESSAGE,l_ as RESERVED_APP_NAME_SUFFIX,u_ as RESERVED_APP_NAME_SUFFIX_MESSAGE,TE as RESOURCE_CATEGORIES,LE as RETIRED_REGION_ABBREVIATIONS,Q_ as SCHEMA_ADMIN_PASSWORD_ENV,z_ as SCHEMA_ADMIN_USER_ENV,_r as SCHEMA_GATE_EXIT,rr as SCHEMA_GATE_EXIT_HINTS,Fe as SCOPED_TOKEN_REGEX,DE as SCOPE_VALUES,lE as SECRET_NAME_ERROR,UE as SECRET_NAME_PATTERN,QE as SETUP_COMMANDS,e_ as SETUP_MODES,__ as SETUP_STEPS,E_ as SETUP_STEP_IDS,S_ as SKILL_INSTALL_FILENAME,t_ as SKILL_INSTALL_PATH,A_ as SKILL_INSTALL_SEGMENTS,xE as SSM_COMPONENT_ERROR,uE as SSM_COMPONENT_PATTERN,dE as SSM_STANDARD_MAX_VALUE_BYTES,cr as STATIC_SITE_CDN_CONFIG_KEYS,pr as STATIC_SITE_CONFIG_KEYS,Dr as STATIC_SITE_DEPLOY_INJECTED_KEYS,fr as STATIC_SITE_ROUTING_INFO,Mr as STATIC_SITE_ROUTING_VALUES,ge as STRUCTURAL_ENVIRONMENTS,GE as SecretNamespaceSchema,y_ as ServiceArtefactSchema,v_ as ServiceArtefactsSchema,C as TOKEN_STDERR_PREFIX,ME as USER_GRANTABLE_SCOPES,RE as abbreviateRegion,f as accountConstructKey,be as accountStageEffect,je as accountTier,l as albDnsExportName,u as albHostedZoneIdExportName,X_ as artefactOutputKey,d as bucketWebsiteEndpointExportName,G as bucketWebsiteHostedZoneIdExportName,n_ as buildAppConfigPath,gE as buildNamespaceParts,hE as buildParameterPath,c as capitalise,AE as categoriseResource,x as cdnDomainExportName,q as defaultConnectedAccountName,yr as defaultFormsCorsOrigin,Kr as defaultFormsFromAddress,IT as deploymentFailureDocsUrl,R_ as deriveAllTargets,G_ as deriveContentHashTag,CT as deriveErrorMessageFromFailure,a_ as deriveRegionsFromOrgConfig,N_ as deriveTargets,h as ec2ServiceName,UT as ensureGitignoreEntries,I_ as environmentOrTier,Xe as environmentToTier,KE as escapeDotEnvValue,O_ as explainRetiredTargetName,PT as extractErrorWindow,pe as filterDangerousEnvVars,w as findAccountNameCollision,s_ as findBoundaryPath,L_ as findInfrastructurePaths,i_ as findTarget,$ as findTrailingRegionShortCode,Oe as fjallCredentialsPath,ie as fjallHomeDir,Ce as fjallLogDir,me as fjallStatePath,ke as formatAccountStageList,te as formatErrorString,C_ as generateTargetName,r as getDomainExportNames,T as getDomainStackName,A as getDomainUsEast1CertificatesStackName,Ze as getEnvironmentLabel,Ae as getErrorCode,re as getErrorMessage,Se as getErrorStack,SE as getExpectedDuration,tE as getFriendlyResourceType,iE as getRegionInfo,M as getSafeZoneName,F as hasAsciiStableConstructKey,Te as hasErrorCode,x_ as hasReservedAppNameSuffix,S as hostsExportPartName,n as imageTagParameterName,c_ as inferContainerFromCandidates,Ve as isAccountStage,ye as isAccountTier,vr as isAddressAtDomain,EE as isBackupTier,wE as isComplianceIssueStatus,dr as isFramework,Be as isGovernanceTier,p_ as isInfrastructureFile,VE as isManageablePath,a as isManagedDomainBinding,Lr as isOpenNextPatternType,ir as isPatternType,U_ as isReservedAppName,xe as mapSettledWithConcurrency,ce as maskSensitiveOutput,H as mintedEc2KeyPairName,_e as normaliseError,nE as optInRegionWarning,NT as parseDeploymentFailure,YE as parseDotEnv,aE as parseGitRemoteUrl,HE as parseParameterPath,Me as parseShellArgs,mr as patternConstructId,J as projectCapacityIdentityToTarget,gr as recommendPatternForFramework,ee as regionSuffixRejectionMessage,PE as regions,Hr as requiredInputsForFramework,we as resolveSynthEnvironment,Tr as schemaGateExitKind,t as serialiseHostsChunks,Pe as singleton,le as sleep,Je as stageFromWireEnvironment,z as suffixedAccountName,sE as suggestRegionForTimezone,_E as tierDefault,mT as toDeploymentFailureAnalysis,s as toKebab,L as toPascalCase,D as toScreamingSnake,p as toValidDatabaseName,$E as upgradeCommand};
|
|
1
|
+
import{DNS_APEX as _,getDomainExportNames as r,getDomainStackName as T,getDomainUsEast1CertificatesStackName as A,hostsExportPartName as S,serialiseHostsChunks as t,HOSTS_OUTPUT_MAX_BYTES as o,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 i,TOKEN_STDERR_PREFIX as C}from"./deploy/approvalTokenOutput.js";import{imageTagParameterName as n}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 U}from"./naming/caseConversion.js";import{albDnsExportName as l,albHostedZoneIdExportName as u,cdnDomainExportName as x,bucketWebsiteEndpointExportName as d,bucketWebsiteHostedZoneIdExportName as G}from"./naming/targetExportNames.js";import{ec2ServiceName as Y,mintedEc2KeyPairName as h}from"./naming/ec2Naming.js";import{CAPACITY_SLOT_PATTERN as V,CAPACITY_SLOT_MAX_LENGTH as K,DEFAULT_CAPACITY_SLOT as y,CAPACITY_ANCHOR_PATTERN as v,CAPACITY_ANCHOR_MAX_LENGTH as B,CAPACITY_IDENTITY_CONTEXT_KEY as X,CapacityIdentityPinSchema as b,CapacityIdentityWireSchema as W,CapacityIdentityConfigSchema as k,projectCapacityIdentityToTarget as J}from"./capacityIdentity.js";import{findAccountNameCollision as w}from"./naming/accountNameCollision.js";import{defaultConnectedAccountName as q,suffixedAccountName as z,REGION_SHORT_CODES as Q,findTrailingRegionShortCode as $,regionSuffixRejectionMessage as ee}from"./naming/connectedAccountName.js";import{normaliseError as _e,getErrorMessage as re,hasErrorCode as Te,getErrorCode as Ae,getErrorStack as Se,formatErrorString as te}from"./errorUtils.js";import{FJALL_CONFIG_DIR_ENV as ae,FJALL_CREDENTIALS_FILENAME as Ne,FJALL_HOME_DIRNAME as Re,FJALL_LOG_DIR_ENV as Ie,fjallCredentialsPath as Oe,fjallHomeDir as ie,fjallLogDir as Ce,fjallStatePath as me}from"./fjallHome.js";import{singleton as Pe}from"./async/singleton.js";import{DANGEROUS_ENV_VARS as se,filterDangerousEnvVars as pe,MASKED_VALUE_MARKER as De,maskSensitiveOutput as Me,parseShellArgs as ce,REDACTED_KEY_SENTINEL as fe,SCOPED_TOKEN_REGEX as Ue}from"./securityHelpers.js";import{sleep as le}from"./async/sleep.js";import{mapSettledWithConcurrency as xe}from"./async/concurrency.js";import{ACCOUNT_STAGES_WITH_ROOT as Ge,STRUCTURAL_ENVIRONMENTS as ge,ACCOUNT_STAGES as Ye,ACCOUNT_STAGE_LABELS as he,isAccountStage as He,ACCOUNT_TIERS as Ve,AccountTierSchema as Ke,isAccountTier as ye,GOVERNANCE_ACCOUNT_TIERS as ve,isGovernanceTier as Be,environmentToTier as Xe,accountStageEffect as be,ACCOUNT_STAGE_EFFECTS as We,formatAccountStageList as ke,stageFromWireEnvironment as Je,accountTier as je,resolveSynthEnvironment as we,getEnvironmentLabel as Ze,ACCOUNT_ROLES as qe}from"./environments.js";import{BACKUP_TIERS as Qe,BACKUP_TIER_DEFAULTS as $e,BACKUP_TIER_TAG_KEY as eE,BACKUP_TIER_TAG_MAP as EE,BackupTierSchema as _E,isBackupTier as rE,tierDefault as TE}from"./backupTiers.js";import{CODEMOD_STATEMENT_TYPES as SE,isCodemodStatementType as tE}from"./codemod/statementTypes.js";import{RESOURCE_CATEGORIES as aE,categoriseResource as NE,getExpectedDuration as RE,getFriendlyResourceType as IE}from"./resourceCategorisation.js";import{parseGitRemoteUrl as iE}from"./repo/gitRemoteParser.js";import{abbreviateRegion as mE,AWS_REGIONS_METADATA as nE,DEFAULT_REGION as PE,getRegionInfo as LE,MAX_SECONDARY_REGIONS as sE,OPT_IN_REGION_CODES as pE,optInRegionWarning as DE,regions as ME,RETIRED_REGION_ABBREVIATIONS as cE,suggestRegionForTimezone as fE}from"./infra/regions.js";import{SCOPE_VALUES as FE,MACHINE_ONLY_SCOPES as lE,USER_GRANTABLE_SCOPES as uE,GOVERNANCE_SCOPE_REQUIRED_CODE as xE,SESSION_ONLY_API_ROUTES as dE}from"./infra/tokenScopes.js";import{SECRET_NAME_PATTERN as gE,SECRET_NAME_ERROR as YE,SSM_COMPONENT_PATTERN as hE,SSM_COMPONENT_ERROR as HE,SSM_STANDARD_MAX_VALUE_BYTES as VE,SecretNamespaceSchema as KE,buildNamespaceParts as yE,buildParameterPath as vE,parseParameterPath as BE,isManageablePath as XE,parseDotEnv as bE,escapeDotEnvValue as WE}from"./secrets.js";import{ConnectionWireSchema as JE,ConnectionsListResponseSchema as jE,CONNECTION_PHASES as wE,CONNECTION_TERMINAL_FAILURE_PHASES as ZE,CONNECTION_FAILURE_REASONS as qE,EXTERNAL_ID_PATTERN as zE}from"./infra/connectionsWire.js";import{COMPLIANCE_ISSUE_STATUSES as $E,isComplianceIssueStatus as e_}from"./complianceIssue.js";import{PUBLIC_PACKAGE_NAME as __,INSTALL_SOURCES as r_,SETUP_COMMANDS as T_,upgradeCommand as A_,SETUP_MODES as S_,SETUP_STEP_IDS as t_,SETUP_STEPS as o_,AGENT_SETUP_PROMPTS as a_,AGENT_INSTALL_COMMAND as N_,SKILL_INSTALL_SEGMENTS as R_,SKILL_INSTALL_FILENAME as I_,SKILL_INSTALL_PATH as O_}from"./onboarding/index.js";import{deriveRegionsFromOrgConfig as C_,deriveTargets as m_,deriveAllTargets as n_,environmentOrTier as P_,explainRetiredTargetName as L_,findTarget as s_,generateTargetName as p_}from"./targets.js";import{buildAppConfigPath as M_}from"./repo/appPath.js";import{findInfrastructurePaths as f_,findBoundaryPath as U_,isInfrastructureFile as F_}from"./repo/findInfrastructurePaths.js";import{inferContainerFromCandidates as u_}from"./repo/inferContainerFromCandidates.js";import{RESERVED_APP_NAMES as d_,RESERVED_APP_NAME_MESSAGE as G_,isReservedAppName as g_,RESERVED_APP_NAME_SUFFIX as Y_,RESERVED_APP_NAME_SUFFIX_MESSAGE as h_,hasReservedAppNameSuffix as H_}from"./naming/reservedAppNames.js";import{deriveContentHashTag as K_,CONTENT_HASH_TAG_PATTERN as y_}from"./infra/deriveContentHashTag.js";import{DEPLOY_MODES as B_,DeployModeSchema as X_,IMAGE_TAG_PATTERN as b_,ImageTagSchema as W_,ServiceArtefactSchema as k_,ServiceArtefactsSchema as J_,ARTEFACT_OUTPUT_FIELDS as j_,artefactOutputKey as w_}from"./infra/deployArtefacts.js";import{MIGRATION_SNAPSHOT_NAME_PREFIX as q_,MIGRATION_SNAPSHOT_RETENTION_DAYS_ENV as z_,MIGRATION_SNAPSHOT_KIND_TAG_KEY as Q_,MIGRATION_SNAPSHOT_KIND_PREMIGRATE as $_,EXPECTED_SCHEMA_VERSION_ENV as er,EXPECTED_SCHEMA_VERSION_TOOL_ENV as Er,EXPECTED_CH_SCHEMA_VERSION_ENV as _r,SCHEMA_ADMIN_USER_ENV as rr,SCHEMA_ADMIN_PASSWORD_ENV as Tr,PRISMA_MIGRATION_DIR_RE as Ar,CLICKHOUSE_MIGRATION_SKIP_RE as Sr}from"./migration/constants.js";import{SCHEMA_GATE_EXIT as or,SCHEMA_GATE_EXIT_HINTS as ar,schemaGateExitKind as Nr}from"./migration/schemaGateExit.js";import{FJALL_SCHEMA_GATE_USER as Ir,FJALL_MAINTENANCE_USER as Or,FJALL_CLICKHOUSE_USERS as ir}from"./migration/clickhouseFrameworkUsers.js";import{PHYSICAL_NAME_FALLBACK_PROPERTIES as mr}from"./cfn/physicalNameProperties.js";import{PATTERN_TYPE_VALUES as Pr,PATTERN_TYPES as Lr,isPatternType as sr,PATTERN_REGISTRY as pr,patternConstructId as Dr,DEPLOYABLE_PATTERN_TYPES as Mr,OPENNEXT_PATTERN_TYPES as cr,isOpenNextPatternType as fr,CLOUDFRONT_PRICE_CLASS_VALUES as Ur,STATIC_SITE_CONFIG_KEYS as Fr,STATIC_SITE_DEPLOY_INJECTED_KEYS as lr,STATIC_SITE_CDN_CONFIG_KEYS as ur,STATIC_SITE_ROUTING_VALUES as xr,STATIC_SITE_ROUTING_INFO as dr,PATTERN_CREATE_INPUT_VALUES as Gr,PATTERN_CREATE_INPUT_FLAGS as gr}from"./patterns/patternTypes.js";import{FRAMEWORK_VALUES as hr,FRAMEWORKS as Hr,isFramework as Vr,FRAMEWORK_PATTERN_RECOMMENDATIONS as Kr,recommendPatternForFramework as yr,CREATABLE_FRAMEWORKS as vr,requiredInputsForFramework as Br}from"./patterns/frameworkPatterns.js";import{DEFAULT_FORMS_FROM_LOCAL_PART as br,defaultFormsFromAddress as Wr,defaultFormsCorsOrigin as kr,isAddressAtDomain as Jr}from"./patterns/staticSiteForms.js";import{DEV_SUBSTRATE_PARAMS_SCHEMA_VERSION as wr,DEV_SUBSTRATE_PARAMS_FILENAME as Zr,DevSubstrateSynthPropsSchema as qr,DevSubstrateParamsSchema as zr}from"./devSubstrate/params.js";import{DEV_SUBSTRATE_ENTRYPOINT_SOURCE as $r}from"./devSubstrate/entrypoint.js";import{BLESSED_CDK_TOOLCHAIN as ET}from"./cdkToolchain.js";import{DEPLOYMENT_FAILURE_PHASES as rT,DeploymentFailurePhaseSchema as TT,DEPLOYMENT_FAULT_ATTRIBUTIONS as AT,DeploymentFaultAttributionSchema as ST,DEPLOYMENT_FAILURE_PROVIDER_SOURCES as tT,DeploymentFailureProviderSourceSchema as oT,DEPLOYMENT_FAILURE_CODE_PATTERN as aT,DEPLOYMENT_FAILURE_SCHEMA_VERSION as NT,DEPLOYMENT_FAILURE_LIMITS as RT,DeploymentFailureAnalysisSchema as IT,DeploymentFailureProviderSchema as OT,DeploymentFailureResourceSchema as iT,DeploymentFailureSchema as CT,parseDeploymentFailure as mT,DEPLOYMENT_FAILURE_DOCS_BASE_URL as nT,deploymentFailureDocsUrl as PT,DEPLOYMENT_FAULT_COPY as LT,DEPLOYMENT_PROVIDER_LABELS as sT,deriveErrorMessageFromFailure as pT,toDeploymentFailureAnalysis as DT}from"./failure/deploymentFailure.js";import{extractErrorWindow as cT,ERROR_WINDOW_CONTEXT_LINES as fT}from"./failure/extractErrorWindow.js";import{FJALL_COMPONENT_GITIGNORE as FT,FJALL_PROJECT_GITIGNORE as lT,FJALL_STATE_GITIGNORE_ENTRIES as uT,FJALL_MANAGED_STATE_DIR_ENTRIES as xT,LOCAL_CONFIG_GITIGNORE_ENTRY as dT}from"./scaffold/gitignore.js";import{ensureGitignoreEntries as gT}from"./scaffold/ensureGitignore.js";export{qe as ACCOUNT_ROLES,Ye as ACCOUNT_STAGES,Ge as ACCOUNT_STAGES_WITH_ROOT,We as ACCOUNT_STAGE_EFFECTS,he as ACCOUNT_STAGE_LABELS,Ve as ACCOUNT_TIERS,N_ as AGENT_INSTALL_COMMAND,a_ as AGENT_SETUP_PROMPTS,i as APPROVAL_TOKEN_OUTPUT_PREFIX,j_ as ARTEFACT_OUTPUT_FIELDS,nE as AWS_REGIONS_METADATA,Ke as AccountTierSchema,Qe as BACKUP_TIERS,$e as BACKUP_TIER_DEFAULTS,eE as BACKUP_TIER_TAG_KEY,EE as BACKUP_TIER_TAG_MAP,I as BACKUP_VAULT_NAME,ET as BLESSED_CDK_TOOLCHAIN,_E as BackupTierSchema,B as CAPACITY_ANCHOR_MAX_LENGTH,v as CAPACITY_ANCHOR_PATTERN,X as CAPACITY_IDENTITY_CONTEXT_KEY,K as CAPACITY_SLOT_MAX_LENGTH,V as CAPACITY_SLOT_PATTERN,Sr as CLICKHOUSE_MIGRATION_SKIP_RE,Ur as CLOUDFRONT_PRICE_CLASS_VALUES,SE as CODEMOD_STATEMENT_TYPES,$E as COMPLIANCE_ISSUE_STATUSES,qE as CONNECTION_FAILURE_REASONS,wE as CONNECTION_PHASES,ZE as CONNECTION_TERMINAL_FAILURE_PHASES,y_ as CONTENT_HASH_TAG_PATTERN,vr as CREATABLE_FRAMEWORKS,k as CapacityIdentityConfigSchema,b as CapacityIdentityPinSchema,W as CapacityIdentityWireSchema,JE as ConnectionWireSchema,jE as ConnectionsListResponseSchema,se as DANGEROUS_ENV_VARS,y as DEFAULT_CAPACITY_SLOT,br as DEFAULT_FORMS_FROM_LOCAL_PART,PE as DEFAULT_REGION,Mr as DEPLOYABLE_PATTERN_TYPES,aT as DEPLOYMENT_FAILURE_CODE_PATTERN,nT as DEPLOYMENT_FAILURE_DOCS_BASE_URL,RT as DEPLOYMENT_FAILURE_LIMITS,rT as DEPLOYMENT_FAILURE_PHASES,tT as DEPLOYMENT_FAILURE_PROVIDER_SOURCES,NT as DEPLOYMENT_FAILURE_SCHEMA_VERSION,AT as DEPLOYMENT_FAULT_ATTRIBUTIONS,LT as DEPLOYMENT_FAULT_COPY,sT as DEPLOYMENT_PROVIDER_LABELS,B_ as DEPLOY_MODES,$r as DEV_SUBSTRATE_ENTRYPOINT_SOURCE,Zr as DEV_SUBSTRATE_PARAMS_FILENAME,wr as DEV_SUBSTRATE_PARAMS_SCHEMA_VERSION,_ as DNS_APEX,N as DOMAIN_DEPLOY_DEFAULT_PHASE,X_ as DeployModeSchema,IT as DeploymentFailureAnalysisSchema,TT as DeploymentFailurePhaseSchema,OT as DeploymentFailureProviderSchema,oT as DeploymentFailureProviderSourceSchema,iT as DeploymentFailureResourceSchema,CT as DeploymentFailureSchema,ST as DeploymentFaultAttributionSchema,zr as DevSubstrateParamsSchema,qr as DevSubstrateSynthPropsSchema,fT as ERROR_WINDOW_CONTEXT_LINES,_r as EXPECTED_CH_SCHEMA_VERSION_ENV,er as EXPECTED_SCHEMA_VERSION_ENV,Er as EXPECTED_SCHEMA_VERSION_TOOL_ENV,zE as EXTERNAL_ID_PATTERN,ir as FJALL_CLICKHOUSE_USERS,FT as FJALL_COMPONENT_GITIGNORE,ae as FJALL_CONFIG_DIR_ENV,Ne as FJALL_CREDENTIALS_FILENAME,Re as FJALL_HOME_DIRNAME,Ie as FJALL_LOG_DIR_ENV,Or as FJALL_MAINTENANCE_USER,xT as FJALL_MANAGED_STATE_DIR_ENTRIES,lT as FJALL_PROJECT_GITIGNORE,Ir as FJALL_SCHEMA_GATE_USER,uT as FJALL_STATE_GITIGNORE_ENTRIES,Hr as FRAMEWORKS,Kr as FRAMEWORK_PATTERN_RECOMMENDATIONS,hr as FRAMEWORK_VALUES,ve as GOVERNANCE_ACCOUNT_TIERS,xE as GOVERNANCE_SCOPE_REQUIRED_CODE,o as HOSTS_OUTPUT_MAX_BYTES,b_ as IMAGE_TAG_PATTERN,r_ as INSTALL_SOURCES,W_ as ImageTagSchema,dT as LOCAL_CONFIG_GITIGNORE_ENTRY,lE as MACHINE_ONLY_SCOPES,De as MASKED_VALUE_MARKER,sE as MAX_SECONDARY_REGIONS,$_ as MIGRATION_SNAPSHOT_KIND_PREMIGRATE,Q_ as MIGRATION_SNAPSHOT_KIND_TAG_KEY,q_ as MIGRATION_SNAPSHOT_NAME_PREFIX,z_ as MIGRATION_SNAPSHOT_RETENTION_DAYS_ENV,cr as OPENNEXT_PATTERN_TYPES,pE as OPT_IN_REGION_CODES,gr as PATTERN_CREATE_INPUT_FLAGS,Gr as PATTERN_CREATE_INPUT_VALUES,pr as PATTERN_REGISTRY,Lr as PATTERN_TYPES,Pr as PATTERN_TYPE_VALUES,mr as PHYSICAL_NAME_FALLBACK_PROPERTIES,Ar as PRISMA_MIGRATION_DIR_RE,__ as PUBLIC_PACKAGE_NAME,fe as REDACTED_KEY_SENTINEL,Q as REGION_SHORT_CODES,d_ as RESERVED_APP_NAMES,G_ as RESERVED_APP_NAME_MESSAGE,Y_ as RESERVED_APP_NAME_SUFFIX,h_ as RESERVED_APP_NAME_SUFFIX_MESSAGE,aE as RESOURCE_CATEGORIES,cE as RETIRED_REGION_ABBREVIATIONS,Tr as SCHEMA_ADMIN_PASSWORD_ENV,rr as SCHEMA_ADMIN_USER_ENV,or as SCHEMA_GATE_EXIT,ar as SCHEMA_GATE_EXIT_HINTS,Ue as SCOPED_TOKEN_REGEX,FE as SCOPE_VALUES,YE as SECRET_NAME_ERROR,gE as SECRET_NAME_PATTERN,dE as SESSION_ONLY_API_ROUTES,T_ as SETUP_COMMANDS,S_ as SETUP_MODES,o_ as SETUP_STEPS,t_ as SETUP_STEP_IDS,I_ as SKILL_INSTALL_FILENAME,O_ as SKILL_INSTALL_PATH,R_ as SKILL_INSTALL_SEGMENTS,HE as SSM_COMPONENT_ERROR,hE as SSM_COMPONENT_PATTERN,VE as SSM_STANDARD_MAX_VALUE_BYTES,ur as STATIC_SITE_CDN_CONFIG_KEYS,Fr as STATIC_SITE_CONFIG_KEYS,lr as STATIC_SITE_DEPLOY_INJECTED_KEYS,dr as STATIC_SITE_ROUTING_INFO,xr as STATIC_SITE_ROUTING_VALUES,ge as STRUCTURAL_ENVIRONMENTS,KE as SecretNamespaceSchema,k_ as ServiceArtefactSchema,J_ as ServiceArtefactsSchema,C as TOKEN_STDERR_PREFIX,uE as USER_GRANTABLE_SCOPES,mE as abbreviateRegion,f as accountConstructKey,be as accountStageEffect,je as accountTier,l as albDnsExportName,u as albHostedZoneIdExportName,w_ as artefactOutputKey,d as bucketWebsiteEndpointExportName,G as bucketWebsiteHostedZoneIdExportName,M_ as buildAppConfigPath,yE as buildNamespaceParts,vE as buildParameterPath,M as capitalise,NE as categoriseResource,x as cdnDomainExportName,q as defaultConnectedAccountName,kr as defaultFormsCorsOrigin,Wr as defaultFormsFromAddress,PT as deploymentFailureDocsUrl,n_ as deriveAllTargets,K_ as deriveContentHashTag,pT as deriveErrorMessageFromFailure,C_ as deriveRegionsFromOrgConfig,m_ as deriveTargets,Y as ec2ServiceName,gT as ensureGitignoreEntries,P_ as environmentOrTier,Xe as environmentToTier,WE as escapeDotEnvValue,L_ as explainRetiredTargetName,cT as extractErrorWindow,pe as filterDangerousEnvVars,w as findAccountNameCollision,U_ as findBoundaryPath,f_ as findInfrastructurePaths,s_ as findTarget,$ as findTrailingRegionShortCode,Oe as fjallCredentialsPath,ie as fjallHomeDir,Ce as fjallLogDir,me as fjallStatePath,ke as formatAccountStageList,te as formatErrorString,p_ as generateTargetName,r as getDomainExportNames,T as getDomainStackName,A as getDomainUsEast1CertificatesStackName,Ze as getEnvironmentLabel,Ae as getErrorCode,re as getErrorMessage,Se as getErrorStack,RE as getExpectedDuration,IE as getFriendlyResourceType,LE as getRegionInfo,c as getSafeZoneName,U as hasAsciiStableConstructKey,Te as hasErrorCode,H_ as hasReservedAppNameSuffix,S as hostsExportPartName,n as imageTagParameterName,u_ as inferContainerFromCandidates,He as isAccountStage,ye as isAccountTier,Jr as isAddressAtDomain,rE as isBackupTier,tE as isCodemodStatementType,e_ as isComplianceIssueStatus,Vr as isFramework,Be as isGovernanceTier,F_ as isInfrastructureFile,XE as isManageablePath,a as isManagedDomainBinding,fr as isOpenNextPatternType,sr as isPatternType,g_ as isReservedAppName,xe as mapSettledWithConcurrency,Me as maskSensitiveOutput,h as mintedEc2KeyPairName,_e as normaliseError,DE as optInRegionWarning,mT as parseDeploymentFailure,bE as parseDotEnv,iE as parseGitRemoteUrl,BE as parseParameterPath,ce as parseShellArgs,Dr as patternConstructId,J as projectCapacityIdentityToTarget,yr as recommendPatternForFramework,ee as regionSuffixRejectionMessage,ME as regions,Br as requiredInputsForFramework,we as resolveSynthEnvironment,Nr as schemaGateExitKind,t as serialiseHostsChunks,Pe as singleton,le as sleep,Je as stageFromWireEnvironment,z as suffixedAccountName,fE as suggestRegionForTimezone,TE as tierDefault,DT as toDeploymentFailureAnalysis,s as toKebab,L as toPascalCase,D as toScreamingSnake,p as toValidDatabaseName,A_ as upgradeCommand};
|
|
@@ -23,3 +23,18 @@ export declare const MACHINE_ONLY_SCOPES: readonly TokenScope[];
|
|
|
23
23
|
export declare const GOVERNANCE_SCOPE_REQUIRED_CODE = "governance_scope_required";
|
|
24
24
|
/** Scopes a user `*` grant expands to (excludes `admin` + machine-only). */
|
|
25
25
|
export declare const USER_GRANTABLE_SCOPES: readonly TokenScope[];
|
|
26
|
+
/**
|
|
27
|
+
* API routes that accept ONLY an interactive browser session — every
|
|
28
|
+
* Bearer-token caller (the CLI, the MCP server, a CI job) is refused at the
|
|
29
|
+
* webapp's trust boundary regardless of scope. The CLI therefore carries no
|
|
30
|
+
* client method for any route listed here: a Bearer client targeting one is
|
|
31
|
+
* dead code that can only ever 403, and the CLI guard test
|
|
32
|
+
* (`cli/src/util/api/__tests__/sessionOnlyRoutes.guard.test.ts`) fails
|
|
33
|
+
* closed if one is added.
|
|
34
|
+
*
|
|
35
|
+
* Stopgap, deleted with its guard when primitive 4 of the CLI dead-weight
|
|
36
|
+
* remediation (a per-path API route contract shared by the webapp and its
|
|
37
|
+
* clients) lands — that contract types the principal class per route, so the
|
|
38
|
+
* list stops needing to be hand-maintained here.
|
|
39
|
+
*/
|
|
40
|
+
export declare const SESSION_ONLY_API_ROUTES: readonly ["/api/ci/tokens"];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const r=["read","write","deploy","secrets:read","secrets:write","destroy","admin","applications:read","applications:deploy","deploy:oidc:mint","deploy:governance"],o={read:"user",write:"user",deploy:"user","secrets:read":"user","secrets:write":"user",destroy:"user",admin:"admin","applications:read":"user","applications:deploy":"user","deploy:oidc:mint":"machine","deploy:governance":"machine"},s=r.filter(e=>o[e]==="machine"),t="governance_scope_required",i=r.filter(e=>o[e]==="user");export{t as GOVERNANCE_SCOPE_REQUIRED_CODE,s as MACHINE_ONLY_SCOPES,r as SCOPE_VALUES,i as USER_GRANTABLE_SCOPES};
|
|
1
|
+
const r=["read","write","deploy","secrets:read","secrets:write","destroy","admin","applications:read","applications:deploy","deploy:oidc:mint","deploy:governance"],o={read:"user",write:"user",deploy:"user","secrets:read":"user","secrets:write":"user",destroy:"user",admin:"admin","applications:read":"user","applications:deploy":"user","deploy:oidc:mint":"machine","deploy:governance":"machine"},s=r.filter(e=>o[e]==="machine"),t="governance_scope_required",i=r.filter(e=>o[e]==="user"),n=["/api/ci/tokens"];export{t as GOVERNANCE_SCOPE_REQUIRED_CODE,s as MACHINE_ONLY_SCOPES,r as SCOPE_VALUES,n as SESSION_ONLY_API_ROUTES,i as USER_GRANTABLE_SCOPES};
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* re-deriving the answer from a ternary chain whose `else` branch would
|
|
16
16
|
* otherwise absorb the new pattern.
|
|
17
17
|
*/
|
|
18
|
+
import type { PolicyResourceKind } from "../posturePolicy/resourceKinds.js";
|
|
18
19
|
export declare const PATTERN_TYPE_VALUES: readonly ["payload", "nextjs", "staticsite"];
|
|
19
20
|
export type PatternType = (typeof PATTERN_TYPE_VALUES)[number];
|
|
20
21
|
export declare const PATTERN_TYPES: ReadonlySet<string>;
|
|
@@ -74,6 +75,15 @@ export interface PatternDescriptor {
|
|
|
74
75
|
* generated wholesale and therefore knows its own layout.
|
|
75
76
|
*/
|
|
76
77
|
readonly requiredCreateInputs: readonly PatternCreateInput[];
|
|
78
|
+
/**
|
|
79
|
+
* The CloudFormation resource types the pattern's construct synthesises,
|
|
80
|
+
* at every tier it can be created at, projected onto the posture
|
|
81
|
+
* registry's vocabulary (`POLICY_RESOURCE_KINDS`): the footprint the
|
|
82
|
+
* create surfaces hand to `expectedRowsAtDefault`, so a pattern is told
|
|
83
|
+
* only about the findings its own resources produce. Pinned to the
|
|
84
|
+
* synthesised templates by the constructs' pattern-footprint test.
|
|
85
|
+
*/
|
|
86
|
+
readonly synthesises: readonly PolicyResourceKind[];
|
|
77
87
|
}
|
|
78
88
|
export declare const PATTERN_REGISTRY: {
|
|
79
89
|
readonly payload: {
|
|
@@ -83,6 +93,7 @@ export declare const PATTERN_REGISTRY: {
|
|
|
83
93
|
readonly stackPlacement: "compute";
|
|
84
94
|
readonly deployable: true;
|
|
85
95
|
readonly requiredCreateInputs: readonly [];
|
|
96
|
+
readonly synthesises: readonly ["AWS::S3::Bucket", "AWS::KMS::Key"];
|
|
86
97
|
};
|
|
87
98
|
readonly nextjs: {
|
|
88
99
|
readonly label: "Next.js";
|
|
@@ -91,6 +102,7 @@ export declare const PATTERN_REGISTRY: {
|
|
|
91
102
|
readonly stackPlacement: "compute";
|
|
92
103
|
readonly deployable: false;
|
|
93
104
|
readonly requiredCreateInputs: readonly [];
|
|
105
|
+
readonly synthesises: readonly ["AWS::S3::Bucket", "AWS::KMS::Key"];
|
|
94
106
|
};
|
|
95
107
|
readonly staticsite: {
|
|
96
108
|
readonly label: "Static site";
|
|
@@ -99,6 +111,7 @@ export declare const PATTERN_REGISTRY: {
|
|
|
99
111
|
readonly stackPlacement: "cdn";
|
|
100
112
|
readonly deployable: true;
|
|
101
113
|
readonly requiredCreateInputs: readonly ["source", "buildCommand", "outputDir"];
|
|
114
|
+
readonly synthesises: readonly ["AWS::S3::Bucket"];
|
|
102
115
|
};
|
|
103
116
|
};
|
|
104
117
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var n=Object.defineProperty;var e=(t,a)=>n(t,"name",{value:a,configurable:!0});import{toPascalCase as
|
|
1
|
+
var n=Object.defineProperty;var e=(t,a)=>n(t,"name",{value:a,configurable:!0});import{toPascalCase as r}from"../naming/caseConversion.js";const s=["payload","nextjs","staticsite"],c=new Set(s);function T(t){return typeof t=="string"&&c.has(t)}e(T,"isPatternType");const S=["source","buildCommand","outputDir"],d={source:"--source",buildCommand:"--build-command",outputDir:"--output-dir"},o={payload:{label:"Payload CMS",constructIdSuffix:"Payload",artefact:"opennext-lambda",stackPlacement:"compute",deployable:!0,requiredCreateInputs:[],synthesises:["AWS::S3::Bucket","AWS::KMS::Key"]},nextjs:{label:"Next.js",constructIdSuffix:"Nextjs",artefact:"opennext-lambda",stackPlacement:"compute",deployable:!1,requiredCreateInputs:[],synthesises:["AWS::S3::Bucket","AWS::KMS::Key"]},staticsite:{label:"Static site",constructIdSuffix:"StaticSite",artefact:"static-assets",stackPlacement:"cdn",deployable:!0,requiredCreateInputs:["source","buildCommand","outputDir"],synthesises:["AWS::S3::Bucket"]}};function E(t,a){return`${r(t)}${o[a].constructIdSuffix}`}e(E,"patternConstructId");const _=s.filter(t=>o[t].deployable),i=s.filter(t=>o[t].artefact==="opennext-lambda"),u=new Set(i);function m(t){return t!=null&&u.has(t)}e(m,"isOpenNextPatternType");const x=["multipage","directory","spa"],P={multipage:{label:"Multi-page (.html files)",summary:"/about serves /about.html"},directory:{label:"Directory index",summary:"/about serves /about/index.html"},spa:{label:"Single-page app",summary:"unknown paths fall back to /index.html"}},I=["PriceClass_100","PriceClass_200","PriceClass_All"],A=["type","name","source","build","routing","security","domain","managedDomain","zoneName","hostedZoneId","forms","cdn","accessGate"],C=["managedDomain"],N=["behaviours","priceClass","invalidateOnDeploy"];export{I as CLOUDFRONT_PRICE_CLASS_VALUES,_ as DEPLOYABLE_PATTERN_TYPES,i as OPENNEXT_PATTERN_TYPES,d as PATTERN_CREATE_INPUT_FLAGS,S as PATTERN_CREATE_INPUT_VALUES,o as PATTERN_REGISTRY,c as PATTERN_TYPES,s as PATTERN_TYPE_VALUES,N as STATIC_SITE_CDN_CONFIG_KEYS,A as STATIC_SITE_CONFIG_KEYS,C as STATIC_SITE_DEPLOY_INJECTED_KEYS,P as STATIC_SITE_ROUTING_INFO,x as STATIC_SITE_ROUTING_VALUES,m as isOpenNextPatternType,T as isPatternType,E as patternConstructId};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@fjall/util/posturePolicy` — the tier-aware alert policy's client-safe
|
|
3
|
+
* data and words (design 2026-09-01-tier-aware-alert-policy § 13): the
|
|
4
|
+
* expected and mitigated registries, the status-label table, the machine
|
|
5
|
+
* lanes and the sentence builders the create surfaces print. No node
|
|
6
|
+
* built-ins: the webapp imports this subpath in browser code and the CLI in
|
|
7
|
+
* its Ink screens. The webapp's scan predicate, the rule titles and the
|
|
8
|
+
* lane writers' actor sentinel stay server-side in the webapp.
|
|
9
|
+
*/
|
|
10
|
+
export { ISSUE_STATUS_LABELS, countClause, listStatusClauses, storedStatusClause, type IssueStatusLabels } from "./issueStatusLabels.js";
|
|
11
|
+
export { MACHINE_LANE_STATUSES, isMachineLaneStatus, type MachineLaneStatus } from "./machineLane.js";
|
|
12
|
+
export { CODEMOD_STATEMENT_TYPES, isCodemodStatementType, type CodemodStatementType } from "../codemod/statementTypes.js";
|
|
13
|
+
export { POLICY_RESOURCE_KINDS, isPolicyResourceKind, policyResourceFootprint, type PolicyResourceFootprint, type PolicyResourceKind } from "./resourceKinds.js";
|
|
14
|
+
export { DEFAULT_POLICY_REGISTRY, EXPECTED_LANE_STAGES, EXPECTED_POLICY, MITIGATED_POLICY, cureClause, cureEdits, cureEntries, evidenceClause, expectedRowCause, findPolicyRow, findPolicyRowByKey, isExpectedLaneStage, laneGroupHeading, policyRowKey, policyRowPresentation, type ExpectedLaneStage, type ExpectedPolicyRow, type MitigatedPolicyRow, type PatternCure, type PolicyCure, type PolicyCureEdit, type PolicyCureEntry, type PolicyRegistry, type PolicyResourceScope, type PolicyRowLookup, type PolicyRowMatch, type PolicyRowPresentation } from "./registry.js";
|
|
15
|
+
export { TIER_CONSENT_NOTE_LABEL, expectedLaneWhereClause, expectedRowsAtDefault, tierConsentLead, tierConsentLine, type TierConsentLead, type TierConsentLine } from "./tierConsent.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{ISSUE_STATUS_LABELS as t,countClause as E,listStatusClauses as r,storedStatusClause as s}from"./issueStatusLabels.js";import{MACHINE_LANE_STATUSES as a,isMachineLaneStatus as n}from"./machineLane.js";import{CODEMOD_STATEMENT_TYPES as C,isCodemodStatementType as T}from"../codemod/statementTypes.js";import{POLICY_RESOURCE_KINDS as u,isPolicyResourceKind as _,policyResourceFootprint as p}from"./resourceKinds.js";import{DEFAULT_POLICY_REGISTRY as l,EXPECTED_LANE_STAGES as d,EXPECTED_POLICY as R,MITIGATED_POLICY as A,cureClause as I,cureEdits as P,cureEntries as x,evidenceClause as y,expectedRowCause as f,findPolicyRow as O,findPolicyRowByKey as m,isExpectedLaneStage as D,laneGroupHeading as N,policyRowKey as w,policyRowPresentation as Y}from"./registry.js";import{TIER_CONSENT_NOTE_LABEL as U,expectedLaneWhereClause as G,expectedRowsAtDefault as K,tierConsentLead as B,tierConsentLine as g}from"./tierConsent.js";export{C as CODEMOD_STATEMENT_TYPES,l as DEFAULT_POLICY_REGISTRY,d as EXPECTED_LANE_STAGES,R as EXPECTED_POLICY,t as ISSUE_STATUS_LABELS,a as MACHINE_LANE_STATUSES,A as MITIGATED_POLICY,u as POLICY_RESOURCE_KINDS,U as TIER_CONSENT_NOTE_LABEL,E as countClause,I as cureClause,P as cureEdits,x as cureEntries,y as evidenceClause,G as expectedLaneWhereClause,f as expectedRowCause,K as expectedRowsAtDefault,O as findPolicyRow,m as findPolicyRowByKey,T as isCodemodStatementType,D as isExpectedLaneStage,n as isMachineLaneStatus,_ as isPolicyResourceKind,N as laneGroupHeading,r as listStatusClauses,p as policyResourceFootprint,w as policyRowKey,Y as policyRowPresentation,s as storedStatusClause,B as tierConsentLead,g as tierConsentLine};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The words a ComplianceIssue status is shown with — the one home for that
|
|
3
|
+
* copy. `../complianceIssue` owns the vocabulary's meaning
|
|
4
|
+
* (`COMPLIANCE_ISSUE_STATUSES`); this table renders it, and every surface
|
|
5
|
+
* that prints a status — the webapp's badges, panels, digest and export, the
|
|
6
|
+
* CLI's create-time consent note — takes the words from here, so two clients
|
|
7
|
+
* cannot disagree on a sentence. Client-safe.
|
|
8
|
+
*
|
|
9
|
+
* Three renderings per status, because they do not collapse into one (alert
|
|
10
|
+
* policy design § 13.11 (e)): the badge is a single capitalised word beside
|
|
11
|
+
* a finding; the clause is a predicate that reads after "is" and after a
|
|
12
|
+
* count ("this finding is expected at this stage", "3 expected at this
|
|
13
|
+
* stage"); the heading is what a lane's rows sit under on the asset panel,
|
|
14
|
+
* the lane digest and the CSV export. The two machine lanes never share a
|
|
15
|
+
* word (ruled). A full `Record` over the vocabulary, so a status added to
|
|
16
|
+
* it fails here at typecheck, at the one place its copy is authored.
|
|
17
|
+
*/
|
|
18
|
+
import { type ComplianceIssueStatus } from "../complianceIssue.js";
|
|
19
|
+
export interface IssueStatusLabels {
|
|
20
|
+
/** One capitalised word, the badge beside a finding. */
|
|
21
|
+
badge: string;
|
|
22
|
+
/** Lower-case predicate: reads after "is" and after a count. */
|
|
23
|
+
clause: string;
|
|
24
|
+
/**
|
|
25
|
+
* The heading a lane's rows sit under on the asset panel and the digest,
|
|
26
|
+
* and the export's count column for that lane. `null` for `open`: its rows
|
|
27
|
+
* are the work band and sit under no heading. (A verifying row joins that
|
|
28
|
+
* band on the panel — the band is the scoring set, the webapp's
|
|
29
|
+
* `issue-display-groups` — yet keeps a heading for its export column.)
|
|
30
|
+
*/
|
|
31
|
+
heading: string | null;
|
|
32
|
+
}
|
|
33
|
+
export declare const ISSUE_STATUS_LABELS: {
|
|
34
|
+
readonly open: {
|
|
35
|
+
readonly badge: "Open";
|
|
36
|
+
readonly clause: "open";
|
|
37
|
+
readonly heading: null;
|
|
38
|
+
};
|
|
39
|
+
readonly acknowledged: {
|
|
40
|
+
readonly badge: "Acknowledged";
|
|
41
|
+
readonly clause: "acknowledged";
|
|
42
|
+
readonly heading: "Acknowledged";
|
|
43
|
+
};
|
|
44
|
+
readonly pending_verification: {
|
|
45
|
+
readonly badge: "Verifying";
|
|
46
|
+
readonly clause: "awaiting verification";
|
|
47
|
+
readonly heading: "Awaiting verification";
|
|
48
|
+
};
|
|
49
|
+
readonly resolved: {
|
|
50
|
+
readonly badge: "Resolved";
|
|
51
|
+
readonly clause: "resolved";
|
|
52
|
+
readonly heading: "Resolved";
|
|
53
|
+
};
|
|
54
|
+
readonly suppressed: {
|
|
55
|
+
readonly badge: "Suppressed";
|
|
56
|
+
readonly clause: "suppressed";
|
|
57
|
+
readonly heading: "Suppressed";
|
|
58
|
+
};
|
|
59
|
+
readonly expected: {
|
|
60
|
+
readonly badge: "Expected";
|
|
61
|
+
readonly clause: "expected at this stage";
|
|
62
|
+
readonly heading: "Expected at this stage";
|
|
63
|
+
};
|
|
64
|
+
readonly mitigated: {
|
|
65
|
+
readonly badge: "Mitigated";
|
|
66
|
+
readonly clause: "mitigated";
|
|
67
|
+
readonly heading: "Mitigated";
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* The clause of a stored status, for a message that names the state a row
|
|
72
|
+
* is in. A stored value outside the vocabulary is a later writer's: it is
|
|
73
|
+
* shown quoted as the token it is, never dressed as one of ours.
|
|
74
|
+
*/
|
|
75
|
+
export declare function storedStatusClause(status: string): string;
|
|
76
|
+
/** `"N <clause>"` — the count clause every conformance figure's sublabel is built from. */
|
|
77
|
+
export declare function countClause(count: number, status: ComplianceIssueStatus): string;
|
|
78
|
+
/**
|
|
79
|
+
* The statuses' clauses as one list in vocabulary order — "a, b or c" —
|
|
80
|
+
* whatever order the caller holds them in, so a sentence derived from a
|
|
81
|
+
* policy set reads the same as the set's own declaration order changes.
|
|
82
|
+
*/
|
|
83
|
+
export declare function listStatusClauses(statuses: readonly ComplianceIssueStatus[]): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var c=Object.defineProperty;var t=(e,a)=>c(e,"name",{value:a,configurable:!0});import{COMPLIANCE_ISSUE_STATUSES as g,isComplianceIssueStatus as u}from"../complianceIssue.js";const i={open:{badge:"Open",clause:"open",heading:null},acknowledged:{badge:"Acknowledged",clause:"acknowledged",heading:"Acknowledged"},pending_verification:{badge:"Verifying",clause:"awaiting verification",heading:"Awaiting verification"},resolved:{badge:"Resolved",clause:"resolved",heading:"Resolved"},suppressed:{badge:"Suppressed",clause:"suppressed",heading:"Suppressed"},expected:{badge:"Expected",clause:"expected at this stage",heading:"Expected at this stage"},mitigated:{badge:"Mitigated",clause:"mitigated",heading:"Mitigated"}};function r(e){return u(e)?i[e].clause:`"${e}"`}t(r,"storedStatusClause");function S(e,a){return`${e} ${i[a].clause}`}t(S,"countClause");const d=new Map(g.map((e,a)=>[e,a]));function f(e){const a=[...new Set(e)].sort((s,o)=>(d.get(s)??0)-(d.get(o)??0)).map(s=>i[s].clause),n=a.pop();return n===void 0?"":a.length===0?n:`${a.join(", ")} or ${n}`}t(f,"listStatusClauses");export{i as ISSUE_STATUS_LABELS,S as countClause,f as listStatusClauses,r as storedStatusClause};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The machine lanes of the alert policy (design
|
|
3
|
+
* 2026-09-01-tier-aware-alert-policy § 13): the two statuses only the scan
|
|
4
|
+
* writes, each spoken for by one registry row (`./registry`). The lane
|
|
5
|
+
* arbitration's write type, the digest's read predicate and the asset
|
|
6
|
+
* panel's grouping all derive from this pair, so a third lane reaches each
|
|
7
|
+
* of them at once. Lives beside the registry because `PolicyRowMatch` is
|
|
8
|
+
* typed on it; the webapp's status classifier re-exports it.
|
|
9
|
+
*/
|
|
10
|
+
export declare const MACHINE_LANE_STATUSES: readonly ["expected", "mitigated"];
|
|
11
|
+
export type MachineLaneStatus = (typeof MACHINE_LANE_STATUSES)[number];
|
|
12
|
+
/** Narrows a stored status to a machine lane — the read guard of every lane surface. */
|
|
13
|
+
export declare function isMachineLaneStatus(status: string): status is MachineLaneStatus;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var E=Object.defineProperty;var e=(t,n)=>E(t,"name",{value:n,configurable:!0});const S=["expected","mitigated"],a=new Set(S);function i(t){return a.has(t)}e(i,"isMachineLaneStatus");export{S as MACHINE_LANE_STATUSES,i as isMachineLaneStatus};
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The expected and mitigated lanes of the alert policy (design
|
|
3
|
+
* 2026-09-01-tier-aware-alert-policy § 13). Two static registries keyed by
|
|
4
|
+
* rule id, client-safe (no node built-ins) and shared by every surface that
|
|
5
|
+
* speaks for a finding: the webapp's scan predicate, asset panel, digest and
|
|
6
|
+
* export, and the CLI's create-time consent note.
|
|
7
|
+
*
|
|
8
|
+
* - `EXPECTED_POLICY`: findings a construct knob's default deliberately
|
|
9
|
+
* produces on Fjall-managed infrastructure. Softened to `expected` only on
|
|
10
|
+
* a development- or staging-stage account (`EXPECTED_LANE_STAGES`) of the
|
|
11
|
+
* account tier; on every other stage, on an organisation- or platform-tier
|
|
12
|
+
* account, and for an organisation that set posture to strict, they flag.
|
|
13
|
+
* - `MITIGATED_POLICY`: findings a compensating control already meets
|
|
14
|
+
* (§ 13.4a). Never a finding at any stage or tier, counted as met in both
|
|
15
|
+
* scores, visible with the evidence pointer.
|
|
16
|
+
*
|
|
17
|
+
* Everything unlisted flags, and every predicate failure flags
|
|
18
|
+
* (fail-toward-flag). The predicate is the webapp's, server-side
|
|
19
|
+
* (`app/.server/services/compliance-rules/expectedPolicy.ts`): it reads the
|
|
20
|
+
* scan's policy context, which no client has. The rule ids are the webapp's
|
|
21
|
+
* rule registry's; its tests cross-check every row against it, and against
|
|
22
|
+
* the remediation edit each cure names.
|
|
23
|
+
*/
|
|
24
|
+
import type { AccountStage } from "../environments.js";
|
|
25
|
+
import { type PatternType } from "../patterns/patternTypes.js";
|
|
26
|
+
import type { BackupTierDefaults } from "../backupTiers.js";
|
|
27
|
+
import { type CodemodStatementType } from "../codemod/statementTypes.js";
|
|
28
|
+
import type { MachineLaneStatus } from "./machineLane.js";
|
|
29
|
+
import type { PolicyResourceKind } from "./resourceKinds.js";
|
|
30
|
+
/** Account stages on which an expected-lane finding is softened. */
|
|
31
|
+
export declare const EXPECTED_LANE_STAGES: readonly ["development", "staging"];
|
|
32
|
+
export type ExpectedLaneStage = (typeof EXPECTED_LANE_STAGES)[number];
|
|
33
|
+
export declare function isExpectedLaneStage(stage: AccountStage): stage is ExpectedLaneStage;
|
|
34
|
+
/**
|
|
35
|
+
* Narrows a row to the resources it speaks for, by one of two signals:
|
|
36
|
+
*
|
|
37
|
+
* - `logicalIdContains`: CloudFormation tags each resource with its logical
|
|
38
|
+
* id, which the scan stores as `iacInfo.logicalId`; the id is the construct
|
|
39
|
+
* path joined with a trailing hash, so the row matches on the construct's
|
|
40
|
+
* own id as a substring. Only for an id nothing but that construct can
|
|
41
|
+
* carry — a fragment a customer's own construct could share
|
|
42
|
+
* (`assetsBucket`) would match their production uploads bucket.
|
|
43
|
+
* - `tag`: a tag the construct stamps on the resource, read from the asset's
|
|
44
|
+
* stored tags. The key alone matches on presence; with `value`, on that
|
|
45
|
+
* value. An asset whose tags the scan has never read (`tags: null`)
|
|
46
|
+
* matches nothing, and a partial read keeps the prior tags, so a throttled
|
|
47
|
+
* scan neither gains nor loses a row here.
|
|
48
|
+
*/
|
|
49
|
+
export type PolicyResourceScope = {
|
|
50
|
+
logicalIdContains: string;
|
|
51
|
+
} | {
|
|
52
|
+
tag: {
|
|
53
|
+
key: string;
|
|
54
|
+
value?: string;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* A `BACKUP_TIER_DEFAULTS` column whose `false` produces a K1 finding: the
|
|
59
|
+
* knob the app's backup tier owns and the construct reads through
|
|
60
|
+
* `tierDefault`. Boolean columns only — the K1 rows are cost-saving defaults
|
|
61
|
+
* that are off, so "off" is the one polarity the registry speaks.
|
|
62
|
+
*/
|
|
63
|
+
type BackupTierFindingKnob = {
|
|
64
|
+
[K in keyof BackupTierDefaults]: BackupTierDefaults[K] extends boolean ? K : never;
|
|
65
|
+
}[keyof BackupTierDefaults];
|
|
66
|
+
/**
|
|
67
|
+
* A cure on the `pattern` family. A pattern statement is one of several
|
|
68
|
+
* pattern types, each with a config schema of its own, so the edit names the
|
|
69
|
+
* pattern types whose config carries its path: the media bucket is an
|
|
70
|
+
* OpenNext resource, and a static site's config has no `storage` key at
|
|
71
|
+
* all. The generator's modify gate refuses the edit on any other type, and
|
|
72
|
+
* the webapp offers it only where it applies.
|
|
73
|
+
*/
|
|
74
|
+
export interface PatternCure {
|
|
75
|
+
/** The edit as the user writes it on the pattern statement: `storage.media.versioned: true`. */
|
|
76
|
+
readonly edit: string;
|
|
77
|
+
/** The pattern types whose config carries the edit's path; never empty. */
|
|
78
|
+
readonly patterns: readonly PatternType[];
|
|
79
|
+
}
|
|
80
|
+
/** The cure on one family: the edit alone, or for `pattern` the edit with the pattern types it applies to. */
|
|
81
|
+
export type PolicyCureEdit<Family extends CodemodStatementType> = Family extends "pattern" ? PatternCure : string;
|
|
82
|
+
/**
|
|
83
|
+
* The cure per family of statement the finding's resource can belong to,
|
|
84
|
+
* keyed by the codemod's vocabulary: a non-empty partial record — the union,
|
|
85
|
+
* over every family, of "this family required, the rest optional" — so `{}`
|
|
86
|
+
* is unrepresentable and a key the codemod cannot address fails typecheck.
|
|
87
|
+
* Each value is the edit as the user writes it in `infrastructure.ts` on a
|
|
88
|
+
* statement of that family (`versioned: true` on a `storage` statement,
|
|
89
|
+
* `storage.media.versioned: true` on the `pattern` statement that owns the
|
|
90
|
+
* bucket, scoped to the pattern types that carry the path).
|
|
91
|
+
*/
|
|
92
|
+
export type PolicyCure = {
|
|
93
|
+
[Family in CodemodStatementType]: {
|
|
94
|
+
readonly [K in Family]: PolicyCureEdit<K>;
|
|
95
|
+
} & {
|
|
96
|
+
readonly [K in Exclude<CodemodStatementType, Family>]?: PolicyCureEdit<K>;
|
|
97
|
+
};
|
|
98
|
+
}[CodemodStatementType];
|
|
99
|
+
export interface ExpectedPolicyRow {
|
|
100
|
+
ruleId: string;
|
|
101
|
+
/**
|
|
102
|
+
* The CloudFormation resource type the row's findings sit on: one of the
|
|
103
|
+
* rule's `resourceTypes` (the webapp's parity test pins it), and what a
|
|
104
|
+
* create surface's footprint is matched against (`./tierConsent`).
|
|
105
|
+
*/
|
|
106
|
+
kind: PolicyResourceKind;
|
|
107
|
+
/** Present on a resource-scoped row: for that resource a scoped row wins over the rule's unscoped row. */
|
|
108
|
+
resource?: PolicyResourceScope;
|
|
109
|
+
/** The knob whose default causes the finding: what the user sets, and on which construct. Groups findings by cause on the asset page. */
|
|
110
|
+
knob: {
|
|
111
|
+
name: string;
|
|
112
|
+
construct: string;
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Where the knob is a tier (`backup.tier`): the tier-defaults column that
|
|
116
|
+
* decides the finding, `false` producing it. The create-app wizard and
|
|
117
|
+
* the CLI's create flow read it to list, for a chosen tier, the rows the
|
|
118
|
+
* tier leaves at that default (`./tierConsent`); a row without one is
|
|
119
|
+
* produced at every tier.
|
|
120
|
+
*/
|
|
121
|
+
tierDefault?: BackupTierFindingKnob;
|
|
122
|
+
/**
|
|
123
|
+
* What the knob's default chose and why it is cheaper. A lower-case clause
|
|
124
|
+
* that reads after "Expected on a development-stage account: ", no
|
|
125
|
+
* trailing full stop.
|
|
126
|
+
*/
|
|
127
|
+
expectation: string;
|
|
128
|
+
/**
|
|
129
|
+
* The cure exactly as the user writes it in `infrastructure.ts`, per
|
|
130
|
+
* family of statement the resource can belong to (`PolicyCure`). Each
|
|
131
|
+
* entry is the one edit the rule's RemediationHint applies for that
|
|
132
|
+
* family, so the clause and the Remediate button name the same change
|
|
133
|
+
* (`${edit.property}: ${formatEditValue(edit.value)}` — a string value
|
|
134
|
+
* quoted, as the PR writes it — pinned per family, and for `pattern` per
|
|
135
|
+
* applicable pattern type, by the webapp's expectedPolicy.test). Where
|
|
136
|
+
* the knob is a tier (`backup.tier`) the cure is deliberately the
|
|
137
|
+
* per-construct override the remediation lane writes, not the tier: the
|
|
138
|
+
* heading names the cause, the cure names the edit. A resource whose
|
|
139
|
+
* statement no entry applies to — a static site's bucket, whose config
|
|
140
|
+
* has no versioning key — is cured by the tier alone.
|
|
141
|
+
*/
|
|
142
|
+
cure: PolicyCure;
|
|
143
|
+
/** A high-severity finding is softened only with this per-row opt-in (§ 5c); critical never is. */
|
|
144
|
+
allowHigh?: true;
|
|
145
|
+
}
|
|
146
|
+
export interface MitigatedPolicyRow {
|
|
147
|
+
ruleId: string;
|
|
148
|
+
/** The CloudFormation resource type the control covers: one of the rule's `resourceTypes`. */
|
|
149
|
+
kind: PolicyResourceKind;
|
|
150
|
+
resource?: PolicyResourceScope;
|
|
151
|
+
/**
|
|
152
|
+
* The resource the control covers — a short noun phrase ("cold-tier
|
|
153
|
+
* bucket"; capitals only for an acronym, "ISR cache bucket") that reads
|
|
154
|
+
* after "Mitigated — " as the row's cause on every surface that heads its
|
|
155
|
+
* group. The S3 rows take it from their exemption control, so a stamp
|
|
156
|
+
* value without a name fails typecheck like one without a control.
|
|
157
|
+
*/
|
|
158
|
+
name: string;
|
|
159
|
+
/** The compensating control. A lower-case clause that reads after "Mitigated: ", no trailing full stop. */
|
|
160
|
+
control: string;
|
|
161
|
+
/** Where a reader verifies the control. */
|
|
162
|
+
evidence: string;
|
|
163
|
+
allowHigh?: true;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* The K1 rows: findings a construct's cost-saving default produces on
|
|
167
|
+
* Fjall-managed infrastructure by design. A rule two constructs produce for
|
|
168
|
+
* two causes carries two rows — the construct with a fixed path scoped by
|
|
169
|
+
* its logical id, the open set unscoped — and the scoped row wins.
|
|
170
|
+
*/
|
|
171
|
+
export declare const EXPECTED_POLICY: readonly ExpectedPolicyRow[];
|
|
172
|
+
/**
|
|
173
|
+
* The K4 rows: a shape Fjall's own engineering chose for one construct at
|
|
174
|
+
* every tier, met by a compensating control. Each is scoped to the resources
|
|
175
|
+
* its construct produces (`PolicyResourceScope`); precedence among scoped
|
|
176
|
+
* rows is `findPolicyRow`'s. The S3 rows are one per value of the
|
|
177
|
+
* versioning-exemption stamp, in the stamp's own order (the pinned wire
|
|
178
|
+
* order, not a precedence — a tag carries one value), and the stamp is the
|
|
179
|
+
* whole contract: a bucket a construct left unversioned before the stamp
|
|
180
|
+
* existed (constructs < 33.1.0) falls to the K1 row until it is redeployed —
|
|
181
|
+
* an existing mitigated row reopens as `no_mitigation_row`, the reason the
|
|
182
|
+
* customer reads — because the stamp is what tells posture the omission is
|
|
183
|
+
* by design.
|
|
184
|
+
*/
|
|
185
|
+
export declare const MITIGATED_POLICY: readonly MitigatedPolicyRow[];
|
|
186
|
+
export interface PolicyRegistry {
|
|
187
|
+
expected: readonly ExpectedPolicyRow[];
|
|
188
|
+
mitigated: readonly MitigatedPolicyRow[];
|
|
189
|
+
}
|
|
190
|
+
export declare const DEFAULT_POLICY_REGISTRY: PolicyRegistry;
|
|
191
|
+
export type PolicyRowMatch = {
|
|
192
|
+
lane: Extract<MachineLaneStatus, "expected">;
|
|
193
|
+
row: ExpectedPolicyRow;
|
|
194
|
+
} | {
|
|
195
|
+
lane: Extract<MachineLaneStatus, "mitigated">;
|
|
196
|
+
row: MitigatedPolicyRow;
|
|
197
|
+
};
|
|
198
|
+
export interface PolicyRowLookup {
|
|
199
|
+
ruleId: string;
|
|
200
|
+
/** `iacInfo.logicalId`: the CloudFormation logical id the resource carries, or `null`. */
|
|
201
|
+
logicalId: string | null;
|
|
202
|
+
/** The asset's stored tags, or `null` when the scan has never read them — a tag-scoped row then matches nothing. */
|
|
203
|
+
tags: Readonly<Record<string, string>> | null;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* The row that speaks for this finding. A resource-scoped row wins over an
|
|
207
|
+
* unscoped one across both registries; at equal scope a mitigated row wins
|
|
208
|
+
* over an expected one, a compensating control being the stronger claim;
|
|
209
|
+
* among scoped rows of one lane, registry order. Nothing matches: the rule
|
|
210
|
+
* flags.
|
|
211
|
+
*/
|
|
212
|
+
export declare function findPolicyRow(input: PolicyRowLookup, registry?: PolicyRegistry): PolicyRowMatch | undefined;
|
|
213
|
+
/**
|
|
214
|
+
* The identity of a registry row, stable across the wire: lane, rule and
|
|
215
|
+
* scope. `findPolicyRowByKey` inverts it. The pair is what lets a finding
|
|
216
|
+
* carry its row to the client as one string and the digest fold a lane's
|
|
217
|
+
* findings under one heading per row — a cause with many findings reads as
|
|
218
|
+
* one cause, the cure or the evidence written once.
|
|
219
|
+
*/
|
|
220
|
+
export declare function policyRowKey(match: PolicyRowMatch): string;
|
|
221
|
+
/** The row a `policyRowKey` names, or `undefined` once the registry no longer carries it. */
|
|
222
|
+
export declare function findPolicyRowByKey(key: string, registry?: PolicyRegistry): PolicyRowMatch | undefined;
|
|
223
|
+
/**
|
|
224
|
+
* What a surface writes once for a row's group — the cause its heading
|
|
225
|
+
* carries (an expected row's knob, and the construct it sits on; a
|
|
226
|
+
* mitigated row's `name`, the resource its control covers) and the cure or
|
|
227
|
+
* the evidence. Derived here so the overview digest (server) and the asset
|
|
228
|
+
* panel (client) present a row identically. Every registry row has a cause;
|
|
229
|
+
* `cause` is null only where a surface presents an uncovered group itself.
|
|
230
|
+
*/
|
|
231
|
+
export interface PolicyRowPresentation {
|
|
232
|
+
cause: string | null;
|
|
233
|
+
cure?: string;
|
|
234
|
+
evidence?: string;
|
|
235
|
+
}
|
|
236
|
+
export declare function policyRowPresentation(match: PolicyRowMatch): PolicyRowPresentation;
|
|
237
|
+
/** The cause an expected row's findings are grouped under: the knob, and the construct it sits on. */
|
|
238
|
+
export declare function expectedRowCause(row: ExpectedPolicyRow): string;
|
|
239
|
+
/** One family's cure, read back from a row: the edit, and for `pattern` the pattern types it applies to. */
|
|
240
|
+
export interface PolicyCureEntry {
|
|
241
|
+
readonly family: CodemodStatementType;
|
|
242
|
+
readonly edit: string;
|
|
243
|
+
/** Present on the `pattern` family only. */
|
|
244
|
+
readonly patterns?: readonly PatternType[];
|
|
245
|
+
}
|
|
246
|
+
/** A row's cure entries, one per statement family, in the vocabulary's order. */
|
|
247
|
+
export declare function cureEntries(row: ExpectedPolicyRow): readonly PolicyCureEntry[];
|
|
248
|
+
/**
|
|
249
|
+
* The edits a row's cure names, as one phrase: the edit alone where one
|
|
250
|
+
* family carries the resource and that family is not `pattern`, else each
|
|
251
|
+
* edit tagged with the statement it is written on and joined by "or" —
|
|
252
|
+
* `versioned: true (storage resource) or storage.media.versioned: true
|
|
253
|
+
* (payload or nextjs pattern resource)`. A pattern cure is always tagged:
|
|
254
|
+
* its edit applies to some pattern types and not others, and the tag is
|
|
255
|
+
* what says which. Worded once for the cure clause and the lane-reopen
|
|
256
|
+
* reason.
|
|
257
|
+
*/
|
|
258
|
+
export declare function cureEdits(row: ExpectedPolicyRow): string;
|
|
259
|
+
/** The cure clause of an expected row, worded once for the reason, the digest and the asset panel. */
|
|
260
|
+
export declare function cureClause(row: ExpectedPolicyRow): string;
|
|
261
|
+
/** The evidence clause of a mitigated row, worded once for the reason, the digest and the asset panel. */
|
|
262
|
+
export declare function evidenceClause(row: MitigatedPolicyRow): string;
|
|
263
|
+
/**
|
|
264
|
+
* The heading a lane's findings sit under, on the overview digest, the
|
|
265
|
+
* asset panel and the export alike: the lane's own heading from the
|
|
266
|
+
* status-label table (the two lanes share no word), then the cause — an
|
|
267
|
+
* expected row's knob, a mitigated row's resource. Only an uncovered group
|
|
268
|
+
* has no cause, so only it is headed by the lane word alone.
|
|
269
|
+
*/
|
|
270
|
+
export declare function laneGroupHeading(lane: MachineLaneStatus, cause: string | null): string;
|
|
271
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var g=Object.defineProperty;var i=(e,t)=>g(e,"name",{value:t,configurable:!0});import{KMS_RETENTION_TAG_KEY as m,S3_VERSIONING_EXEMPT_TAG_KEY as d,S3_VERSIONING_EXEMPTIONS as b}from"../aws/index.js";import{OPENNEXT_PATTERN_TYPES as E}from"../patterns/patternTypes.js";import{CODEMOD_STATEMENT_TYPES as S}from"../codemod/statementTypes.js";import{ISSUE_STATUS_LABELS as k}from"./issueStatusLabels.js";const y=["development","staging"];function M(e){return y.includes(e)}i(M,"isExpectedLaneStage");const I=[{ruleId:"SNS_TOPIC_NOT_ENCRYPTED",kind:"AWS::SNS::Topic",resource:{logicalIdContains:"AlarmTopicAlarmNotificationsAlarmNotificationsTopic"},knob:{name:"alarmTopicEncryption",construct:"the alarm topic"},allowHigh:!0,expectation:"the alarm topic is unencrypted because alarmTopicEncryption is off (a customer-managed key costs about $1 to $3 a month per account and region)",cure:{organisation:"alarmTopicEncryption: true"}},{ruleId:"SNS_TOPIC_NOT_ENCRYPTED",kind:"AWS::SNS::Topic",knob:{name:"backup.tier",construct:"the app"},tierDefault:"customerManagedKeys",allowHigh:!0,expectation:"the topic is unencrypted because the app's backup tier does not encrypt topics (the enterprise tier's shared customer-managed key costs about $1 to $3 a month per stack)",cure:{messaging:'encryption: "SSE_KMS"'}},{ruleId:"ECS_CONTAINER_INSIGHTS_DISABLED",kind:"AWS::ECS::Cluster",knob:{name:"backup.tier",construct:"the app"},tierDefault:"containerInsights",expectation:"Container Insights is off because the app's backup tier does not enable it (it bills per metric per cluster)",cure:{compute:"containerInsights: true"}},{ruleId:"S3_VERSIONING_DISABLED",kind:"AWS::S3::Bucket",knob:{name:"backup.tier",construct:"the app"},tierDefault:"s3Versioned",expectation:"bucket versioning is off because the app's backup tier does not version buckets (every overwrite would keep a billed copy)",cure:{storage:"versioned: true",pattern:{edit:"storage.media.versioned: true",patterns:E}}}],h={"build-output":{name:"build-output bucket",control:"the bucket holds OpenNext build output that every deploy rewrites and prunes, so versioning would retain a billed copy of each superseded build; the build is reproduced from the commit that made it",site:"createAssetsBucket in fjall/components/infrastructure/lib/patterns/aws/payload.ts",stamped:"on the assets bucket it leaves unversioned"},"isr-cache":{name:"ISR cache bucket",control:"the bucket is the ISR cache Next.js regenerates at runtime, so versioning would retain a billed copy of every regenerated page; a lost entry is rendered again on the next request",site:"createCacheBucket in fjall/components/infrastructure/lib/patterns/aws/payload.ts",stamped:"on the cache bucket it leaves unversioned"},"cold-tier":{name:"cold-tier bucket",control:"the cold tier is MergeTree tiered storage owned by the database, so parts are written and deleted continuously and object versioning would retain every deleted part at unbounded cost; recoverability is the ClickHouse backup lane",site:"ClickHouseColdTierBucket in fjall/components/infrastructure/lib/patterns/aws/clickhouseDatabase.ts",stamped:"(versioned: false by design), the versioned backup bucket beside it"},"access-logs":{name:"access-log bucket",control:"the bucket is the stack's access-log delivery target (application load balancer and CloudFront access logs, expired after 90 days by its lifecycle rule), so versioning would only multiply expired objects",site:"stackAccessLogBucket in fjall/components/infrastructure/lib/resources/aws/logging/accessLogBucket.ts",stamped:"(versioned: false, ACCESS_LOG_RETENTION_DAYS expiry)"}},T=[...b.map(e=>{const{name:t,control:n,site:r,stamped:o}=h[e];return{ruleId:"S3_VERSIONING_DISABLED",kind:"AWS::S3::Bucket",resource:{tag:{key:d,value:e}},name:t,control:n,evidence:`${r} stamps ${d}=${e} ${o}`}}),{ruleId:"KMS_KEY_ORPHAN",kind:"AWS::KMS::Key",resource:{tag:{key:m}},name:"retained customer key",control:"the key was retained on purpose (D17) so existing ciphertext stays decryptable; scheduling deletion would render that data unreadable",evidence:"CustomerManagedKey in fjall/components/infrastructure/lib/resources/aws/secrets/kms.ts stamps fjall:kms:retention with the protects scope on every retained key"}],l={expected:I,mitigated:T};function p(e,t){const n=e.resource;if(n===void 0)return!1;if("logicalIdContains"in n)return t.logicalId!==null&&t.logicalId.includes(n.logicalIdContains);if(t.tags===null)return!1;const r=t.tags[n.tag.key];return r!==void 0&&(n.tag.value===void 0||r===n.tag.value)}i(p,"scopeMatches");function L(e,t=l){const n=t.mitigated.filter(a=>a.ruleId===e.ruleId),r=t.expected.filter(a=>a.ruleId===e.ruleId),o=n.find(a=>p(a,e));if(o!==void 0)return{lane:"mitigated",row:o};const s=r.find(a=>p(a,e));if(s!==void 0)return{lane:"expected",row:s};const c=n.find(a=>a.resource===void 0);if(c!==void 0)return{lane:"mitigated",row:c};const u=r.find(a=>a.resource===void 0);return u===void 0?void 0:{lane:"expected",row:u}}i(L,"findPolicyRow");function _(e){return e===void 0?"":"logicalIdContains"in e?e.logicalIdContains:e.tag.value===void 0?`tag:${e.tag.key}`:`tag:${e.tag.key}=${e.tag.value}`}i(_,"scopeKey");function f(e){return`${e.lane}:${e.row.ruleId}:${_(e.row.resource)}`}i(f,"policyRowKey");function G(e,t=l){const n=t.expected.find(o=>f({lane:"expected",row:o})===e);if(n!==void 0)return{lane:"expected",row:n};const r=t.mitigated.find(o=>f({lane:"mitigated",row:o})===e);return r===void 0?void 0:{lane:"mitigated",row:r}}i(G,"findPolicyRowByKey");function K(e){return e.lane==="expected"?{cause:x(e.row),cure:v(e.row)}:{cause:e.row.name,evidence:A(e.row)}}i(K,"policyRowPresentation");function x(e){return`${e.knob.name} on ${e.knob.construct}`}i(x,"expectedRowCause");function N(e){const t=[];for(const n of S){if(n==="pattern"){const o=e.cure.pattern;o!==void 0&&t.push({family:n,edit:o.edit,patterns:o.patterns});continue}const r=e.cure[n];r!==void 0&&t.push({family:n,edit:r})}return t}i(N,"cureEntries");function w({family:e,patterns:t}){return t===void 0?`${e} resource`:`${t.join(" or ")} ${e} resource`}i(w,"cureEntryTag");function C(e){const t=N(e),[n]=t;return t.length===1&&n!==void 0&&n.patterns===void 0?n.edit:t.map(r=>`${r.edit} (${w(r)})`).join(" or ")}i(C,"cureEdits");function v(e){return`Cure: set ${C(e)} in your infrastructure code.`}i(v,"cureClause");function A(e){return`Evidence: ${e.evidence}.`}i(A,"evidenceClause");function B(e,t){const n=k[e].heading;return t===null?n:`${n} \u2014 ${t}`}i(B,"laneGroupHeading");export{l as DEFAULT_POLICY_REGISTRY,y as EXPECTED_LANE_STAGES,I as EXPECTED_POLICY,T as MITIGATED_POLICY,v as cureClause,C as cureEdits,N as cureEntries,A as evidenceClause,x as expectedRowCause,L as findPolicyRow,G as findPolicyRowByKey,M as isExpectedLaneStage,B as laneGroupHeading,f as policyRowKey,K as policyRowPresentation};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The CloudFormation resource types the policy registries speak for: the
|
|
3
|
+
* `kind` every row carries, and the vocabulary a create surface's footprint
|
|
4
|
+
* is expressed in (`expectedRowsAtDefault`). The literals are
|
|
5
|
+
* CloudFormation's own (`AWS::S3::Bucket`) — the strings the scan stores as
|
|
6
|
+
* an asset's resource type and a webapp rule lists in its `resourceTypes` —
|
|
7
|
+
* so a row's kind is checked against its rule by equality, never through a
|
|
8
|
+
* mapping. A kind joins the tuple when a row needs it; a footprint can only
|
|
9
|
+
* name a kind some row can match.
|
|
10
|
+
*/
|
|
11
|
+
export declare const POLICY_RESOURCE_KINDS: readonly ["AWS::S3::Bucket", "AWS::ECS::Cluster", "AWS::SNS::Topic", "AWS::KMS::Key"];
|
|
12
|
+
export type PolicyResourceKind = (typeof POLICY_RESOURCE_KINDS)[number];
|
|
13
|
+
/**
|
|
14
|
+
* The resource kinds a workload synthesises, projected onto the registry's
|
|
15
|
+
* vocabulary: what a plan's entries or a pattern's construct produce, as
|
|
16
|
+
* CloudFormation types the registry has a row for. Required wherever a
|
|
17
|
+
* consent surface lists rows — an unknown footprint is not an empty one.
|
|
18
|
+
*/
|
|
19
|
+
export type PolicyResourceFootprint = ReadonlySet<PolicyResourceKind>;
|
|
20
|
+
export declare function isPolicyResourceKind(value: unknown): value is PolicyResourceKind;
|
|
21
|
+
/**
|
|
22
|
+
* Projects CloudFormation resource types — a synthesised template's, a
|
|
23
|
+
* plan's — onto the registry vocabulary, dropping every type no row speaks
|
|
24
|
+
* for. The one projection the constructs' footprint test, the generator's
|
|
25
|
+
* plan footprint and the create surfaces share.
|
|
26
|
+
*/
|
|
27
|
+
export declare function policyResourceFootprint(resourceTypes: Iterable<string>): PolicyResourceFootprint;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var S=Object.defineProperty;var e=(t,o)=>S(t,"name",{value:o,configurable:!0});const r=["AWS::S3::Bucket","AWS::ECS::Cluster","AWS::SNS::Topic","AWS::KMS::Key"],c=new Set(r);function i(t){return typeof t=="string"&&c.has(t)}e(i,"isPolicyResourceKind");function p(t){const o=new Set;for(const n of t)i(n)&&o.add(n);return o}e(p,"policyResourceFootprint");export{r as POLICY_RESOURCE_KINDS,i as isPolicyResourceKind,p as policyResourceFootprint};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The consent lines a create flow shows for a tier (alert policy design
|
|
3
|
+
* § 13.10): for the backup tier a chosen tier implies, the K1 rows the tier
|
|
4
|
+
* leaves at the default that produces the finding — so the create-app
|
|
5
|
+
* wizard and `fjall create` say, before the app exists, what the first
|
|
6
|
+
* posture scan will list and where. Derived from the registry and from the
|
|
7
|
+
* tier table the constructs read, so the wizard, the CLI, the scan and the
|
|
8
|
+
* deploy cannot disagree; the words are built here once so the two clients
|
|
9
|
+
* print them byte-identically. It informs the choice and gates nothing.
|
|
10
|
+
* Client-safe: the tier table is zod-only.
|
|
11
|
+
*/
|
|
12
|
+
import { type BackupTier } from "../backupTiers.js";
|
|
13
|
+
import { type ExpectedPolicyRow } from "./registry.js";
|
|
14
|
+
import type { PolicyResourceFootprint } from "./resourceKinds.js";
|
|
15
|
+
/**
|
|
16
|
+
* The K1 rows a backup tier leaves at the default that produces the finding,
|
|
17
|
+
* on a resource the workload synthesises, in registry order. An undefined
|
|
18
|
+
* tier reads the `standard` column, as the constructs do. Only rows keyed on
|
|
19
|
+
* the backup tier are lines: creating the app is what produces them. A row
|
|
20
|
+
* on another knob — the alarm topic's account-level `alarmTopicEncryption`,
|
|
21
|
+
* scoped to the Account's own construct — is produced by the account, not
|
|
22
|
+
* by the app being created, so it is not a line at any tier. And only rows
|
|
23
|
+
* whose `kind` is in the footprint — the CloudFormation resource types the
|
|
24
|
+
* plan or the pattern produces, projected onto `POLICY_RESOURCE_KINDS` — are
|
|
25
|
+
* lines: an app with no topic is not told about the topic row, a pattern
|
|
26
|
+
* with no cluster not about Container Insights. The footprint is required,
|
|
27
|
+
* not defaulted: an unknown footprint is not an empty one, so a caller that
|
|
28
|
+
* cannot derive it fails typecheck rather than list nothing.
|
|
29
|
+
*/
|
|
30
|
+
export declare function expectedRowsAtDefault(backupTier: BackupTier | undefined, footprint: PolicyResourceFootprint, registry?: readonly ExpectedPolicyRow[]): ExpectedPolicyRow[];
|
|
31
|
+
/** One line of the note: the cause, the finding as it is listed, and the registry's own expectation words. */
|
|
32
|
+
export interface TierConsentLine {
|
|
33
|
+
/** `policyRowKey` of the expected row: the line's identity. */
|
|
34
|
+
rowKey: string;
|
|
35
|
+
ruleId: string;
|
|
36
|
+
/**
|
|
37
|
+
* The finding as the scan lists it: the rule's title where the caller
|
|
38
|
+
* holds the rule registry (the webapp wizard), else the rule id (the CLI).
|
|
39
|
+
*/
|
|
40
|
+
title: string;
|
|
41
|
+
/** The knob and the construct it sits on, as the asset page groups the finding. */
|
|
42
|
+
cause: string;
|
|
43
|
+
expectation: string;
|
|
44
|
+
}
|
|
45
|
+
export declare function tierConsentLine(row: ExpectedPolicyRow, title: string): TierConsentLine;
|
|
46
|
+
/**
|
|
47
|
+
* Where the lines land, in the words the scan uses: the expected-lane stages
|
|
48
|
+
* and the status-label table's clauses, under the organisation's posture
|
|
49
|
+
* setting — the scan's ladder flags on a strict organisation before it
|
|
50
|
+
* looks at the stage, so a strict organisation is told `open` everywhere.
|
|
51
|
+
* `null` is a posture setting the caller could not read; the clause says so
|
|
52
|
+
* rather than promise either lane. Rendered once as the note's lead,
|
|
53
|
+
* because every K1 row shares the one lane rule.
|
|
54
|
+
*/
|
|
55
|
+
export declare function expectedLaneWhereClause(postureStrict: boolean | null): string;
|
|
56
|
+
/** The note's name: the wizard panel's accessible name and the CLI note's heading. */
|
|
57
|
+
export declare const TIER_CONSENT_NOTE_LABEL = "Posture findings this tier produces";
|
|
58
|
+
/**
|
|
59
|
+
* The note's lead in three parts, so a renderer may emphasise the tier name
|
|
60
|
+
* between them: "Choosing <tier> keeps these defaults, and the first posture
|
|
61
|
+
* scan lists them. <where the scan lists them> Nothing is accepted on your
|
|
62
|
+
* behalf." The where-clause is `expectedLaneWhereClause`.
|
|
63
|
+
*/
|
|
64
|
+
export interface TierConsentLead {
|
|
65
|
+
prefix: string;
|
|
66
|
+
tierName: string;
|
|
67
|
+
rest: string;
|
|
68
|
+
}
|
|
69
|
+
export declare function tierConsentLead(tierName: string, postureStrict: boolean | null): TierConsentLead;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var i=Object.defineProperty;var o=(e,t)=>i(e,"name",{value:t,configurable:!0});import{tierDefault as a}from"../backupTiers.js";import{ISSUE_STATUS_LABELS as r}from"./issueStatusLabels.js";import{EXPECTED_LANE_STAGES as c,EXPECTED_POLICY as u,expectedRowCause as p,policyRowKey as l}from"./registry.js";function $(e,t,n=u){return n.filter(s=>t.has(s.kind)&&s.knob.name==="backup.tier"&&s.tierDefault!==void 0&&a(e,s.tierDefault)===!1)}o($,"expectedRowsAtDefault");function g(e,t){return{rowKey:l({lane:"expected",row:e}),ruleId:e.ruleId,title:t,cause:p(e),expectation:e.expectation}}o(g,"tierConsentLine");function f(e){const t=e.slice(0,-1),n=e[e.length-1]??"";return t.length===0?n:`${t.join(", ")} or ${n}`}o(f,"orList");function d(e){const t=r.expected.clause,n=r.open.clause,s=f(c);return e===!0?`This organisation's posture is strict, so a posture scan lists each as ${n} on every account.`:e===null?`A posture scan lists each as ${t} on a ${s} account, or as ${n} everywhere if the organisation's posture is strict; the posture setting could not be read.`:`On a ${s} account a posture scan lists each as ${t}; on any other account it is ${n}.`}o(d,"expectedLaneWhereClause");const C="Posture findings this tier produces";function T(e,t){return{prefix:"Choosing ",tierName:e,rest:` keeps these defaults, and the first posture scan lists them. ${d(t)} Nothing is accepted on your behalf.`}}o(T,"tierConsentLead");export{C as TIER_CONSENT_NOTE_LABEL,d as expectedLaneWhereClause,$ as expectedRowsAtDefault,T as tierConsentLead,g as tierConsentLine};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
var d=Object.defineProperty;var
|
|
1
|
+
var d=Object.defineProperty;var s=(o,e)=>d(o,"name",{value:e,configurable:!0});function l(){return process.getBuiltinModule("node:fs")}s(l,"nodeFs");function g(){return process.getBuiltinModule("node:path")}s(g,"nodePath");function p(o,e,u){const t=g().join(o,".gitignore");try{const r=l(),i=r.existsSync(t)?r.readFileSync(t,"utf8"):void 0;if(i===void 0){if(u.createIfMissing===!1)return!1;const n=u.header??"";return r.writeFileSync(t,`${n}${e.join(`
|
|
2
2
|
`)}
|
|
3
|
-
`,{encoding:"utf8"}),!0}const
|
|
4
|
-
`).map(
|
|
3
|
+
`,{encoding:"utf8"}),!0}const f=new Set(i.split(`
|
|
4
|
+
`).map(n=>n.trim())),c=e.filter(n=>!f.has(n));if(c.length===0)return!0;const a=i===""||i.endsWith(`
|
|
5
5
|
`)?"":`
|
|
6
|
-
`;return
|
|
7
|
-
${
|
|
6
|
+
`;return r.appendFileSync(t,`${a}${u.marker}
|
|
7
|
+
${c.join(`
|
|
8
8
|
`)}
|
|
9
|
-
`,"utf8"),!0}catch{return!1}}
|
|
9
|
+
`,"utf8"),!0}catch{return!1}}s(p,"ensureGitignoreEntries");export{p as ensureGitignoreEntries};
|
package/dist/securityHelpers.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var p=Object.defineProperty;var c=(t,_)=>p(t,"name",{value:_,configurable:!0});const D=new Set(["NODE_OPTIONS","NODE_PATH","NODE_EXTRA_CA_CERTS","NODE_DEBUG","NODE_PRESERVE_SYMLINKS","LD_PRELOAD","LD_LIBRARY_PATH","LD_AUDIT","LD_BIND_NOW","DYLD_INSERT_LIBRARIES","DYLD_LIBRARY_PATH","DYLD_FRAMEWORK_PATH","PYTHONPATH","PYTHONSTARTUP","PERL5LIB","PERL5OPT","RUBYLIB","RUBYOPT","HOME","XDG_CONFIG_HOME","AWS_SHARED_CREDENTIALS_FILE","AWS_CONFIG_FILE","SHELL","BASH_ENV","ENV","ZDOTDIR"]);function
|
|
1
|
+
var p=Object.defineProperty;var c=(t,_)=>p(t,"name",{value:_,configurable:!0});const D=new Set(["NODE_OPTIONS","NODE_PATH","NODE_EXTRA_CA_CERTS","NODE_DEBUG","NODE_PRESERVE_SYMLINKS","LD_PRELOAD","LD_LIBRARY_PATH","LD_AUDIT","LD_BIND_NOW","DYLD_INSERT_LIBRARIES","DYLD_LIBRARY_PATH","DYLD_FRAMEWORK_PATH","PYTHONPATH","PYTHONSTARTUP","PERL5LIB","PERL5OPT","RUBYLIB","RUBYOPT","HOME","XDG_CONFIG_HOME","AWS_SHARED_CREDENTIALS_FILE","AWS_CONFIG_FILE","SHELL","BASH_ENV","ENV","ZDOTDIR"]);function h(t){return Object.fromEntries(Object.entries(t).filter(([_])=>!D.has(_.toUpperCase())))}c(h,"filterDangerousEnvVars");const P=/fjall_(?:ak|dk)_[A-Z2-7]{16}\.[A-Z2-7]{40}/,T=/(fjall_(?:ak|dk)_)[A-Z2-7]{16}\.[A-Z2-7]{40}/g,L=/\bfj_[0-9a-f]{8}_[0-9a-f]{48}\b/gi,$=/(fjall:\/\/plans\/)[^\s"'<>\\]+/g,s="***",l="[REDACTED]",g=`-----BEGIN ${l} PRIVATE KEY-----...-----END ${l} PRIVATE KEY-----`,R=String.raw`(?:next|continuation|pagination|page|forward|backward)+token`,S=String.raw`(?!ghu_|ghs_|ghp_|gho_|github_pat_|(?:sk|rk)_(?:live|test)_|whsec_|fjall_(?:ak|dk)_|fj_[0-9a-f]{8}_|AKIA|ASIA|%[a-zA-Z])`,i=String.raw`password|passwd|secret|api[_-]?key|token|auth|credential`,N=String.raw`arn:aws[a-z-]*:[a-z0-9-]+:[a-z0-9-]*:[0-9]*:`,w=new RegExp(String.raw`(?<!"${R}":\s*")`+String.raw`(?<="[a-zA-Z0-9_-]*(?:${i})":\s*")`+S+String.raw`(?:[^"\\]|\\.)+`,"gi"),o=String.raw`(?:\\?["'])?`,I=String.raw`(?:[^\s"'\\]|\\[^\s"'nrt])+`,O=new RegExp(String.raw`(?<!${R}\s*[=:]\s*${o})`+String.raw`(?<!${N}(?:${i})\s*[=:]\s*${o})`+String.raw`(?<=(?<!/)(?:${i})\s*[=:]\s*${o})`+S+I,"gi"),f=new RegExp(String.raw`(?<!${N})(?<![a-zA-Z])(${i})([=:])${o}${I}`,"gi");function k(t){return t.replace(/-----BEGIN [A-Z ]*PRIVATE KEY-----(?:[^"\\]|\\[\\nrt"])*?-----END [A-Z ]*PRIVATE KEY-----/g,()=>g).replace(/-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*?-----END [A-Z ]*PRIVATE KEY-----/g,()=>g).replace(/(\w+:\/\/[^:\s"']+:)[^@\s"']+(@)/gi,(_,e,a)=>`${e}${s}${a}`).replace(f,(_,e,a)=>`${e}${a}${s}`).replace(w,s).replace(O,s).replace(/\b(ghu_|ghs_|ghp_|gho_|github_pat_)[A-Za-z0-9_]+/g,(_,e)=>`${e}${s}`).replace(/\b(sk|rk)_(live|test)_[A-Za-z0-9]{8,}/g,(_,e,a)=>`${e}_${a}_${s}`).replace(/\bwhsec_[A-Za-z0-9]{8,}/g,()=>`whsec_${s}`).replace(/(?<=Authorization:\s*Bearer\s+)[A-Za-z0-9._~+/=-]+/gi,s).replace(/\b(AKIA|ASIA)[A-Z0-9]{12,}\b/g,(_,e)=>`${e}${s}`).replace(/(?<=aws_secret_access_key\s*=\s*["']?|SecretAccessKey[=:]\s*|"(aws)?secretAccessKey":\s*"|"aws_secret_access_key":\s*")[A-Za-z0-9/+=]{40,}/gi,s).replace(/(?<="(aws)?sessionToken":\s*"|"aws_session_token":\s*")[^"]+/gi,s).replace(/(?<=aws_session_token\s*[=:]\s*["']?|SessionToken[=:]\s*["']?)[^\s"']+/gi,s).replace(/(?<="(internal[Aa]piKey|fjallCallbackToken)":\s*")[^"]+/g,s).replace(T,(_,e)=>`${e}${s}`).replace(L,()=>`fj_${s}`).replace($,(_,e)=>`${e}${s}`)}c(k,"maskSensitiveOutput");function G(t){const _=[];let e="",a=!1,r=!1,A=!1,n=!1;for(const E of t){if(A){e+=E,A=!1;continue}if(E==="\\"&&!a){A=!0;continue}if(E==="'"&&!r){a=!a,n=!0;continue}if(E==='"'&&!a){r=!r,n=!0;continue}if(E===" "&&!a&&!r){(e||n)&&(_.push(e),e="",n=!1);continue}e+=E}if(a||r)throw new Error(`Unbalanced ${a?"single":"double"} quote in command: ${t.slice(0,80)}`);if(A)throw new Error(`Trailing backslash in command: ${t.slice(0,80)}`);return(e||n)&&_.push(e),_}c(G,"parseShellArgs");export{D as DANGEROUS_ENV_VARS,s as MASKED_VALUE_MARKER,l as REDACTED_KEY_SENTINEL,P as SCOPED_TOKEN_REGEX,h as filterDangerousEnvVars,k as maskSensitiveOutput,G as parseShellArgs};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fjall/util",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "37.0.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/fjall-tech/fjall.git",
|
|
@@ -63,6 +63,10 @@
|
|
|
63
63
|
"types": "./dist/organisationBinding/index.d.ts",
|
|
64
64
|
"default": "./dist/organisationBinding/index.js"
|
|
65
65
|
},
|
|
66
|
+
"./posturePolicy": {
|
|
67
|
+
"types": "./dist/posturePolicy/index.d.ts",
|
|
68
|
+
"default": "./dist/posturePolicy/index.js"
|
|
69
|
+
},
|
|
66
70
|
"./environments": {
|
|
67
71
|
"types": "./dist/environments.d.ts",
|
|
68
72
|
"default": "./dist/environments.js"
|
|
@@ -179,6 +183,6 @@
|
|
|
179
183
|
"@smithy/core": "2.5.5"
|
|
180
184
|
},
|
|
181
185
|
"engines": {
|
|
182
|
-
"node": ">=22.
|
|
186
|
+
"node": ">=22.3.0"
|
|
183
187
|
}
|
|
184
188
|
}
|