vite-plugin-vercel 10.0.0 → 11.0.0-beta.2
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/README.md +55 -98
- package/dist/api-DR2y7JVQ.js +70 -0
- package/dist/api.d.ts +53 -0
- package/dist/api.js +3 -0
- package/dist/index.d.ts +20 -689
- package/dist/index.js +57 -789
- package/dist/path-B4ThGm96.js +10 -0
- package/dist/types.d.ts +103 -0
- package/dist/types.js +1 -0
- package/dist/vite.d.ts +9 -0
- package/dist/vite.js +629 -0
- package/meta.d.ts +7 -0
- package/package.json +31 -35
- package/dist/index.cjs +0 -829
- package/dist/index.d.cts +0 -694
- package/index.d.ts +0 -10
package/dist/index.js
CHANGED
|
@@ -1,802 +1,70 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import fs, { copyFile } from "fs/promises";
|
|
7
|
-
import { builtinModules } from "module";
|
|
8
|
-
import path2, { basename } from "path";
|
|
9
|
-
import { findRoot } from "@manypkg/find-root";
|
|
10
|
-
import { getNodeVersion } from "@vercel/build-utils";
|
|
11
|
-
import { nodeFileTrace } from "@vercel/nft";
|
|
12
|
-
import { build } from "esbuild";
|
|
1
|
+
import { t as pathRelativeTo } from "./path-B4ThGm96.js";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { vercelEndpointExports } from "@vite-plugin-vercel/schemas";
|
|
4
|
+
import { fromNextFs } from "convert-route/next-fs";
|
|
5
|
+
import { toRou3 } from "convert-route/rou3";
|
|
13
6
|
import glob from "fast-glob";
|
|
14
7
|
import { generateCode, loadFile } from "magicast";
|
|
15
|
-
|
|
16
|
-
// src/assert.ts
|
|
17
|
-
import { newError } from "@brillout/libassert";
|
|
18
|
-
var libName = "vite-plugin-vercel";
|
|
19
|
-
function assert(condition, errorMessage) {
|
|
20
|
-
if (condition) {
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
const err = newError(`[${libName}][Wrong Usage] ${errorMessage}`, 2);
|
|
24
|
-
throw err;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// src/schemas/config/vc-config.ts
|
|
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()
|
|
33
|
-
}).strict();
|
|
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()
|
|
43
|
-
}).strict();
|
|
44
|
-
var vercelOutputServerlessNodeVcConfigSchema = vercelOutputServerlessVcConfigSchema.extend({
|
|
45
|
-
launcherType: z.literal("Nodejs"),
|
|
46
|
-
shouldAddHelpers: z.boolean().optional(),
|
|
47
|
-
shouldAddSourcemapSupport: z.boolean().optional(),
|
|
48
|
-
awsLambdaHandler: z.string().optional()
|
|
49
|
-
}).strict();
|
|
50
|
-
var vercelOutputVcConfigSchema = z.union([
|
|
51
|
-
vercelOutputEdgeVcConfigSchema,
|
|
52
|
-
vercelOutputServerlessVcConfigSchema,
|
|
53
|
-
vercelOutputServerlessNodeVcConfigSchema
|
|
54
|
-
]);
|
|
55
|
-
|
|
56
|
-
// src/schemas/exports.ts
|
|
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))
|
|
64
|
-
}).optional()
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
// src/utils.ts
|
|
68
8
|
import { normalizePath } from "vite";
|
|
69
|
-
import path from "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
9
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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
|
-
);
|
|
10
|
+
//#region src/index.ts
|
|
11
|
+
/**
|
|
12
|
+
* Scans the filesystem for entry points.
|
|
13
|
+
* @experimental
|
|
14
|
+
*/
|
|
15
|
+
async function getVercelEntries(dir, { destination = dir, tryParseExports = true }) {
|
|
16
|
+
const normalizedDir = normalizePath(dir);
|
|
17
|
+
destination = normalizePath(destination);
|
|
18
|
+
const apiEntries = glob.sync(`${path.posix.resolve(normalizedDir)}/**/*.?(m)[jt]s?(x)`).filter((filepath) => !path.basename(filepath).startsWith("_"));
|
|
19
|
+
const entryPoints = [];
|
|
20
|
+
for (const filePath of apiEntries) {
|
|
21
|
+
const outFilePath = pathRelativeTo(filePath, normalizedDir);
|
|
22
|
+
const parsed = path.posix.parse(outFilePath);
|
|
23
|
+
let xports;
|
|
24
|
+
if (tryParseExports) xports = await extractExports(filePath);
|
|
25
|
+
const key = path.posix.join(destination, parsed.dir, parsed.name);
|
|
26
|
+
const entry = {
|
|
27
|
+
id: filePath,
|
|
28
|
+
vercel: {}
|
|
29
|
+
};
|
|
30
|
+
if (xports?.edge) entry.vercel.edge = xports.edge;
|
|
31
|
+
if (xports?.isr) entry.vercel.isr = xports.isr;
|
|
32
|
+
if (xports?.headers) entry.vercel.headers = xports.headers;
|
|
33
|
+
if (xports?.streaming) entry.vercel.streaming = xports.streaming;
|
|
34
|
+
entry.pattern = entryToRou3(key);
|
|
35
|
+
if (key.includes("[...")) entry.vercel.enforce = "post";
|
|
36
|
+
entryPoints.push(entry);
|
|
37
|
+
}
|
|
38
|
+
return entryPoints;
|
|
39
|
+
}
|
|
40
|
+
function entryToRou3(key) {
|
|
41
|
+
return toRou3(fromNextFs(path.posix.resolve("/", key)))[0].replace(/\/index$/, "/");
|
|
133
42
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
setup(build2) {
|
|
149
|
-
build2.onResolve({ filter: /@vercel\/og/ }, () => {
|
|
150
|
-
ctx.found = true;
|
|
151
|
-
return void 0;
|
|
152
|
-
});
|
|
153
|
-
build2.onLoad({ filter: /@vercel\/og/ }, (args) => {
|
|
154
|
-
ctx.index = args.path;
|
|
155
|
-
return void 0;
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
};
|
|
159
|
-
};
|
|
160
|
-
var standardBuildOptions = {
|
|
161
|
-
bundle: true,
|
|
162
|
-
target: "es2022",
|
|
163
|
-
format: "esm",
|
|
164
|
-
platform: "node",
|
|
165
|
-
logLevel: "info",
|
|
166
|
-
logOverride: {
|
|
167
|
-
"ignored-bare-import": "verbose",
|
|
168
|
-
"require-resolve-not-external": "verbose"
|
|
169
|
-
},
|
|
170
|
-
minify: false,
|
|
171
|
-
plugins: [],
|
|
172
|
-
define: {
|
|
173
|
-
"process.env.NODE_ENV": '"production"',
|
|
174
|
-
"import.meta.env.NODE_ENV": '"production"'
|
|
175
|
-
}
|
|
176
|
-
};
|
|
177
|
-
async function buildFn(resolvedConfig, entry, buildOptions) {
|
|
178
|
-
assert(
|
|
179
|
-
entry.destination.length > 0,
|
|
180
|
-
`Endpoint ${typeof entry.source === "string" ? entry.source : "-"} does not have build destination`
|
|
181
|
-
);
|
|
182
|
-
const options = Object.assign({}, standardBuildOptions);
|
|
183
|
-
if (buildOptions) {
|
|
184
|
-
Object.assign(options, buildOptions);
|
|
185
|
-
}
|
|
186
|
-
const filename = entry.edge || options.format === "cjs" ? "index.js" : "index.mjs";
|
|
187
|
-
const outfile = path2.join(getOutput(resolvedConfig, "functions"), entry.destination, filename);
|
|
188
|
-
Object.assign(options, { outfile });
|
|
189
|
-
if (!options.stdin) {
|
|
190
|
-
if (typeof entry.source === "string") {
|
|
191
|
-
options.entryPoints = [entry.source];
|
|
192
|
-
} else {
|
|
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");
|
|
195
|
-
options.stdin = entry.source;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
if (entry.edge) {
|
|
199
|
-
options.platform = void 0;
|
|
200
|
-
options.external = [...builtinModules, ...builtinModules.map((m) => `node:${m}`)];
|
|
201
|
-
options.conditions = ["edge-light", "worker", "browser", "module", "import", "require"];
|
|
202
|
-
options.plugins?.push(edgeWasmPlugin);
|
|
203
|
-
options.format = "esm";
|
|
204
|
-
} else if (options.format === "esm") {
|
|
205
|
-
options.banner = {
|
|
206
|
-
js: `import { createRequire as VPV_createRequire } from "node:module";
|
|
207
|
-
import { fileURLToPath as VPV_fileURLToPath } from "node:url";
|
|
208
|
-
import { dirname as VPV_dirname } from "node:path";
|
|
209
|
-
const require = VPV_createRequire(import.meta.url);
|
|
210
|
-
const __filename = VPV_fileURLToPath(import.meta.url);
|
|
211
|
-
const __dirname = VPV_dirname(__filename);
|
|
212
|
-
`
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
const ctx = { found: false, index: "" };
|
|
216
|
-
options.plugins?.push(vercelOgPlugin(ctx));
|
|
217
|
-
const output = await build(options);
|
|
218
|
-
if (typeof entry.source === "string") {
|
|
219
|
-
let base = resolvedConfig.root;
|
|
220
|
-
try {
|
|
221
|
-
const dir = await findRoot(resolvedConfig.root);
|
|
222
|
-
base = dir.rootDir;
|
|
223
|
-
} catch (e) {
|
|
224
|
-
}
|
|
225
|
-
const { fileList, reasons } = await nodeFileTrace([entry.source], {
|
|
226
|
-
base,
|
|
227
|
-
processCwd: resolvedConfig.root,
|
|
228
|
-
mixedModules: true,
|
|
229
|
-
ignore: [
|
|
230
|
-
"**/node_modules/react{,-dom,-dom-server-turbopack}/**/*.development.js",
|
|
231
|
-
"**/*.d.ts",
|
|
232
|
-
"**/*.map",
|
|
233
|
-
"**/node_modules/webpack5/**/*"
|
|
234
|
-
],
|
|
235
|
-
async readFile(filepath) {
|
|
236
|
-
if (filepath.endsWith(".ts") || filepath.endsWith(".tsx")) {
|
|
237
|
-
const result = await build({
|
|
238
|
-
...standardBuildOptions,
|
|
239
|
-
entryPoints: [entry.source],
|
|
240
|
-
bundle: false,
|
|
241
|
-
write: false
|
|
242
|
-
});
|
|
243
|
-
return result.outputFiles[0].text;
|
|
244
|
-
}
|
|
245
|
-
return fs.readFile(filepath, "utf-8");
|
|
246
|
-
}
|
|
247
|
-
});
|
|
248
|
-
for (const file of fileList) {
|
|
249
|
-
if (reasons.has(file) && reasons.get(file)?.type.includes("asset") && !file.endsWith(".js") && !file.endsWith(".cjs") && !file.endsWith(".mjs") && !file.endsWith("package.json")) {
|
|
250
|
-
await copyFile(
|
|
251
|
-
path2.join(base, file),
|
|
252
|
-
path2.join(getOutput(resolvedConfig, "functions"), entry.destination, basename(file))
|
|
253
|
-
);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
await writeVcConfig(resolvedConfig, entry.destination, filename, {
|
|
258
|
-
edge: Boolean(entry.edge),
|
|
259
|
-
streaming: entry.streaming
|
|
260
|
-
});
|
|
261
|
-
return output;
|
|
262
|
-
}
|
|
263
|
-
async function writeVcConfig(resolvedConfig, destination, filename, options) {
|
|
264
|
-
const vcConfig = path2.join(getOutput(resolvedConfig, "functions"), destination, ".vc-config.json");
|
|
265
|
-
const nodeVersion = await getNodeVersion(getOutput(resolvedConfig));
|
|
266
|
-
await fs.writeFile(
|
|
267
|
-
vcConfig,
|
|
268
|
-
JSON.stringify(
|
|
269
|
-
vercelOutputVcConfigSchema.parse(
|
|
270
|
-
options.edge ? {
|
|
271
|
-
runtime: "edge",
|
|
272
|
-
entrypoint: filename
|
|
273
|
-
} : {
|
|
274
|
-
runtime: nodeVersion.runtime,
|
|
275
|
-
handler: filename,
|
|
276
|
-
maxDuration: resolvedConfig.vercel?.defaultMaxDuration,
|
|
277
|
-
launcherType: "Nodejs",
|
|
278
|
-
shouldAddHelpers: true,
|
|
279
|
-
supportsResponseStreaming: options.streaming ?? resolvedConfig.vercel?.defaultSupportsResponseStreaming
|
|
280
|
-
}
|
|
281
|
-
),
|
|
282
|
-
void 0,
|
|
283
|
-
2
|
|
284
|
-
),
|
|
285
|
-
"utf-8"
|
|
286
|
-
);
|
|
287
|
-
}
|
|
288
|
-
function getSourceAndDestination(destination) {
|
|
289
|
-
if (destination.startsWith("api/")) {
|
|
290
|
-
return path2.posix.resolve("/", destination);
|
|
291
|
-
}
|
|
292
|
-
return path2.posix.resolve("/", destination, ":match*");
|
|
293
|
-
}
|
|
294
|
-
var RE_BRACKETS = /^\[([^/]+)\]$/gm;
|
|
295
|
-
function replaceBrackets(source) {
|
|
296
|
-
return source.split("/").map((segment) => segment.replace(RE_BRACKETS, ":$1")).join("/");
|
|
43
|
+
async function extractExports(filepath) {
|
|
44
|
+
try {
|
|
45
|
+
const mod = await loadFile(filepath);
|
|
46
|
+
const subject = {
|
|
47
|
+
edge: evalExport(mod.exports.edge),
|
|
48
|
+
headers: evalExport(mod.exports.headers),
|
|
49
|
+
streaming: evalExport(mod.exports.streaming),
|
|
50
|
+
isr: evalExport(mod.exports.isr)
|
|
51
|
+
};
|
|
52
|
+
return vercelEndpointExports.parse(subject);
|
|
53
|
+
} catch (e) {
|
|
54
|
+
console.warn(`Warning: failed to read exports of '${filepath}'`, e);
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
297
57
|
}
|
|
298
58
|
function isPrimitive(test) {
|
|
299
|
-
|
|
59
|
+
return test !== Object(test);
|
|
300
60
|
}
|
|
301
61
|
function _eval(code) {
|
|
302
|
-
|
|
303
|
-
return func.call(null).call(null);
|
|
62
|
+
return new Function(`{ return function(){ return ${code} } };`).call(null).call(null);
|
|
304
63
|
}
|
|
305
64
|
function evalExport(exp) {
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
return _eval(code);
|
|
309
|
-
}
|
|
310
|
-
async function extractExports(filepath) {
|
|
311
|
-
try {
|
|
312
|
-
const mod = await loadFile(filepath);
|
|
313
|
-
const subject = {
|
|
314
|
-
edge: evalExport(mod.exports.edge),
|
|
315
|
-
headers: evalExport(mod.exports.headers),
|
|
316
|
-
streaming: evalExport(mod.exports.streaming),
|
|
317
|
-
isr: evalExport(mod.exports.isr)
|
|
318
|
-
};
|
|
319
|
-
return vercelEndpointExports.parse(subject);
|
|
320
|
-
} catch (e) {
|
|
321
|
-
console.warn(`Warning: failed to read exports of '${filepath}'`, e);
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
async function extractHeaders(resolvedConfig) {
|
|
325
|
-
let headers = [];
|
|
326
|
-
if (typeof resolvedConfig.vercel?.headers === "function") {
|
|
327
|
-
headers = await resolvedConfig.vercel.headers();
|
|
328
|
-
} else if (Array.isArray(resolvedConfig.vercel?.headers)) {
|
|
329
|
-
headers = resolvedConfig.vercel.headers;
|
|
330
|
-
}
|
|
331
|
-
return headers;
|
|
332
|
-
}
|
|
333
|
-
async function buildEndpoints(resolvedConfig) {
|
|
334
|
-
const entries = await getEntries(resolvedConfig);
|
|
335
|
-
const headers = await extractHeaders(resolvedConfig);
|
|
336
|
-
for (const entry of entries) {
|
|
337
|
-
if (typeof entry.source === "string") {
|
|
338
|
-
const exports = await extractExports(entry.source);
|
|
339
|
-
if (exports) {
|
|
340
|
-
if (entry.headers || exports.headers) {
|
|
341
|
-
entry.headers = {
|
|
342
|
-
...exports.headers,
|
|
343
|
-
...entry.headers
|
|
344
|
-
};
|
|
345
|
-
}
|
|
346
|
-
if (entry.edge !== void 0 && exports.edge !== void 0) {
|
|
347
|
-
throw new Error(
|
|
348
|
-
`edge configuration should be defined either in the endpoint itself or through Vite config, not both ('${entry.source}')`
|
|
349
|
-
);
|
|
350
|
-
}
|
|
351
|
-
if (exports.edge !== void 0) {
|
|
352
|
-
entry.edge = exports.edge;
|
|
353
|
-
}
|
|
354
|
-
if (entry.isr !== void 0 && exports.isr !== void 0) {
|
|
355
|
-
throw new Error(
|
|
356
|
-
`isr configuration should be defined either in the endpoint itself or through Vite config, not both ('${entry.source}')`
|
|
357
|
-
);
|
|
358
|
-
}
|
|
359
|
-
if ((entry.isr !== void 0 || exports.isr !== void 0) && (entry.edge !== void 0 || exports.edge !== void 0)) {
|
|
360
|
-
throw new Error(`isr cannot be enabled for edge functions ('${entry.source}')`);
|
|
361
|
-
}
|
|
362
|
-
if (exports.isr) {
|
|
363
|
-
entry.isr = exports.isr;
|
|
364
|
-
}
|
|
365
|
-
if (typeof exports.streaming === "boolean") {
|
|
366
|
-
entry.streaming = exports.streaming;
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
await buildFn(resolvedConfig, entry, entry.buildOptions);
|
|
371
|
-
}
|
|
372
|
-
const isrEntries = entries.filter((e) => e.isr).map((e) => [e.destination.replace(/\.func$/, ""), { expiration: e.isr?.expiration }]);
|
|
373
|
-
return {
|
|
374
|
-
rewrites: entries.filter((e) => {
|
|
375
|
-
if (e.addRoute === void 0 && e.route !== void 0) {
|
|
376
|
-
return e.route !== false;
|
|
377
|
-
}
|
|
378
|
-
if (e.addRoute !== void 0 && e.route === void 0) {
|
|
379
|
-
return e.addRoute !== false;
|
|
380
|
-
}
|
|
381
|
-
if (e.addRoute !== void 0 && e.route !== void 0) {
|
|
382
|
-
throw new Error("Cannot use both `route` and `addRoute` in `additionalEndpoints`");
|
|
383
|
-
}
|
|
384
|
-
return true;
|
|
385
|
-
}).map((e) => {
|
|
386
|
-
const destination = e.destination.replace(/\.func$/, "");
|
|
387
|
-
if (typeof e.route === "string") {
|
|
388
|
-
return {
|
|
389
|
-
source: `(${e.route})`,
|
|
390
|
-
destination: `${destination}/?__original_path=$1`
|
|
391
|
-
};
|
|
392
|
-
}
|
|
393
|
-
return {
|
|
394
|
-
source: replaceBrackets(getSourceAndDestination(destination)),
|
|
395
|
-
destination: getSourceAndDestination(destination)
|
|
396
|
-
};
|
|
397
|
-
}),
|
|
398
|
-
isr: Object.fromEntries(isrEntries),
|
|
399
|
-
headers: [
|
|
400
|
-
...entries.filter((e) => e.headers).map((e) => ({
|
|
401
|
-
source: `/${e.destination.replace(/\.func$/, "")}`,
|
|
402
|
-
headers: Object.entries(e.headers ?? {}).map(([key, value]) => ({
|
|
403
|
-
key,
|
|
404
|
-
value
|
|
405
|
-
}))
|
|
406
|
-
})),
|
|
407
|
-
...headers
|
|
408
|
-
]
|
|
409
|
-
};
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
// src/config.ts
|
|
413
|
-
import path3 from "path";
|
|
414
|
-
|
|
415
|
-
// src/schemas/config/config.ts
|
|
416
|
-
import { z as z3 } from "zod";
|
|
417
|
-
var HasOrMissing = z3.array(
|
|
418
|
-
z3.union([
|
|
419
|
-
z3.object({
|
|
420
|
-
type: z3.literal("host"),
|
|
421
|
-
value: z3.string()
|
|
422
|
-
}).strict(),
|
|
423
|
-
z3.object({
|
|
424
|
-
type: z3.literal("header"),
|
|
425
|
-
key: z3.string(),
|
|
426
|
-
value: z3.string().optional()
|
|
427
|
-
}).strict(),
|
|
428
|
-
z3.object({
|
|
429
|
-
type: z3.literal("cookie"),
|
|
430
|
-
key: z3.string(),
|
|
431
|
-
value: z3.string().optional()
|
|
432
|
-
}).strict(),
|
|
433
|
-
z3.object({
|
|
434
|
-
type: z3.literal("query"),
|
|
435
|
-
key: z3.string(),
|
|
436
|
-
value: z3.string().optional()
|
|
437
|
-
}).strict()
|
|
438
|
-
])
|
|
439
|
-
).optional();
|
|
440
|
-
var vercelOutputConfigSchema = z3.object({
|
|
441
|
-
version: z3.literal(3),
|
|
442
|
-
routes: z3.array(
|
|
443
|
-
z3.union([
|
|
444
|
-
z3.object({
|
|
445
|
-
src: z3.string(),
|
|
446
|
-
dest: z3.string().optional(),
|
|
447
|
-
headers: z3.record(z3.string()).optional(),
|
|
448
|
-
methods: z3.array(z3.string()).optional(),
|
|
449
|
-
status: z3.number().int().positive().optional(),
|
|
450
|
-
continue: z3.boolean().optional(),
|
|
451
|
-
check: z3.boolean().optional(),
|
|
452
|
-
missing: HasOrMissing,
|
|
453
|
-
has: HasOrMissing,
|
|
454
|
-
locale: z3.object({
|
|
455
|
-
redirect: z3.record(z3.string()).optional(),
|
|
456
|
-
cookie: z3.string().optional()
|
|
457
|
-
}).strict().optional(),
|
|
458
|
-
middlewarePath: z3.string().optional()
|
|
459
|
-
}).strict(),
|
|
460
|
-
z3.object({
|
|
461
|
-
handle: z3.union([
|
|
462
|
-
z3.literal("rewrite"),
|
|
463
|
-
z3.literal("filesystem"),
|
|
464
|
-
z3.literal("resource"),
|
|
465
|
-
z3.literal("miss"),
|
|
466
|
-
z3.literal("hit"),
|
|
467
|
-
z3.literal("error")
|
|
468
|
-
]),
|
|
469
|
-
src: z3.string().optional(),
|
|
470
|
-
dest: z3.string().optional(),
|
|
471
|
-
status: z3.number().optional()
|
|
472
|
-
}).strict()
|
|
473
|
-
])
|
|
474
|
-
).optional(),
|
|
475
|
-
images: z3.object({
|
|
476
|
-
sizes: z3.tuple([z3.number().int().positive(), z3.number().int().positive()]),
|
|
477
|
-
domains: z3.array(z3.string()).nonempty().optional(),
|
|
478
|
-
minimumCacheTTL: z3.number().int().positive().optional(),
|
|
479
|
-
formats: z3.union([z3.literal("image/avif"), z3.literal("image/webp")]).array().nonempty().optional(),
|
|
480
|
-
dangerouslyAllowSVG: z3.boolean().optional(),
|
|
481
|
-
contentSecurityPolicy: z3.string().optional()
|
|
482
|
-
}).strict().optional(),
|
|
483
|
-
wildcard: z3.array(
|
|
484
|
-
z3.object({
|
|
485
|
-
domain: z3.string(),
|
|
486
|
-
value: z3.string()
|
|
487
|
-
}).strict()
|
|
488
|
-
).optional(),
|
|
489
|
-
overrides: z3.record(
|
|
490
|
-
z3.object({
|
|
491
|
-
path: z3.string().optional(),
|
|
492
|
-
contentType: z3.string().optional()
|
|
493
|
-
}).strict()
|
|
494
|
-
).optional(),
|
|
495
|
-
cache: z3.array(z3.string()).optional()
|
|
496
|
-
}).strict();
|
|
497
|
-
|
|
498
|
-
// src/config.ts
|
|
499
|
-
import fs2 from "fs/promises";
|
|
500
|
-
import {
|
|
501
|
-
getTransformedRoutes,
|
|
502
|
-
mergeRoutes,
|
|
503
|
-
normalizeRoutes
|
|
504
|
-
} from "@vercel/routing-utils";
|
|
505
|
-
function reorderEnforce(arr) {
|
|
506
|
-
return [
|
|
507
|
-
...arr.filter((r) => r.enforce === "pre"),
|
|
508
|
-
...arr.filter((r) => !r.enforce),
|
|
509
|
-
...arr.filter((r) => r.enforce === "post")
|
|
510
|
-
];
|
|
511
|
-
}
|
|
512
|
-
function getConfig(resolvedConfig, rewrites, overrides, headers) {
|
|
513
|
-
const _rewrites = [
|
|
514
|
-
// User provided config always comes first
|
|
515
|
-
...resolvedConfig.vercel?.rewrites ?? [],
|
|
516
|
-
...rewrites ?? []
|
|
517
|
-
];
|
|
518
|
-
const _enforcedRewrites = reorderEnforce(_rewrites).map((r) => {
|
|
519
|
-
r.source = r.source.replaceAll(/:\[(\.\.\.)(.*)\]/g, ":$2*");
|
|
520
|
-
r.source = r.source.replaceAll(/:(\.\.\.)(.*)/g, ":$2+");
|
|
521
|
-
return r;
|
|
522
|
-
});
|
|
523
|
-
const { routes, error } = getTransformedRoutes({
|
|
524
|
-
cleanUrls: resolvedConfig.vercel?.cleanUrls ?? true,
|
|
525
|
-
trailingSlash: resolvedConfig.vercel?.trailingSlash,
|
|
526
|
-
rewrites: _enforcedRewrites,
|
|
527
|
-
redirects: resolvedConfig.vercel?.redirects ? reorderEnforce(resolvedConfig.vercel?.redirects) : void 0,
|
|
528
|
-
headers
|
|
529
|
-
});
|
|
530
|
-
if (error) {
|
|
531
|
-
throw error;
|
|
532
|
-
}
|
|
533
|
-
if (resolvedConfig.vercel?.config?.routes && resolvedConfig.vercel.config.routes.length > 0 && !resolvedConfig.vercel.config.routes.every((r) => "continue" in r && r.continue)) {
|
|
534
|
-
console.warn(
|
|
535
|
-
'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`.'
|
|
536
|
-
);
|
|
537
|
-
}
|
|
538
|
-
let userRoutes = [];
|
|
539
|
-
let buildRoutes = [];
|
|
540
|
-
if (resolvedConfig.vercel?.config?.routes) {
|
|
541
|
-
const norm = normalizeRoutes(resolvedConfig.vercel.config.routes);
|
|
542
|
-
if (norm.error) {
|
|
543
|
-
throw norm.error;
|
|
544
|
-
}
|
|
545
|
-
userRoutes = norm.routes ?? [];
|
|
546
|
-
}
|
|
547
|
-
if (routes) {
|
|
548
|
-
const norm = normalizeRoutes(routes);
|
|
549
|
-
if (norm.error) {
|
|
550
|
-
throw norm.error;
|
|
551
|
-
}
|
|
552
|
-
buildRoutes = norm.routes ?? [];
|
|
553
|
-
}
|
|
554
|
-
const cleanRoutes = mergeRoutes({
|
|
555
|
-
userRoutes,
|
|
556
|
-
builds: [
|
|
557
|
-
{
|
|
558
|
-
use: "@vercel/node",
|
|
559
|
-
entrypoint: "index.js",
|
|
560
|
-
routes: buildRoutes
|
|
561
|
-
}
|
|
562
|
-
]
|
|
563
|
-
});
|
|
564
|
-
return vercelOutputConfigSchema.parse({
|
|
565
|
-
version: 3,
|
|
566
|
-
...resolvedConfig.vercel?.config,
|
|
567
|
-
routes: cleanRoutes,
|
|
568
|
-
overrides: {
|
|
569
|
-
...resolvedConfig.vercel?.config?.overrides,
|
|
570
|
-
...overrides
|
|
571
|
-
}
|
|
572
|
-
});
|
|
573
|
-
}
|
|
574
|
-
function getConfigDestination(resolvedConfig) {
|
|
575
|
-
return path3.join(getOutput(resolvedConfig), "config.json");
|
|
576
|
-
}
|
|
577
|
-
async function writeConfig(resolvedConfig, rewrites, overrides, headers) {
|
|
578
|
-
await fs2.writeFile(
|
|
579
|
-
getConfigDestination(resolvedConfig),
|
|
580
|
-
JSON.stringify(getConfig(resolvedConfig, rewrites, overrides, headers), void 0, 2),
|
|
581
|
-
"utf-8"
|
|
582
|
-
);
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
// src/helpers.ts
|
|
586
|
-
import fs3 from "fs/promises";
|
|
587
|
-
import path4 from "path";
|
|
588
|
-
async function copyDir(src, dest) {
|
|
589
|
-
await fs3.mkdir(dest, { recursive: true });
|
|
590
|
-
const entries = await fs3.readdir(src, { withFileTypes: true });
|
|
591
|
-
for (const entry of entries) {
|
|
592
|
-
const srcPath = path4.join(src, entry.name);
|
|
593
|
-
const destPath = path4.join(dest, entry.name);
|
|
594
|
-
entry.isDirectory() ? await copyDir(srcPath, destPath) : await fs3.copyFile(srcPath, destPath);
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
// src/prerender.ts
|
|
599
|
-
import fs4 from "fs/promises";
|
|
600
|
-
import path5 from "path";
|
|
601
|
-
|
|
602
|
-
// src/schemas/config/prerender-config.ts
|
|
603
|
-
import { z as z4 } from "zod";
|
|
604
|
-
var vercelOutputPrerenderConfigSchema = z4.object({
|
|
605
|
-
expiration: z4.union([z4.number().int().positive(), z4.literal(false)]),
|
|
606
|
-
group: z4.number().int().optional(),
|
|
607
|
-
bypassToken: z4.string().optional(),
|
|
608
|
-
fallback: z4.string().optional(),
|
|
609
|
-
allowQuery: z4.array(z4.string()).optional()
|
|
610
|
-
}).strict();
|
|
611
|
-
|
|
612
|
-
// src/prerender.ts
|
|
613
|
-
function execPrerender(resolvedConfig) {
|
|
614
|
-
const prerender = resolvedConfig.vercel?.prerender;
|
|
615
|
-
if (prerender === false) {
|
|
616
|
-
return;
|
|
617
|
-
}
|
|
618
|
-
return prerender?.(resolvedConfig);
|
|
619
|
-
}
|
|
620
|
-
var group = 1;
|
|
621
|
-
async function writePrerenderConfig(resolvedConfig, destination, isr) {
|
|
622
|
-
const parsed = path5.parse(destination);
|
|
623
|
-
const outfile = path5.join(getOutput(resolvedConfig, "functions"), parsed.dir, `${parsed.name}.prerender-config.json`);
|
|
624
|
-
await fs4.mkdir(path5.join(getOutput(resolvedConfig, "functions"), parsed.dir), { recursive: true });
|
|
625
|
-
await fs4.writeFile(
|
|
626
|
-
outfile,
|
|
627
|
-
JSON.stringify(
|
|
628
|
-
vercelOutputPrerenderConfigSchema.parse({
|
|
629
|
-
group: group++,
|
|
630
|
-
...isr
|
|
631
|
-
}),
|
|
632
|
-
void 0,
|
|
633
|
-
2
|
|
634
|
-
),
|
|
635
|
-
"utf-8"
|
|
636
|
-
);
|
|
637
|
-
}
|
|
638
|
-
function getPrerenderSymlinkInfo(resolvedConfig, destination, target) {
|
|
639
|
-
const parsed = path5.parse(destination);
|
|
640
|
-
const targetParsed = path5.parse(target);
|
|
641
|
-
return {
|
|
642
|
-
target: path5.join(getOutput(resolvedConfig, "functions"), targetParsed.dir, `${targetParsed.name}.func`),
|
|
643
|
-
link: path5.join(getOutput(resolvedConfig, "functions"), parsed.dir, `${parsed.name}.func`)
|
|
644
|
-
};
|
|
645
|
-
}
|
|
646
|
-
async function buildPrerenderConfigs(resolvedConfig, extractedIsr) {
|
|
647
|
-
const isr = Object.assign({}, extractedIsr, await getIsrConfig(resolvedConfig));
|
|
648
|
-
const entries = Object.entries(isr);
|
|
649
|
-
const rewrites = [];
|
|
650
|
-
for (const [destination, { symlink, route, ...isr2 }] of entries) {
|
|
651
|
-
await writePrerenderConfig(resolvedConfig, destination, isr2);
|
|
652
|
-
if (symlink) {
|
|
653
|
-
const info = getPrerenderSymlinkInfo(resolvedConfig, destination, symlink);
|
|
654
|
-
await copyDir(info.target, info.link);
|
|
655
|
-
}
|
|
656
|
-
if (route) {
|
|
657
|
-
rewrites.push({
|
|
658
|
-
source: `(${route})`,
|
|
659
|
-
destination: `${destination}/?__original_path=$1`
|
|
660
|
-
});
|
|
661
|
-
}
|
|
662
|
-
}
|
|
663
|
-
return rewrites;
|
|
664
|
-
}
|
|
665
|
-
async function getIsrConfig(resolvedConfig) {
|
|
666
|
-
const isr = resolvedConfig.vercel?.isr ?? {};
|
|
667
|
-
if (typeof isr === "function") {
|
|
668
|
-
return await isr();
|
|
669
|
-
}
|
|
670
|
-
return isr;
|
|
65
|
+
if (!exp) return;
|
|
66
|
+
return _eval(isPrimitive(exp) ? exp : generateCode(exp).code);
|
|
671
67
|
}
|
|
672
68
|
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
let resolvedConfig;
|
|
676
|
-
return {
|
|
677
|
-
apply: "build",
|
|
678
|
-
name: "vite-plugin-vercel:cleanup",
|
|
679
|
-
enforce: "pre",
|
|
680
|
-
configResolved(config) {
|
|
681
|
-
resolvedConfig = config;
|
|
682
|
-
},
|
|
683
|
-
writeBundle: {
|
|
684
|
-
order: "pre",
|
|
685
|
-
sequential: true,
|
|
686
|
-
async handler() {
|
|
687
|
-
if (!resolvedConfig.build?.ssr) {
|
|
688
|
-
await cleanOutputDirectory(resolvedConfig);
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
};
|
|
693
|
-
}
|
|
694
|
-
function vercelPlugin() {
|
|
695
|
-
let resolvedConfig;
|
|
696
|
-
let vikeFound = false;
|
|
697
|
-
return {
|
|
698
|
-
apply: "build",
|
|
699
|
-
name: "vite-plugin-vercel",
|
|
700
|
-
enforce: "post",
|
|
701
|
-
configResolved(config) {
|
|
702
|
-
resolvedConfig = config;
|
|
703
|
-
vikeFound = resolvedConfig.plugins.some((p) => p.name.match("^vite-plugin-ssr:|^vike:"));
|
|
704
|
-
if (typeof resolvedConfig.vercel?.distContainsOnlyStatic === "undefined") {
|
|
705
|
-
resolvedConfig.vercel ??= {};
|
|
706
|
-
resolvedConfig.vercel.distContainsOnlyStatic = !vikeFound;
|
|
707
|
-
}
|
|
708
|
-
},
|
|
709
|
-
writeBundle: {
|
|
710
|
-
order: "post",
|
|
711
|
-
sequential: true,
|
|
712
|
-
async handler() {
|
|
713
|
-
if (!resolvedConfig.build?.ssr) {
|
|
714
|
-
if (vikeFound) {
|
|
715
|
-
return;
|
|
716
|
-
}
|
|
717
|
-
}
|
|
718
|
-
const overrides = await execPrerender(resolvedConfig);
|
|
719
|
-
const userOverrides = await computeStaticHtmlOverrides(resolvedConfig);
|
|
720
|
-
const { rewrites, isr, headers } = await buildEndpoints(resolvedConfig);
|
|
721
|
-
rewrites.push(...await buildPrerenderConfigs(resolvedConfig, isr));
|
|
722
|
-
await writeConfig(
|
|
723
|
-
resolvedConfig,
|
|
724
|
-
rewrites,
|
|
725
|
-
{
|
|
726
|
-
...userOverrides,
|
|
727
|
-
...overrides
|
|
728
|
-
},
|
|
729
|
-
headers
|
|
730
|
-
);
|
|
731
|
-
await copyDistToStatic(resolvedConfig);
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
};
|
|
735
|
-
}
|
|
736
|
-
async function cleanOutputDirectory(resolvedConfig) {
|
|
737
|
-
await fs5.rm(getOutput(resolvedConfig), {
|
|
738
|
-
recursive: true,
|
|
739
|
-
force: true
|
|
740
|
-
});
|
|
741
|
-
await fs5.mkdir(getOutput(resolvedConfig), { recursive: true });
|
|
742
|
-
}
|
|
743
|
-
async function copyDistToStatic(resolvedConfig) {
|
|
744
|
-
if (resolvedConfig.vercel?.distContainsOnlyStatic) {
|
|
745
|
-
await copyDir(resolvedConfig.build.outDir, getOutput(resolvedConfig, "static"));
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
async function computeStaticHtmlOverrides(resolvedConfig) {
|
|
749
|
-
const staticAbsolutePath = getOutput(resolvedConfig, "static");
|
|
750
|
-
const files = await getStaticHtmlFiles(staticAbsolutePath);
|
|
751
|
-
const publicDir = getPublic(resolvedConfig);
|
|
752
|
-
const publicFiles = await getStaticHtmlFiles(publicDir);
|
|
753
|
-
files.push(...publicFiles.map((f) => f.replace(publicDir, staticAbsolutePath)));
|
|
754
|
-
return files.reduce(
|
|
755
|
-
(acc, curr) => {
|
|
756
|
-
const relPath = path6.relative(staticAbsolutePath, curr);
|
|
757
|
-
const parsed = path6.parse(relPath);
|
|
758
|
-
const pathJoined = path6.join(parsed.dir, parsed.name);
|
|
759
|
-
acc[relPath] = {
|
|
760
|
-
path: pathJoined
|
|
761
|
-
};
|
|
762
|
-
return acc;
|
|
763
|
-
},
|
|
764
|
-
{}
|
|
765
|
-
);
|
|
766
|
-
}
|
|
767
|
-
async function getStaticHtmlFiles(src) {
|
|
768
|
-
try {
|
|
769
|
-
await fs5.stat(src);
|
|
770
|
-
} catch (e) {
|
|
771
|
-
return [];
|
|
772
|
-
}
|
|
773
|
-
const entries = await fs5.readdir(src, { withFileTypes: true });
|
|
774
|
-
const htmlFiles = [];
|
|
775
|
-
for (const entry of entries) {
|
|
776
|
-
const srcPath = path6.join(src, entry.name);
|
|
777
|
-
entry.isDirectory() ? htmlFiles.push(...await getStaticHtmlFiles(srcPath)) : srcPath.endsWith(".html") ? htmlFiles.push(srcPath) : void 0;
|
|
778
|
-
}
|
|
779
|
-
return htmlFiles;
|
|
780
|
-
}
|
|
781
|
-
async function tryImportVpvv(options) {
|
|
782
|
-
try {
|
|
783
|
-
await import("vike/plugin");
|
|
784
|
-
const vpvv = await import("@vite-plugin-vercel/vike");
|
|
785
|
-
return vpvv.default(options);
|
|
786
|
-
} catch (e) {
|
|
787
|
-
try {
|
|
788
|
-
await import("vite-plugin-ssr/plugin");
|
|
789
|
-
const vpvv = await import("@vite-plugin-vercel/vike");
|
|
790
|
-
return vpvv.default(options);
|
|
791
|
-
} catch (e2) {
|
|
792
|
-
return null;
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
}
|
|
796
|
-
function allPlugins(options = {}) {
|
|
797
|
-
const { smart, ...rest } = options;
|
|
798
|
-
return [vercelPluginCleanup(), vercelPlugin(), smart !== false ? tryImportVpvv(rest) : null];
|
|
799
|
-
}
|
|
800
|
-
export {
|
|
801
|
-
allPlugins as default
|
|
802
|
-
};
|
|
69
|
+
//#endregion
|
|
70
|
+
export { extractExports, getVercelEntries };
|