@fjall/generator 0.88.4 → 0.89.2

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 (73) hide show
  1. package/LICENSE +21 -0
  2. package/dist/src/ast/astCdnParser.d.ts +15 -0
  3. package/dist/src/ast/astCdnParser.js +114 -0
  4. package/dist/src/ast/astCommonParser.d.ts +90 -0
  5. package/dist/src/ast/astCommonParser.js +351 -0
  6. package/dist/src/ast/astComputeParser.d.ts +14 -2
  7. package/dist/src/ast/astComputeParser.js +55 -9
  8. package/dist/src/ast/astDatabaseParser.d.ts +104 -0
  9. package/dist/src/ast/astDatabaseParser.js +275 -0
  10. package/dist/src/ast/astInfrastructureParser.d.ts +23 -277
  11. package/dist/src/ast/astInfrastructureParser.js +83 -1456
  12. package/dist/src/ast/astMessagingParser.d.ts +25 -0
  13. package/dist/src/ast/astMessagingParser.js +78 -0
  14. package/dist/src/ast/astNetworkParser.d.ts +70 -0
  15. package/dist/src/ast/astNetworkParser.js +219 -0
  16. package/dist/src/ast/astPatternParser.d.ts +80 -0
  17. package/dist/src/ast/astPatternParser.js +155 -0
  18. package/dist/src/ast/astStorageParser.d.ts +18 -0
  19. package/dist/src/ast/astStorageParser.js +164 -0
  20. package/dist/src/ast/index.d.ts +1 -0
  21. package/dist/src/ast/index.js +4 -0
  22. package/dist/src/dns/bindParser.d.ts +13 -0
  23. package/dist/src/dns/bindParser.js +224 -0
  24. package/dist/src/dns/bindWriter.d.ts +2 -0
  25. package/dist/src/dns/bindWriter.js +52 -0
  26. package/dist/src/dns/index.d.ts +4 -0
  27. package/dist/src/dns/index.js +4 -0
  28. package/dist/src/dns/infrastructureWriter.d.ts +2 -0
  29. package/dist/src/dns/infrastructureWriter.js +58 -0
  30. package/dist/src/dns/types.d.ts +82 -0
  31. package/dist/src/dns/types.js +52 -0
  32. package/dist/src/generation/common.d.ts +1 -16
  33. package/dist/src/generation/common.js +2 -28
  34. package/dist/src/generation/compute.js +77 -28
  35. package/dist/src/generation/index.d.ts +2 -1
  36. package/dist/src/generation/index.js +3 -1
  37. package/dist/src/generation/messagingConnections.d.ts +33 -0
  38. package/dist/src/generation/messagingConnections.js +73 -0
  39. package/dist/src/generation/storage.d.ts +5 -1
  40. package/dist/src/generation/storage.js +9 -1
  41. package/dist/src/generation/storageConnections.d.ts +3 -3
  42. package/dist/src/generation/storageConnections.js +8 -4
  43. package/dist/src/index.d.ts +1 -0
  44. package/dist/src/index.js +2 -0
  45. package/dist/src/planning/resourcePlanning.js +0 -2
  46. package/dist/src/presets/tierTypes.d.ts +4 -1
  47. package/dist/src/schemas/applicationSchemas.d.ts +854 -0
  48. package/dist/src/schemas/applicationSchemas.js +80 -0
  49. package/dist/src/schemas/baseSchemas.d.ts +206 -0
  50. package/dist/src/schemas/baseSchemas.js +248 -0
  51. package/dist/src/schemas/cdnSchemas.d.ts +61 -0
  52. package/dist/src/schemas/cdnSchemas.js +62 -0
  53. package/dist/src/schemas/computeSchemas.d.ts +723 -0
  54. package/dist/src/schemas/computeSchemas.js +727 -0
  55. package/dist/src/schemas/constants.d.ts +12 -8
  56. package/dist/src/schemas/constants.js +14 -4
  57. package/dist/src/schemas/databaseSchemas.d.ts +638 -0
  58. package/dist/src/schemas/databaseSchemas.js +366 -0
  59. package/dist/src/schemas/messagingSchemas.d.ts +20 -0
  60. package/dist/src/schemas/messagingSchemas.js +29 -0
  61. package/dist/src/schemas/networkSchemas.d.ts +246 -0
  62. package/dist/src/schemas/networkSchemas.js +125 -0
  63. package/dist/src/schemas/patternSchemas.d.ts +708 -0
  64. package/dist/src/schemas/patternSchemas.js +294 -0
  65. package/dist/src/schemas/resourceSchemas.d.ts +24 -3530
  66. package/dist/src/schemas/resourceSchemas.js +24 -2011
  67. package/dist/src/schemas/storageSchemas.d.ts +93 -0
  68. package/dist/src/schemas/storageSchemas.js +119 -0
  69. package/dist/src/util/errorUtils.d.ts +1 -2
  70. package/dist/src/util/errorUtils.js +1 -15
  71. package/dist/src/validation/patterns.d.ts +9 -0
  72. package/dist/src/validation/patterns.js +9 -0
  73. package/package.json +4 -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 declare function normaliseError(error: unknown): Error;
2
- export declare function getErrorMessage(error: unknown): string;
1
+ export { normaliseError, getErrorMessage, hasErrorCode, getErrorCode, getErrorStack, formatErrorString, } from "@fjall/util";
@@ -1,15 +1 @@
1
- export function normaliseError(error) {
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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fjall/generator",
3
- "version": "0.88.4",
3
+ "version": "0.89.2",
4
4
  "description": "Pure infrastructure generation logic for Fjall",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",
@@ -20,13 +20,14 @@
20
20
  "engines": {
21
21
  "node": ">=18.0.0"
22
22
  },
23
- "license": "ISC",
23
+ "license": "MIT",
24
24
  "dependencies": {
25
+ "@fjall/util": "^0.89.2",
25
26
  "typescript": "^5.8.2",
26
27
  "zod": "^4.0.14"
27
28
  },
28
29
  "devDependencies": {
29
30
  "vitest": "^3.2.3"
30
31
  },
31
- "gitHead": "bae02efe8e447ef008c7bc3eef3398ded4872f42"
32
+ "gitHead": "5bb039ff669fbe96d656ae1467e9986cf4327e92"
32
33
  }