@vercel/backends 0.4.1 → 0.6.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.mjs +10 -355
- package/package.json +2 -4
package/dist/index.mjs
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { builtinModules, createRequire } from "node:module";
|
|
2
2
|
import { createWriteStream, existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, unlinkSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { basename, dirname, extname, isAbsolute, join, posix, relative, resolve, sep } from "node:path";
|
|
4
|
-
import
|
|
5
|
-
import { FileBlob, FileFsRef,
|
|
6
|
-
import fs from "fs";
|
|
7
|
-
import yaml from "js-yaml";
|
|
8
|
-
import { parseSyml } from "@yarnpkg/parsers";
|
|
4
|
+
import { delimiter, dirname as dirname$1, join as join$1 } from "path";
|
|
5
|
+
import { FileBlob, FileFsRef, NodejsLambda, Span, createDiagnostics, debug, defaultCachePathGlob, download, execCommand, generateProjectManifest, getEnvForPackageManager, getInternalServiceCronPath, getLambdaOptionsFromFunction, getNodeBinPaths, getNodeVersion, getReportedServiceType, glob, isBackendFramework, isBunVersion, isExperimentalBackendsWithoutIntrospectionEnabled, isScheduleTriggeredService, runNpmInstall, runPackageJsonScript, scanParentDirs } from "@vercel/build-utils";
|
|
9
6
|
import { lstat, readFile, rm, stat } from "node:fs/promises";
|
|
10
7
|
import { build as build$2 } from "rolldown";
|
|
11
8
|
import { exports } from "resolve.exports";
|
|
@@ -70,347 +67,6 @@ async function maybeExecBuildCommand(args, { spawnEnv }) {
|
|
|
70
67
|
|
|
71
68
|
//#endregion
|
|
72
69
|
//#region src/diagnostics.ts
|
|
73
|
-
function classifySource(resolvedUrl) {
|
|
74
|
-
if (!resolvedUrl) return {};
|
|
75
|
-
if (resolvedUrl.startsWith("file:")) return {
|
|
76
|
-
source: "file",
|
|
77
|
-
sourceUrl: resolvedUrl.slice(5)
|
|
78
|
-
};
|
|
79
|
-
if (resolvedUrl.startsWith("git+") || resolvedUrl.startsWith("git://")) return {
|
|
80
|
-
source: "git",
|
|
81
|
-
sourceUrl: resolvedUrl.replace(/^git\+/, "")
|
|
82
|
-
};
|
|
83
|
-
try {
|
|
84
|
-
return {
|
|
85
|
-
source: "registry",
|
|
86
|
-
sourceUrl: new URL(resolvedUrl).origin
|
|
87
|
-
};
|
|
88
|
-
} catch {
|
|
89
|
-
return {};
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
function npmEntryScopes(entry) {
|
|
93
|
-
const scopes = [];
|
|
94
|
-
if (entry.dev) scopes.push("dev");
|
|
95
|
-
if (entry.peer) scopes.push("peer");
|
|
96
|
-
if (entry.optional) scopes.push("optional");
|
|
97
|
-
if (scopes.length === 0) scopes.push("prod");
|
|
98
|
-
return scopes;
|
|
99
|
-
}
|
|
100
|
-
function parseNpmLock(content, lockfileVersion) {
|
|
101
|
-
const lockMap = /* @__PURE__ */ new Map();
|
|
102
|
-
const parsed = JSON.parse(content);
|
|
103
|
-
if ((lockfileVersion ?? parsed.lockfileVersion ?? 1) >= 2) {
|
|
104
|
-
const packages = parsed.packages;
|
|
105
|
-
if (!packages) return lockMap;
|
|
106
|
-
for (const [key, entry] of Object.entries(packages)) {
|
|
107
|
-
if (key === "") continue;
|
|
108
|
-
if (!key.startsWith("node_modules/")) continue;
|
|
109
|
-
if (entry.link === true) continue;
|
|
110
|
-
const rest = key.slice(13);
|
|
111
|
-
const isScoped = rest.startsWith("@");
|
|
112
|
-
const slashCount = (rest.match(/\//g) ?? []).length;
|
|
113
|
-
if (isScoped ? slashCount !== 1 : slashCount !== 0) continue;
|
|
114
|
-
const resolved = entry.resolved;
|
|
115
|
-
if (resolved?.startsWith("file:")) continue;
|
|
116
|
-
const version$1 = entry.version ?? "";
|
|
117
|
-
const existing = lockMap.get(rest);
|
|
118
|
-
if (existing && !isHigherVersion(version$1, existing.resolved)) continue;
|
|
119
|
-
const { source, sourceUrl } = classifySource(resolved);
|
|
120
|
-
const lockEntry = {
|
|
121
|
-
resolved: version$1,
|
|
122
|
-
scopes: npmEntryScopes(entry)
|
|
123
|
-
};
|
|
124
|
-
if (source) lockEntry.source = source;
|
|
125
|
-
if (sourceUrl) lockEntry.sourceUrl = sourceUrl;
|
|
126
|
-
lockMap.set(rest, lockEntry);
|
|
127
|
-
}
|
|
128
|
-
} else {
|
|
129
|
-
const dependencies = parsed.dependencies;
|
|
130
|
-
if (!dependencies) return lockMap;
|
|
131
|
-
const walk = (deps) => {
|
|
132
|
-
for (const [name, entry] of Object.entries(deps)) {
|
|
133
|
-
const resolved = entry.resolved;
|
|
134
|
-
if (!resolved?.startsWith("file:")) {
|
|
135
|
-
const version$1 = entry.version ?? "";
|
|
136
|
-
const existing = lockMap.get(name);
|
|
137
|
-
if (!existing || isHigherVersion(version$1, existing.resolved)) {
|
|
138
|
-
const { source, sourceUrl } = classifySource(resolved);
|
|
139
|
-
const lockEntry = {
|
|
140
|
-
resolved: version$1,
|
|
141
|
-
scopes: npmEntryScopes(entry)
|
|
142
|
-
};
|
|
143
|
-
if (source) lockEntry.source = source;
|
|
144
|
-
if (sourceUrl) lockEntry.sourceUrl = sourceUrl;
|
|
145
|
-
lockMap.set(name, lockEntry);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
const nested = entry.dependencies;
|
|
149
|
-
if (nested) walk(nested);
|
|
150
|
-
}
|
|
151
|
-
};
|
|
152
|
-
walk(dependencies);
|
|
153
|
-
}
|
|
154
|
-
return lockMap;
|
|
155
|
-
}
|
|
156
|
-
function isHigherVersion(a, b) {
|
|
157
|
-
const seg = (v) => v.split(/[.\-+]/).map((s) => parseInt(s, 10) || 0);
|
|
158
|
-
const pa = seg(a);
|
|
159
|
-
const pb = seg(b);
|
|
160
|
-
for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
|
|
161
|
-
if ((pa[i] ?? 0) > (pb[i] ?? 0)) return true;
|
|
162
|
-
if ((pa[i] ?? 0) < (pb[i] ?? 0)) return false;
|
|
163
|
-
}
|
|
164
|
-
return false;
|
|
165
|
-
}
|
|
166
|
-
function extractPackageName(spec) {
|
|
167
|
-
const s = spec.replace(/\(.*\)$/, "");
|
|
168
|
-
if (s.startsWith("@")) {
|
|
169
|
-
const i$1 = s.indexOf("@", 1);
|
|
170
|
-
return i$1 === -1 ? null : s.slice(0, i$1);
|
|
171
|
-
}
|
|
172
|
-
const i = s.lastIndexOf("@");
|
|
173
|
-
return i <= 0 ? null : s.slice(0, i);
|
|
174
|
-
}
|
|
175
|
-
function parsePnpmV9Key(key) {
|
|
176
|
-
const name = extractPackageName(key);
|
|
177
|
-
if (!name) return null;
|
|
178
|
-
return {
|
|
179
|
-
name,
|
|
180
|
-
version: key.replace(/\(.*\)$/, "").slice(name.length + 1)
|
|
181
|
-
};
|
|
182
|
-
}
|
|
183
|
-
function parsePnpmV5Key(key) {
|
|
184
|
-
if (!key.startsWith("/")) return null;
|
|
185
|
-
const rest = key.slice(1);
|
|
186
|
-
if (rest.startsWith("@")) {
|
|
187
|
-
const firstSlash = rest.indexOf("/");
|
|
188
|
-
if (firstSlash === -1) return null;
|
|
189
|
-
const secondSlash = rest.indexOf("/", firstSlash + 1);
|
|
190
|
-
if (secondSlash === -1) return null;
|
|
191
|
-
return {
|
|
192
|
-
name: rest.slice(0, secondSlash),
|
|
193
|
-
version: rest.slice(secondSlash + 1).split("_")[0]
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
const slashIndex = rest.indexOf("/");
|
|
197
|
-
if (slashIndex === -1) return null;
|
|
198
|
-
return {
|
|
199
|
-
name: rest.slice(0, slashIndex),
|
|
200
|
-
version: rest.slice(slashIndex + 1).split("_")[0]
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
function parsePnpmV6Key(key) {
|
|
204
|
-
if (!key.startsWith("/")) return null;
|
|
205
|
-
const rest = key.slice(1);
|
|
206
|
-
let atIdx;
|
|
207
|
-
if (rest.startsWith("@")) atIdx = rest.indexOf("@", 1);
|
|
208
|
-
else atIdx = rest.indexOf("@");
|
|
209
|
-
if (atIdx === -1) return null;
|
|
210
|
-
return {
|
|
211
|
-
name: rest.slice(0, atIdx),
|
|
212
|
-
version: rest.slice(atIdx + 1).split("_")[0].replace(/\(.*\)$/, "")
|
|
213
|
-
};
|
|
214
|
-
}
|
|
215
|
-
function classifyPnpmResolution(resolution) {
|
|
216
|
-
if (!resolution) return {};
|
|
217
|
-
if (resolution.type === "directory" || resolution.directory) return { local: true };
|
|
218
|
-
if (typeof resolution.tarball === "string") return classifySource(resolution.tarball);
|
|
219
|
-
if (resolution.type === "git" || typeof resolution.repo === "string") return {
|
|
220
|
-
source: "git",
|
|
221
|
-
sourceUrl: resolution.repo ?? void 0
|
|
222
|
-
};
|
|
223
|
-
return {};
|
|
224
|
-
}
|
|
225
|
-
function parsePnpmLock(content, lockfileVersion) {
|
|
226
|
-
const lockMap = /* @__PURE__ */ new Map();
|
|
227
|
-
const docs = [];
|
|
228
|
-
yaml.safeLoadAll(content, (doc) => docs.push(doc));
|
|
229
|
-
const parsedYaml = docs[0];
|
|
230
|
-
if (!parsedYaml) return lockMap;
|
|
231
|
-
const lv = lockfileVersion ?? Number(parsedYaml.lockfileVersion ?? "0");
|
|
232
|
-
const packages = parsedYaml.packages;
|
|
233
|
-
if (!packages) return lockMap;
|
|
234
|
-
const parseKey = lv >= 9 ? parsePnpmV9Key : lv >= 6 ? parsePnpmV6Key : parsePnpmV5Key;
|
|
235
|
-
for (const [key, entry] of Object.entries(packages)) {
|
|
236
|
-
const keyParsed = parseKey(key);
|
|
237
|
-
if (!keyParsed) continue;
|
|
238
|
-
const { name, version: version$1 } = keyParsed;
|
|
239
|
-
const resolution = entry.resolution;
|
|
240
|
-
const { local, source, sourceUrl } = classifyPnpmResolution(resolution);
|
|
241
|
-
if (local) continue;
|
|
242
|
-
const existing = lockMap.get(name);
|
|
243
|
-
if (existing && !isHigherVersion(version$1, existing.resolved)) continue;
|
|
244
|
-
const lockEntry = {
|
|
245
|
-
resolved: version$1,
|
|
246
|
-
scopes: ["prod"]
|
|
247
|
-
};
|
|
248
|
-
if (source) lockEntry.source = source;
|
|
249
|
-
if (sourceUrl) lockEntry.sourceUrl = sourceUrl;
|
|
250
|
-
lockMap.set(name, lockEntry);
|
|
251
|
-
}
|
|
252
|
-
return lockMap;
|
|
253
|
-
}
|
|
254
|
-
function parseYarnLock(content, lockfileVersion) {
|
|
255
|
-
const lockMap = /* @__PURE__ */ new Map();
|
|
256
|
-
const isBerry = (lockfileVersion ?? 1) >= 2;
|
|
257
|
-
const parsed = parseSyml(content);
|
|
258
|
-
for (const [key, entry] of Object.entries(parsed)) {
|
|
259
|
-
if (key === "__metadata" || !entry) continue;
|
|
260
|
-
if (isBerry && entry.linkType === "soft") continue;
|
|
261
|
-
const version$1 = entry.version;
|
|
262
|
-
if (!version$1) continue;
|
|
263
|
-
let source;
|
|
264
|
-
let sourceUrl;
|
|
265
|
-
if (!isBerry && entry.resolved) {
|
|
266
|
-
if (entry.resolved.startsWith("file:")) continue;
|
|
267
|
-
const classified = classifySource(entry.resolved);
|
|
268
|
-
source = classified.source;
|
|
269
|
-
sourceUrl = classified.sourceUrl;
|
|
270
|
-
}
|
|
271
|
-
const specifiers = key.split(",").map((s) => s.trim().replace(/^"|"$/g, ""));
|
|
272
|
-
let name = null;
|
|
273
|
-
for (const spec of specifiers) {
|
|
274
|
-
name = extractPackageName(spec);
|
|
275
|
-
if (name) break;
|
|
276
|
-
}
|
|
277
|
-
if (!name) continue;
|
|
278
|
-
const existing = lockMap.get(name);
|
|
279
|
-
if (existing && !isHigherVersion(version$1, existing.resolved)) continue;
|
|
280
|
-
const lockEntry = {
|
|
281
|
-
resolved: version$1,
|
|
282
|
-
scopes: ["prod"]
|
|
283
|
-
};
|
|
284
|
-
if (source) lockEntry.source = source;
|
|
285
|
-
if (sourceUrl) lockEntry.sourceUrl = sourceUrl;
|
|
286
|
-
lockMap.set(name, lockEntry);
|
|
287
|
-
}
|
|
288
|
-
return lockMap;
|
|
289
|
-
}
|
|
290
|
-
function parseBunLock(content) {
|
|
291
|
-
const lockMap = /* @__PURE__ */ new Map();
|
|
292
|
-
const json = content.replace(/,(\s*[}\]])/g, "$1");
|
|
293
|
-
const packages = JSON.parse(json).packages;
|
|
294
|
-
if (!packages) return lockMap;
|
|
295
|
-
for (const [name, value] of Object.entries(packages)) {
|
|
296
|
-
if (!Array.isArray(value)) continue;
|
|
297
|
-
const ref = value[0];
|
|
298
|
-
if (!ref || typeof ref !== "string") continue;
|
|
299
|
-
const pkgName = extractPackageName(ref);
|
|
300
|
-
if (!pkgName) continue;
|
|
301
|
-
const version$1 = ref.slice(pkgName.length + 1);
|
|
302
|
-
if (!version$1) continue;
|
|
303
|
-
if (version$1.startsWith("file:") || version$1.startsWith("workspace:")) continue;
|
|
304
|
-
const existingBun = lockMap.get(name);
|
|
305
|
-
if (existingBun && !isHigherVersion(version$1, existingBun.resolved)) continue;
|
|
306
|
-
lockMap.set(name, {
|
|
307
|
-
resolved: version$1,
|
|
308
|
-
scopes: ["prod"]
|
|
309
|
-
});
|
|
310
|
-
}
|
|
311
|
-
return lockMap;
|
|
312
|
-
}
|
|
313
|
-
async function parseLockfile(cliType, lockfilePath, lockfileVersion) {
|
|
314
|
-
if (cliType === "bun" && lockfileVersion === 0) return /* @__PURE__ */ new Map();
|
|
315
|
-
if (cliType === "vlt") return /* @__PURE__ */ new Map();
|
|
316
|
-
const content = await fs.promises.readFile(lockfilePath, "utf-8");
|
|
317
|
-
switch (cliType) {
|
|
318
|
-
case "npm": return parseNpmLock(content, lockfileVersion);
|
|
319
|
-
case "pnpm": return parsePnpmLock(content, lockfileVersion);
|
|
320
|
-
case "yarn": return parseYarnLock(content, lockfileVersion);
|
|
321
|
-
case "bun": return parseBunLock(content);
|
|
322
|
-
default: return /* @__PURE__ */ new Map();
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
async function readPackageJson(startDir) {
|
|
326
|
-
let current = startDir;
|
|
327
|
-
for (;;) try {
|
|
328
|
-
const content = await fs.promises.readFile(path.join(current, "package.json"), "utf-8");
|
|
329
|
-
return JSON.parse(content);
|
|
330
|
-
} catch {
|
|
331
|
-
const parent = path.dirname(current);
|
|
332
|
-
if (parent === current) return null;
|
|
333
|
-
current = parent;
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
function buildDirectMaps(pkgJson) {
|
|
337
|
-
const directScopes = /* @__PURE__ */ new Map();
|
|
338
|
-
const directRequested = /* @__PURE__ */ new Map();
|
|
339
|
-
const add = (deps, scope) => {
|
|
340
|
-
if (!deps || typeof deps !== "object") return;
|
|
341
|
-
for (const [name, specifier] of Object.entries(deps)) {
|
|
342
|
-
if (!directScopes.has(name)) directScopes.set(name, /* @__PURE__ */ new Set());
|
|
343
|
-
directScopes.get(name).add(scope);
|
|
344
|
-
if (!directRequested.has(name)) directRequested.set(name, specifier);
|
|
345
|
-
}
|
|
346
|
-
};
|
|
347
|
-
add(pkgJson.dependencies, "prod");
|
|
348
|
-
add(pkgJson.devDependencies, "dev");
|
|
349
|
-
add(pkgJson.peerDependencies, "peer");
|
|
350
|
-
add(pkgJson.optionalDependencies, "optional");
|
|
351
|
-
return {
|
|
352
|
-
directScopes,
|
|
353
|
-
directRequested
|
|
354
|
-
};
|
|
355
|
-
}
|
|
356
|
-
async function generateProjectManifest({ workPath, nodeVersion, cliType, lockfilePath, lockfileVersion, framework, serviceType }) {
|
|
357
|
-
try {
|
|
358
|
-
const pkgJson = await readPackageJson(workPath);
|
|
359
|
-
if (!pkgJson) return;
|
|
360
|
-
const { directScopes, directRequested } = buildDirectMaps(pkgJson);
|
|
361
|
-
const lockMap = lockfilePath ? await parseLockfile(cliType, lockfilePath, lockfileVersion) : /* @__PURE__ */ new Map();
|
|
362
|
-
const directDeps = [];
|
|
363
|
-
const transitiveDeps = [];
|
|
364
|
-
for (const [name, scopes] of directScopes) {
|
|
365
|
-
const lock = lockMap.get(name);
|
|
366
|
-
const dep = {
|
|
367
|
-
name,
|
|
368
|
-
type: "direct",
|
|
369
|
-
scopes: [...scopes].sort(),
|
|
370
|
-
requested: directRequested.get(name),
|
|
371
|
-
resolved: lock?.resolved ?? ""
|
|
372
|
-
};
|
|
373
|
-
if (lock?.source) dep.source = lock.source;
|
|
374
|
-
if (lock?.sourceUrl) dep.sourceUrl = lock.sourceUrl;
|
|
375
|
-
directDeps.push(dep);
|
|
376
|
-
}
|
|
377
|
-
for (const [name, lock] of lockMap) {
|
|
378
|
-
if (directScopes.has(name)) continue;
|
|
379
|
-
const dep = {
|
|
380
|
-
name,
|
|
381
|
-
type: "transitive",
|
|
382
|
-
scopes: lock.scopes,
|
|
383
|
-
resolved: lock.resolved
|
|
384
|
-
};
|
|
385
|
-
if (lock.source) dep.source = lock.source;
|
|
386
|
-
if (lock.sourceUrl) dep.sourceUrl = lock.sourceUrl;
|
|
387
|
-
transitiveDeps.push(dep);
|
|
388
|
-
}
|
|
389
|
-
const runtimeVersion = { resolved: String(nodeVersion.major) };
|
|
390
|
-
const enginesNode = pkgJson.engines?.node;
|
|
391
|
-
if (enginesNode) {
|
|
392
|
-
runtimeVersion.requested = enginesNode;
|
|
393
|
-
runtimeVersion.requestedSource = "package.json";
|
|
394
|
-
} else for (const filename of [".node-version", ".nvmrc"]) try {
|
|
395
|
-
const trimmed = (await fs.promises.readFile(path.join(workPath, filename), "utf-8")).trim();
|
|
396
|
-
if (trimmed) {
|
|
397
|
-
runtimeVersion.requested = trimmed;
|
|
398
|
-
runtimeVersion.requestedSource = filename;
|
|
399
|
-
break;
|
|
400
|
-
}
|
|
401
|
-
} catch {}
|
|
402
|
-
await writeProjectManifest({
|
|
403
|
-
version: MANIFEST_VERSION,
|
|
404
|
-
runtime: "node",
|
|
405
|
-
...framework ? { framework } : {},
|
|
406
|
-
...serviceType ? { serviceType } : {},
|
|
407
|
-
runtimeVersion,
|
|
408
|
-
dependencies: [...directDeps.sort((a, b) => a.name.localeCompare(b.name)), ...transitiveDeps.sort((a, b) => a.name.localeCompare(b.name))]
|
|
409
|
-
}, workPath, "node");
|
|
410
|
-
} catch (err) {
|
|
411
|
-
debug(`generateProjectManifest: ${err instanceof Error ? err.message : String(err)}`);
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
70
|
const diagnostics = createDiagnostics("node");
|
|
415
71
|
|
|
416
72
|
//#endregion
|
|
@@ -1267,10 +923,10 @@ async function resolveShimFormat(args) {
|
|
|
1267
923
|
//#endregion
|
|
1268
924
|
//#region src/crons.ts
|
|
1269
925
|
const DYNAMIC_SCHEDULE = "<dynamic>";
|
|
1270
|
-
/** Build the JSON route table embedded in
|
|
926
|
+
/** Build the JSON route table embedded in the dispatcher shim. */
|
|
1271
927
|
function buildCronRouteTable(crons) {
|
|
1272
928
|
const table = {};
|
|
1273
|
-
for (const cron of crons) table[cron.path] =
|
|
929
|
+
for (const cron of crons) table[cron.path] = cron.exportName;
|
|
1274
930
|
return table;
|
|
1275
931
|
}
|
|
1276
932
|
/**
|
|
@@ -1279,11 +935,6 @@ function buildCronRouteTable(crons) {
|
|
|
1279
935
|
* Mirrors `packages/python/src/crons.ts` for static schedules. Returns
|
|
1280
936
|
* `undefined` when the service is not schedule-triggered. Throws on
|
|
1281
937
|
* `<dynamic>` schedules — that path is reserved for a follow-up.
|
|
1282
|
-
*
|
|
1283
|
-
* v1 always invokes the user module's default export, so this returns
|
|
1284
|
-
* plain `Cron[]` (no handler-name field). When `handlerFunction` or
|
|
1285
|
-
* `<dynamic>` support lands, this will need to grow a per-path handler
|
|
1286
|
-
* name back.
|
|
1287
938
|
*/
|
|
1288
939
|
function getServiceCrons(opts) {
|
|
1289
940
|
const { service, entrypoint } = opts;
|
|
@@ -1293,7 +944,8 @@ function getServiceCrons(opts) {
|
|
|
1293
944
|
if (service.schedule === DYNAMIC_SCHEDULE) throw new Error("Dynamic cron schedules (\"<dynamic>\") are not yet supported for JavaScript/TypeScript services. Use a static cron expression in vercel.json.");
|
|
1294
945
|
return [{
|
|
1295
946
|
path: getInternalServiceCronPath(service.name, entrypoint, "cron"),
|
|
1296
|
-
schedule: service.schedule
|
|
947
|
+
schedule: service.schedule,
|
|
948
|
+
exportName: "default"
|
|
1297
949
|
}];
|
|
1298
950
|
}
|
|
1299
951
|
|
|
@@ -2145,7 +1797,10 @@ const build = async (args) => {
|
|
|
2145
1797
|
return {
|
|
2146
1798
|
routes,
|
|
2147
1799
|
output,
|
|
2148
|
-
...cronEntries ? { crons: cronEntries }
|
|
1800
|
+
...cronEntries ? { crons: cronEntries.map(({ path, schedule }) => ({
|
|
1801
|
+
path,
|
|
1802
|
+
schedule
|
|
1803
|
+
})) } : {}
|
|
2149
1804
|
};
|
|
2150
1805
|
});
|
|
2151
1806
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vercel/backends",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"main": "./dist/index.mjs",
|
|
6
6
|
"homepage": "https://vercel.com/docs",
|
|
@@ -25,8 +25,6 @@
|
|
|
25
25
|
"templates"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@yarnpkg/parsers": "^3.0.0",
|
|
29
|
-
"js-yaml": "^3.13.1",
|
|
30
28
|
"@vercel/nft": "1.5.0",
|
|
31
29
|
"execa": "3.2.0",
|
|
32
30
|
"fs-extra": "11.1.0",
|
|
@@ -37,7 +35,7 @@
|
|
|
37
35
|
"srvx": "0.8.9",
|
|
38
36
|
"tsx": "4.21.0",
|
|
39
37
|
"zod": "3.22.4",
|
|
40
|
-
"@vercel/build-utils": "13.
|
|
38
|
+
"@vercel/build-utils": "13.24.0"
|
|
41
39
|
},
|
|
42
40
|
"devDependencies": {
|
|
43
41
|
"@types/express": "5.0.3",
|