vite-plugin-vercel 8.0.0 → 9.0.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.
package/dist/index.js CHANGED
@@ -1,210 +1,17 @@
1
1
  // src/index.ts
2
- import fs5 from "fs/promises";
3
-
4
- // src/utils.ts
5
- import { normalizePath } from "vite";
6
- import path from "path";
7
- function getRoot(config) {
8
- return normalizePath(config.root || process.cwd());
9
- }
10
- function getOutput(config, suffix) {
11
- return path.join(
12
- config.vercel?.outDir ? "" : getRoot(config),
13
- config.vercel?.outDir ?? ".vercel/output",
14
- suffix ?? ""
15
- );
16
- }
17
- function getPublic(config) {
18
- return path.join(getRoot(config), config.publicDir || "public");
19
- }
20
- function pathRelativeTo(filePath, config, rel) {
21
- const root = getRoot(config);
22
- return normalizePath(
23
- path.relative(normalizePath(path.join(root, rel)), filePath)
24
- );
25
- }
26
-
27
- // src/config.ts
28
- import path2 from "path";
29
-
30
- // src/schemas/config/config.ts
31
- import { z } from "zod";
32
- var HasOrMissing = z.array(
33
- z.union([
34
- z.object({
35
- type: z.literal("host"),
36
- value: z.string()
37
- }).strict(),
38
- z.object({
39
- type: z.literal("header"),
40
- key: z.string(),
41
- value: z.string().optional()
42
- }).strict(),
43
- z.object({
44
- type: z.literal("cookie"),
45
- key: z.string(),
46
- value: z.string().optional()
47
- }).strict(),
48
- z.object({
49
- type: z.literal("query"),
50
- key: z.string(),
51
- value: z.string().optional()
52
- }).strict()
53
- ])
54
- ).optional();
55
- var vercelOutputConfigSchema = z.object({
56
- version: z.literal(3),
57
- routes: z.array(
58
- z.union([
59
- z.object({
60
- src: z.string(),
61
- dest: z.string().optional(),
62
- headers: z.record(z.string()).optional(),
63
- methods: z.array(z.string()).optional(),
64
- status: z.number().int().positive().optional(),
65
- continue: z.boolean().optional(),
66
- check: z.boolean().optional(),
67
- missing: HasOrMissing,
68
- has: HasOrMissing,
69
- locale: z.object({
70
- redirect: z.record(z.string()).optional(),
71
- cookie: z.string().optional()
72
- }).strict().optional(),
73
- middlewarePath: z.string().optional()
74
- }).strict(),
75
- z.object({
76
- handle: z.union([
77
- z.literal("rewrite"),
78
- z.literal("filesystem"),
79
- z.literal("resource"),
80
- z.literal("miss"),
81
- z.literal("hit"),
82
- z.literal("error")
83
- ]),
84
- src: z.string().optional(),
85
- dest: z.string().optional(),
86
- status: z.number().optional()
87
- }).strict()
88
- ])
89
- ).optional(),
90
- images: z.object({
91
- sizes: z.tuple([
92
- z.number().int().positive(),
93
- z.number().int().positive()
94
- ]),
95
- domains: z.array(z.string()).nonempty().optional(),
96
- minimumCacheTTL: z.number().int().positive().optional(),
97
- formats: z.union([z.literal("image/avif"), z.literal("image/webp")]).array().nonempty().optional(),
98
- dangerouslyAllowSVG: z.boolean().optional(),
99
- contentSecurityPolicy: z.string().optional()
100
- }).strict().optional(),
101
- wildcard: z.array(
102
- z.object({
103
- domain: z.string(),
104
- value: z.string()
105
- }).strict()
106
- ).optional(),
107
- overrides: z.record(
108
- z.object({
109
- path: z.string().optional(),
110
- contentType: z.string().optional()
111
- }).strict()
112
- ).optional(),
113
- cache: z.array(z.string()).optional()
114
- }).strict();
115
-
116
- // src/config.ts
117
- import fs from "fs/promises";
118
- import {
119
- getTransformedRoutes,
120
- mergeRoutes,
121
- normalizeRoutes
122
- } from "@vercel/routing-utils";
123
- function reorderEnforce(arr) {
124
- return [
125
- ...arr.filter((r) => r.enforce === "pre"),
126
- ...arr.filter((r) => !r.enforce),
127
- ...arr.filter((r) => r.enforce === "post")
128
- ];
129
- }
130
- function getConfig(resolvedConfig, rewrites, overrides, headers) {
131
- const _rewrites = [
132
- // User provided config always comes first
133
- ...resolvedConfig.vercel?.rewrites ?? [],
134
- ...rewrites ?? []
135
- ];
136
- const { routes, error } = getTransformedRoutes({
137
- cleanUrls: resolvedConfig.vercel?.cleanUrls ?? true,
138
- trailingSlash: resolvedConfig.vercel?.trailingSlash,
139
- rewrites: reorderEnforce(_rewrites),
140
- redirects: resolvedConfig.vercel?.redirects ? reorderEnforce(resolvedConfig.vercel?.redirects) : void 0,
141
- headers
142
- });
143
- if (error) {
144
- throw error;
145
- }
146
- if (resolvedConfig.vercel?.config?.routes && resolvedConfig.vercel.config.routes.length > 0 && !resolvedConfig.vercel.config.routes.every(
147
- (r) => "continue" in r && r.continue
148
- )) {
149
- console.warn(
150
- 'Did you forget to add `"continue": true` to your routes? See https://vercel.com/docs/build-output-api/v3/configuration#source-route\nIf not, it is discouraged to use `vercel.config.routes` to override routes. Prefer using `vercel.rewrites` and `vercel.redirects`.'
151
- );
152
- }
153
- let userRoutes = [];
154
- let buildRoutes = [];
155
- if (resolvedConfig.vercel?.config?.routes) {
156
- const norm = normalizeRoutes(resolvedConfig.vercel.config.routes);
157
- if (norm.error) {
158
- throw norm.error;
159
- }
160
- userRoutes = norm.routes ?? [];
161
- }
162
- if (routes) {
163
- const norm = normalizeRoutes(routes);
164
- if (norm.error) {
165
- throw norm.error;
166
- }
167
- buildRoutes = norm.routes ?? [];
168
- }
169
- const cleanRoutes = mergeRoutes({
170
- userRoutes,
171
- builds: [
172
- {
173
- use: "@vercel/node",
174
- entrypoint: "index.js",
175
- routes: buildRoutes
176
- }
177
- ]
178
- });
179
- return vercelOutputConfigSchema.parse({
180
- version: 3,
181
- ...resolvedConfig.vercel?.config,
182
- routes: cleanRoutes,
183
- overrides: {
184
- ...resolvedConfig.vercel?.config?.overrides,
185
- ...overrides
186
- }
187
- });
188
- }
189
- function getConfigDestination(resolvedConfig) {
190
- return path2.join(getOutput(resolvedConfig), "config.json");
191
- }
192
- async function writeConfig(resolvedConfig, rewrites, overrides, headers) {
193
- await fs.writeFile(
194
- getConfigDestination(resolvedConfig),
195
- JSON.stringify(
196
- getConfig(resolvedConfig, rewrites, overrides, headers),
197
- void 0,
198
- 2
199
- ),
200
- "utf-8"
201
- );
202
- }
2
+ import fs5 from "node:fs/promises";
3
+ import path6 from "node:path";
203
4
 
204
5
  // src/build.ts
205
- import glob from "fast-glob";
206
- import path3, { basename } from "path";
6
+ import fs, { copyFile } from "node:fs/promises";
7
+ import { builtinModules } from "node:module";
8
+ import path2, { basename } from "node:path";
9
+ import { findRoot } from "@manypkg/find-root";
10
+ import { getNodeVersion } from "@vercel/build-utils";
11
+ import { nodeFileTrace } from "@vercel/nft";
207
12
  import { build } from "esbuild";
13
+ import glob from "fast-glob";
14
+ import { generateCode, loadFile } from "magicast";
208
15
 
209
16
  // src/assert.ts
210
17
  import { newError } from "@brillout/libassert";
@@ -218,83 +25,111 @@ function assert(condition, errorMessage) {
218
25
  }
219
26
 
220
27
  // src/schemas/config/vc-config.ts
221
- import { z as z2 } from "zod";
222
- var vercelOutputEdgeVcConfigSchema = z2.object({
223
- runtime: z2.literal("edge"),
224
- entrypoint: z2.string(),
225
- envVarsInUse: z2.array(z2.string()).optional()
28
+ import { z } from "zod";
29
+ var vercelOutputEdgeVcConfigSchema = z.object({
30
+ runtime: z.literal("edge"),
31
+ entrypoint: z.string(),
32
+ envVarsInUse: z.array(z.string()).optional()
226
33
  }).strict();
227
- var vercelOutputServerlessVcConfigSchema = z2.object({
228
- runtime: z2.string(),
229
- handler: z2.string(),
230
- memory: z2.number().int().min(128).max(3008).optional(),
231
- maxDuration: z2.number().int().positive().optional(),
232
- environment: z2.record(z2.string()).optional(),
233
- regions: z2.array(z2.string()).optional(),
234
- supportsWrapper: z2.boolean().optional(),
235
- supportsResponseStreaming: z2.boolean().optional()
34
+ var vercelOutputServerlessVcConfigSchema = z.object({
35
+ runtime: z.string(),
36
+ handler: z.string(),
37
+ memory: z.number().int().min(128).max(3008).optional(),
38
+ maxDuration: z.number().int().positive().optional(),
39
+ environment: z.record(z.string()).optional(),
40
+ regions: z.array(z.string()).optional(),
41
+ supportsWrapper: z.boolean().optional(),
42
+ supportsResponseStreaming: z.boolean().optional()
236
43
  }).strict();
237
44
  var vercelOutputServerlessNodeVcConfigSchema = vercelOutputServerlessVcConfigSchema.extend({
238
- launcherType: z2.literal("Nodejs"),
239
- shouldAddHelpers: z2.boolean().optional(),
240
- shouldAddSourcemapSupport: z2.boolean().optional(),
241
- awsLambdaHandler: z2.string().optional()
45
+ launcherType: z.literal("Nodejs"),
46
+ shouldAddHelpers: z.boolean().optional(),
47
+ shouldAddSourcemapSupport: z.boolean().optional(),
48
+ awsLambdaHandler: z.string().optional()
242
49
  }).strict();
243
- var vercelOutputVcConfigSchema = z2.union([
50
+ var vercelOutputVcConfigSchema = z.union([
244
51
  vercelOutputEdgeVcConfigSchema,
245
52
  vercelOutputServerlessVcConfigSchema,
246
53
  vercelOutputServerlessNodeVcConfigSchema
247
54
  ]);
248
55
 
249
- // src/build.ts
250
- import fs2, { copyFile } from "fs/promises";
251
-
252
56
  // src/schemas/exports.ts
253
- import { z as z3 } from "zod";
254
- var vercelEndpointExports = z3.object({
255
- edge: z3.boolean().optional(),
256
- headers: z3.record(z3.string()).optional(),
257
- streaming: z3.boolean().optional(),
258
- isr: z3.object({
259
- expiration: z3.number().or(z3.literal(false))
57
+ import { z as z2 } from "zod";
58
+ var vercelEndpointExports = z2.object({
59
+ edge: z2.boolean().optional(),
60
+ headers: z2.record(z2.string()).optional(),
61
+ streaming: z2.boolean().optional(),
62
+ isr: z2.object({
63
+ expiration: z2.number().or(z2.literal(false))
260
64
  }).optional()
261
65
  });
262
66
 
67
+ // src/utils.ts
68
+ import { normalizePath } from "vite";
69
+ import path from "node:path";
70
+ function getRoot(config) {
71
+ return normalizePath(config.root || process.cwd());
72
+ }
73
+ function getOutput(config, suffix) {
74
+ return path.join(
75
+ config.vercel?.outDir ? "" : getRoot(config),
76
+ config.vercel?.outDir ?? ".vercel/output",
77
+ suffix ?? ""
78
+ );
79
+ }
80
+ function getPublic(config) {
81
+ return path.join(getRoot(config), config.publicDir || "public");
82
+ }
83
+ function pathRelativeTo(filePath, config, rel) {
84
+ const root = getRoot(config);
85
+ return normalizePath(path.relative(normalizePath(path.join(root, rel)), filePath));
86
+ }
87
+
263
88
  // src/build.ts
264
- import { generateCode, loadFile } from "magicast";
265
- import { getNodeVersion } from "@vercel/build-utils";
266
- import { nodeFileTrace } from "@vercel/nft";
267
- import { findRoot } from "@manypkg/find-root";
268
- function getAdditionalEndpoints(resolvedConfig) {
269
- return (resolvedConfig.vercel?.additionalEndpoints ?? []).map((e) => ({
89
+ async function getAdditionalEndpoints(resolvedConfig) {
90
+ const userEndpoints = [];
91
+ if (Array.isArray(resolvedConfig.vercel?.additionalEndpoints)) {
92
+ for (const endpoint of resolvedConfig.vercel.additionalEndpoints) {
93
+ if (typeof endpoint === "function") {
94
+ const res = await endpoint();
95
+ if (Array.isArray(res)) {
96
+ userEndpoints.push(...res);
97
+ } else {
98
+ userEndpoints.push(res);
99
+ }
100
+ } else {
101
+ userEndpoints.push(endpoint);
102
+ }
103
+ }
104
+ }
105
+ return userEndpoints.map((e) => ({
270
106
  ...e,
271
- addRoute: e.addRoute ?? true,
107
+ route: e.route ?? true,
272
108
  // path.resolve removes the trailing slash if any
273
- destination: path3.posix.resolve("/", e.destination) + ".func"
109
+ destination: `${path2.posix.resolve("/", e.destination)}.func`
274
110
  }));
275
111
  }
276
- function getEntries(resolvedConfig) {
277
- const apiEntries = glob.sync(`${getRoot(resolvedConfig)}/api/**/*.*([a-zA-Z0-9])`).filter((filepath) => !path3.basename(filepath).startsWith("_"));
112
+ async function getEntries(resolvedConfig) {
113
+ const apiEntries = glob.sync(`${getRoot(resolvedConfig)}/api/**/*.*([a-zA-Z0-9])`).filter((filepath) => !path2.basename(filepath).startsWith("_"));
278
114
  if (apiEntries.length > 0) {
279
115
  console.warn(
280
116
  "@vercel/build is currently force building /api files itself, with no way to disable it. In order to avoid double compilation, you should temporarily rename /api to /_api while using this plugin. /_api functions are compiled under .vercel/output/functions/api/*.func as if they were in /api."
281
117
  );
282
118
  }
283
- const otherApiEntries = glob.sync(`${getRoot(resolvedConfig)}/_api/**/*.*([a-zA-Z0-9])`).filter((filepath) => !path3.basename(filepath).startsWith("_"));
284
- return [...apiEntries, ...otherApiEntries].reduce((entryPoints, filePath) => {
285
- const outFilePath = pathRelativeTo(
286
- filePath,
287
- resolvedConfig,
288
- filePath.includes("/_api/") ? "_api" : "api"
289
- );
290
- const parsed = path3.posix.parse(outFilePath);
291
- entryPoints.push({
292
- source: filePath,
293
- destination: `api/${path3.posix.join(parsed.dir, parsed.name)}.func`,
294
- addRoute: true
295
- });
296
- return entryPoints;
297
- }, getAdditionalEndpoints(resolvedConfig));
119
+ const otherApiEntries = glob.sync(`${getRoot(resolvedConfig)}/_api/**/*.*([a-zA-Z0-9])`).filter((filepath) => !path2.basename(filepath).startsWith("_"));
120
+ return [...apiEntries, ...otherApiEntries].reduce(
121
+ (entryPoints, filePath) => {
122
+ const outFilePath = pathRelativeTo(filePath, resolvedConfig, filePath.includes("/_api/") ? "_api" : "api");
123
+ const parsed = path2.posix.parse(outFilePath);
124
+ entryPoints.push({
125
+ source: filePath,
126
+ destination: `api/${path2.posix.join(parsed.dir, parsed.name)}.func`,
127
+ route: true
128
+ });
129
+ return entryPoints;
130
+ },
131
+ await getAdditionalEndpoints(resolvedConfig)
132
+ );
298
133
  }
299
134
  var edgeWasmPlugin = {
300
135
  name: "edge-wasm-vercel",
@@ -349,35 +184,21 @@ async function buildFn(resolvedConfig, entry, buildOptions) {
349
184
  Object.assign(options, buildOptions);
350
185
  }
351
186
  const filename = entry.edge || options.format === "cjs" ? "index.js" : "index.mjs";
352
- const outfile = path3.join(
353
- getOutput(resolvedConfig, "functions"),
354
- entry.destination,
355
- filename
356
- );
187
+ const outfile = path2.join(getOutput(resolvedConfig, "functions"), entry.destination, filename);
357
188
  Object.assign(options, { outfile });
358
189
  if (!options.stdin) {
359
190
  if (typeof entry.source === "string") {
360
191
  options.entryPoints = [entry.source];
361
192
  } else {
362
- assert(
363
- typeof entry.source === "object",
364
- `\`{ source }\` must be a string or an object`
365
- );
366
- assert(
367
- typeof entry.source.contents === "string",
368
- `\`{ contents }\` must be a string`
369
- );
193
+ assert(typeof entry.source === "object", "`{ source }` must be a string or an object");
194
+ assert(typeof entry.source.contents === "string", "`{ contents }` must be a string");
370
195
  options.stdin = entry.source;
371
196
  }
372
197
  }
373
198
  if (entry.edge) {
374
- options.conditions = [
375
- "edge-light",
376
- "browser",
377
- "module",
378
- "import",
379
- "require"
380
- ];
199
+ options.platform = void 0;
200
+ options.external = [...builtinModules, ...builtinModules.map((m) => `node:${m}`)];
201
+ options.conditions = ["edge-light", "worker", "browser", "module", "import", "require"];
381
202
  options.plugins?.push(edgeWasmPlugin);
382
203
  options.format = "esm";
383
204
  } else if (options.format === "esm") {
@@ -392,9 +213,9 @@ const __dirname = VPV_dirname(__filename);
392
213
  };
393
214
  }
394
215
  const ctx = { found: false, index: "" };
395
- options.plugins.push(vercelOgPlugin(ctx));
216
+ options.plugins?.push(vercelOgPlugin(ctx));
396
217
  const output = await build(options);
397
- if (typeof entry.source == "string") {
218
+ if (typeof entry.source === "string") {
398
219
  let base = resolvedConfig.root;
399
220
  try {
400
221
  const dir = await findRoot(resolvedConfig.root);
@@ -421,18 +242,14 @@ const __dirname = VPV_dirname(__filename);
421
242
  });
422
243
  return result.outputFiles[0].text;
423
244
  }
424
- return fs2.readFile(filepath, "utf-8");
245
+ return fs.readFile(filepath, "utf-8");
425
246
  }
426
247
  });
427
248
  for (const file of fileList) {
428
- if (reasons.has(file) && reasons.get(file).type.includes("asset") && !file.endsWith(".js") && !file.endsWith(".cjs") && !file.endsWith(".mjs") && !file.endsWith("package.json")) {
249
+ if (reasons.has(file) && reasons.get(file)?.type.includes("asset") && !file.endsWith(".js") && !file.endsWith(".cjs") && !file.endsWith(".mjs") && !file.endsWith("package.json")) {
429
250
  await copyFile(
430
- path3.join(base, file),
431
- path3.join(
432
- getOutput(resolvedConfig, "functions"),
433
- entry.destination,
434
- basename(file)
435
- )
251
+ path2.join(base, file),
252
+ path2.join(getOutput(resolvedConfig, "functions"), entry.destination, basename(file))
436
253
  );
437
254
  }
438
255
  }
@@ -444,13 +261,9 @@ const __dirname = VPV_dirname(__filename);
444
261
  return output;
445
262
  }
446
263
  async function writeVcConfig(resolvedConfig, destination, filename, options) {
447
- const vcConfig = path3.join(
448
- getOutput(resolvedConfig, "functions"),
449
- destination,
450
- ".vc-config.json"
451
- );
264
+ const vcConfig = path2.join(getOutput(resolvedConfig, "functions"), destination, ".vc-config.json");
452
265
  const nodeVersion = await getNodeVersion(getOutput(resolvedConfig));
453
- await fs2.writeFile(
266
+ await fs.writeFile(
454
267
  vcConfig,
455
268
  JSON.stringify(
456
269
  vercelOutputVcConfigSchema.parse(
@@ -474,9 +287,9 @@ async function writeVcConfig(resolvedConfig, destination, filename, options) {
474
287
  }
475
288
  function getSourceAndDestination(destination) {
476
289
  if (destination.startsWith("api/")) {
477
- return path3.posix.resolve("/", destination);
290
+ return path2.posix.resolve("/", destination);
478
291
  }
479
- return path3.posix.resolve("/", destination, ":match*");
292
+ return path2.posix.resolve("/", destination, ":match*");
480
293
  }
481
294
  var RE_BRACKETS = /^\[([^/]+)\]$/gm;
482
295
  function replaceBrackets(source) {
@@ -509,7 +322,7 @@ async function extractExports(filepath) {
509
322
  }
510
323
  }
511
324
  async function buildEndpoints(resolvedConfig) {
512
- const entries = getEntries(resolvedConfig);
325
+ const entries = await getEntries(resolvedConfig);
513
326
  for (const entry of entries) {
514
327
  if (typeof entry.source === "string") {
515
328
  const exports = await extractExports(entry.source);
@@ -533,6 +346,9 @@ async function buildEndpoints(resolvedConfig) {
533
346
  `isr configuration should be defined either in the endpoint itself or through Vite config, not both ('${entry.source}')`
534
347
  );
535
348
  }
349
+ if ((entry.isr !== void 0 || exports.isr !== void 0) && (entry.edge !== void 0 || exports.edge !== void 0)) {
350
+ throw new Error(`isr cannot be enabled for edge functions ('${entry.source}')`);
351
+ }
536
352
  if (exports.isr) {
537
353
  entry.isr = exports.isr;
538
354
  }
@@ -543,21 +359,36 @@ async function buildEndpoints(resolvedConfig) {
543
359
  }
544
360
  await buildFn(resolvedConfig, entry);
545
361
  }
546
- const isrEntries = entries.filter((e) => e.isr).map(
547
- (e) => [
548
- e.destination.replace(/\.func$/, ""),
549
- { expiration: e.isr.expiration }
550
- ]
551
- );
362
+ const isrEntries = entries.filter((e) => e.isr).map((e) => [e.destination.replace(/\.func$/, ""), { expiration: e.isr?.expiration }]);
552
363
  return {
553
- rewrites: entries.filter((e) => e.addRoute !== false).map((e) => e.destination.replace(/\.func$/, "")).map((destination) => ({
554
- source: replaceBrackets(getSourceAndDestination(destination)),
555
- destination: getSourceAndDestination(destination)
556
- })),
364
+ rewrites: entries.filter((e) => {
365
+ if (e.addRoute === void 0 && e.route !== void 0) {
366
+ return e.route !== false;
367
+ }
368
+ if (e.addRoute !== void 0 && e.route === void 0) {
369
+ return e.addRoute !== false;
370
+ }
371
+ if (e.addRoute !== void 0 && e.route !== void 0) {
372
+ throw new Error("Cannot use both `route` and `addRoute` in `additionalEndpoints`");
373
+ }
374
+ return true;
375
+ }).map((e) => {
376
+ const destination = e.destination.replace(/\.func$/, "");
377
+ if (typeof e.route === "string") {
378
+ return {
379
+ source: `(${e.route})`,
380
+ destination: `${destination}/?__original_path=$1`
381
+ };
382
+ }
383
+ return {
384
+ source: replaceBrackets(getSourceAndDestination(destination)),
385
+ destination: getSourceAndDestination(destination)
386
+ };
387
+ }),
557
388
  isr: Object.fromEntries(isrEntries),
558
389
  headers: entries.filter((e) => e.headers).map((e) => ({
559
- source: "/" + e.destination.replace(/\.func$/, ""),
560
- headers: Object.entries(e.headers).map(([key, value]) => ({
390
+ source: `/${e.destination.replace(/\.func$/, "")}`,
391
+ headers: Object.entries(e.headers ?? {}).map(([key, value]) => ({
561
392
  key,
562
393
  value
563
394
  }))
@@ -565,25 +396,177 @@ async function buildEndpoints(resolvedConfig) {
565
396
  };
566
397
  }
567
398
 
568
- // src/prerender.ts
569
- import path5 from "path";
399
+ // src/config.ts
400
+ import path3 from "node:path";
570
401
 
571
- // src/schemas/config/prerender-config.ts
572
- import { z as z4 } from "zod";
573
- var vercelOutputPrerenderConfigSchema = z4.object({
574
- expiration: z4.union([z4.number().int().positive(), z4.literal(false)]),
575
- group: z4.number().int().optional(),
576
- bypassToken: z4.string().optional(),
577
- fallback: z4.string().optional(),
578
- allowQuery: z4.array(z4.string()).optional()
402
+ // src/schemas/config/config.ts
403
+ import { z as z3 } from "zod";
404
+ var HasOrMissing = z3.array(
405
+ z3.union([
406
+ z3.object({
407
+ type: z3.literal("host"),
408
+ value: z3.string()
409
+ }).strict(),
410
+ z3.object({
411
+ type: z3.literal("header"),
412
+ key: z3.string(),
413
+ value: z3.string().optional()
414
+ }).strict(),
415
+ z3.object({
416
+ type: z3.literal("cookie"),
417
+ key: z3.string(),
418
+ value: z3.string().optional()
419
+ }).strict(),
420
+ z3.object({
421
+ type: z3.literal("query"),
422
+ key: z3.string(),
423
+ value: z3.string().optional()
424
+ }).strict()
425
+ ])
426
+ ).optional();
427
+ var vercelOutputConfigSchema = z3.object({
428
+ version: z3.literal(3),
429
+ routes: z3.array(
430
+ z3.union([
431
+ z3.object({
432
+ src: z3.string(),
433
+ dest: z3.string().optional(),
434
+ headers: z3.record(z3.string()).optional(),
435
+ methods: z3.array(z3.string()).optional(),
436
+ status: z3.number().int().positive().optional(),
437
+ continue: z3.boolean().optional(),
438
+ check: z3.boolean().optional(),
439
+ missing: HasOrMissing,
440
+ has: HasOrMissing,
441
+ locale: z3.object({
442
+ redirect: z3.record(z3.string()).optional(),
443
+ cookie: z3.string().optional()
444
+ }).strict().optional(),
445
+ middlewarePath: z3.string().optional()
446
+ }).strict(),
447
+ z3.object({
448
+ handle: z3.union([
449
+ z3.literal("rewrite"),
450
+ z3.literal("filesystem"),
451
+ z3.literal("resource"),
452
+ z3.literal("miss"),
453
+ z3.literal("hit"),
454
+ z3.literal("error")
455
+ ]),
456
+ src: z3.string().optional(),
457
+ dest: z3.string().optional(),
458
+ status: z3.number().optional()
459
+ }).strict()
460
+ ])
461
+ ).optional(),
462
+ images: z3.object({
463
+ sizes: z3.tuple([z3.number().int().positive(), z3.number().int().positive()]),
464
+ domains: z3.array(z3.string()).nonempty().optional(),
465
+ minimumCacheTTL: z3.number().int().positive().optional(),
466
+ formats: z3.union([z3.literal("image/avif"), z3.literal("image/webp")]).array().nonempty().optional(),
467
+ dangerouslyAllowSVG: z3.boolean().optional(),
468
+ contentSecurityPolicy: z3.string().optional()
469
+ }).strict().optional(),
470
+ wildcard: z3.array(
471
+ z3.object({
472
+ domain: z3.string(),
473
+ value: z3.string()
474
+ }).strict()
475
+ ).optional(),
476
+ overrides: z3.record(
477
+ z3.object({
478
+ path: z3.string().optional(),
479
+ contentType: z3.string().optional()
480
+ }).strict()
481
+ ).optional(),
482
+ cache: z3.array(z3.string()).optional()
579
483
  }).strict();
580
484
 
581
- // src/prerender.ts
582
- import fs4 from "fs/promises";
485
+ // src/config.ts
486
+ import fs2 from "node:fs/promises";
487
+ import {
488
+ getTransformedRoutes,
489
+ mergeRoutes,
490
+ normalizeRoutes
491
+ } from "@vercel/routing-utils";
492
+ function reorderEnforce(arr) {
493
+ return [
494
+ ...arr.filter((r) => r.enforce === "pre"),
495
+ ...arr.filter((r) => !r.enforce),
496
+ ...arr.filter((r) => r.enforce === "post")
497
+ ];
498
+ }
499
+ function getConfig(resolvedConfig, rewrites, overrides, headers) {
500
+ const _rewrites = [
501
+ // User provided config always comes first
502
+ ...resolvedConfig.vercel?.rewrites ?? [],
503
+ ...rewrites ?? []
504
+ ];
505
+ const { routes, error } = getTransformedRoutes({
506
+ cleanUrls: resolvedConfig.vercel?.cleanUrls ?? true,
507
+ trailingSlash: resolvedConfig.vercel?.trailingSlash,
508
+ rewrites: reorderEnforce(_rewrites),
509
+ redirects: resolvedConfig.vercel?.redirects ? reorderEnforce(resolvedConfig.vercel?.redirects) : void 0,
510
+ headers
511
+ });
512
+ if (error) {
513
+ throw error;
514
+ }
515
+ if (resolvedConfig.vercel?.config?.routes && resolvedConfig.vercel.config.routes.length > 0 && !resolvedConfig.vercel.config.routes.every((r) => "continue" in r && r.continue)) {
516
+ console.warn(
517
+ 'Did you forget to add `"continue": true` to your routes? See https://vercel.com/docs/build-output-api/v3/configuration#source-route\nIf not, it is discouraged to use `vercel.config.routes` to override routes. Prefer using `vercel.rewrites` and `vercel.redirects`.'
518
+ );
519
+ }
520
+ let userRoutes = [];
521
+ let buildRoutes = [];
522
+ if (resolvedConfig.vercel?.config?.routes) {
523
+ const norm = normalizeRoutes(resolvedConfig.vercel.config.routes);
524
+ if (norm.error) {
525
+ throw norm.error;
526
+ }
527
+ userRoutes = norm.routes ?? [];
528
+ }
529
+ if (routes) {
530
+ const norm = normalizeRoutes(routes);
531
+ if (norm.error) {
532
+ throw norm.error;
533
+ }
534
+ buildRoutes = norm.routes ?? [];
535
+ }
536
+ const cleanRoutes = mergeRoutes({
537
+ userRoutes,
538
+ builds: [
539
+ {
540
+ use: "@vercel/node",
541
+ entrypoint: "index.js",
542
+ routes: buildRoutes
543
+ }
544
+ ]
545
+ });
546
+ return vercelOutputConfigSchema.parse({
547
+ version: 3,
548
+ ...resolvedConfig.vercel?.config,
549
+ routes: cleanRoutes,
550
+ overrides: {
551
+ ...resolvedConfig.vercel?.config?.overrides,
552
+ ...overrides
553
+ }
554
+ });
555
+ }
556
+ function getConfigDestination(resolvedConfig) {
557
+ return path3.join(getOutput(resolvedConfig), "config.json");
558
+ }
559
+ async function writeConfig(resolvedConfig, rewrites, overrides, headers) {
560
+ await fs2.writeFile(
561
+ getConfigDestination(resolvedConfig),
562
+ JSON.stringify(getConfig(resolvedConfig, rewrites, overrides, headers), void 0, 2),
563
+ "utf-8"
564
+ );
565
+ }
583
566
 
584
567
  // src/helpers.ts
585
- import fs3 from "fs/promises";
586
- import path4 from "path";
568
+ import fs3 from "node:fs/promises";
569
+ import path4 from "node:path";
587
570
  async function copyDir(src, dest) {
588
571
  await fs3.mkdir(dest, { recursive: true });
589
572
  const entries = await fs3.readdir(src, { withFileTypes: true });
@@ -595,6 +578,20 @@ async function copyDir(src, dest) {
595
578
  }
596
579
 
597
580
  // src/prerender.ts
581
+ import path5 from "node:path";
582
+
583
+ // src/schemas/config/prerender-config.ts
584
+ import { z as z4 } from "zod";
585
+ var vercelOutputPrerenderConfigSchema = z4.object({
586
+ expiration: z4.union([z4.number().int().positive(), z4.literal(false)]),
587
+ group: z4.number().int().optional(),
588
+ bypassToken: z4.string().optional(),
589
+ fallback: z4.string().optional(),
590
+ allowQuery: z4.array(z4.string()).optional()
591
+ }).strict();
592
+
593
+ // src/prerender.ts
594
+ import fs4 from "node:fs/promises";
598
595
  function execPrerender(resolvedConfig) {
599
596
  const prerender = resolvedConfig.vercel?.prerender;
600
597
  if (prerender === false) {
@@ -605,15 +602,8 @@ function execPrerender(resolvedConfig) {
605
602
  var group = 1;
606
603
  async function writePrerenderConfig(resolvedConfig, destination, isr) {
607
604
  const parsed = path5.parse(destination);
608
- const outfile = path5.join(
609
- getOutput(resolvedConfig, "functions"),
610
- parsed.dir,
611
- parsed.name + ".prerender-config.json"
612
- );
613
- await fs4.mkdir(
614
- path5.join(getOutput(resolvedConfig, "functions"), parsed.dir),
615
- { recursive: true }
616
- );
605
+ const outfile = path5.join(getOutput(resolvedConfig, "functions"), parsed.dir, `${parsed.name}.prerender-config.json`);
606
+ await fs4.mkdir(path5.join(getOutput(resolvedConfig, "functions"), parsed.dir), { recursive: true });
617
607
  await fs4.writeFile(
618
608
  outfile,
619
609
  JSON.stringify(
@@ -631,34 +621,18 @@ function getPrerenderSymlinkInfo(resolvedConfig, destination, target) {
631
621
  const parsed = path5.parse(destination);
632
622
  const targetParsed = path5.parse(target);
633
623
  return {
634
- target: path5.join(
635
- getOutput(resolvedConfig, "functions"),
636
- targetParsed.dir,
637
- targetParsed.name + ".func"
638
- ),
639
- link: path5.join(
640
- getOutput(resolvedConfig, "functions"),
641
- parsed.dir,
642
- parsed.name + ".func"
643
- )
624
+ target: path5.join(getOutput(resolvedConfig, "functions"), targetParsed.dir, `${targetParsed.name}.func`),
625
+ link: path5.join(getOutput(resolvedConfig, "functions"), parsed.dir, `${parsed.name}.func`)
644
626
  };
645
627
  }
646
628
  async function buildPrerenderConfigs(resolvedConfig, extractedIsr) {
647
- const isr = Object.assign(
648
- {},
649
- extractedIsr,
650
- await getIsrConfig(resolvedConfig)
651
- );
629
+ const isr = Object.assign({}, extractedIsr, await getIsrConfig(resolvedConfig));
652
630
  const entries = Object.entries(isr);
653
631
  const rewrites = [];
654
632
  for (const [destination, { symlink, route, ...isr2 }] of entries) {
655
633
  await writePrerenderConfig(resolvedConfig, destination, isr2);
656
634
  if (symlink) {
657
- const info = getPrerenderSymlinkInfo(
658
- resolvedConfig,
659
- destination,
660
- symlink
661
- );
635
+ const info = getPrerenderSymlinkInfo(resolvedConfig, destination, symlink);
662
636
  await copyDir(info.target, info.link);
663
637
  }
664
638
  if (route) {
@@ -679,7 +653,6 @@ async function getIsrConfig(resolvedConfig) {
679
653
  }
680
654
 
681
655
  // src/index.ts
682
- import path6 from "path";
683
656
  function vercelPluginCleanup() {
684
657
  let resolvedConfig;
685
658
  return {
@@ -709,9 +682,7 @@ function vercelPlugin() {
709
682
  enforce: "post",
710
683
  configResolved(config) {
711
684
  resolvedConfig = config;
712
- vikeFound = resolvedConfig.plugins.some(
713
- (p) => p.name.match("^vite-plugin-ssr:|^vike:")
714
- );
685
+ vikeFound = resolvedConfig.plugins.some((p) => p.name.match("^vite-plugin-ssr:|^vike:"));
715
686
  if (typeof resolvedConfig.vercel?.distContainsOnlyStatic === "undefined") {
716
687
  resolvedConfig.vercel ??= {};
717
688
  resolvedConfig.vercel.distContainsOnlyStatic = !vikeFound;
@@ -753,10 +724,7 @@ async function cleanOutputDirectory(resolvedConfig) {
753
724
  }
754
725
  async function copyDistToStatic(resolvedConfig) {
755
726
  if (resolvedConfig.vercel?.distContainsOnlyStatic) {
756
- await copyDir(
757
- resolvedConfig.build.outDir,
758
- getOutput(resolvedConfig, "static")
759
- );
727
+ await copyDir(resolvedConfig.build.outDir, getOutput(resolvedConfig, "static"));
760
728
  }
761
729
  }
762
730
  async function computeStaticHtmlOverrides(resolvedConfig) {
@@ -764,18 +732,19 @@ async function computeStaticHtmlOverrides(resolvedConfig) {
764
732
  const files = await getStaticHtmlFiles(staticAbsolutePath);
765
733
  const publicDir = getPublic(resolvedConfig);
766
734
  const publicFiles = await getStaticHtmlFiles(publicDir);
767
- files.push(
768
- ...publicFiles.map((f) => f.replace(publicDir, staticAbsolutePath))
735
+ files.push(...publicFiles.map((f) => f.replace(publicDir, staticAbsolutePath)));
736
+ return files.reduce(
737
+ (acc, curr) => {
738
+ const relPath = path6.relative(staticAbsolutePath, curr);
739
+ const parsed = path6.parse(relPath);
740
+ const pathJoined = path6.join(parsed.dir, parsed.name);
741
+ acc[relPath] = {
742
+ path: pathJoined
743
+ };
744
+ return acc;
745
+ },
746
+ {}
769
747
  );
770
- return files.reduce((acc, curr) => {
771
- const relPath = path6.relative(staticAbsolutePath, curr);
772
- const parsed = path6.parse(relPath);
773
- const pathJoined = path6.join(parsed.dir, parsed.name);
774
- acc[relPath] = {
775
- path: pathJoined
776
- };
777
- return acc;
778
- }, {});
779
748
  }
780
749
  async function getStaticHtmlFiles(src) {
781
750
  try {
@@ -808,11 +777,7 @@ async function tryImportVpvv(options) {
808
777
  }
809
778
  function allPlugins(options = {}) {
810
779
  const { smart, ...rest } = options;
811
- return [
812
- vercelPluginCleanup(),
813
- vercelPlugin(),
814
- smart !== false ? tryImportVpvv(rest) : null
815
- ];
780
+ return [vercelPluginCleanup(), vercelPlugin(), smart !== false ? tryImportVpvv(rest) : null];
816
781
  }
817
782
  export {
818
783
  allPlugins as default