vite-plugin-vercel 8.0.1 → 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,211 +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 { builtinModules } from "module";
207
- 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";
208
12
  import { build } from "esbuild";
13
+ import glob from "fast-glob";
14
+ import { generateCode, loadFile } from "magicast";
209
15
 
210
16
  // src/assert.ts
211
17
  import { newError } from "@brillout/libassert";
@@ -219,83 +25,111 @@ function assert(condition, errorMessage) {
219
25
  }
220
26
 
221
27
  // src/schemas/config/vc-config.ts
222
- import { z as z2 } from "zod";
223
- var vercelOutputEdgeVcConfigSchema = z2.object({
224
- runtime: z2.literal("edge"),
225
- entrypoint: z2.string(),
226
- 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()
227
33
  }).strict();
228
- var vercelOutputServerlessVcConfigSchema = z2.object({
229
- runtime: z2.string(),
230
- handler: z2.string(),
231
- memory: z2.number().int().min(128).max(3008).optional(),
232
- maxDuration: z2.number().int().positive().optional(),
233
- environment: z2.record(z2.string()).optional(),
234
- regions: z2.array(z2.string()).optional(),
235
- supportsWrapper: z2.boolean().optional(),
236
- 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()
237
43
  }).strict();
238
44
  var vercelOutputServerlessNodeVcConfigSchema = vercelOutputServerlessVcConfigSchema.extend({
239
- launcherType: z2.literal("Nodejs"),
240
- shouldAddHelpers: z2.boolean().optional(),
241
- shouldAddSourcemapSupport: z2.boolean().optional(),
242
- awsLambdaHandler: z2.string().optional()
45
+ launcherType: z.literal("Nodejs"),
46
+ shouldAddHelpers: z.boolean().optional(),
47
+ shouldAddSourcemapSupport: z.boolean().optional(),
48
+ awsLambdaHandler: z.string().optional()
243
49
  }).strict();
244
- var vercelOutputVcConfigSchema = z2.union([
50
+ var vercelOutputVcConfigSchema = z.union([
245
51
  vercelOutputEdgeVcConfigSchema,
246
52
  vercelOutputServerlessVcConfigSchema,
247
53
  vercelOutputServerlessNodeVcConfigSchema
248
54
  ]);
249
55
 
250
- // src/build.ts
251
- import fs2, { copyFile } from "fs/promises";
252
-
253
56
  // src/schemas/exports.ts
254
- import { z as z3 } from "zod";
255
- var vercelEndpointExports = z3.object({
256
- edge: z3.boolean().optional(),
257
- headers: z3.record(z3.string()).optional(),
258
- streaming: z3.boolean().optional(),
259
- isr: z3.object({
260
- 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))
261
64
  }).optional()
262
65
  });
263
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
+
264
88
  // src/build.ts
265
- import { generateCode, loadFile } from "magicast";
266
- import { getNodeVersion } from "@vercel/build-utils";
267
- import { nodeFileTrace } from "@vercel/nft";
268
- import { findRoot } from "@manypkg/find-root";
269
- function getAdditionalEndpoints(resolvedConfig) {
270
- 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) => ({
271
106
  ...e,
272
- addRoute: e.addRoute ?? true,
107
+ route: e.route ?? true,
273
108
  // path.resolve removes the trailing slash if any
274
- destination: path3.posix.resolve("/", e.destination) + ".func"
109
+ destination: `${path2.posix.resolve("/", e.destination)}.func`
275
110
  }));
276
111
  }
277
- function getEntries(resolvedConfig) {
278
- 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("_"));
279
114
  if (apiEntries.length > 0) {
280
115
  console.warn(
281
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."
282
117
  );
283
118
  }
284
- const otherApiEntries = glob.sync(`${getRoot(resolvedConfig)}/_api/**/*.*([a-zA-Z0-9])`).filter((filepath) => !path3.basename(filepath).startsWith("_"));
285
- return [...apiEntries, ...otherApiEntries].reduce((entryPoints, filePath) => {
286
- const outFilePath = pathRelativeTo(
287
- filePath,
288
- resolvedConfig,
289
- filePath.includes("/_api/") ? "_api" : "api"
290
- );
291
- const parsed = path3.posix.parse(outFilePath);
292
- entryPoints.push({
293
- source: filePath,
294
- destination: `api/${path3.posix.join(parsed.dir, parsed.name)}.func`,
295
- addRoute: true
296
- });
297
- return entryPoints;
298
- }, 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
+ );
299
133
  }
300
134
  var edgeWasmPlugin = {
301
135
  name: "edge-wasm-vercel",
@@ -350,38 +184,21 @@ async function buildFn(resolvedConfig, entry, buildOptions) {
350
184
  Object.assign(options, buildOptions);
351
185
  }
352
186
  const filename = entry.edge || options.format === "cjs" ? "index.js" : "index.mjs";
353
- const outfile = path3.join(
354
- getOutput(resolvedConfig, "functions"),
355
- entry.destination,
356
- filename
357
- );
187
+ const outfile = path2.join(getOutput(resolvedConfig, "functions"), entry.destination, filename);
358
188
  Object.assign(options, { outfile });
359
189
  if (!options.stdin) {
360
190
  if (typeof entry.source === "string") {
361
191
  options.entryPoints = [entry.source];
362
192
  } else {
363
- assert(
364
- typeof entry.source === "object",
365
- `\`{ source }\` must be a string or an object`
366
- );
367
- assert(
368
- typeof entry.source.contents === "string",
369
- `\`{ contents }\` must be a string`
370
- );
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");
371
195
  options.stdin = entry.source;
372
196
  }
373
197
  }
374
198
  if (entry.edge) {
375
- delete options.platform;
199
+ options.platform = void 0;
376
200
  options.external = [...builtinModules, ...builtinModules.map((m) => `node:${m}`)];
377
- options.conditions = [
378
- "edge-light",
379
- "worker",
380
- "browser",
381
- "module",
382
- "import",
383
- "require"
384
- ];
201
+ options.conditions = ["edge-light", "worker", "browser", "module", "import", "require"];
385
202
  options.plugins?.push(edgeWasmPlugin);
386
203
  options.format = "esm";
387
204
  } else if (options.format === "esm") {
@@ -396,9 +213,9 @@ const __dirname = VPV_dirname(__filename);
396
213
  };
397
214
  }
398
215
  const ctx = { found: false, index: "" };
399
- options.plugins.push(vercelOgPlugin(ctx));
216
+ options.plugins?.push(vercelOgPlugin(ctx));
400
217
  const output = await build(options);
401
- if (typeof entry.source == "string") {
218
+ if (typeof entry.source === "string") {
402
219
  let base = resolvedConfig.root;
403
220
  try {
404
221
  const dir = await findRoot(resolvedConfig.root);
@@ -425,18 +242,14 @@ const __dirname = VPV_dirname(__filename);
425
242
  });
426
243
  return result.outputFiles[0].text;
427
244
  }
428
- return fs2.readFile(filepath, "utf-8");
245
+ return fs.readFile(filepath, "utf-8");
429
246
  }
430
247
  });
431
248
  for (const file of fileList) {
432
- 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")) {
433
250
  await copyFile(
434
- path3.join(base, file),
435
- path3.join(
436
- getOutput(resolvedConfig, "functions"),
437
- entry.destination,
438
- basename(file)
439
- )
251
+ path2.join(base, file),
252
+ path2.join(getOutput(resolvedConfig, "functions"), entry.destination, basename(file))
440
253
  );
441
254
  }
442
255
  }
@@ -448,13 +261,9 @@ const __dirname = VPV_dirname(__filename);
448
261
  return output;
449
262
  }
450
263
  async function writeVcConfig(resolvedConfig, destination, filename, options) {
451
- const vcConfig = path3.join(
452
- getOutput(resolvedConfig, "functions"),
453
- destination,
454
- ".vc-config.json"
455
- );
264
+ const vcConfig = path2.join(getOutput(resolvedConfig, "functions"), destination, ".vc-config.json");
456
265
  const nodeVersion = await getNodeVersion(getOutput(resolvedConfig));
457
- await fs2.writeFile(
266
+ await fs.writeFile(
458
267
  vcConfig,
459
268
  JSON.stringify(
460
269
  vercelOutputVcConfigSchema.parse(
@@ -478,9 +287,9 @@ async function writeVcConfig(resolvedConfig, destination, filename, options) {
478
287
  }
479
288
  function getSourceAndDestination(destination) {
480
289
  if (destination.startsWith("api/")) {
481
- return path3.posix.resolve("/", destination);
290
+ return path2.posix.resolve("/", destination);
482
291
  }
483
- return path3.posix.resolve("/", destination, ":match*");
292
+ return path2.posix.resolve("/", destination, ":match*");
484
293
  }
485
294
  var RE_BRACKETS = /^\[([^/]+)\]$/gm;
486
295
  function replaceBrackets(source) {
@@ -513,7 +322,7 @@ async function extractExports(filepath) {
513
322
  }
514
323
  }
515
324
  async function buildEndpoints(resolvedConfig) {
516
- const entries = getEntries(resolvedConfig);
325
+ const entries = await getEntries(resolvedConfig);
517
326
  for (const entry of entries) {
518
327
  if (typeof entry.source === "string") {
519
328
  const exports = await extractExports(entry.source);
@@ -537,6 +346,9 @@ async function buildEndpoints(resolvedConfig) {
537
346
  `isr configuration should be defined either in the endpoint itself or through Vite config, not both ('${entry.source}')`
538
347
  );
539
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
+ }
540
352
  if (exports.isr) {
541
353
  entry.isr = exports.isr;
542
354
  }
@@ -547,21 +359,36 @@ async function buildEndpoints(resolvedConfig) {
547
359
  }
548
360
  await buildFn(resolvedConfig, entry);
549
361
  }
550
- const isrEntries = entries.filter((e) => e.isr).map(
551
- (e) => [
552
- e.destination.replace(/\.func$/, ""),
553
- { expiration: e.isr.expiration }
554
- ]
555
- );
362
+ const isrEntries = entries.filter((e) => e.isr).map((e) => [e.destination.replace(/\.func$/, ""), { expiration: e.isr?.expiration }]);
556
363
  return {
557
- rewrites: entries.filter((e) => e.addRoute !== false).map((e) => e.destination.replace(/\.func$/, "")).map((destination) => ({
558
- source: replaceBrackets(getSourceAndDestination(destination)),
559
- destination: getSourceAndDestination(destination)
560
- })),
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
+ }),
561
388
  isr: Object.fromEntries(isrEntries),
562
389
  headers: entries.filter((e) => e.headers).map((e) => ({
563
- source: "/" + e.destination.replace(/\.func$/, ""),
564
- headers: Object.entries(e.headers).map(([key, value]) => ({
390
+ source: `/${e.destination.replace(/\.func$/, "")}`,
391
+ headers: Object.entries(e.headers ?? {}).map(([key, value]) => ({
565
392
  key,
566
393
  value
567
394
  }))
@@ -569,25 +396,177 @@ async function buildEndpoints(resolvedConfig) {
569
396
  };
570
397
  }
571
398
 
572
- // src/prerender.ts
573
- import path5 from "path";
399
+ // src/config.ts
400
+ import path3 from "node:path";
574
401
 
575
- // src/schemas/config/prerender-config.ts
576
- import { z as z4 } from "zod";
577
- var vercelOutputPrerenderConfigSchema = z4.object({
578
- expiration: z4.union([z4.number().int().positive(), z4.literal(false)]),
579
- group: z4.number().int().optional(),
580
- bypassToken: z4.string().optional(),
581
- fallback: z4.string().optional(),
582
- 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()
583
483
  }).strict();
584
484
 
585
- // src/prerender.ts
586
- 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
+ }
587
566
 
588
567
  // src/helpers.ts
589
- import fs3 from "fs/promises";
590
- import path4 from "path";
568
+ import fs3 from "node:fs/promises";
569
+ import path4 from "node:path";
591
570
  async function copyDir(src, dest) {
592
571
  await fs3.mkdir(dest, { recursive: true });
593
572
  const entries = await fs3.readdir(src, { withFileTypes: true });
@@ -599,6 +578,20 @@ async function copyDir(src, dest) {
599
578
  }
600
579
 
601
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";
602
595
  function execPrerender(resolvedConfig) {
603
596
  const prerender = resolvedConfig.vercel?.prerender;
604
597
  if (prerender === false) {
@@ -609,15 +602,8 @@ function execPrerender(resolvedConfig) {
609
602
  var group = 1;
610
603
  async function writePrerenderConfig(resolvedConfig, destination, isr) {
611
604
  const parsed = path5.parse(destination);
612
- const outfile = path5.join(
613
- getOutput(resolvedConfig, "functions"),
614
- parsed.dir,
615
- parsed.name + ".prerender-config.json"
616
- );
617
- await fs4.mkdir(
618
- path5.join(getOutput(resolvedConfig, "functions"), parsed.dir),
619
- { recursive: true }
620
- );
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 });
621
607
  await fs4.writeFile(
622
608
  outfile,
623
609
  JSON.stringify(
@@ -635,34 +621,18 @@ function getPrerenderSymlinkInfo(resolvedConfig, destination, target) {
635
621
  const parsed = path5.parse(destination);
636
622
  const targetParsed = path5.parse(target);
637
623
  return {
638
- target: path5.join(
639
- getOutput(resolvedConfig, "functions"),
640
- targetParsed.dir,
641
- targetParsed.name + ".func"
642
- ),
643
- link: path5.join(
644
- getOutput(resolvedConfig, "functions"),
645
- parsed.dir,
646
- parsed.name + ".func"
647
- )
624
+ target: path5.join(getOutput(resolvedConfig, "functions"), targetParsed.dir, `${targetParsed.name}.func`),
625
+ link: path5.join(getOutput(resolvedConfig, "functions"), parsed.dir, `${parsed.name}.func`)
648
626
  };
649
627
  }
650
628
  async function buildPrerenderConfigs(resolvedConfig, extractedIsr) {
651
- const isr = Object.assign(
652
- {},
653
- extractedIsr,
654
- await getIsrConfig(resolvedConfig)
655
- );
629
+ const isr = Object.assign({}, extractedIsr, await getIsrConfig(resolvedConfig));
656
630
  const entries = Object.entries(isr);
657
631
  const rewrites = [];
658
632
  for (const [destination, { symlink, route, ...isr2 }] of entries) {
659
633
  await writePrerenderConfig(resolvedConfig, destination, isr2);
660
634
  if (symlink) {
661
- const info = getPrerenderSymlinkInfo(
662
- resolvedConfig,
663
- destination,
664
- symlink
665
- );
635
+ const info = getPrerenderSymlinkInfo(resolvedConfig, destination, symlink);
666
636
  await copyDir(info.target, info.link);
667
637
  }
668
638
  if (route) {
@@ -683,7 +653,6 @@ async function getIsrConfig(resolvedConfig) {
683
653
  }
684
654
 
685
655
  // src/index.ts
686
- import path6 from "path";
687
656
  function vercelPluginCleanup() {
688
657
  let resolvedConfig;
689
658
  return {
@@ -713,9 +682,7 @@ function vercelPlugin() {
713
682
  enforce: "post",
714
683
  configResolved(config) {
715
684
  resolvedConfig = config;
716
- vikeFound = resolvedConfig.plugins.some(
717
- (p) => p.name.match("^vite-plugin-ssr:|^vike:")
718
- );
685
+ vikeFound = resolvedConfig.plugins.some((p) => p.name.match("^vite-plugin-ssr:|^vike:"));
719
686
  if (typeof resolvedConfig.vercel?.distContainsOnlyStatic === "undefined") {
720
687
  resolvedConfig.vercel ??= {};
721
688
  resolvedConfig.vercel.distContainsOnlyStatic = !vikeFound;
@@ -757,10 +724,7 @@ async function cleanOutputDirectory(resolvedConfig) {
757
724
  }
758
725
  async function copyDistToStatic(resolvedConfig) {
759
726
  if (resolvedConfig.vercel?.distContainsOnlyStatic) {
760
- await copyDir(
761
- resolvedConfig.build.outDir,
762
- getOutput(resolvedConfig, "static")
763
- );
727
+ await copyDir(resolvedConfig.build.outDir, getOutput(resolvedConfig, "static"));
764
728
  }
765
729
  }
766
730
  async function computeStaticHtmlOverrides(resolvedConfig) {
@@ -768,18 +732,19 @@ async function computeStaticHtmlOverrides(resolvedConfig) {
768
732
  const files = await getStaticHtmlFiles(staticAbsolutePath);
769
733
  const publicDir = getPublic(resolvedConfig);
770
734
  const publicFiles = await getStaticHtmlFiles(publicDir);
771
- files.push(
772
- ...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
+ {}
773
747
  );
774
- return files.reduce((acc, curr) => {
775
- const relPath = path6.relative(staticAbsolutePath, curr);
776
- const parsed = path6.parse(relPath);
777
- const pathJoined = path6.join(parsed.dir, parsed.name);
778
- acc[relPath] = {
779
- path: pathJoined
780
- };
781
- return acc;
782
- }, {});
783
748
  }
784
749
  async function getStaticHtmlFiles(src) {
785
750
  try {
@@ -812,11 +777,7 @@ async function tryImportVpvv(options) {
812
777
  }
813
778
  function allPlugins(options = {}) {
814
779
  const { smart, ...rest } = options;
815
- return [
816
- vercelPluginCleanup(),
817
- vercelPlugin(),
818
- smart !== false ? tryImportVpvv(rest) : null
819
- ];
780
+ return [vercelPluginCleanup(), vercelPlugin(), smart !== false ? tryImportVpvv(rest) : null];
820
781
  }
821
782
  export {
822
783
  allPlugins as default