@fjall/util 0.95.0 → 0.99.1

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 (78) hide show
  1. package/dist/.minified +1 -1
  2. package/dist/Config.d.ts +1 -1
  3. package/dist/appPath.d.ts +29 -0
  4. package/dist/appPath.js +1 -0
  5. package/dist/caseConversion.d.ts +6 -0
  6. package/dist/caseConversion.js +1 -1
  7. package/dist/constructMap.d.ts +9 -13
  8. package/dist/constructMap.js +1 -1
  9. package/dist/deriveContentHashTag.d.ts +34 -0
  10. package/dist/deriveContentHashTag.js +1 -0
  11. package/dist/docker/DockerCli.build.d.ts +42 -0
  12. package/dist/docker/DockerCli.build.js +1 -0
  13. package/dist/docker/DockerCli.d.ts +135 -0
  14. package/dist/docker/DockerCli.daemon.d.ts +24 -0
  15. package/dist/docker/DockerCli.daemon.js +1 -0
  16. package/dist/docker/DockerCli.js +1 -0
  17. package/dist/docker/DockerCli.registry.d.ts +19 -0
  18. package/dist/docker/DockerCli.registry.js +3 -0
  19. package/dist/docker/abortHelpers.d.ts +18 -0
  20. package/dist/docker/abortHelpers.js +1 -0
  21. package/dist/docker/buildxArgvBuilder.d.ts +15 -0
  22. package/dist/docker/buildxArgvBuilder.js +1 -0
  23. package/dist/docker/dockerCliConstants.d.ts +15 -0
  24. package/dist/docker/dockerCliConstants.js +1 -0
  25. package/dist/docker/dockerCliSchemas.d.ts +88 -0
  26. package/dist/docker/dockerCliSchemas.js +1 -0
  27. package/dist/docker/index.d.ts +10 -0
  28. package/dist/docker/index.js +1 -0
  29. package/dist/docker/metadataFileParser.d.ts +17 -0
  30. package/dist/docker/metadataFileParser.js +1 -0
  31. package/dist/docker/projectBuildxResult.d.ts +35 -0
  32. package/dist/docker/projectBuildxResult.js +1 -0
  33. package/dist/docker/rawjsonParser.d.ts +56 -0
  34. package/dist/docker/rawjsonParser.js +1 -0
  35. package/dist/docker/rawjsonToVertexEvent.d.ts +64 -0
  36. package/dist/docker/rawjsonToVertexEvent.js +1 -0
  37. package/dist/docker/result.d.ts +34 -0
  38. package/dist/docker/result.js +1 -0
  39. package/dist/errorUtils.d.ts +14 -4
  40. package/dist/findInfrastructurePaths.d.ts +62 -0
  41. package/dist/findInfrastructurePaths.js +1 -0
  42. package/dist/findRepoRoot.d.ts +12 -0
  43. package/dist/findRepoRoot.js +1 -0
  44. package/dist/fsHelpers.d.ts +15 -0
  45. package/dist/fsHelpers.js +1 -1
  46. package/dist/fsScan.d.ts +15 -0
  47. package/dist/fsScan.js +1 -0
  48. package/dist/index.d.ts +9 -1
  49. package/dist/index.js +1 -1
  50. package/dist/inferContainerFromCandidates.d.ts +23 -0
  51. package/dist/inferContainerFromCandidates.js +1 -0
  52. package/dist/manifest/index.d.ts +10 -0
  53. package/dist/manifest/index.js +1 -0
  54. package/dist/manifest/io.d.ts +60 -0
  55. package/dist/manifest/io.js +1 -0
  56. package/dist/manifest/schemas.d.ts +163 -0
  57. package/dist/manifest/schemas.js +1 -0
  58. package/dist/mcpProtocol/index.d.ts +362 -0
  59. package/dist/mcpProtocol/index.js +1 -0
  60. package/dist/migration/clickhouseSqlUsers.d.ts +69 -0
  61. package/dist/migration/clickhouseSqlUsers.js +1 -0
  62. package/dist/migration/constants.d.ts +34 -0
  63. package/dist/migration/constants.js +1 -0
  64. package/dist/migration/index.d.ts +3 -0
  65. package/dist/migration/index.js +1 -0
  66. package/dist/migration/pickLatestPrismaMigration.d.ts +10 -0
  67. package/dist/migration/pickLatestPrismaMigration.js +1 -0
  68. package/dist/reservedAppNames.d.ts +30 -0
  69. package/dist/reservedAppNames.js +1 -0
  70. package/dist/scanLocalRepository.d.ts +24 -0
  71. package/dist/scanLocalRepository.js +1 -0
  72. package/dist/scanTypes.d.ts +17 -0
  73. package/dist/scanTypes.js +0 -0
  74. package/dist/securityHelpers.d.ts +11 -1
  75. package/dist/securityHelpers.js +1 -1
  76. package/dist/tokenScopes.d.ts +11 -0
  77. package/dist/tokenScopes.js +1 -0
  78. package/package.json +43 -9
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Pure Zod schemas for the Fjall build-time manifest.
3
+ *
4
+ * This module is the canonical, environment-agnostic source of truth for:
5
+ * - DockerBuild — the universal `{ path, context?, target? }` primitive
6
+ * consumed by every container-image-producing role (service today,
7
+ * migrations next, future sidecars and batch jobs).
8
+ * - DockerBuildPartial — the all-optional variant used by `migrations.docker`
9
+ * for per-field inheritance from the parent service.
10
+ * - mergeDockerBuild() — single source of truth for the merge semantics
11
+ * (target-only override, full override, no override → inherit).
12
+ * - The full Fjall manifest schema (services, lambdas, pattern, ecr,
13
+ * stacks, resourceMap).
14
+ *
15
+ * Purity: this module imports only `zod`. No `fs`, no `path`, no logger.
16
+ * That lets the generator (which is forbidden from doing I/O) consume
17
+ * docker-shape types without dragging Node-only modules into the cloud
18
+ * assembly. I/O helpers live in the sibling `./io` module.
19
+ */
20
+ import { z } from "zod";
21
+ /** Manifest file name — single source of truth across CLI, deploy-core, and infrastructure. */
22
+ export declare const FJALL_MANIFEST_FILENAME = "fjall-manifest.json";
23
+ /** Current manifest schema version. */
24
+ export declare const MANIFEST_SCHEMA_VERSION: 1;
25
+ /**
26
+ * The universal Docker-build role primitive.
27
+ *
28
+ * `path` is the Dockerfile path (absolute or relative to `context`); `context`
29
+ * is the build context (defaults to the directory containing `path` when
30
+ * absent — that default lives in the build orchestrator, not in the schema);
31
+ * `target` selects a multi-stage Dockerfile target; `buildArgs` are forwarded
32
+ * to `docker buildx build --build-arg KEY=VALUE` and are the only mechanism
33
+ * by which Vite-style `import.meta.env.VITE_*` variables can be baked into
34
+ * the production client bundle (the substitution happens at build time, not
35
+ * runtime, so container ENV vars cannot reach the client).
36
+ */
37
+ export declare const DockerBuildSchema: z.ZodObject<{
38
+ path: z.ZodString;
39
+ context: z.ZodOptional<z.ZodString>;
40
+ target: z.ZodOptional<z.ZodString>;
41
+ buildArgs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
42
+ }, z.core.$strict>;
43
+ export type DockerBuild = z.infer<typeof DockerBuildSchema>;
44
+ /**
45
+ * All-optional variant used by `migrations.docker` for per-field inheritance.
46
+ *
47
+ * Every field is optional; missing fields inherit from the parent service's
48
+ * `docker` via `mergeDockerBuild()`. A migrations override of just
49
+ * `{ target: "migrate" }` keeps the service's `path` and `context`.
50
+ */
51
+ export declare const DockerBuildPartialSchema: z.ZodObject<{
52
+ path: z.ZodOptional<z.ZodString>;
53
+ context: z.ZodOptional<z.ZodOptional<z.ZodString>>;
54
+ target: z.ZodOptional<z.ZodOptional<z.ZodString>>;
55
+ buildArgs: z.ZodOptional<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
56
+ }, z.core.$strict>;
57
+ export type DockerBuildPartial = z.infer<typeof DockerBuildPartialSchema>;
58
+ /**
59
+ * Per-field merge of a service's `docker` and an optional migrations override.
60
+ *
61
+ * - When `migrationsOverride` is undefined, the service's docker is returned unchanged.
62
+ * - When set, each field on the override wins; missing fields inherit from the service.
63
+ * - The result preserves the structural mutex with `image` because callers only
64
+ * invoke this when they have a service-side `docker` to merge against.
65
+ */
66
+ export declare function mergeDockerBuild(service: DockerBuild, migrationsOverride: DockerBuildPartial | undefined): DockerBuild;
67
+ declare const ManifestServiceSchema: z.ZodObject<{
68
+ name: z.ZodString;
69
+ clusterName: z.ZodOptional<z.ZodString>;
70
+ docker: z.ZodOptional<z.ZodObject<{
71
+ path: z.ZodString;
72
+ context: z.ZodOptional<z.ZodString>;
73
+ target: z.ZodOptional<z.ZodString>;
74
+ buildArgs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
75
+ }, z.core.$strict>>;
76
+ containerPort: z.ZodOptional<z.ZodNumber>;
77
+ secrets: z.ZodOptional<z.ZodArray<z.ZodString>>;
78
+ ssmSecretsPath: z.ZodOptional<z.ZodString>;
79
+ }, z.core.$strict>;
80
+ export type ManifestService = z.infer<typeof ManifestServiceSchema>;
81
+ declare const ManifestPatternSchema: z.ZodObject<{
82
+ type: z.ZodEnum<{
83
+ payload: "payload";
84
+ }>;
85
+ name: z.ZodString;
86
+ source: z.ZodString;
87
+ }, z.core.$strict>;
88
+ export type ManifestPattern = z.infer<typeof ManifestPatternSchema>;
89
+ declare const ManifestEcrSchema: z.ZodObject<{
90
+ repositoryName: z.ZodString;
91
+ }, z.core.$strict>;
92
+ export type ManifestEcr = z.infer<typeof ManifestEcrSchema>;
93
+ declare const ManifestLambdaSchema: z.ZodObject<{
94
+ name: z.ZodString;
95
+ secrets: z.ZodOptional<z.ZodArray<z.ZodString>>;
96
+ ssmSecretsPath: z.ZodOptional<z.ZodString>;
97
+ }, z.core.$strict>;
98
+ export type ManifestLambda = z.infer<typeof ManifestLambdaSchema>;
99
+ declare const ManifestStackHashSchema: z.ZodObject<{
100
+ templateHash: z.ZodString;
101
+ synthTimestamp: z.ZodString;
102
+ }, z.core.$strict>;
103
+ export type ManifestStackHash = z.infer<typeof ManifestStackHashSchema>;
104
+ /**
105
+ * Construct-map entry shape — duplicated structurally with `ResourceMapEntry`
106
+ * in `../constructMap.ts`. The two shapes must stay in lockstep; the canonical
107
+ * runtime type is the schema-inferred form here, and `recordToConstructMap()`
108
+ * produces a Map<string, ResourceMapEntry> that is structurally compatible.
109
+ */
110
+ declare const ResourceMapEntrySchema: z.ZodObject<{
111
+ constructPath: z.ZodString;
112
+ group: z.ZodString;
113
+ resourceType: z.ZodString;
114
+ }, z.core.$strict>;
115
+ export type ResourceMapEntry = z.infer<typeof ResourceMapEntrySchema>;
116
+ /**
117
+ * Fjall manifest schema — generated during CDK synth.
118
+ * Location: `<cdk.out>/fjall-manifest.json`.
119
+ */
120
+ export declare const FjallManifestSchema: z.ZodObject<{
121
+ version: z.ZodLiteral<1>;
122
+ generatedAt: z.ZodString;
123
+ appName: z.ZodString;
124
+ services: z.ZodArray<z.ZodObject<{
125
+ name: z.ZodString;
126
+ clusterName: z.ZodOptional<z.ZodString>;
127
+ docker: z.ZodOptional<z.ZodObject<{
128
+ path: z.ZodString;
129
+ context: z.ZodOptional<z.ZodString>;
130
+ target: z.ZodOptional<z.ZodString>;
131
+ buildArgs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
132
+ }, z.core.$strict>>;
133
+ containerPort: z.ZodOptional<z.ZodNumber>;
134
+ secrets: z.ZodOptional<z.ZodArray<z.ZodString>>;
135
+ ssmSecretsPath: z.ZodOptional<z.ZodString>;
136
+ }, z.core.$strict>>;
137
+ lambdas: z.ZodArray<z.ZodObject<{
138
+ name: z.ZodString;
139
+ secrets: z.ZodOptional<z.ZodArray<z.ZodString>>;
140
+ ssmSecretsPath: z.ZodOptional<z.ZodString>;
141
+ }, z.core.$strict>>;
142
+ pattern: z.ZodOptional<z.ZodObject<{
143
+ type: z.ZodEnum<{
144
+ payload: "payload";
145
+ }>;
146
+ name: z.ZodString;
147
+ source: z.ZodString;
148
+ }, z.core.$strict>>;
149
+ ecr: z.ZodOptional<z.ZodObject<{
150
+ repositoryName: z.ZodString;
151
+ }, z.core.$strict>>;
152
+ stacks: z.ZodRecord<z.ZodString, z.ZodObject<{
153
+ templateHash: z.ZodString;
154
+ synthTimestamp: z.ZodString;
155
+ }, z.core.$strict>>;
156
+ resourceMap: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
157
+ constructPath: z.ZodString;
158
+ group: z.ZodString;
159
+ resourceType: z.ZodString;
160
+ }, z.core.$strict>>>;
161
+ }, z.core.$strict>;
162
+ export type FjallManifest = z.infer<typeof FjallManifestSchema>;
163
+ export { ManifestServiceSchema, ManifestPatternSchema, ManifestEcrSchema, ManifestLambdaSchema, ManifestStackHashSchema, ResourceMapEntrySchema };
@@ -0,0 +1 @@
1
+ import{z as t}from"zod";const h="fjall-manifest.json",u=1,s=t.object({path:t.string(),context:t.string().min(1,"context cannot be empty").optional(),target:t.string().min(1,"target cannot be empty").optional(),buildArgs:t.record(t.string(),t.string()).optional()}).strict(),b=s.partial();function S(e,n){if(n===void 0)return e;const r=n.context??e.context,a=n.target??e.target,o=n.buildArgs??e.buildArgs;return{path:n.path??e.path,...r!==void 0&&{context:r},...a!==void 0&&{target:a},...o!==void 0&&{buildArgs:o}}}const c=t.object({name:t.string(),clusterName:t.string().optional(),docker:s.optional(),containerPort:t.number().optional(),secrets:t.array(t.string()).optional(),ssmSecretsPath:t.string().optional()}).strict(),i=t.object({type:t.enum(["payload"]),name:t.string(),source:t.string()}).strict(),p=t.object({repositoryName:t.string()}).strict(),g=t.object({name:t.string(),secrets:t.array(t.string()).optional(),ssmSecretsPath:t.string().optional()}).strict(),m=t.object({templateHash:t.string(),synthTimestamp:t.string()}).strict(),l=t.object({constructPath:t.string().max(512),group:t.string().max(128),resourceType:t.string().max(256)}).strict(),x=t.object({version:t.literal(u),generatedAt:t.string(),appName:t.string(),services:t.array(c),lambdas:t.array(g),pattern:i.optional(),ecr:p.optional(),stacks:t.record(t.string(),m),resourceMap:t.record(t.string(),l).optional()}).strict();export{b as DockerBuildPartialSchema,s as DockerBuildSchema,h as FJALL_MANIFEST_FILENAME,x as FjallManifestSchema,u as MANIFEST_SCHEMA_VERSION,p as ManifestEcrSchema,g as ManifestLambdaSchema,i as ManifestPatternSchema,c as ManifestServiceSchema,m as ManifestStackHashSchema,l as ResourceMapEntrySchema,S as mergeDockerBuild};
@@ -0,0 +1,362 @@
1
+ import { z } from "zod";
2
+ export declare const MCP_PROTOCOL_VERSION: 2;
3
+ /**
4
+ * Wire-format error codes emitted by `kind: "error"` frames.
5
+ * The CLI emitter and MCP consumer pattern-match on these strings —
6
+ * the codes ARE the contract.
7
+ */
8
+ export declare const MCP_ERROR_CODES: {
9
+ readonly AUTHENTICATION_REQUIRED: "AUTHENTICATION_REQUIRED";
10
+ readonly VALIDATION_ERROR: "VALIDATION_ERROR";
11
+ readonly INTERNAL_ERROR: "INTERNAL_ERROR";
12
+ readonly INVALID_SUBCOMMAND: "INVALID_SUBCOMMAND";
13
+ readonly INVALID_FRAME: "INVALID_FRAME";
14
+ };
15
+ export type McpErrorCode = (typeof MCP_ERROR_CODES)[keyof typeof MCP_ERROR_CODES];
16
+ /** Maximum length of a free-form `intent` string carried on scaffold inputs. */
17
+ export declare const INTENT_MAX_LENGTH = 1000;
18
+ declare const stepStatusSchema: z.ZodEnum<{
19
+ error: "error";
20
+ completed: "completed";
21
+ skipped: "skipped";
22
+ }>;
23
+ export type McpStepStatus = z.infer<typeof stepStatusSchema>;
24
+ export declare const StepStartFrameSchema: z.ZodObject<{
25
+ v: z.ZodLiteral<2>;
26
+ kind: z.ZodLiteral<"step.start">;
27
+ stepId: z.ZodString;
28
+ name: z.ZodString;
29
+ index: z.ZodNumber;
30
+ total: z.ZodNumber;
31
+ }, z.core.$strict>;
32
+ export type StepStartFrame = z.infer<typeof StepStartFrameSchema>;
33
+ export declare const StepCompleteFrameSchema: z.ZodObject<{
34
+ v: z.ZodLiteral<2>;
35
+ kind: z.ZodLiteral<"step.complete">;
36
+ stepId: z.ZodString;
37
+ name: z.ZodString;
38
+ status: z.ZodEnum<{
39
+ error: "error";
40
+ completed: "completed";
41
+ skipped: "skipped";
42
+ }>;
43
+ index: z.ZodNumber;
44
+ total: z.ZodNumber;
45
+ errorMessage: z.ZodOptional<z.ZodString>;
46
+ }, z.core.$strict>;
47
+ export type StepCompleteFrame = z.infer<typeof StepCompleteFrameSchema>;
48
+ export declare const WarningFrameSchema: z.ZodObject<{
49
+ v: z.ZodLiteral<2>;
50
+ kind: z.ZodLiteral<"warning">;
51
+ message: z.ZodString;
52
+ }, z.core.$strict>;
53
+ export type WarningFrame = z.infer<typeof WarningFrameSchema>;
54
+ declare const errorPayloadSchema: z.ZodObject<{
55
+ code: z.ZodString;
56
+ message: z.ZodString;
57
+ details: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
58
+ }, z.core.$strict>;
59
+ export type McpErrorPayload = z.infer<typeof errorPayloadSchema>;
60
+ export declare const ErrorFrameSchema: z.ZodObject<{
61
+ v: z.ZodLiteral<2>;
62
+ kind: z.ZodLiteral<"error">;
63
+ error: z.ZodObject<{
64
+ code: z.ZodString;
65
+ message: z.ZodString;
66
+ details: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
67
+ }, z.core.$strict>;
68
+ }, z.core.$strict>;
69
+ export type ErrorFrame = z.infer<typeof ErrorFrameSchema>;
70
+ export declare const ResultFrameSchema: z.ZodObject<{
71
+ v: z.ZodLiteral<2>;
72
+ kind: z.ZodLiteral<"result">;
73
+ data: z.ZodUnknown;
74
+ }, z.core.$strict>;
75
+ export type ResultFrame = z.infer<typeof ResultFrameSchema>;
76
+ export declare const AuthBrowserRequiredFrameSchema: z.ZodObject<{
77
+ v: z.ZodLiteral<2>;
78
+ kind: z.ZodLiteral<"auth.browser.required">;
79
+ url: z.ZodString;
80
+ externalId: z.ZodString;
81
+ region: z.ZodString;
82
+ environment: z.ZodString;
83
+ reason: z.ZodString;
84
+ }, z.core.$strict>;
85
+ export type AuthBrowserRequiredFrame = z.infer<typeof AuthBrowserRequiredFrameSchema>;
86
+ export declare const AuthBrowserCompleteFrameSchema: z.ZodObject<{
87
+ v: z.ZodLiteral<2>;
88
+ kind: z.ZodLiteral<"auth.browser.complete">;
89
+ awsAccountId: z.ZodString;
90
+ accountName: z.ZodString;
91
+ roleArn: z.ZodString;
92
+ }, z.core.$strict>;
93
+ export type AuthBrowserCompleteFrame = z.infer<typeof AuthBrowserCompleteFrameSchema>;
94
+ export declare const McpProtocolFrameSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
95
+ v: z.ZodLiteral<2>;
96
+ kind: z.ZodLiteral<"step.start">;
97
+ stepId: z.ZodString;
98
+ name: z.ZodString;
99
+ index: z.ZodNumber;
100
+ total: z.ZodNumber;
101
+ }, z.core.$strict>, z.ZodObject<{
102
+ v: z.ZodLiteral<2>;
103
+ kind: z.ZodLiteral<"step.complete">;
104
+ stepId: z.ZodString;
105
+ name: z.ZodString;
106
+ status: z.ZodEnum<{
107
+ error: "error";
108
+ completed: "completed";
109
+ skipped: "skipped";
110
+ }>;
111
+ index: z.ZodNumber;
112
+ total: z.ZodNumber;
113
+ errorMessage: z.ZodOptional<z.ZodString>;
114
+ }, z.core.$strict>, z.ZodObject<{
115
+ v: z.ZodLiteral<2>;
116
+ kind: z.ZodLiteral<"warning">;
117
+ message: z.ZodString;
118
+ }, z.core.$strict>, z.ZodObject<{
119
+ v: z.ZodLiteral<2>;
120
+ kind: z.ZodLiteral<"error">;
121
+ error: z.ZodObject<{
122
+ code: z.ZodString;
123
+ message: z.ZodString;
124
+ details: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
125
+ }, z.core.$strict>;
126
+ }, z.core.$strict>, z.ZodObject<{
127
+ v: z.ZodLiteral<2>;
128
+ kind: z.ZodLiteral<"result">;
129
+ data: z.ZodUnknown;
130
+ }, z.core.$strict>, z.ZodObject<{
131
+ v: z.ZodLiteral<2>;
132
+ kind: z.ZodLiteral<"auth.browser.required">;
133
+ url: z.ZodString;
134
+ externalId: z.ZodString;
135
+ region: z.ZodString;
136
+ environment: z.ZodString;
137
+ reason: z.ZodString;
138
+ }, z.core.$strict>, z.ZodObject<{
139
+ v: z.ZodLiteral<2>;
140
+ kind: z.ZodLiteral<"auth.browser.complete">;
141
+ awsAccountId: z.ZodString;
142
+ accountName: z.ZodString;
143
+ roleArn: z.ZodString;
144
+ }, z.core.$strict>], "kind">;
145
+ export type McpProtocolFrame = z.infer<typeof McpProtocolFrameSchema>;
146
+ /**
147
+ * Scaffold protocol schemas — wire types for the `plan_app_scaffold`,
148
+ * `apply_app_scaffold`, and dry-run helper paths in `@fjall/mcp`.
149
+ *
150
+ * The shapes here mirror the CLI-side `DryRunArtefacts` (in
151
+ * `cli/src/operations/types.ts`) by hand because `@fjall/util` is a leaf
152
+ * dependency of the CLI and cannot import from it. Drift between the two
153
+ * is a wire-level bug; both sides MUST move together.
154
+ */
155
+ export declare const FileToWriteSchema: z.ZodObject<{
156
+ path: z.ZodString;
157
+ sizeBytes: z.ZodNumber;
158
+ collisionMode: z.ZodEnum<{
159
+ create: "create";
160
+ overwrite: "overwrite";
161
+ }>;
162
+ }, z.core.$strict>;
163
+ export type ScaffoldFileToWrite = z.infer<typeof FileToWriteSchema>;
164
+ export declare const RegistryActionSchema: z.ZodObject<{
165
+ type: z.ZodEnum<{
166
+ "register-application": "register-application";
167
+ "create-activity": "create-activity";
168
+ "auto-link-repository": "auto-link-repository";
169
+ "writeback-config-path": "writeback-config-path";
170
+ }>;
171
+ description: z.ZodString;
172
+ }, z.core.$strict>;
173
+ export type ScaffoldRegistryAction = z.infer<typeof RegistryActionSchema>;
174
+ export declare const TargetAccountSchema: z.ZodObject<{
175
+ name: z.ZodString;
176
+ environment: z.ZodString;
177
+ source: z.ZodString;
178
+ }, z.core.$strict>;
179
+ export type TargetAccount = z.infer<typeof TargetAccountSchema>;
180
+ export declare const ResolvedInputsSchema: z.ZodObject<{
181
+ name: z.ZodString;
182
+ pattern: z.ZodOptional<z.ZodString>;
183
+ patternTier: z.ZodOptional<z.ZodEnum<{
184
+ tinkerer: "tinkerer";
185
+ lightweight: "lightweight";
186
+ standard: "standard";
187
+ resilient: "resilient";
188
+ enterprise: "enterprise";
189
+ }>>;
190
+ patternDomain: z.ZodOptional<z.ZodString>;
191
+ network: z.ZodOptional<z.ZodEnum<{
192
+ lightweight: "lightweight";
193
+ standard: "standard";
194
+ resilient: "resilient";
195
+ enterprise: "enterprise";
196
+ none: "none";
197
+ }>>;
198
+ template: z.ZodOptional<z.ZodString>;
199
+ docker: z.ZodOptional<z.ZodObject<{
200
+ path: z.ZodOptional<z.ZodString>;
201
+ context: z.ZodOptional<z.ZodString>;
202
+ target: z.ZodOptional<z.ZodString>;
203
+ }, z.core.$strict>>;
204
+ git: z.ZodOptional<z.ZodBoolean>;
205
+ github: z.ZodOptional<z.ZodBoolean>;
206
+ repoVisibility: z.ZodOptional<z.ZodEnum<{
207
+ private: "private";
208
+ public: "public";
209
+ }>>;
210
+ intent: z.ZodOptional<z.ZodString>;
211
+ }, z.core.$strict>;
212
+ export type ResolvedInputs = z.infer<typeof ResolvedInputsSchema>;
213
+ export declare const ScaffoldPlanSchema: z.ZodObject<{
214
+ planId: z.ZodString;
215
+ normalisedPath: z.ZodString;
216
+ resolvedInputs: z.ZodObject<{
217
+ name: z.ZodString;
218
+ pattern: z.ZodOptional<z.ZodString>;
219
+ patternTier: z.ZodOptional<z.ZodEnum<{
220
+ tinkerer: "tinkerer";
221
+ lightweight: "lightweight";
222
+ standard: "standard";
223
+ resilient: "resilient";
224
+ enterprise: "enterprise";
225
+ }>>;
226
+ patternDomain: z.ZodOptional<z.ZodString>;
227
+ network: z.ZodOptional<z.ZodEnum<{
228
+ lightweight: "lightweight";
229
+ standard: "standard";
230
+ resilient: "resilient";
231
+ enterprise: "enterprise";
232
+ none: "none";
233
+ }>>;
234
+ template: z.ZodOptional<z.ZodString>;
235
+ docker: z.ZodOptional<z.ZodObject<{
236
+ path: z.ZodOptional<z.ZodString>;
237
+ context: z.ZodOptional<z.ZodString>;
238
+ target: z.ZodOptional<z.ZodString>;
239
+ }, z.core.$strict>>;
240
+ git: z.ZodOptional<z.ZodBoolean>;
241
+ github: z.ZodOptional<z.ZodBoolean>;
242
+ repoVisibility: z.ZodOptional<z.ZodEnum<{
243
+ private: "private";
244
+ public: "public";
245
+ }>>;
246
+ intent: z.ZodOptional<z.ZodString>;
247
+ }, z.core.$strict>;
248
+ targetAccount: z.ZodNullable<z.ZodObject<{
249
+ name: z.ZodString;
250
+ environment: z.ZodString;
251
+ source: z.ZodString;
252
+ }, z.core.$strict>>;
253
+ targetAccountCandidates: z.ZodArray<z.ZodObject<{
254
+ name: z.ZodString;
255
+ environment: z.ZodString;
256
+ source: z.ZodString;
257
+ }, z.core.$strict>>;
258
+ filesToWrite: z.ZodArray<z.ZodObject<{
259
+ path: z.ZodString;
260
+ sizeBytes: z.ZodNumber;
261
+ collisionMode: z.ZodEnum<{
262
+ create: "create";
263
+ overwrite: "overwrite";
264
+ }>;
265
+ }, z.core.$strict>>;
266
+ npmPackages: z.ZodArray<z.ZodString>;
267
+ registryActions: z.ZodArray<z.ZodObject<{
268
+ type: z.ZodEnum<{
269
+ "register-application": "register-application";
270
+ "create-activity": "create-activity";
271
+ "auto-link-repository": "auto-link-repository";
272
+ "writeback-config-path": "writeback-config-path";
273
+ }>;
274
+ description: z.ZodString;
275
+ }, z.core.$strict>>;
276
+ patternUnsupportedForDryRun: z.ZodOptional<z.ZodBoolean>;
277
+ intent: z.ZodOptional<z.ZodString>;
278
+ framework: z.ZodOptional<z.ZodString>;
279
+ summary: z.ZodString;
280
+ }, z.core.$strict>;
281
+ export type ScaffoldPlan = z.infer<typeof ScaffoldPlanSchema>;
282
+ export declare const DryRunArtefactsSchema: z.ZodObject<{
283
+ filesToWrite: z.ZodArray<z.ZodObject<{
284
+ path: z.ZodString;
285
+ sizeBytes: z.ZodNumber;
286
+ collisionMode: z.ZodEnum<{
287
+ create: "create";
288
+ overwrite: "overwrite";
289
+ }>;
290
+ }, z.core.$strict>>;
291
+ npmPackages: z.ZodArray<z.ZodString>;
292
+ registryActions: z.ZodArray<z.ZodObject<{
293
+ type: z.ZodEnum<{
294
+ "register-application": "register-application";
295
+ "create-activity": "create-activity";
296
+ "auto-link-repository": "auto-link-repository";
297
+ "writeback-config-path": "writeback-config-path";
298
+ }>;
299
+ description: z.ZodString;
300
+ }, z.core.$strict>>;
301
+ patternUnsupportedForDryRun: z.ZodOptional<z.ZodBoolean>;
302
+ }, z.core.$strict>;
303
+ export type ScaffoldDryRunArtefacts = z.infer<typeof DryRunArtefactsSchema>;
304
+ export declare const ScaffoldResultDataSchema: z.ZodObject<{
305
+ path: z.ZodString;
306
+ name: z.ZodString;
307
+ mode: z.ZodEnum<{
308
+ pattern: "pattern";
309
+ application: "application";
310
+ }>;
311
+ dependenciesInstalled: z.ZodOptional<z.ZodBoolean>;
312
+ warning: z.ZodOptional<z.ZodString>;
313
+ dryRunArtefacts: z.ZodOptional<z.ZodObject<{
314
+ filesToWrite: z.ZodArray<z.ZodObject<{
315
+ path: z.ZodString;
316
+ sizeBytes: z.ZodNumber;
317
+ collisionMode: z.ZodEnum<{
318
+ create: "create";
319
+ overwrite: "overwrite";
320
+ }>;
321
+ }, z.core.$strict>>;
322
+ npmPackages: z.ZodArray<z.ZodString>;
323
+ registryActions: z.ZodArray<z.ZodObject<{
324
+ type: z.ZodEnum<{
325
+ "register-application": "register-application";
326
+ "create-activity": "create-activity";
327
+ "auto-link-repository": "auto-link-repository";
328
+ "writeback-config-path": "writeback-config-path";
329
+ }>;
330
+ description: z.ZodString;
331
+ }, z.core.$strict>>;
332
+ patternUnsupportedForDryRun: z.ZodOptional<z.ZodBoolean>;
333
+ }, z.core.$strict>>;
334
+ }, z.core.$strict>;
335
+ export type ScaffoldResultData = z.infer<typeof ScaffoldResultDataSchema>;
336
+ /**
337
+ * Progress frame emitted via MCP `notifications/progress` during
338
+ * `apply_app_scaffold`. `total` is omitted for unbounded streams (warnings).
339
+ */
340
+ export declare const ScaffoldProgressFrameSchema: z.ZodObject<{
341
+ step: z.ZodString;
342
+ current: z.ZodNumber;
343
+ total: z.ZodOptional<z.ZodNumber>;
344
+ message: z.ZodString;
345
+ }, z.core.$strict>;
346
+ export type ScaffoldProgressFrame = z.infer<typeof ScaffoldProgressFrameSchema>;
347
+ export type ParseFrameResult = {
348
+ ok: true;
349
+ frame: McpProtocolFrame;
350
+ } | {
351
+ ok: false;
352
+ reason: "json";
353
+ raw: string;
354
+ error: string;
355
+ } | {
356
+ ok: false;
357
+ reason: "schema";
358
+ raw: string;
359
+ error: string;
360
+ };
361
+ export declare function parseFrame(line: string): ParseFrameResult;
362
+ export {};
@@ -0,0 +1 @@
1
+ import{z as t}from"zod";const p=2,f={AUTHENTICATION_REQUIRED:"AUTHENTICATION_REQUIRED",VALIDATION_ERROR:"VALIDATION_ERROR",INTERNAL_ERROR:"INTERNAL_ERROR",INVALID_SUBCOMMAND:"INVALID_SUBCOMMAND",INVALID_FRAME:"INVALID_FRAME"},a=1e3,e=t.literal(p),l=t.enum(["completed","error","skipped"]),g=t.object({v:e,kind:t.literal("step.start"),stepId:t.string().min(1),name:t.string().min(1),index:t.number().int().min(0),total:t.number().int().min(1)}).strict(),u=t.object({v:e,kind:t.literal("step.complete"),stepId:t.string().min(1),name:t.string().min(1),status:l,index:t.number().int().min(0),total:t.number().int().min(1),errorMessage:t.string().optional()}).strict(),d=t.object({v:e,kind:t.literal("warning"),message:t.string().min(1)}).strict(),b=t.object({code:t.string().min(1),message:t.string().min(1),details:t.record(t.string(),t.unknown()).optional()}).strict(),h=t.object({v:e,kind:t.literal("error"),error:b}).strict(),R=t.object({v:e,kind:t.literal("result"),data:t.unknown()}).strict(),A=t.object({v:e,kind:t.literal("auth.browser.required"),url:t.string().url(),externalId:t.string().min(1),region:t.string().min(1),environment:t.string().min(1),reason:t.string().min(1)}).strict(),S=t.object({v:e,kind:t.literal("auth.browser.complete"),awsAccountId:t.string().min(1),accountName:t.string().min(1),roleArn:t.string().min(1)}).strict(),I=t.discriminatedUnion("kind",[g,u,d,h,R,A,S]),s=t.object({path:t.string().min(1),sizeBytes:t.number().int().nonnegative(),collisionMode:t.enum(["create","overwrite"])}).strict(),c=t.object({type:t.enum(["register-application","create-activity","auto-link-repository","writeback-config-path"]),description:t.string().min(1)}).strict(),x=t.enum(["tinkerer","lightweight","standard","resilient","enterprise"]),k=t.enum(["lightweight","standard","resilient","enterprise","none"]),m=t.object({name:t.string().min(1),environment:t.string().min(1),source:t.string().min(1)}).strict(),E=t.object({name:t.string().min(1),pattern:t.string().min(1).optional(),patternTier:x.optional(),patternDomain:t.string().min(1).optional(),network:k.optional(),template:t.string().min(1).optional(),docker:t.object({path:t.string().min(1).optional(),context:t.string().min(1).optional(),target:t.string().min(1).optional()}).strict().optional(),git:t.boolean().optional(),github:t.boolean().optional(),repoVisibility:t.enum(["private","public"]).optional(),intent:t.string().max(a).optional()}).strict(),T=t.object({planId:t.string().regex(/^[0-9a-f]{32}$/),normalisedPath:t.string().min(1),resolvedInputs:E,targetAccount:m.nullable(),targetAccountCandidates:t.array(m),filesToWrite:t.array(s),npmPackages:t.array(t.string().min(1)),registryActions:t.array(c),patternUnsupportedForDryRun:t.boolean().optional(),intent:t.string().max(a).optional(),framework:t.string().min(1).optional(),summary:t.string().min(1)}).strict(),N=t.object({filesToWrite:t.array(s),npmPackages:t.array(t.string().min(1)),registryActions:t.array(c),patternUnsupportedForDryRun:t.boolean().optional()}).strict(),j=t.object({path:t.string().min(1),name:t.string().min(1),mode:t.enum(["application","pattern"]),dependenciesInstalled:t.boolean().optional(),warning:t.string().optional(),dryRunArtefacts:N.optional()}).strict(),v=t.object({step:t.string().min(1),current:t.number().int().nonnegative(),total:t.number().int().positive().optional(),message:t.string().min(1)}).strict();function w(n){let o;try{o=JSON.parse(n)}catch(i){return{ok:!1,reason:"json",raw:n,error:i instanceof Error?i.message:String(i)}}const r=I.safeParse(o);return r.success?{ok:!0,frame:r.data}:{ok:!1,reason:"schema",raw:n,error:r.error.message}}export{S as AuthBrowserCompleteFrameSchema,A as AuthBrowserRequiredFrameSchema,N as DryRunArtefactsSchema,h as ErrorFrameSchema,s as FileToWriteSchema,a as INTENT_MAX_LENGTH,f as MCP_ERROR_CODES,p as MCP_PROTOCOL_VERSION,I as McpProtocolFrameSchema,c as RegistryActionSchema,E as ResolvedInputsSchema,R as ResultFrameSchema,T as ScaffoldPlanSchema,v as ScaffoldProgressFrameSchema,j as ScaffoldResultDataSchema,u as StepCompleteFrameSchema,g as StepStartFrameSchema,m as TargetAccountSchema,d as WarningFrameSchema,w as parseFrame};
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Cross-package contract for the ClickHouse managed-users manifest.
3
+ *
4
+ * Producer: `ClickHouseDatabase.getMigrationContributions()` emits the
5
+ * managed-password user names (every entry in the construct's
6
+ * `managedPasswords:` prop, plus the `schemaAdmin.name`) as a JSON-stringified
7
+ * array of strings on the migration container's env, plus per-user
8
+ * `USER_<NAME>_PASSWORD` secretsImport entries.
9
+ *
10
+ * Consumer: `@fjall/clickhouse-migrations § provisionUsersFromEnv` parses the
11
+ * env, reads each password from `process.env[USER_<NAME>_PASSWORD]` (injected
12
+ * by ECS executionRole — no runtime SDK call), and issues
13
+ * `CREATE USER IF NOT EXISTS … IDENTIFIED WITH sha256_password BY '<pw>'`
14
+ * followed by `ALTER USER …`. Profile binding is NOT performed by the helper
15
+ * — profiles are bound by customer SQL migrations via
16
+ * `ALTER USER <name> SETTINGS PROFILE '<profile>'`.
17
+ *
18
+ * Coupled values — must move together per
19
+ * `.claude/rules/code-quality.md § "Coupled values: shared source at 2
20
+ * occurrences"`. Lives in `@fjall/util` so the runtime Docker image picks the
21
+ * constant + schema up without pulling `aws-cdk-lib`.
22
+ */
23
+ import { z } from "zod";
24
+ /**
25
+ * Container env var name carrying the JSON-stringified manifest of managed
26
+ * users (just names — no profile binding). Set by
27
+ * `getMigrationContributions()` at synth; consumed by the migration helper at
28
+ * runtime.
29
+ */
30
+ export declare const CLICKHOUSE_MANAGED_USERS_ENV: "CLICKHOUSE_MANAGED_USERS";
31
+ /**
32
+ * ECS-injected env var name carrying a managed user's plaintext password.
33
+ *
34
+ * Producer: `ClickHouseDatabase.getMigrationContributions()` populates
35
+ * `secretsImport[userPasswordEnvName(name)] = secret.getImport("password")`
36
+ * (the framework wires the executionRole `secretsmanager:GetSecretValue` grant
37
+ * via the standard `secretsImport` path).
38
+ *
39
+ * Consumer: `@fjall/clickhouse-migrations § provisionUsersFromEnv` reads
40
+ * `process.env[userPasswordEnvName(name)]` for each entry in the manifest —
41
+ * no runtime SDK call.
42
+ *
43
+ * Coupled values — must move together per
44
+ * `.claude/rules/code-quality.md § "Coupled values: shared source at 2
45
+ * occurrences"`. Single source-of-truth here so a future shape change
46
+ * (`USER_<NAME>_SECRET`, lower-case, prefixed) lands at one site, not three.
47
+ */
48
+ export declare function userPasswordEnvName(userName: string): string;
49
+ /**
50
+ * Lowercase snake_case name regex. Mirrors the construct's `NAME_PATTERN` at
51
+ * `fjall/components/infrastructure/lib/resources/aws/database/clickhouseSchemas.ts § NAME_PATTERN`.
52
+ * Drift between the two surfaces as a parse failure in the runner.
53
+ */
54
+ export declare const MANAGED_USER_NAME_PATTERN: RegExp;
55
+ /**
56
+ * One managed user — just the name. Passwords flow via the sibling
57
+ * `USER_<NAME>_PASSWORD` env vars injected by ECS executionRole; profiles
58
+ * flow via customer SQL (`ALTER USER … SETTINGS PROFILE …`), not via this
59
+ * manifest.
60
+ */
61
+ export declare const ManagedUserNameSchema: z.ZodString;
62
+ export type ManagedUserName = z.infer<typeof ManagedUserNameSchema>;
63
+ /**
64
+ * Manifest = ordered array of managed user names. Order matches the
65
+ * construct's `[schemaAdmin.name, ...managedPasswords]` order so provisioning
66
+ * is deterministic across deploys.
67
+ */
68
+ export declare const ManagedUserNamesSchema: z.ZodArray<z.ZodString>;
69
+ export type ManagedUserNames = z.infer<typeof ManagedUserNamesSchema>;
@@ -0,0 +1 @@
1
+ import{z as e}from"zod";const t="CLICKHOUSE_MANAGED_USERS";function n(a){return`USER_${a.toUpperCase()}_PASSWORD`}const r=/^[a-z][a-z0-9_]*$/,s=e.string().min(1).max(63).regex(r,"Must be lowercase snake_case"),E=e.array(s).min(0);export{t as CLICKHOUSE_MANAGED_USERS_ENV,r as MANAGED_USER_NAME_PATTERN,s as ManagedUserNameSchema,E as ManagedUserNamesSchema,n as userPasswordEnvName};
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Cross-package contract constants for the migration runner. Imported by both
3
+ * `@fjall/components-infrastructure` (CDK synth, IAM globs, env-var injection)
4
+ * and `webapp/scripts/migration-runner.mjs` (runtime, snapshot naming, gate).
5
+ * Coupled values — must move together (Code Quality § "Coupled values: shared
6
+ * source at 2 occurrences"). Live in `@fjall/util` so the runtime Docker image
7
+ * picks them up without pulling `aws-cdk-lib`.
8
+ */
9
+ /**
10
+ * Snapshot-name prefix shared between the IAM glob in
11
+ * `IRelationalDatabaseBase.getMigrationSnapshotPolicy()` and the runner's
12
+ * `DBSnapshotIdentifier`. Both sites import this so a renamed prefix can't
13
+ * leave the IAM glob granting access to a name the runner no longer emits.
14
+ */
15
+ export declare const MIGRATION_SNAPSHOT_NAME_PREFIX: "fjall-premigrate";
16
+ /**
17
+ * Container env var name for the schema-version fail-fast gate. Every
18
+ * container of every service whose `connections:` includes a relational DB
19
+ * declaring `migrations:` receives this env baked in at synth time. The
20
+ * booting service reads it at runtime and refuses to start when the actual
21
+ * schema version trails the expected.
22
+ */
23
+ export declare const EXPECTED_SCHEMA_VERSION_ENV: "EXPECTED_SCHEMA_VERSION";
24
+ /**
25
+ * Sibling env carrying the producing `MigrationsConfig.tool` discriminator
26
+ * (`"prisma" | "custom"`). Emitted alongside `EXPECTED_SCHEMA_VERSION` so the
27
+ * runtime gate can dispatch to the matching consumer-side resolver.
28
+ */
29
+ export declare const EXPECTED_SCHEMA_VERSION_TOOL_ENV: "EXPECTED_SCHEMA_VERSION_TOOL";
30
+ /**
31
+ * Prisma migration directory pattern: 14-digit timestamp + underscore prefix.
32
+ * Sortable alphanumerically because the timestamp is fixed-width.
33
+ */
34
+ export declare const PRISMA_MIGRATION_DIR_RE: RegExp;
@@ -0,0 +1 @@
1
+ const E="fjall-premigrate",_="EXPECTED_SCHEMA_VERSION",I="EXPECTED_SCHEMA_VERSION_TOOL",O=/^\d{14}_/;export{_ as EXPECTED_SCHEMA_VERSION_ENV,I as EXPECTED_SCHEMA_VERSION_TOOL_ENV,E as MIGRATION_SNAPSHOT_NAME_PREFIX,O as PRISMA_MIGRATION_DIR_RE};
@@ -0,0 +1,3 @@
1
+ export { MIGRATION_SNAPSHOT_NAME_PREFIX, EXPECTED_SCHEMA_VERSION_ENV, EXPECTED_SCHEMA_VERSION_TOOL_ENV, PRISMA_MIGRATION_DIR_RE } from "./constants.js";
2
+ export { pickLatestPrismaMigration } from "./pickLatestPrismaMigration.js";
3
+ export { CLICKHOUSE_MANAGED_USERS_ENV, MANAGED_USER_NAME_PATTERN, userPasswordEnvName, ManagedUserNameSchema, ManagedUserNamesSchema, type ManagedUserName, type ManagedUserNames } from "./clickhouseSqlUsers.js";
@@ -0,0 +1 @@
1
+ import{MIGRATION_SNAPSHOT_NAME_PREFIX as N,EXPECTED_SCHEMA_VERSION_ENV as e,EXPECTED_SCHEMA_VERSION_TOOL_ENV as a,PRISMA_MIGRATION_DIR_RE as A}from"./constants.js";import{pickLatestPrismaMigration as r}from"./pickLatestPrismaMigration.js";import{CLICKHOUSE_MANAGED_USERS_ENV as R,MANAGED_USER_NAME_PATTERN as I,userPasswordEnvName as m,ManagedUserNameSchema as o,ManagedUserNamesSchema as s}from"./clickhouseSqlUsers.js";export{R as CLICKHOUSE_MANAGED_USERS_ENV,e as EXPECTED_SCHEMA_VERSION_ENV,a as EXPECTED_SCHEMA_VERSION_TOOL_ENV,I as MANAGED_USER_NAME_PATTERN,N as MIGRATION_SNAPSHOT_NAME_PREFIX,o as ManagedUserNameSchema,s as ManagedUserNamesSchema,A as PRISMA_MIGRATION_DIR_RE,r as pickLatestPrismaMigration,m as userPasswordEnvName};
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Returns the lexicographically-latest Prisma migration directory name
3
+ * under `prismaRoot` (e.g. `"20260201000000_add_users"`). Lexicographic
4
+ * order equals chronological order because of the fixed-width timestamp.
5
+ *
6
+ * Synchronous I/O — safe at both CDK synth time (the original use site) and
7
+ * inside the migration runner script (the new use site). Throws when the
8
+ * directory contains no entries matching `PRISMA_MIGRATION_DIR_RE`.
9
+ */
10
+ export declare function pickLatestPrismaMigration(prismaRoot: string): string;