@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,93 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Stack placement options for S3 buckets.
|
|
4
|
+
* - "storage" (default): Created via app.addStorage() in Storage stack
|
|
5
|
+
* - "cdn": Created in CDN stack for CloudFront-consumed buckets (avoids circular dependencies)
|
|
6
|
+
* - "compute": Created in Compute stack for Lambda-consumed buckets
|
|
7
|
+
*/
|
|
8
|
+
export declare const S3_STACK_PLACEMENTS: readonly ["storage", "cdn", "compute"];
|
|
9
|
+
export declare const S3ResourcePlanSchema: z.ZodObject<{
|
|
10
|
+
name: z.ZodString;
|
|
11
|
+
bucketName: z.ZodOptional<z.ZodString>;
|
|
12
|
+
publicReadAccess: z.ZodOptional<z.ZodBoolean>;
|
|
13
|
+
websiteHosting: z.ZodOptional<z.ZodObject<{
|
|
14
|
+
indexDocument: z.ZodString;
|
|
15
|
+
errorDocument: z.ZodOptional<z.ZodString>;
|
|
16
|
+
}, z.core.$strict>>;
|
|
17
|
+
backupVaultTier: z.ZodOptional<z.ZodEnum<{
|
|
18
|
+
standard: "standard";
|
|
19
|
+
resilient: "resilient";
|
|
20
|
+
enterprise: "enterprise";
|
|
21
|
+
}>>;
|
|
22
|
+
versioned: z.ZodOptional<z.ZodBoolean>;
|
|
23
|
+
encryption: z.ZodOptional<z.ZodEnum<{
|
|
24
|
+
KMS: "KMS";
|
|
25
|
+
AES256: "AES256";
|
|
26
|
+
}>>;
|
|
27
|
+
kmsKeyArn: z.ZodOptional<z.ZodString>;
|
|
28
|
+
cors: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
29
|
+
allowedOrigins: z.ZodArray<z.ZodString>;
|
|
30
|
+
allowedMethods: z.ZodArray<z.ZodString>;
|
|
31
|
+
allowedHeaders: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
32
|
+
exposedHeaders: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
33
|
+
maxAge: z.ZodOptional<z.ZodNumber>;
|
|
34
|
+
}, z.core.$strict>>>;
|
|
35
|
+
deployment: z.ZodOptional<z.ZodObject<{
|
|
36
|
+
source: z.ZodString;
|
|
37
|
+
prune: z.ZodOptional<z.ZodBoolean>;
|
|
38
|
+
cacheControl: z.ZodOptional<z.ZodObject<{
|
|
39
|
+
maxAge: z.ZodOptional<z.ZodNumber>;
|
|
40
|
+
immutable: z.ZodOptional<z.ZodBoolean>;
|
|
41
|
+
}, z.core.$strict>>;
|
|
42
|
+
}, z.core.$strict>>;
|
|
43
|
+
stackPlacement: z.ZodOptional<z.ZodEnum<{
|
|
44
|
+
storage: "storage";
|
|
45
|
+
compute: "compute";
|
|
46
|
+
cdn: "cdn";
|
|
47
|
+
}>>;
|
|
48
|
+
variableName: z.ZodOptional<z.ZodString>;
|
|
49
|
+
extraProperties: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
50
|
+
key: z.ZodString;
|
|
51
|
+
sourceText: z.ZodString;
|
|
52
|
+
}, z.core.$strict>>>;
|
|
53
|
+
}, z.core.$strict>;
|
|
54
|
+
export declare const S3GeneratorSchema: z.ZodObject<{
|
|
55
|
+
appName: z.ZodString;
|
|
56
|
+
bucketName: z.ZodString;
|
|
57
|
+
nameProvidedByFlag: z.ZodOptional<z.ZodBoolean>;
|
|
58
|
+
storagePreset: z.ZodOptional<z.ZodEnum<{
|
|
59
|
+
standard: "standard";
|
|
60
|
+
assets: "assets";
|
|
61
|
+
upload: "upload";
|
|
62
|
+
website: "website";
|
|
63
|
+
}>>;
|
|
64
|
+
publicReadAccess: z.ZodOptional<z.ZodBoolean>;
|
|
65
|
+
websiteHosting: z.ZodOptional<z.ZodObject<{
|
|
66
|
+
indexDocument: z.ZodString;
|
|
67
|
+
errorDocument: z.ZodOptional<z.ZodString>;
|
|
68
|
+
}, z.core.$strict>>;
|
|
69
|
+
backupVaultTier: z.ZodOptional<z.ZodEnum<{
|
|
70
|
+
standard: "standard";
|
|
71
|
+
resilient: "resilient";
|
|
72
|
+
enterprise: "enterprise";
|
|
73
|
+
}>>;
|
|
74
|
+
versioned: z.ZodOptional<z.ZodBoolean>;
|
|
75
|
+
encryption: z.ZodOptional<z.ZodEnum<{
|
|
76
|
+
KMS: "KMS";
|
|
77
|
+
AES256: "AES256";
|
|
78
|
+
}>>;
|
|
79
|
+
kmsKeyArn: z.ZodOptional<z.ZodString>;
|
|
80
|
+
cors: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
81
|
+
allowedOrigins: z.ZodArray<z.ZodString>;
|
|
82
|
+
allowedMethods: z.ZodArray<z.ZodString>;
|
|
83
|
+
allowedHeaders: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
84
|
+
exposedHeaders: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
85
|
+
maxAge: z.ZodOptional<z.ZodNumber>;
|
|
86
|
+
}, z.core.$strict>>>;
|
|
87
|
+
connectionConfig: z.ZodOptional<z.ZodObject<{
|
|
88
|
+
connectToCompute: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
89
|
+
connectToServices: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
90
|
+
}, z.core.$strict>>;
|
|
91
|
+
}, z.core.$strict>;
|
|
92
|
+
export type S3ResourcePlan = z.infer<typeof S3ResourcePlanSchema>;
|
|
93
|
+
export type S3GeneratorOptions = z.infer<typeof S3GeneratorSchema>;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { VALIDATION_MESSAGES } from "../validation/patterns.js";
|
|
3
|
+
import { BACKUP_VAULT_TIERS, S3_ENCRYPTION_TYPES, STORAGE_PRESET_TYPES, } from "./constants.js";
|
|
4
|
+
import { ResourceNameSchema, BucketNameSchema, AppNameSchema, ExtraPropertySchema, } from "./baseSchemas.js";
|
|
5
|
+
// ─── S3 resource plan ────────────────────────────────────────────────────────
|
|
6
|
+
/**
|
|
7
|
+
* Stack placement options for S3 buckets.
|
|
8
|
+
* - "storage" (default): Created via app.addStorage() in Storage stack
|
|
9
|
+
* - "cdn": Created in CDN stack for CloudFront-consumed buckets (avoids circular dependencies)
|
|
10
|
+
* - "compute": Created in Compute stack for Lambda-consumed buckets
|
|
11
|
+
*/
|
|
12
|
+
export const S3_STACK_PLACEMENTS = ["storage", "cdn", "compute"];
|
|
13
|
+
export const S3ResourcePlanSchema = z
|
|
14
|
+
.object({
|
|
15
|
+
name: ResourceNameSchema,
|
|
16
|
+
// Explicit S3 bucket name (user-provided, kebab-case)
|
|
17
|
+
bucketName: z.string().optional(),
|
|
18
|
+
// Access control (replaces bucketType)
|
|
19
|
+
publicReadAccess: z.boolean().optional(),
|
|
20
|
+
// Website hosting (presence-based)
|
|
21
|
+
websiteHosting: z
|
|
22
|
+
.object({
|
|
23
|
+
indexDocument: z.string(),
|
|
24
|
+
errorDocument: z.string().optional(),
|
|
25
|
+
})
|
|
26
|
+
.strict()
|
|
27
|
+
.optional(),
|
|
28
|
+
// Core
|
|
29
|
+
backupVaultTier: z.enum(BACKUP_VAULT_TIERS).optional(),
|
|
30
|
+
versioned: z.boolean().optional(),
|
|
31
|
+
encryption: z.enum(S3_ENCRYPTION_TYPES).optional(),
|
|
32
|
+
kmsKeyArn: z.string().optional(),
|
|
33
|
+
// CORS (any bucket)
|
|
34
|
+
cors: z
|
|
35
|
+
.array(z
|
|
36
|
+
.object({
|
|
37
|
+
allowedOrigins: z.array(z.string()),
|
|
38
|
+
allowedMethods: z.array(z.string()),
|
|
39
|
+
allowedHeaders: z.array(z.string()).optional(),
|
|
40
|
+
exposedHeaders: z.array(z.string()).optional(),
|
|
41
|
+
maxAge: z.number().optional(),
|
|
42
|
+
})
|
|
43
|
+
.strict())
|
|
44
|
+
.optional(),
|
|
45
|
+
// Deployment (any bucket)
|
|
46
|
+
deployment: z
|
|
47
|
+
.object({
|
|
48
|
+
source: z.string(),
|
|
49
|
+
prune: z.boolean().optional(),
|
|
50
|
+
cacheControl: z
|
|
51
|
+
.object({
|
|
52
|
+
maxAge: z.number().optional(),
|
|
53
|
+
immutable: z.boolean().optional(),
|
|
54
|
+
})
|
|
55
|
+
.strict()
|
|
56
|
+
.optional(),
|
|
57
|
+
})
|
|
58
|
+
.strict()
|
|
59
|
+
.optional(),
|
|
60
|
+
// Stack placement
|
|
61
|
+
stackPlacement: z.enum(S3_STACK_PLACEMENTS).optional(),
|
|
62
|
+
// Round-trip preservation
|
|
63
|
+
variableName: z.string().optional(),
|
|
64
|
+
extraProperties: z.array(ExtraPropertySchema).optional(),
|
|
65
|
+
})
|
|
66
|
+
.strict()
|
|
67
|
+
.refine((data) => data.encryption !== "KMS" || !!data.kmsKeyArn, {
|
|
68
|
+
message: VALIDATION_MESSAGES.KMS.KEY_REQUIRED,
|
|
69
|
+
});
|
|
70
|
+
// ─── S3 generator schema ────────────────────────────────────────────────────
|
|
71
|
+
export const S3GeneratorSchema = z
|
|
72
|
+
.object({
|
|
73
|
+
appName: AppNameSchema,
|
|
74
|
+
bucketName: BucketNameSchema,
|
|
75
|
+
nameProvidedByFlag: z.boolean().optional(),
|
|
76
|
+
// Preset (generator-only -- resolved to params before plan creation)
|
|
77
|
+
storagePreset: z.enum(STORAGE_PRESET_TYPES).optional(),
|
|
78
|
+
// Explicit overrides
|
|
79
|
+
publicReadAccess: z.boolean().optional(),
|
|
80
|
+
websiteHosting: z
|
|
81
|
+
.object({
|
|
82
|
+
indexDocument: z.string(),
|
|
83
|
+
errorDocument: z.string().optional(),
|
|
84
|
+
})
|
|
85
|
+
.strict()
|
|
86
|
+
.optional(),
|
|
87
|
+
// Core
|
|
88
|
+
backupVaultTier: z.enum(BACKUP_VAULT_TIERS).optional(),
|
|
89
|
+
versioned: z.boolean().optional(),
|
|
90
|
+
encryption: z.enum(S3_ENCRYPTION_TYPES).optional(),
|
|
91
|
+
kmsKeyArn: z.string().optional(),
|
|
92
|
+
// CORS
|
|
93
|
+
cors: z
|
|
94
|
+
.array(z
|
|
95
|
+
.object({
|
|
96
|
+
allowedOrigins: z.array(z.string()),
|
|
97
|
+
allowedMethods: z.array(z.string()),
|
|
98
|
+
allowedHeaders: z.array(z.string()).optional(),
|
|
99
|
+
exposedHeaders: z.array(z.string()).optional(),
|
|
100
|
+
maxAge: z.number().optional(),
|
|
101
|
+
})
|
|
102
|
+
.strict())
|
|
103
|
+
.optional(),
|
|
104
|
+
// Connection config (non-interactive mode)
|
|
105
|
+
connectionConfig: z
|
|
106
|
+
.object({
|
|
107
|
+
/** Connect to entire compute resources */
|
|
108
|
+
connectToCompute: z.array(z.string()).optional(),
|
|
109
|
+
/** Connect to specific ECS services (format: "ClusterName/ServiceName") */
|
|
110
|
+
connectToServices: z.array(z.string()).optional(),
|
|
111
|
+
})
|
|
112
|
+
.strict()
|
|
113
|
+
.optional(),
|
|
114
|
+
})
|
|
115
|
+
.strict()
|
|
116
|
+
.refine((data) => data.encryption !== "KMS" || !!data.kmsKeyArn, {
|
|
117
|
+
message: VALIDATION_MESSAGES.KMS.KEY_REQUIRED,
|
|
118
|
+
path: ["kmsKeyArn"],
|
|
119
|
+
});
|
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
export declare function getErrorMessage(error: unknown): string;
|
|
1
|
+
export { normaliseError, getErrorMessage, hasErrorCode, getErrorCode, getErrorStack, formatErrorString, } from "@fjall/util";
|
|
@@ -1,15 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
return error instanceof Error ? error : new Error(String(error));
|
|
3
|
-
}
|
|
4
|
-
export function getErrorMessage(error) {
|
|
5
|
-
if (error instanceof Error) {
|
|
6
|
-
return error.message;
|
|
7
|
-
}
|
|
8
|
-
if (typeof error === "string") {
|
|
9
|
-
return error;
|
|
10
|
-
}
|
|
11
|
-
if (error && typeof error === "object" && "message" in error) {
|
|
12
|
-
return String(error.message);
|
|
13
|
-
}
|
|
14
|
-
return "An unknown error occurred";
|
|
15
|
-
}
|
|
1
|
+
export { normaliseError, getErrorMessage, hasErrorCode, getErrorCode, getErrorStack, formatErrorString, } from "@fjall/util";
|
|
@@ -104,6 +104,15 @@ export declare const VALIDATION_MESSAGES: Readonly<{
|
|
|
104
104
|
readonly MIN: "Desired count must be at least 0";
|
|
105
105
|
readonly MAX: "Desired count cannot exceed 100";
|
|
106
106
|
};
|
|
107
|
+
readonly WARM_POOL_REQUIRED: "minCapacity 0 requires a warmPool — without it, new tasks wait 60-90s for a cold instance launch";
|
|
108
|
+
readonly WARM_POOL: {
|
|
109
|
+
readonly MIN_SIZE: {
|
|
110
|
+
readonly INTEGER: "Warm pool minSize must be an integer";
|
|
111
|
+
readonly MIN: "Warm pool minSize must be at least 0";
|
|
112
|
+
readonly MAX: "Warm pool minSize cannot exceed 100";
|
|
113
|
+
};
|
|
114
|
+
readonly MIN_SIZE_EXCEEDS_MAX_CAPACITY: "warmPool.minSize cannot exceed maxCapacity — the warm pool cannot hold more instances than the ASG allows";
|
|
115
|
+
};
|
|
107
116
|
};
|
|
108
117
|
readonly MEMORY_LIMIT: {
|
|
109
118
|
readonly INTEGER: "Memory limit must be an integer";
|
|
@@ -133,6 +133,15 @@ export const VALIDATION_MESSAGES = Object.freeze({
|
|
|
133
133
|
MIN: "Desired count must be at least 0",
|
|
134
134
|
MAX: "Desired count cannot exceed 100",
|
|
135
135
|
},
|
|
136
|
+
WARM_POOL_REQUIRED: "minCapacity 0 requires a warmPool — without it, new tasks wait 60-90s for a cold instance launch",
|
|
137
|
+
WARM_POOL: {
|
|
138
|
+
MIN_SIZE: {
|
|
139
|
+
INTEGER: "Warm pool minSize must be an integer",
|
|
140
|
+
MIN: "Warm pool minSize must be at least 0",
|
|
141
|
+
MAX: "Warm pool minSize cannot exceed 100",
|
|
142
|
+
},
|
|
143
|
+
MIN_SIZE_EXCEEDS_MAX_CAPACITY: "warmPool.minSize cannot exceed maxCapacity — the warm pool cannot hold more instances than the ASG allows",
|
|
144
|
+
},
|
|
136
145
|
},
|
|
137
146
|
// Memory limit validation messages (ECS)
|
|
138
147
|
MEMORY_LIMIT: {
|
package/dist/src/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const GENERATOR_VERSION = "0.
|
|
1
|
+
export declare const GENERATOR_VERSION = "0.89.3";
|
package/dist/src/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const GENERATOR_VERSION = "0.
|
|
1
|
+
export const GENERATOR_VERSION = "0.89.3";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fjall/generator",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.89.4",
|
|
4
4
|
"description": "Pure infrastructure generation logic for Fjall",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/src/index.js",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"scripts": {
|
|
12
12
|
"clean": "rm -rf ./dist",
|
|
13
13
|
"build": "npm run clean && tsc",
|
|
14
|
+
"watch": "npm run build && tsc --watch --preserveWatchOutput",
|
|
14
15
|
"typecheck": "tsc --noEmit",
|
|
15
16
|
"test": "vitest run",
|
|
16
17
|
"test:watch": "vitest",
|
|
@@ -20,13 +21,14 @@
|
|
|
20
21
|
"engines": {
|
|
21
22
|
"node": ">=18.0.0"
|
|
22
23
|
},
|
|
23
|
-
"license": "
|
|
24
|
+
"license": "MIT",
|
|
24
25
|
"dependencies": {
|
|
26
|
+
"@fjall/util": "^0.89.4",
|
|
25
27
|
"typescript": "^5.8.2",
|
|
26
28
|
"zod": "^4.0.14"
|
|
27
29
|
},
|
|
28
30
|
"devDependencies": {
|
|
29
31
|
"vitest": "^3.2.3"
|
|
30
32
|
},
|
|
31
|
-
"gitHead": "
|
|
33
|
+
"gitHead": "6b2b2d2082b8c07174f4091202cd5bd9862f5556"
|
|
32
34
|
}
|