vite-plugin-vercel 9.0.6 → 10.0.0-beta.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,136 +1,104 @@
1
- // src/index.ts
2
- import fs5 from "node:fs/promises";
3
- import path6 from "node:path";
1
+ import {
2
+ entryToPathtoregex,
3
+ photonEntryDestination,
4
+ photonEntryDestinationDefault
5
+ } from "./chunk-OCCU6UM5.js";
6
+ import {
7
+ createAPI,
8
+ getVercelAPI
9
+ } from "./chunk-CR7Q2T4Q.js";
10
+ import {
11
+ assert
12
+ } from "./chunk-UTQ72LMT.js";
4
13
 
5
- // src/build.ts
6
- import fs, { copyFile } from "node:fs/promises";
7
- import { builtinModules } from "node:module";
8
- import path2, { basename } from "node:path";
14
+ // src/plugins/index.ts
15
+ import { installPhoton } from "@photonjs/runtime/vite";
16
+
17
+ // src/plugins/api.ts
18
+ function apiPlugin(pluginConfig) {
19
+ const outfiles = [];
20
+ return {
21
+ name: "vite-plugin-vercel:api",
22
+ api() {
23
+ return createAPI(outfiles, pluginConfig);
24
+ },
25
+ // Compute outfiles for the API
26
+ writeBundle(_opts, bundle2) {
27
+ if (this.environment.name !== "vercel_edge" && this.environment.name !== "vercel_node") return;
28
+ const entries = this.environment.config.photon.entries;
29
+ const server = this.environment.config.photon.server;
30
+ const entryMapByDestination = new Map(
31
+ [server, ...Object.values(entries)].map((e) => [photonEntryDestination(e, ".func/index"), e])
32
+ );
33
+ for (const entry of this.environment.config.photon.entries.filter((e) => e.type === "server-config")) {
34
+ entryMapByDestination.set(photonEntryDestination(entry, ".func/index"), entry);
35
+ }
36
+ for (const [key, value] of Object.entries(bundle2)) {
37
+ if (value.type === "chunk" && value.isEntry && entryMapByDestination.has(removeExtension(key))) {
38
+ outfiles.push({
39
+ type: "chunk",
40
+ root: this.environment.config.root,
41
+ outdir: this.environment.config.build.outDir,
42
+ filepath: key,
43
+ // biome-ignore lint/style/noNonNullAssertion: guarded by entryMap.has(...)
44
+ relatedEntry: entryMapByDestination.get(removeExtension(key))
45
+ });
46
+ } else if (value.type === "asset" && key.startsWith("functions/") || key === "config.json") {
47
+ outfiles.push({
48
+ type: "asset",
49
+ root: this.environment.config.root,
50
+ outdir: this.environment.config.build.outDir,
51
+ filepath: key
52
+ });
53
+ }
54
+ }
55
+ },
56
+ sharedDuringBuild: true
57
+ };
58
+ }
59
+ function removeExtension(subject) {
60
+ return subject.replace(/\.[^/.]+$/, "");
61
+ }
62
+
63
+ // src/plugins/bundle.ts
64
+ import { existsSync, readFileSync, writeFileSync } from "fs";
65
+ import { copyFile, mkdir, rm } from "fs/promises";
66
+ import { builtinModules } from "module";
67
+ import path2 from "path";
9
68
  import { findRoot } from "@manypkg/find-root";
10
- import { getNodeVersion } from "@vercel/build-utils";
11
69
  import { nodeFileTrace } from "@vercel/nft";
12
70
  import { build } from "esbuild";
13
- import glob from "fast-glob";
14
- import { generateCode, loadFile } from "magicast";
15
71
 
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;
72
+ // src/helpers.ts
73
+ import path from "path";
74
+ function joinAbsolute(env_or_p0, p1, ...p) {
75
+ if (path.isAbsolute(p1)) {
76
+ return path.join(p1, ...p);
22
77
  }
23
- const err = newError(`[${libName}][Wrong Usage] ${errorMessage}`, 2);
24
- throw err;
78
+ return path.join(typeof env_or_p0 === "string" ? env_or_p0 : env_or_p0.config.root, p1, ...p);
79
+ }
80
+ function joinAbsolutePosix(env_or_p0, p1, ...p) {
81
+ if (path.isAbsolute(p1)) {
82
+ return path.posix.join(p1, ...p);
83
+ }
84
+ return path.posix.join(typeof env_or_p0 === "string" ? env_or_p0 : env_or_p0.config.root, p1, ...p);
25
85
  }
26
86
 
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
- });
87
+ // src/utils/edge.ts
88
+ var edgeConditions = ["edge-light", "worker", "browser", "module", "import", "default"];
66
89
 
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));
90
+ // src/utils/env.ts
91
+ function isVercelLastBuildStep(env) {
92
+ const name = typeof env !== "string" ? env.name : env;
93
+ return name === "vercel_node";
86
94
  }
87
95
 
88
- // src/build.ts
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) => ({
106
- ...e,
107
- route: e.route ?? true,
108
- // path.resolve removes the trailing slash if any
109
- destination: `${path2.posix.resolve("/", e.destination)}.func`
110
- }));
111
- }
112
- async function getEntries(resolvedConfig) {
113
- const apiEntries = glob.sync(`${getRoot(resolvedConfig)}/api/**/*.*([a-zA-Z0-9])`).filter((filepath) => !path2.basename(filepath).startsWith("_"));
114
- if (apiEntries.length > 0) {
115
- console.warn(
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."
117
- );
118
- }
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
- );
133
- }
96
+ // src/utils/external.ts
97
+ var _external = ["async_hooks", "events", "buffer", "assert", "util"];
98
+ var edgeExternal = [..._external, ..._external.map((e) => `node:${e}`)];
99
+
100
+ // src/plugins/bundle.ts
101
+ var builtIns = new Set(builtinModules.flatMap((m) => [m, `node:${m}`]));
134
102
  var edgeWasmPlugin = {
135
103
  name: "edge-wasm-vercel",
136
104
  setup(build2) {
@@ -142,366 +110,411 @@ var edgeWasmPlugin = {
142
110
  });
143
111
  }
144
112
  };
145
- var vercelOgPlugin = (ctx) => {
146
- return {
147
- name: "vercel-og",
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"'
113
+ var dynamicNativeImportPlugin = {
114
+ name: "edge-dynamic-import-native",
115
+ setup(build2) {
116
+ build2.onResolve({ filter: /.*/ }, (args) => {
117
+ if (args.kind === "dynamic-import" && builtIns.has(args.path)) {
118
+ return { path: args.path, external: true };
119
+ }
120
+ });
175
121
  }
176
122
  };
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);
123
+ var reactEdgePlugin = {
124
+ name: "react-edge-plugin",
125
+ setup(build2) {
126
+ build2.onResolve({ filter: /^react-dom\/server$/ }, (args) => {
127
+ const { path: _, ...rest } = args;
128
+ return build2.resolve("react-dom/server.edge", rest);
129
+ });
185
130
  }
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;
131
+ };
132
+ function bundlePlugin(pluginConfig) {
133
+ const bundledAssets = /* @__PURE__ */ new Map();
134
+ return [
135
+ {
136
+ name: "vite-plugin-vercel:bundle",
137
+ enforce: "post",
138
+ apply: "build",
139
+ generateBundle(_opts, bundle2) {
140
+ for (const b of Object.values(bundle2)) {
141
+ if (b.type === "asset") {
142
+ const originalFileNames = b.originalFileNames.map(
143
+ (relativePath) => path2.resolve(this.environment.config.root, relativePath)
144
+ );
145
+ const asset = {
146
+ env: this.environment.name,
147
+ root: this.environment.config.root,
148
+ outDir: this.environment.config.build.outDir,
149
+ outFile: joinAbsolute(this.environment, this.environment.config.build.outDir, b.fileName),
150
+ fileName: b.fileName
151
+ };
152
+ for (const originalFileName of originalFileNames) {
153
+ bundledAssets.set(originalFileName, asset);
154
+ }
155
+ }
156
+ }
157
+ },
158
+ closeBundle: {
159
+ order: "post",
160
+ async handler() {
161
+ if (!isVercelLastBuildStep(this.environment)) return;
162
+ this.environment.logger.info("Creating Vercel bundles...");
163
+ const api = getVercelAPI(this);
164
+ const outfiles = api.getOutFiles();
165
+ for (const outfile of outfiles) {
166
+ if (outfile.type === "asset") {
167
+ const { source, destination } = getAbsoluteOutFileWithout_tmp(outfile);
168
+ await mkdir(path2.dirname(destination), { recursive: true });
169
+ await copyFile(source, destination);
170
+ } else {
171
+ await bundle(this.environment, bundledAssets, outfile);
172
+ }
173
+ }
174
+ const tmpDir = pluginConfig.outDir ? path2.posix.join(pluginConfig.outDir, "_tmp") : ".vercel/output/_tmp";
175
+ await rm(tmpDir, { recursive: true });
176
+ }
177
+ },
178
+ sharedDuringBuild: true
196
179
  }
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);
180
+ ];
181
+ }
182
+ function getAbsoluteOutFileWithout_tmp(outfile) {
183
+ const source = joinAbsolutePosix(outfile.root, outfile.outdir, outfile.filepath);
184
+ const destination = source.replace(outfile.outdir, outfile.outdir.replace(/_tmp(\/|\\|$)/, ""));
185
+ return {
186
+ source,
187
+ destination
188
+ };
189
+ }
190
+ async function bundle(environment, bundledAssets, outfile) {
191
+ const { source, destination } = getAbsoluteOutFileWithout_tmp(outfile);
192
+ const isEdge = Boolean(outfile.relatedEntry.vercel?.edge);
193
+ const buildOptions = {
194
+ format: "esm",
195
+ target: "es2022",
196
+ legalComments: "none",
197
+ bundle: true,
198
+ entryPoints: [source],
199
+ treeShaking: true,
200
+ logOverride: { "ignored-bare-import": "silent" }
201
+ };
202
+ if (isEdge) {
203
+ buildOptions.platform = "browser";
204
+ buildOptions.external = edgeExternal;
205
+ buildOptions.conditions = edgeConditions;
206
+ buildOptions.define = {
207
+ "process.env.NODE_ENV": JSON.stringify("production")
208
+ };
209
+ buildOptions.outExtension = { ".js": ".mjs" };
210
+ buildOptions.outfile = destination.replace(/\.mjs$/, ".js");
211
+ buildOptions.plugins = [edgeWasmPlugin, dynamicNativeImportPlugin, reactEdgePlugin];
212
+ } else {
213
+ buildOptions.platform = "node";
214
+ buildOptions.outfile = destination.replace(/\.js$/, ".mjs");
215
+ buildOptions.banner = {
216
+ js: `import { createRequire as topLevelCreateRequire } from 'module';
217
+ import { dirname as topLevelDirname } from 'path';
218
+ import { fileURLToPath as topLevelFileURLToPath } from 'url';
219
+ const require = topLevelCreateRequire(import.meta.url);
220
+ const __filename = topLevelFileURLToPath(import.meta.url);
221
+ const __dirname = topLevelDirname(__filename);
212
222
  `
213
223
  };
214
224
  }
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");
225
+ try {
226
+ await build(buildOptions);
227
+ } catch (e) {
228
+ throw new Error(`Error while bundling ${destination}`, { cause: e });
229
+ }
230
+ let base = environment.config.root;
231
+ try {
232
+ const dir = await findRoot(environment.config.root);
233
+ base = dir.rootDir;
234
+ } catch (_e) {
235
+ }
236
+ const entryFilePath = existsSync(outfile.relatedEntry.id) ? outfile.relatedEntry.id : outfile.relatedEntry.resolvedId && existsSync(outfile.relatedEntry.resolvedId) ? outfile.relatedEntry.resolvedId : null;
237
+ if (entryFilePath === null) {
238
+ return;
239
+ }
240
+ const { fileList, reasons } = await nodeFileTrace([entryFilePath], {
241
+ base,
242
+ processCwd: environment.config.root,
243
+ mixedModules: true,
244
+ // https://github.com/vercel/next.js/blob/7c8e2b4e50449ce2d2c83de0b5638c61b7de2362/packages/next/src/build/collect-build-traces.ts#L201
245
+ ignore: [
246
+ "**/node_modules/react{,-dom,-dom-server-turbopack}/**/*.development.js",
247
+ "**/*.d.ts",
248
+ "**/*.map",
249
+ "**/node_modules/webpack5/**/*"
250
+ ],
251
+ async readFile(filepath) {
252
+ if (filepath.endsWith(".ts") || filepath.endsWith(".tsx")) {
253
+ const result = await build({
254
+ target: "es2022",
255
+ format: "esm",
256
+ platform: "node",
257
+ logLevel: "info",
258
+ logOverride: {
259
+ "ignored-bare-import": "verbose",
260
+ "require-resolve-not-external": "verbose"
261
+ },
262
+ minify: false,
263
+ plugins: [],
264
+ define: {
265
+ "process.env.NODE_ENV": '"production"',
266
+ "import.meta.env.NODE_ENV": '"production"'
267
+ },
268
+ entryPoints: [entryFilePath],
269
+ bundle: false,
270
+ write: false
271
+ });
272
+ return result.outputFiles[0].text;
246
273
  }
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))
274
+ return readFileSync(filepath, "utf-8");
275
+ }
276
+ });
277
+ for (const file of fileList) {
278
+ if (reasons.has(file) && reasons.get(file)?.type.includes("asset") && !file.endsWith(".js") && !file.endsWith(".cjs") && !file.endsWith(".mjs") && !file.endsWith("package.json")) {
279
+ const absolutePath = path2.join(base, file);
280
+ const assetRenamedByVite = bundledAssets.get(absolutePath);
281
+ const basename = path2.basename(assetRenamedByVite ? assetRenamedByVite.fileName : absolutePath);
282
+ if (assetRenamedByVite) {
283
+ writeFileSync(
284
+ destination,
285
+ readFileSync(destination, "utf-8").replaceAll(
286
+ `/${assetRenamedByVite.fileName}`,
287
+ `./${path2.basename(assetRenamedByVite.fileName)}`
288
+ )
253
289
  );
254
290
  }
291
+ await copyFile(absolutePath, path2.join(path2.dirname(destination), basename));
255
292
  }
256
293
  }
257
- await writeVcConfig(resolvedConfig, entry.destination, filename, {
258
- edge: Boolean(entry.edge),
259
- streaming: entry.streaming
260
- });
261
- return output;
262
294
  }
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("/");
297
- }
298
- function isPrimitive(test) {
299
- return test !== Object(test);
300
- }
301
- function _eval(code) {
302
- const func = new Function(`{ return function(){ return ${code} } };`);
303
- return func.call(null).call(null);
304
- }
305
- function evalExport(exp) {
306
- if (!exp) return;
307
- const code = isPrimitive(exp) ? exp : generateCode(exp).code;
308
- return _eval(code);
295
+
296
+ // src/plugins/clean-outdir.ts
297
+ import fs from "fs";
298
+ import path3 from "path";
299
+ function vercelCleanupPlugin(pluginConfig) {
300
+ let alreadyRun = false;
301
+ return {
302
+ apply: "build",
303
+ name: "vite-plugin-vercel:cleanup",
304
+ enforce: "pre",
305
+ applyToEnvironment(env) {
306
+ return env.name === "client";
307
+ },
308
+ buildStart: {
309
+ order: "pre",
310
+ sequential: true,
311
+ handler() {
312
+ if (alreadyRun) return;
313
+ alreadyRun = true;
314
+ const absoluteOutdir = pluginConfig?.outDir && path3.isAbsolute(pluginConfig.outDir) ? pluginConfig.outDir : path3.join(this.environment.config.root, pluginConfig?.outDir ?? ".vercel/output");
315
+ cleanOutputDirectory(absoluteOutdir);
316
+ }
317
+ },
318
+ sharedDuringBuild: true
319
+ };
309
320
  }
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
- }
321
+ function cleanOutputDirectory(outdir) {
322
+ fs.rmSync(outdir, {
323
+ recursive: true,
324
+ force: true
325
+ });
326
+ fs.mkdirSync(outdir, { recursive: true });
323
327
  }
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;
328
+
329
+ // src/plugins/loader.ts
330
+ import { targetLoader } from "@photonjs/core/vite";
331
+ import { getNodeVersion } from "@vercel/build-utils";
332
+ import { vercelOutputPrerenderConfigSchema } from "@vite-plugin-vercel/schemas";
333
+ import { toPathToRegexpV6 } from "convert-route/path-to-regexp-v6";
334
+ import { fromRou3 } from "convert-route/rou3";
335
+
336
+ // src/build.ts
337
+ import { vercelOutputVcConfigSchema } from "@vite-plugin-vercel/schemas";
338
+ function getVcConfig(pluginConfig, filename, options) {
339
+ return vercelOutputVcConfigSchema.parse(
340
+ options.edge ? {
341
+ runtime: "edge",
342
+ entrypoint: filename
343
+ } : {
344
+ runtime: options.nodeVersion.runtime,
345
+ handler: filename,
346
+ maxDuration: pluginConfig.defaultMaxDuration,
347
+ launcherType: "Nodejs",
348
+ shouldAddHelpers: true,
349
+ supportsResponseStreaming: options.streaming ?? pluginConfig.defaultSupportsResponseStreaming
350
+ }
351
+ );
332
352
  }
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
- );
353
+
354
+ // src/plugins/loader.ts
355
+ var DUMMY = "__DUMMY__";
356
+ var re_DUMMY = new RegExp(`${DUMMY}$`);
357
+ var nonEdgeServers = ["express", "fastify"];
358
+ function loaderPlugin(pluginConfig) {
359
+ let nodeVersion;
360
+ return [
361
+ {
362
+ name: "vite-plugin-vercel:update-entries",
363
+ apply: "build",
364
+ buildStart: {
365
+ order: "post",
366
+ handler() {
367
+ for (const entry of [this.environment.config.photon.server, ...this.environment.config.photon.entries]) {
368
+ if (!entry.env) {
369
+ entry.env = entry.vercel?.edge ? "vercel_edge" : "vercel_node";
370
+ }
371
+ if (entry.env === "vercel_edge" || entry.env === "vercel_node") {
372
+ entry.target = `${photonEntryDestination(entry, ".func/index")}.js`;
373
+ }
374
+ }
350
375
  }
351
- if (exports.edge !== void 0) {
352
- entry.edge = exports.edge;
376
+ },
377
+ sharedDuringBuild: true
378
+ },
379
+ {
380
+ name: "vite-plugin-vercel:dummy",
381
+ enforce: "pre",
382
+ resolveId: {
383
+ filter: {
384
+ id: re_DUMMY
385
+ },
386
+ handler(id) {
387
+ return id;
353
388
  }
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
- );
389
+ },
390
+ load: {
391
+ filter: {
392
+ id: re_DUMMY
393
+ },
394
+ handler() {
395
+ return "export default {};";
358
396
  }
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}')`);
397
+ }
398
+ },
399
+ ...targetLoader("vercel", {
400
+ async buildStart() {
401
+ nodeVersion = await getNodeVersion(process.cwd());
402
+ },
403
+ applyToEnvironment(env) {
404
+ return env.name === "vercel_node" || env.name === "vercel_edge" || env.name === "vercel_client";
405
+ },
406
+ async load(_id, { meta }) {
407
+ const entry = meta;
408
+ const isEdge = Boolean(entry.vercel?.edge);
409
+ this.emitFile({
410
+ type: "asset",
411
+ fileName: photonEntryDestination(entry, ".func/.vc-config.json"),
412
+ source: JSON.stringify(
413
+ // Unpredictable things happen when the extension is .mjs on edge
414
+ getVcConfig(pluginConfig, isEdge ? "index.js" : "index.mjs", {
415
+ nodeVersion,
416
+ edge: isEdge,
417
+ streaming: entry.vercel?.streaming
418
+ }),
419
+ void 0,
420
+ 2
421
+ )
422
+ });
423
+ if (entry.vercel?.isr) {
424
+ this.emitFile({
425
+ type: "asset",
426
+ fileName: photonEntryDestination(entry, ".prerender-config.json"),
427
+ source: JSON.stringify(vercelOutputPrerenderConfigSchema.parse(entry.vercel.isr), void 0, 2)
428
+ });
361
429
  }
362
- if (exports.isr) {
363
- entry.isr = exports.isr;
430
+ if (entry.route || entry.vercel?.route) {
431
+ pluginConfig.rewrites ??= [];
432
+ const source = typeof entry.vercel?.route === "string" ? `(${entry.vercel.route})` : typeof entry.route === "string" ? toPathToRegexpV6(fromRou3(entry.route)) : entryToPathtoregex(entry);
433
+ pluginConfig.rewrites.push({
434
+ enforce: entry.vercel?.enforce,
435
+ source,
436
+ destination: typeof entry.vercel?.route === "string" ? `/${photonEntryDestinationDefault(entry)}?__original_path=$1` : `/${photonEntryDestinationDefault(entry)}`
437
+ });
438
+ if (entry.vercel?.headers) {
439
+ pluginConfig.headers ??= [];
440
+ pluginConfig.headers.push({
441
+ source,
442
+ headers: Object.entries(entry.vercel.headers).map(([key, value]) => ({
443
+ key,
444
+ value
445
+ }))
446
+ });
447
+ }
364
448
  }
365
- if (typeof exports.streaming === "boolean") {
366
- entry.streaming = exports.streaming;
449
+ const fn = isEdge ? "createEdgeHandler" : "createNodeHandler";
450
+ const isServerEntry = entry.type === "server";
451
+ if (isServerEntry) {
452
+ assert(entry.server, `Could not determine server for entry ${entry.id}`);
453
+ if (isEdge) {
454
+ assert(
455
+ !nonEdgeServers.includes(entry.server),
456
+ `${entry.server} is not compatible with Vercel Edge target. Either use another server like Hono or change target to Node`
457
+ );
458
+ }
367
459
  }
460
+ const importFrom = isServerEntry ? `@universal-middleware/vercel/${entry.server}` : "@universal-middleware/vercel";
461
+ const exportDefault = isServerEntry ? `export default ${fn}(handlerOrApp)` : `export default ${fn}(() => handlerOrApp)()`;
462
+ return `
463
+ import { ${fn} } from "photon:resolve-from-photon:${importFrom}";
464
+ import handlerOrApp from "${entry.resolvedId ?? entry.id}";
465
+
466
+ ${exportDefault};
467
+ `;
368
468
  }
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
- };
469
+ })
470
+ ];
410
471
  }
411
472
 
412
- // src/config.ts
413
- import path3 from "node:path";
473
+ // src/plugins/routes.ts
474
+ function routesPlugins() {
475
+ return [
476
+ {
477
+ name: "vite-plugin-vercel:routes-dedupe",
478
+ apply: "build",
479
+ applyToEnvironment(env) {
480
+ return env.name === "ssr";
481
+ },
482
+ buildStart: {
483
+ // Ensure that this hook is executed close to last, ensuring that all plugins had time to inject their Photon entries
484
+ order: "post",
485
+ handler() {
486
+ const entriesEdge = this.environment.config.photon.entries.filter((e) => e.vercel?.edge);
487
+ const entriesNode = this.environment.config.photon.entries.filter((e) => !e.vercel?.edge);
488
+ const entriesToKeep = /* @__PURE__ */ new Set();
489
+ for (const envEntries of [entriesEdge, entriesNode]) {
490
+ for (const page of envEntries.filter(
491
+ (p) => p.vercel?.isr || p.vercel?.route && p.vercel?.headers !== null && p.vercel?.headers !== void 0
492
+ )) {
493
+ entriesToKeep.add(page);
494
+ }
495
+ }
496
+ this.environment.config.photon.entries = this.environment.config.photon.entries.filter(
497
+ (e) => !e.vikeMeta || entriesToKeep.has(e)
498
+ );
499
+ }
500
+ },
501
+ sharedDuringBuild: true
502
+ }
503
+ ];
504
+ }
414
505
 
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();
506
+ // src/plugins/setupEnvs.ts
507
+ import {
508
+ BuildEnvironment,
509
+ createLogger,
510
+ createRunnableDevEnvironment,
511
+ mergeConfig
512
+ } from "vite";
513
+ import path4 from "path";
497
514
 
498
515
  // src/config.ts
499
- import fs2 from "node:fs/promises";
500
- import {
501
- getTransformedRoutes,
502
- mergeRoutes,
503
- normalizeRoutes
504
- } from "@vercel/routing-utils";
516
+ import { getTransformedRoutes, mergeRoutes, normalizeRoutes } from "@vercel/routing-utils";
517
+ import { vercelOutputConfigSchema } from "@vite-plugin-vercel/schemas";
505
518
  function reorderEnforce(arr) {
506
519
  return [
507
520
  ...arr.filter((r) => r.enforce === "pre"),
@@ -509,36 +522,27 @@ function reorderEnforce(arr) {
509
522
  ...arr.filter((r) => r.enforce === "post")
510
523
  ];
511
524
  }
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
- });
525
+ function getConfig(pluginConfig) {
526
+ const _rewrites = [...pluginConfig.rewrites ?? []];
523
527
  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
528
+ cleanUrls: pluginConfig.cleanUrls ?? true,
529
+ trailingSlash: pluginConfig.trailingSlash,
530
+ rewrites: reorderEnforce(_rewrites),
531
+ redirects: pluginConfig.redirects ? reorderEnforce(pluginConfig.redirects) : void 0,
532
+ headers: pluginConfig.headers
529
533
  });
530
534
  if (error) {
531
535
  throw error;
532
536
  }
533
- if (resolvedConfig.vercel?.config?.routes && resolvedConfig.vercel.config.routes.length > 0 && !resolvedConfig.vercel.config.routes.every((r) => "continue" in r && r.continue)) {
537
+ if (pluginConfig.config?.routes && pluginConfig.config.routes.length > 0 && !pluginConfig.config.routes.every((r) => "continue" in r && r.continue)) {
534
538
  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`.'
539
+ '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 `routes` config to override routes. Prefer using `rewrites` and `redirects`.'
536
540
  );
537
541
  }
538
542
  let userRoutes = [];
539
543
  let buildRoutes = [];
540
- if (resolvedConfig.vercel?.config?.routes) {
541
- const norm = normalizeRoutes(resolvedConfig.vercel.config.routes);
544
+ if (pluginConfig.config?.routes) {
545
+ const norm = normalizeRoutes(pluginConfig.config.routes);
542
546
  if (norm.error) {
543
547
  throw norm.error;
544
548
  }
@@ -556,247 +560,256 @@ function getConfig(resolvedConfig, rewrites, overrides, headers) {
556
560
  builds: [
557
561
  {
558
562
  use: "@vercel/node",
559
- entrypoint: "index.js",
563
+ entrypoint: "index.mjs",
560
564
  routes: buildRoutes
561
565
  }
562
566
  ]
563
567
  });
564
568
  return vercelOutputConfigSchema.parse({
565
569
  version: 3,
566
- ...resolvedConfig.vercel?.config,
570
+ ...pluginConfig.config,
567
571
  routes: cleanRoutes,
568
572
  overrides: {
569
- ...resolvedConfig.vercel?.config?.overrides,
570
- ...overrides
573
+ ...pluginConfig.config?.overrides
571
574
  }
572
575
  });
573
576
  }
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
577
 
585
- // src/helpers.ts
586
- import fs3 from "node:fs/promises";
587
- import path4 from "node: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 path5 from "node:path";
578
+ // src/plugins/setupEnvs.ts
579
+ import stripAnsi from "strip-ansi";
600
580
 
601
- // src/schemas/config/prerender-config.ts
602
- import { z as z4 } from "zod";
603
- var vercelOutputPrerenderConfigSchema = z4.object({
604
- expiration: z4.union([z4.number().int().positive(), z4.literal(false)]),
605
- group: z4.number().int().optional(),
606
- bypassToken: z4.string().optional(),
607
- fallback: z4.string().optional(),
608
- allowQuery: z4.array(z4.string()).optional()
609
- }).strict();
581
+ // src/utils/const.ts
582
+ var virtualEntry = "virtual:vite-plugin-vercel:entry";
610
583
 
611
- // src/prerender.ts
612
- import fs4 from "node:fs/promises";
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
- };
584
+ // src/plugins/setupEnvs.ts
585
+ var outDir = ".vercel/output";
586
+ var DUMMY2 = "__DUMMY__";
587
+ function setupEnvs(pluginConfig) {
588
+ return [
589
+ {
590
+ name: "vite-plugin-vercel:setup-envs",
591
+ buildApp: {
592
+ order: "post",
593
+ async handler(builder) {
594
+ await builder.build(builder.environments.vercel_client);
595
+ await builder.build(builder.environments.vercel_edge);
596
+ await builder.build(builder.environments.vercel_node);
597
+ }
598
+ },
599
+ config() {
600
+ const outDirOverride = pluginConfig.outDir ? {
601
+ build: {
602
+ outDir: path4.posix.join(pluginConfig.outDir, "_tmp")
603
+ }
604
+ } : {};
605
+ return {
606
+ environments: {
607
+ vercel_edge: createVercelEnvironmentOptions(outDirOverride),
608
+ vercel_node: createVercelEnvironmentOptions(outDirOverride),
609
+ vercel_client: {
610
+ build: {
611
+ outDir: path4.join(pluginConfig.outDir ?? outDir, "static"),
612
+ copyPublicDir: true
613
+ },
614
+ consumer: "client"
615
+ }
616
+ },
617
+ customLogger: createVercelLogger(),
618
+ // Required for environments to be taken into account
619
+ builder: {}
620
+ };
621
+ },
622
+ sharedDuringBuild: true
623
+ },
624
+ {
625
+ name: "vite-plugin-vercel:setup-envs:vercel_edge",
626
+ applyToEnvironment(env) {
627
+ return env.name === "vercel_edge";
628
+ },
629
+ configEnvironment(name, config, env) {
630
+ if (name !== "vercel_edge") return;
631
+ const isDev = env.command === "serve";
632
+ const conditions = !isDev ? {
633
+ conditions: edgeConditions
634
+ } : {};
635
+ return {
636
+ resolve: {
637
+ external: edgeExternal,
638
+ ...conditions
639
+ },
640
+ build: {
641
+ target: "es2022",
642
+ rollupOptions: {
643
+ input: {},
644
+ treeshake: "smallest"
645
+ }
646
+ },
647
+ optimizeDeps: {
648
+ ...config.optimizeDeps,
649
+ esbuildOptions: {
650
+ target: "es2022",
651
+ format: "esm"
652
+ }
653
+ }
654
+ };
655
+ },
656
+ generateBundle: {
657
+ order: "post",
658
+ async handler(_opts, bundle2) {
659
+ cleanupDummy(bundle2);
660
+ }
661
+ },
662
+ sharedDuringBuild: true
663
+ },
664
+ {
665
+ name: "vite-plugin-vercel:setup-envs:vercel_node",
666
+ applyToEnvironment(env) {
667
+ return env.name === "vercel_node";
668
+ },
669
+ configEnvironment(name, config) {
670
+ if (name !== "vercel_node") return;
671
+ return {
672
+ optimizeDeps: {
673
+ ...config.optimizeDeps
674
+ }
675
+ };
676
+ },
677
+ generateBundle: {
678
+ order: "post",
679
+ async handler(_opts, bundle2) {
680
+ cleanupDummy(bundle2);
681
+ this.emitFile({
682
+ type: "asset",
683
+ fileName: "config.json",
684
+ source: JSON.stringify(getConfig(pluginConfig), void 0, 2)
685
+ });
686
+ }
687
+ },
688
+ sharedDuringBuild: true
689
+ }
690
+ ];
645
691
  }
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);
692
+ function createVercelLogger() {
693
+ const logger = createLogger();
694
+ const loggerInfo = logger.info;
695
+ logger.info = (msg, options) => {
696
+ if (options?.environment && (msg.includes("building for production") || msg.includes("building SSR bundle for production"))) {
697
+ return loggerInfo(`${msg} ${options.environment}`, options);
655
698
  }
656
- if (route) {
657
- rewrites.push({
658
- source: `(${route})`,
659
- destination: `${destination}/?__original_path=$1`
660
- });
699
+ if (msg.includes(".vercel/output/_tmp")) {
700
+ const strippedMsg = stripAnsi(msg);
701
+ if (strippedMsg.includes(".vercel/output/_tmp/assets") || strippedMsg.includes(".vercel/output/_tmp/chunks") || strippedMsg.includes(".vercel/output/_tmp/entries"))
702
+ return;
703
+ if (!strippedMsg.includes(".vercel/output/_tmp/functions/") && !strippedMsg.includes(".vercel/output/_tmp/config.json")) {
704
+ return;
705
+ }
706
+ return loggerInfo(msg.replace(".vercel/output/_tmp/", ".vercel/output/"), options);
661
707
  }
662
- }
663
- return rewrites;
708
+ loggerInfo(msg, options);
709
+ };
710
+ return logger;
711
+ }
712
+ function createVercelEnvironmentOptions(overrides) {
713
+ return mergeConfig(
714
+ {
715
+ // The bundle generated by esbuild takes care of this
716
+ // resolve: {
717
+ // noExternal: true,
718
+ // },
719
+ dev: {
720
+ async createEnvironment(name, config) {
721
+ return createRunnableDevEnvironment(name, config);
722
+ }
723
+ },
724
+ build: {
725
+ createEnvironment(name, config) {
726
+ return new BuildEnvironment(name, config);
727
+ },
728
+ outDir: path4.posix.join(outDir, "_tmp"),
729
+ copyPublicDir: false,
730
+ rollupOptions: {
731
+ input: getDummyInput(),
732
+ output: {
733
+ sanitizeFileName: false,
734
+ sourcemap: false
735
+ }
736
+ },
737
+ target: "es2022",
738
+ emptyOutDir: false,
739
+ emitAssets: true
740
+ },
741
+ consumer: "server",
742
+ keepProcessEnv: true
743
+ },
744
+ overrides ?? {}
745
+ );
664
746
  }
665
- async function getIsrConfig(resolvedConfig) {
666
- const isr = resolvedConfig.vercel?.isr ?? {};
667
- if (typeof isr === "function") {
668
- return await isr();
747
+ function getDummyInput() {
748
+ return { [DUMMY2]: `${virtualEntry}:${DUMMY2}` };
749
+ }
750
+ function cleanupDummy(bundle2) {
751
+ const dummy = Object.keys(bundle2).find((key) => key.includes(DUMMY2));
752
+ if (dummy) {
753
+ delete bundle2[dummy];
669
754
  }
670
- return isr;
671
755
  }
672
756
 
673
- // src/index.ts
674
- function vercelPluginCleanup() {
675
- let resolvedConfig;
757
+ // src/plugins/wasm.ts
758
+ function wasmPlugin() {
676
759
  return {
677
- apply: "build",
678
- name: "vite-plugin-vercel:cleanup",
760
+ name: "vite-plugin-vercel:fix-wasm-module",
679
761
  enforce: "pre",
680
- configResolved(config) {
681
- resolvedConfig = config;
682
- },
683
- writeBundle: {
762
+ resolveId: {
684
763
  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);
764
+ async handler(id) {
765
+ if (!id.endsWith(".wasm?module")) return;
766
+ if (this.environment.name !== "vercel_edge") return;
767
+ return {
768
+ id,
769
+ external: true
770
+ };
732
771
  }
733
772
  }
734
773
  };
735
774
  }
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 [];
775
+
776
+ // src/plugins/index.ts
777
+ function vercel(pluginConfig = {}) {
778
+ const additionalConfig = {};
779
+ if (pluginConfig.entries) {
780
+ additionalConfig.entries = pluginConfig.entries;
772
781
  }
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;
782
+ if (pluginConfig.server) {
783
+ additionalConfig.server = pluginConfig.server;
778
784
  }
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];
785
+ return [
786
+ ...installPhoton("vite-plugin-vercel", {
787
+ ...additionalConfig,
788
+ defaultBuildEnv: "vercel_node",
789
+ codeSplitting: {
790
+ target: true
791
+ },
792
+ devServer: {
793
+ env: "vercel_node"
794
+ },
795
+ resolveMiddlewares(env) {
796
+ if (env === "dev") {
797
+ return "vite-plugin-vercel/universal-middleware/dev";
798
+ }
799
+ return "vite-plugin-vercel/universal-middleware";
800
+ }
801
+ }),
802
+ vercelCleanupPlugin(),
803
+ apiPlugin(pluginConfig),
804
+ ...setupEnvs(pluginConfig),
805
+ wasmPlugin(),
806
+ ...loaderPlugin(pluginConfig),
807
+ ...routesPlugins(),
808
+ ...bundlePlugin(pluginConfig)
809
+ ];
799
810
  }
811
+ var plugins_default = vercel;
800
812
  export {
801
- allPlugins as default
813
+ plugins_default as default,
814
+ vercel
802
815
  };