@craft-ts/deploy 0.7.0-beta.15
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/README.md +41 -0
- package/package.json +42 -0
- package/src/index.d.ts +18 -0
- package/src/index.d.ts.map +1 -0
- package/src/index.js +10 -0
- package/src/index.js.map +1 -0
- package/src/lib/artifact.d.ts +18 -0
- package/src/lib/artifact.d.ts.map +1 -0
- package/src/lib/artifact.js +121 -0
- package/src/lib/artifact.js.map +1 -0
- package/src/lib/check.d.ts +31 -0
- package/src/lib/check.d.ts.map +1 -0
- package/src/lib/check.js +278 -0
- package/src/lib/check.js.map +1 -0
- package/src/lib/diagnostics.d.ts +38 -0
- package/src/lib/diagnostics.d.ts.map +1 -0
- package/src/lib/diagnostics.js +297 -0
- package/src/lib/diagnostics.js.map +1 -0
- package/src/lib/format.d.ts +17 -0
- package/src/lib/format.d.ts.map +1 -0
- package/src/lib/format.js +42 -0
- package/src/lib/format.js.map +1 -0
- package/src/lib/manifest.d.ts +236 -0
- package/src/lib/manifest.d.ts.map +1 -0
- package/src/lib/manifest.js +47 -0
- package/src/lib/manifest.js.map +1 -0
- package/src/lib/protocol.d.ts +22 -0
- package/src/lib/protocol.d.ts.map +1 -0
- package/src/lib/protocol.js +182 -0
- package/src/lib/protocol.js.map +1 -0
- package/src/lib/providers.d.ts +111 -0
- package/src/lib/providers.d.ts.map +1 -0
- package/src/lib/providers.js +156 -0
- package/src/lib/providers.js.map +1 -0
- package/src/lib/sources.d.ts +31 -0
- package/src/lib/sources.d.ts.map +1 -0
- package/src/lib/sources.js +155 -0
- package/src/lib/sources.js.map +1 -0
- package/src/lib/validate.d.ts +16 -0
- package/src/lib/validate.d.ts.map +1 -0
- package/src/lib/validate.js +361 -0
- package/src/lib/validate.js.map +1 -0
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deployment contract of a CraftTS application.
|
|
3
|
+
*
|
|
4
|
+
* The contract separates three notions that the tooling must never merge:
|
|
5
|
+
*
|
|
6
|
+
* - `runtime` — the execution shape of the bundle (`static`, `node`, `worker`
|
|
7
|
+
* or `lambda`);
|
|
8
|
+
* - `platform` — the technical platform targeted by that bundle;
|
|
9
|
+
* - `provider` — the integration that builds, publishes or provisions the
|
|
10
|
+
* platform. Providers live outside this module: a manifest is
|
|
11
|
+
* provider-neutral so the same artefact can be published by several of them.
|
|
12
|
+
*/
|
|
13
|
+
/** Version of the manifest protocol, bumped on any breaking field change. */
|
|
14
|
+
export declare const CRAFT_DEPLOYMENT_PROTOCOL_VERSION = "1";
|
|
15
|
+
export declare const CRAFT_DEPLOYMENT_RUNTIMES: readonly ["static", "node", "worker", "lambda"];
|
|
16
|
+
export type CraftDeploymentRuntime = (typeof CRAFT_DEPLOYMENT_RUNTIMES)[number];
|
|
17
|
+
export declare const CRAFT_STATIC_MODES: readonly ["spa", "ssg"];
|
|
18
|
+
export type CraftStaticMode = (typeof CRAFT_STATIC_MODES)[number];
|
|
19
|
+
export declare const CRAFT_DEPLOYMENT_PLATFORMS: readonly ["node", "docker", "cloudflare", "aws", "vercel", "netlify", "firebase", "github-pages"];
|
|
20
|
+
export type CraftDeploymentPlatform = (typeof CRAFT_DEPLOYMENT_PLATFORMS)[number];
|
|
21
|
+
export declare const CRAFT_SOURCE_MAP_POLICIES: readonly ["forbidden", "external", "allowed"];
|
|
22
|
+
/**
|
|
23
|
+
* `forbidden` fails the artefact check when a `.map` file is shipped,
|
|
24
|
+
* `external` accepts them as separate files, `allowed` accepts anything.
|
|
25
|
+
*/
|
|
26
|
+
export type CraftSourceMapPolicy = (typeof CRAFT_SOURCE_MAP_POLICIES)[number];
|
|
27
|
+
/**
|
|
28
|
+
* An environment variable the deployment expects. The manifest is committed,
|
|
29
|
+
* so it carries the name and the requirement, never the value.
|
|
30
|
+
*/
|
|
31
|
+
export type CraftDeploymentEnvironmentVariable = Readonly<{
|
|
32
|
+
name: string;
|
|
33
|
+
required: boolean;
|
|
34
|
+
description?: string;
|
|
35
|
+
}>;
|
|
36
|
+
/** A platform resource the runtime expects to be bound at deploy time. */
|
|
37
|
+
export type CraftDeploymentBinding = Readonly<{
|
|
38
|
+
name: string;
|
|
39
|
+
type: string;
|
|
40
|
+
description?: string;
|
|
41
|
+
}>;
|
|
42
|
+
export type CraftDeploymentClient = Readonly<{
|
|
43
|
+
/** Command producing the browser bundle. */
|
|
44
|
+
build: string;
|
|
45
|
+
/** Directory produced by that command, relative to the workspace root. */
|
|
46
|
+
outDir: string;
|
|
47
|
+
}>;
|
|
48
|
+
export type CraftDeploymentStaticInput = Readonly<{
|
|
49
|
+
mode: CraftStaticMode;
|
|
50
|
+
/** `spa` only: document served for unknown paths. Defaults to `index.html`. */
|
|
51
|
+
fallback?: string;
|
|
52
|
+
/** `ssg` only: the exhaustive list of routes to pre-render. */
|
|
53
|
+
routes?: readonly string[];
|
|
54
|
+
/** Routes that cannot be pre-rendered and still need a server runtime. */
|
|
55
|
+
serverRoutes?: readonly string[];
|
|
56
|
+
}>;
|
|
57
|
+
export type CraftDeploymentStatic = Readonly<{
|
|
58
|
+
mode: CraftStaticMode;
|
|
59
|
+
fallback: string;
|
|
60
|
+
routes: readonly string[];
|
|
61
|
+
serverRoutes: readonly string[];
|
|
62
|
+
}>;
|
|
63
|
+
export type CraftDeploymentServerInput = Readonly<{
|
|
64
|
+
build?: string;
|
|
65
|
+
/** SSR entry point produced by the build. */
|
|
66
|
+
entry: string;
|
|
67
|
+
/**
|
|
68
|
+
* Source module producing `entry`. Declaring it lets the checker read the
|
|
69
|
+
* real module graph before the build has ever run.
|
|
70
|
+
*/
|
|
71
|
+
source?: string;
|
|
72
|
+
/** Command starting the built server. */
|
|
73
|
+
start?: string;
|
|
74
|
+
healthPath: string;
|
|
75
|
+
readyPath: string;
|
|
76
|
+
}>;
|
|
77
|
+
export type CraftDeploymentServer = Readonly<{
|
|
78
|
+
build?: string;
|
|
79
|
+
entry: string;
|
|
80
|
+
source?: string;
|
|
81
|
+
start?: string;
|
|
82
|
+
healthPath: string;
|
|
83
|
+
readyPath: string;
|
|
84
|
+
}>;
|
|
85
|
+
export type CraftDeploymentWorkerInput = Readonly<{
|
|
86
|
+
build?: string;
|
|
87
|
+
/** Module exporting `fetch(request, env, ctx)`. */
|
|
88
|
+
entry: string;
|
|
89
|
+
/** Source module producing `entry`, analysed before the build. */
|
|
90
|
+
source?: string;
|
|
91
|
+
bindings?: readonly CraftDeploymentBinding[];
|
|
92
|
+
}>;
|
|
93
|
+
export type CraftDeploymentWorker = Readonly<{
|
|
94
|
+
build?: string;
|
|
95
|
+
entry: string;
|
|
96
|
+
source?: string;
|
|
97
|
+
bindings: readonly CraftDeploymentBinding[];
|
|
98
|
+
}>;
|
|
99
|
+
export type CraftDeploymentLambdaInput = Readonly<{
|
|
100
|
+
build?: string;
|
|
101
|
+
/** Module exporting the Function URL handler. */
|
|
102
|
+
entry: string;
|
|
103
|
+
/** Source module producing `entry`, analysed before the build. */
|
|
104
|
+
source?: string;
|
|
105
|
+
permissions?: readonly string[];
|
|
106
|
+
}>;
|
|
107
|
+
export type CraftDeploymentLambda = Readonly<{
|
|
108
|
+
build?: string;
|
|
109
|
+
entry: string;
|
|
110
|
+
source?: string;
|
|
111
|
+
permissions: readonly string[];
|
|
112
|
+
}>;
|
|
113
|
+
export type CraftDeploymentFunctionsInput = Readonly<{
|
|
114
|
+
/** Module building the server-function registry. */
|
|
115
|
+
entry: string;
|
|
116
|
+
/** HTTP prefix the registry is mounted on. Defaults to `/api`. */
|
|
117
|
+
basePath?: string;
|
|
118
|
+
/** Identifiers exposed to clients. */
|
|
119
|
+
ids?: readonly string[];
|
|
120
|
+
}>;
|
|
121
|
+
export type CraftDeploymentFunctions = Readonly<{
|
|
122
|
+
entry: string;
|
|
123
|
+
basePath: string;
|
|
124
|
+
ids: readonly string[];
|
|
125
|
+
}>;
|
|
126
|
+
export type CraftDeploymentArtifactInput = Readonly<{
|
|
127
|
+
/** Directory uploaded as-is by a publication provider. */
|
|
128
|
+
publicDir?: string;
|
|
129
|
+
/** Entry a runtime provider has to execute. */
|
|
130
|
+
serverEntry?: string;
|
|
131
|
+
/** Command starting the artefact locally or on the platform. */
|
|
132
|
+
start?: string;
|
|
133
|
+
/** Files the provider must ship next to the artefact. */
|
|
134
|
+
configFiles?: readonly string[];
|
|
135
|
+
sourceMaps?: CraftSourceMapPolicy;
|
|
136
|
+
}>;
|
|
137
|
+
export type CraftDeploymentArtifact = Readonly<{
|
|
138
|
+
publicDir?: string;
|
|
139
|
+
serverEntry?: string;
|
|
140
|
+
start?: string;
|
|
141
|
+
configFiles: readonly string[];
|
|
142
|
+
sourceMaps: CraftSourceMapPolicy;
|
|
143
|
+
}>;
|
|
144
|
+
type DefinitionBase = Readonly<{
|
|
145
|
+
name: string;
|
|
146
|
+
/** Target environment, e.g. `production` or `staging`. */
|
|
147
|
+
environment?: string;
|
|
148
|
+
platform: CraftDeploymentPlatform;
|
|
149
|
+
functions?: CraftDeploymentFunctionsInput;
|
|
150
|
+
env?: readonly CraftDeploymentEnvironmentVariable[];
|
|
151
|
+
artifact?: CraftDeploymentArtifactInput;
|
|
152
|
+
}>;
|
|
153
|
+
/**
|
|
154
|
+
* The runtime discriminates which section is mandatory. Forbidding the other
|
|
155
|
+
* sections at the type level keeps `craft.deploy.ts` honest: a worker
|
|
156
|
+
* deployment cannot silently carry an SSR entry that nothing will execute.
|
|
157
|
+
*/
|
|
158
|
+
export type CraftStaticDeploymentDefinition = DefinitionBase & Readonly<{
|
|
159
|
+
runtime: 'static';
|
|
160
|
+
static: CraftDeploymentStaticInput;
|
|
161
|
+
client: CraftDeploymentClient;
|
|
162
|
+
server?: never;
|
|
163
|
+
worker?: never;
|
|
164
|
+
lambda?: never;
|
|
165
|
+
}>;
|
|
166
|
+
export type CraftNodeDeploymentDefinition = DefinitionBase & Readonly<{
|
|
167
|
+
runtime: 'node';
|
|
168
|
+
server: CraftDeploymentServerInput;
|
|
169
|
+
client?: CraftDeploymentClient;
|
|
170
|
+
static?: never;
|
|
171
|
+
worker?: never;
|
|
172
|
+
lambda?: never;
|
|
173
|
+
}>;
|
|
174
|
+
export type CraftWorkerDeploymentDefinition = DefinitionBase & Readonly<{
|
|
175
|
+
runtime: 'worker';
|
|
176
|
+
worker: CraftDeploymentWorkerInput;
|
|
177
|
+
client?: CraftDeploymentClient;
|
|
178
|
+
static?: never;
|
|
179
|
+
server?: never;
|
|
180
|
+
lambda?: never;
|
|
181
|
+
}>;
|
|
182
|
+
export type CraftLambdaDeploymentDefinition = DefinitionBase & Readonly<{
|
|
183
|
+
runtime: 'lambda';
|
|
184
|
+
lambda: CraftDeploymentLambdaInput;
|
|
185
|
+
client?: CraftDeploymentClient;
|
|
186
|
+
static?: never;
|
|
187
|
+
server?: never;
|
|
188
|
+
worker?: never;
|
|
189
|
+
}>;
|
|
190
|
+
/** What an application author writes in `craft.deploy.ts`. */
|
|
191
|
+
export type CraftDeploymentDefinition = CraftStaticDeploymentDefinition | CraftNodeDeploymentDefinition | CraftWorkerDeploymentDefinition | CraftLambdaDeploymentDefinition;
|
|
192
|
+
type ManifestBase = Readonly<{
|
|
193
|
+
protocolVersion: string;
|
|
194
|
+
name: string;
|
|
195
|
+
environment: string;
|
|
196
|
+
platform: CraftDeploymentPlatform;
|
|
197
|
+
functions?: CraftDeploymentFunctions;
|
|
198
|
+
env: readonly CraftDeploymentEnvironmentVariable[];
|
|
199
|
+
artifact: CraftDeploymentArtifact;
|
|
200
|
+
}>;
|
|
201
|
+
export type CraftStaticDeploymentManifest = ManifestBase & Readonly<{
|
|
202
|
+
runtime: 'static';
|
|
203
|
+
static: CraftDeploymentStatic;
|
|
204
|
+
client: CraftDeploymentClient;
|
|
205
|
+
}>;
|
|
206
|
+
export type CraftNodeDeploymentManifest = ManifestBase & Readonly<{
|
|
207
|
+
runtime: 'node';
|
|
208
|
+
server: CraftDeploymentServer;
|
|
209
|
+
client?: CraftDeploymentClient;
|
|
210
|
+
}>;
|
|
211
|
+
export type CraftWorkerDeploymentManifest = ManifestBase & Readonly<{
|
|
212
|
+
runtime: 'worker';
|
|
213
|
+
worker: CraftDeploymentWorker;
|
|
214
|
+
client?: CraftDeploymentClient;
|
|
215
|
+
}>;
|
|
216
|
+
export type CraftLambdaDeploymentManifest = ManifestBase & Readonly<{
|
|
217
|
+
runtime: 'lambda';
|
|
218
|
+
lambda: CraftDeploymentLambda;
|
|
219
|
+
client?: CraftDeploymentClient;
|
|
220
|
+
}>;
|
|
221
|
+
/**
|
|
222
|
+
* The resolved, serialisable form written to
|
|
223
|
+
* `dist/<app>/craft-deployment-manifest.json`. Every default is applied, so a
|
|
224
|
+
* provider never has to know the defaults of the CraftTS tooling.
|
|
225
|
+
*/
|
|
226
|
+
export type CraftDeploymentManifest = CraftStaticDeploymentManifest | CraftNodeDeploymentManifest | CraftWorkerDeploymentManifest | CraftLambdaDeploymentManifest;
|
|
227
|
+
/**
|
|
228
|
+
* Declares the deployment of a CraftTS application.
|
|
229
|
+
*
|
|
230
|
+
* The call is pure: it neither reads the filesystem nor resolves defaults, so
|
|
231
|
+
* importing `craft.deploy.ts` stays free of side effects. Defaults belong to
|
|
232
|
+
* {@link resolveCraftDeploymentManifest}.
|
|
233
|
+
*/
|
|
234
|
+
export declare function defineCraftDeployment<const Definition extends CraftDeploymentDefinition>(definition: Definition): Definition;
|
|
235
|
+
export {};
|
|
236
|
+
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../../../libs/deploy/src/lib/manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deployment contract of a CraftTS application.
|
|
3
|
+
*
|
|
4
|
+
* The contract separates three notions that the tooling must never merge:
|
|
5
|
+
*
|
|
6
|
+
* - `runtime` — the execution shape of the bundle (`static`, `node`, `worker`
|
|
7
|
+
* or `lambda`);
|
|
8
|
+
* - `platform` — the technical platform targeted by that bundle;
|
|
9
|
+
* - `provider` — the integration that builds, publishes or provisions the
|
|
10
|
+
* platform. Providers live outside this module: a manifest is
|
|
11
|
+
* provider-neutral so the same artefact can be published by several of them.
|
|
12
|
+
*/
|
|
13
|
+
/** Version of the manifest protocol, bumped on any breaking field change. */
|
|
14
|
+
export const CRAFT_DEPLOYMENT_PROTOCOL_VERSION = '1';
|
|
15
|
+
export const CRAFT_DEPLOYMENT_RUNTIMES = [
|
|
16
|
+
'static',
|
|
17
|
+
'node',
|
|
18
|
+
'worker',
|
|
19
|
+
'lambda',
|
|
20
|
+
];
|
|
21
|
+
export const CRAFT_STATIC_MODES = ['spa', 'ssg'];
|
|
22
|
+
export const CRAFT_DEPLOYMENT_PLATFORMS = [
|
|
23
|
+
'node',
|
|
24
|
+
'docker',
|
|
25
|
+
'cloudflare',
|
|
26
|
+
'aws',
|
|
27
|
+
'vercel',
|
|
28
|
+
'netlify',
|
|
29
|
+
'firebase',
|
|
30
|
+
'github-pages',
|
|
31
|
+
];
|
|
32
|
+
export const CRAFT_SOURCE_MAP_POLICIES = [
|
|
33
|
+
'forbidden',
|
|
34
|
+
'external',
|
|
35
|
+
'allowed',
|
|
36
|
+
];
|
|
37
|
+
/**
|
|
38
|
+
* Declares the deployment of a CraftTS application.
|
|
39
|
+
*
|
|
40
|
+
* The call is pure: it neither reads the filesystem nor resolves defaults, so
|
|
41
|
+
* importing `craft.deploy.ts` stays free of side effects. Defaults belong to
|
|
42
|
+
* {@link resolveCraftDeploymentManifest}.
|
|
43
|
+
*/
|
|
44
|
+
export function defineCraftDeployment(definition) {
|
|
45
|
+
return Object.freeze(definition);
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../../../../libs/deploy/src/lib/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,6EAA6E;AAC7E,MAAM,CAAC,MAAM,iCAAiC,GAAG,GAAG,CAAC;AAErD,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,QAAQ;IACR,MAAM;IACN,QAAQ;IACR,QAAQ;CACA,CAAC;AAIX,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE,KAAK,CAAU,CAAC;AAI1D,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,MAAM;IACN,QAAQ;IACR,YAAY;IACZ,KAAK;IACL,QAAQ;IACR,SAAS;IACT,UAAU;IACV,cAAc;CACN,CAAC;AAKX,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,WAAW;IACX,UAAU;IACV,SAAS;CACD,CAAC;AA2PX;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAEnC,UAAsB;IACtB,OAAO,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;AACnC,CAAC","sourcesContent":["/**\n * Deployment contract of a CraftTS application.\n *\n * The contract separates three notions that the tooling must never merge:\n *\n * - `runtime` — the execution shape of the bundle (`static`, `node`, `worker`\n * or `lambda`);\n * - `platform` — the technical platform targeted by that bundle;\n * - `provider` — the integration that builds, publishes or provisions the\n * platform. Providers live outside this module: a manifest is\n * provider-neutral so the same artefact can be published by several of them.\n */\n\n/** Version of the manifest protocol, bumped on any breaking field change. */\nexport const CRAFT_DEPLOYMENT_PROTOCOL_VERSION = '1';\n\nexport const CRAFT_DEPLOYMENT_RUNTIMES = [\n 'static',\n 'node',\n 'worker',\n 'lambda',\n] as const;\n\nexport type CraftDeploymentRuntime = (typeof CRAFT_DEPLOYMENT_RUNTIMES)[number];\n\nexport const CRAFT_STATIC_MODES = ['spa', 'ssg'] as const;\n\nexport type CraftStaticMode = (typeof CRAFT_STATIC_MODES)[number];\n\nexport const CRAFT_DEPLOYMENT_PLATFORMS = [\n 'node',\n 'docker',\n 'cloudflare',\n 'aws',\n 'vercel',\n 'netlify',\n 'firebase',\n 'github-pages',\n] as const;\n\nexport type CraftDeploymentPlatform =\n (typeof CRAFT_DEPLOYMENT_PLATFORMS)[number];\n\nexport const CRAFT_SOURCE_MAP_POLICIES = [\n 'forbidden',\n 'external',\n 'allowed',\n] as const;\n\n/**\n * `forbidden` fails the artefact check when a `.map` file is shipped,\n * `external` accepts them as separate files, `allowed` accepts anything.\n */\nexport type CraftSourceMapPolicy = (typeof CRAFT_SOURCE_MAP_POLICIES)[number];\n\n/**\n * An environment variable the deployment expects. The manifest is committed,\n * so it carries the name and the requirement, never the value.\n */\nexport type CraftDeploymentEnvironmentVariable = Readonly<{\n name: string;\n required: boolean;\n description?: string;\n}>;\n\n/** A platform resource the runtime expects to be bound at deploy time. */\nexport type CraftDeploymentBinding = Readonly<{\n name: string;\n type: string;\n description?: string;\n}>;\n\nexport type CraftDeploymentClient = Readonly<{\n /** Command producing the browser bundle. */\n build: string;\n /** Directory produced by that command, relative to the workspace root. */\n outDir: string;\n}>;\n\nexport type CraftDeploymentStaticInput = Readonly<{\n mode: CraftStaticMode;\n /** `spa` only: document served for unknown paths. Defaults to `index.html`. */\n fallback?: string;\n /** `ssg` only: the exhaustive list of routes to pre-render. */\n routes?: readonly string[];\n /** Routes that cannot be pre-rendered and still need a server runtime. */\n serverRoutes?: readonly string[];\n}>;\n\nexport type CraftDeploymentStatic = Readonly<{\n mode: CraftStaticMode;\n fallback: string;\n routes: readonly string[];\n serverRoutes: readonly string[];\n}>;\n\nexport type CraftDeploymentServerInput = Readonly<{\n build?: string;\n /** SSR entry point produced by the build. */\n entry: string;\n /**\n * Source module producing `entry`. Declaring it lets the checker read the\n * real module graph before the build has ever run.\n */\n source?: string;\n /** Command starting the built server. */\n start?: string;\n healthPath: string;\n readyPath: string;\n}>;\n\nexport type CraftDeploymentServer = Readonly<{\n build?: string;\n entry: string;\n source?: string;\n start?: string;\n healthPath: string;\n readyPath: string;\n}>;\n\nexport type CraftDeploymentWorkerInput = Readonly<{\n build?: string;\n /** Module exporting `fetch(request, env, ctx)`. */\n entry: string;\n /** Source module producing `entry`, analysed before the build. */\n source?: string;\n bindings?: readonly CraftDeploymentBinding[];\n}>;\n\nexport type CraftDeploymentWorker = Readonly<{\n build?: string;\n entry: string;\n source?: string;\n bindings: readonly CraftDeploymentBinding[];\n}>;\n\nexport type CraftDeploymentLambdaInput = Readonly<{\n build?: string;\n /** Module exporting the Function URL handler. */\n entry: string;\n /** Source module producing `entry`, analysed before the build. */\n source?: string;\n permissions?: readonly string[];\n}>;\n\nexport type CraftDeploymentLambda = Readonly<{\n build?: string;\n entry: string;\n source?: string;\n permissions: readonly string[];\n}>;\n\nexport type CraftDeploymentFunctionsInput = Readonly<{\n /** Module building the server-function registry. */\n entry: string;\n /** HTTP prefix the registry is mounted on. Defaults to `/api`. */\n basePath?: string;\n /** Identifiers exposed to clients. */\n ids?: readonly string[];\n}>;\n\nexport type CraftDeploymentFunctions = Readonly<{\n entry: string;\n basePath: string;\n ids: readonly string[];\n}>;\n\nexport type CraftDeploymentArtifactInput = Readonly<{\n /** Directory uploaded as-is by a publication provider. */\n publicDir?: string;\n /** Entry a runtime provider has to execute. */\n serverEntry?: string;\n /** Command starting the artefact locally or on the platform. */\n start?: string;\n /** Files the provider must ship next to the artefact. */\n configFiles?: readonly string[];\n sourceMaps?: CraftSourceMapPolicy;\n}>;\n\nexport type CraftDeploymentArtifact = Readonly<{\n publicDir?: string;\n serverEntry?: string;\n start?: string;\n configFiles: readonly string[];\n sourceMaps: CraftSourceMapPolicy;\n}>;\n\ntype DefinitionBase = Readonly<{\n name: string;\n /** Target environment, e.g. `production` or `staging`. */\n environment?: string;\n platform: CraftDeploymentPlatform;\n functions?: CraftDeploymentFunctionsInput;\n env?: readonly CraftDeploymentEnvironmentVariable[];\n artifact?: CraftDeploymentArtifactInput;\n}>;\n\n/**\n * The runtime discriminates which section is mandatory. Forbidding the other\n * sections at the type level keeps `craft.deploy.ts` honest: a worker\n * deployment cannot silently carry an SSR entry that nothing will execute.\n */\nexport type CraftStaticDeploymentDefinition = DefinitionBase &\n Readonly<{\n runtime: 'static';\n static: CraftDeploymentStaticInput;\n client: CraftDeploymentClient;\n server?: never;\n worker?: never;\n lambda?: never;\n }>;\n\nexport type CraftNodeDeploymentDefinition = DefinitionBase &\n Readonly<{\n runtime: 'node';\n server: CraftDeploymentServerInput;\n client?: CraftDeploymentClient;\n static?: never;\n worker?: never;\n lambda?: never;\n }>;\n\nexport type CraftWorkerDeploymentDefinition = DefinitionBase &\n Readonly<{\n runtime: 'worker';\n worker: CraftDeploymentWorkerInput;\n client?: CraftDeploymentClient;\n static?: never;\n server?: never;\n lambda?: never;\n }>;\n\nexport type CraftLambdaDeploymentDefinition = DefinitionBase &\n Readonly<{\n runtime: 'lambda';\n lambda: CraftDeploymentLambdaInput;\n client?: CraftDeploymentClient;\n static?: never;\n server?: never;\n worker?: never;\n }>;\n\n/** What an application author writes in `craft.deploy.ts`. */\nexport type CraftDeploymentDefinition =\n | CraftStaticDeploymentDefinition\n | CraftNodeDeploymentDefinition\n | CraftWorkerDeploymentDefinition\n | CraftLambdaDeploymentDefinition;\n\ntype ManifestBase = Readonly<{\n protocolVersion: string;\n name: string;\n environment: string;\n platform: CraftDeploymentPlatform;\n functions?: CraftDeploymentFunctions;\n env: readonly CraftDeploymentEnvironmentVariable[];\n artifact: CraftDeploymentArtifact;\n}>;\n\nexport type CraftStaticDeploymentManifest = ManifestBase &\n Readonly<{\n runtime: 'static';\n static: CraftDeploymentStatic;\n client: CraftDeploymentClient;\n }>;\n\nexport type CraftNodeDeploymentManifest = ManifestBase &\n Readonly<{\n runtime: 'node';\n server: CraftDeploymentServer;\n client?: CraftDeploymentClient;\n }>;\n\nexport type CraftWorkerDeploymentManifest = ManifestBase &\n Readonly<{\n runtime: 'worker';\n worker: CraftDeploymentWorker;\n client?: CraftDeploymentClient;\n }>;\n\nexport type CraftLambdaDeploymentManifest = ManifestBase &\n Readonly<{\n runtime: 'lambda';\n lambda: CraftDeploymentLambda;\n client?: CraftDeploymentClient;\n }>;\n\n/**\n * The resolved, serialisable form written to\n * `dist/<app>/craft-deployment-manifest.json`. Every default is applied, so a\n * provider never has to know the defaults of the CraftTS tooling.\n */\nexport type CraftDeploymentManifest =\n | CraftStaticDeploymentManifest\n | CraftNodeDeploymentManifest\n | CraftWorkerDeploymentManifest\n | CraftLambdaDeploymentManifest;\n\n/**\n * Declares the deployment of a CraftTS application.\n *\n * The call is pure: it neither reads the filesystem nor resolves defaults, so\n * importing `craft.deploy.ts` stays free of side effects. Defaults belong to\n * {@link resolveCraftDeploymentManifest}.\n */\nexport function defineCraftDeployment<\n const Definition extends CraftDeploymentDefinition,\n>(definition: Definition): Definition {\n return Object.freeze(definition);\n}\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CraftDeploymentDiagnostic } from './diagnostics.js';
|
|
2
|
+
import { type CraftDeploymentDefinition, type CraftDeploymentManifest } from './manifest.js';
|
|
3
|
+
/**
|
|
4
|
+
* Applies every default of the CraftTS tooling and produces the artefact form
|
|
5
|
+
* of the manifest.
|
|
6
|
+
*
|
|
7
|
+
* Resolution is pure and idempotent: resolving an already-resolved manifest
|
|
8
|
+
* returns the same value, which is what makes the JSON round-trip safe.
|
|
9
|
+
*/
|
|
10
|
+
export declare function resolveCraftDeploymentManifest(definition: CraftDeploymentDefinition): CraftDeploymentManifest;
|
|
11
|
+
/**
|
|
12
|
+
* Serialises a manifest with sorted keys so two builds of the same input
|
|
13
|
+
* produce byte-identical artefacts and reviewable diffs.
|
|
14
|
+
*/
|
|
15
|
+
export declare function serializeCraftDeploymentManifest(manifest: CraftDeploymentManifest): string;
|
|
16
|
+
export type CraftDeploymentParseResult = Readonly<{
|
|
17
|
+
manifest: CraftDeploymentManifest | null;
|
|
18
|
+
diagnostics: readonly CraftDeploymentDiagnostic[];
|
|
19
|
+
}>;
|
|
20
|
+
/** Reads a serialised manifest and validates it against the current protocol. */
|
|
21
|
+
export declare function parseCraftDeploymentManifest(json: string): CraftDeploymentParseResult;
|
|
22
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../../../../libs/deploy/src/lib/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,EAGL,KAAK,yBAAyB,EAE9B,KAAK,uBAAuB,EAC7B,MAAM,eAAe,CAAC;AAQvB;;;;;;GAMG;AACH,wBAAgB,8BAA8B,CAC5C,UAAU,EAAE,yBAAyB,GACpC,uBAAuB,CAwFzB;AAiCD;;;GAGG;AACH,wBAAgB,gCAAgC,CAC9C,QAAQ,EAAE,uBAAuB,GAChC,MAAM,CAER;AAED,MAAM,MAAM,0BAA0B,GAAG,QAAQ,CAAC;IAChD,QAAQ,EAAE,uBAAuB,GAAG,IAAI,CAAC;IACzC,WAAW,EAAE,SAAS,yBAAyB,EAAE,CAAC;CACnD,CAAC,CAAC;AAEH,iFAAiF;AACjF,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,MAAM,GACX,0BAA0B,CAmD5B"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { CRAFT_DEPLOYMENT_PROTOCOL_VERSION, } from './manifest.js';
|
|
2
|
+
import { validateCraftDeploymentDefinition } from './validate.js';
|
|
3
|
+
/** Document served for unknown paths when the static mode is `spa`. */
|
|
4
|
+
const DEFAULT_SPA_FALLBACK = 'index.html';
|
|
5
|
+
/** HTTP prefix the server-function registry is mounted on. */
|
|
6
|
+
const DEFAULT_FUNCTIONS_BASE_PATH = '/api';
|
|
7
|
+
/**
|
|
8
|
+
* Applies every default of the CraftTS tooling and produces the artefact form
|
|
9
|
+
* of the manifest.
|
|
10
|
+
*
|
|
11
|
+
* Resolution is pure and idempotent: resolving an already-resolved manifest
|
|
12
|
+
* returns the same value, which is what makes the JSON round-trip safe.
|
|
13
|
+
*/
|
|
14
|
+
export function resolveCraftDeploymentManifest(definition) {
|
|
15
|
+
const base = {
|
|
16
|
+
protocolVersion: CRAFT_DEPLOYMENT_PROTOCOL_VERSION,
|
|
17
|
+
name: definition.name,
|
|
18
|
+
environment: definition.environment ?? 'production',
|
|
19
|
+
platform: definition.platform,
|
|
20
|
+
env: definition.env ?? [],
|
|
21
|
+
...(definition.functions
|
|
22
|
+
? { functions: resolveFunctions(definition.functions) }
|
|
23
|
+
: {}),
|
|
24
|
+
};
|
|
25
|
+
if (definition.runtime === 'static') {
|
|
26
|
+
const client = definition.client;
|
|
27
|
+
return {
|
|
28
|
+
...base,
|
|
29
|
+
runtime: 'static',
|
|
30
|
+
client,
|
|
31
|
+
static: {
|
|
32
|
+
mode: definition.static.mode,
|
|
33
|
+
fallback: definition.static.fallback ?? DEFAULT_SPA_FALLBACK,
|
|
34
|
+
routes: definition.static.routes ?? [],
|
|
35
|
+
serverRoutes: definition.static.serverRoutes ?? [],
|
|
36
|
+
},
|
|
37
|
+
artifact: resolveArtifact(definition, client.outDir, undefined),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
if (definition.runtime === 'node') {
|
|
41
|
+
const server = {
|
|
42
|
+
...(definition.server.build ? { build: definition.server.build } : {}),
|
|
43
|
+
entry: definition.server.entry,
|
|
44
|
+
...(definition.server.source ? { source: definition.server.source } : {}),
|
|
45
|
+
...(definition.server.start ? { start: definition.server.start } : {}),
|
|
46
|
+
healthPath: definition.server.healthPath,
|
|
47
|
+
readyPath: definition.server.readyPath,
|
|
48
|
+
};
|
|
49
|
+
return {
|
|
50
|
+
...base,
|
|
51
|
+
runtime: 'node',
|
|
52
|
+
...(definition.client ? { client: definition.client } : {}),
|
|
53
|
+
server,
|
|
54
|
+
artifact: resolveArtifact(definition, definition.client?.outDir, server.entry, server.start),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
if (definition.runtime === 'worker') {
|
|
58
|
+
const worker = {
|
|
59
|
+
...(definition.worker.build ? { build: definition.worker.build } : {}),
|
|
60
|
+
entry: definition.worker.entry,
|
|
61
|
+
...(definition.worker.source ? { source: definition.worker.source } : {}),
|
|
62
|
+
bindings: definition.worker.bindings ?? [],
|
|
63
|
+
};
|
|
64
|
+
return {
|
|
65
|
+
...base,
|
|
66
|
+
runtime: 'worker',
|
|
67
|
+
...(definition.client ? { client: definition.client } : {}),
|
|
68
|
+
worker,
|
|
69
|
+
artifact: resolveArtifact(definition, definition.client?.outDir, worker.entry),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const lambda = {
|
|
73
|
+
...(definition.lambda.build ? { build: definition.lambda.build } : {}),
|
|
74
|
+
entry: definition.lambda.entry,
|
|
75
|
+
...(definition.lambda.source ? { source: definition.lambda.source } : {}),
|
|
76
|
+
permissions: definition.lambda.permissions ?? [],
|
|
77
|
+
};
|
|
78
|
+
return {
|
|
79
|
+
...base,
|
|
80
|
+
runtime: 'lambda',
|
|
81
|
+
...(definition.client ? { client: definition.client } : {}),
|
|
82
|
+
lambda,
|
|
83
|
+
artifact: resolveArtifact(definition, definition.client?.outDir, lambda.entry),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function resolveFunctions(functions) {
|
|
87
|
+
return {
|
|
88
|
+
entry: functions.entry,
|
|
89
|
+
basePath: functions.basePath ?? DEFAULT_FUNCTIONS_BASE_PATH,
|
|
90
|
+
ids: functions.ids ?? [],
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
function resolveArtifact(definition, publicDir, serverEntry, start) {
|
|
94
|
+
const artifact = definition.artifact;
|
|
95
|
+
const resolvedPublicDir = artifact?.publicDir ?? publicDir;
|
|
96
|
+
const resolvedServerEntry = artifact?.serverEntry ?? serverEntry;
|
|
97
|
+
const resolvedStart = artifact?.start ?? start;
|
|
98
|
+
return {
|
|
99
|
+
...(resolvedPublicDir ? { publicDir: resolvedPublicDir } : {}),
|
|
100
|
+
...(resolvedServerEntry ? { serverEntry: resolvedServerEntry } : {}),
|
|
101
|
+
...(resolvedStart ? { start: resolvedStart } : {}),
|
|
102
|
+
configFiles: artifact?.configFiles ?? [],
|
|
103
|
+
// Shipping maps of a production bundle publishes the sources, so the
|
|
104
|
+
// default refuses them and an application has to opt out explicitly.
|
|
105
|
+
sourceMaps: artifact?.sourceMaps ?? 'forbidden',
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Serialises a manifest with sorted keys so two builds of the same input
|
|
110
|
+
* produce byte-identical artefacts and reviewable diffs.
|
|
111
|
+
*/
|
|
112
|
+
export function serializeCraftDeploymentManifest(manifest) {
|
|
113
|
+
return `${JSON.stringify(sortValue(manifest), null, 2)}\n`;
|
|
114
|
+
}
|
|
115
|
+
/** Reads a serialised manifest and validates it against the current protocol. */
|
|
116
|
+
export function parseCraftDeploymentManifest(json) {
|
|
117
|
+
let parsed;
|
|
118
|
+
try {
|
|
119
|
+
parsed = JSON.parse(json);
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
return {
|
|
123
|
+
manifest: null,
|
|
124
|
+
diagnostics: [
|
|
125
|
+
{
|
|
126
|
+
code: 'CRAFT_DEPLOY_CONFIG_LOAD_FAILED',
|
|
127
|
+
severity: 'error',
|
|
128
|
+
message: `The manifest is not valid JSON: ${messageOf(error)}`,
|
|
129
|
+
fix: 'Rebuild the manifest with `resolveCraftDeploymentManifest` and `serializeCraftDeploymentManifest`.',
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
const diagnostics = [];
|
|
135
|
+
const version = typeof parsed === 'object' && parsed !== null
|
|
136
|
+
? parsed['protocolVersion']
|
|
137
|
+
: undefined;
|
|
138
|
+
if (version === undefined) {
|
|
139
|
+
diagnostics.push({
|
|
140
|
+
code: 'CRAFT_DEPLOY_MANIFEST_MISSING_FIELD',
|
|
141
|
+
severity: 'error',
|
|
142
|
+
path: 'protocolVersion',
|
|
143
|
+
message: '`protocolVersion` is missing from the serialised manifest.',
|
|
144
|
+
fix: 'Serialise the manifest with `serializeCraftDeploymentManifest`.',
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
else if (version !== CRAFT_DEPLOYMENT_PROTOCOL_VERSION) {
|
|
148
|
+
diagnostics.push({
|
|
149
|
+
code: 'CRAFT_DEPLOY_PROTOCOL_VERSION_UNSUPPORTED',
|
|
150
|
+
severity: 'error',
|
|
151
|
+
path: 'protocolVersion',
|
|
152
|
+
message: `The manifest declares protocol \`${String(version)}\` and this tooling reads \`${CRAFT_DEPLOYMENT_PROTOCOL_VERSION}\`.`,
|
|
153
|
+
fix: 'Rebuild the manifest with the current CraftTS tooling, or follow the migration notes.',
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
const validation = validateCraftDeploymentDefinition(parsed);
|
|
157
|
+
diagnostics.push(...validation.diagnostics);
|
|
158
|
+
return {
|
|
159
|
+
manifest: validation.definition && diagnostics.every((d) => d.severity !== 'error')
|
|
160
|
+
? resolveCraftDeploymentManifest(validation.definition)
|
|
161
|
+
: null,
|
|
162
|
+
diagnostics,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
function sortValue(value) {
|
|
166
|
+
if (Array.isArray(value))
|
|
167
|
+
return value.map(sortValue);
|
|
168
|
+
if (typeof value === 'object' && value !== null) {
|
|
169
|
+
const record = value;
|
|
170
|
+
const sorted = {};
|
|
171
|
+
for (const key of Object.keys(record).sort()) {
|
|
172
|
+
if (record[key] !== undefined)
|
|
173
|
+
sorted[key] = sortValue(record[key]);
|
|
174
|
+
}
|
|
175
|
+
return sorted;
|
|
176
|
+
}
|
|
177
|
+
return value;
|
|
178
|
+
}
|
|
179
|
+
function messageOf(error) {
|
|
180
|
+
return error instanceof Error ? error.message : String(error);
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../../../../libs/deploy/src/lib/protocol.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CraftDeploymentDiagnostic } from './diagnostics.js';\nimport {\n CRAFT_DEPLOYMENT_PROTOCOL_VERSION,\n type CraftDeploymentArtifact,\n type CraftDeploymentDefinition,\n type CraftDeploymentFunctions,\n type CraftDeploymentManifest,\n} from './manifest.js';\nimport { validateCraftDeploymentDefinition } from './validate.js';\n\n/** Document served for unknown paths when the static mode is `spa`. */\nconst DEFAULT_SPA_FALLBACK = 'index.html';\n/** HTTP prefix the server-function registry is mounted on. */\nconst DEFAULT_FUNCTIONS_BASE_PATH = '/api';\n\n/**\n * Applies every default of the CraftTS tooling and produces the artefact form\n * of the manifest.\n *\n * Resolution is pure and idempotent: resolving an already-resolved manifest\n * returns the same value, which is what makes the JSON round-trip safe.\n */\nexport function resolveCraftDeploymentManifest(\n definition: CraftDeploymentDefinition,\n): CraftDeploymentManifest {\n const base = {\n protocolVersion: CRAFT_DEPLOYMENT_PROTOCOL_VERSION,\n name: definition.name,\n environment: definition.environment ?? 'production',\n platform: definition.platform,\n env: definition.env ?? [],\n ...(definition.functions\n ? { functions: resolveFunctions(definition.functions) }\n : {}),\n };\n\n if (definition.runtime === 'static') {\n const client = definition.client;\n return {\n ...base,\n runtime: 'static',\n client,\n static: {\n mode: definition.static.mode,\n fallback: definition.static.fallback ?? DEFAULT_SPA_FALLBACK,\n routes: definition.static.routes ?? [],\n serverRoutes: definition.static.serverRoutes ?? [],\n },\n artifact: resolveArtifact(definition, client.outDir, undefined),\n };\n }\n\n if (definition.runtime === 'node') {\n const server = {\n ...(definition.server.build ? { build: definition.server.build } : {}),\n entry: definition.server.entry,\n ...(definition.server.source ? { source: definition.server.source } : {}),\n ...(definition.server.start ? { start: definition.server.start } : {}),\n healthPath: definition.server.healthPath,\n readyPath: definition.server.readyPath,\n };\n return {\n ...base,\n runtime: 'node',\n ...(definition.client ? { client: definition.client } : {}),\n server,\n artifact: resolveArtifact(\n definition,\n definition.client?.outDir,\n server.entry,\n server.start,\n ),\n };\n }\n\n if (definition.runtime === 'worker') {\n const worker = {\n ...(definition.worker.build ? { build: definition.worker.build } : {}),\n entry: definition.worker.entry,\n ...(definition.worker.source ? { source: definition.worker.source } : {}),\n bindings: definition.worker.bindings ?? [],\n };\n return {\n ...base,\n runtime: 'worker',\n ...(definition.client ? { client: definition.client } : {}),\n worker,\n artifact: resolveArtifact(\n definition,\n definition.client?.outDir,\n worker.entry,\n ),\n };\n }\n\n const lambda = {\n ...(definition.lambda.build ? { build: definition.lambda.build } : {}),\n entry: definition.lambda.entry,\n ...(definition.lambda.source ? { source: definition.lambda.source } : {}),\n permissions: definition.lambda.permissions ?? [],\n };\n return {\n ...base,\n runtime: 'lambda',\n ...(definition.client ? { client: definition.client } : {}),\n lambda,\n artifact: resolveArtifact(\n definition,\n definition.client?.outDir,\n lambda.entry,\n ),\n };\n}\n\nfunction resolveFunctions(\n functions: NonNullable<CraftDeploymentDefinition['functions']>,\n): CraftDeploymentFunctions {\n return {\n entry: functions.entry,\n basePath: functions.basePath ?? DEFAULT_FUNCTIONS_BASE_PATH,\n ids: functions.ids ?? [],\n };\n}\n\nfunction resolveArtifact(\n definition: CraftDeploymentDefinition,\n publicDir: string | undefined,\n serverEntry: string | undefined,\n start?: string,\n): CraftDeploymentArtifact {\n const artifact = definition.artifact;\n const resolvedPublicDir = artifact?.publicDir ?? publicDir;\n const resolvedServerEntry = artifact?.serverEntry ?? serverEntry;\n const resolvedStart = artifact?.start ?? start;\n return {\n ...(resolvedPublicDir ? { publicDir: resolvedPublicDir } : {}),\n ...(resolvedServerEntry ? { serverEntry: resolvedServerEntry } : {}),\n ...(resolvedStart ? { start: resolvedStart } : {}),\n configFiles: artifact?.configFiles ?? [],\n // Shipping maps of a production bundle publishes the sources, so the\n // default refuses them and an application has to opt out explicitly.\n sourceMaps: artifact?.sourceMaps ?? 'forbidden',\n };\n}\n\n/**\n * Serialises a manifest with sorted keys so two builds of the same input\n * produce byte-identical artefacts and reviewable diffs.\n */\nexport function serializeCraftDeploymentManifest(\n manifest: CraftDeploymentManifest,\n): string {\n return `${JSON.stringify(sortValue(manifest), null, 2)}\\n`;\n}\n\nexport type CraftDeploymentParseResult = Readonly<{\n manifest: CraftDeploymentManifest | null;\n diagnostics: readonly CraftDeploymentDiagnostic[];\n}>;\n\n/** Reads a serialised manifest and validates it against the current protocol. */\nexport function parseCraftDeploymentManifest(\n json: string,\n): CraftDeploymentParseResult {\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch (error) {\n return {\n manifest: null,\n diagnostics: [\n {\n code: 'CRAFT_DEPLOY_CONFIG_LOAD_FAILED',\n severity: 'error',\n message: `The manifest is not valid JSON: ${messageOf(error)}`,\n fix: 'Rebuild the manifest with `resolveCraftDeploymentManifest` and `serializeCraftDeploymentManifest`.',\n },\n ],\n };\n }\n\n const diagnostics: CraftDeploymentDiagnostic[] = [];\n const version =\n typeof parsed === 'object' && parsed !== null\n ? (parsed as Record<string, unknown>)['protocolVersion']\n : undefined;\n if (version === undefined) {\n diagnostics.push({\n code: 'CRAFT_DEPLOY_MANIFEST_MISSING_FIELD',\n severity: 'error',\n path: 'protocolVersion',\n message: '`protocolVersion` is missing from the serialised manifest.',\n fix: 'Serialise the manifest with `serializeCraftDeploymentManifest`.',\n });\n } else if (version !== CRAFT_DEPLOYMENT_PROTOCOL_VERSION) {\n diagnostics.push({\n code: 'CRAFT_DEPLOY_PROTOCOL_VERSION_UNSUPPORTED',\n severity: 'error',\n path: 'protocolVersion',\n message: `The manifest declares protocol \\`${String(version)}\\` and this tooling reads \\`${CRAFT_DEPLOYMENT_PROTOCOL_VERSION}\\`.`,\n fix: 'Rebuild the manifest with the current CraftTS tooling, or follow the migration notes.',\n });\n }\n\n const validation = validateCraftDeploymentDefinition(parsed);\n diagnostics.push(...validation.diagnostics);\n\n return {\n manifest:\n validation.definition && diagnostics.every((d) => d.severity !== 'error')\n ? resolveCraftDeploymentManifest(validation.definition)\n : null,\n diagnostics,\n };\n}\n\nfunction sortValue(value: unknown): unknown {\n if (Array.isArray(value)) return value.map(sortValue);\n if (typeof value === 'object' && value !== null) {\n const record = value as Record<string, unknown>;\n const sorted: Record<string, unknown> = {};\n for (const key of Object.keys(record).sort()) {\n if (record[key] !== undefined) sorted[key] = sortValue(record[key]);\n }\n return sorted;\n }\n return value;\n}\n\nfunction messageOf(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n"]}
|