@vercel/backends 0.0.63 → 0.1.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.d.mts +4 -1
- package/dist/index.mjs +365 -5
- package/package.json +5 -2
package/dist/index.d.mts
CHANGED
|
@@ -97,9 +97,12 @@ declare const introspectApp: (args: {
|
|
|
97
97
|
additionalDeps: string[];
|
|
98
98
|
}>;
|
|
99
99
|
//#endregion
|
|
100
|
+
//#region src/diagnostics.d.ts
|
|
101
|
+
declare const diagnostics: _vercel_build_utils0.Diagnostics;
|
|
102
|
+
//#endregion
|
|
100
103
|
//#region src/index.d.ts
|
|
101
104
|
declare const version = 2;
|
|
102
105
|
declare const build: BuildV2;
|
|
103
106
|
declare const prepareCache: PrepareCache;
|
|
104
107
|
//#endregion
|
|
105
|
-
export { type CervelBuildOptions, type CervelServeOptions, type PathOptions, build, build$1 as cervelBuild, serve as cervelServe, findEntrypoint, findEntrypointOrThrow, getBuildSummary, introspectApp, nodeFileTrace, prepareCache, srvxOptions, version };
|
|
108
|
+
export { type CervelBuildOptions, type CervelServeOptions, type PathOptions, build, build$1 as cervelBuild, serve as cervelServe, diagnostics, findEntrypoint, findEntrypointOrThrow, getBuildSummary, introspectApp, nodeFileTrace, prepareCache, srvxOptions, version };
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { builtinModules, createRequire } from "node:module";
|
|
2
|
-
import { delimiter, dirname, join } from "path";
|
|
3
|
-
import { FileBlob, FileFsRef, NodejsLambda, Span, debug, defaultCachePathGlob, download, execCommand, getEnvForPackageManager, getLambdaOptionsFromFunction, getNodeBinPaths, getNodeVersion, glob, isBackendFramework, isBunVersion, isExperimentalBackendsWithoutIntrospectionEnabled, runNpmInstall, runPackageJsonScript, scanParentDirs } from "@vercel/build-utils";
|
|
2
|
+
import path, { delimiter, dirname, join } from "path";
|
|
3
|
+
import { FileBlob, FileFsRef, MANIFEST_VERSION, NodejsLambda, Span, createDiagnostics, debug, defaultCachePathGlob, download, execCommand, getEnvForPackageManager, getLambdaOptionsFromFunction, getNodeBinPaths, getNodeVersion, glob, isBackendFramework, isBunVersion, isExperimentalBackendsWithoutIntrospectionEnabled, runNpmInstall, runPackageJsonScript, scanParentDirs, writeProjectManifest } from "@vercel/build-utils";
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import yaml from "js-yaml";
|
|
6
|
+
import { parseSyml } from "@yarnpkg/parsers";
|
|
4
7
|
import { createWriteStream, existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, unlinkSync, writeFileSync } from "node:fs";
|
|
5
8
|
import { lstat, readFile, rm, stat } from "node:fs/promises";
|
|
6
9
|
import { basename, dirname as dirname$1, extname, isAbsolute, join as join$1, relative, resolve, sep } from "node:path";
|
|
@@ -20,7 +23,7 @@ async function downloadInstallAndBundle(args) {
|
|
|
20
23
|
const { entrypoint, files, workPath, meta, config, repoRootPath } = args;
|
|
21
24
|
await download(files, workPath, meta);
|
|
22
25
|
const entrypointFsDirname = join(workPath, dirname(entrypoint));
|
|
23
|
-
const { cliType, lockfileVersion, packageJsonPackageManager, turboSupportsCorepackHome } = await scanParentDirs(entrypointFsDirname, true, repoRootPath);
|
|
26
|
+
const { cliType, lockfilePath, lockfileVersion, packageJsonPackageManager, turboSupportsCorepackHome } = await scanParentDirs(entrypointFsDirname, true, repoRootPath);
|
|
24
27
|
const spawnEnv = getEnvForPackageManager({
|
|
25
28
|
cliType,
|
|
26
29
|
lockfileVersion,
|
|
@@ -40,7 +43,10 @@ async function downloadInstallAndBundle(args) {
|
|
|
40
43
|
else await runNpmInstall(entrypointFsDirname, [], { env: spawnEnv }, meta, config.projectSettings?.createdAt);
|
|
41
44
|
return {
|
|
42
45
|
entrypointFsDirname,
|
|
43
|
-
spawnEnv
|
|
46
|
+
spawnEnv,
|
|
47
|
+
cliType,
|
|
48
|
+
lockfilePath,
|
|
49
|
+
lockfileVersion
|
|
44
50
|
};
|
|
45
51
|
}
|
|
46
52
|
async function maybeExecBuildCommand(args, { spawnEnv }) {
|
|
@@ -61,6 +67,349 @@ async function maybeExecBuildCommand(args, { spawnEnv }) {
|
|
|
61
67
|
return runPackageJsonScript(args.workPath, ["build"], { env: spawnEnv }, args.config.projectSettings?.createdAt);
|
|
62
68
|
}
|
|
63
69
|
|
|
70
|
+
//#endregion
|
|
71
|
+
//#region src/diagnostics.ts
|
|
72
|
+
function classifySource(resolvedUrl) {
|
|
73
|
+
if (!resolvedUrl) return {};
|
|
74
|
+
if (resolvedUrl.startsWith("file:")) return {
|
|
75
|
+
source: "file",
|
|
76
|
+
sourceUrl: resolvedUrl.slice(5)
|
|
77
|
+
};
|
|
78
|
+
if (resolvedUrl.startsWith("git+") || resolvedUrl.startsWith("git://")) return {
|
|
79
|
+
source: "git",
|
|
80
|
+
sourceUrl: resolvedUrl.replace(/^git\+/, "")
|
|
81
|
+
};
|
|
82
|
+
try {
|
|
83
|
+
return {
|
|
84
|
+
source: "registry",
|
|
85
|
+
sourceUrl: new URL(resolvedUrl).origin
|
|
86
|
+
};
|
|
87
|
+
} catch {
|
|
88
|
+
return {};
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function npmEntryScopes(entry) {
|
|
92
|
+
const scopes = [];
|
|
93
|
+
if (entry.dev) scopes.push("dev");
|
|
94
|
+
if (entry.peer) scopes.push("peer");
|
|
95
|
+
if (entry.optional) scopes.push("optional");
|
|
96
|
+
if (scopes.length === 0) scopes.push("prod");
|
|
97
|
+
return scopes;
|
|
98
|
+
}
|
|
99
|
+
function parseNpmLock(content, lockfileVersion) {
|
|
100
|
+
const lockMap = /* @__PURE__ */ new Map();
|
|
101
|
+
const parsed = JSON.parse(content);
|
|
102
|
+
if ((lockfileVersion ?? parsed.lockfileVersion ?? 1) >= 2) {
|
|
103
|
+
const packages = parsed.packages;
|
|
104
|
+
if (!packages) return lockMap;
|
|
105
|
+
for (const [key, entry] of Object.entries(packages)) {
|
|
106
|
+
if (key === "") continue;
|
|
107
|
+
if (!key.startsWith("node_modules/")) continue;
|
|
108
|
+
if (entry.link === true) continue;
|
|
109
|
+
const rest = key.slice(13);
|
|
110
|
+
const isScoped = rest.startsWith("@");
|
|
111
|
+
const slashCount = (rest.match(/\//g) ?? []).length;
|
|
112
|
+
if (isScoped ? slashCount !== 1 : slashCount !== 0) continue;
|
|
113
|
+
const resolved = entry.resolved;
|
|
114
|
+
if (resolved?.startsWith("file:")) continue;
|
|
115
|
+
const version$1 = entry.version ?? "";
|
|
116
|
+
const existing = lockMap.get(rest);
|
|
117
|
+
if (existing && !isHigherVersion(version$1, existing.resolved)) continue;
|
|
118
|
+
const { source, sourceUrl } = classifySource(resolved);
|
|
119
|
+
const lockEntry = {
|
|
120
|
+
resolved: version$1,
|
|
121
|
+
scopes: npmEntryScopes(entry)
|
|
122
|
+
};
|
|
123
|
+
if (source) lockEntry.source = source;
|
|
124
|
+
if (sourceUrl) lockEntry.sourceUrl = sourceUrl;
|
|
125
|
+
lockMap.set(rest, lockEntry);
|
|
126
|
+
}
|
|
127
|
+
} else {
|
|
128
|
+
const dependencies = parsed.dependencies;
|
|
129
|
+
if (!dependencies) return lockMap;
|
|
130
|
+
const walk = (deps) => {
|
|
131
|
+
for (const [name, entry] of Object.entries(deps)) {
|
|
132
|
+
const resolved = entry.resolved;
|
|
133
|
+
if (!resolved?.startsWith("file:")) {
|
|
134
|
+
const version$1 = entry.version ?? "";
|
|
135
|
+
const existing = lockMap.get(name);
|
|
136
|
+
if (!existing || isHigherVersion(version$1, existing.resolved)) {
|
|
137
|
+
const { source, sourceUrl } = classifySource(resolved);
|
|
138
|
+
const lockEntry = {
|
|
139
|
+
resolved: version$1,
|
|
140
|
+
scopes: npmEntryScopes(entry)
|
|
141
|
+
};
|
|
142
|
+
if (source) lockEntry.source = source;
|
|
143
|
+
if (sourceUrl) lockEntry.sourceUrl = sourceUrl;
|
|
144
|
+
lockMap.set(name, lockEntry);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const nested = entry.dependencies;
|
|
148
|
+
if (nested) walk(nested);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
walk(dependencies);
|
|
152
|
+
}
|
|
153
|
+
return lockMap;
|
|
154
|
+
}
|
|
155
|
+
function isHigherVersion(a, b) {
|
|
156
|
+
const seg = (v) => v.split(/[.\-+]/).map((s) => parseInt(s, 10) || 0);
|
|
157
|
+
const pa = seg(a);
|
|
158
|
+
const pb = seg(b);
|
|
159
|
+
for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
|
|
160
|
+
if ((pa[i] ?? 0) > (pb[i] ?? 0)) return true;
|
|
161
|
+
if ((pa[i] ?? 0) < (pb[i] ?? 0)) return false;
|
|
162
|
+
}
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
165
|
+
function extractPackageName(spec) {
|
|
166
|
+
const s = spec.replace(/\(.*\)$/, "");
|
|
167
|
+
if (s.startsWith("@")) {
|
|
168
|
+
const i$1 = s.indexOf("@", 1);
|
|
169
|
+
return i$1 === -1 ? null : s.slice(0, i$1);
|
|
170
|
+
}
|
|
171
|
+
const i = s.lastIndexOf("@");
|
|
172
|
+
return i <= 0 ? null : s.slice(0, i);
|
|
173
|
+
}
|
|
174
|
+
function parsePnpmV9Key(key) {
|
|
175
|
+
const name = extractPackageName(key);
|
|
176
|
+
if (!name) return null;
|
|
177
|
+
return {
|
|
178
|
+
name,
|
|
179
|
+
version: key.replace(/\(.*\)$/, "").slice(name.length + 1)
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
function parsePnpmV5Key(key) {
|
|
183
|
+
if (!key.startsWith("/")) return null;
|
|
184
|
+
const rest = key.slice(1);
|
|
185
|
+
if (rest.startsWith("@")) {
|
|
186
|
+
const firstSlash = rest.indexOf("/");
|
|
187
|
+
if (firstSlash === -1) return null;
|
|
188
|
+
const secondSlash = rest.indexOf("/", firstSlash + 1);
|
|
189
|
+
if (secondSlash === -1) return null;
|
|
190
|
+
return {
|
|
191
|
+
name: rest.slice(0, secondSlash),
|
|
192
|
+
version: rest.slice(secondSlash + 1).split("_")[0]
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
const slashIndex = rest.indexOf("/");
|
|
196
|
+
if (slashIndex === -1) return null;
|
|
197
|
+
return {
|
|
198
|
+
name: rest.slice(0, slashIndex),
|
|
199
|
+
version: rest.slice(slashIndex + 1).split("_")[0]
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
function parsePnpmV6Key(key) {
|
|
203
|
+
if (!key.startsWith("/")) return null;
|
|
204
|
+
const rest = key.slice(1);
|
|
205
|
+
let atIdx;
|
|
206
|
+
if (rest.startsWith("@")) atIdx = rest.indexOf("@", 1);
|
|
207
|
+
else atIdx = rest.indexOf("@");
|
|
208
|
+
if (atIdx === -1) return null;
|
|
209
|
+
return {
|
|
210
|
+
name: rest.slice(0, atIdx),
|
|
211
|
+
version: rest.slice(atIdx + 1).split("_")[0].replace(/\(.*\)$/, "")
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
function classifyPnpmResolution(resolution) {
|
|
215
|
+
if (!resolution) return {};
|
|
216
|
+
if (resolution.type === "directory" || resolution.directory) return { local: true };
|
|
217
|
+
if (typeof resolution.tarball === "string") return classifySource(resolution.tarball);
|
|
218
|
+
if (resolution.type === "git" || typeof resolution.repo === "string") return {
|
|
219
|
+
source: "git",
|
|
220
|
+
sourceUrl: resolution.repo ?? void 0
|
|
221
|
+
};
|
|
222
|
+
return {};
|
|
223
|
+
}
|
|
224
|
+
function parsePnpmLock(content, lockfileVersion) {
|
|
225
|
+
const lockMap = /* @__PURE__ */ new Map();
|
|
226
|
+
const docs = [];
|
|
227
|
+
yaml.safeLoadAll(content, (doc) => docs.push(doc));
|
|
228
|
+
const parsedYaml = docs[0];
|
|
229
|
+
if (!parsedYaml) return lockMap;
|
|
230
|
+
const lv = lockfileVersion ?? Number(parsedYaml.lockfileVersion ?? "0");
|
|
231
|
+
const packages = parsedYaml.packages;
|
|
232
|
+
if (!packages) return lockMap;
|
|
233
|
+
const parseKey = lv >= 9 ? parsePnpmV9Key : lv >= 6 ? parsePnpmV6Key : parsePnpmV5Key;
|
|
234
|
+
for (const [key, entry] of Object.entries(packages)) {
|
|
235
|
+
const keyParsed = parseKey(key);
|
|
236
|
+
if (!keyParsed) continue;
|
|
237
|
+
const { name, version: version$1 } = keyParsed;
|
|
238
|
+
const resolution = entry.resolution;
|
|
239
|
+
const { local, source, sourceUrl } = classifyPnpmResolution(resolution);
|
|
240
|
+
if (local) continue;
|
|
241
|
+
const existing = lockMap.get(name);
|
|
242
|
+
if (existing && !isHigherVersion(version$1, existing.resolved)) continue;
|
|
243
|
+
const lockEntry = {
|
|
244
|
+
resolved: version$1,
|
|
245
|
+
scopes: ["prod"]
|
|
246
|
+
};
|
|
247
|
+
if (source) lockEntry.source = source;
|
|
248
|
+
if (sourceUrl) lockEntry.sourceUrl = sourceUrl;
|
|
249
|
+
lockMap.set(name, lockEntry);
|
|
250
|
+
}
|
|
251
|
+
return lockMap;
|
|
252
|
+
}
|
|
253
|
+
function parseYarnLock(content, lockfileVersion) {
|
|
254
|
+
const lockMap = /* @__PURE__ */ new Map();
|
|
255
|
+
const isBerry = (lockfileVersion ?? 1) >= 2;
|
|
256
|
+
const parsed = parseSyml(content);
|
|
257
|
+
for (const [key, entry] of Object.entries(parsed)) {
|
|
258
|
+
if (key === "__metadata" || !entry) continue;
|
|
259
|
+
if (isBerry && entry.linkType === "soft") continue;
|
|
260
|
+
const version$1 = entry.version;
|
|
261
|
+
if (!version$1) continue;
|
|
262
|
+
let source;
|
|
263
|
+
let sourceUrl;
|
|
264
|
+
if (!isBerry && entry.resolved) {
|
|
265
|
+
if (entry.resolved.startsWith("file:")) continue;
|
|
266
|
+
const classified = classifySource(entry.resolved);
|
|
267
|
+
source = classified.source;
|
|
268
|
+
sourceUrl = classified.sourceUrl;
|
|
269
|
+
}
|
|
270
|
+
const specifiers = key.split(",").map((s) => s.trim().replace(/^"|"$/g, ""));
|
|
271
|
+
let name = null;
|
|
272
|
+
for (const spec of specifiers) {
|
|
273
|
+
name = extractPackageName(spec);
|
|
274
|
+
if (name) break;
|
|
275
|
+
}
|
|
276
|
+
if (!name) continue;
|
|
277
|
+
const existing = lockMap.get(name);
|
|
278
|
+
if (existing && !isHigherVersion(version$1, existing.resolved)) continue;
|
|
279
|
+
const lockEntry = {
|
|
280
|
+
resolved: version$1,
|
|
281
|
+
scopes: ["prod"]
|
|
282
|
+
};
|
|
283
|
+
if (source) lockEntry.source = source;
|
|
284
|
+
if (sourceUrl) lockEntry.sourceUrl = sourceUrl;
|
|
285
|
+
lockMap.set(name, lockEntry);
|
|
286
|
+
}
|
|
287
|
+
return lockMap;
|
|
288
|
+
}
|
|
289
|
+
function parseBunLock(content) {
|
|
290
|
+
const lockMap = /* @__PURE__ */ new Map();
|
|
291
|
+
const json = content.replace(/,(\s*[}\]])/g, "$1");
|
|
292
|
+
const packages = JSON.parse(json).packages;
|
|
293
|
+
if (!packages) return lockMap;
|
|
294
|
+
for (const [name, value] of Object.entries(packages)) {
|
|
295
|
+
if (!Array.isArray(value)) continue;
|
|
296
|
+
const ref = value[0];
|
|
297
|
+
if (!ref || typeof ref !== "string") continue;
|
|
298
|
+
const pkgName = extractPackageName(ref);
|
|
299
|
+
if (!pkgName) continue;
|
|
300
|
+
const version$1 = ref.slice(pkgName.length + 1);
|
|
301
|
+
if (!version$1) continue;
|
|
302
|
+
if (version$1.startsWith("file:") || version$1.startsWith("workspace:")) continue;
|
|
303
|
+
const existingBun = lockMap.get(name);
|
|
304
|
+
if (existingBun && !isHigherVersion(version$1, existingBun.resolved)) continue;
|
|
305
|
+
lockMap.set(name, {
|
|
306
|
+
resolved: version$1,
|
|
307
|
+
scopes: ["prod"]
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
return lockMap;
|
|
311
|
+
}
|
|
312
|
+
async function parseLockfile(cliType, lockfilePath, lockfileVersion) {
|
|
313
|
+
if (cliType === "bun" && lockfileVersion === 0) return /* @__PURE__ */ new Map();
|
|
314
|
+
if (cliType === "vlt") return /* @__PURE__ */ new Map();
|
|
315
|
+
const content = await fs.promises.readFile(lockfilePath, "utf-8");
|
|
316
|
+
switch (cliType) {
|
|
317
|
+
case "npm": return parseNpmLock(content, lockfileVersion);
|
|
318
|
+
case "pnpm": return parsePnpmLock(content, lockfileVersion);
|
|
319
|
+
case "yarn": return parseYarnLock(content, lockfileVersion);
|
|
320
|
+
case "bun": return parseBunLock(content);
|
|
321
|
+
default: return /* @__PURE__ */ new Map();
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
async function readPackageJson(startDir) {
|
|
325
|
+
let current = startDir;
|
|
326
|
+
for (;;) try {
|
|
327
|
+
const content = await fs.promises.readFile(path.join(current, "package.json"), "utf-8");
|
|
328
|
+
return JSON.parse(content);
|
|
329
|
+
} catch {
|
|
330
|
+
const parent = path.dirname(current);
|
|
331
|
+
if (parent === current) return null;
|
|
332
|
+
current = parent;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
function buildDirectMaps(pkgJson) {
|
|
336
|
+
const directScopes = /* @__PURE__ */ new Map();
|
|
337
|
+
const directRequested = /* @__PURE__ */ new Map();
|
|
338
|
+
const add = (deps, scope) => {
|
|
339
|
+
if (!deps || typeof deps !== "object") return;
|
|
340
|
+
for (const [name, specifier] of Object.entries(deps)) {
|
|
341
|
+
if (!directScopes.has(name)) directScopes.set(name, /* @__PURE__ */ new Set());
|
|
342
|
+
directScopes.get(name).add(scope);
|
|
343
|
+
if (!directRequested.has(name)) directRequested.set(name, specifier);
|
|
344
|
+
}
|
|
345
|
+
};
|
|
346
|
+
add(pkgJson.dependencies, "prod");
|
|
347
|
+
add(pkgJson.devDependencies, "dev");
|
|
348
|
+
add(pkgJson.peerDependencies, "peer");
|
|
349
|
+
add(pkgJson.optionalDependencies, "optional");
|
|
350
|
+
return {
|
|
351
|
+
directScopes,
|
|
352
|
+
directRequested
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
async function generateProjectManifest({ workPath, nodeVersion, cliType, lockfilePath, lockfileVersion }) {
|
|
356
|
+
try {
|
|
357
|
+
const pkgJson = await readPackageJson(workPath);
|
|
358
|
+
if (!pkgJson) return;
|
|
359
|
+
const { directScopes, directRequested } = buildDirectMaps(pkgJson);
|
|
360
|
+
const lockMap = lockfilePath ? await parseLockfile(cliType, lockfilePath, lockfileVersion) : /* @__PURE__ */ new Map();
|
|
361
|
+
const directDeps = [];
|
|
362
|
+
const transitiveDeps = [];
|
|
363
|
+
for (const [name, scopes] of directScopes) {
|
|
364
|
+
const lock = lockMap.get(name);
|
|
365
|
+
const dep = {
|
|
366
|
+
name,
|
|
367
|
+
type: "direct",
|
|
368
|
+
scopes: [...scopes].sort(),
|
|
369
|
+
requested: directRequested.get(name),
|
|
370
|
+
resolved: lock?.resolved ?? ""
|
|
371
|
+
};
|
|
372
|
+
if (lock?.source) dep.source = lock.source;
|
|
373
|
+
if (lock?.sourceUrl) dep.sourceUrl = lock.sourceUrl;
|
|
374
|
+
directDeps.push(dep);
|
|
375
|
+
}
|
|
376
|
+
for (const [name, lock] of lockMap) {
|
|
377
|
+
if (directScopes.has(name)) continue;
|
|
378
|
+
const dep = {
|
|
379
|
+
name,
|
|
380
|
+
type: "transitive",
|
|
381
|
+
scopes: lock.scopes,
|
|
382
|
+
resolved: lock.resolved
|
|
383
|
+
};
|
|
384
|
+
if (lock.source) dep.source = lock.source;
|
|
385
|
+
if (lock.sourceUrl) dep.sourceUrl = lock.sourceUrl;
|
|
386
|
+
transitiveDeps.push(dep);
|
|
387
|
+
}
|
|
388
|
+
const runtimeVersion = { resolved: String(nodeVersion.major) };
|
|
389
|
+
const enginesNode = pkgJson.engines?.node;
|
|
390
|
+
if (enginesNode) {
|
|
391
|
+
runtimeVersion.requested = enginesNode;
|
|
392
|
+
runtimeVersion.requestedSource = "package.json";
|
|
393
|
+
} else for (const filename of [".node-version", ".nvmrc"]) try {
|
|
394
|
+
const trimmed = (await fs.promises.readFile(path.join(workPath, filename), "utf-8")).trim();
|
|
395
|
+
if (trimmed) {
|
|
396
|
+
runtimeVersion.requested = trimmed;
|
|
397
|
+
runtimeVersion.requestedSource = filename;
|
|
398
|
+
break;
|
|
399
|
+
}
|
|
400
|
+
} catch {}
|
|
401
|
+
await writeProjectManifest({
|
|
402
|
+
version: MANIFEST_VERSION,
|
|
403
|
+
runtime: "node",
|
|
404
|
+
runtimeVersion,
|
|
405
|
+
dependencies: [...directDeps.sort((a, b) => a.name.localeCompare(b.name)), ...transitiveDeps.sort((a, b) => a.name.localeCompare(b.name))]
|
|
406
|
+
}, workPath, "node");
|
|
407
|
+
} catch (err) {
|
|
408
|
+
debug(`generateProjectManifest: ${err instanceof Error ? err.message : String(err)}`);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
const diagnostics = createDiagnostics("node");
|
|
412
|
+
|
|
64
413
|
//#endregion
|
|
65
414
|
//#region src/cervel/plugin.ts
|
|
66
415
|
const CJS_SHIM_PREFIX$1 = "\0cjs-shim:";
|
|
@@ -1607,6 +1956,17 @@ const build = async (args) => {
|
|
|
1607
1956
|
conditions: isBun ? ["bun"] : void 0,
|
|
1608
1957
|
span: buildSpan
|
|
1609
1958
|
});
|
|
1959
|
+
try {
|
|
1960
|
+
await generateProjectManifest({
|
|
1961
|
+
workPath: args.workPath,
|
|
1962
|
+
nodeVersion,
|
|
1963
|
+
cliType: downloadResult.cliType,
|
|
1964
|
+
lockfilePath: downloadResult.lockfilePath,
|
|
1965
|
+
lockfileVersion: downloadResult.lockfileVersion
|
|
1966
|
+
});
|
|
1967
|
+
} catch (err) {
|
|
1968
|
+
debug(`Failed to write node manifest: ${err instanceof Error ? err.message : String(err)}`);
|
|
1969
|
+
}
|
|
1610
1970
|
const baseDir = args.repoRootPath || args.workPath;
|
|
1611
1971
|
const includeResults = await Promise.all(normalizeArray(args.config.includeFiles).map((pattern) => glob(pattern, baseDir)));
|
|
1612
1972
|
for (const matched of includeResults) for (const [relPath, entry] of Object.entries(matched)) files[relPath] = entry;
|
|
@@ -1709,4 +2069,4 @@ const escapeForRegex = (value) => value.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&");
|
|
|
1709
2069
|
const toRegexSource = (value) => escapeForRegex(value).replaceAll("/", "\\/");
|
|
1710
2070
|
|
|
1711
2071
|
//#endregion
|
|
1712
|
-
export { build, build$1 as cervelBuild, serve as cervelServe, findEntrypoint, findEntrypointOrThrow, getBuildSummary, introspectApp, nodeFileTrace, prepareCache, srvxOptions, version };
|
|
2072
|
+
export { build, build$1 as cervelBuild, serve as cervelServe, diagnostics, findEntrypoint, findEntrypointOrThrow, getBuildSummary, introspectApp, nodeFileTrace, prepareCache, srvxOptions, version };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vercel/backends",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"main": "./dist/index.mjs",
|
|
6
6
|
"homepage": "https://vercel.com/docs",
|
|
@@ -24,6 +24,8 @@
|
|
|
24
24
|
"dist"
|
|
25
25
|
],
|
|
26
26
|
"dependencies": {
|
|
27
|
+
"@yarnpkg/parsers": "^3.0.0",
|
|
28
|
+
"js-yaml": "^3.13.1",
|
|
27
29
|
"@vercel/nft": "1.5.0",
|
|
28
30
|
"execa": "3.2.0",
|
|
29
31
|
"fs-extra": "11.1.0",
|
|
@@ -34,13 +36,14 @@
|
|
|
34
36
|
"srvx": "0.8.9",
|
|
35
37
|
"tsx": "4.21.0",
|
|
36
38
|
"zod": "3.22.4",
|
|
37
|
-
"@vercel/build-utils": "13.
|
|
39
|
+
"@vercel/build-utils": "13.18.0"
|
|
38
40
|
},
|
|
39
41
|
"peerDependencies": {
|
|
40
42
|
"typescript": "^4.0.0 || ^5.0.0"
|
|
41
43
|
},
|
|
42
44
|
"devDependencies": {
|
|
43
45
|
"@types/express": "5.0.3",
|
|
46
|
+
"@types/js-yaml": "3.12.1",
|
|
44
47
|
"@types/fs-extra": "11",
|
|
45
48
|
"@types/jest": "27.5.1",
|
|
46
49
|
"@types/node": "20.11.0",
|