@fjall/generator 0.88.4 → 0.89.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/dist/src/ast/astCdnParser.d.ts +15 -0
- package/dist/src/ast/astCdnParser.js +114 -0
- package/dist/src/ast/astCommonParser.d.ts +90 -0
- package/dist/src/ast/astCommonParser.js +351 -0
- package/dist/src/ast/astComputeParser.d.ts +14 -2
- package/dist/src/ast/astComputeParser.js +55 -9
- package/dist/src/ast/astDatabaseParser.d.ts +104 -0
- package/dist/src/ast/astDatabaseParser.js +275 -0
- package/dist/src/ast/astInfrastructureParser.d.ts +23 -277
- package/dist/src/ast/astInfrastructureParser.js +83 -1456
- package/dist/src/ast/astMessagingParser.d.ts +25 -0
- package/dist/src/ast/astMessagingParser.js +78 -0
- package/dist/src/ast/astNetworkParser.d.ts +70 -0
- package/dist/src/ast/astNetworkParser.js +219 -0
- package/dist/src/ast/astPatternParser.d.ts +80 -0
- package/dist/src/ast/astPatternParser.js +155 -0
- package/dist/src/ast/astStorageParser.d.ts +18 -0
- package/dist/src/ast/astStorageParser.js +164 -0
- package/dist/src/ast/index.d.ts +1 -0
- package/dist/src/ast/index.js +4 -0
- package/dist/src/dns/bindParser.d.ts +13 -0
- package/dist/src/dns/bindParser.js +224 -0
- package/dist/src/dns/bindWriter.d.ts +2 -0
- package/dist/src/dns/bindWriter.js +52 -0
- package/dist/src/dns/index.d.ts +4 -0
- package/dist/src/dns/index.js +4 -0
- package/dist/src/dns/infrastructureWriter.d.ts +2 -0
- package/dist/src/dns/infrastructureWriter.js +58 -0
- package/dist/src/dns/types.d.ts +82 -0
- package/dist/src/dns/types.js +52 -0
- package/dist/src/generation/common.d.ts +1 -16
- package/dist/src/generation/common.js +2 -28
- package/dist/src/generation/compute.js +77 -28
- package/dist/src/generation/index.d.ts +2 -1
- package/dist/src/generation/index.js +3 -1
- package/dist/src/generation/messagingConnections.d.ts +33 -0
- package/dist/src/generation/messagingConnections.js +73 -0
- package/dist/src/generation/storage.d.ts +5 -1
- package/dist/src/generation/storage.js +9 -1
- package/dist/src/generation/storageConnections.d.ts +3 -3
- package/dist/src/generation/storageConnections.js +8 -4
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +2 -0
- package/dist/src/planning/resourcePlanning.js +0 -2
- package/dist/src/presets/tierTypes.d.ts +4 -1
- package/dist/src/schemas/applicationSchemas.d.ts +854 -0
- package/dist/src/schemas/applicationSchemas.js +80 -0
- package/dist/src/schemas/baseSchemas.d.ts +206 -0
- package/dist/src/schemas/baseSchemas.js +248 -0
- package/dist/src/schemas/cdnSchemas.d.ts +61 -0
- package/dist/src/schemas/cdnSchemas.js +62 -0
- package/dist/src/schemas/computeSchemas.d.ts +723 -0
- package/dist/src/schemas/computeSchemas.js +727 -0
- package/dist/src/schemas/constants.d.ts +12 -8
- package/dist/src/schemas/constants.js +14 -4
- package/dist/src/schemas/databaseSchemas.d.ts +638 -0
- package/dist/src/schemas/databaseSchemas.js +366 -0
- package/dist/src/schemas/messagingSchemas.d.ts +20 -0
- package/dist/src/schemas/messagingSchemas.js +29 -0
- package/dist/src/schemas/networkSchemas.d.ts +246 -0
- package/dist/src/schemas/networkSchemas.js +125 -0
- package/dist/src/schemas/patternSchemas.d.ts +708 -0
- package/dist/src/schemas/patternSchemas.js +294 -0
- package/dist/src/schemas/resourceSchemas.d.ts +24 -3530
- package/dist/src/schemas/resourceSchemas.js +24 -2011
- package/dist/src/schemas/storageSchemas.d.ts +93 -0
- package/dist/src/schemas/storageSchemas.js +119 -0
- package/dist/src/util/errorUtils.d.ts +1 -2
- package/dist/src/util/errorUtils.js +1 -15
- package/dist/src/validation/patterns.d.ts +9 -0
- package/dist/src/validation/patterns.js +9 -0
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/package.json +5 -3
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { VALIDATION_MESSAGES } from "../validation/patterns.js";
|
|
3
|
+
import { AppNameSchema, AppTypeSchema, PatternSchema, CustomCodeBlockSchema, BackupConfigSchema, TunnelConfigSchema, } from "./baseSchemas.js";
|
|
4
|
+
import { DatabaseResourcePlanSchema } from "./databaseSchemas.js";
|
|
5
|
+
import { NetworkResourcePlanSchema, AdditionalNetworkResourcePlanSchema, NetworkConfigSchema, } from "./networkSchemas.js";
|
|
6
|
+
import { S3ResourcePlanSchema } from "./storageSchemas.js";
|
|
7
|
+
import { SQSResourcePlanSchema } from "./messagingSchemas.js";
|
|
8
|
+
import { CDNResourcePlanSchema } from "./cdnSchemas.js";
|
|
9
|
+
import { ComputeResourcePlanSchema, ApplicationServiceConfigSchema, } from "./computeSchemas.js";
|
|
10
|
+
import { DynamoDBResourcePlanSchema } from "./databaseSchemas.js";
|
|
11
|
+
import { PatternConfigSchema, PatternTierSchema, CustomPatternDatabaseSchema, CustomPatternComputeSchema, } from "./patternSchemas.js";
|
|
12
|
+
// ─── Application resource plan ───────────────────────────────────────────────
|
|
13
|
+
/**
|
|
14
|
+
* Application resource plan schema.
|
|
15
|
+
* Represents the complete plan for an application's infrastructure.
|
|
16
|
+
* Must be defined after ComputeResourcePlanSchema due to declaration order.
|
|
17
|
+
*/
|
|
18
|
+
export const ApplicationResourcePlanSchema = z
|
|
19
|
+
.object({
|
|
20
|
+
appName: AppNameSchema,
|
|
21
|
+
type: AppTypeSchema,
|
|
22
|
+
pattern: PatternSchema.optional(),
|
|
23
|
+
/** Pattern configuration for high-level infrastructure patterns (Payload, etc.) */
|
|
24
|
+
patternConfig: PatternConfigSchema.optional(),
|
|
25
|
+
owner: z.string().optional(),
|
|
26
|
+
tags: z.record(z.string(), z.string()).optional(),
|
|
27
|
+
vpcId: z.string().optional(),
|
|
28
|
+
network: NetworkResourcePlanSchema.optional(),
|
|
29
|
+
backup: BackupConfigSchema.optional(),
|
|
30
|
+
tunnel: TunnelConfigSchema.optional(),
|
|
31
|
+
additionalNetworks: z.array(AdditionalNetworkResourcePlanSchema).optional(),
|
|
32
|
+
database: z.array(DatabaseResourcePlanSchema),
|
|
33
|
+
s3: z.array(S3ResourcePlanSchema),
|
|
34
|
+
compute: z.array(ComputeResourcePlanSchema),
|
|
35
|
+
dynamodb: z.array(DynamoDBResourcePlanSchema).optional(),
|
|
36
|
+
sqs: z.array(SQSResourcePlanSchema).optional(),
|
|
37
|
+
cdn: CDNResourcePlanSchema.optional(),
|
|
38
|
+
/** Custom code blocks to preserve during regeneration */
|
|
39
|
+
customCodeBlocks: z.array(CustomCodeBlockSchema).optional(),
|
|
40
|
+
/** Additional managed imports to preserve during round-trip (non-standard imports from managed modules) */
|
|
41
|
+
additionalManagedImports: z
|
|
42
|
+
.array(z
|
|
43
|
+
.object({
|
|
44
|
+
moduleSpecifier: z.string(),
|
|
45
|
+
namedImports: z.array(z.string()),
|
|
46
|
+
defaultImport: z.string().optional(),
|
|
47
|
+
})
|
|
48
|
+
.strict())
|
|
49
|
+
.optional(),
|
|
50
|
+
})
|
|
51
|
+
.strict();
|
|
52
|
+
// ─── Application generator schema ────────────────────────────────────────────
|
|
53
|
+
export const ApplicationGeneratorSchema = z
|
|
54
|
+
.object({
|
|
55
|
+
name: AppNameSchema,
|
|
56
|
+
type: AppTypeSchema,
|
|
57
|
+
pattern: PatternSchema.optional(),
|
|
58
|
+
/** Pattern tier: lightweight, standard, resilient, or custom */
|
|
59
|
+
patternTier: PatternTierSchema.optional(),
|
|
60
|
+
/** Custom domain for pattern (e.g., cms.example.com) */
|
|
61
|
+
patternDomain: z.string().optional(),
|
|
62
|
+
/** Custom database configuration (only used when patternTier is "custom") */
|
|
63
|
+
customDatabase: CustomPatternDatabaseSchema.optional(),
|
|
64
|
+
/** Custom compute configuration (only used when patternTier is "custom") */
|
|
65
|
+
customCompute: CustomPatternComputeSchema.optional(),
|
|
66
|
+
region: z.string().optional(),
|
|
67
|
+
owner: z.string().optional(),
|
|
68
|
+
includeDatabase: z.boolean().optional(),
|
|
69
|
+
databaseName: z
|
|
70
|
+
.string()
|
|
71
|
+
.min(1, VALIDATION_MESSAGES.DATABASE.NAME.REQUIRED)
|
|
72
|
+
.max(63, VALIDATION_MESSAGES.DATABASE.NAME.MAX_LENGTH)
|
|
73
|
+
.optional(),
|
|
74
|
+
vpcId: z.string().optional(),
|
|
75
|
+
network: NetworkConfigSchema.optional(),
|
|
76
|
+
services: z.array(ApplicationServiceConfigSchema).optional(),
|
|
77
|
+
snapshotIdentifier: z.string().optional(),
|
|
78
|
+
snapshotUsername: z.string().optional(),
|
|
79
|
+
})
|
|
80
|
+
.strict();
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const optionalOrDisabled: <T extends z.ZodTypeAny>(schema: T) => z.ZodUnion<[z.ZodLiteral<false>, T]>;
|
|
3
|
+
/** Reusable capacity validation: ensures minCapacity <= maxCapacity. */
|
|
4
|
+
export declare const CAPACITY_REFINEMENT: {
|
|
5
|
+
check: (data: {
|
|
6
|
+
minCapacity?: number;
|
|
7
|
+
maxCapacity?: number;
|
|
8
|
+
}) => boolean;
|
|
9
|
+
params: {
|
|
10
|
+
message: "minCapacity must be less than or equal to maxCapacity";
|
|
11
|
+
path: string[];
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
/** Reusable memory limit schema. EC2 allows 128 MiB min; ECS/containers require 512 MiB min. */
|
|
15
|
+
export declare const memoryLimitMiBSchema: (min: 128 | 512) => z.ZodNumber;
|
|
16
|
+
export declare const ResourceNameSchema: z.ZodString;
|
|
17
|
+
export declare const BucketNameSchema: z.ZodString;
|
|
18
|
+
export declare const DatabaseNameSchema: z.ZodString;
|
|
19
|
+
export declare const AppNameSchema: z.ZodString;
|
|
20
|
+
export declare const PortSchema: z.ZodNumber;
|
|
21
|
+
/**
|
|
22
|
+
* Extra property preserved verbatim during round-trip.
|
|
23
|
+
* Captures properties inside managed factory calls that the parser
|
|
24
|
+
* does not specifically handle (e.g. CDK PolicyStatement[], custom configs).
|
|
25
|
+
*/
|
|
26
|
+
export declare const ExtraPropertySchema: z.ZodObject<{
|
|
27
|
+
key: z.ZodString;
|
|
28
|
+
sourceText: z.ZodString;
|
|
29
|
+
}, z.core.$strict>;
|
|
30
|
+
export declare const IdentifierValueSchema: z.ZodObject<{
|
|
31
|
+
__identifier: z.ZodString;
|
|
32
|
+
}, z.core.$strict>;
|
|
33
|
+
export declare const ExpressionValueSchema: z.ZodObject<{
|
|
34
|
+
__expression: z.ZodString;
|
|
35
|
+
}, z.core.$strict>;
|
|
36
|
+
export declare const CallValueSchema: z.ZodObject<{
|
|
37
|
+
__call: z.ZodString;
|
|
38
|
+
}, z.core.$strict>;
|
|
39
|
+
export declare const SpecialValueSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
40
|
+
__identifier: z.ZodString;
|
|
41
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
42
|
+
__expression: z.ZodString;
|
|
43
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
44
|
+
__call: z.ZodString;
|
|
45
|
+
}, z.core.$strict>]>;
|
|
46
|
+
/**
|
|
47
|
+
* Schema for environment variable values.
|
|
48
|
+
* Supports literal values and special code generation values.
|
|
49
|
+
*/
|
|
50
|
+
export declare const EnvironmentValueSchema: z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodUnion<readonly [z.ZodObject<{
|
|
51
|
+
__identifier: z.ZodString;
|
|
52
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
53
|
+
__expression: z.ZodString;
|
|
54
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
55
|
+
__call: z.ZodString;
|
|
56
|
+
}, z.core.$strict>]>]>;
|
|
57
|
+
export declare const EnvironmentRecordSchema: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodUnion<readonly [z.ZodObject<{
|
|
58
|
+
__identifier: z.ZodString;
|
|
59
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
60
|
+
__expression: z.ZodString;
|
|
61
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
62
|
+
__call: z.ZodString;
|
|
63
|
+
}, z.core.$strict>]>]>>;
|
|
64
|
+
/**
|
|
65
|
+
* Schema for importing secrets from AWS Secrets Manager.
|
|
66
|
+
* Matches the SecretImport type in infrastructure.
|
|
67
|
+
*/
|
|
68
|
+
export declare const SecretImportSchema: z.ZodObject<{
|
|
69
|
+
id: z.ZodString;
|
|
70
|
+
name: z.ZodString;
|
|
71
|
+
field: z.ZodOptional<z.ZodString>;
|
|
72
|
+
}, z.core.$strict>;
|
|
73
|
+
/**
|
|
74
|
+
* Record of secret imports keyed by environment variable name.
|
|
75
|
+
*/
|
|
76
|
+
export declare const SecretsImportRecordSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
77
|
+
id: z.ZodString;
|
|
78
|
+
name: z.ZodString;
|
|
79
|
+
field: z.ZodOptional<z.ZodString>;
|
|
80
|
+
}, z.core.$strict>>;
|
|
81
|
+
/**
|
|
82
|
+
* Schema for metadata values.
|
|
83
|
+
* Supports simple types and complex AWS SDK types (VpcConfigResponse, Date, etc.)
|
|
84
|
+
* Uses z.unknown() for flexibility with AWS resource properties whilst avoiding z.any().
|
|
85
|
+
*/
|
|
86
|
+
export declare const MetadataRecordSchema: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
87
|
+
export declare const AppTypeSchema: z.ZodEnum<{
|
|
88
|
+
custom: "custom";
|
|
89
|
+
standard: "standard";
|
|
90
|
+
resilient: "resilient";
|
|
91
|
+
enterprise: "enterprise";
|
|
92
|
+
tinkerer: "tinkerer";
|
|
93
|
+
lightweight: "lightweight";
|
|
94
|
+
}>;
|
|
95
|
+
export declare const PatternSchema: z.ZodEnum<{
|
|
96
|
+
payload: "payload";
|
|
97
|
+
nextjs: "nextjs";
|
|
98
|
+
}>;
|
|
99
|
+
/**
|
|
100
|
+
* Custom code block position type.
|
|
101
|
+
* Defines where a custom code block appears relative to managed code.
|
|
102
|
+
*/
|
|
103
|
+
export declare const CustomCodePositionSchema: z.ZodEnum<{
|
|
104
|
+
"before-imports": "before-imports";
|
|
105
|
+
"after-imports": "after-imports";
|
|
106
|
+
"after-app-init": "after-app-init";
|
|
107
|
+
"after-tags": "after-tags";
|
|
108
|
+
"after-resource": "after-resource";
|
|
109
|
+
"end-of-file": "end-of-file";
|
|
110
|
+
}>;
|
|
111
|
+
/**
|
|
112
|
+
* Statement type for managed resources.
|
|
113
|
+
*/
|
|
114
|
+
export declare const StatementTypeSchema: z.ZodEnum<{
|
|
115
|
+
custom: "custom";
|
|
116
|
+
pattern: "pattern";
|
|
117
|
+
storage: "storage";
|
|
118
|
+
database: "database";
|
|
119
|
+
compute: "compute";
|
|
120
|
+
import: "import";
|
|
121
|
+
"app-init": "app-init";
|
|
122
|
+
tags: "tags";
|
|
123
|
+
network: "network";
|
|
124
|
+
messaging: "messaging";
|
|
125
|
+
cdn: "cdn";
|
|
126
|
+
}>;
|
|
127
|
+
/**
|
|
128
|
+
* Custom code block schema.
|
|
129
|
+
* Represents user-written code that should be preserved during regeneration.
|
|
130
|
+
* Used by the hybrid parse-preserve-generate approach.
|
|
131
|
+
*/
|
|
132
|
+
export declare const CustomCodeBlockSchema: z.ZodObject<{
|
|
133
|
+
sourceText: z.ZodString;
|
|
134
|
+
position: z.ZodEnum<{
|
|
135
|
+
"before-imports": "before-imports";
|
|
136
|
+
"after-imports": "after-imports";
|
|
137
|
+
"after-app-init": "after-app-init";
|
|
138
|
+
"after-tags": "after-tags";
|
|
139
|
+
"after-resource": "after-resource";
|
|
140
|
+
"end-of-file": "end-of-file";
|
|
141
|
+
}>;
|
|
142
|
+
afterManagedResource: z.ZodOptional<z.ZodObject<{
|
|
143
|
+
type: z.ZodEnum<{
|
|
144
|
+
custom: "custom";
|
|
145
|
+
pattern: "pattern";
|
|
146
|
+
storage: "storage";
|
|
147
|
+
database: "database";
|
|
148
|
+
compute: "compute";
|
|
149
|
+
import: "import";
|
|
150
|
+
"app-init": "app-init";
|
|
151
|
+
tags: "tags";
|
|
152
|
+
network: "network";
|
|
153
|
+
messaging: "messaging";
|
|
154
|
+
cdn: "cdn";
|
|
155
|
+
}>;
|
|
156
|
+
name: z.ZodOptional<z.ZodString>;
|
|
157
|
+
}, z.core.$strict>>;
|
|
158
|
+
originalLine: z.ZodOptional<z.ZodNumber>;
|
|
159
|
+
leadingComments: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
160
|
+
orphaned: z.ZodOptional<z.ZodBoolean>;
|
|
161
|
+
orphanedComment: z.ZodOptional<z.ZodString>;
|
|
162
|
+
}, z.core.$strict>;
|
|
163
|
+
/**
|
|
164
|
+
* Backup configuration schema.
|
|
165
|
+
* Controls automatic AWS Backup enrolment via tier presets.
|
|
166
|
+
* - Object with tier: Tags all resources with `fjall:disasterRecovery:tier`
|
|
167
|
+
* - false: Explicitly disabled (no backup tag applied)
|
|
168
|
+
*/
|
|
169
|
+
export declare const BackupConfigSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
170
|
+
tier: z.ZodEnum<{
|
|
171
|
+
standard: "standard";
|
|
172
|
+
resilient: "resilient";
|
|
173
|
+
enterprise: "enterprise";
|
|
174
|
+
}>;
|
|
175
|
+
}, z.core.$strict>, z.ZodLiteral<false>]>;
|
|
176
|
+
/**
|
|
177
|
+
* Tunnel configuration schema.
|
|
178
|
+
* Controls bastion host creation for secure SSM database access.
|
|
179
|
+
* - Object with optional instanceType: Create bastion with custom config
|
|
180
|
+
* - false: Explicitly disabled (no bastion)
|
|
181
|
+
*/
|
|
182
|
+
export declare const TunnelConfigSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
183
|
+
instanceType: z.ZodOptional<z.ZodString>;
|
|
184
|
+
}, z.core.$strict>, z.ZodLiteral<false>]>;
|
|
185
|
+
export declare const OrganisationNameSchema: z.ZodString;
|
|
186
|
+
export declare const EmailSchema: z.ZodString;
|
|
187
|
+
export declare const RegionSchema: z.ZodString;
|
|
188
|
+
export declare const OrganisationGeneratorSchema: z.ZodObject<{
|
|
189
|
+
name: z.ZodString;
|
|
190
|
+
email: z.ZodString;
|
|
191
|
+
accountName: z.ZodOptional<z.ZodString>;
|
|
192
|
+
primaryRegion: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
193
|
+
secondaryRegions: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
194
|
+
force: z.ZodOptional<z.ZodBoolean>;
|
|
195
|
+
}, z.core.$strict>;
|
|
196
|
+
export declare function getZodErrorMessage(error: z.ZodError<unknown>): string;
|
|
197
|
+
export type IdentifierValue = z.infer<typeof IdentifierValueSchema>;
|
|
198
|
+
export type ExpressionValue = z.infer<typeof ExpressionValueSchema>;
|
|
199
|
+
export type CallValue = z.infer<typeof CallValueSchema>;
|
|
200
|
+
export type SpecialValue = z.infer<typeof SpecialValueSchema>;
|
|
201
|
+
export type EnvironmentValue = z.infer<typeof EnvironmentValueSchema>;
|
|
202
|
+
export type CustomCodePosition = z.infer<typeof CustomCodePositionSchema>;
|
|
203
|
+
export type StatementType = z.infer<typeof StatementTypeSchema>;
|
|
204
|
+
export type CustomCodeBlock = z.infer<typeof CustomCodeBlockSchema>;
|
|
205
|
+
export type ExtraProperty = z.infer<typeof ExtraPropertySchema>;
|
|
206
|
+
export type OrganisationGeneratorOptions = z.infer<typeof OrganisationGeneratorSchema>;
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { VALIDATION_PATTERNS, VALIDATION_MESSAGES, } from "../validation/patterns.js";
|
|
3
|
+
import { APP_TYPES, PATTERN_TYPE_VALUES, MIN_PORT, MAX_PORT, BACKUP_VAULT_TIERS, } from "./constants.js";
|
|
4
|
+
import { regions } from "../aws/regions.js";
|
|
5
|
+
// ─── Shared utility ──────────────────────────────────────────────────────────
|
|
6
|
+
export const optionalOrDisabled = (schema) => z.union([z.literal(false), schema]);
|
|
7
|
+
/** Reusable capacity validation: ensures minCapacity <= maxCapacity. */
|
|
8
|
+
export const CAPACITY_REFINEMENT = {
|
|
9
|
+
check: (data) => {
|
|
10
|
+
if (data.minCapacity !== undefined && data.maxCapacity !== undefined) {
|
|
11
|
+
return data.minCapacity <= data.maxCapacity;
|
|
12
|
+
}
|
|
13
|
+
return true;
|
|
14
|
+
},
|
|
15
|
+
params: {
|
|
16
|
+
message: VALIDATION_MESSAGES.CAPACITY_CONSTRAINT.MIN_LTE_MAX,
|
|
17
|
+
path: ["maxCapacity"],
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
/** Reusable memory limit schema. EC2 allows 128 MiB min; ECS/containers require 512 MiB min. */
|
|
21
|
+
export const memoryLimitMiBSchema = (min) => z
|
|
22
|
+
.number()
|
|
23
|
+
.int(VALIDATION_MESSAGES.MEMORY_LIMIT.INTEGER)
|
|
24
|
+
.min(min, min === 128
|
|
25
|
+
? VALIDATION_MESSAGES.MEMORY_LIMIT.MIN_128
|
|
26
|
+
: VALIDATION_MESSAGES.MEMORY_LIMIT.MIN_512)
|
|
27
|
+
.max(30720, VALIDATION_MESSAGES.MEMORY_LIMIT.MAX);
|
|
28
|
+
// ─── Name / identifier schemas ───────────────────────────────────────────────
|
|
29
|
+
export const ResourceNameSchema = z
|
|
30
|
+
.string()
|
|
31
|
+
.min(1, VALIDATION_MESSAGES.REQUIRED.RESOURCE_NAME)
|
|
32
|
+
.max(63, VALIDATION_MESSAGES.MAX_LENGTH.RESOURCE_NAME)
|
|
33
|
+
.regex(VALIDATION_PATTERNS.RESOURCE_NAME, VALIDATION_MESSAGES.RESOURCE_NAME);
|
|
34
|
+
export const BucketNameSchema = z
|
|
35
|
+
.string()
|
|
36
|
+
.min(1, VALIDATION_MESSAGES.REQUIRED.BUCKET_NAME)
|
|
37
|
+
.max(63, VALIDATION_MESSAGES.MAX_LENGTH.BUCKET_NAME)
|
|
38
|
+
.regex(VALIDATION_PATTERNS.BUCKET_NAME, VALIDATION_MESSAGES.BUCKET_NAME);
|
|
39
|
+
export const DatabaseNameSchema = z
|
|
40
|
+
.string()
|
|
41
|
+
.min(1, VALIDATION_MESSAGES.REQUIRED.DATABASE_NAME)
|
|
42
|
+
.max(63, VALIDATION_MESSAGES.MAX_LENGTH.DATABASE_NAME)
|
|
43
|
+
.regex(VALIDATION_PATTERNS.DATABASE_NAME, VALIDATION_MESSAGES.DATABASE_NAME);
|
|
44
|
+
export const AppNameSchema = z
|
|
45
|
+
.string()
|
|
46
|
+
.min(2, VALIDATION_MESSAGES.IDENTIFIER_MIN_LENGTH)
|
|
47
|
+
.max(50, VALIDATION_MESSAGES.MAX_LENGTH.APP_NAME)
|
|
48
|
+
.regex(VALIDATION_PATTERNS.IDENTIFIER, VALIDATION_MESSAGES.IDENTIFIER)
|
|
49
|
+
.refine((val) => !val.endsWith("-"), {
|
|
50
|
+
message: VALIDATION_MESSAGES.IDENTIFIER_NO_TRAILING_HYPHEN,
|
|
51
|
+
})
|
|
52
|
+
.refine((val) => !val.includes("--"), {
|
|
53
|
+
message: VALIDATION_MESSAGES.IDENTIFIER_NO_CONSECUTIVE_HYPHENS,
|
|
54
|
+
});
|
|
55
|
+
export const PortSchema = z
|
|
56
|
+
.number()
|
|
57
|
+
.int(VALIDATION_MESSAGES.PORT.INTEGER)
|
|
58
|
+
.min(MIN_PORT, VALIDATION_MESSAGES.PORT.MIN)
|
|
59
|
+
.max(MAX_PORT, VALIDATION_MESSAGES.PORT.MAX);
|
|
60
|
+
// ─── Special / environment value schemas ─────────────────────────────────────
|
|
61
|
+
/**
|
|
62
|
+
* Extra property preserved verbatim during round-trip.
|
|
63
|
+
* Captures properties inside managed factory calls that the parser
|
|
64
|
+
* does not specifically handle (e.g. CDK PolicyStatement[], custom configs).
|
|
65
|
+
*/
|
|
66
|
+
export const ExtraPropertySchema = z
|
|
67
|
+
.object({
|
|
68
|
+
key: z.string(),
|
|
69
|
+
sourceText: z.string(),
|
|
70
|
+
})
|
|
71
|
+
.strict();
|
|
72
|
+
export const IdentifierValueSchema = z
|
|
73
|
+
.object({ __identifier: z.string() })
|
|
74
|
+
.strict();
|
|
75
|
+
export const ExpressionValueSchema = z
|
|
76
|
+
.object({ __expression: z.string() })
|
|
77
|
+
.strict();
|
|
78
|
+
export const CallValueSchema = z.object({ __call: z.string() }).strict();
|
|
79
|
+
export const SpecialValueSchema = z.union([
|
|
80
|
+
IdentifierValueSchema,
|
|
81
|
+
ExpressionValueSchema,
|
|
82
|
+
CallValueSchema,
|
|
83
|
+
]);
|
|
84
|
+
/**
|
|
85
|
+
* Schema for environment variable values.
|
|
86
|
+
* Supports literal values and special code generation values.
|
|
87
|
+
*/
|
|
88
|
+
export const EnvironmentValueSchema = z.union([
|
|
89
|
+
z.string(),
|
|
90
|
+
z.number(),
|
|
91
|
+
z.boolean(),
|
|
92
|
+
SpecialValueSchema,
|
|
93
|
+
]);
|
|
94
|
+
export const EnvironmentRecordSchema = z.record(z.string(), EnvironmentValueSchema);
|
|
95
|
+
/**
|
|
96
|
+
* Schema for importing secrets from AWS Secrets Manager.
|
|
97
|
+
* Matches the SecretImport type in infrastructure.
|
|
98
|
+
*/
|
|
99
|
+
export const SecretImportSchema = z
|
|
100
|
+
.object({
|
|
101
|
+
/** Secret construct ID */
|
|
102
|
+
id: z.string(),
|
|
103
|
+
/** Secret name in Secrets Manager */
|
|
104
|
+
name: z.string(),
|
|
105
|
+
/** Optional field to extract from the secret */
|
|
106
|
+
field: z.string().optional(),
|
|
107
|
+
})
|
|
108
|
+
.strict();
|
|
109
|
+
/**
|
|
110
|
+
* Record of secret imports keyed by environment variable name.
|
|
111
|
+
*/
|
|
112
|
+
export const SecretsImportRecordSchema = z.record(z.string(), SecretImportSchema);
|
|
113
|
+
/**
|
|
114
|
+
* Schema for metadata values.
|
|
115
|
+
* Supports simple types and complex AWS SDK types (VpcConfigResponse, Date, etc.)
|
|
116
|
+
* Uses z.unknown() for flexibility with AWS resource properties whilst avoiding z.any().
|
|
117
|
+
*/
|
|
118
|
+
export const MetadataRecordSchema = z.record(z.string(), z.unknown());
|
|
119
|
+
// ─── Application-level schemas ───────────────────────────────────────────────
|
|
120
|
+
export const AppTypeSchema = z
|
|
121
|
+
.enum(APP_TYPES)
|
|
122
|
+
.describe(`Application type must be one of: ${APP_TYPES.join(", ")}`);
|
|
123
|
+
export const PatternSchema = z
|
|
124
|
+
.enum(PATTERN_TYPE_VALUES)
|
|
125
|
+
.describe(`OpenNext deployment pattern: ${PATTERN_TYPE_VALUES.join(", ")}`);
|
|
126
|
+
// ─── Custom code preservation schemas ────────────────────────────────────────
|
|
127
|
+
/**
|
|
128
|
+
* Custom code block position type.
|
|
129
|
+
* Defines where a custom code block appears relative to managed code.
|
|
130
|
+
*/
|
|
131
|
+
export const CustomCodePositionSchema = z.enum([
|
|
132
|
+
"before-imports",
|
|
133
|
+
"after-imports",
|
|
134
|
+
"after-app-init",
|
|
135
|
+
"after-tags",
|
|
136
|
+
"after-resource",
|
|
137
|
+
"end-of-file",
|
|
138
|
+
]);
|
|
139
|
+
/**
|
|
140
|
+
* Statement type for managed resources.
|
|
141
|
+
*/
|
|
142
|
+
export const StatementTypeSchema = z.enum([
|
|
143
|
+
"import",
|
|
144
|
+
"app-init",
|
|
145
|
+
"tags",
|
|
146
|
+
"database",
|
|
147
|
+
"compute",
|
|
148
|
+
"storage",
|
|
149
|
+
"network",
|
|
150
|
+
"messaging",
|
|
151
|
+
"cdn",
|
|
152
|
+
"pattern",
|
|
153
|
+
"custom",
|
|
154
|
+
]);
|
|
155
|
+
/**
|
|
156
|
+
* Custom code block schema.
|
|
157
|
+
* Represents user-written code that should be preserved during regeneration.
|
|
158
|
+
* Used by the hybrid parse-preserve-generate approach.
|
|
159
|
+
*/
|
|
160
|
+
export const CustomCodeBlockSchema = z
|
|
161
|
+
.object({
|
|
162
|
+
/** The exact source text to preserve (including leading comments) */
|
|
163
|
+
sourceText: z.string(),
|
|
164
|
+
/** Position relative to managed resources */
|
|
165
|
+
position: CustomCodePositionSchema,
|
|
166
|
+
/** For "after-resource" position, the managed resource type and name */
|
|
167
|
+
afterManagedResource: z
|
|
168
|
+
.object({
|
|
169
|
+
type: StatementTypeSchema,
|
|
170
|
+
name: z.string().optional(),
|
|
171
|
+
})
|
|
172
|
+
.strict()
|
|
173
|
+
.optional(),
|
|
174
|
+
/** Original line number in source (for debugging) */
|
|
175
|
+
originalLine: z.number().int().optional(),
|
|
176
|
+
/** Leading comments associated with this block */
|
|
177
|
+
leadingComments: z.array(z.string()).optional(),
|
|
178
|
+
/** Orphaned marker - set when the resource this block was after is deleted */
|
|
179
|
+
orphaned: z.boolean().optional(),
|
|
180
|
+
/** Orphaned warning comment to add */
|
|
181
|
+
orphanedComment: z.string().optional(),
|
|
182
|
+
})
|
|
183
|
+
.strict();
|
|
184
|
+
// ─── Backup / tunnel configuration ──────────────────────────────────────────
|
|
185
|
+
/**
|
|
186
|
+
* Backup configuration schema.
|
|
187
|
+
* Controls automatic AWS Backup enrolment via tier presets.
|
|
188
|
+
* - Object with tier: Tags all resources with `fjall:disasterRecovery:tier`
|
|
189
|
+
* - false: Explicitly disabled (no backup tag applied)
|
|
190
|
+
*/
|
|
191
|
+
export const BackupConfigSchema = z.union([
|
|
192
|
+
z
|
|
193
|
+
.object({
|
|
194
|
+
tier: z.enum(BACKUP_VAULT_TIERS),
|
|
195
|
+
})
|
|
196
|
+
.strict(),
|
|
197
|
+
z.literal(false),
|
|
198
|
+
]);
|
|
199
|
+
/**
|
|
200
|
+
* Tunnel configuration schema.
|
|
201
|
+
* Controls bastion host creation for secure SSM database access.
|
|
202
|
+
* - Object with optional instanceType: Create bastion with custom config
|
|
203
|
+
* - false: Explicitly disabled (no bastion)
|
|
204
|
+
*/
|
|
205
|
+
export const TunnelConfigSchema = z.union([
|
|
206
|
+
z
|
|
207
|
+
.object({
|
|
208
|
+
instanceType: z.string().optional(),
|
|
209
|
+
})
|
|
210
|
+
.strict(),
|
|
211
|
+
z.literal(false),
|
|
212
|
+
]);
|
|
213
|
+
// ─── Organisation / region schemas ──────────────────────────────────────────
|
|
214
|
+
export const OrganisationNameSchema = z
|
|
215
|
+
.string()
|
|
216
|
+
.min(2, VALIDATION_MESSAGES.IDENTIFIER_MIN_LENGTH)
|
|
217
|
+
.max(50, VALIDATION_MESSAGES.MAX_LENGTH.ORGANISATION_NAME)
|
|
218
|
+
.regex(VALIDATION_PATTERNS.IDENTIFIER, VALIDATION_MESSAGES.IDENTIFIER)
|
|
219
|
+
.refine((val) => !val.endsWith("-"), {
|
|
220
|
+
message: VALIDATION_MESSAGES.IDENTIFIER_NO_TRAILING_HYPHEN,
|
|
221
|
+
})
|
|
222
|
+
.refine((val) => !val.includes("--"), {
|
|
223
|
+
message: VALIDATION_MESSAGES.IDENTIFIER_NO_CONSECUTIVE_HYPHENS,
|
|
224
|
+
});
|
|
225
|
+
export const EmailSchema = z.string().email(VALIDATION_MESSAGES.EMAIL);
|
|
226
|
+
export const RegionSchema = z
|
|
227
|
+
.string()
|
|
228
|
+
.refine((region) => regions.includes(region), {
|
|
229
|
+
message: VALIDATION_MESSAGES.REGION,
|
|
230
|
+
});
|
|
231
|
+
export const OrganisationGeneratorSchema = z
|
|
232
|
+
.object({
|
|
233
|
+
name: OrganisationNameSchema,
|
|
234
|
+
email: EmailSchema,
|
|
235
|
+
accountName: z.string().optional(),
|
|
236
|
+
primaryRegion: RegionSchema.optional().default("us-east-1"),
|
|
237
|
+
secondaryRegions: z.array(RegionSchema).optional(),
|
|
238
|
+
force: z.boolean().optional(),
|
|
239
|
+
})
|
|
240
|
+
.strict();
|
|
241
|
+
// ─── Utility function ────────────────────────────────────────────────────────
|
|
242
|
+
export function getZodErrorMessage(error) {
|
|
243
|
+
const messages = error.issues.map((issue) => {
|
|
244
|
+
const path = issue.path.length > 0 ? `${issue.path.join(".")}: ` : "";
|
|
245
|
+
return `${path}${issue.message}`;
|
|
246
|
+
});
|
|
247
|
+
return messages.join("\n");
|
|
248
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Access gate configuration for CDN distributions.
|
|
4
|
+
* Extensible discriminated union — currently supports basic-auth,
|
|
5
|
+
* future types (cognito, oidc, ip-allowlist) can be added.
|
|
6
|
+
*/
|
|
7
|
+
export declare const AccessGateSchema: z.ZodObject<{
|
|
8
|
+
type: z.ZodLiteral<"basic-auth">;
|
|
9
|
+
username: z.ZodString;
|
|
10
|
+
password: z.ZodString;
|
|
11
|
+
}, z.core.$strict>;
|
|
12
|
+
export type AccessGateConfig = z.infer<typeof AccessGateSchema>;
|
|
13
|
+
/**
|
|
14
|
+
* CDN resource plan schema (for OpenNext patterns)
|
|
15
|
+
*/
|
|
16
|
+
export declare const CDNResourcePlanSchema: z.ZodObject<{
|
|
17
|
+
name: z.ZodString;
|
|
18
|
+
defaultOriginRef: z.ZodString;
|
|
19
|
+
behaviours: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
20
|
+
pathPattern: z.ZodString;
|
|
21
|
+
originRef: z.ZodString;
|
|
22
|
+
cachePolicy: z.ZodOptional<z.ZodEnum<{
|
|
23
|
+
CACHING_OPTIMIZED: "CACHING_OPTIMIZED";
|
|
24
|
+
CACHING_DISABLED: "CACHING_DISABLED";
|
|
25
|
+
}>>;
|
|
26
|
+
}, z.core.$strict>>>;
|
|
27
|
+
customDomain: z.ZodOptional<z.ZodString>;
|
|
28
|
+
certificateArn: z.ZodOptional<z.ZodString>;
|
|
29
|
+
accessGate: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodObject<{
|
|
30
|
+
type: z.ZodLiteral<"basic-auth">;
|
|
31
|
+
username: z.ZodString;
|
|
32
|
+
password: z.ZodString;
|
|
33
|
+
}, z.core.$strict>]>>;
|
|
34
|
+
extraProperties: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
35
|
+
key: z.ZodString;
|
|
36
|
+
sourceText: z.ZodString;
|
|
37
|
+
}, z.core.$strict>>>;
|
|
38
|
+
}, z.core.$strict>;
|
|
39
|
+
export declare const CdnGeneratorSchema: z.ZodObject<{
|
|
40
|
+
appName: z.ZodString;
|
|
41
|
+
name: z.ZodOptional<z.ZodString>;
|
|
42
|
+
defaultOriginRef: z.ZodString;
|
|
43
|
+
behaviours: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
44
|
+
pathPattern: z.ZodString;
|
|
45
|
+
originRef: z.ZodString;
|
|
46
|
+
cachePolicy: z.ZodOptional<z.ZodEnum<{
|
|
47
|
+
CACHING_OPTIMIZED: "CACHING_OPTIMIZED";
|
|
48
|
+
CACHING_DISABLED: "CACHING_DISABLED";
|
|
49
|
+
}>>;
|
|
50
|
+
}, z.core.$strict>>>;
|
|
51
|
+
customDomain: z.ZodOptional<z.ZodString>;
|
|
52
|
+
certificateArn: z.ZodOptional<z.ZodString>;
|
|
53
|
+
accessGate: z.ZodOptional<z.ZodUnion<readonly [z.ZodLiteral<false>, z.ZodObject<{
|
|
54
|
+
type: z.ZodLiteral<"basic-auth">;
|
|
55
|
+
username: z.ZodString;
|
|
56
|
+
password: z.ZodString;
|
|
57
|
+
}, z.core.$strict>]>>;
|
|
58
|
+
nameProvidedByFlag: z.ZodOptional<z.ZodBoolean>;
|
|
59
|
+
}, z.core.$strict>;
|
|
60
|
+
export type CdnGeneratorOptions = z.infer<typeof CdnGeneratorSchema>;
|
|
61
|
+
export type CDNResourcePlan = z.infer<typeof CDNResourcePlanSchema>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ResourceNameSchema, ExtraPropertySchema } from "./baseSchemas.js";
|
|
3
|
+
// ─── Access gate ─────────────────────────────────────────────────────────────
|
|
4
|
+
/**
|
|
5
|
+
* Access gate configuration for CDN distributions.
|
|
6
|
+
* Extensible discriminated union — currently supports basic-auth,
|
|
7
|
+
* future types (cognito, oidc, ip-allowlist) can be added.
|
|
8
|
+
*/
|
|
9
|
+
export const AccessGateSchema = z
|
|
10
|
+
.object({
|
|
11
|
+
type: z.literal("basic-auth"),
|
|
12
|
+
username: z.string().min(1),
|
|
13
|
+
password: z.string().min(1),
|
|
14
|
+
})
|
|
15
|
+
.strict();
|
|
16
|
+
// ─── CDN resource plan ───────────────────────────────────────────────────────
|
|
17
|
+
/**
|
|
18
|
+
* CDN resource plan schema (for OpenNext patterns)
|
|
19
|
+
*/
|
|
20
|
+
export const CDNResourcePlanSchema = z
|
|
21
|
+
.object({
|
|
22
|
+
name: ResourceNameSchema,
|
|
23
|
+
defaultOriginRef: z.string(),
|
|
24
|
+
behaviours: z
|
|
25
|
+
.array(z
|
|
26
|
+
.object({
|
|
27
|
+
pathPattern: z.string(),
|
|
28
|
+
originRef: z.string(),
|
|
29
|
+
cachePolicy: z
|
|
30
|
+
.enum(["CACHING_OPTIMIZED", "CACHING_DISABLED"])
|
|
31
|
+
.optional(),
|
|
32
|
+
})
|
|
33
|
+
.strict())
|
|
34
|
+
.optional(),
|
|
35
|
+
customDomain: z.string().optional(),
|
|
36
|
+
certificateArn: z.string().optional(),
|
|
37
|
+
accessGate: z.union([z.literal(false), AccessGateSchema]).optional(),
|
|
38
|
+
extraProperties: z.array(ExtraPropertySchema).optional(),
|
|
39
|
+
})
|
|
40
|
+
.strict();
|
|
41
|
+
export const CdnGeneratorSchema = z
|
|
42
|
+
.object({
|
|
43
|
+
appName: z.string(),
|
|
44
|
+
name: ResourceNameSchema.optional(),
|
|
45
|
+
defaultOriginRef: z.string(),
|
|
46
|
+
behaviours: z
|
|
47
|
+
.array(z
|
|
48
|
+
.object({
|
|
49
|
+
pathPattern: z.string(),
|
|
50
|
+
originRef: z.string(),
|
|
51
|
+
cachePolicy: z
|
|
52
|
+
.enum(["CACHING_OPTIMIZED", "CACHING_DISABLED"])
|
|
53
|
+
.optional(),
|
|
54
|
+
})
|
|
55
|
+
.strict())
|
|
56
|
+
.optional(),
|
|
57
|
+
customDomain: z.string().optional(),
|
|
58
|
+
certificateArn: z.string().optional(),
|
|
59
|
+
accessGate: z.union([z.literal(false), AccessGateSchema]).optional(),
|
|
60
|
+
nameProvidedByFlag: z.boolean().optional(),
|
|
61
|
+
})
|
|
62
|
+
.strict();
|