@fjall/components-infrastructure 0.96.0 → 0.99.3

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.
Files changed (209) hide show
  1. package/dist/lib/app.d.ts +68 -1
  2. package/dist/lib/app.js +113 -4
  3. package/dist/lib/config/aws/__t17fixture.d.ts +1 -0
  4. package/dist/lib/config/aws/__t17fixture.js +3 -0
  5. package/dist/lib/config/aws/__t17fixtureType.d.ts +2 -0
  6. package/dist/lib/config/aws/__t17fixtureType.js +1 -0
  7. package/dist/lib/config/aws/alarmTopic.js +8 -4
  8. package/dist/lib/config/aws/cloudTrail.js +1 -1
  9. package/dist/lib/config/aws/disasterRecovery.js +11 -16
  10. package/dist/lib/config/aws/ecrDefaultImage.d.ts +0 -1
  11. package/dist/lib/config/aws/ecrDefaultImage.js +13 -23
  12. package/dist/lib/config/aws/identityCenter.d.ts +10 -3
  13. package/dist/lib/config/aws/identityCenter.js +101 -37
  14. package/dist/lib/config/aws/identityCenterGroupMembership.js +8 -2
  15. package/dist/lib/config/aws/identityCenterMembership.d.ts +11 -0
  16. package/dist/lib/config/aws/identityCenterMembership.js +61 -0
  17. package/dist/lib/config/aws/index.d.ts +1 -1
  18. package/dist/lib/config/aws/index.js +1 -1
  19. package/dist/lib/config/aws/ipam.js +6 -11
  20. package/dist/lib/config/aws/oidcConnector.js +5 -1
  21. package/dist/lib/config/aws/scpPreset.js +4 -1
  22. package/dist/lib/patterns/aws/_eslint_test_tmp/leak.d.ts +1 -0
  23. package/dist/lib/patterns/aws/_eslint_test_tmp/leak.js +4 -0
  24. package/dist/lib/patterns/aws/account.js +2 -4
  25. package/dist/lib/patterns/aws/apexDomainPattern.js +10 -10
  26. package/dist/lib/patterns/aws/bastionFactory.d.ts +10 -0
  27. package/dist/lib/patterns/aws/bastionFactory.js +29 -0
  28. package/dist/lib/patterns/aws/buildkite.d.ts +2 -2
  29. package/dist/lib/patterns/aws/buildkite.js +51 -97
  30. package/dist/lib/patterns/aws/cdn.js +1 -1
  31. package/dist/lib/patterns/aws/clickhouseDatabase.d.ts +173 -0
  32. package/dist/lib/patterns/aws/clickhouseDatabase.js +601 -0
  33. package/dist/lib/patterns/aws/compute.d.ts +4 -6
  34. package/dist/lib/patterns/aws/compute.js +7 -13
  35. package/dist/lib/patterns/aws/computeEcs.d.ts +93 -5
  36. package/dist/lib/patterns/aws/computeEcs.js +867 -37
  37. package/dist/lib/patterns/aws/computeEcsTypes.d.ts +528 -25
  38. package/dist/lib/patterns/aws/computeEcsTypes.js +10 -0
  39. package/dist/lib/patterns/aws/computeLambda.d.ts +0 -5
  40. package/dist/lib/patterns/aws/computeLambda.js +1 -2
  41. package/dist/lib/patterns/aws/database.d.ts +50 -8
  42. package/dist/lib/patterns/aws/database.js +183 -27
  43. package/dist/lib/patterns/aws/domain.js +6 -4
  44. package/dist/lib/patterns/aws/index.d.ts +1 -0
  45. package/dist/lib/patterns/aws/index.js +1 -0
  46. package/dist/lib/patterns/aws/interfaces/compute.d.ts +7 -1
  47. package/dist/lib/patterns/aws/interfaces/database.d.ts +187 -8
  48. package/dist/lib/patterns/aws/interfaces/database.js +17 -3
  49. package/dist/lib/patterns/aws/interfaces/index.d.ts +2 -1
  50. package/dist/lib/patterns/aws/interfaces/index.js +3 -1
  51. package/dist/lib/patterns/aws/interfaces/messaging.d.ts +7 -0
  52. package/dist/lib/patterns/aws/interfaces/migrationContributor.d.ts +47 -0
  53. package/dist/lib/patterns/aws/interfaces/migrationContributor.js +9 -0
  54. package/dist/lib/patterns/aws/messaging.d.ts +66 -10
  55. package/dist/lib/patterns/aws/messaging.js +115 -20
  56. package/dist/lib/patterns/aws/network.js +16 -7
  57. package/dist/lib/patterns/aws/organisation.d.ts +4 -0
  58. package/dist/lib/patterns/aws/organisation.js +22 -4
  59. package/dist/lib/patterns/aws/storage.d.ts +1 -2
  60. package/dist/lib/patterns/aws/storage.js +3 -2
  61. package/dist/lib/patterns/aws/vpcPeer.js +3 -1
  62. package/dist/lib/resources/aws/analytics/clickhouse.js +18 -9
  63. package/dist/lib/resources/aws/analytics/clickhouseAlarms.d.ts +24 -9
  64. package/dist/lib/resources/aws/analytics/clickhouseAlarms.js +61 -10
  65. package/dist/lib/resources/aws/analytics/clickhouseConstants.d.ts +3 -3
  66. package/dist/lib/resources/aws/analytics/clickhouseConstants.js +3 -3
  67. package/dist/lib/resources/aws/analytics/clickhouseTypes.d.ts +7 -1
  68. package/dist/lib/resources/aws/analytics/clickhouseUserData.d.ts +1 -1
  69. package/dist/lib/resources/aws/analytics/clickhouseUserData.js +53 -3
  70. package/dist/lib/resources/aws/base/awsStack.js +4 -2
  71. package/dist/lib/resources/aws/compute/__tmp__/regression-shape.d.ts +2 -0
  72. package/dist/lib/resources/aws/compute/__tmp__/regression-shape.js +11 -0
  73. package/dist/lib/resources/aws/compute/asgInlineLifecycleHook.d.ts +52 -0
  74. package/dist/lib/resources/aws/compute/asgInlineLifecycleHook.js +60 -0
  75. package/dist/lib/resources/aws/compute/blockDeviceVolume.d.ts +8 -0
  76. package/dist/lib/resources/aws/compute/blockDeviceVolume.js +10 -0
  77. package/dist/lib/resources/aws/compute/ec2.d.ts +132 -12
  78. package/dist/lib/resources/aws/compute/ec2.js +163 -23
  79. package/dist/lib/resources/aws/compute/ec2GracefulTerminationHandler.d.ts +41 -0
  80. package/dist/lib/resources/aws/compute/ec2GracefulTerminationHandler.js +194 -0
  81. package/dist/lib/resources/aws/compute/ec2GracefulTerminationLambda.source.cjs +458 -0
  82. package/dist/lib/resources/aws/compute/ecs.d.ts +27 -1
  83. package/dist/lib/resources/aws/compute/ecs.js +42 -2
  84. package/dist/lib/resources/aws/compute/ecsConstants.d.ts +9 -0
  85. package/dist/lib/resources/aws/compute/ecsConstants.js +16 -0
  86. package/dist/lib/resources/aws/compute/ecsImages.js +32 -20
  87. package/dist/lib/resources/aws/compute/ecsLifecycleHookMigration.d.ts +96 -0
  88. package/dist/lib/resources/aws/compute/ecsLifecycleHookMigration.js +113 -0
  89. package/dist/lib/resources/aws/compute/ecsNetworking.d.ts +2 -1
  90. package/dist/lib/resources/aws/compute/ecsNetworking.js +18 -6
  91. package/dist/lib/resources/aws/compute/ecsServiceFactory.d.ts +13 -4
  92. package/dist/lib/resources/aws/compute/ecsServiceFactory.js +155 -33
  93. package/dist/lib/resources/aws/compute/ecsTaskDefinition.d.ts +31 -1
  94. package/dist/lib/resources/aws/compute/ecsTaskDefinition.js +102 -6
  95. package/dist/lib/resources/aws/compute/ecsTypes.d.ts +173 -13
  96. package/dist/lib/resources/aws/compute/ecsValidation.d.ts +9 -0
  97. package/dist/lib/resources/aws/compute/ecsValidation.js +63 -0
  98. package/dist/lib/resources/aws/compute/index.d.ts +2 -0
  99. package/dist/lib/resources/aws/compute/index.js +2 -0
  100. package/dist/lib/resources/aws/compute/lambda.d.ts +7 -13
  101. package/dist/lib/resources/aws/compute/lambda.js +30 -38
  102. package/dist/lib/resources/aws/compute/lifecycleHookLambda.source.cjs +192 -0
  103. package/dist/lib/resources/aws/compute/persistentDataVolume.d.ts +104 -0
  104. package/dist/lib/resources/aws/compute/persistentDataVolume.js +245 -0
  105. package/dist/lib/resources/aws/compute/persistentDataVolumeLambda.source.cjs +398 -0
  106. package/dist/lib/resources/aws/compute/samApplication.d.ts +15 -0
  107. package/dist/lib/resources/aws/compute/samApplication.js +27 -0
  108. package/dist/lib/resources/aws/database/clickhouseConstants.d.ts +159 -0
  109. package/dist/lib/resources/aws/database/clickhouseConstants.js +181 -0
  110. package/dist/lib/resources/aws/database/clickhouseSchemas.d.ts +71 -0
  111. package/dist/lib/resources/aws/database/clickhouseSchemas.js +160 -0
  112. package/dist/lib/resources/aws/database/clickhouseSecurityGroup.d.ts +14 -0
  113. package/dist/lib/resources/aws/database/clickhouseSecurityGroup.js +23 -0
  114. package/dist/lib/resources/aws/database/clickhouseUserData.d.ts +69 -0
  115. package/dist/lib/resources/aws/database/clickhouseUserData.js +371 -0
  116. package/dist/lib/resources/aws/database/clickhouseXmlRenderer.d.ts +56 -0
  117. package/dist/lib/resources/aws/database/clickhouseXmlRenderer.js +112 -0
  118. package/dist/lib/resources/aws/database/rdsAurora.d.ts +8 -1
  119. package/dist/lib/resources/aws/database/rdsAurora.js +42 -32
  120. package/dist/lib/resources/aws/database/rdsAuroraGlobal.d.ts +15 -2
  121. package/dist/lib/resources/aws/database/rdsAuroraGlobal.js +39 -43
  122. package/dist/lib/resources/aws/database/rdsDefaults.d.ts +6 -0
  123. package/dist/lib/resources/aws/database/rdsDefaults.js +7 -1
  124. package/dist/lib/resources/aws/database/rdsHelpers.d.ts +3 -3
  125. package/dist/lib/resources/aws/database/rdsHelpers.js +1 -0
  126. package/dist/lib/resources/aws/database/rdsInstance.d.ts +8 -1
  127. package/dist/lib/resources/aws/database/rdsInstance.js +51 -34
  128. package/dist/lib/resources/aws/database/rdsProxyOutput.d.ts +1 -1
  129. package/dist/lib/resources/aws/database/rdsProxyOutput.js +1 -1
  130. package/dist/lib/resources/aws/iam/delegationRole.js +1 -1
  131. package/dist/lib/resources/aws/iam/identityCenter/groupMembership.d.ts +9 -0
  132. package/dist/lib/resources/aws/iam/identityCenter/groupMembership.js +12 -0
  133. package/dist/lib/resources/aws/iam/identityCenter/index.d.ts +1 -0
  134. package/dist/lib/resources/aws/iam/identityCenter/index.js +1 -0
  135. package/dist/lib/resources/aws/iam/identityCenter/permissionSet.d.ts +1 -0
  136. package/dist/lib/resources/aws/iam/identityCenter/permissionSet.js +1 -0
  137. package/dist/lib/resources/aws/logging/logGroup.d.ts +0 -8
  138. package/dist/lib/resources/aws/logging/logGroup.js +0 -11
  139. package/dist/lib/resources/aws/messaging/defaultEventBus.d.ts +7 -0
  140. package/dist/lib/resources/aws/messaging/defaultEventBus.js +21 -0
  141. package/dist/lib/resources/aws/messaging/eventBridgeRule.d.ts +96 -0
  142. package/dist/lib/resources/aws/messaging/eventBridgeRule.js +110 -0
  143. package/dist/lib/resources/aws/messaging/eventTargets.d.ts +84 -0
  144. package/dist/lib/resources/aws/messaging/eventTargets.js +152 -0
  145. package/dist/lib/resources/aws/messaging/eventbridge.d.ts +25 -2
  146. package/dist/lib/resources/aws/messaging/eventbridge.js +22 -10
  147. package/dist/lib/resources/aws/messaging/index.d.ts +5 -0
  148. package/dist/lib/resources/aws/messaging/index.js +2 -0
  149. package/dist/lib/resources/aws/messaging/schedule.d.ts +118 -0
  150. package/dist/lib/resources/aws/messaging/schedule.js +64 -0
  151. package/dist/lib/resources/aws/messaging/sns.d.ts +2 -1
  152. package/dist/lib/resources/aws/messaging/sqs.d.ts +2 -1
  153. package/dist/lib/resources/aws/messaging/subscription.d.ts +112 -0
  154. package/dist/lib/resources/aws/messaging/subscription.js +67 -0
  155. package/dist/lib/resources/aws/messaging/utils.d.ts +6 -0
  156. package/dist/lib/resources/aws/messaging/utils.js +10 -0
  157. package/dist/lib/resources/aws/monitoring/clickhouseAlarms.d.ts +60 -0
  158. package/dist/lib/resources/aws/monitoring/clickhouseAlarms.js +139 -0
  159. package/dist/lib/resources/aws/monitoring/index.d.ts +2 -0
  160. package/dist/lib/resources/aws/monitoring/index.js +2 -0
  161. package/dist/lib/resources/aws/monitoring/scheduleAlarms.d.ts +47 -0
  162. package/dist/lib/resources/aws/monitoring/scheduleAlarms.js +106 -0
  163. package/dist/lib/resources/aws/networking/crossAccountDelegationRecord.js +6 -4
  164. package/dist/lib/resources/aws/networking/crossAccountReturnRoutes.js +17 -13
  165. package/dist/lib/resources/aws/networking/dnsRecord/dnsRecordBase.js +7 -5
  166. package/dist/lib/resources/aws/networking/domainCertificate.d.ts +2 -2
  167. package/dist/lib/resources/aws/networking/domainCertificate.js +6 -4
  168. package/dist/lib/resources/aws/networking/hostedZone.js +6 -5
  169. package/dist/lib/resources/aws/networking/serviceDiscovery.d.ts +96 -0
  170. package/dist/lib/resources/aws/networking/serviceDiscovery.js +96 -0
  171. package/dist/lib/resources/aws/networking/vpc.d.ts +4 -1
  172. package/dist/lib/resources/aws/networking/vpc.js +4 -1
  173. package/dist/lib/resources/aws/networking/vpcPeeringConnection.js +21 -3
  174. package/dist/lib/resources/aws/organisation/costAllocationTagActivator.d.ts +16 -5
  175. package/dist/lib/resources/aws/organisation/costAllocationTagActivator.js +17 -3
  176. package/dist/lib/resources/aws/organisation/index.d.ts +1 -1
  177. package/dist/lib/resources/aws/organisation/organisationPolicy.d.ts +2 -0
  178. package/dist/lib/resources/aws/organisation/organisationPolicy.js +3 -2
  179. package/dist/lib/resources/aws/secrets/secret.d.ts +7 -0
  180. package/dist/lib/resources/aws/secrets/secret.js +4 -3
  181. package/dist/lib/resources/aws/storage/bucketDeployment.d.ts +16 -0
  182. package/dist/lib/resources/aws/storage/bucketDeployment.js +17 -0
  183. package/dist/lib/resources/aws/storage/ecr.js +5 -5
  184. package/dist/lib/resources/aws/storage/index.d.ts +1 -0
  185. package/dist/lib/resources/aws/storage/index.js +1 -0
  186. package/dist/lib/resources/aws/storage/s3.js +10 -3
  187. package/dist/lib/resources/aws/utilities/customResource.js +18 -9
  188. package/dist/lib/synth_dump.d.ts +1 -0
  189. package/dist/lib/synth_dump.js +42 -0
  190. package/dist/lib/utils/cdkContext.d.ts +2 -0
  191. package/dist/lib/utils/cdkContext.js +4 -2
  192. package/dist/lib/utils/connections.js +6 -0
  193. package/dist/lib/utils/connector.d.ts +12 -0
  194. package/dist/lib/utils/costAllocationTags.d.ts +9 -0
  195. package/dist/lib/utils/costAllocationTags.js +11 -1
  196. package/dist/lib/utils/databaseTypes.d.ts +14 -0
  197. package/dist/lib/utils/getConfig.d.ts +2 -0
  198. package/dist/lib/utils/getConfig.js +2 -0
  199. package/dist/lib/utils/index.d.ts +1 -0
  200. package/dist/lib/utils/index.js +1 -0
  201. package/dist/lib/utils/manifestWriter.d.ts +6 -89
  202. package/dist/lib/utils/manifestWriter.js +36 -23
  203. package/dist/lib/utils/migrationVersionResolvers.d.ts +2 -0
  204. package/dist/lib/utils/migrationVersionResolvers.js +2 -0
  205. package/dist/lib/utils/orgConfigParser.js +2 -1
  206. package/dist/lib/utils/resolveAlertsTopic.d.ts +14 -0
  207. package/dist/lib/utils/resolveAlertsTopic.js +30 -0
  208. package/dist/lib/utils/validationLogger.js +6 -3
  209. package/package.json +22 -19
@@ -2,7 +2,21 @@ import { type Duration } from "aws-cdk-lib";
2
2
  import { type IKey } from "aws-cdk-lib/aws-kms";
3
3
  import { type SubnetSelection } from "aws-cdk-lib/aws-ec2";
4
4
  export type DatabaseEngine = "postgresql" | "mysql";
5
+ /**
6
+ * Discriminated snapshot target. Instance variants return
7
+ * `{ kind: "instance", arn }`; cluster variants return
8
+ * `{ kind: "cluster", arn }`. Consumers branch on `kind` to choose between
9
+ * `rds:CreateDBSnapshot` and `rds:CreateDBClusterSnapshot`.
10
+ */
11
+ export type SnapshotTarget = {
12
+ kind: "instance";
13
+ arn: string;
14
+ } | {
15
+ kind: "cluster";
16
+ arn: string;
17
+ };
5
18
  export interface EngineConfig {
19
+ family: DatabaseEngine;
6
20
  defaultUsername: string;
7
21
  sslParameters: Record<string, string>;
8
22
  rotationAppName: string;
@@ -1,9 +1,11 @@
1
+ import { type ProviderAccount } from "@fjall/util/config";
1
2
  export interface Config {
2
3
  region: string;
3
4
  environment: string;
4
5
  accountId?: string;
5
6
  accountName?: string;
6
7
  accountIds?: Record<string, string>;
8
+ providerAccounts: ProviderAccount[];
7
9
  primaryRegion?: string;
8
10
  secondaryRegions: string[];
9
11
  allRegions: string[];
@@ -6,6 +6,7 @@ export function getConfig(accountName) {
6
6
  const config = {
7
7
  region: process.env.AWS_REGION || "us-east-1",
8
8
  environment: "unknown",
9
+ providerAccounts: [],
9
10
  secondaryRegions: [],
10
11
  allRegions: []
11
12
  };
@@ -18,6 +19,7 @@ export function getConfig(accountName) {
18
19
  }
19
20
  const orgConfig = parseOrgConfig(typeof orgConfigRaw === "string" ? orgConfigRaw : undefined);
20
21
  const providerAccounts = orgConfig.providerAccounts;
22
+ config.providerAccounts = providerAccounts;
21
23
  config.primaryRegion = orgConfig.primaryRegion;
22
24
  config.secondaryRegions = orgConfig.secondaryRegions;
23
25
  config.disasterRecoveryRegion = orgConfig.disasterRecoveryRegion;
@@ -13,3 +13,4 @@ export * from "./env.js";
13
13
  export * from "./vpcPeerInterface.js";
14
14
  export * from "./vpcUtils.js";
15
15
  export * from "./domainTypes.js";
16
+ export * from "./migrationVersionResolvers.js";
@@ -13,3 +13,4 @@ export * from "./env.js";
13
13
  export * from "./vpcPeerInterface.js";
14
14
  export * from "./vpcUtils.js";
15
15
  export * from "./domainTypes.js";
16
+ export * from "./migrationVersionResolvers.js";
@@ -7,99 +7,16 @@
7
7
  *
8
8
  * The manifest is written to cdk.out/fjall-manifest.json after synthesis.
9
9
  *
10
- * NOTE: This file uses synchronous file operations (writeFileSync, readFileSync, etc.)
11
- * because CDK synthesis is inherently synchronous. The synth() method blocks until
12
- * complete, so async operations would provide no benefit and add complexity.
10
+ * Synchronous fs ops are intentional: CDK synth() is inherently synchronous.
13
11
  *
14
- * TYPE DUPLICATION NOTE: The interfaces below (ManifestService, ManifestPattern, etc.)
15
- * are mirrored by Zod schemas in cli/src/types/FjallManifest.ts. The CLI schemas are
16
- * the authoritative source for validation. If you modify these interfaces, update
17
- * the Zod schemas to match. Future work: extract to shared @fjall/types package.
12
+ * Manifest type shapes are re-exported from @fjall/util/manifest/schemas the
13
+ * Zod-derived definitions there are the single source of truth for both runtime
14
+ * validation and TypeScript inference.
18
15
  */
19
16
  import type { CloudAssembly } from "aws-cdk-lib/cx-api";
20
- import { type ResourceMapEntry, MANIFEST_SCHEMA_VERSION } from "@fjall/util/constructMap";
21
17
  import { type ResourceCategory } from "@fjall/util/resourceCategorisation";
22
- /**
23
- * Service configuration extracted from ECS services.
24
- */
25
- export interface ManifestService {
26
- /** Service name (must match ECS service name) */
27
- name: string;
28
- /** Cluster name this service belongs to */
29
- clusterName?: string;
30
- /** Path to Dockerfile relative to app root */
31
- dockerfilePath?: string;
32
- /** Docker build target for multi-stage builds */
33
- dockerTarget?: string;
34
- /** Container port */
35
- containerPort?: number;
36
- /** SSM secrets configured for this service (aggregated from all containers) */
37
- secrets?: string[];
38
- /** SSM secrets path (derived or explicit) */
39
- ssmSecretsPath?: string;
40
- }
41
- /**
42
- * Pattern configuration extracted from PatternFactory.
43
- */
44
- export interface ManifestPattern {
45
- /** Pattern type */
46
- type: "payload";
47
- /** Pattern name (CMS name) */
48
- name: string;
49
- /** Source directory containing build output */
50
- source: string;
51
- }
52
- /**
53
- * ECR configuration.
54
- */
55
- export interface ManifestEcr {
56
- /** ECR repository name */
57
- repositoryName: string;
58
- }
59
- /**
60
- * Lambda function configuration extracted from Lambda compute.
61
- * Enables CLI discovery of Lambda functions for secrets management.
62
- */
63
- export interface ManifestLambda {
64
- /** Lambda function name (construct ID) */
65
- name: string;
66
- /** SSM secrets configured for this Lambda */
67
- secrets?: string[];
68
- /** SSM secrets path (derived or explicit) */
69
- ssmSecretsPath?: string;
70
- }
71
- /**
72
- * Stack hash entry computed from synthesised template.
73
- */
74
- export interface ManifestStackHash {
75
- /** SHA-256 hash of the synthesised template */
76
- templateHash: string;
77
- /** ISO timestamp when synth completed */
78
- synthTimestamp: string;
79
- }
80
- /**
81
- * Fjall manifest - generated during CDK synth.
82
- */
83
- export interface FjallManifest {
84
- /** Schema version for future compatibility */
85
- version: typeof MANIFEST_SCHEMA_VERSION;
86
- /** ISO timestamp when manifest was generated */
87
- generatedAt: string;
88
- /** Application name */
89
- appName: string;
90
- /** Resolved service configurations */
91
- services: ManifestService[];
92
- /** Lambda function configurations */
93
- lambdas: ManifestLambda[];
94
- /** Pattern configuration (if using PatternFactory) */
95
- pattern?: ManifestPattern;
96
- /** ECR configuration */
97
- ecr?: ManifestEcr;
98
- /** Template hashes by stack name */
99
- stacks: Record<string, ManifestStackHash>;
100
- /** Resource map: logicalId → construct context for topology grouping */
101
- resourceMap?: Record<string, ResourceMapEntry>;
102
- }
18
+ import { type ManifestService, type ManifestPattern, type ManifestEcr, type ManifestLambda, type ManifestStackHash, type FjallManifest } from "@fjall/util/manifest/schemas";
19
+ export type { ManifestService, ManifestPattern, ManifestEcr, ManifestLambda, ManifestStackHash, FjallManifest };
103
20
  /**
104
21
  * Collected manifest data during synthesis.
105
22
  * Stores all data that will be written to the manifest file.
@@ -7,19 +7,18 @@
7
7
  *
8
8
  * The manifest is written to cdk.out/fjall-manifest.json after synthesis.
9
9
  *
10
- * NOTE: This file uses synchronous file operations (writeFileSync, readFileSync, etc.)
11
- * because CDK synthesis is inherently synchronous. The synth() method blocks until
12
- * complete, so async operations would provide no benefit and add complexity.
10
+ * Synchronous fs ops are intentional: CDK synth() is inherently synchronous.
13
11
  *
14
- * TYPE DUPLICATION NOTE: The interfaces below (ManifestService, ManifestPattern, etc.)
15
- * are mirrored by Zod schemas in cli/src/types/FjallManifest.ts. The CLI schemas are
16
- * the authoritative source for validation. If you modify these interfaces, update
17
- * the Zod schemas to match. Future work: extract to shared @fjall/types package.
12
+ * Manifest type shapes are re-exported from @fjall/util/manifest/schemas the
13
+ * Zod-derived definitions there are the single source of truth for both runtime
14
+ * validation and TypeScript inference.
18
15
  */
19
- import { writeFileSync, readFileSync, existsSync, readdirSync } from "fs";
16
+ import { writeFileSync, readFileSync, existsSync, readdirSync, renameSync, unlinkSync } from "fs";
20
17
  import { join, basename } from "path";
21
18
  import { createHash } from "crypto";
22
- import { buildConstructMap, constructMapToRecord, ACCOUNT_CONSTRUCT_GROUPS, FJALL_MANIFEST_FILENAME, MANIFEST_SCHEMA_VERSION } from "@fjall/util/constructMap";
19
+ import { buildConstructMap, constructMapToRecord, ACCOUNT_CONSTRUCT_GROUPS } from "@fjall/util/constructMap";
20
+ import { maskSensitiveOutput } from "@fjall/util";
21
+ import { FJALL_MANIFEST_FILENAME, MANIFEST_SCHEMA_VERSION, FjallManifestSchema } from "@fjall/util/manifest/schemas";
23
22
  import { FjallLogger } from "./validationLogger.js";
24
23
  /**
25
24
  * Collected manifest data during synthesis.
@@ -118,8 +117,8 @@ function computeTemplateHash(templatePath) {
118
117
  return createHash("sha256").update(normalised).digest("hex");
119
118
  }
120
119
  catch (error) {
121
- const errorMessage = error instanceof Error ? error.message : String(error);
122
- FjallLogger.warn(`Failed to compute hash for ${templatePath}: ${errorMessage}`);
120
+ const maskedMessage = maskSensitiveOutput(error instanceof Error ? error.message : String(error));
121
+ FjallLogger.warn(`Failed to compute hash for ${templatePath}: ${maskedMessage}`);
123
122
  return null;
124
123
  }
125
124
  }
@@ -145,8 +144,8 @@ function computeStackHashes(cdkOutPath) {
145
144
  }
146
145
  }
147
146
  catch (error) {
148
- const errorMessage = error instanceof Error ? error.message : String(error);
149
- FjallLogger.warn(`Failed to read cdk.out for hash computation: ${errorMessage}`);
147
+ const maskedMessage = maskSensitiveOutput(error instanceof Error ? error.message : String(error));
148
+ FjallLogger.warn(`Failed to read cdk.out for hash computation: ${maskedMessage}`);
150
149
  }
151
150
  return stacks;
152
151
  }
@@ -181,13 +180,30 @@ export function writeManifest(assembly, collector) {
181
180
  if (ecr) {
182
181
  manifest.ecr = ecr;
183
182
  }
183
+ // CLI deploy reads this manifest and silently degrades on malformed JSON,
184
+ // so a truncated write is worse than no write — atomic-rename via .tmp.
185
+ const tmpPath = `${manifestPath}.tmp`;
184
186
  try {
185
- writeFileSync(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
187
+ writeFileSync(tmpPath, JSON.stringify(manifest, null, 2), "utf-8");
188
+ renameSync(tmpPath, manifestPath);
186
189
  FjallLogger.info(`Fjall manifest written to ${manifestPath}`);
187
190
  }
188
191
  catch (error) {
192
+ if (existsSync(tmpPath)) {
193
+ try {
194
+ unlinkSync(tmpPath);
195
+ }
196
+ catch (cleanupError) {
197
+ const cleanupMessage = cleanupError instanceof Error
198
+ ? cleanupError.message
199
+ : String(cleanupError);
200
+ FjallLogger.warn(`Failed to clean up tmp manifest at ${tmpPath}: ${maskSensitiveOutput(cleanupMessage)}`);
201
+ }
202
+ }
189
203
  const errorMessage = error instanceof Error ? error.message : String(error);
190
- FjallLogger.warn(`Failed to write Fjall manifest: ${errorMessage}`);
204
+ throw new Error(`Failed to write Fjall manifest: ${errorMessage}`, {
205
+ cause: error
206
+ });
191
207
  }
192
208
  }
193
209
  /**
@@ -200,19 +216,16 @@ export function readExistingManifest(cdkOutPath) {
200
216
  }
201
217
  try {
202
218
  const content = readFileSync(manifestPath, "utf-8");
203
- const parsed = JSON.parse(content);
204
- if (typeof parsed !== "object" ||
205
- parsed === null ||
206
- !("version" in parsed) ||
207
- !("appName" in parsed)) {
208
- FjallLogger.warn("Existing manifest has unexpected shape");
219
+ const result = FjallManifestSchema.safeParse(JSON.parse(content));
220
+ if (!result.success) {
221
+ FjallLogger.warn(`Existing manifest has unexpected shape: ${maskSensitiveOutput(result.error.message)}`);
209
222
  return null;
210
223
  }
211
- return parsed;
224
+ return result.data;
212
225
  }
213
226
  catch (error) {
214
227
  const message = error instanceof Error ? error.message : String(error);
215
- FjallLogger.warn(`Failed to parse existing manifest: ${message}`);
228
+ FjallLogger.warn(`Failed to parse existing manifest: ${maskSensitiveOutput(message)}`);
216
229
  return null;
217
230
  }
218
231
  }
@@ -0,0 +1,2 @@
1
+ export { PRISMA_MIGRATION_DIR_RE } from "@fjall/util";
2
+ export { pickLatestPrismaMigration } from "@fjall/util/migration";
@@ -0,0 +1,2 @@
1
+ export { PRISMA_MIGRATION_DIR_RE } from "@fjall/util";
2
+ export { pickLatestPrismaMigration } from "@fjall/util/migration";
@@ -1,3 +1,4 @@
1
+ import { maskSensitiveOutput } from "@fjall/util";
1
2
  import { FjallLogger } from "./validationLogger.js";
2
3
  /**
3
4
  * Parse orgConfig JSON from CDK context into a validated structure.
@@ -43,7 +44,7 @@ export function parseOrgConfig(raw) {
43
44
  };
44
45
  }
45
46
  catch (error) {
46
- FjallLogger.warn(`[fjall] Failed to parse orgConfig from CDK context: ${error instanceof Error ? error.message : String(error)}`);
47
+ FjallLogger.warn(`[fjall] Failed to parse orgConfig from CDK context: ${maskSensitiveOutput(error instanceof Error ? error.message : String(error))}`);
47
48
  return empty;
48
49
  }
49
50
  }
@@ -0,0 +1,14 @@
1
+ import type { Construct } from "constructs";
2
+ import type { ITopic } from "aws-cdk-lib/aws-sns";
3
+ /**
4
+ * Resolve an `ITopic | string | undefined` alertsTopic to an `ITopic | undefined`.
5
+ *
6
+ * String values are accepted in two shapes:
7
+ * - `"import:<ExportName>"` — resolved via `Fn.importValue`.
8
+ * - `"arn:..."` — used as-is.
9
+ *
10
+ * Any other string shape throws — `Topic.fromTopicArn` accepts any string without
11
+ * validation, so a non-`import:` value MUST be ARN-shape-checked here or a malformed
12
+ * reference reaches synth.
13
+ */
14
+ export declare function resolveAlertsTopic(scope: Construct, id: string, alertsTopic: ITopic | string | undefined): ITopic | undefined;
@@ -0,0 +1,30 @@
1
+ import { Fn } from "aws-cdk-lib";
2
+ import { Topic } from "aws-cdk-lib/aws-sns";
3
+ /**
4
+ * Resolve an `ITopic | string | undefined` alertsTopic to an `ITopic | undefined`.
5
+ *
6
+ * String values are accepted in two shapes:
7
+ * - `"import:<ExportName>"` — resolved via `Fn.importValue`.
8
+ * - `"arn:..."` — used as-is.
9
+ *
10
+ * Any other string shape throws — `Topic.fromTopicArn` accepts any string without
11
+ * validation, so a non-`import:` value MUST be ARN-shape-checked here or a malformed
12
+ * reference reaches synth.
13
+ */
14
+ export function resolveAlertsTopic(scope, id, alertsTopic) {
15
+ if (alertsTopic === undefined)
16
+ return undefined;
17
+ if (typeof alertsTopic !== "string")
18
+ return alertsTopic;
19
+ let arn;
20
+ if (alertsTopic.startsWith("import:")) {
21
+ arn = Fn.importValue(alertsTopic.slice("import:".length));
22
+ }
23
+ else {
24
+ if (!alertsTopic.startsWith("arn:")) {
25
+ throw new Error(`alertsTopic string must be an ARN (starts with "arn:") or use the "import:<ExportName>" form; got "${alertsTopic}"`);
26
+ }
27
+ arn = alertsTopic;
28
+ }
29
+ return Topic.fromTopicArn(scope, id, arn);
30
+ }
@@ -6,7 +6,10 @@
6
6
  import { appendFileSync, existsSync, mkdirSync } from "fs";
7
7
  import { homedir } from "os";
8
8
  import { join } from "path";
9
- const LOG_DIR = process.env.FJALL_LOG_DIR ?? join(homedir(), ".fjall", "logs");
9
+ const ENV_LOG_DIR = process.env.FJALL_LOG_DIR;
10
+ const LOG_DIR = ENV_LOG_DIR !== undefined && ENV_LOG_DIR !== ""
11
+ ? ENV_LOG_DIR
12
+ : join(homedir(), ".fjall", "logs");
10
13
  const LOG_FILE = join(LOG_DIR, "infrastructure.jsonl");
11
14
  /**
12
15
  * Write a log entry to the infrastructure JSONL file
@@ -25,8 +28,8 @@ function writeToLog(level, message) {
25
28
  });
26
29
  appendFileSync(LOG_FILE, entry + "\n");
27
30
  }
28
- catch {
29
- // Never crash CDK on logging failure
31
+ catch (err) {
32
+ console.debug("[Fjall] writeToLog failed:", err instanceof Error ? err.message : String(err));
30
33
  }
31
34
  }
32
35
  export const FjallLogger = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fjall/components-infrastructure",
3
- "version": "0.96.0",
3
+ "version": "0.99.3",
4
4
  "license": "SEE LICENSE IN LICENSE",
5
5
  "type": "module",
6
6
  "bin": {
@@ -30,40 +30,42 @@
30
30
  "scripts": {
31
31
  "clean": "rm -rf ./dist",
32
32
  "clean:node": "rm -rf ./node_modules",
33
- "build": "tsc && cp -r lib/layers dist/lib/layers",
33
+ "build": "tsc && cp -r lib/layers dist/lib/layers && cp lib/resources/aws/compute/lifecycleHookLambda.source.cjs dist/lib/resources/aws/compute/lifecycleHookLambda.source.cjs && cp lib/resources/aws/compute/ec2GracefulTerminationLambda.source.cjs dist/lib/resources/aws/compute/ec2GracefulTerminationLambda.source.cjs && cp lib/resources/aws/compute/persistentDataVolumeLambda.source.cjs dist/lib/resources/aws/compute/persistentDataVolumeLambda.source.cjs",
34
34
  "watch": "tsc -w",
35
35
  "watch:only": "tsc -w",
36
36
  "test": "vitest run",
37
37
  "test:watch": "vitest",
38
38
  "cdk": "cdk",
39
- "typecheck": "tsc --noEmit",
39
+ "typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
40
+ "typecheck:tests": "tsc --noEmit -p tsconfig.test.json",
40
41
  "check:scripts": "tsc --project tsconfig.scripts.json",
42
+ "lint": "eslint lib --no-warn-ignored",
43
+ "lint:fix": "eslint lib --fix --no-warn-ignored",
41
44
  "format": "prettier --write \"lib/**/*.{ts,tsx,js,jsx,json}\" \"scripts/**/*.mts\"",
42
45
  "format:check": "prettier --check \"lib/**/*.{ts,tsx,js,jsx,json}\" \"scripts/**/*.mts\""
43
46
  },
44
47
  "devDependencies": {
45
- "@types/aws-lambda": "^8.10.109",
46
- "@types/node": "^22.13.10",
47
- "@types/uuid": "^10.0.0",
48
- "@typescript-eslint/eslint-plugin": "^8.26.1",
49
- "@typescript-eslint/parser": "^8.26.1",
50
- "eslint": "^9.39.1",
51
- "prettier": "^3.2.5",
52
- "typescript": "^5.8.2",
53
- "vitest": "^4.1.2"
48
+ "@aws-sdk/client-elastic-load-balancing-v2": "^3.1045.0",
49
+ "@types/aws-lambda": "^8.10.161",
50
+ "@types/node": "^25.6.0",
51
+ "@types/uuid": "^11.0.0",
52
+ "@typescript-eslint/eslint-plugin": "^8.59.1",
53
+ "@typescript-eslint/parser": "^8.59.1",
54
+ "eslint": "^10.2.1",
55
+ "prettier": "^3.8.3",
56
+ "typescript": "^6.0.3",
57
+ "vitest": "^4.1.5"
54
58
  },
55
59
  "dependencies": {
56
- "@aws-sdk/client-organizations": "^3.997.0",
57
- "@fjall/generator": "^0.96.0",
58
- "@fjall/util": "^0.96.0",
59
- "cdk-time-sleep": "^1.0.0",
60
+ "@aws-sdk/client-organizations": "^3.1038.0",
61
+ "@fjall/generator": "^0.99.3",
62
+ "@fjall/util": "^0.99.3",
60
63
  "constructs": "^10.0.0",
61
- "uuid": "^10.0.0"
64
+ "uuid": "^14.0.0"
62
65
  },
63
66
  "overrides": {
64
67
  "@smithy/core": "2.5.5"
65
68
  },
66
- "gitHead": "bfbd3625ab029ba77a6571630e0edb85f9d53380",
67
69
  "peerDependencies": {
68
70
  "aws-cdk": "^2.239.0",
69
71
  "aws-cdk-lib": "^2.239.0",
@@ -71,5 +73,6 @@
71
73
  },
72
74
  "engines": {
73
75
  "node": ">=18.0.0"
74
- }
76
+ },
77
+ "gitHead": "e50d25185d5eab618e2a90622466296fa0cbffe8"
75
78
  }