run402 1.65.1 → 1.67.0

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.
@@ -16,4 +16,466 @@ export const ROUTE_HTTP_METHODS = [
16
16
  "DELETE",
17
17
  "OPTIONS",
18
18
  ];
19
+ export const EMPTY_STATIC_MANIFEST_METADATA = {
20
+ file_count: 0,
21
+ total_bytes: 0,
22
+ cache_classes: {},
23
+ cache_class_sources: {},
24
+ spa_fallback: null,
25
+ };
26
+ export function normalizeStaticManifestMetadata(metadata) {
27
+ return metadata ?? EMPTY_STATIC_MANIFEST_METADATA;
28
+ }
29
+ export function normalizeDeployResolveRequest(opts) {
30
+ if (!opts || typeof opts !== "object") {
31
+ throw new TypeError("Deploy resolve options must be an object");
32
+ }
33
+ const hasUrl = "url" in opts && opts.url !== undefined;
34
+ const hasHost = "host" in opts && opts.host !== undefined;
35
+ if (hasUrl === hasHost) {
36
+ throw new TypeError("Deploy resolve requires exactly one input form: a full absolute url, or a clean host/path pair.");
37
+ }
38
+ if (!opts.project || typeof opts.project !== "string") {
39
+ throw new TypeError("Deploy resolve requires project");
40
+ }
41
+ const method = normalizeDeployResolveMethod(opts.method);
42
+ if (hasUrl) {
43
+ const original = String(opts.url);
44
+ let parsed;
45
+ try {
46
+ parsed = opts.url instanceof URL ? opts.url : new URL(original);
47
+ }
48
+ catch {
49
+ throw new TypeError("Deploy resolve url must be an absolute HTTP(S) public URL.");
50
+ }
51
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
52
+ throw new TypeError("Deploy resolve url must use http: or https:.");
53
+ }
54
+ if (parsed.username || parsed.password) {
55
+ throw new TypeError("Deploy resolve url must not include username or password credentials.");
56
+ }
57
+ const ignored = {};
58
+ if (parsed.search)
59
+ ignored.query = parsed.search;
60
+ if (parsed.hash)
61
+ ignored.fragment = parsed.hash;
62
+ return {
63
+ project: opts.project,
64
+ project_scope: "credential_lookup_only",
65
+ project_sent_to_gateway: false,
66
+ original_url: original,
67
+ host: parsed.hostname,
68
+ path: parsed.pathname || "/",
69
+ ...(method ? { method } : {}),
70
+ ...(Object.keys(ignored).length > 0 ? { ignored } : {}),
71
+ };
72
+ }
73
+ const host = opts.host;
74
+ if (typeof host !== "string" || host.length === 0) {
75
+ throw new TypeError("Deploy resolve host must be a non-empty hostname.");
76
+ }
77
+ if (/\s/.test(host) ||
78
+ host.includes("/") ||
79
+ host.includes("?") ||
80
+ host.includes("#") ||
81
+ /^[a-z][a-z0-9+.-]*:/i.test(host) ||
82
+ host.includes("@")) {
83
+ throw new TypeError("Deploy resolve host must be a clean hostname without scheme, credentials, path, query, or fragment.");
84
+ }
85
+ const path = opts.path;
86
+ if (path !== undefined) {
87
+ if (typeof path !== "string" || !path.startsWith("/")) {
88
+ throw new TypeError("Deploy resolve path must start with '/'.");
89
+ }
90
+ if (path.includes("?") || path.includes("#")) {
91
+ throw new TypeError("Deploy resolve host/path mode does not accept query strings or fragments in path.");
92
+ }
93
+ }
94
+ return {
95
+ project: opts.project,
96
+ project_scope: "credential_lookup_only",
97
+ project_sent_to_gateway: false,
98
+ host,
99
+ path: path ?? "/",
100
+ ...(method ? { method } : {}),
101
+ };
102
+ }
103
+ export function isDeployResolveStaticHit(response) {
104
+ return (response.match === "static_exact" ||
105
+ response.match === "static_index" ||
106
+ response.match === "spa_fallback");
107
+ }
108
+ export function isDeployResolveRouteHit(response) {
109
+ return !!response.route && typeof response.route === "object";
110
+ }
111
+ export function buildDeployResolveSummary(response, request) {
112
+ const warnings = deployResolveWarningsForRequest(request);
113
+ const next_steps = deployResolveNextSteps(response);
114
+ const would_serve = response.authorized === true &&
115
+ response.result >= 200 &&
116
+ response.result < 400 &&
117
+ response.match !== "host_missing";
118
+ const method = request.method ?? "GET";
119
+ const url = `${method} ${request.original_url ? displayResolveUrl(request) : `https://${request.host}${request.path}`}`;
120
+ const category = deployResolveCategory(response);
121
+ const summary = deployResolveSummaryText(response, url);
122
+ return {
123
+ would_serve,
124
+ diagnostic_status: response.result,
125
+ match: response.match,
126
+ category,
127
+ summary,
128
+ warnings,
129
+ next_steps,
130
+ };
131
+ }
132
+ export function summarizeDeployResult(result) {
133
+ const diff = result.diff ?? {};
134
+ const summary = {
135
+ schema_version: "deploy-summary.v1",
136
+ release_id: result.release_id,
137
+ operation_id: result.operation_id,
138
+ ...(typeof diff.is_noop === "boolean" ? { is_noop: diff.is_noop } : {}),
139
+ headline: "",
140
+ warnings: summarizeDeployWarnings(result.warnings),
141
+ };
142
+ const site = summarizeDeploySite(diff);
143
+ if (site)
144
+ summary.site = site;
145
+ if (isModernFunctionsDiff(diff.functions)) {
146
+ summary.functions = {
147
+ added: [...diff.functions.added],
148
+ removed: [...diff.functions.removed],
149
+ changed: diff.functions.changed.map((entry) => ({
150
+ name: entry.name,
151
+ fields_changed: [...entry.fields_changed],
152
+ })),
153
+ };
154
+ }
155
+ if (isModernPlanMigrationDiff(diff.migrations)) {
156
+ summary.migrations = {
157
+ new: diff.migrations.new.map((entry) => entry.id),
158
+ noop: diff.migrations.noop.map((entry) => entry.id),
159
+ };
160
+ }
161
+ if (isModernRoutesDiff(diff.routes)) {
162
+ summary.routes = summarizeResourceCounts(diff.routes);
163
+ }
164
+ if (isModernSecretsDiff(diff.secrets)) {
165
+ summary.secrets = {
166
+ added: diff.secrets.added.length,
167
+ removed: diff.secrets.removed.length,
168
+ };
169
+ }
170
+ if (isModernSubdomainsDiff(diff.subdomains)) {
171
+ summary.subdomains = {
172
+ added: diff.subdomains.added.length,
173
+ removed: diff.subdomains.removed.length,
174
+ };
175
+ }
176
+ summary.headline = buildDeploySummaryHeadline(summary);
177
+ return summary;
178
+ }
179
+ function summarizeDeployWarnings(warnings) {
180
+ const codes = Array.from(new Set(warnings.map((warning) => warning.code))).sort();
181
+ return {
182
+ count: warnings.length,
183
+ blocking: warnings.filter((warning) => warning.requires_confirmation || warning.code === "MISSING_REQUIRED_SECRET").length,
184
+ codes,
185
+ };
186
+ }
187
+ function summarizeDeploySite(diff) {
188
+ const out = {};
189
+ if (isStaticAssetsDiff(diff.static_assets)) {
190
+ out.paths = {
191
+ added: diff.static_assets.added,
192
+ changed: diff.static_assets.changed,
193
+ removed: diff.static_assets.removed,
194
+ unchanged: diff.static_assets.unchanged,
195
+ total_changed: diff.static_assets.added +
196
+ diff.static_assets.changed +
197
+ diff.static_assets.removed,
198
+ };
199
+ out.cas = {
200
+ newly_uploaded_bytes: diff.static_assets.newly_uploaded_cas_bytes,
201
+ reused_bytes: diff.static_assets.reused_cas_bytes,
202
+ deployment_copy_bytes_eliminated: diff.static_assets.deployment_copy_bytes_eliminated,
203
+ };
204
+ }
205
+ else if (isModernSiteDiff(diff.site)) {
206
+ const added = diff.site.totals?.added ?? diff.site.added.length;
207
+ const changed = diff.site.totals?.changed ?? diff.site.changed.length;
208
+ const removed = diff.site.totals?.removed ?? diff.site.removed.length;
209
+ out.paths = {
210
+ added,
211
+ changed,
212
+ removed,
213
+ total_changed: added + changed + removed,
214
+ };
215
+ }
216
+ return out.paths || out.cas ? out : undefined;
217
+ }
218
+ function summarizeResourceCounts(diff) {
219
+ const added = diff.totals?.added ?? diff.added.length;
220
+ const changed = diff.totals?.changed ?? diff.changed.length;
221
+ const removed = diff.totals?.removed ?? diff.removed.length;
222
+ return { added, changed, removed };
223
+ }
224
+ function isStaticAssetsDiff(value) {
225
+ if (!value || typeof value !== "object" || Array.isArray(value))
226
+ return false;
227
+ const obj = value;
228
+ return (typeof obj.unchanged === "number" &&
229
+ typeof obj.changed === "number" &&
230
+ typeof obj.added === "number" &&
231
+ typeof obj.removed === "number" &&
232
+ typeof obj.newly_uploaded_cas_bytes === "number" &&
233
+ typeof obj.reused_cas_bytes === "number" &&
234
+ typeof obj.deployment_copy_bytes_eliminated === "number");
235
+ }
236
+ function isModernSiteDiff(value) {
237
+ if (!value || typeof value !== "object" || Array.isArray(value))
238
+ return false;
239
+ const obj = value;
240
+ return (Array.isArray(obj.added) &&
241
+ Array.isArray(obj.changed) &&
242
+ Array.isArray(obj.removed));
243
+ }
244
+ function isModernFunctionsDiff(value) {
245
+ if (!value || typeof value !== "object" || Array.isArray(value))
246
+ return false;
247
+ const obj = value;
248
+ return (Array.isArray(obj.added) &&
249
+ Array.isArray(obj.removed) &&
250
+ Array.isArray(obj.changed));
251
+ }
252
+ function isModernPlanMigrationDiff(value) {
253
+ if (!value || typeof value !== "object" || Array.isArray(value))
254
+ return false;
255
+ const obj = value;
256
+ return Array.isArray(obj.new) && Array.isArray(obj.noop);
257
+ }
258
+ function isModernRoutesDiff(value) {
259
+ if (!value || typeof value !== "object" || Array.isArray(value))
260
+ return false;
261
+ const obj = value;
262
+ return Array.isArray(obj.added) && Array.isArray(obj.changed) && Array.isArray(obj.removed);
263
+ }
264
+ function isModernSecretsDiff(value) {
265
+ if (!value || typeof value !== "object" || Array.isArray(value))
266
+ return false;
267
+ const obj = value;
268
+ return Array.isArray(obj.added) && Array.isArray(obj.removed);
269
+ }
270
+ function isModernSubdomainsDiff(value) {
271
+ if (!value || typeof value !== "object" || Array.isArray(value))
272
+ return false;
273
+ const obj = value;
274
+ return Array.isArray(obj.added) && Array.isArray(obj.removed);
275
+ }
276
+ function buildDeploySummaryHeadline(summary) {
277
+ const parts = [];
278
+ const paths = summary.site?.paths;
279
+ if (paths) {
280
+ parts.push(paths.total_changed === 0
281
+ ? "no static path changes"
282
+ : `${formatCount(paths.total_changed, "static path")} changed`);
283
+ }
284
+ const cas = summary.site?.cas;
285
+ if (cas) {
286
+ parts.push(`${formatBytes(cas.newly_uploaded_bytes)} uploaded, ${formatBytes(cas.reused_bytes)} reused`);
287
+ }
288
+ const functions = summary.functions;
289
+ if (functions) {
290
+ const count = functions.added.length + functions.removed.length + functions.changed.length;
291
+ parts.push(count === 0
292
+ ? "no functions changed"
293
+ : `${formatCount(count, "function")} changed`);
294
+ }
295
+ const migrations = summary.migrations;
296
+ if (migrations && migrations.new.length > 0) {
297
+ parts.push(`${formatCount(migrations.new.length, "migration")} new`);
298
+ }
299
+ const routes = summary.routes;
300
+ if (routes) {
301
+ const count = routes.added + routes.changed + routes.removed;
302
+ if (count > 0)
303
+ parts.push(`${formatCount(count, "route")} changed`);
304
+ }
305
+ if (parts.length > 0)
306
+ return parts.join("; ");
307
+ if (summary.is_noop === true)
308
+ return "no deploy changes reported";
309
+ return "deploy summary unavailable";
310
+ }
311
+ function formatCount(count, singular) {
312
+ return `${count} ${singular}${count === 1 ? "" : "s"}`;
313
+ }
314
+ function formatBytes(bytes) {
315
+ if (!Number.isFinite(bytes))
316
+ return `${bytes} B`;
317
+ const units = ["B", "KB", "MB", "GB", "TB"];
318
+ let value = bytes;
319
+ let unitIndex = 0;
320
+ while (Math.abs(value) >= 1000 && unitIndex < units.length - 1) {
321
+ value /= 1000;
322
+ unitIndex += 1;
323
+ }
324
+ if (unitIndex === 0)
325
+ return `${bytes} B`;
326
+ return `${value.toFixed(1)} ${units[unitIndex]}`;
327
+ }
328
+ function normalizeDeployResolveMethod(method) {
329
+ if (method === undefined)
330
+ return undefined;
331
+ if (typeof method !== "string") {
332
+ throw new TypeError("Deploy resolve method must be a string.");
333
+ }
334
+ const normalized = method.trim().toUpperCase();
335
+ if (!/^[A-Z][A-Z0-9!#$%&'*+.^_`|~-]*$/.test(normalized)) {
336
+ throw new TypeError("Deploy resolve method must be a valid HTTP token such as GET, HEAD, POST, or OPTIONS.");
337
+ }
338
+ return normalized;
339
+ }
340
+ function displayResolveUrl(request) {
341
+ if (!request.original_url)
342
+ return `https://${request.host}${request.path}`;
343
+ try {
344
+ const url = new URL(request.original_url);
345
+ return `${url.protocol}//${url.host}${url.pathname || "/"}`;
346
+ }
347
+ catch {
348
+ return `${request.host}${request.path}`;
349
+ }
350
+ }
351
+ function deployResolveWarningsForRequest(request) {
352
+ const warnings = [];
353
+ if (request.ignored?.query) {
354
+ warnings.push({
355
+ code: "query_ignored",
356
+ message: "Query strings do not affect Run402 route resolution.",
357
+ });
358
+ }
359
+ if (request.ignored?.fragment) {
360
+ warnings.push({
361
+ code: "fragment_ignored",
362
+ message: "URL fragments are never sent to the server and do not affect resolution.",
363
+ });
364
+ }
365
+ return warnings;
366
+ }
367
+ function deployResolveCategory(response) {
368
+ if (isDeployResolveRouteHit(response))
369
+ return "route";
370
+ if (isDeployResolveStaticHit(response))
371
+ return "static";
372
+ if (response.match === "host_missing")
373
+ return "host";
374
+ if (response.match === "manifest_missing")
375
+ return "manifest";
376
+ if (response.match === "path_error")
377
+ return "path";
378
+ if (response.match === "spa_fallback_missing")
379
+ return "fallback";
380
+ if (response.match === "none")
381
+ return "miss";
382
+ return "unknown";
383
+ }
384
+ function deployResolveSummaryText(response, url) {
385
+ if (response.match === "host_missing") {
386
+ return `${url} did not resolve because the host is not bound to this account/project context.`;
387
+ }
388
+ if (response.match === "manifest_missing") {
389
+ return `${url} reached the host, but no active static manifest is available for diagnostics.`;
390
+ }
391
+ if (response.match === "path_error") {
392
+ return `${url} could not be evaluated because the path is not a valid Run402 public path.`;
393
+ }
394
+ if (response.match === "none") {
395
+ return `${url} did not match a materialized static file or SPA fallback.`;
396
+ }
397
+ if (response.match === "spa_fallback_missing") {
398
+ return `${url} was eligible for SPA fallback, but the configured fallback file is missing.`;
399
+ }
400
+ if (response.match === "spa_fallback") {
401
+ return `${url} would serve the configured SPA fallback.`;
402
+ }
403
+ if (response.match === "static_index") {
404
+ return `${url} would serve a static index file.`;
405
+ }
406
+ if (response.match === "static_exact") {
407
+ return `${url} would serve an exact static file.`;
408
+ }
409
+ if (isDeployResolveRouteHit(response)) {
410
+ return `${url} matched a deploy route.`;
411
+ }
412
+ if (response.result >= 200 && response.result < 400) {
413
+ return `${url} resolved with gateway match ${String(response.match)}.`;
414
+ }
415
+ return `${url} did not resolve to a servable public response; gateway match was ${String(response.match)}.`;
416
+ }
417
+ function deployResolveNextSteps(response) {
418
+ switch (response.match) {
419
+ case "host_missing":
420
+ return [
421
+ {
422
+ code: "check_domain_binding",
423
+ message: "Check that the host is configured as a Run402 custom domain or subdomain.",
424
+ },
425
+ {
426
+ code: "check_dns",
427
+ message: "Check DNS and domain binding status.",
428
+ },
429
+ {
430
+ code: "check_credentials",
431
+ message: "Check that the selected local project credentials can inspect this host.",
432
+ },
433
+ ];
434
+ case "manifest_missing":
435
+ return [
436
+ {
437
+ code: "check_active_release",
438
+ message: "Check that the project has an active deploy-v2 release.",
439
+ },
440
+ {
441
+ code: "redeploy_static_site",
442
+ message: "Deploy static site content again if the active release predates static manifest metadata.",
443
+ },
444
+ ];
445
+ case "path_error":
446
+ return [
447
+ {
448
+ code: "check_public_path",
449
+ message: "Use an absolute URL path that starts with '/' and does not contain invalid encoded segments.",
450
+ },
451
+ ];
452
+ case "none":
453
+ return [
454
+ {
455
+ code: "check_static_path",
456
+ message: "Check the active release site.paths inventory for the requested file.",
457
+ },
458
+ {
459
+ code: "check_spa_fallback",
460
+ message: "Check whether the release has a configured SPA fallback.",
461
+ },
462
+ ];
463
+ case "spa_fallback_missing":
464
+ return [
465
+ {
466
+ code: "restore_spa_fallback",
467
+ message: "Deploy the configured SPA fallback file or remove the fallback declaration.",
468
+ },
469
+ ];
470
+ default:
471
+ return response.result >= 200 && response.result < 400
472
+ ? []
473
+ : [
474
+ {
475
+ code: "inspect_resolution",
476
+ message: "Inspect the full resolution payload for gateway-specific fields.",
477
+ },
478
+ ];
479
+ }
480
+ }
19
481
  //# sourceMappingURL=deploy.types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.types.js","sourceRoot":"","sources":["../../src/namespaces/deploy.types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAgKH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,KAAK;IACL,MAAM;IACN,MAAM;IACN,KAAK;IACL,OAAO;IACP,QAAQ;IACR,SAAS;CACD,CAAC"}
1
+ {"version":3,"file":"deploy.types.js","sourceRoot":"","sources":["../../src/namespaces/deploy.types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"deploy-manifest.d.ts","sourceRoot":"","sources":["../../src/node/deploy-manifest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"deploy-manifest.d.ts","sourceRoot":"","sources":["../../src/node/deploy-manifest.ts"],"names":[],"mappings":"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"}
@@ -41,7 +41,8 @@ const MANIFEST_SITE_FIELDS = new Set(["replace", "patch"]);
41
41
  const MANIFEST_SITE_PATCH_FIELDS = new Set(["put", "delete"]);
42
42
  const MANIFEST_ROUTES_FIELDS = new Set(["replace"]);
43
43
  const MANIFEST_ROUTE_ENTRY_FIELDS = new Set(["pattern", "methods", "target"]);
44
- const MANIFEST_ROUTE_TARGET_FIELDS = new Set(["type", "name"]);
44
+ const MANIFEST_FUNCTION_ROUTE_TARGET_FIELDS = new Set(["type", "name"]);
45
+ const MANIFEST_STATIC_ROUTE_TARGET_FIELDS = new Set(["type", "file"]);
45
46
  const ROUTE_METHOD_SET = new Set(ROUTE_HTTP_METHODS);
46
47
  export async function loadDeployManifest(path, opts = {}) {
47
48
  const manifestPath = isAbsolute(path) ? path : resolvePath(process.cwd(), path);
@@ -271,7 +272,7 @@ function mapRoutes(routes) {
271
272
  assertPlainRecord(routes, "Deploy manifest routes");
272
273
  assertKnownFields(routes, "Deploy manifest routes", MANIFEST_ROUTES_FIELDS, routeShapeHints(routes));
273
274
  if (!Object.prototype.hasOwnProperty.call(routes, "replace")) {
274
- throw new LocalError("Deploy manifest routes must be null or { \"replace\": [{ \"pattern\": \"/api/*\", \"target\": { \"type\": \"function\", \"name\": \"api\" } }] }. Path-keyed route maps are not supported.", CONTEXT);
275
+ throw new LocalError("Deploy manifest routes must be null or { \"replace\": [{ \"pattern\": \"/api/*\", \"target\": { \"type\": \"function\", \"name\": \"api\" } }, { \"pattern\": \"/events\", \"methods\": [\"GET\"], \"target\": { \"type\": \"static\", \"file\": \"events.html\" } }] }. Path-keyed route maps are not supported.", CONTEXT);
275
276
  }
276
277
  const replace = routes.replace;
277
278
  if (!Array.isArray(replace)) {
@@ -284,7 +285,7 @@ function routeShapeHints(obj) {
284
285
  const hints = {};
285
286
  for (const key of Object.keys(obj)) {
286
287
  if (key.startsWith("/")) {
287
- hints[key] = "Use routes.replace[] entries like { pattern, target: { type: \"function\", name } } instead of a path-keyed route map.";
288
+ hints[key] = "Use routes.replace[] entries like { pattern, target: { type: \"function\", name } } or { pattern, methods: [\"GET\"], target: { type: \"static\", file } } instead of a path-keyed route map.";
288
289
  }
289
290
  }
290
291
  return hints;
@@ -308,24 +309,70 @@ function validateManifestRouteEntry(route, index) {
308
309
  throw new LocalError(`${label}.methods contains unsupported method ${JSON.stringify(method)}. Supported methods: ${ROUTE_HTTP_METHODS.join(", ")}`, CONTEXT);
309
310
  }
310
311
  }
312
+ const seen = new Set();
313
+ for (const method of route.methods) {
314
+ if (seen.has(method)) {
315
+ throw new LocalError(`${label}.methods contains duplicate method ${JSON.stringify(method)}`, CONTEXT);
316
+ }
317
+ seen.add(method);
318
+ }
311
319
  }
312
- validateManifestRouteTarget(route.target, `${label}.target`);
320
+ const targetType = validateManifestRouteTarget(route.target, `${label}.target`);
321
+ if (targetType === "static")
322
+ validateManifestStaticRouteEntry(route, label);
313
323
  }
314
324
  function validateManifestRouteTarget(target, label) {
315
325
  assertPlainRecord(target, label);
316
- if (Object.prototype.hasOwnProperty.call(target, "function") &&
326
+ if ((Object.prototype.hasOwnProperty.call(target, "function") ||
327
+ Object.prototype.hasOwnProperty.call(target, "static")) &&
317
328
  !Object.prototype.hasOwnProperty.call(target, "type")) {
318
- throw new LocalError(`${label} uses unsupported target shorthand. Use { "type": "function", "name": "api" }.`, CONTEXT);
329
+ throw new LocalError(`${label} uses unsupported target shorthand. Use { "type": "function", "name": "api" } or { "type": "static", "file": "events.html" }.`, CONTEXT);
319
330
  }
320
- assertKnownFields(target, label, MANIFEST_ROUTE_TARGET_FIELDS);
321
331
  if (target.type === undefined) {
322
- throw new LocalError(`${label}.type is required; use "function"`, CONTEXT);
332
+ throw new LocalError(`${label}.type is required; use "function" or "static"`, CONTEXT);
323
333
  }
324
- if (target.type !== "function") {
325
- throw new LocalError(`${label}.type must be "function"; Phase 1 routes do not support ${JSON.stringify(target.type)}`, CONTEXT);
334
+ if (target.type === "function") {
335
+ assertKnownFields(target, label, MANIFEST_FUNCTION_ROUTE_TARGET_FIELDS);
336
+ if (typeof target.name !== "string" || target.name.length === 0) {
337
+ throw new LocalError(`${label}.name is required for function route targets`, CONTEXT);
338
+ }
339
+ return "function";
340
+ }
341
+ if (target.type === "static") {
342
+ assertKnownFields(target, label, MANIFEST_STATIC_ROUTE_TARGET_FIELDS);
343
+ if (typeof target.file !== "string" || target.file.length === 0) {
344
+ throw new LocalError(`${label}.file is required for static route targets`, CONTEXT);
345
+ }
346
+ validateManifestStaticTargetFile(target.file, `${label}.file`);
347
+ return "static";
326
348
  }
327
- if (typeof target.name !== "string" || target.name.length === 0) {
328
- throw new LocalError(`${label}.name is required for function route targets`, CONTEXT);
349
+ throw new LocalError(`${label}.type must be "function" or "static"; got ${JSON.stringify(target.type)}`, CONTEXT);
350
+ }
351
+ function validateManifestStaticRouteEntry(route, label) {
352
+ const pattern = route.pattern;
353
+ if (pattern.includes("*")) {
354
+ throw new LocalError(`${label}.pattern uses a static route target, so it must be an exact path pattern; wildcard static route targets such as /docs/* are not supported`, CONTEXT);
355
+ }
356
+ if (route.methods === undefined) {
357
+ throw new LocalError(`${label}.methods is required for static route targets; use ["GET"] or ["GET", "HEAD"]`, CONTEXT);
358
+ }
359
+ const methods = route.methods;
360
+ const methodSet = new Set(methods);
361
+ const valid = methodSet.has("GET") &&
362
+ (methodSet.size === 1 || (methodSet.size === 2 && methodSet.has("HEAD")));
363
+ if (!valid) {
364
+ throw new LocalError(`${label}.methods for static route targets must be ["GET"] or ["GET", "HEAD"]; either form materializes effective GET plus HEAD`, CONTEXT);
365
+ }
366
+ }
367
+ function validateManifestStaticTargetFile(file, label) {
368
+ const invalid = file.startsWith("/") ||
369
+ file.includes("?") ||
370
+ file.includes("#") ||
371
+ file.includes("\\") ||
372
+ file.endsWith("/") ||
373
+ file.split("/").some((segment) => segment === "" || segment === "." || segment === "..");
374
+ if (invalid) {
375
+ throw new LocalError(`${label} must be a relative materialized static-site file path without leading slash, query, fragment, traversal, empty segments, backslashes, or directory shorthand`, CONTEXT);
329
376
  }
330
377
  }
331
378
  function mapFileSet(map, opts) {