@vite-hub/workflow 0.0.4 → 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/README.md +34 -14
- package/dist/{_app-DgwN4ulW.d.ts → app-BojnC_yf.d.ts} +1 -4
- package/dist/{app-BZpq2cwC.js → app-CzPoP84f.js} +2 -1
- package/dist/client-DsGM3M4U.js +389 -0
- package/dist/cloudflare-env-BNrYo29x.js +113 -0
- package/dist/{cloudflare-D0Di-QYL.js → cloudflare-nF4abPd4.js} +20 -4
- package/dist/cloudflare-shared-CaxrMD1A.d.ts +1 -0
- package/dist/{cloudflare-vite-BkDgB6Sr.js → cloudflare-vite-B3IabBsv.js} +5 -4
- package/dist/{config-BHknO_rT.js → config-IJMb0eeZ.js} +38 -30
- package/dist/error-diagnostics-A_8Kp-48.js +116 -0
- package/dist/error-diagnostics-pwNFvAHP.js +67 -0
- package/dist/index.d.ts +20 -21
- package/dist/index.js +25 -369
- package/dist/inspect-B72iFyj-.js +70 -0
- package/dist/operations-B_rYG71W.js +230 -0
- package/dist/operations-tNUdj3G4.d.ts +212 -0
- package/dist/operations.d.ts +37 -0
- package/dist/operations.js +887 -0
- package/dist/out-CsaJxg8m.js +21755 -0
- package/dist/rolldown-runtime-CMFfr-1z.js +26 -0
- package/dist/runtime/cloudflare-runner.d.ts +5 -15
- package/dist/runtime/cloudflare-runner.js +40 -5
- package/dist/runtime/cloudflare-shared.d.ts +1 -0
- package/dist/runtime/cloudflare-shared.js +1 -1
- package/dist/runtime/cloudflare-vite.d.ts +8 -10
- package/dist/runtime/cloudflare-vite.js +1 -1
- package/dist/runtime/execute.d.ts +8 -7
- package/dist/runtime/execute.js +28 -5
- package/dist/runtime/openworkflow-worker.d.ts +6 -8
- package/dist/runtime/openworkflow-worker.js +5 -4
- package/dist/runtime/openworkflow.d.ts +8 -10
- package/dist/runtime/openworkflow.js +23 -17
- package/dist/runtime/state.d.ts +20 -21
- package/dist/runtime/state.js +90 -20
- package/dist/runtime/vercel-vite.d.ts +10 -12
- package/dist/runtime/vercel-vite.js +2 -2
- package/dist/runtime-type-DBCvIh5x.js +7 -0
- package/dist/{types-B9RdRkKh.d.ts → types-D82WmfZa.d.ts} +23 -12
- package/dist/{vercel-B0MuIVgJ.js → vercel-D-ZNtB_u.js} +34 -9
- package/dist/vite.d.ts +325 -11
- package/dist/vite.js +1267 -691
- package/package.json +79 -29
- package/dist/cloudflare-env-DjxQNbrx.js +0 -58
- package/dist/cloudflare-shared-BVVgDSdq.d.ts +0 -1
- package/dist/runtime-type-DGUn8Ple.js +0 -37
package/dist/vite.js
CHANGED
|
@@ -1,44 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { n as
|
|
1
|
+
import { r as __toESM } from "./rolldown-runtime-CMFfr-1z.js";
|
|
2
|
+
import { t as internalErrorDiagnostics } from "./error-diagnostics-A_8Kp-48.js";
|
|
3
|
+
import { i as normalizeHosting, n as isPlainObject, r as getHostingProvider, t as normalizeWorkflowOptions } from "./config-IJMb0eeZ.js";
|
|
4
|
+
import { t as workflowErrorDiagnostics } from "./error-diagnostics-pwNFvAHP.js";
|
|
5
|
+
import { a as getLegacyCloudflareWorkflowClassName, r as getCloudflareWorkflowClassName, t as createCloudflareWorkflowBindings } from "./cloudflare-nF4abPd4.js";
|
|
6
|
+
import { n as isRuntimeRecord, t as hasRuntimeType } from "./runtime-type-DBCvIh5x.js";
|
|
7
|
+
import { r as relativeDefinitionFile } from "./inspect-B72iFyj-.js";
|
|
4
8
|
import { builtinModules, createRequire } from "node:module";
|
|
5
|
-
import {
|
|
9
|
+
import { access, copyFile, cp, mkdir, mkdtemp, readFile, readdir, readlink, realpath, rename, rm, rmdir, stat, symlink, writeFile } from "node:fs/promises";
|
|
6
10
|
import { basename, dirname, extname, isAbsolute, join, parse, relative, resolve, sep } from "node:path";
|
|
7
|
-
import { cp, mkdir, mkdtemp, readFile, readdir, readlink, realpath, rename, rm, rmdir, stat, symlink, writeFile } from "node:fs/promises";
|
|
8
11
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
9
|
-
import { build, buildSync } from "esbuild";
|
|
12
|
+
import { build, buildSync, transform } from "esbuild";
|
|
13
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
10
14
|
import { existsSync, lstatSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync } from "node:fs";
|
|
11
15
|
import { tmpdir } from "node:os";
|
|
12
16
|
import { dirname as dirname$1, normalize, relative as relative$1, resolve as resolve$1 } from "pathe";
|
|
13
|
-
|
|
14
|
-
e2e: "e2e",
|
|
15
|
-
blob: "blob",
|
|
16
|
-
chat: "chat",
|
|
17
|
-
db: "db",
|
|
18
|
-
env: "env",
|
|
19
|
-
kv: "kv",
|
|
20
|
-
queue: "queue",
|
|
21
|
-
schedule: "schedule",
|
|
22
|
-
sandbox: "sandbox",
|
|
23
|
-
workspace: "workspace",
|
|
24
|
-
workflow: "workflow"
|
|
25
|
-
};
|
|
26
|
-
function isViteCli(argv) {
|
|
27
|
-
return argv.some((arg) => /(?:^|[/\\])vite(?:\.[cm]?js)?$/.test(arg) || arg === "vite");
|
|
28
|
-
}
|
|
29
|
-
function getViteCliMode(argv = process.argv) {
|
|
30
|
-
if (!isViteCli(argv)) return;
|
|
31
|
-
const modes = new Set(Object.values(VITEHUB_MODES));
|
|
32
|
-
for (let index = 0; index < argv.length; index += 1) {
|
|
33
|
-
const arg = argv[index];
|
|
34
|
-
const mode = arg === "--mode" || arg === "-m" ? argv[index + 1] : arg.startsWith("--mode=") ? arg.slice(7) : void 0;
|
|
35
|
-
if (mode && modes.has(mode)) return mode;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
function getViteMode(env = process.env) {
|
|
39
|
-
return env["VITEHUB_VITE_MODE"] ?? getViteCliMode();
|
|
40
|
-
}
|
|
41
|
-
//#endregion
|
|
17
|
+
import { parseSync } from "vite";
|
|
42
18
|
//#region ../internal/src/build/esbuild.ts
|
|
43
19
|
const viteRawNamespace = "vitehub-vite-raw";
|
|
44
20
|
const viteMarkdownTemplateNamespace = "vitehub-markdown-template";
|
|
@@ -316,62 +292,20 @@ function createViteAliasPlugin(aliases) {
|
|
|
316
292
|
}
|
|
317
293
|
};
|
|
318
294
|
}
|
|
319
|
-
function stripMarkdownCode(template) {
|
|
320
|
-
let fence;
|
|
321
|
-
let inList = false;
|
|
322
|
-
let previousLineBlank = true;
|
|
323
|
-
return template.split("\n").map((line) => {
|
|
324
|
-
const content = line.replace(/^(?: {0,3}> ?)+/, "");
|
|
325
|
-
if (!fence) {
|
|
326
|
-
const listIndented = inList && /^ {4}(?:`{3,}|~{3,})/.test(content);
|
|
327
|
-
const opening = (listIndented ? content.slice(4) : content).match(/^ {0,3}(`{3,}|~{3,})/);
|
|
328
|
-
if (!opening) {
|
|
329
|
-
if (/^ {0,3}(?:[-+*]|\d+[.)])\s+/.test(content)) inList = true;
|
|
330
|
-
else if (content.trim() && !/^ {2,}/.test(content)) inList = false;
|
|
331
|
-
const indentedCode = !inList && previousLineBlank && /^(?: {4}|\t)/.test(content) || inList && previousLineBlank && /^(?: {8}| {4}\t|\t{2})/.test(content);
|
|
332
|
-
previousLineBlank = content.trim() === "";
|
|
333
|
-
return indentedCode ? "" : line;
|
|
334
|
-
}
|
|
335
|
-
fence = {
|
|
336
|
-
marker: opening[1][0],
|
|
337
|
-
length: opening[1].length,
|
|
338
|
-
listIndented
|
|
339
|
-
};
|
|
340
|
-
previousLineBlank = false;
|
|
341
|
-
return "";
|
|
342
|
-
}
|
|
343
|
-
const closing = (fence.listIndented ? content.replace(/^ {4}/, "") : content).match(/^ {0,3}(`+|~+)\s*$/)?.[1];
|
|
344
|
-
if (closing?.[0] === fence.marker && closing.length >= fence.length) fence = void 0;
|
|
345
|
-
previousLineBlank = false;
|
|
346
|
-
return "";
|
|
347
|
-
}).join("\n");
|
|
348
|
-
}
|
|
349
|
-
function extractMarkdownTemplateImportSpecifiers(template) {
|
|
350
|
-
const visible = stripMarkdownCode(template).replace(/(`+)[\s\S]*?\1/g, "").replace(/(!?\[[^\]]*\])\([^)]*\)/g, "$1").replace(/^ {0,3}\[[^\]]+\]:\s*\S+/gm, "").replace(/<[^>]*>/g, "");
|
|
351
|
-
const specifiers = /* @__PURE__ */ new Set();
|
|
352
|
-
for (const match of visible.matchAll(/@(\.\.?\/[^\s<>{}[\]]+)/g)) {
|
|
353
|
-
const token = match[1];
|
|
354
|
-
const trailing = token.match(/[.,;:!?)]*$/)?.[0] || "";
|
|
355
|
-
specifiers.add(token.slice(0, token.length - trailing.length));
|
|
356
|
-
}
|
|
357
|
-
return [...specifiers];
|
|
358
|
-
}
|
|
359
295
|
function parseMarkdownTemplateRequest(id) {
|
|
296
|
+
if (id.includes("#")) return;
|
|
360
297
|
const queryIndex = id.indexOf("?");
|
|
361
|
-
const path = id.split(
|
|
298
|
+
const path = id.split("?", 1)[0];
|
|
362
299
|
if (queryIndex === -1) return path.endsWith(markdownTemplateFileSuffix) ? { path } : void 0;
|
|
363
|
-
|
|
364
|
-
if (!new URLSearchParams(query).has(markdownTemplateModuleQuery)) return;
|
|
300
|
+
if (id.slice(queryIndex + 1) !== markdownTemplateModuleQuery) return;
|
|
365
301
|
return { path };
|
|
366
302
|
}
|
|
367
|
-
function renderMarkdownTemplateModule(template
|
|
303
|
+
function renderMarkdownTemplateModule(template) {
|
|
368
304
|
return [
|
|
369
305
|
`import { renderMarkdownTemplate as vitehubRenderMarkdownTemplate } from ${JSON.stringify(markdownTemplateRuntimeSpecifier)}`,
|
|
370
306
|
`const vitehubMarkdownTemplate = ${JSON.stringify(template)}`,
|
|
371
|
-
`const vitehubMarkdownTemplateSourceId = ${JSON.stringify(sourceId)}`,
|
|
372
|
-
`const vitehubMarkdownTemplateImports = ${JSON.stringify(imports)}`,
|
|
373
307
|
"export default function render(data = {}) {",
|
|
374
|
-
" return vitehubRenderMarkdownTemplate(vitehubMarkdownTemplate, { data
|
|
308
|
+
" return vitehubRenderMarkdownTemplate(vitehubMarkdownTemplate, { data })",
|
|
375
309
|
"}",
|
|
376
310
|
""
|
|
377
311
|
].join("\n");
|
|
@@ -464,45 +398,22 @@ function createViteRawPlugin(rootDir, frameworkRuntime) {
|
|
|
464
398
|
filter: /.*/,
|
|
465
399
|
namespace: viteMarkdownTemplateNamespace
|
|
466
400
|
}, async (args) => ({
|
|
467
|
-
contents: await (
|
|
468
|
-
const template = await readFile(args.path, "utf8");
|
|
469
|
-
const imports = {};
|
|
470
|
-
const visited = new Set([args.path]);
|
|
471
|
-
const visit = async (source, importer) => {
|
|
472
|
-
for (const specifier of extractMarkdownTemplateImportSpecifiers(source)) {
|
|
473
|
-
const key = `${importer}\0${specifier}`;
|
|
474
|
-
if (imports[key]) continue;
|
|
475
|
-
const resolved = await build.resolve(specifier, {
|
|
476
|
-
importer,
|
|
477
|
-
kind: "import-statement",
|
|
478
|
-
pluginData: {
|
|
479
|
-
...args.pluginData,
|
|
480
|
-
[skipMarkdownTemplateResolve]: true
|
|
481
|
-
},
|
|
482
|
-
resolveDir: dirname(importer)
|
|
483
|
-
});
|
|
484
|
-
if (resolved.errors.length) return Promise.reject(new Error(resolved.errors.map((error) => error.text).join("\n")));
|
|
485
|
-
if (resolved.external || resolved.namespace !== "file") throw new Error(`[vitehub] Could not resolve Markdown template import ${JSON.stringify(specifier)} from ${JSON.stringify(importer)} to a file.`);
|
|
486
|
-
const imported = {
|
|
487
|
-
id: resolved.path,
|
|
488
|
-
template: await readFile(resolved.path, "utf8")
|
|
489
|
-
};
|
|
490
|
-
imports[key] = imported;
|
|
491
|
-
if (!visited.has(imported.id)) {
|
|
492
|
-
visited.add(imported.id);
|
|
493
|
-
await visit(imported.template, imported.id);
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
};
|
|
497
|
-
await visit(template, args.path);
|
|
498
|
-
return renderMarkdownTemplateModule(template, args.path, imports);
|
|
499
|
-
})(),
|
|
401
|
+
contents: renderMarkdownTemplateModule(await readFile(args.path, "utf8")),
|
|
500
402
|
loader: "js",
|
|
501
403
|
resolveDir: dirname(args.path)
|
|
502
404
|
}));
|
|
503
405
|
}
|
|
504
406
|
};
|
|
505
407
|
}
|
|
408
|
+
/** Select the runtime constants from one resolved Vite configuration. */
|
|
409
|
+
function resolveViteHubBundleDefines(config) {
|
|
410
|
+
const defines = {};
|
|
411
|
+
for (const name of ["__VITEHUB_PUBLIC_URL__", "__VITEHUB_APP_BASE_URL__"]) {
|
|
412
|
+
const value = config.define?.[name];
|
|
413
|
+
if (typeof value === "string") defines[name] = value;
|
|
414
|
+
}
|
|
415
|
+
return defines;
|
|
416
|
+
}
|
|
506
417
|
function createFileUrlPlugin() {
|
|
507
418
|
return {
|
|
508
419
|
name: "vitehub-file-url",
|
|
@@ -534,13 +445,16 @@ async function bundleEsmEntry(entryFile, outfile, options = {}) {
|
|
|
534
445
|
] : []].filter(Boolean).join("\n") } : void 0,
|
|
535
446
|
bundle: true,
|
|
536
447
|
conditions: options.conditions ?? (platform === "node" ? ["node"] : void 0),
|
|
448
|
+
define: options.define,
|
|
537
449
|
entryPoints: [entryFile],
|
|
538
450
|
external: options.external,
|
|
539
451
|
format,
|
|
452
|
+
keepNames: options.minifySyntax || options.minifyIdentifiers,
|
|
540
453
|
logLevel: "silent",
|
|
541
454
|
mainFields: options.mainFields ?? (platform === "neutral" ? ["module", "main"] : void 0),
|
|
542
455
|
resolveExtensions: options.extensions,
|
|
543
456
|
minifyIdentifiers: options.minifyIdentifiers,
|
|
457
|
+
minifySyntax: options.minifySyntax,
|
|
544
458
|
minifyWhitespace: options.minifyWhitespace,
|
|
545
459
|
outfile,
|
|
546
460
|
packages: options.packages,
|
|
@@ -561,15 +475,52 @@ async function bundleEsmEntry(entryFile, outfile, options = {}) {
|
|
|
561
475
|
options.signal.throwIfAborted();
|
|
562
476
|
}
|
|
563
477
|
}
|
|
478
|
+
const VITEHUB_MODES = {
|
|
479
|
+
e2e: "e2e",
|
|
480
|
+
blob: "blob",
|
|
481
|
+
chat: "chat",
|
|
482
|
+
db: "db",
|
|
483
|
+
env: "env",
|
|
484
|
+
kv: "kv",
|
|
485
|
+
queue: "queue",
|
|
486
|
+
schedule: "schedule",
|
|
487
|
+
sandbox: "sandbox",
|
|
488
|
+
workspace: "workspace",
|
|
489
|
+
workflow: "workflow"
|
|
490
|
+
};
|
|
491
|
+
function isViteCli(argv) {
|
|
492
|
+
return argv.some((arg) => /(?:^|[/\\])vite(?:\.[cm]?js)?$/.test(arg) || arg === "vite");
|
|
493
|
+
}
|
|
494
|
+
function getViteCliMode(argv = process.argv) {
|
|
495
|
+
if (!isViteCli(argv)) return;
|
|
496
|
+
const modes = new Set(Object.values(VITEHUB_MODES));
|
|
497
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
498
|
+
const arg = argv[index];
|
|
499
|
+
const mode = arg === "--mode" || arg === "-m" ? argv[index + 1] : arg.startsWith("--mode=") ? arg.slice(7) : void 0;
|
|
500
|
+
if (mode && modes.has(mode)) return mode;
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
function getViteMode(env = process.env) {
|
|
504
|
+
return env["VITEHUB_VITE_MODE"] ?? getViteCliMode();
|
|
505
|
+
}
|
|
564
506
|
//#endregion
|
|
565
507
|
//#region ../internal/src/build/client-output.ts
|
|
566
508
|
function hasStaticIndex(clientDir) {
|
|
567
509
|
return existsSync(resolve$1(clientDir, "index.html"));
|
|
568
510
|
}
|
|
569
|
-
async function copyClientOutput(clientDir, targetDir) {
|
|
511
|
+
async function copyClientOutput(clientDir, targetDir, excludedDirs = []) {
|
|
570
512
|
const resolvedClientDir = resolve$1(clientDir);
|
|
571
513
|
const resolvedTargetDir = resolve$1(targetDir);
|
|
572
514
|
if (resolvedClientDir === resolvedTargetDir) return;
|
|
515
|
+
const excluded = /* @__PURE__ */ new Set();
|
|
516
|
+
for (const dir of excludedDirs) {
|
|
517
|
+
const resolved = resolve$1(dir);
|
|
518
|
+
if (resolved !== resolvedClientDir && resolved.startsWith(`${resolvedClientDir}/`)) excluded.add(resolved);
|
|
519
|
+
}
|
|
520
|
+
const filter = (source) => {
|
|
521
|
+
const resolved = resolve$1(source);
|
|
522
|
+
return ![...excluded].some((dir) => resolved === dir || resolved.startsWith(`${dir}/`));
|
|
523
|
+
};
|
|
573
524
|
await rm(resolvedTargetDir, {
|
|
574
525
|
force: true,
|
|
575
526
|
recursive: true
|
|
@@ -579,10 +530,16 @@ async function copyClientOutput(clientDir, targetDir) {
|
|
|
579
530
|
if (targetRelativePath && !targetRelativePath.startsWith("../")) {
|
|
580
531
|
const [targetRootEntry] = targetRelativePath.split("/", 1);
|
|
581
532
|
await mkdir(resolvedTargetDir, { recursive: true });
|
|
582
|
-
await Promise.all((await readdir(resolvedClientDir)).filter((entry) => entry !== targetRootEntry).map((entry) => cp(resolve$1(resolvedClientDir, entry), resolve$1(resolvedTargetDir, entry), {
|
|
533
|
+
await Promise.all((await readdir(resolvedClientDir)).filter((entry) => entry !== targetRootEntry).map((entry) => cp(resolve$1(resolvedClientDir, entry), resolve$1(resolvedTargetDir, entry), {
|
|
534
|
+
recursive: true,
|
|
535
|
+
filter
|
|
536
|
+
})));
|
|
583
537
|
return;
|
|
584
538
|
}
|
|
585
|
-
await cp(resolvedClientDir, resolvedTargetDir, {
|
|
539
|
+
await cp(resolvedClientDir, resolvedTargetDir, {
|
|
540
|
+
recursive: true,
|
|
541
|
+
filter
|
|
542
|
+
});
|
|
586
543
|
}
|
|
587
544
|
//#endregion
|
|
588
545
|
//#region ../internal/src/build/provider-output-config.ts
|
|
@@ -628,7 +585,7 @@ function isProviderJsonRecord(value) {
|
|
|
628
585
|
}
|
|
629
586
|
}
|
|
630
587
|
function assertProviderJsonRecord(value) {
|
|
631
|
-
if (!isProviderJsonRecord(value)) throw
|
|
588
|
+
if (!isProviderJsonRecord(value)) throw internalErrorDiagnostics.INTERNAL_B0043({ message: "[vitehub] Provider output config must be a JSON object." });
|
|
632
589
|
}
|
|
633
590
|
function isFileNotFoundError(error) {
|
|
634
591
|
return error instanceof Error && "code" in error && error.code === "ENOENT";
|
|
@@ -661,7 +618,7 @@ function preserveUnownedKeyedArrayEntries(value, ownership, replacements = []) {
|
|
|
661
618
|
const key = getKeyedArrayEntryValue(entry, ownership.key);
|
|
662
619
|
return key === void 0 ? [] : [key];
|
|
663
620
|
});
|
|
664
|
-
const ownedKeys = new Set([...ownership.values ?? [], ...replacementKeys]);
|
|
621
|
+
const ownedKeys = /* @__PURE__ */ new Set([...ownership.values ?? [], ...replacementKeys]);
|
|
665
622
|
return current.filter((entry) => {
|
|
666
623
|
const key = getKeyedArrayEntryValue(entry, ownership.key);
|
|
667
624
|
return key === void 0 || !ownedKeys.has(key);
|
|
@@ -772,7 +729,9 @@ function ensureGeneratedDir(rootDir, productName) {
|
|
|
772
729
|
return resolve$1(rootDir, ...generatedDirSegments(productName));
|
|
773
730
|
}
|
|
774
731
|
function createImportPath(fromFile, targetFile) {
|
|
775
|
-
const
|
|
732
|
+
const fromDir = realpathIfExists(dirname$1(fromFile));
|
|
733
|
+
const target = realpathIfExists(targetFile);
|
|
734
|
+
const importPath = relative$1(fromDir, target);
|
|
776
735
|
return importPath.startsWith(".") ? importPath : `./${importPath}`;
|
|
777
736
|
}
|
|
778
737
|
function realpathIfExists(path) {
|
|
@@ -783,328 +742,84 @@ function realpathIfExists(path) {
|
|
|
783
742
|
}
|
|
784
743
|
}
|
|
785
744
|
//#endregion
|
|
786
|
-
//#region ../internal/src/
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
index += 2;
|
|
813
|
-
continue;
|
|
814
|
-
}
|
|
815
|
-
if (expressionDepth === 0) {
|
|
816
|
-
if (char === "`") return index + 1;
|
|
817
|
-
if (char === "$" && next === "{") {
|
|
818
|
-
expressionDepth = 1;
|
|
819
|
-
previousSignificant = "{";
|
|
820
|
-
index += 2;
|
|
821
|
-
continue;
|
|
822
|
-
}
|
|
823
|
-
index += 1;
|
|
824
|
-
continue;
|
|
825
|
-
}
|
|
826
|
-
if (char === "\"" || char === "'") {
|
|
827
|
-
index = skipQuoted(source, index, controlFlowRegexes);
|
|
828
|
-
previousSignificant = "literal";
|
|
829
|
-
continue;
|
|
830
|
-
}
|
|
831
|
-
if (char === "`") {
|
|
832
|
-
index = skipTemplateLiteral(source, index, controlFlowRegexes);
|
|
833
|
-
previousSignificant = "literal";
|
|
834
|
-
continue;
|
|
835
|
-
}
|
|
836
|
-
if (char === "/" && next === "/") {
|
|
837
|
-
index = skipLineComment(source, index);
|
|
838
|
-
continue;
|
|
839
|
-
}
|
|
840
|
-
if (char === "/" && next === "*") {
|
|
841
|
-
index = skipBlockComment(source, index);
|
|
842
|
-
continue;
|
|
843
|
-
}
|
|
844
|
-
if (char === "/" && (isRegexLiteralStart(previousSignificant) || isControlFlowRegexStart(source, index, controlFlowRegexes))) {
|
|
845
|
-
index = skipRegexLiteral(source, index);
|
|
846
|
-
previousSignificant = "/";
|
|
847
|
-
continue;
|
|
848
|
-
}
|
|
849
|
-
if (char === "{") expressionDepth += 1;
|
|
850
|
-
if (char === "}") expressionDepth -= 1;
|
|
851
|
-
previousSignificant = trackSignificant(previousSignificant, char);
|
|
852
|
-
index += 1;
|
|
853
|
-
}
|
|
854
|
-
return index;
|
|
855
|
-
}
|
|
856
|
-
function skipLineComment(source, index) {
|
|
857
|
-
const end = source.indexOf("\n", index + 2);
|
|
858
|
-
return end === -1 ? source.length : end + 1;
|
|
859
|
-
}
|
|
860
|
-
function skipBlockComment(source, index) {
|
|
861
|
-
const end = source.indexOf("*/", index + 2);
|
|
862
|
-
return end === -1 ? source.length : end + 2;
|
|
863
|
-
}
|
|
864
|
-
function isRegexLiteralStart(previousSignificant) {
|
|
865
|
-
const token = previousSignificant.trimEnd();
|
|
866
|
-
if (/^\.[\w$]+$/.test(token)) return false;
|
|
867
|
-
return !token || /[({[=,:!&|?;>+\-*%^~]/.test(token) || /\b(?:await|case|delete|do|else|in|instanceof|return|throw|typeof|void|yield)$/.test(token);
|
|
868
|
-
}
|
|
869
|
-
function findLineCommentStart(source, start, end, controlFlowRegexes) {
|
|
870
|
-
for (let index = start; index <= end;) {
|
|
871
|
-
const char = source[index];
|
|
872
|
-
const next = source[index + 1];
|
|
873
|
-
if (isQuote(char)) {
|
|
874
|
-
index = skipQuoted(source, index, controlFlowRegexes);
|
|
875
|
-
continue;
|
|
876
|
-
}
|
|
877
|
-
if (char === "/" && next === "*") {
|
|
878
|
-
index = skipBlockComment(source, index);
|
|
879
|
-
continue;
|
|
880
|
-
}
|
|
881
|
-
if (char === "/" && next === "/") return index;
|
|
882
|
-
index += 1;
|
|
883
|
-
}
|
|
884
|
-
return -1;
|
|
885
|
-
}
|
|
886
|
-
function previousCodeIndex(source, index, controlFlowRegexes) {
|
|
887
|
-
let current = index;
|
|
888
|
-
while (current >= 0) {
|
|
889
|
-
while (/\s/.test(source[current] ?? "")) current--;
|
|
890
|
-
if (source[current] === "/" && source[current - 1] === "*") {
|
|
891
|
-
const start = source.lastIndexOf("/*", current - 2);
|
|
892
|
-
if (start === -1) return current;
|
|
893
|
-
current = start - 1;
|
|
894
|
-
continue;
|
|
895
|
-
}
|
|
896
|
-
const lineStart = source.lastIndexOf("\n", current) + 1;
|
|
897
|
-
const lineComment = findLineCommentStart(source, lineStart, current, controlFlowRegexes);
|
|
898
|
-
if (lineComment !== -1 && lineComment <= current) {
|
|
899
|
-
current = lineStart - 1;
|
|
900
|
-
continue;
|
|
901
|
-
}
|
|
902
|
-
return current;
|
|
903
|
-
}
|
|
904
|
-
return current;
|
|
745
|
+
//#region ../internal/src/build/scan-module.ts
|
|
746
|
+
/**
|
|
747
|
+
* Reads facts from JavaScript and TypeScript modules at build and dev time. The scanner parses each module once with
|
|
748
|
+
* the oxc parser that Vite ships through Rolldown, and never runs it. Values that are not static literals read as
|
|
749
|
+
* `dynamic`, so callers can report their own diagnostics.
|
|
750
|
+
*/
|
|
751
|
+
function languageOf(file) {
|
|
752
|
+
if (/\.(?:c|m)?tsx$/i.test(file)) return "tsx";
|
|
753
|
+
if (/\.(?:c|m)?jsx$/i.test(file)) return "jsx";
|
|
754
|
+
if (/\.(?:c|m)?js$/i.test(file)) return "js";
|
|
755
|
+
return "ts";
|
|
756
|
+
}
|
|
757
|
+
/** Parses a module once. `file` selects the grammar from its extension and defaults to TypeScript. */
|
|
758
|
+
function scanModule(source, file = "module.ts") {
|
|
759
|
+
const result = parseSync(file, source, {
|
|
760
|
+
lang: languageOf(file),
|
|
761
|
+
preserveParens: false,
|
|
762
|
+
sourceType: "module"
|
|
763
|
+
});
|
|
764
|
+
return {
|
|
765
|
+
comments: result.comments,
|
|
766
|
+
errors: result.errors,
|
|
767
|
+
file,
|
|
768
|
+
program: result.program,
|
|
769
|
+
source
|
|
770
|
+
};
|
|
905
771
|
}
|
|
906
|
-
function
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
772
|
+
function isNode(value) {
|
|
773
|
+
return typeof value === "object" && value !== null && "type" in value && typeof value.type === "string";
|
|
774
|
+
}
|
|
775
|
+
/** Visits `node` and its descendants. Return `false` from `visit` to skip the children of a node. */
|
|
776
|
+
function walk(node, visit, parent) {
|
|
777
|
+
if (visit(node, parent) === false) return;
|
|
778
|
+
const fields = node;
|
|
779
|
+
for (const key in fields) {
|
|
780
|
+
const child = fields[key];
|
|
781
|
+
if (typeof child !== "object" || child === null || key === "parent") continue;
|
|
782
|
+
if (Array.isArray(child)) {
|
|
783
|
+
for (const item of child) if (isNode(item)) walk(item, visit, node);
|
|
784
|
+
} else if (isNode(child)) walk(child, visit, node);
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
function isLineTerminator(char) {
|
|
788
|
+
return char === "\n" || char === "\r" || char === "\u2028" || char === "\u2029";
|
|
789
|
+
}
|
|
790
|
+
/** Comments, JSX text, and string, template, and regular expression literals, sorted by position. Templates are not split. */
|
|
791
|
+
function literalSpans(module) {
|
|
792
|
+
const spans = module.comments.map((comment) => ({
|
|
793
|
+
end: comment.end,
|
|
794
|
+
inert: true,
|
|
795
|
+
start: comment.start
|
|
796
|
+
}));
|
|
797
|
+
walk(module.program, (node) => {
|
|
798
|
+
if (node.type === "TemplateLiteral" || node.type === "JSXText") {
|
|
799
|
+
spans.push({
|
|
800
|
+
end: node.end,
|
|
801
|
+
inert: node.type === "JSXText",
|
|
802
|
+
start: node.start
|
|
803
|
+
});
|
|
915
804
|
return false;
|
|
916
805
|
}
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
function skipRegexLiteral(source, index) {
|
|
933
|
-
index += 1;
|
|
934
|
-
while (index < source.length) {
|
|
935
|
-
const char = source[index];
|
|
936
|
-
if (char === "\\") {
|
|
937
|
-
index += 2;
|
|
938
|
-
continue;
|
|
939
|
-
}
|
|
940
|
-
if (char === "[") {
|
|
941
|
-
index += 1;
|
|
942
|
-
while (index < source.length) {
|
|
943
|
-
if (source[index] === "\\") {
|
|
944
|
-
index += 2;
|
|
945
|
-
continue;
|
|
946
|
-
}
|
|
947
|
-
if (source[index] === "]") break;
|
|
948
|
-
index += 1;
|
|
949
|
-
}
|
|
950
|
-
}
|
|
951
|
-
if (char === "/") {
|
|
952
|
-
index += 1;
|
|
953
|
-
while (/[a-z]/i.test(source[index] ?? "")) index += 1;
|
|
954
|
-
return index;
|
|
955
|
-
}
|
|
956
|
-
index += 1;
|
|
957
|
-
}
|
|
958
|
-
return index;
|
|
959
|
-
}
|
|
960
|
-
function trackSignificant(previousSignificant, char) {
|
|
961
|
-
if (/[a-z$]/i.test(char ?? "")) return /[\w$]$/.test(previousSignificant) || previousSignificant === "." ? previousSignificant + char : char ?? "";
|
|
962
|
-
if (/\s/.test(char ?? "")) return /[\w$]$/.test(previousSignificant) ? `${previousSignificant} ` : previousSignificant;
|
|
963
|
-
if (!/\s/.test(char ?? "")) return char ?? "";
|
|
964
|
-
return previousSignificant;
|
|
965
|
-
}
|
|
966
|
-
function nextNonWhitespace(source, index) {
|
|
967
|
-
return source[skipWhitespaceAndComments(source, index)];
|
|
968
|
-
}
|
|
969
|
-
function skipWhitespaceAndComments(source, index) {
|
|
970
|
-
while (index < source.length) {
|
|
971
|
-
if (/\s/.test(source[index] ?? "")) {
|
|
972
|
-
index += 1;
|
|
973
|
-
continue;
|
|
974
|
-
}
|
|
975
|
-
if (source[index] === "/" && source[index + 1] === "/") {
|
|
976
|
-
index = skipLineComment(source, index);
|
|
977
|
-
continue;
|
|
978
|
-
}
|
|
979
|
-
if (source[index] === "/" && source[index + 1] === "*") {
|
|
980
|
-
index = skipBlockComment(source, index);
|
|
981
|
-
continue;
|
|
982
|
-
}
|
|
983
|
-
return index;
|
|
984
|
-
}
|
|
985
|
-
return index;
|
|
986
|
-
}
|
|
987
|
-
function maskSourceLiterals(source) {
|
|
988
|
-
const output = source.split("");
|
|
989
|
-
let previousSignificant = "";
|
|
990
|
-
const mask = (start, end) => {
|
|
991
|
-
for (let index = start; index < end; index++) if (output[index] !== "\n" && output[index] !== "\r") output[index] = " ";
|
|
992
|
-
};
|
|
993
|
-
for (let index = 0; index < source.length;) {
|
|
994
|
-
const char = source[index];
|
|
995
|
-
const next = source[index + 1];
|
|
996
|
-
let end;
|
|
997
|
-
if (isQuote(char)) {
|
|
998
|
-
end = skipQuoted(source, index);
|
|
999
|
-
previousSignificant = "literal";
|
|
1000
|
-
} else if (char === "/" && next === "/") end = skipLineComment(source, index);
|
|
1001
|
-
else if (char === "/" && next === "*") end = skipBlockComment(source, index);
|
|
1002
|
-
else if (char === "/" && (isRegexLiteralStart(previousSignificant) || isControlFlowRegexStart(source, index))) {
|
|
1003
|
-
end = skipRegexLiteral(source, index);
|
|
1004
|
-
previousSignificant = "/";
|
|
1005
|
-
}
|
|
1006
|
-
if (end !== void 0) {
|
|
1007
|
-
mask(index, end);
|
|
1008
|
-
index = end;
|
|
1009
|
-
continue;
|
|
1010
|
-
}
|
|
1011
|
-
previousSignificant = trackSignificant(previousSignificant, char);
|
|
1012
|
-
index += 1;
|
|
1013
|
-
}
|
|
806
|
+
if (node.type === "Literal" && (typeof node.value === "string" || "regex" in node)) spans.push({
|
|
807
|
+
end: node.end,
|
|
808
|
+
inert: false,
|
|
809
|
+
start: node.start
|
|
810
|
+
});
|
|
811
|
+
});
|
|
812
|
+
return spans.sort((left, right) => left.start - right.start);
|
|
813
|
+
}
|
|
814
|
+
/**
|
|
815
|
+
* The module source with comments, strings, templates, regular expressions, and JSX text replaced by spaces. Line
|
|
816
|
+
* terminators and all positions stay the same, so text matches map back to the source.
|
|
817
|
+
*/
|
|
818
|
+
function maskLiterals(module) {
|
|
819
|
+
const output = module.source.split("");
|
|
820
|
+
for (const span of literalSpans(module)) for (let index = span.start; index < span.end; index++) if (!isLineTerminator(output[index] ?? "")) output[index] = " ";
|
|
1014
821
|
return output.join("");
|
|
1015
822
|
}
|
|
1016
|
-
function findMatching(source, index, open, close, controlFlowRegexes = /* @__PURE__ */ new Map()) {
|
|
1017
|
-
let depth = 0;
|
|
1018
|
-
let previousSignificant = "";
|
|
1019
|
-
for (let current = index; current < source.length; current++) {
|
|
1020
|
-
const char = source[current];
|
|
1021
|
-
const next = source[current + 1];
|
|
1022
|
-
if (isQuote(char)) {
|
|
1023
|
-
current = skipQuoted(source, current, controlFlowRegexes) - 1;
|
|
1024
|
-
previousSignificant = "literal";
|
|
1025
|
-
continue;
|
|
1026
|
-
}
|
|
1027
|
-
if (char === "/" && next === "/") {
|
|
1028
|
-
current = skipLineComment(source, current) - 1;
|
|
1029
|
-
continue;
|
|
1030
|
-
}
|
|
1031
|
-
if (char === "/" && next === "*") {
|
|
1032
|
-
current = skipBlockComment(source, current) - 1;
|
|
1033
|
-
continue;
|
|
1034
|
-
}
|
|
1035
|
-
if (char === "/" && (isRegexLiteralStart(previousSignificant) || isControlFlowRegexStart(source, current, controlFlowRegexes))) {
|
|
1036
|
-
current = skipRegexLiteral(source, current) - 1;
|
|
1037
|
-
previousSignificant = "/";
|
|
1038
|
-
continue;
|
|
1039
|
-
}
|
|
1040
|
-
if (char === open) {
|
|
1041
|
-
depth += 1;
|
|
1042
|
-
previousSignificant = char;
|
|
1043
|
-
continue;
|
|
1044
|
-
}
|
|
1045
|
-
if (char === close && !(open === "<" && close === ">" && source[current - 1] === "=")) {
|
|
1046
|
-
depth -= 1;
|
|
1047
|
-
if (depth === 0) return current;
|
|
1048
|
-
previousSignificant = char;
|
|
1049
|
-
continue;
|
|
1050
|
-
}
|
|
1051
|
-
previousSignificant = trackSignificant(previousSignificant, char);
|
|
1052
|
-
}
|
|
1053
|
-
}
|
|
1054
|
-
function splitTopLevel(source, separator = ",") {
|
|
1055
|
-
const parts = [];
|
|
1056
|
-
let depth = 0;
|
|
1057
|
-
let previousSignificant = "";
|
|
1058
|
-
let start = 0;
|
|
1059
|
-
for (let index = 0; index < source.length; index++) {
|
|
1060
|
-
const char = source[index];
|
|
1061
|
-
const next = source[index + 1];
|
|
1062
|
-
if (isQuote(char)) {
|
|
1063
|
-
index = skipQuoted(source, index) - 1;
|
|
1064
|
-
previousSignificant = "literal";
|
|
1065
|
-
continue;
|
|
1066
|
-
}
|
|
1067
|
-
if (char === "/" && next === "/") {
|
|
1068
|
-
index = skipLineComment(source, index) - 1;
|
|
1069
|
-
continue;
|
|
1070
|
-
}
|
|
1071
|
-
if (char === "/" && next === "*") {
|
|
1072
|
-
index = skipBlockComment(source, index) - 1;
|
|
1073
|
-
continue;
|
|
1074
|
-
}
|
|
1075
|
-
if (char === "/" && (isRegexLiteralStart(previousSignificant) || isControlFlowRegexStart(source, index))) {
|
|
1076
|
-
index = skipRegexLiteral(source, index) - 1;
|
|
1077
|
-
previousSignificant = "/";
|
|
1078
|
-
continue;
|
|
1079
|
-
}
|
|
1080
|
-
if (char === "<") {
|
|
1081
|
-
const genericEnd = findMatching(source, index, "<", ">");
|
|
1082
|
-
if (genericEnd !== void 0 && nextNonWhitespace(source, genericEnd + 1) === "(") {
|
|
1083
|
-
index = genericEnd;
|
|
1084
|
-
previousSignificant = ">";
|
|
1085
|
-
continue;
|
|
1086
|
-
}
|
|
1087
|
-
}
|
|
1088
|
-
if (char === "(" || char === "{" || char === "[") {
|
|
1089
|
-
depth += 1;
|
|
1090
|
-
previousSignificant = char;
|
|
1091
|
-
continue;
|
|
1092
|
-
}
|
|
1093
|
-
if (char === ")" || char === "}" || char === "]") {
|
|
1094
|
-
depth -= 1;
|
|
1095
|
-
previousSignificant = char;
|
|
1096
|
-
continue;
|
|
1097
|
-
}
|
|
1098
|
-
if (char === separator && depth === 0) {
|
|
1099
|
-
parts.push(source.slice(start, index).trim());
|
|
1100
|
-
start = index + 1;
|
|
1101
|
-
continue;
|
|
1102
|
-
}
|
|
1103
|
-
previousSignificant = trackSignificant(previousSignificant, char);
|
|
1104
|
-
}
|
|
1105
|
-
parts.push(source.slice(start).trim());
|
|
1106
|
-
return parts;
|
|
1107
|
-
}
|
|
1108
823
|
//#endregion
|
|
1109
824
|
//#region ../internal/src/build/provider-output-sources.ts
|
|
1110
825
|
function escapeRegExp(value) {
|
|
@@ -1118,7 +833,8 @@ function rewriteRetainedProviderSourcePaths(contents, retainedSourcesDir, publis
|
|
|
1118
833
|
const serializedPublishedSeparator = publishedSeparator === "\\" ? "\\\\" : "/";
|
|
1119
834
|
const serializedPath = new RegExp(`${escapeRegExp(serializedRetainedSourcesDir)}((?:(?:\\\\\\\\|/)[^"\\\\/]*)+)`, "g");
|
|
1120
835
|
const normalizedContents = contents.replace(serializedPath, (_matched, suffix) => {
|
|
1121
|
-
|
|
836
|
+
const normalizedSuffix = suffix.replaceAll("\\\\", serializedPublishedSeparator).replaceAll("/", serializedPublishedSeparator);
|
|
837
|
+
return `${serializedPublishedSourcesDir}${normalizedSuffix}`;
|
|
1122
838
|
});
|
|
1123
839
|
const replacements = [
|
|
1124
840
|
[`${pathToFileURL(retainedSourcesDir).href}/`, `${pathToFileURL(publishedSourcesDir).href}/`],
|
|
@@ -1229,7 +945,7 @@ function retainProviderOutputAliases(aliases, retainedSources) {
|
|
|
1229
945
|
}
|
|
1230
946
|
return retainedAliases;
|
|
1231
947
|
}
|
|
1232
|
-
const ignoredSourceDirectories = new Set([
|
|
948
|
+
const ignoredSourceDirectories = /* @__PURE__ */ new Set([
|
|
1233
949
|
".git",
|
|
1234
950
|
".netlify",
|
|
1235
951
|
".nuxt",
|
|
@@ -1241,7 +957,7 @@ const ignoredSourceDirectories = new Set([
|
|
|
1241
957
|
"dist",
|
|
1242
958
|
"node_modules"
|
|
1243
959
|
]);
|
|
1244
|
-
const ignoredGeneratedDirectories = new Set([".vitehub", ".vitest-tmp"]);
|
|
960
|
+
const ignoredGeneratedDirectories = /* @__PURE__ */ new Set([".vitehub", ".vitest-tmp"]);
|
|
1245
961
|
function isTransientSourceDirectory(path) {
|
|
1246
962
|
return basename(path).startsWith(".drizzle-generate-");
|
|
1247
963
|
}
|
|
@@ -1321,7 +1037,7 @@ function commonSourceRoot(root, paths) {
|
|
|
1321
1037
|
}
|
|
1322
1038
|
return common;
|
|
1323
1039
|
}
|
|
1324
|
-
const traceableSourceExtensions = new Set([
|
|
1040
|
+
const traceableSourceExtensions = /* @__PURE__ */ new Set([
|
|
1325
1041
|
".cjs",
|
|
1326
1042
|
".cts",
|
|
1327
1043
|
".js",
|
|
@@ -1339,8 +1055,34 @@ function resolveComputedModuleSource(file, specifier, resolveFrom = file) {
|
|
|
1339
1055
|
return;
|
|
1340
1056
|
}
|
|
1341
1057
|
}
|
|
1058
|
+
/** The index of the delimiter that closes the one at `open`. `masked` has no literals or comments. */
|
|
1059
|
+
function matchingDelimiter(masked, open) {
|
|
1060
|
+
let depth = 0;
|
|
1061
|
+
for (let index = open; index < masked.length; index++) {
|
|
1062
|
+
const char = masked[index];
|
|
1063
|
+
if (char === "(" || char === "[" || char === "{") depth++;
|
|
1064
|
+
else if ((char === ")" || char === "]" || char === "}") && --depth === 0) return index;
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
/** Splits `source.slice(start, end)` at top-level commas. */
|
|
1068
|
+
function splitTopLevel(source, masked, start, end) {
|
|
1069
|
+
const parts = [];
|
|
1070
|
+
let depth = 0;
|
|
1071
|
+
let partStart = start;
|
|
1072
|
+
for (let index = start; index < end; index++) {
|
|
1073
|
+
const char = masked[index];
|
|
1074
|
+
if (char === "(" || char === "[" || char === "{") depth++;
|
|
1075
|
+
else if (char === ")" || char === "]" || char === "}") depth--;
|
|
1076
|
+
else if (char === "," && depth === 0) {
|
|
1077
|
+
parts.push(source.slice(partStart, index).trim());
|
|
1078
|
+
partStart = index + 1;
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
parts.push(source.slice(partStart, end).trim());
|
|
1082
|
+
return parts;
|
|
1083
|
+
}
|
|
1342
1084
|
function traceComputedModuleSources(file, source, onRuntimePackageRequest) {
|
|
1343
|
-
const masked =
|
|
1085
|
+
const masked = maskLiterals(scanModule(source, file));
|
|
1344
1086
|
const bindings = /* @__PURE__ */ new Map();
|
|
1345
1087
|
for (const match of source.matchAll(/\b(?:const|let|var)\s+([A-Z_$][\w$]*)\s*=\s*([`"'])(.*?)\2/gis)) {
|
|
1346
1088
|
const quoteOffset = match[0].indexOf(match[2]);
|
|
@@ -1348,7 +1090,7 @@ function traceComputedModuleSources(file, source, onRuntimePackageRequest) {
|
|
|
1348
1090
|
if (match[2] === "`" && match[3].includes("${")) continue;
|
|
1349
1091
|
bindings.set(match[1], match[3]);
|
|
1350
1092
|
}
|
|
1351
|
-
const createRequireNames = new Set(["createRequire"]);
|
|
1093
|
+
const createRequireNames = /* @__PURE__ */ new Set(["createRequire"]);
|
|
1352
1094
|
for (const match of source.matchAll(/\bimport\s+(?:[A-Z_$][\w$]*\s*,\s*)?\{([^}]*)\}\s*from\s*([`"'])(?:node:)?module\2/gis)) for (const specifier of match[1].split(",")) {
|
|
1353
1095
|
const binding = /^\s*createRequire(?:\s+as\s+([A-Z_$][\w$]*))?\s*$/i.exec(specifier)?.[1];
|
|
1354
1096
|
if (binding) createRequireNames.add(binding);
|
|
@@ -1375,17 +1117,18 @@ function traceComputedModuleSources(file, source, onRuntimePackageRequest) {
|
|
|
1375
1117
|
if (!literal || literal[1] === "`" && literal[2].includes("${")) return void 0;
|
|
1376
1118
|
return literal[2];
|
|
1377
1119
|
};
|
|
1378
|
-
const createRequireBase = (
|
|
1120
|
+
const createRequireBase = (start, end) => {
|
|
1121
|
+
const expression = source.slice(start, end);
|
|
1379
1122
|
const normalized = expression.trim();
|
|
1380
1123
|
if (normalized === "import.meta.url" || normalized === "__filename") return file;
|
|
1381
1124
|
const direct = staticModuleSpecifier(normalized);
|
|
1382
1125
|
if (direct) return direct;
|
|
1383
1126
|
const newUrl = /^new\s+URL\s*\(/i.exec(normalized);
|
|
1384
1127
|
if (!newUrl) return file;
|
|
1385
|
-
const openParen = normalized.indexOf("(", newUrl.index);
|
|
1386
|
-
const closeParen =
|
|
1387
|
-
if (closeParen === void 0 ||
|
|
1388
|
-
const [relativeUrl, baseUrl] = splitTopLevel(
|
|
1128
|
+
const openParen = start + expression.indexOf(normalized) + normalized.indexOf("(", newUrl.index);
|
|
1129
|
+
const closeParen = matchingDelimiter(masked, openParen);
|
|
1130
|
+
if (closeParen === void 0 || closeParen >= end || source.slice(closeParen + 1, end).trim()) return file;
|
|
1131
|
+
const [relativeUrl, baseUrl] = splitTopLevel(source, masked, openParen + 1, closeParen);
|
|
1389
1132
|
const relativePath = relativeUrl ? staticModuleSpecifier(relativeUrl) : void 0;
|
|
1390
1133
|
if (!relativePath || baseUrl?.replace(/\s/g, "") !== "import.meta.url") return file;
|
|
1391
1134
|
return fileURLToPath(new URL(relativePath, pathToFileURL(file)));
|
|
@@ -1394,8 +1137,8 @@ function traceComputedModuleSources(file, source, onRuntimePackageRequest) {
|
|
|
1394
1137
|
for (const match of masked.matchAll(/\b(?:const|let|var)\s+([A-Z_$][\w$]*)\s*=\s*([A-Z_$][\w$]*(?:\s*\.\s*createRequire)?)\s*\(/gi)) {
|
|
1395
1138
|
if (!isCreateRequireExpression(match[2])) continue;
|
|
1396
1139
|
const openParen = match.index + match[0].lastIndexOf("(");
|
|
1397
|
-
const closeParen =
|
|
1398
|
-
const base = closeParen === void 0 ? file : createRequireBase(
|
|
1140
|
+
const closeParen = matchingDelimiter(masked, openParen);
|
|
1141
|
+
const base = closeParen === void 0 ? file : createRequireBase(openParen + 1, closeParen);
|
|
1399
1142
|
boundRequireBases.set(match[1], base);
|
|
1400
1143
|
}
|
|
1401
1144
|
const boundResolveBases = /* @__PURE__ */ new Map();
|
|
@@ -1406,8 +1149,8 @@ function traceComputedModuleSources(file, source, onRuntimePackageRequest) {
|
|
|
1406
1149
|
for (const match of masked.matchAll(/\b(?:const|let|var)\s*\{([^}]*)\}\s*=\s*([A-Z_$][\w$]*(?:\s*\.\s*createRequire)?)\s*\(/gi)) {
|
|
1407
1150
|
if (!isCreateRequireExpression(match[2])) continue;
|
|
1408
1151
|
const openParen = match.index + match[0].lastIndexOf("(");
|
|
1409
|
-
const closeParen =
|
|
1410
|
-
const base = closeParen === void 0 ? file : createRequireBase(
|
|
1152
|
+
const closeParen = matchingDelimiter(masked, openParen);
|
|
1153
|
+
const base = closeParen === void 0 ? file : createRequireBase(openParen + 1, closeParen);
|
|
1411
1154
|
recordBoundResolve(match[1], base);
|
|
1412
1155
|
}
|
|
1413
1156
|
for (const match of masked.matchAll(/\b(?:const|let|var)\s*\{([^}]*)\}\s*=\s*([A-Z_$][\w$]*)\b/gi)) {
|
|
@@ -1455,16 +1198,16 @@ function traceComputedModuleSources(file, source, onRuntimePackageRequest) {
|
|
|
1455
1198
|
for (const match of masked.matchAll(/\b([A-Z_$][\w$]*(?:\s*\.\s*createRequire)?)\s*\(/gi)) {
|
|
1456
1199
|
if (!isCreateRequireExpression(match[1])) continue;
|
|
1457
1200
|
const openParen = match.index + match[0].lastIndexOf("(");
|
|
1458
|
-
const closeParen =
|
|
1201
|
+
const closeParen = matchingDelimiter(masked, openParen);
|
|
1459
1202
|
if (closeParen === void 0) continue;
|
|
1460
1203
|
const invocation = /^\s*(?:\.\s*resolve\s*)?\(/i.exec(masked.slice(closeParen + 1));
|
|
1461
1204
|
if (!invocation) continue;
|
|
1462
1205
|
const invocationOpenParen = closeParen + 1 + invocation[0].lastIndexOf("(");
|
|
1463
|
-
const invocationCloseParen =
|
|
1206
|
+
const invocationCloseParen = matchingDelimiter(masked, invocationOpenParen);
|
|
1464
1207
|
if (invocationCloseParen === void 0) continue;
|
|
1465
|
-
const [target] = splitTopLevel(source
|
|
1208
|
+
const [target] = splitTopLevel(source, masked, invocationOpenParen + 1, invocationCloseParen);
|
|
1466
1209
|
const specifier = target ? staticModuleSpecifier(target) : void 0;
|
|
1467
|
-
if (specifier) recordRequest(specifier, /\.\s*resolve/i.test(invocation[0]) ? "require-resolve" : "require-call", createRequireBase(
|
|
1210
|
+
if (specifier) recordRequest(specifier, /\.\s*resolve/i.test(invocation[0]) ? "require-resolve" : "require-call", createRequireBase(openParen + 1, closeParen));
|
|
1468
1211
|
}
|
|
1469
1212
|
for (const match of masked.matchAll(/\b([A-Z_$][\w$]*)\s*\(\s*([A-Z_$][\w$]*)\s*\)/gi)) {
|
|
1470
1213
|
const specifier = bindings.get(match[2]);
|
|
@@ -1560,6 +1303,19 @@ async function traceImportedSources(paths, root, configuredRoots) {
|
|
|
1560
1303
|
platform: "node"
|
|
1561
1304
|
}
|
|
1562
1305
|
];
|
|
1306
|
+
const computedModuleSources = /* @__PURE__ */ new Map();
|
|
1307
|
+
const traceComputedModuleSourcesOnce = (file, source) => {
|
|
1308
|
+
const cached = computedModuleSources.get(file);
|
|
1309
|
+
if (cached?.source === source) return cached;
|
|
1310
|
+
const requests = [];
|
|
1311
|
+
const traced = {
|
|
1312
|
+
paths: traceComputedModuleSources(file, source, (request) => requests.push(request)),
|
|
1313
|
+
requests,
|
|
1314
|
+
source
|
|
1315
|
+
};
|
|
1316
|
+
computedModuleSources.set(file, traced);
|
|
1317
|
+
return traced;
|
|
1318
|
+
};
|
|
1563
1319
|
try {
|
|
1564
1320
|
const importedSources = new Set(entries);
|
|
1565
1321
|
const scannedModuleRequestSources = /* @__PURE__ */ new Set();
|
|
@@ -1656,9 +1412,7 @@ async function traceImportedSources(paths, root, configuredRoots) {
|
|
|
1656
1412
|
const source = await readFile(request.path, "utf8").catch(() => void 0);
|
|
1657
1413
|
if (!source) return void 0;
|
|
1658
1414
|
const runtimeRequests = /* @__PURE__ */ new Map();
|
|
1659
|
-
|
|
1660
|
-
runtimeRequests.set(`${runtimeRequest.kind}\0${runtimeRequest.resolveFrom}\0${runtimeRequest.specifier}`, runtimeRequest);
|
|
1661
|
-
});
|
|
1415
|
+
for (const runtimeRequest of traceComputedModuleSourcesOnce(request.path, source).requests) runtimeRequests.set(`${runtimeRequest.kind}\0${runtimeRequest.resolveFrom}\0${runtimeRequest.specifier}`, runtimeRequest);
|
|
1662
1416
|
await Promise.all([...runtimeRequests.values()].map(async (runtimeRequest) => {
|
|
1663
1417
|
const resolveFrom = runtimeRequest.resolveFrom ?? request.path;
|
|
1664
1418
|
const resolution = await traceBuild.resolve(runtimeRequest.specifier, {
|
|
@@ -1690,7 +1444,7 @@ async function traceImportedSources(paths, root, configuredRoots) {
|
|
|
1690
1444
|
const moduleRequestSourceContents = await Promise.all(moduleRequestSources.map(async (path) => [path, await readFile(path, "utf8")]));
|
|
1691
1445
|
for (const [file, source] of moduleRequestSourceContents) {
|
|
1692
1446
|
scannedModuleRequestSources.add(file);
|
|
1693
|
-
for (const imported of
|
|
1447
|
+
for (const imported of traceComputedModuleSourcesOnce(file, source).paths) {
|
|
1694
1448
|
importedSources.add(imported);
|
|
1695
1449
|
if (traceableSourceExtensions.has(extname(imported)) && !tracedEntries.has(imported) && !pendingEntries.includes(imported)) pendingEntries.push(imported);
|
|
1696
1450
|
}
|
|
@@ -1722,6 +1476,22 @@ function packageMetadataSourcesForPath(root, path) {
|
|
|
1722
1476
|
}
|
|
1723
1477
|
return sources;
|
|
1724
1478
|
}
|
|
1479
|
+
/**
|
|
1480
|
+
* Generated Provider Output can import a package by the physical pnpm store path
|
|
1481
|
+
* that Vite resolved during the source build. Retained source trees do not copy
|
|
1482
|
+
* `node_modules/.pnpm`, so keep only the store package directories that the
|
|
1483
|
+
* traced source graph actually references.
|
|
1484
|
+
*/
|
|
1485
|
+
function pnpmStorePackageRoot(root, source) {
|
|
1486
|
+
const segments = relative(root, source).split(sep);
|
|
1487
|
+
let nodeModulesIndex = -1;
|
|
1488
|
+
for (let index = segments.length - 2; index >= 0; index -= 1) if (segments[index] === "node_modules" && segments[index + 1] === ".pnpm") {
|
|
1489
|
+
nodeModulesIndex = index;
|
|
1490
|
+
break;
|
|
1491
|
+
}
|
|
1492
|
+
if (nodeModulesIndex === -1) return;
|
|
1493
|
+
return segments[nodeModulesIndex + 2] ? resolve(root, ...segments.slice(0, nodeModulesIndex + 3)) : void 0;
|
|
1494
|
+
}
|
|
1725
1495
|
function parseJsonWithComments(source) {
|
|
1726
1496
|
let output = "";
|
|
1727
1497
|
let blockComment = false;
|
|
@@ -1866,7 +1636,7 @@ async function retainProviderOutputSources(options) {
|
|
|
1866
1636
|
const retainedContainer = resolve(artifactDir, String(index));
|
|
1867
1637
|
const retainedRoot = resolve(retainedContainer, relative(captureRoot, root));
|
|
1868
1638
|
retainedRoots.set(root, retainedRoot);
|
|
1869
|
-
const materializedSources = [
|
|
1639
|
+
const materializedSources = [.../* @__PURE__ */ new Set([
|
|
1870
1640
|
...materializedSourcePaths,
|
|
1871
1641
|
...governingPackageMetadata,
|
|
1872
1642
|
...materializedSourcePaths.flatMap((path) => packageMetadataSourcesForPath(captureRoot, path))
|
|
@@ -1950,11 +1720,47 @@ async function retainProviderOutputSources(options) {
|
|
|
1950
1720
|
await cp(stagedContainer, retainedContainer, { recursive: true });
|
|
1951
1721
|
}
|
|
1952
1722
|
const resolveRetainedDependencyTarget = (source) => {
|
|
1953
|
-
if (!pathContains$1(root, source)
|
|
1723
|
+
if (!pathContains$1(root, source)) {
|
|
1724
|
+
const capturedSource = pnpmStorePackageRoot(captureRoot, source) && resolve(retainedContainer, relative(captureRoot, source));
|
|
1725
|
+
return capturedSource && existsSync(capturedSource) ? capturedSource : source;
|
|
1726
|
+
}
|
|
1727
|
+
if (relative(root, source).split(sep).includes("node_modules")) return source;
|
|
1954
1728
|
const retainedSource = resolve(retainedRoot, relative(root, source));
|
|
1955
1729
|
return existsSync(retainedSource) ? retainedSource : source;
|
|
1956
1730
|
};
|
|
1957
1731
|
for (const dependencies of dependencyRoots(root)) await linkDependencies(dependencies, resolve(retainedRoot, "node_modules"), resolveRetainedDependencyTarget);
|
|
1732
|
+
const retainedPnpmPackages = /* @__PURE__ */ new Set();
|
|
1733
|
+
for (const source of materializedSources) {
|
|
1734
|
+
const packageRoot = pnpmStorePackageRoot(root, source);
|
|
1735
|
+
if (packageRoot && pathContains$1(root, packageRoot) && existsSync(packageRoot)) retainedPnpmPackages.add(packageRoot);
|
|
1736
|
+
}
|
|
1737
|
+
await Promise.all([...retainedPnpmPackages].map(async (source) => {
|
|
1738
|
+
const target = resolve(retainedRoot, relative(root, source));
|
|
1739
|
+
let directory = dirname(target);
|
|
1740
|
+
while (pathContains$1(retainedRoot, directory)) {
|
|
1741
|
+
try {
|
|
1742
|
+
if (lstatSync(directory).isSymbolicLink()) await rm(directory, {
|
|
1743
|
+
force: true,
|
|
1744
|
+
recursive: true
|
|
1745
|
+
});
|
|
1746
|
+
} catch (error) {
|
|
1747
|
+
if (error.code !== "ENOENT") throw error;
|
|
1748
|
+
}
|
|
1749
|
+
await mkdir(directory, { recursive: true });
|
|
1750
|
+
if (directory === retainedRoot) break;
|
|
1751
|
+
directory = dirname(directory);
|
|
1752
|
+
}
|
|
1753
|
+
try {
|
|
1754
|
+
if (lstatSync(target).isSymbolicLink()) await rm(target, {
|
|
1755
|
+
force: true,
|
|
1756
|
+
recursive: true
|
|
1757
|
+
});
|
|
1758
|
+
else if (existsSync(target)) return;
|
|
1759
|
+
} catch (error) {
|
|
1760
|
+
if (error.code !== "ENOENT") throw error;
|
|
1761
|
+
}
|
|
1762
|
+
await cp(realpathSync(source), target, { recursive: true });
|
|
1763
|
+
}));
|
|
1958
1764
|
for (const source of escapedMaterializedSources) {
|
|
1959
1765
|
const sourceDirectory = statSync(source).isDirectory() ? source : dirname(source);
|
|
1960
1766
|
for (const dependencies of dependencyRoots(sourceDirectory)) await linkDependencies(dependencies, pathContains$1(captureRoot, dependencies) ? resolve(retainedContainer, relative(captureRoot, dependencies)) : resolve(retainedContainer, "node_modules"), resolveRetainedDependencyTarget);
|
|
@@ -2009,6 +1815,7 @@ function createNodeFunctionConfig(extra = {}) {
|
|
|
2009
1815
|
//#endregion
|
|
2010
1816
|
//#region ../internal/src/build/provider-output-catalog.ts
|
|
2011
1817
|
var ProviderOutputCatalog = class {
|
|
1818
|
+
bundleDefines = {};
|
|
2012
1819
|
#appliedCloudflareContributions = /* @__PURE__ */ new Map();
|
|
2013
1820
|
#cloudflareContributions = /* @__PURE__ */ new Map();
|
|
2014
1821
|
#runtimeContributions = /* @__PURE__ */ new Map();
|
|
@@ -2059,8 +1866,21 @@ var ProviderOutputCatalog = class {
|
|
|
2059
1866
|
runtimeContributions(generation) {
|
|
2060
1867
|
return (generation ? this.#runtimeContributionsByGeneration.get(generation) : this.#runtimeContributions)?.entries() ?? (/* @__PURE__ */ new Map()).entries();
|
|
2061
1868
|
}
|
|
2062
|
-
resetRuntimeContributions() {
|
|
2063
|
-
|
|
1869
|
+
resetRuntimeContributions(generation, owner) {
|
|
1870
|
+
if (generation) {
|
|
1871
|
+
if (owner) this.#runtimeContributionsByGeneration.get(generation)?.delete(owner);
|
|
1872
|
+
else this.#runtimeContributionsByGeneration.delete(generation);
|
|
1873
|
+
return;
|
|
1874
|
+
}
|
|
1875
|
+
if (owner) this.#runtimeContributions.delete(owner);
|
|
1876
|
+
else this.#runtimeContributions.clear();
|
|
1877
|
+
}
|
|
1878
|
+
resetRuntimeContribution(product, generation) {
|
|
1879
|
+
if (!generation) {
|
|
1880
|
+
this.#runtimeContributions.delete(product);
|
|
1881
|
+
return;
|
|
1882
|
+
}
|
|
1883
|
+
this.#runtimeContributionsByGeneration.get(generation)?.delete(product);
|
|
2064
1884
|
}
|
|
2065
1885
|
createDeploymentGeneration() {
|
|
2066
1886
|
const generation = { valid: true };
|
|
@@ -2219,10 +2039,14 @@ const providerOutputCatalog = Symbol.for("vitehub.provider-output-catalog");
|
|
|
2219
2039
|
function createProviderOutputCatalog() {
|
|
2220
2040
|
return new ProviderOutputCatalog();
|
|
2221
2041
|
}
|
|
2042
|
+
function getProviderOutputCatalog(config) {
|
|
2043
|
+
return config[providerOutputCatalog] ?? providerOutputCatalogs.get(config);
|
|
2044
|
+
}
|
|
2222
2045
|
function useProviderOutputCatalog(config) {
|
|
2223
2046
|
const owner = config;
|
|
2224
2047
|
let catalog = owner[providerOutputCatalog] ?? providerOutputCatalogs.get(config);
|
|
2225
2048
|
if (!catalog) catalog = createProviderOutputCatalog();
|
|
2049
|
+
catalog.bundleDefines = resolveViteHubBundleDefines(config);
|
|
2226
2050
|
owner[providerOutputCatalog] = catalog;
|
|
2227
2051
|
providerOutputCatalogs.set(config, catalog);
|
|
2228
2052
|
return catalog;
|
|
@@ -2232,6 +2056,10 @@ function getProviderRuntimeModule(catalog, product, provider, generation) {
|
|
|
2232
2056
|
if (!contribution) return;
|
|
2233
2057
|
return contribution.runtimeModules[provider];
|
|
2234
2058
|
}
|
|
2059
|
+
function getVercelRuntimePackages(catalog, product, generation) {
|
|
2060
|
+
const contribution = catalog?.runtimeContribution(product, generation);
|
|
2061
|
+
return contribution?.owner === "blob" ? contribution.vercelRuntimePackages ?? [] : [];
|
|
2062
|
+
}
|
|
2235
2063
|
//#endregion
|
|
2236
2064
|
//#region ../internal/src/build/vite.ts
|
|
2237
2065
|
async function collectViteHubProviderImportAliases(plugins) {
|
|
@@ -2240,23 +2068,36 @@ async function collectViteHubProviderImportAliases(plugins) {
|
|
|
2240
2068
|
const projectRootDirectoryMarkers = [
|
|
2241
2069
|
["server", "agents"],
|
|
2242
2070
|
["server", "channels"],
|
|
2071
|
+
["server", "connections"],
|
|
2243
2072
|
["server", "browsers"],
|
|
2244
2073
|
["server", "emails"],
|
|
2245
2074
|
["server", "schedules"],
|
|
2246
2075
|
["server", "workspaces"]
|
|
2247
2076
|
];
|
|
2248
|
-
const projectRootFileMarkers = [
|
|
2249
|
-
|
|
2077
|
+
const projectRootFileMarkers = [
|
|
2078
|
+
["package.json"],
|
|
2079
|
+
["nuxt.config.ts"],
|
|
2080
|
+
["nuxt.config.mts"],
|
|
2081
|
+
["nuxt.config.js"],
|
|
2082
|
+
["nuxt.config.mjs"]
|
|
2083
|
+
];
|
|
2084
|
+
function createNoExternalAddition(...packageNames) {
|
|
2250
2085
|
return (current) => {
|
|
2251
|
-
if (current === true) return
|
|
2252
|
-
if (!current) return [packageName];
|
|
2086
|
+
if (current === true) return;
|
|
2253
2087
|
const values = Array.isArray(current) ? current : [current];
|
|
2254
|
-
|
|
2088
|
+
const missing = packageNames.filter((packageName) => !values.includes(packageName));
|
|
2089
|
+
return missing.length ? missing : void 0;
|
|
2255
2090
|
};
|
|
2256
2091
|
}
|
|
2257
2092
|
function isServerEnvironment(name, config) {
|
|
2258
2093
|
return name === "ssr" || config.consumer === "server";
|
|
2259
2094
|
}
|
|
2095
|
+
const VITEHUB_PROJECT_ROOT = "__vitehubProjectRoot";
|
|
2096
|
+
/**
|
|
2097
|
+
* Server directories that ViteHub scans for Definitions. The first entry is the application.
|
|
2098
|
+
* Later entries are Nuxt layers in Nuxt priority order.
|
|
2099
|
+
*/
|
|
2100
|
+
const VITEHUB_SERVER_DIRS = "__vitehubServerDirs";
|
|
2260
2101
|
function includesNitroVitePlugin(value) {
|
|
2261
2102
|
if (Array.isArray(value)) return value.some(includesNitroVitePlugin);
|
|
2262
2103
|
if (!value || typeof value !== "object") return false;
|
|
@@ -2282,7 +2123,12 @@ function resolveViteHubProjectRoot(root, options = {}) {
|
|
|
2282
2123
|
if (options.projectRoot) return resolve(resolvedRoot, options.projectRoot);
|
|
2283
2124
|
if (basename(resolvedRoot) === "app") {
|
|
2284
2125
|
const parent = dirname(resolvedRoot);
|
|
2285
|
-
if (parent !== sharedTemporaryRoot && hasProjectRootDirectoryMarker(parent)
|
|
2126
|
+
if (parent !== sharedTemporaryRoot && (hasProjectRootDirectoryMarker(parent) || hasProjectRootFileMarker(parent, [
|
|
2127
|
+
"nuxt.config.ts",
|
|
2128
|
+
"nuxt.config.mts",
|
|
2129
|
+
"nuxt.config.js",
|
|
2130
|
+
"nuxt.config.mjs"
|
|
2131
|
+
]))) return parent;
|
|
2286
2132
|
}
|
|
2287
2133
|
let current = resolvedRoot;
|
|
2288
2134
|
while (true) {
|
|
@@ -2303,10 +2149,16 @@ function hasProjectRootDirectoryMarker(root) {
|
|
|
2303
2149
|
}
|
|
2304
2150
|
function hasProjectRootMarker(root) {
|
|
2305
2151
|
if (hasProjectRootDirectoryMarker(root)) return true;
|
|
2306
|
-
|
|
2307
|
-
|
|
2308
|
-
|
|
2309
|
-
|
|
2152
|
+
return hasProjectRootFileMarker(root, projectRootFileMarkers.flat());
|
|
2153
|
+
}
|
|
2154
|
+
function hasProjectRootFileMarker(root, markers) {
|
|
2155
|
+
for (const marker of markers) {
|
|
2156
|
+
const path = Array.isArray(marker) ? marker : [marker];
|
|
2157
|
+
try {
|
|
2158
|
+
if (statSync(resolve(root, ...path)).isFile()) return true;
|
|
2159
|
+
} catch (error) {
|
|
2160
|
+
if (error.code !== "ENOENT") throw error;
|
|
2161
|
+
}
|
|
2310
2162
|
}
|
|
2311
2163
|
return false;
|
|
2312
2164
|
}
|
|
@@ -2322,7 +2174,6 @@ const providerDeploymentOutputOwnerOrder = [
|
|
|
2322
2174
|
"database",
|
|
2323
2175
|
"blob",
|
|
2324
2176
|
"queue",
|
|
2325
|
-
"rate-limit",
|
|
2326
2177
|
"schedule",
|
|
2327
2178
|
"workflow",
|
|
2328
2179
|
"vite-hub",
|
|
@@ -2349,13 +2200,13 @@ function createDefaultCloudflareStaticOutputDir(rootDir) {
|
|
|
2349
2200
|
return resolve(rootDir, "dist", "client");
|
|
2350
2201
|
}
|
|
2351
2202
|
function resolveProviderOutputOwnershipFile(outputRoot, fileName) {
|
|
2352
|
-
if (!fileName || fileName.includes("/") || fileName.includes("\\") || fileName === "." || fileName === "..") throw
|
|
2203
|
+
if (!fileName || fileName.includes("/") || fileName.includes("\\") || fileName === "." || fileName === "..") throw internalErrorDiagnostics.INTERNAL_B0034({ message: `Invalid Provider Output ownership file name: ${JSON.stringify(fileName)}` });
|
|
2353
2204
|
return resolve(outputRoot, fileName);
|
|
2354
2205
|
}
|
|
2355
2206
|
async function readProviderOutputOwnershipFile(outputRoot, fileName) {
|
|
2356
2207
|
try {
|
|
2357
2208
|
const parsed = JSON.parse(await readFile(resolveProviderOutputOwnershipFile(outputRoot, fileName), "utf8"));
|
|
2358
|
-
if (!Array.isArray(parsed) || !parsed.every((value) => typeof value === "string")) throw
|
|
2209
|
+
if (!Array.isArray(parsed) || !parsed.every((value) => typeof value === "string")) throw internalErrorDiagnostics.INTERNAL_B0035({ message: `Invalid Provider Output ownership file schema: ${JSON.stringify(fileName)}` });
|
|
2359
2210
|
return parsed;
|
|
2360
2211
|
} catch (error) {
|
|
2361
2212
|
if (error instanceof Error && "code" in error && error.code === "ENOENT") return [];
|
|
@@ -2380,7 +2231,7 @@ async function resolvePersistedProviderOutputOwnership(outputRoot, ownership, fi
|
|
|
2380
2231
|
const arrays = { ...ownership?.arrays };
|
|
2381
2232
|
await Promise.all(Object.entries(files).map(async ([field, fileName]) => {
|
|
2382
2233
|
const current = arrays[field];
|
|
2383
|
-
if (!current) throw
|
|
2234
|
+
if (!current) throw internalErrorDiagnostics.INTERNAL_B0036({ message: `Provider Output ownership file for ${JSON.stringify(field)} requires array ownership.` });
|
|
2384
2235
|
arrays[field] = {
|
|
2385
2236
|
...current,
|
|
2386
2237
|
values: [...await readProviderOutputOwnershipFile(outputRoot, fileName), ...current.values ?? []]
|
|
@@ -2409,8 +2260,14 @@ function createDefaultVercelOutputRoot(rootDir) {
|
|
|
2409
2260
|
function createDefaultNetlifyOutputRoot(rootDir) {
|
|
2410
2261
|
return resolve(rootDir, ".netlify", "v1");
|
|
2411
2262
|
}
|
|
2263
|
+
/** Restore a retained complete publication before generation or transaction snapshots. Call under the output lock. */
|
|
2264
|
+
function recoverNetlifyDeploymentOutput(rootDir) {
|
|
2265
|
+
const outputRoot = createDefaultNetlifyOutputRoot(rootDir);
|
|
2266
|
+
const previousOutputRoot = `${outputRoot}.previous`;
|
|
2267
|
+
if (!existsSync(outputRoot) && existsSync(previousOutputRoot)) renameSync(previousOutputRoot, outputRoot);
|
|
2268
|
+
}
|
|
2412
2269
|
function assertNetlifyFunctionName(functionName) {
|
|
2413
|
-
if (!functionName || functionName.includes("\\") || functionName.split("/").some((part) => !part || part === "." || part === "..")) throw
|
|
2270
|
+
if (!functionName || functionName.includes("\\") || functionName.split("/").some((part) => !part || part === "." || part === "..")) throw internalErrorDiagnostics.INTERNAL_B0037({ message: `Invalid Netlify function name: ${functionName}` });
|
|
2414
2271
|
}
|
|
2415
2272
|
function resolveNetlifyFunctionFile(functionsRoot, functionName) {
|
|
2416
2273
|
assertNetlifyFunctionName(functionName);
|
|
@@ -2418,7 +2275,8 @@ function resolveNetlifyFunctionFile(functionsRoot, functionName) {
|
|
|
2418
2275
|
}
|
|
2419
2276
|
async function appendNetlifyFunctionConfig(outfile, config) {
|
|
2420
2277
|
if (!config) return;
|
|
2421
|
-
|
|
2278
|
+
const bundled = await readFile(outfile, "utf8");
|
|
2279
|
+
await writeFile(outfile, `${bundled.trimEnd()}\n\nexport const config = ${stringifyProviderOutputConfig(config)}\n`, "utf8");
|
|
2422
2280
|
}
|
|
2423
2281
|
async function writeCloudflareDeploymentOutput(options, signal) {
|
|
2424
2282
|
signal?.throwIfAborted();
|
|
@@ -2428,7 +2286,7 @@ async function writeCloudflareDeploymentOutput(options, signal) {
|
|
|
2428
2286
|
const copiesStaticOutput = Boolean(options.bundleEntry && staticIndex && resolve(clientDir) !== resolve(staticOutputDir));
|
|
2429
2287
|
const files = Object.entries(options.files ?? {});
|
|
2430
2288
|
const workerOutfile = options.bundleEntry ? resolve(outputRoot, options.bundleOutfileName ?? "index.js") : void 0;
|
|
2431
|
-
if (workerOutfile && files.some(([fileName]) => resolve(outputRoot, fileName) === workerOutfile)) throw
|
|
2289
|
+
if (workerOutfile && files.some(([fileName]) => resolve(outputRoot, fileName) === workerOutfile)) throw internalErrorDiagnostics.INTERNAL_B0038({ message: `Cloudflare output file conflicts with bundle outfile: ${workerOutfile}` });
|
|
2432
2290
|
const backupRoot = copiesStaticOutput ? await mkdtemp(resolve(options.rootDir, ".vitehub-cloudflare-output-")) : void 0;
|
|
2433
2291
|
const previousOutputRoot = backupRoot ? resolve(backupRoot, "output") : `${outputRoot}.previous`;
|
|
2434
2292
|
const previousStaticOutputDir = backupRoot ? resolve(backupRoot, "static") : `${staticOutputDir}.previous`;
|
|
@@ -2470,7 +2328,7 @@ async function writeCloudflareDeploymentOutput(options, signal) {
|
|
|
2470
2328
|
wranglerConfigDefaults: options.wranglerConfigDefaults,
|
|
2471
2329
|
wranglerConfigOwnership
|
|
2472
2330
|
}),
|
|
2473
|
-
options.bundleEntry && staticIndex ? copyClientOutput(clientDir, staticOutputDir) : Promise.resolve(),
|
|
2331
|
+
options.bundleEntry && staticIndex ? copyClientOutput(clientDir, staticOutputDir, [outputRoot]) : Promise.resolve(),
|
|
2474
2332
|
...files.map(([fileName, contents]) => writeFile(resolve(outputRoot, fileName), contents, "utf8"))
|
|
2475
2333
|
];
|
|
2476
2334
|
if (options.bundleEntry && workerOutfile) {
|
|
@@ -2483,6 +2341,13 @@ async function writeCloudflareDeploymentOutput(options, signal) {
|
|
|
2483
2341
|
});
|
|
2484
2342
|
await bundleEsmEntry(options.bundleEntry, stagedWorkerOutfile, {
|
|
2485
2343
|
...options.bundleOptions,
|
|
2344
|
+
define: {
|
|
2345
|
+
...options.bundleDefines,
|
|
2346
|
+
...options.bundleOptions?.define
|
|
2347
|
+
},
|
|
2348
|
+
minifyIdentifiers: options.bundleOptions?.minifyIdentifiers ?? true,
|
|
2349
|
+
minifySyntax: options.bundleOptions?.minifySyntax ?? true,
|
|
2350
|
+
minifyWhitespace: options.bundleOptions?.minifyWhitespace ?? true,
|
|
2486
2351
|
rootDir: options.sourceRootDir ?? options.rootDir,
|
|
2487
2352
|
signal
|
|
2488
2353
|
});
|
|
@@ -2596,6 +2461,13 @@ async function writeVercelDeploymentOutput(options, signal) {
|
|
|
2596
2461
|
}
|
|
2597
2462
|
await bundleEsmEntry(options.bundleEntry, serverEntry, {
|
|
2598
2463
|
...options.bundleOptions,
|
|
2464
|
+
define: {
|
|
2465
|
+
...options.bundleDefines,
|
|
2466
|
+
...options.bundleOptions?.define
|
|
2467
|
+
},
|
|
2468
|
+
minifyIdentifiers: options.bundleOptions?.minifyIdentifiers ?? true,
|
|
2469
|
+
minifySyntax: options.bundleOptions?.minifySyntax ?? true,
|
|
2470
|
+
minifyWhitespace: options.bundleOptions?.minifyWhitespace ?? true,
|
|
2599
2471
|
rootDir: options.sourceRootDir ?? options.rootDir,
|
|
2600
2472
|
signal
|
|
2601
2473
|
});
|
|
@@ -2703,7 +2575,14 @@ async function writeNetlifyDeploymentOutput(options, signal) {
|
|
|
2703
2575
|
await mkdir(dirname(outfile), { recursive: true });
|
|
2704
2576
|
await bundleEsmEntry(func.bundleEntry, outfile, {
|
|
2705
2577
|
...func.bundleOptions,
|
|
2706
|
-
|
|
2578
|
+
conditions: func.bundleOptions.conditions ?? ["netlify", "node"],
|
|
2579
|
+
define: {
|
|
2580
|
+
...options.bundleDefines,
|
|
2581
|
+
...func.bundleOptions.define
|
|
2582
|
+
},
|
|
2583
|
+
minifyIdentifiers: func.config ? true : func.bundleOptions.minifyIdentifiers ?? true,
|
|
2584
|
+
minifySyntax: func.bundleOptions.minifySyntax ?? true,
|
|
2585
|
+
minifyWhitespace: func.bundleOptions.minifyWhitespace ?? true,
|
|
2707
2586
|
rootDir: options.sourceRootDir ?? options.rootDir,
|
|
2708
2587
|
signal
|
|
2709
2588
|
});
|
|
@@ -2800,19 +2679,22 @@ async function writeProviderDeploymentOutputsNow(options, signal, transaction) {
|
|
|
2800
2679
|
...options.cloudflare,
|
|
2801
2680
|
clientOutDir: options.clientOutDir,
|
|
2802
2681
|
rootDir: options.rootDir,
|
|
2803
|
-
sourceRootDir: options.sourceRootDir
|
|
2682
|
+
sourceRootDir: options.sourceRootDir,
|
|
2683
|
+
bundleDefines: options.bundleDefines
|
|
2804
2684
|
}, signal));
|
|
2805
2685
|
if (options.netlify) writes.push(writeNetlifyDeploymentOutput({
|
|
2806
2686
|
...options.netlify,
|
|
2807
2687
|
clientOutDir: options.clientOutDir,
|
|
2808
2688
|
rootDir: options.rootDir,
|
|
2809
|
-
sourceRootDir: options.sourceRootDir
|
|
2689
|
+
sourceRootDir: options.sourceRootDir,
|
|
2690
|
+
bundleDefines: options.bundleDefines
|
|
2810
2691
|
}, signal));
|
|
2811
2692
|
if (options.vercel) writes.push(writeVercelDeploymentOutput({
|
|
2812
2693
|
...options.vercel,
|
|
2813
2694
|
clientOutDir: options.clientOutDir,
|
|
2814
2695
|
rootDir: options.rootDir,
|
|
2815
|
-
sourceRootDir: options.sourceRootDir
|
|
2696
|
+
sourceRootDir: options.sourceRootDir,
|
|
2697
|
+
bundleDefines: options.bundleDefines
|
|
2816
2698
|
}, signal));
|
|
2817
2699
|
await settleWrites(writes);
|
|
2818
2700
|
if (options.cloudflare && transaction) transaction.cloudflareWritten = true;
|
|
@@ -2923,6 +2805,7 @@ async function restoreProviderDeploymentOutputSnapshot(snapshot) {
|
|
|
2923
2805
|
}
|
|
2924
2806
|
}
|
|
2925
2807
|
async function withProviderDeploymentOutputRootTransaction(rootDir, operation, options = {}) {
|
|
2808
|
+
recoverNetlifyDeploymentOutput(rootDir);
|
|
2926
2809
|
const roots = [
|
|
2927
2810
|
createDefaultCloudflareOutputRoot(rootDir),
|
|
2928
2811
|
createDefaultNetlifyOutputRoot(rootDir),
|
|
@@ -2932,8 +2815,6 @@ async function withProviderDeploymentOutputRootTransaction(rootDir, operation, o
|
|
|
2932
2815
|
resolve(rootDir, ".vitehub/queue/cloudflare-output.json"),
|
|
2933
2816
|
resolve(rootDir, ".vitehub/queue/registry.mjs"),
|
|
2934
2817
|
resolve(rootDir, ".vitehub/queue/vercel-output.json"),
|
|
2935
|
-
resolve(rootDir, ".vitehub/rate-limit/cloudflare-output.json"),
|
|
2936
|
-
resolve(rootDir, ".vitehub/rate-limit/manifest.json"),
|
|
2937
2818
|
resolve(rootDir, ".vitehub/schedule"),
|
|
2938
2819
|
resolve(rootDir, ".vitehub/workflow")
|
|
2939
2820
|
];
|
|
@@ -3110,15 +2991,15 @@ async function resetProviderDeploymentOutputs(catalog, failure, generation) {
|
|
|
3110
2991
|
if (!generation) catalog.resetDeploymentContributions();
|
|
3111
2992
|
if (active && (!generation || active.state.generations.has(generation))) {
|
|
3112
2993
|
active.state.rollback = true;
|
|
3113
|
-
active.controller.abort(
|
|
2994
|
+
active.controller.abort(internalErrorDiagnostics.INTERNAL_B0039({ message: "Provider Output finalization reset" }));
|
|
3114
2995
|
active.reset = {
|
|
3115
|
-
failures: new Set([failure]),
|
|
2996
|
+
failures: /* @__PURE__ */ new Set([failure]),
|
|
3116
2997
|
promise: active.promise.catch(() => void 0)
|
|
3117
2998
|
};
|
|
3118
2999
|
providerDeploymentOutputCompletedResets.set(catalog, active.reset);
|
|
3119
3000
|
await active.reset.promise;
|
|
3120
3001
|
} else if (failure !== void 0) providerDeploymentOutputCompletedResets.set(catalog, {
|
|
3121
|
-
failures: new Set([failure]),
|
|
3002
|
+
failures: /* @__PURE__ */ new Set([failure]),
|
|
3122
3003
|
promise: Promise.resolve()
|
|
3123
3004
|
});
|
|
3124
3005
|
}
|
|
@@ -3142,6 +3023,7 @@ async function finalizeProviderDeploymentOutputs(catalog, options = {}) {
|
|
|
3142
3023
|
if (catalog.hasDeploymentContributions()) await finalizeProviderDeploymentOutputs(catalog, options);
|
|
3143
3024
|
return;
|
|
3144
3025
|
}
|
|
3026
|
+
const bundleDefines = { ...catalog.bundleDefines };
|
|
3145
3027
|
const controller = new AbortController();
|
|
3146
3028
|
const state = {
|
|
3147
3029
|
generations: /* @__PURE__ */ new Set(),
|
|
@@ -3203,7 +3085,13 @@ async function finalizeProviderDeploymentOutputs(catalog, options = {}) {
|
|
|
3203
3085
|
signal: controller.signal,
|
|
3204
3086
|
write: async (writeOptions) => {
|
|
3205
3087
|
throwIfProviderOutputAborted(controller.signal);
|
|
3206
|
-
await writeProviderDeploymentOutputsNow(
|
|
3088
|
+
await writeProviderDeploymentOutputsNow({
|
|
3089
|
+
...writeOptions,
|
|
3090
|
+
bundleDefines: {
|
|
3091
|
+
...bundleDefines,
|
|
3092
|
+
...writeOptions.bundleDefines
|
|
3093
|
+
}
|
|
3094
|
+
}, controller.signal, transaction);
|
|
3207
3095
|
}
|
|
3208
3096
|
});
|
|
3209
3097
|
throwIfProviderOutputAborted(controller.signal);
|
|
@@ -3271,77 +3159,42 @@ async function withProviderDeploymentOutputLock(rootDir, operation) {
|
|
|
3271
3159
|
return await withProviderDeploymentOutputRootLock(rootDir, async () => await withProviderDeploymentOutputRootTransaction(rootDir, async (transaction) => await operation(async (options) => await writeProviderDeploymentOutputsNow(options, void 0, transaction))));
|
|
3272
3160
|
}
|
|
3273
3161
|
//#endregion
|
|
3274
|
-
//#region ../internal/src/
|
|
3275
|
-
function
|
|
3276
|
-
return
|
|
3277
|
-
}
|
|
3278
|
-
|
|
3279
|
-
|
|
3280
|
-
|
|
3281
|
-
|
|
3282
|
-
return
|
|
3283
|
-
}
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
return
|
|
3292
|
-
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
}
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
return;
|
|
3303
|
-
}
|
|
3304
|
-
const files = {};
|
|
3305
|
-
let fileCount = 0;
|
|
3306
|
-
let totalSize = 0;
|
|
3307
|
-
const visit = (directory) => {
|
|
3308
|
-
for (const entry of readdirSync(directory, { withFileTypes: true }).sort((left, right) => left.name.localeCompare(right.name))) {
|
|
3309
|
-
const file = join(directory, entry.name);
|
|
3310
|
-
const target = relative(root, file).replace(/\\/g, "/");
|
|
3311
|
-
if (entry.isDirectory()) {
|
|
3312
|
-
visit(file);
|
|
3313
|
-
continue;
|
|
3314
|
-
}
|
|
3315
|
-
if (!entry.isFile()) {
|
|
3316
|
-
if (options.rejectUnsupportedEntries) throw new Error(`[vitehub] ${options.label || "Colocated Agent files"} supports regular files and directories only: ${target}`);
|
|
3317
|
-
continue;
|
|
3318
|
-
}
|
|
3319
|
-
const size = statSync(file).size;
|
|
3320
|
-
fileCount += 1;
|
|
3321
|
-
if (options.fileCountLimit !== void 0 && fileCount > options.fileCountLimit) throw new Error(`[vitehub] ${options.label || "Colocated Agent files"} exceeds ${options.fileCountLimit} files.`);
|
|
3322
|
-
if (options.fileSizeLimit !== void 0 && size > options.fileSizeLimit) throw new Error(`[vitehub] ${options.label || "Colocated Agent file"} file exceeds ${formatSize(options.fileSizeLimit)}: ${target}`);
|
|
3323
|
-
totalSize += size;
|
|
3324
|
-
if (options.totalSizeLimit !== void 0 && totalSize > options.totalSizeLimit) throw new Error(`[vitehub] ${options.label || "Colocated Agent files"} exceeds ${formatSize(options.totalSizeLimit)}.`);
|
|
3325
|
-
const content = readFileSync(file);
|
|
3326
|
-
if (content.byteLength !== size) {
|
|
3327
|
-
if (options.fileSizeLimit !== void 0 && content.byteLength > options.fileSizeLimit) throw new Error(`[vitehub] ${options.label || "Colocated Agent file"} file exceeds ${formatSize(options.fileSizeLimit)}: ${target}`);
|
|
3328
|
-
totalSize += content.byteLength - size;
|
|
3329
|
-
if (options.totalSizeLimit !== void 0 && totalSize > options.totalSizeLimit) throw new Error(`[vitehub] ${options.label || "Colocated Agent files"} exceeds ${formatSize(options.totalSizeLimit)}.`);
|
|
3330
|
-
}
|
|
3331
|
-
files[target] = {
|
|
3332
|
-
content: content.toString("base64"),
|
|
3333
|
-
encoding: "base64"
|
|
3334
|
-
};
|
|
3162
|
+
//#region ../internal/src/nitro-kit.ts
|
|
3163
|
+
function cloneArray(value) {
|
|
3164
|
+
return Array.isArray(value) ? [...value] : [];
|
|
3165
|
+
}
|
|
3166
|
+
function isRecord(value) {
|
|
3167
|
+
return Object(value) === value && !Array.isArray(value);
|
|
3168
|
+
}
|
|
3169
|
+
function sameHandler(left, right) {
|
|
3170
|
+
return left.handler === right.handler && left.route === right.route && left.method === right.method && left.middleware === right.middleware;
|
|
3171
|
+
}
|
|
3172
|
+
/** Create a Nitro 3 configuration builder for generated ViteHub output. */
|
|
3173
|
+
function createNitroServerKit(value = {}) {
|
|
3174
|
+
const config = isRecord(value) ? { ...value } : {};
|
|
3175
|
+
const handlers = cloneArray(config.handlers);
|
|
3176
|
+
const plugins = cloneArray(config.plugins);
|
|
3177
|
+
config.handlers = handlers;
|
|
3178
|
+
config.plugins = plugins;
|
|
3179
|
+
return {
|
|
3180
|
+
config,
|
|
3181
|
+
addHandler(handler, position = "end") {
|
|
3182
|
+
if (handlers.some((candidate) => isRecord(candidate) && sameHandler(candidate, handler))) return;
|
|
3183
|
+
if (position === "start") handlers.unshift({ ...handler });
|
|
3184
|
+
else handlers.push({ ...handler });
|
|
3185
|
+
},
|
|
3186
|
+
addPlugin(plugin, position = "end") {
|
|
3187
|
+
if (plugins.includes(plugin)) return;
|
|
3188
|
+
if (position === "start") plugins.unshift(plugin);
|
|
3189
|
+
else plugins.push(plugin);
|
|
3335
3190
|
}
|
|
3336
3191
|
};
|
|
3337
|
-
visit(root);
|
|
3338
|
-
return Object.keys(files).length ? files : void 0;
|
|
3339
3192
|
}
|
|
3340
3193
|
//#endregion
|
|
3341
3194
|
//#region ../internal/src/definition-catalog.ts
|
|
3342
3195
|
const sourceFilePattern$1 = /\.(?:c|m)?[jt]sx?$/i;
|
|
3343
3196
|
const declarationFilePattern$1 = /\.d\.(?:c|m)?[jt]sx?$/i;
|
|
3344
|
-
const ignoredDirs = new Set([
|
|
3197
|
+
const ignoredDirs = /* @__PURE__ */ new Set([
|
|
3345
3198
|
"node_modules",
|
|
3346
3199
|
"dist",
|
|
3347
3200
|
".output",
|
|
@@ -3415,7 +3268,7 @@ function sortDefinitions(definitions) {
|
|
|
3415
3268
|
}
|
|
3416
3269
|
function registerDefinition(definitions, definition, sourceLabel) {
|
|
3417
3270
|
const existing = definitions.get(definition.name);
|
|
3418
|
-
if (existing) throw
|
|
3271
|
+
if (existing) throw internalErrorDiagnostics.INTERNAL_C0001({ message: `Duplicate ${sourceLabel} name "${definition.name}":\n - ${existing.handler}\n - ${definition.handler}` });
|
|
3419
3272
|
definitions.set(definition.name, definition);
|
|
3420
3273
|
}
|
|
3421
3274
|
function mergeDefinitions(feature, ...sources) {
|
|
@@ -3424,7 +3277,7 @@ function mergeDefinitions(feature, ...sources) {
|
|
|
3424
3277
|
if (!source) continue;
|
|
3425
3278
|
for (const definition of source) {
|
|
3426
3279
|
const existing = definitions.get(definition.name);
|
|
3427
|
-
if (existing && existing.handler !== definition.handler) throw
|
|
3280
|
+
if (existing && existing.handler !== definition.handler) throw internalErrorDiagnostics.INTERNAL_C0002({ message: `Duplicate ${feature} name "${definition.name}" from multiple discovery sources:\n - ${existing.handler} (${existing.source ?? "unknown"})\n - ${definition.handler} (${definition.source ?? "unknown"})` });
|
|
3428
3281
|
if (!existing) definitions.set(definition.name, definition);
|
|
3429
3282
|
}
|
|
3430
3283
|
}
|
|
@@ -3443,7 +3296,10 @@ function createDefinition(source, file, name) {
|
|
|
3443
3296
|
}
|
|
3444
3297
|
function scanSuffixDefinitions(feature, source) {
|
|
3445
3298
|
const definitions = /* @__PURE__ */ new Map();
|
|
3446
|
-
for (const root of source.roots) for (const file of listMatchingFiles(root, (name) =>
|
|
3299
|
+
for (const root of source.roots) for (const file of listMatchingFiles(root, (name) => {
|
|
3300
|
+
source.pattern.lastIndex = 0;
|
|
3301
|
+
return source.pattern.test(name);
|
|
3302
|
+
}, { includeHidden: source.includeHidden })) {
|
|
3447
3303
|
const name = source.normalizeName(root, file);
|
|
3448
3304
|
if (!name) continue;
|
|
3449
3305
|
registerDefinition(definitions, createDefinition(source, file, name), feature);
|
|
@@ -3515,7 +3371,7 @@ function findDefineAgentObjectStart(masked, start) {
|
|
|
3515
3371
|
}
|
|
3516
3372
|
}
|
|
3517
3373
|
function agentFactoryNames(source) {
|
|
3518
|
-
const names = new Set(["defineAgent"]);
|
|
3374
|
+
const names = /* @__PURE__ */ new Set(["defineAgent"]);
|
|
3519
3375
|
for (const match of source.matchAll(/\bimport\s*\{([^}]+)\}\s*from\s*["']@vite-hub\/agent["']/g)) for (const specifier of match[1].split(",")) {
|
|
3520
3376
|
const alias = /^\s*defineAgent\s+as\s+([A-Za-z_$][\w$]*)\s*$/.exec(specifier)?.[1];
|
|
3521
3377
|
if (alias) names.add(alias);
|
|
@@ -3565,6 +3421,9 @@ function resolveAgentReExport(file, source, masked) {
|
|
|
3565
3421
|
...extensions.map((extension) => resolve$1(target, `index${extension}`))
|
|
3566
3422
|
]) if (existsSync(candidate) && statSync(candidate).isFile()) return candidate;
|
|
3567
3423
|
}
|
|
3424
|
+
function maskSourceLiterals(source, file) {
|
|
3425
|
+
return maskLiterals(scanModule(source, file));
|
|
3426
|
+
}
|
|
3568
3427
|
function isFolderAgentImplementationTarget(file) {
|
|
3569
3428
|
const fileName = normalize(file).split("/").pop();
|
|
3570
3429
|
if (/^definition\.(?:c|m)?[jt]s$/i.test(fileName)) return true;
|
|
@@ -3574,7 +3433,7 @@ function extractAgentRuntime(file, seen = /* @__PURE__ */ new Set()) {
|
|
|
3574
3433
|
if (seen.has(file)) return void 0;
|
|
3575
3434
|
seen.add(file);
|
|
3576
3435
|
const source = readFileSync(file, "utf8");
|
|
3577
|
-
const masked = maskSourceLiterals(source);
|
|
3436
|
+
const masked = maskSourceLiterals(source, file);
|
|
3578
3437
|
const start = findAgentObjectStart(source, masked);
|
|
3579
3438
|
if (start === void 0) {
|
|
3580
3439
|
const target = resolveAgentReExport(file, source, masked);
|
|
@@ -3617,7 +3476,7 @@ function extractAgentWorkflowName(file, fallbackName) {
|
|
|
3617
3476
|
const shorthand = /^([A-Za-z_$][\w$]*)$/.exec(runtime.masked || "")?.[1];
|
|
3618
3477
|
if (shorthand) {
|
|
3619
3478
|
const source = readFileSync(file, "utf8");
|
|
3620
|
-
const masked = maskSourceLiterals(source);
|
|
3479
|
+
const masked = maskSourceLiterals(source, file);
|
|
3621
3480
|
const declaration = new RegExp(`\\b(?:const|let|var)\\s+${shorthand}\\s*(?::(?:=>|[^=])*?)?=\\s*`).exec(masked);
|
|
3622
3481
|
if (declaration) {
|
|
3623
3482
|
const start = declaration.index + declaration[0].length;
|
|
@@ -3693,7 +3552,7 @@ function discoverFlatServerAgentWorkflowDefinitions(scanDirs) {
|
|
|
3693
3552
|
const folderAgentDirs = new Set(folderAgentFiles.map((file) => normalize(resolve$1(file, ".."))));
|
|
3694
3553
|
const folderAgentTargets = new Set(folderAgentFiles.flatMap((file) => {
|
|
3695
3554
|
const source = readFileSync(file, "utf8");
|
|
3696
|
-
const target = resolveAgentReExport(file, source, maskSourceLiterals(source));
|
|
3555
|
+
const target = resolveAgentReExport(file, source, maskSourceLiterals(source, file));
|
|
3697
3556
|
const relativeTarget = target && normalize(relative(resolve$1(file, ".."), target));
|
|
3698
3557
|
return target && relativeTarget && relativeTarget !== ".." && !relativeTarget.startsWith("../") && isFolderAgentImplementationTarget(target) ? [normalize(target)] : [];
|
|
3699
3558
|
}));
|
|
@@ -3729,7 +3588,7 @@ function discoverConfiguredServerAgentWorkflowDefinitions(scanDirs) {
|
|
|
3729
3588
|
const files = findFolderAgentFiles(agentsDir);
|
|
3730
3589
|
const targets = new Set(files.flatMap((file) => {
|
|
3731
3590
|
const source = readFileSync(file, "utf8");
|
|
3732
|
-
const target = resolveAgentReExport(file, source, maskSourceLiterals(source));
|
|
3591
|
+
const target = resolveAgentReExport(file, source, maskSourceLiterals(source, file));
|
|
3733
3592
|
const relativeTarget = target && normalize(relative(resolve$1(file, ".."), target));
|
|
3734
3593
|
return target && relativeTarget && relativeTarget !== ".." && !relativeTarget.startsWith("../") ? [normalize(target)] : [];
|
|
3735
3594
|
}));
|
|
@@ -3795,7 +3654,381 @@ function discoverWorkflowDefinitions(options) {
|
|
|
3795
3654
|
}) })]), discoverFlatServerWorkflowDefinitions(serverScanDirs, "server-workflows"), folderDefinitions, discoverAgentWorkflowDefinitions(roots, serverScanDirs));
|
|
3796
3655
|
}
|
|
3797
3656
|
//#endregion
|
|
3657
|
+
//#region src/inspect.ts
|
|
3658
|
+
function summarizeWorkflowDefinition(projectRoot, definition) {
|
|
3659
|
+
return {
|
|
3660
|
+
fields: [...definition.agentIdentity ? [{
|
|
3661
|
+
label: "Agent identity",
|
|
3662
|
+
value: definition.agentIdentity
|
|
3663
|
+
}] : [], ...definition.steps?.length ? [{
|
|
3664
|
+
label: "Steps",
|
|
3665
|
+
value: definition.steps.map((step) => relativeDefinitionFile(projectRoot, step)).join(", ")
|
|
3666
|
+
}] : []],
|
|
3667
|
+
file: relativeDefinitionFile(projectRoot, definition.handler),
|
|
3668
|
+
name: definition.name,
|
|
3669
|
+
source: definition.source || "workflow"
|
|
3670
|
+
};
|
|
3671
|
+
}
|
|
3672
|
+
/** Lists user-facing Workflow Definitions. Generated Agent recovery Workflows are internal and stay hidden. */
|
|
3673
|
+
function inspectWorkflowDefinitions(options) {
|
|
3674
|
+
return discoverWorkflowDefinitions({
|
|
3675
|
+
rootDir: options.rootDir,
|
|
3676
|
+
serverDirs: options.serverDirs
|
|
3677
|
+
}).filter((definition) => definition.source !== "agent-workflow-recovery").map((definition) => summarizeWorkflowDefinition(options.projectRoot, definition));
|
|
3678
|
+
}
|
|
3679
|
+
/** Console section that lists discovered Workflow Definitions. `vitehub inspect definitions` reads the same data. */
|
|
3680
|
+
const workflowConsoleSection = {
|
|
3681
|
+
description: "Inspect discovered Workflow Definitions and their source metadata.",
|
|
3682
|
+
icon: "i-lucide-git-branch",
|
|
3683
|
+
id: "workflows",
|
|
3684
|
+
label: "Workflows",
|
|
3685
|
+
read: inspectWorkflowDefinitions,
|
|
3686
|
+
view: {
|
|
3687
|
+
kind: "definition-catalog",
|
|
3688
|
+
notice: "Workflow run history is not exposed by ViteHub's provider-independent Workflow contract yet."
|
|
3689
|
+
}
|
|
3690
|
+
};
|
|
3691
|
+
//#endregion
|
|
3692
|
+
//#region ../internal/src/agent-workflow.ts
|
|
3693
|
+
function getAgentInvocationRecoveryWorkflowName(agentWorkflowName) {
|
|
3694
|
+
return `vitehub-agent-invocation-recovery-${agentWorkflowName}`;
|
|
3695
|
+
}
|
|
3696
|
+
//#endregion
|
|
3697
|
+
//#region ../internal/src/build/colocated-agent-files.ts
|
|
3698
|
+
function formatSize(bytes) {
|
|
3699
|
+
const mebibyte = 1048576;
|
|
3700
|
+
return bytes % mebibyte === 0 ? `${bytes / mebibyte} MiB` : `${bytes} bytes`;
|
|
3701
|
+
}
|
|
3702
|
+
function isFolderAgentEntry(file) {
|
|
3703
|
+
if (!/^(?:agent|index)\.(?:c|m)?[jt]s$/i.test(basename(file))) return false;
|
|
3704
|
+
return !(basename(file).toLowerCase().startsWith("agent.") && basename(dirname(file)) === "agents" && basename(dirname(dirname(file))) === "server");
|
|
3705
|
+
}
|
|
3706
|
+
function colocatedAgentFilesRoot(handler, directoryName) {
|
|
3707
|
+
if (!isFolderAgentEntry(handler)) return;
|
|
3708
|
+
const root = join(dirname(handler), directoryName);
|
|
3709
|
+
return existsSync(root) ? root : void 0;
|
|
3710
|
+
}
|
|
3711
|
+
function resolveColocatedAgentFilesRoot(handler, directoryName) {
|
|
3712
|
+
const root = colocatedAgentFilesRoot(handler, directoryName);
|
|
3713
|
+
return root && statSync(root).isDirectory() ? root : void 0;
|
|
3714
|
+
}
|
|
3715
|
+
function readColocatedAgentFiles(handler, directoryName, options = {}) {
|
|
3716
|
+
const root = colocatedAgentFilesRoot(handler, directoryName);
|
|
3717
|
+
if (!root) return;
|
|
3718
|
+
if (!(options.rejectUnsupportedEntries ? lstatSync(root) : statSync(root)).isDirectory()) {
|
|
3719
|
+
if (options.rejectUnsupportedEntries) throw internalErrorDiagnostics.INTERNAL_B0002({ message: `[vitehub] ${options.label || "Colocated Agent files"} supports regular files and directories only: ${directoryName}` });
|
|
3720
|
+
return;
|
|
3721
|
+
}
|
|
3722
|
+
const files = {};
|
|
3723
|
+
let fileCount = 0;
|
|
3724
|
+
let totalSize = 0;
|
|
3725
|
+
const visit = (directory) => {
|
|
3726
|
+
for (const entry of readdirSync(directory, { withFileTypes: true }).sort((left, right) => left.name.localeCompare(right.name))) {
|
|
3727
|
+
const file = join(directory, entry.name);
|
|
3728
|
+
const target = relative(root, file).replace(/\\/g, "/");
|
|
3729
|
+
if (entry.isDirectory()) {
|
|
3730
|
+
visit(file);
|
|
3731
|
+
continue;
|
|
3732
|
+
}
|
|
3733
|
+
if (!entry.isFile()) {
|
|
3734
|
+
if (options.rejectUnsupportedEntries) throw internalErrorDiagnostics.INTERNAL_B0003({ message: `[vitehub] ${options.label || "Colocated Agent files"} supports regular files and directories only: ${target}` });
|
|
3735
|
+
continue;
|
|
3736
|
+
}
|
|
3737
|
+
const size = statSync(file).size;
|
|
3738
|
+
fileCount += 1;
|
|
3739
|
+
if (options.fileCountLimit !== void 0 && fileCount > options.fileCountLimit) throw internalErrorDiagnostics.INTERNAL_B0004({ message: `[vitehub] ${options.label || "Colocated Agent files"} exceeds ${options.fileCountLimit} files.` });
|
|
3740
|
+
if (options.fileSizeLimit !== void 0 && size > options.fileSizeLimit) throw internalErrorDiagnostics.INTERNAL_B0005({ message: `[vitehub] ${options.label || "Colocated Agent file"} file exceeds ${formatSize(options.fileSizeLimit)}: ${target}` });
|
|
3741
|
+
totalSize += size;
|
|
3742
|
+
if (options.totalSizeLimit !== void 0 && totalSize > options.totalSizeLimit) throw internalErrorDiagnostics.INTERNAL_B0006({ message: `[vitehub] ${options.label || "Colocated Agent files"} exceeds ${formatSize(options.totalSizeLimit)}.` });
|
|
3743
|
+
const content = readFileSync(file);
|
|
3744
|
+
if (content.byteLength !== size) {
|
|
3745
|
+
if (options.fileSizeLimit !== void 0 && content.byteLength > options.fileSizeLimit) throw internalErrorDiagnostics.INTERNAL_B0007({ message: `[vitehub] ${options.label || "Colocated Agent file"} file exceeds ${formatSize(options.fileSizeLimit)}: ${target}` });
|
|
3746
|
+
totalSize += content.byteLength - size;
|
|
3747
|
+
if (options.totalSizeLimit !== void 0 && totalSize > options.totalSizeLimit) throw internalErrorDiagnostics.INTERNAL_B0008({ message: `[vitehub] ${options.label || "Colocated Agent files"} exceeds ${formatSize(options.totalSizeLimit)}.` });
|
|
3748
|
+
}
|
|
3749
|
+
files[target] = {
|
|
3750
|
+
content: content.toString("base64"),
|
|
3751
|
+
encoding: "base64"
|
|
3752
|
+
};
|
|
3753
|
+
}
|
|
3754
|
+
};
|
|
3755
|
+
visit(root);
|
|
3756
|
+
return Object.keys(files).length ? files : void 0;
|
|
3757
|
+
}
|
|
3758
|
+
//#endregion
|
|
3759
|
+
//#region ../internal/src/build/runtime-package-resolution.ts
|
|
3760
|
+
/** Locates package metadata through exports, an entry's ancestors, or the project's dependency roots. */
|
|
3761
|
+
function createRuntimePackageResolver(readPackageName) {
|
|
3762
|
+
return async (name, resolver, fromDir) => {
|
|
3763
|
+
try {
|
|
3764
|
+
return resolver.resolve(`${name}/package.json`);
|
|
3765
|
+
} catch (error) {
|
|
3766
|
+
if (!isPackageResolutionMiss(error)) throw error;
|
|
3767
|
+
}
|
|
3768
|
+
try {
|
|
3769
|
+
let current = dirname(resolver.resolve(name));
|
|
3770
|
+
while (current !== dirname(current)) {
|
|
3771
|
+
const candidate = join(current, "package.json");
|
|
3772
|
+
try {
|
|
3773
|
+
await access(candidate);
|
|
3774
|
+
if (readPackageName(await readFile(candidate, "utf8"), candidate) === name) return candidate;
|
|
3775
|
+
} catch (error) {
|
|
3776
|
+
if (error.code !== "ENOENT") throw error;
|
|
3777
|
+
}
|
|
3778
|
+
current = dirname(current);
|
|
3779
|
+
}
|
|
3780
|
+
} catch (error) {
|
|
3781
|
+
if (!isPackageResolutionMiss(error)) throw error;
|
|
3782
|
+
}
|
|
3783
|
+
let current = fromDir;
|
|
3784
|
+
while (current !== dirname(current)) {
|
|
3785
|
+
const candidate = join(current, "node_modules", ...name.split("/"), "package.json");
|
|
3786
|
+
try {
|
|
3787
|
+
await access(candidate);
|
|
3788
|
+
return candidate;
|
|
3789
|
+
} catch (error) {
|
|
3790
|
+
if (error.code !== "ENOENT") throw error;
|
|
3791
|
+
}
|
|
3792
|
+
current = dirname(current);
|
|
3793
|
+
}
|
|
3794
|
+
};
|
|
3795
|
+
}
|
|
3796
|
+
function isPackageResolutionMiss(error) {
|
|
3797
|
+
const code = error?.code;
|
|
3798
|
+
return code === "MODULE_NOT_FOUND" || code === "ERR_MODULE_NOT_FOUND" || code === "ERR_PACKAGE_PATH_NOT_EXPORTED";
|
|
3799
|
+
}
|
|
3800
|
+
//#endregion
|
|
3801
|
+
//#region ../internal/src/build/runtime-package-directory.ts
|
|
3802
|
+
/** Update a staged copy, then publish it with rollback on failure or cancellation. */
|
|
3803
|
+
async function updateRuntimePackageDirectory(options) {
|
|
3804
|
+
const stagingRoot = await mkdtemp(join(dirname(options.directory), ".vitehub-runtime-packages-"));
|
|
3805
|
+
const stagedDirectory = join(stagingRoot, "node_modules");
|
|
3806
|
+
const previousDirectory = join(stagingRoot, "previous-node_modules");
|
|
3807
|
+
let movedPreviousOutput = false;
|
|
3808
|
+
let installedReplacement = false;
|
|
3809
|
+
let cleanupStagingRoot = true;
|
|
3810
|
+
try {
|
|
3811
|
+
try {
|
|
3812
|
+
await cp(options.directory, stagedDirectory, { recursive: true });
|
|
3813
|
+
} catch (error) {
|
|
3814
|
+
if (error.code !== "ENOENT") throw error;
|
|
3815
|
+
}
|
|
3816
|
+
await mkdir(stagedDirectory, { recursive: true });
|
|
3817
|
+
await options.update(stagedDirectory);
|
|
3818
|
+
options.signal?.throwIfAborted();
|
|
3819
|
+
try {
|
|
3820
|
+
await rename(options.directory, previousDirectory);
|
|
3821
|
+
movedPreviousOutput = true;
|
|
3822
|
+
cleanupStagingRoot = false;
|
|
3823
|
+
} catch (error) {
|
|
3824
|
+
if (error.code !== "ENOENT") throw error;
|
|
3825
|
+
}
|
|
3826
|
+
try {
|
|
3827
|
+
options.signal?.throwIfAborted();
|
|
3828
|
+
await rename(stagedDirectory, options.directory);
|
|
3829
|
+
installedReplacement = true;
|
|
3830
|
+
options.signal?.throwIfAborted();
|
|
3831
|
+
cleanupStagingRoot = true;
|
|
3832
|
+
} catch (error) {
|
|
3833
|
+
if (installedReplacement) await rm(options.directory, {
|
|
3834
|
+
force: true,
|
|
3835
|
+
recursive: true
|
|
3836
|
+
});
|
|
3837
|
+
if (movedPreviousOutput) await rename(previousDirectory, options.directory);
|
|
3838
|
+
cleanupStagingRoot = true;
|
|
3839
|
+
throw error;
|
|
3840
|
+
}
|
|
3841
|
+
} finally {
|
|
3842
|
+
if (cleanupStagingRoot) await rm(stagingRoot, {
|
|
3843
|
+
force: true,
|
|
3844
|
+
recursive: true
|
|
3845
|
+
});
|
|
3846
|
+
}
|
|
3847
|
+
}
|
|
3848
|
+
//#endregion
|
|
3849
|
+
//#region ../internal/src/build/vercel-runtime-packages.ts
|
|
3850
|
+
const runtimeExportConditions = /* @__PURE__ */ new Set([
|
|
3851
|
+
"default",
|
|
3852
|
+
"import",
|
|
3853
|
+
"module",
|
|
3854
|
+
"node",
|
|
3855
|
+
"node-addons",
|
|
3856
|
+
"require"
|
|
3857
|
+
]);
|
|
3858
|
+
const resolvePackageJson = createRuntimePackageResolver((source, path) => parsePackageJson(JSON.parse(source), path).name);
|
|
3859
|
+
let nodeFileTracePromise;
|
|
3860
|
+
async function copyVercelFunctionRuntimePackages(options) {
|
|
3861
|
+
const outputRoot = options.outputRoot ?? createDefaultVercelOutputRoot(options.rootDir);
|
|
3862
|
+
const serverFunctionName = options.serverFunctionName ?? "__server.func";
|
|
3863
|
+
const serverDir = resolve(outputRoot, "functions", serverFunctionName);
|
|
3864
|
+
try {
|
|
3865
|
+
await access(serverDir);
|
|
3866
|
+
} catch (error) {
|
|
3867
|
+
if (error.code === "ENOENT") return;
|
|
3868
|
+
throw error;
|
|
3869
|
+
}
|
|
3870
|
+
const packages = Array.isArray(options.packages) ? options.packages : await options.packages();
|
|
3871
|
+
if (!packages.length) return;
|
|
3872
|
+
await updateRuntimePackageDirectory({
|
|
3873
|
+
directory: resolve(serverDir, "node_modules"),
|
|
3874
|
+
signal: options.signal,
|
|
3875
|
+
update: (outputNodeModules) => copyNodeRuntimePackages({
|
|
3876
|
+
outputNodeModules,
|
|
3877
|
+
packages,
|
|
3878
|
+
rootDir: options.rootDir
|
|
3879
|
+
})
|
|
3880
|
+
});
|
|
3881
|
+
}
|
|
3882
|
+
async function copyNodeRuntimePackages(options) {
|
|
3883
|
+
if (!options.packages.length) return;
|
|
3884
|
+
const copied = /* @__PURE__ */ new Set();
|
|
3885
|
+
const expanded = /* @__PURE__ */ new Set();
|
|
3886
|
+
for (const runtimePackage of options.packages) {
|
|
3887
|
+
const resolveFrom = runtimePackage.resolveFrom ?? join(options.rootDir, "package.json");
|
|
3888
|
+
const resolver = createRequire(resolveFrom);
|
|
3889
|
+
await copyPackageToNodeModules(runtimePackage.name, resolver, dirname(resolveFrom), options.outputNodeModules, copied, expanded, runtimePackage);
|
|
3890
|
+
}
|
|
3891
|
+
}
|
|
3892
|
+
async function copyPackageToNodeModules(name, resolver, fromDir, outputNodeModules, copied, expanded, options = { name }) {
|
|
3893
|
+
const packageJsonPath = await resolvePackageJson(name, resolver, fromDir);
|
|
3894
|
+
if (!packageJsonPath) {
|
|
3895
|
+
if (options.optional) return;
|
|
3896
|
+
throw internalErrorDiagnostics.INTERNAL_B0046({ message: `Could not resolve package.json for ${name}.` });
|
|
3897
|
+
}
|
|
3898
|
+
const resolvedPackageJsonPath = await realpath(packageJsonPath);
|
|
3899
|
+
const packageDir = dirname(resolvedPackageJsonPath);
|
|
3900
|
+
const packageJson = parsePackageJson(JSON.parse(await readFile(resolvedPackageJsonPath, "utf8")), resolvedPackageJsonPath);
|
|
3901
|
+
const packageKey = `${name}\0${resolvedPackageJsonPath}`;
|
|
3902
|
+
if (!copied.has(packageKey)) {
|
|
3903
|
+
copied.add(packageKey);
|
|
3904
|
+
const targetDir = join(outputNodeModules, ...name.split("/"));
|
|
3905
|
+
await rm(targetDir, {
|
|
3906
|
+
force: true,
|
|
3907
|
+
recursive: true
|
|
3908
|
+
});
|
|
3909
|
+
if (!await copyTracedPackageFiles(name, resolver, packageDir, resolvedPackageJsonPath, packageJson, targetDir)) await copyPackageDirectory(packageDir, targetDir);
|
|
3910
|
+
}
|
|
3911
|
+
const expansionKey = `${packageKey}\0${options.includePeerDependencies ? "peers" : "dependencies"}`;
|
|
3912
|
+
if (expanded.has(expansionKey)) return;
|
|
3913
|
+
expanded.add(expansionKey);
|
|
3914
|
+
const packageRequire = createRequire(resolvedPackageJsonPath);
|
|
3915
|
+
const dependencyNames = new Set(Object.keys(packageJson.dependencies || {}));
|
|
3916
|
+
const optionalDependencyNames = new Set(Object.keys(packageJson.optionalDependencies || {}));
|
|
3917
|
+
for (const dependencyName of optionalDependencyNames) dependencyNames.add(dependencyName);
|
|
3918
|
+
const requiredPeerDependencyNames = /* @__PURE__ */ new Set();
|
|
3919
|
+
if (options.includePeerDependencies) {
|
|
3920
|
+
for (const dependencyName of Object.keys(packageJson.peerDependencies || {})) if (!packageJson.peerDependenciesMeta?.[dependencyName]?.optional) {
|
|
3921
|
+
dependencyNames.add(dependencyName);
|
|
3922
|
+
requiredPeerDependencyNames.add(dependencyName);
|
|
3923
|
+
}
|
|
3924
|
+
}
|
|
3925
|
+
for (const dependencyName of dependencyNames) await copyPackageToNodeModules(dependencyName, packageRequire, packageDir, outputNodeModules, copied, expanded, {
|
|
3926
|
+
includePeerDependencies: options.includePeerDependencies,
|
|
3927
|
+
name: dependencyName,
|
|
3928
|
+
optional: optionalDependencyNames.has(dependencyName) && !requiredPeerDependencyNames.has(dependencyName)
|
|
3929
|
+
});
|
|
3930
|
+
}
|
|
3931
|
+
async function copyTracedPackageFiles(name, resolver, packageDir, packageJsonPath, packageJson, targetDir) {
|
|
3932
|
+
const entries = await resolvePackageTraceEntries(name, resolver, packageDir, packageJson);
|
|
3933
|
+
if (!entries) return false;
|
|
3934
|
+
const { fileList } = await (await loadNodeFileTrace())([...entries], {
|
|
3935
|
+
base: packageDir,
|
|
3936
|
+
conditions: ["node"],
|
|
3937
|
+
exportsOnly: true,
|
|
3938
|
+
processCwd: packageDir
|
|
3939
|
+
});
|
|
3940
|
+
fileList.add(relative(packageDir, packageJsonPath));
|
|
3941
|
+
for (const file of fileList) {
|
|
3942
|
+
const source = resolve(packageDir, file);
|
|
3943
|
+
if (!isInsideDirectory(packageDir, source) || hasNodeModulesSegment(file)) continue;
|
|
3944
|
+
if (!(await stat(source)).isFile()) continue;
|
|
3945
|
+
const target = resolve(targetDir, file);
|
|
3946
|
+
await mkdir(dirname(target), { recursive: true });
|
|
3947
|
+
await copyFile(source, target);
|
|
3948
|
+
}
|
|
3949
|
+
return true;
|
|
3950
|
+
}
|
|
3951
|
+
async function copyPackageDirectory(packageDir, targetDir) {
|
|
3952
|
+
await mkdir(dirname(targetDir), { recursive: true });
|
|
3953
|
+
await cp(packageDir, targetDir, {
|
|
3954
|
+
dereference: true,
|
|
3955
|
+
filter: (source) => !hasNodeModulesSegment(relative(packageDir, source)),
|
|
3956
|
+
recursive: true
|
|
3957
|
+
});
|
|
3958
|
+
}
|
|
3959
|
+
async function loadNodeFileTrace() {
|
|
3960
|
+
nodeFileTracePromise ??= import("./out-CsaJxg8m.js").then((m) => /* @__PURE__ */ __toESM(m.default, 1)).then(({ nodeFileTrace }) => nodeFileTrace);
|
|
3961
|
+
return nodeFileTracePromise;
|
|
3962
|
+
}
|
|
3963
|
+
async function resolvePackageTraceEntries(name, resolver, packageDir, packageJson) {
|
|
3964
|
+
const entryCandidates = /* @__PURE__ */ new Set();
|
|
3965
|
+
if (packageJson.exports) {
|
|
3966
|
+
const exportedTargets = collectRuntimeExportTargets(packageJson.exports);
|
|
3967
|
+
if (!exportedTargets) return void 0;
|
|
3968
|
+
for (const target of exportedTargets) entryCandidates.add(resolve(packageDir, target));
|
|
3969
|
+
} else {
|
|
3970
|
+
try {
|
|
3971
|
+
entryCandidates.add(resolver.resolve(name));
|
|
3972
|
+
} catch (error) {
|
|
3973
|
+
if (!isPackageResolutionMiss(error)) throw error;
|
|
3974
|
+
}
|
|
3975
|
+
if (packageJson.main) entryCandidates.add(resolve(packageDir, packageJson.main));
|
|
3976
|
+
if (packageJson.module) entryCandidates.add(resolve(packageDir, packageJson.module));
|
|
3977
|
+
entryCandidates.add(resolve(packageDir, "index.js"));
|
|
3978
|
+
}
|
|
3979
|
+
const entries = [];
|
|
3980
|
+
for (const candidate of entryCandidates) try {
|
|
3981
|
+
const candidateStat = await stat(candidate);
|
|
3982
|
+
if (candidateStat.isFile()) entries.push(candidate);
|
|
3983
|
+
else if (candidateStat.isDirectory()) return void 0;
|
|
3984
|
+
} catch (error) {
|
|
3985
|
+
if (error.code !== "ENOENT") throw error;
|
|
3986
|
+
}
|
|
3987
|
+
return entries.length ? entries : void 0;
|
|
3988
|
+
}
|
|
3989
|
+
function collectRuntimeExportTargets(exportsValue, condition) {
|
|
3990
|
+
if (typeof exportsValue === "string") {
|
|
3991
|
+
if (condition === "types") return /* @__PURE__ */ new Set();
|
|
3992
|
+
if (exportsValue.includes("*")) return void 0;
|
|
3993
|
+
return exportsValue.startsWith("./") ? /* @__PURE__ */ new Set([exportsValue]) : /* @__PURE__ */ new Set();
|
|
3994
|
+
}
|
|
3995
|
+
if (Array.isArray(exportsValue)) {
|
|
3996
|
+
const targets = /* @__PURE__ */ new Set();
|
|
3997
|
+
for (const entry of exportsValue) {
|
|
3998
|
+
const entryTargets = collectRuntimeExportTargets(entry, condition);
|
|
3999
|
+
if (!entryTargets) return void 0;
|
|
4000
|
+
for (const target of entryTargets) targets.add(target);
|
|
4001
|
+
}
|
|
4002
|
+
return targets;
|
|
4003
|
+
}
|
|
4004
|
+
if (typeof exportsValue !== "object" || exportsValue === null) return /* @__PURE__ */ new Set();
|
|
4005
|
+
const targets = /* @__PURE__ */ new Set();
|
|
4006
|
+
for (const [key, value] of Object.entries(exportsValue)) {
|
|
4007
|
+
if (key === "types") continue;
|
|
4008
|
+
if (!key.startsWith(".") && !runtimeExportConditions.has(key)) continue;
|
|
4009
|
+
const entryTargets = collectRuntimeExportTargets(value, key);
|
|
4010
|
+
if (!entryTargets) return void 0;
|
|
4011
|
+
for (const target of entryTargets) targets.add(target);
|
|
4012
|
+
}
|
|
4013
|
+
return targets;
|
|
4014
|
+
}
|
|
4015
|
+
function hasNodeModulesSegment(path) {
|
|
4016
|
+
return path.split(/[\\/]/).includes("node_modules");
|
|
4017
|
+
}
|
|
4018
|
+
function isInsideDirectory(parent, child) {
|
|
4019
|
+
const childRelativePath = relative(parent, child);
|
|
4020
|
+
return childRelativePath === "" || !childRelativePath.startsWith(`..${sep}`) && childRelativePath !== ".." && !isAbsolute(childRelativePath);
|
|
4021
|
+
}
|
|
4022
|
+
function parsePackageJson(value, path) {
|
|
4023
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) throw internalErrorDiagnostics.INTERNAL_B0047({ message: `Expected ${path} to contain a JSON object.` });
|
|
4024
|
+
return value;
|
|
4025
|
+
}
|
|
4026
|
+
//#endregion
|
|
3798
4027
|
//#region src/internal/vite-build.ts
|
|
4028
|
+
function resolveVercelWorkflowWorld(workflowApi) {
|
|
4029
|
+
const workflowCore = createRequire(workflowApi).resolve("@workflow/core");
|
|
4030
|
+
return createRequire(workflowCore).resolve("@workflow/world-vercel");
|
|
4031
|
+
}
|
|
3799
4032
|
const workflowPackageName = "@vite-hub/workflow";
|
|
3800
4033
|
const productName = "workflow";
|
|
3801
4034
|
const vercelNativeWorkflowOwnershipMarker = ".vitehub-owned";
|
|
@@ -3804,7 +4037,7 @@ const vercelWorkflowOutputState = ".vitehub/workflow/vercel-output.json";
|
|
|
3804
4037
|
const deployedWorkflowSourcesPath = ".vitehub/workflow/sources";
|
|
3805
4038
|
function parseJsonRecord(text, label) {
|
|
3806
4039
|
const value = JSON.parse(text);
|
|
3807
|
-
if (!isRuntimeRecord(value)) throw
|
|
4040
|
+
if (!isRuntimeRecord(value)) throw workflowErrorDiagnostics.WORKFLOW_R0003({ message: `Expected ${label} to contain a JSON record.` });
|
|
3808
4041
|
return value;
|
|
3809
4042
|
}
|
|
3810
4043
|
const vercelRootWorkflowRoutes = [{ handle: "filesystem" }, {
|
|
@@ -3851,7 +4084,7 @@ const cloudflareWorkflowWranglerConfigKeys = [
|
|
|
3851
4084
|
"workflows"
|
|
3852
4085
|
];
|
|
3853
4086
|
const cloudflareWorkflowWrapperImport = `import worker, { runViteHubWorkflowDefinition } from "./worker.mjs"`;
|
|
3854
|
-
const nodeBuiltinExternals = [
|
|
4087
|
+
const nodeBuiltinExternals = [.../* @__PURE__ */ new Set([
|
|
3855
4088
|
"node:*",
|
|
3856
4089
|
...builtinModules,
|
|
3857
4090
|
...builtinModules.map((module) => `node:${module}`)
|
|
@@ -3924,7 +4157,8 @@ async function createVercelWorkflowTransformPlugin(rootDir) {
|
|
|
3924
4157
|
async function withVercelWorkflowPackageLink(rootDir, run) {
|
|
3925
4158
|
const target = join(rootDir, "node_modules", "workflow");
|
|
3926
4159
|
if (existsSync(target)) return await run();
|
|
3927
|
-
const
|
|
4160
|
+
const require = createRequire(import.meta.url);
|
|
4161
|
+
const source = dirname(dirname(dirname(require.resolve("workflow/internal/builtins"))));
|
|
3928
4162
|
await mkdir(dirname(target), { recursive: true });
|
|
3929
4163
|
let ownsLink = false;
|
|
3930
4164
|
try {
|
|
@@ -3941,7 +4175,7 @@ async function withVercelWorkflowPackageLink(rootDir, run) {
|
|
|
3941
4175
|
}
|
|
3942
4176
|
function hasVercelNativeWorkflowEntry(rootDir, definitions, aliases = {}, nativeFiles = []) {
|
|
3943
4177
|
if (!definitions.length) return false;
|
|
3944
|
-
const definitionDirs = [
|
|
4178
|
+
const definitionDirs = [.../* @__PURE__ */ new Set([...definitions.map((definition) => dirname(definition.handler)), ...nativeFiles.map((file) => dirname(file))])];
|
|
3945
4179
|
let hasNativeEntry = false;
|
|
3946
4180
|
const visited = /* @__PURE__ */ new Set();
|
|
3947
4181
|
const definitionHandlers = new Set(definitions.map((definition) => definition.handler));
|
|
@@ -3956,6 +4190,7 @@ function hasVercelNativeWorkflowEntry(rootDir, definitions, aliases = {}, native
|
|
|
3956
4190
|
}
|
|
3957
4191
|
return;
|
|
3958
4192
|
}
|
|
4193
|
+
const source = readFileSync(file, "utf8");
|
|
3959
4194
|
const parsed = buildSync({
|
|
3960
4195
|
bundle: false,
|
|
3961
4196
|
format: "esm",
|
|
@@ -3963,7 +4198,7 @@ function hasVercelNativeWorkflowEntry(rootDir, definitions, aliases = {}, native
|
|
|
3963
4198
|
metafile: true,
|
|
3964
4199
|
minifySyntax: true,
|
|
3965
4200
|
stdin: {
|
|
3966
|
-
contents:
|
|
4201
|
+
contents: source,
|
|
3967
4202
|
loader: /\.[cm]?[jt]sx$/.test(file) ? "tsx" : "ts",
|
|
3968
4203
|
sourcefile: file
|
|
3969
4204
|
},
|
|
@@ -3974,7 +4209,7 @@ function hasVercelNativeWorkflowEntry(rootDir, definitions, aliases = {}, native
|
|
|
3974
4209
|
if (!definitionDirs.some((definitionDir) => {
|
|
3975
4210
|
const path = relative(definitionDir, file);
|
|
3976
4211
|
return !path.startsWith("..") && !isAbsolute(path);
|
|
3977
|
-
})) throw
|
|
4212
|
+
})) throw workflowErrorDiagnostics.WORKFLOW_R0004({ message: `Native Vercel workflow entry ${JSON.stringify(relative(rootDir, file))} must be colocated with its discovered workflow definition.` });
|
|
3978
4213
|
hasNativeEntry = true;
|
|
3979
4214
|
}
|
|
3980
4215
|
if (definitionHandlers.has(file) && !/\bnative\s*(?::|(?=[,}]))/.test(parsedSource)) return;
|
|
@@ -4173,15 +4408,15 @@ async function readVercelNativeWorkflowState(rootDir) {
|
|
|
4173
4408
|
}
|
|
4174
4409
|
function assertNoExternalCanonicalWorkflowOutput(state) {
|
|
4175
4410
|
const externalCanonicalFiles = Object.entries(state.files).filter(([file, digest]) => /^v1\/(?:flow|step)\.func\/|^v1\/webhook\//.test(file) && state.ownership?.files[file] !== digest).map(([file]) => file);
|
|
4176
|
-
if (externalCanonicalFiles.length) throw
|
|
4411
|
+
if (externalCanonicalFiles.length) throw workflowErrorDiagnostics.WORKFLOW_R0005({ message: `Native Vercel Workflow output conflicts with existing unowned Workflow DevKit functions: ${externalCanonicalFiles.join(", ")}. Build all native Workflow source directories together.` });
|
|
4177
4412
|
}
|
|
4178
|
-
async function buildVercelNativeWorkflowOutput(rootDir, definitions, aliases = {}, nativeFiles = [], previousState) {
|
|
4413
|
+
async function buildVercelNativeWorkflowOutput(rootDir, definitions, aliases = {}, nativeFiles = [], previousState, bundleDefines = {}) {
|
|
4179
4414
|
if (!hasVercelNativeWorkflowEntry(rootDir, definitions, aliases, nativeFiles)) {
|
|
4180
4415
|
await cleanVercelNativeWorkflowOutput(rootDir);
|
|
4181
4416
|
return;
|
|
4182
4417
|
}
|
|
4183
4418
|
const builders = await loadVercelWorkflowBuilders();
|
|
4184
|
-
if (!builders) throw
|
|
4419
|
+
if (!builders) throw workflowErrorDiagnostics.WORKFLOW_R0006({ message: "Native Vercel workflows require the optional workflow and @workflow/builders peer dependencies." });
|
|
4185
4420
|
const snapshot = await snapshotVercelNativeWorkflowOutput(rootDir);
|
|
4186
4421
|
const outputConfigFile = resolve(rootDir, ".vercel", "output", "config.json");
|
|
4187
4422
|
const viteHubConfig = parseJsonRecord(await readFile(outputConfigFile, "utf8"), "ViteHub Vercel output config");
|
|
@@ -4199,8 +4434,31 @@ async function buildVercelNativeWorkflowOutput(rootDir, definitions, aliases = {
|
|
|
4199
4434
|
routes: rollbackRoutes
|
|
4200
4435
|
}, null, 2)}\n`);
|
|
4201
4436
|
const externalWorkflowRoutes = new Set(preservedRoutes.filter((route) => JSON.stringify(route).includes("/.well-known/workflow/v1/")).map((route) => JSON.stringify(route)));
|
|
4202
|
-
const definitionDirs = [
|
|
4203
|
-
|
|
4437
|
+
const definitionDirs = [.../* @__PURE__ */ new Set([...definitions.map((definition) => dirname(definition.handler)), ...nativeFiles.map((file) => dirname(file))])];
|
|
4438
|
+
class ConfiguredWorkflowBuilder extends builders.VercelBuildOutputAPIBuilder {
|
|
4439
|
+
async createStepsBundle(options) {
|
|
4440
|
+
const result = await super.createStepsBundle(options);
|
|
4441
|
+
if (!Object.keys(bundleDefines).length) return result;
|
|
4442
|
+
const source = await readFile(options.outfile, "utf8");
|
|
4443
|
+
const output = await transform(source, {
|
|
4444
|
+
define: bundleDefines,
|
|
4445
|
+
sourcefile: options.outfile,
|
|
4446
|
+
sourcemap: "inline"
|
|
4447
|
+
});
|
|
4448
|
+
await writeFile(options.outfile, output.code);
|
|
4449
|
+
return result;
|
|
4450
|
+
}
|
|
4451
|
+
async createWorkflowsBundle(options) {
|
|
4452
|
+
const result = await super.createWorkflowsBundle(options);
|
|
4453
|
+
if (result.interimBundleText && Object.keys(bundleDefines).length) result.interimBundleText = (await transform(result.interimBundleText, {
|
|
4454
|
+
define: bundleDefines,
|
|
4455
|
+
sourcefile: options.outfile,
|
|
4456
|
+
sourcemap: "inline"
|
|
4457
|
+
})).code;
|
|
4458
|
+
return result;
|
|
4459
|
+
}
|
|
4460
|
+
}
|
|
4461
|
+
const builder = new ConfiguredWorkflowBuilder({
|
|
4204
4462
|
buildTarget: "vercel-build-output-api",
|
|
4205
4463
|
dirs: definitionDirs,
|
|
4206
4464
|
projectRoot: rootDir,
|
|
@@ -4259,20 +4517,49 @@ const providerEntrySpecs = [{
|
|
|
4259
4517
|
function resolveWorkflowConfig(workflow, hosting) {
|
|
4260
4518
|
return normalizeWorkflowOptions(workflow, { hosting }) ?? false;
|
|
4261
4519
|
}
|
|
4520
|
+
/**
|
|
4521
|
+
* The Provider Output that a build writes. Without a host, both outputs are written.
|
|
4522
|
+
* Only Vercel deploys the Vercel output, so other hosts skip it.
|
|
4523
|
+
*/
|
|
4524
|
+
function resolveWorkflowProviderOutputs(workflow, hosting) {
|
|
4525
|
+
if (!hosting) return {
|
|
4526
|
+
cloudflare: resolveWorkflowConfig(workflow, "cloudflare"),
|
|
4527
|
+
vercel: resolveWorkflowConfig(workflow, "vercel")
|
|
4528
|
+
};
|
|
4529
|
+
const config = resolveWorkflowConfig(workflow, hosting);
|
|
4530
|
+
return {
|
|
4531
|
+
cloudflare: config && config.provider === "cloudflare" ? config : false,
|
|
4532
|
+
vercel: config && config.provider === "vercel" && getHostingProvider(hosting) === "vercel" ? config : false
|
|
4533
|
+
};
|
|
4534
|
+
}
|
|
4262
4535
|
function record(value) {
|
|
4263
4536
|
return value && hasRuntimeType(value, "object") ? value : {};
|
|
4264
4537
|
}
|
|
4265
4538
|
function mergeCloudflareWorkersExternal(external) {
|
|
4266
4539
|
const cloudflareRuntimeModules = ["cloudflare:workers", "cloudflare:workflows"];
|
|
4267
4540
|
if (external === void 0) return cloudflareRuntimeModules;
|
|
4268
|
-
if (hasRuntimeType(external, "string")) return [
|
|
4541
|
+
if (hasRuntimeType(external, "string")) return [.../* @__PURE__ */ new Set([external, ...cloudflareRuntimeModules])];
|
|
4269
4542
|
if (external instanceof RegExp) return [external, ...cloudflareRuntimeModules];
|
|
4270
|
-
if (Array.isArray(external)) return [
|
|
4543
|
+
if (Array.isArray(external)) return [.../* @__PURE__ */ new Set([...external, ...cloudflareRuntimeModules])];
|
|
4271
4544
|
if (hasRuntimeType(external, "function")) return (source, importer, isResolved) => cloudflareRuntimeModules.includes(source) || external(source, importer, isResolved);
|
|
4272
4545
|
return external;
|
|
4273
4546
|
}
|
|
4547
|
+
function getUniqueLegacyCloudflareWorkflowAliases(definitions) {
|
|
4548
|
+
const counts = /* @__PURE__ */ new Map();
|
|
4549
|
+
for (const definition of definitions) {
|
|
4550
|
+
const alias = getLegacyCloudflareWorkflowClassName(definition.name);
|
|
4551
|
+
counts.set(alias, (counts.get(alias) || 0) + 1);
|
|
4552
|
+
}
|
|
4553
|
+
const aliases = /* @__PURE__ */ new Map();
|
|
4554
|
+
for (const definition of definitions) {
|
|
4555
|
+
const alias = getLegacyCloudflareWorkflowClassName(definition.name);
|
|
4556
|
+
if (counts.get(alias) === 1) aliases.set(definition.name, alias);
|
|
4557
|
+
}
|
|
4558
|
+
return aliases;
|
|
4559
|
+
}
|
|
4274
4560
|
function createCloudflareWorkflowNitroPlugin(entryFile, definitions) {
|
|
4275
4561
|
const moduleId = "virtual:vitehub-workflow-cloudflare-exports";
|
|
4562
|
+
const legacyAliases = getUniqueLegacyCloudflareWorkflowAliases(definitions);
|
|
4276
4563
|
const resolvedModuleId = `\0${moduleId}`;
|
|
4277
4564
|
const fileName = "workflow-cloudflare-exports.mjs";
|
|
4278
4565
|
return {
|
|
@@ -4297,12 +4584,15 @@ function createCloudflareWorkflowNitroPlugin(entryFile, definitions) {
|
|
|
4297
4584
|
"installViteHubWorkflowRuntime()",
|
|
4298
4585
|
"",
|
|
4299
4586
|
...definitions.map((definition) => {
|
|
4587
|
+
const className = getCloudflareWorkflowClassName(definition.name);
|
|
4588
|
+
const legacyClassName = legacyAliases.get(definition.name);
|
|
4300
4589
|
return [
|
|
4301
|
-
`export class ${
|
|
4590
|
+
`export class ${className} extends WorkflowEntrypoint {`,
|
|
4302
4591
|
" async run(event, step) {",
|
|
4303
4592
|
` return await runViteHubWorkflowDefinition(${JSON.stringify(definition.name)}, this.env || {}, event, step)`,
|
|
4304
4593
|
" }",
|
|
4305
4594
|
"}",
|
|
4595
|
+
...legacyClassName ? [`export { ${className} as ${legacyClassName} }`] : [],
|
|
4306
4596
|
""
|
|
4307
4597
|
].join("\n");
|
|
4308
4598
|
})
|
|
@@ -4311,7 +4601,7 @@ function createCloudflareWorkflowNitroPlugin(entryFile, definitions) {
|
|
|
4311
4601
|
renderChunk(code, chunk) {
|
|
4312
4602
|
if (!chunk.isEntry || chunk.fileName !== "index.mjs" && chunk.fileName !== "index.js") return null;
|
|
4313
4603
|
return {
|
|
4314
|
-
code: `${code}\nexport { ${definitions.
|
|
4604
|
+
code: `${code}\nexport { ${definitions.flatMap((definition) => [getCloudflareWorkflowClassName(definition.name), ...legacyAliases.get(definition.name) ? [legacyAliases.get(definition.name)] : []]).join(", ")} } from './${fileName}'\n`,
|
|
4315
4605
|
map: null
|
|
4316
4606
|
};
|
|
4317
4607
|
}
|
|
@@ -4353,43 +4643,20 @@ function resolveAgentWorkspaceSourceRoot(file) {
|
|
|
4353
4643
|
const workspaceDirectory = join(dirname(file), "workspace");
|
|
4354
4644
|
return existsSync(workspaceDirectory) && statSync(workspaceDirectory).isDirectory() ? workspaceDirectory : dirname(file);
|
|
4355
4645
|
}
|
|
4356
|
-
function resolveInstructionFile(file, seen, dependencies) {
|
|
4357
|
-
if (seen.has(file)) throw new Error(`[vitehub] Circular instruction import: ${file}.`);
|
|
4358
|
-
seen.add(file);
|
|
4359
|
-
dependencies?.add(file);
|
|
4360
|
-
try {
|
|
4361
|
-
const replaceImports = (content) => content.replace(/@(\.\.?\/\S+)/g, (_token, rawSpecifier) => {
|
|
4362
|
-
const trailing = rawSpecifier.match(/[.,;:!?)]*$/)?.[0] || "";
|
|
4363
|
-
const specifier = rawSpecifier.slice(0, rawSpecifier.length - trailing.length);
|
|
4364
|
-
return `${resolveInstructionFile(resolve(dirname(file), specifier), seen, dependencies)}${trailing}`;
|
|
4365
|
-
});
|
|
4366
|
-
let fence;
|
|
4367
|
-
return readFileSync(file, "utf8").split(/(?<=\n)/).map((line) => {
|
|
4368
|
-
const marker = line.match(/^\s*(```|~~~)/)?.[1];
|
|
4369
|
-
if (marker) {
|
|
4370
|
-
fence = fence === marker ? void 0 : fence || marker;
|
|
4371
|
-
return line;
|
|
4372
|
-
}
|
|
4373
|
-
if (fence) return line;
|
|
4374
|
-
if (/^(?: {4}|\t)/.test(line)) return line;
|
|
4375
|
-
return line.split(/(`+[^`]*`+)/g).map((segment, index) => index % 2 ? segment : replaceImports(segment)).join("");
|
|
4376
|
-
}).join("");
|
|
4377
|
-
} finally {
|
|
4378
|
-
seen.delete(file);
|
|
4379
|
-
}
|
|
4380
|
-
}
|
|
4381
4646
|
function readAgentInstructions(file, dependencies) {
|
|
4382
4647
|
const instructions = join(dirname(file), "instructions.md");
|
|
4383
|
-
|
|
4648
|
+
if (!existsSync(instructions) || !statSync(instructions).isFile()) return;
|
|
4649
|
+
dependencies?.add(instructions);
|
|
4650
|
+
return readFileSync(instructions, "utf8");
|
|
4384
4651
|
}
|
|
4385
4652
|
function readAgentSkills(file) {
|
|
4386
4653
|
const files = readColocatedAgentFiles(file, "skills");
|
|
4387
4654
|
if (!files) return;
|
|
4388
4655
|
return Object.fromEntries(Object.entries(files).map(([path, source]) => {
|
|
4389
|
-
const workspacePath =
|
|
4656
|
+
const workspacePath = `.agents/skills/${path}`;
|
|
4390
4657
|
return [`__vitehubAgentSkill:${workspacePath}`, {
|
|
4391
4658
|
...source,
|
|
4392
|
-
materialize: "
|
|
4659
|
+
materialize: "startup",
|
|
4393
4660
|
mount: "",
|
|
4394
4661
|
workspacePath
|
|
4395
4662
|
}];
|
|
@@ -4398,11 +4665,11 @@ function readAgentSkills(file) {
|
|
|
4398
4665
|
function renderAgentWorkflowRegistryEntry(registryFile, definition, retainedAgentInstructions) {
|
|
4399
4666
|
const instructions = retainedAgentInstructions?.has(definition.handler) ? retainedAgentInstructions.get(definition.handler) : readAgentInstructions(definition.handler);
|
|
4400
4667
|
return [
|
|
4401
|
-
` ${JSON.stringify(definition.name)}: Object.assign(async () => {`,
|
|
4668
|
+
` [${JSON.stringify(definition.name)}]: Object.assign(async () => {`,
|
|
4402
4669
|
` const cached = registryEntryCache.get(${JSON.stringify(definition.name)})`,
|
|
4403
4670
|
" if (cached) return cached",
|
|
4404
4671
|
` const loaded = await ${renderRegistryImport(registryFile, definition.handler)}`,
|
|
4405
|
-
` const agent = agentWithColocatedSkills(
|
|
4672
|
+
` const agent = workspaceAgentWithSourceRoot(agentWithColocatedSkills(agentWithColocatedInstructions("default" in loaded ? loaded.default : loaded, ${JSON.stringify(instructions)}), ${JSON.stringify(readAgentSkills(definition.handler))}), ${JSON.stringify(resolveAgentWorkspaceSourceRoot(definition.handler))}, ${JSON.stringify(instructions)})`,
|
|
4406
4673
|
` const entry = { options: { rootStep: false }, handler: async (context) => await runAgentWorkflowDefinition(agent, { ...context, payload: { ...context.payload, agentIdentity: context.payload?.agentIdentity || { name: ${JSON.stringify(definition.agentIdentity || definition.name)} } } }, runAgentInline)${definition.source === "agent-workflow-recovery" ? ", internalAgentInvocationRecovery: true" : ""} }`,
|
|
4407
4674
|
` registryEntryCache.set(${JSON.stringify(definition.name)}, entry)`,
|
|
4408
4675
|
" return entry",
|
|
@@ -4436,7 +4703,7 @@ function createVercelNativeWorkflowContents(definition) {
|
|
|
4436
4703
|
}
|
|
4437
4704
|
function renderWorkflowRegistryEntry(registryFile, definition, vercelNativeFiles = {}, retainedAgentInstructions) {
|
|
4438
4705
|
if (definition.source === "agent-workflow" || definition.source === "agent-workflow-recovery") return renderAgentWorkflowRegistryEntry(registryFile, definition, retainedAgentInstructions);
|
|
4439
|
-
if (!definition.steps?.length) return ` ${JSON.stringify(definition.name)}: async () => ${renderRegistryImport(registryFile, definition.handler)},`;
|
|
4706
|
+
if (!definition.steps?.length) return ` [${JSON.stringify(definition.name)}]: async () => ${renderRegistryImport(registryFile, definition.handler)},`;
|
|
4440
4707
|
const workflowDirectory = /\.(?:c|m)?[jt]s$/i.test(definition.handler) ? dirname(definition.handler) : definition.handler;
|
|
4441
4708
|
const stepImports = definition.steps.map((step) => {
|
|
4442
4709
|
const stepName = relative(workflowDirectory, step);
|
|
@@ -4449,7 +4716,7 @@ function renderWorkflowRegistryEntry(registryFile, definition, vercelNativeFiles
|
|
|
4449
4716
|
const nativeImport = nativeExport && vercelNativeFile ? `const native = (await import(${JSON.stringify(createImportPath(registryFile, vercelNativeFile))})).${nativeExport}\n native.workflowId ||= ${JSON.stringify(`workflow//./.vitehub/workflow/vercel-native//${nativeExport}`)}` : "";
|
|
4450
4717
|
const handler = hasIndex ? `index.default?.handler ? index.default : takeInlineWorkflowDefinitionForModule(${JSON.stringify(definition.name)}, index) || { handler: index.default }` : "{ handler: async (context) => { let value = context.payload; for (const step of Object.values(context.steps || {})) value = await step(value); return value } }";
|
|
4451
4718
|
return [
|
|
4452
|
-
` ${JSON.stringify(definition.name)}: async () => {`,
|
|
4719
|
+
` [${JSON.stringify(definition.name)}]: async () => {`,
|
|
4453
4720
|
` const cached = registryEntryCache.get(${JSON.stringify(definition.name)})`,
|
|
4454
4721
|
" if (cached) return cached",
|
|
4455
4722
|
indexImport ? ` ${indexImport}` : "",
|
|
@@ -4500,8 +4767,8 @@ function createWorkflowRegistryContents(registryFile, definitions, importBases =
|
|
|
4500
4767
|
] : [],
|
|
4501
4768
|
...workspaceDependencyRuntimeImports ? [
|
|
4502
4769
|
"setWorkspaceDependencyRuntimeLoaders({",
|
|
4503
|
-
...workspaceDependencyRuntimeImports.
|
|
4504
|
-
...workspaceDependencyRuntimeImports.
|
|
4770
|
+
...workspaceDependencyRuntimeImports.sandboxTask ? [` sandboxTask: () => import(${JSON.stringify(workspaceDependencyRuntimeImports.sandboxTask)}),`] : [],
|
|
4771
|
+
...workspaceDependencyRuntimeImports.sandboxTaskRuntimeState ? [` sandboxTaskRuntimeState: () => import(${JSON.stringify(workspaceDependencyRuntimeImports.sandboxTaskRuntimeState)}),`] : [],
|
|
4505
4772
|
...workspaceDependencyRuntimeImports.shellWorkspace ? [` shellWorkspace: () => import(${JSON.stringify(workspaceDependencyRuntimeImports.shellWorkspace)}),`] : [],
|
|
4506
4773
|
"})",
|
|
4507
4774
|
""
|
|
@@ -4516,17 +4783,21 @@ function createWorkflowRegistryContents(registryFile, definitions, importBases =
|
|
|
4516
4783
|
].join("\n");
|
|
4517
4784
|
}
|
|
4518
4785
|
function renderCloudflareWorkerWrapper(definitions) {
|
|
4786
|
+
const legacyAliases = getUniqueLegacyCloudflareWorkflowAliases(definitions);
|
|
4519
4787
|
return [
|
|
4520
4788
|
definitions.length ? `import { WorkflowEntrypoint, waitUntil as viteHubWaitUntil } from "cloudflare:workers"` : `import { waitUntil as viteHubWaitUntil } from "cloudflare:workers"`,
|
|
4521
4789
|
cloudflareWorkflowWrapperImport,
|
|
4522
4790
|
"",
|
|
4523
4791
|
...definitions.map((definition) => {
|
|
4792
|
+
const className = getCloudflareWorkflowClassName(definition.name);
|
|
4793
|
+
const legacyClassName = legacyAliases.get(definition.name);
|
|
4524
4794
|
return [
|
|
4525
|
-
`export class ${
|
|
4795
|
+
`export class ${className} extends WorkflowEntrypoint {`,
|
|
4526
4796
|
" async run(event, step) {",
|
|
4527
4797
|
` return await runViteHubWorkflowDefinition(${JSON.stringify(definition.name)}, this.env || {}, event, step)`,
|
|
4528
4798
|
" }",
|
|
4529
4799
|
"}",
|
|
4800
|
+
...legacyClassName ? [`export { ${className} as ${legacyClassName} }`] : [],
|
|
4530
4801
|
""
|
|
4531
4802
|
].join("\n");
|
|
4532
4803
|
}),
|
|
@@ -4560,7 +4831,7 @@ function renderProviderEntry(spec, entryFile, userAppEntry, serializedWorkflowCo
|
|
|
4560
4831
|
"}",
|
|
4561
4832
|
"",
|
|
4562
4833
|
"export async function runViteHubWorkflowDefinition(name, env, event, step) {",
|
|
4563
|
-
" return await runCloudflareWorkflow({ config: workflowConfig, createNonRetryableError: error => new NonRetryableError(error.message, error.name), env: env || {}, event, name, registry: workflowRegistry, step })",
|
|
4834
|
+
" return await runCloudflareWorkflow({ config: workflowConfig, createNonRetryableError: error => Object.defineProperty(new NonRetryableError(error.message, error.name), \"cause\", { value: error, configurable: true, writable: true }), env: env || {}, event, name, registry: workflowRegistry, step })",
|
|
4564
4835
|
"}"
|
|
4565
4836
|
] : [];
|
|
4566
4837
|
return [
|
|
@@ -4589,7 +4860,7 @@ async function writeProviderEntries(rootDir, workflow, importBases = {}, serverD
|
|
|
4589
4860
|
for (const definition of definitions) {
|
|
4590
4861
|
if (definition.source !== "agent-workflow") continue;
|
|
4591
4862
|
const recoveryName = getAgentInvocationRecoveryWorkflowName(definition.name);
|
|
4592
|
-
if (definitionNames.has(recoveryName)) throw
|
|
4863
|
+
if (definitionNames.has(recoveryName)) throw workflowErrorDiagnostics.WORKFLOW_R0008({ message: `Workflow name ${JSON.stringify(recoveryName)} conflicts with the generated Agent invocation recovery Workflow for ${JSON.stringify(definition.name)}.` });
|
|
4593
4864
|
}
|
|
4594
4865
|
const providerDefinitions = definitions.flatMap((definition) => definition.source === "agent-workflow" ? [definition, {
|
|
4595
4866
|
...definition,
|
|
@@ -4622,7 +4893,8 @@ async function writeProviderEntries(rootDir, workflow, importBases = {}, serverD
|
|
|
4622
4893
|
await Promise.all(providerEntrySpecs.map(async (spec) => {
|
|
4623
4894
|
const entryFile = resolve(generatedDir, spec.entryFile);
|
|
4624
4895
|
const workflowConfig = spec.name === "cloudflare" ? cloudflareWorkflowConfig : resolveWorkflowConfig(workflow, spec.hosting);
|
|
4625
|
-
|
|
4896
|
+
const serialized = JSON.stringify(workflowConfig, null, 2);
|
|
4897
|
+
await writeFile(entryFile, renderProviderEntry(spec, entryFile, userAppEntry, serialized, importBases.workflow ?? "@vite-hub/workflow", Boolean(importBases.workflow)), "utf8");
|
|
4626
4898
|
entryFiles[spec.name] = entryFile;
|
|
4627
4899
|
}));
|
|
4628
4900
|
return {
|
|
@@ -4660,7 +4932,8 @@ function discoverWorkflowProviderSources(definitionRootDir, serverDirs) {
|
|
|
4660
4932
|
}
|
|
4661
4933
|
function createCloudflareOutput(rootDir, artifacts, providerImportAliases) {
|
|
4662
4934
|
const workflowConfig = artifacts.cloudflareWorkflowConfig && artifacts.cloudflareWorkflowConfig.provider === "cloudflare" ? artifacts.cloudflareWorkflowConfig : false;
|
|
4663
|
-
const
|
|
4935
|
+
const workflowDefinitions = workflowConfig ? artifacts.providerDefinitions : [];
|
|
4936
|
+
const workflows = createCloudflareWorkflowBindings(workflowDefinitions, workflowConfig);
|
|
4664
4937
|
const wranglerConfig = {
|
|
4665
4938
|
compatibility_date: defaultCloudflareCompatibilityDate,
|
|
4666
4939
|
compatibility_flags: ["nodejs_compat"],
|
|
@@ -4820,7 +5093,7 @@ async function cleanVercelWorkflowRootConfig(rootDir, ownedRoutes) {
|
|
|
4820
5093
|
}
|
|
4821
5094
|
async function updateVercelWorkflowFunctionOwnership(rootDir, activeServerFunctionName, ownsRootConfig) {
|
|
4822
5095
|
const functionsRoot = resolve(createDefaultVercelOutputRoot(rootDir), "functions");
|
|
4823
|
-
const candidates = new Set(["__server.func", "__workflow.func"]);
|
|
5096
|
+
const candidates = /* @__PURE__ */ new Set(["__server.func", "__workflow.func"]);
|
|
4824
5097
|
const previousOutput = await readVercelWorkflowOutputState(rootDir, functionsRoot);
|
|
4825
5098
|
if (previousOutput) candidates.add(previousOutput.serverFunctionName);
|
|
4826
5099
|
if (activeServerFunctionName) candidates.add(activeServerFunctionName);
|
|
@@ -4875,9 +5148,7 @@ async function generateProviderOutputsWithinLock(options, writeProviderDeploymen
|
|
|
4875
5148
|
workspace: options.workspaceImportBase,
|
|
4876
5149
|
workspaceDependencies: options.workspaceDependencyRuntimeImports
|
|
4877
5150
|
}, options.serverDirs, options.includeUserAppEntry, options.transformRegistry, options.definitionRootDir);
|
|
4878
|
-
const
|
|
4879
|
-
const cloudflareWorkflowConfig = inferredWorkflowConfig === void 0 ? resolveWorkflowConfig(options.workflow, "cloudflare") : inferredWorkflowConfig && inferredWorkflowConfig.provider === "cloudflare" ? inferredWorkflowConfig : false;
|
|
4880
|
-
const vercelWorkflowConfig = inferredWorkflowConfig === void 0 ? resolveWorkflowConfig(options.workflow, "vercel") : inferredWorkflowConfig && inferredWorkflowConfig.provider === "vercel" ? inferredWorkflowConfig : false;
|
|
5151
|
+
const { cloudflare: cloudflareWorkflowConfig, vercel: vercelWorkflowConfig } = resolveWorkflowProviderOutputs(options.workflow, options.hosting);
|
|
4881
5152
|
const workflowTransformPlugin = vercelWorkflowConfig && vercelWorkflowConfig.provider === "vercel" ? await createVercelWorkflowTransformPlugin(options.rootDir) : void 0;
|
|
4882
5153
|
let commitGeneratedArtifacts = async () => {};
|
|
4883
5154
|
let rollbackGeneratedArtifacts = async () => {};
|
|
@@ -5017,7 +5288,7 @@ async function generateProviderOutputsWithinLock(options, writeProviderDeploymen
|
|
|
5017
5288
|
if (vercelOutput) await buildVercelNativeWorkflowOutput(options.rootDir, artifacts.providerDefinitions, {
|
|
5018
5289
|
...options.providerImportAliases,
|
|
5019
5290
|
...options.providerRuntimeImportAliases?.vercel
|
|
5020
|
-
}, artifacts.vercelNativeFiles, previousNativeOutput);
|
|
5291
|
+
}, artifacts.vercelNativeFiles, previousNativeOutput, options.bundleDefines);
|
|
5021
5292
|
else await cleanVercelNativeWorkflowOutput(options.rootDir);
|
|
5022
5293
|
signal?.throwIfAborted();
|
|
5023
5294
|
await updateVercelWorkflowFunctionOwnership(options.rootDir, vercelOutput ? options.serverFunctionName ?? "__server.func" : void 0, Boolean(vercelOutput && !options.serverFunctionName));
|
|
@@ -5028,6 +5299,11 @@ async function generateProviderOutputsWithinLock(options, writeProviderDeploymen
|
|
|
5028
5299
|
};
|
|
5029
5300
|
if (vercelOutput) deploymentOutput.vercel = vercelOutput;
|
|
5030
5301
|
await writeProviderDeploymentOutputs(deploymentOutput);
|
|
5302
|
+
if (vercelOutput) await copyVercelFunctionRuntimePackages({
|
|
5303
|
+
packages: options.vercelRuntimePackages ?? [],
|
|
5304
|
+
rootDir: options.rootDir,
|
|
5305
|
+
serverFunctionName: options.serverFunctionName ?? "__server.func"
|
|
5306
|
+
});
|
|
5031
5307
|
publicationSucceeded = true;
|
|
5032
5308
|
} catch (error) {
|
|
5033
5309
|
await rm(outputRoot, {
|
|
@@ -5065,45 +5341,150 @@ async function generateWorkflowProviderOutputs(options, write) {
|
|
|
5065
5341
|
return await withProviderDeploymentOutputLock(options.rootDir, async (lockedWrite) => await generateProviderOutputsWithinLock(options, lockedWrite));
|
|
5066
5342
|
}
|
|
5067
5343
|
//#endregion
|
|
5344
|
+
//#region src/internal/dev-registry.ts
|
|
5345
|
+
const workflowDevGeneratedDir = ".vitehub/nitro/workflow";
|
|
5346
|
+
const devRegistryFile = "dev-registry.mjs";
|
|
5347
|
+
const devPluginFile = "dev-plugin.mjs";
|
|
5348
|
+
/**
|
|
5349
|
+
* Agent Workflows need the Agent registry transform of the provider build, so
|
|
5350
|
+
* the development registry does not contain them.
|
|
5351
|
+
*/
|
|
5352
|
+
function isWorkflowDevDefinition(definition) {
|
|
5353
|
+
return definition.source !== "agent-workflow" && definition.source !== "agent-workflow-recovery";
|
|
5354
|
+
}
|
|
5355
|
+
function discoverWorkflowDevDefinitions(rootDir, serverDirs) {
|
|
5356
|
+
return discoverWorkflowDefinitions({
|
|
5357
|
+
rootDir,
|
|
5358
|
+
serverDirs
|
|
5359
|
+
}).filter(isWorkflowDevDefinition);
|
|
5360
|
+
}
|
|
5361
|
+
function createWorkflowDevRegistryModule(registryFile, definitions, importBase = workflowPackageName) {
|
|
5362
|
+
return createWorkflowRegistryContents(registryFile, definitions.filter(isWorkflowDevDefinition), { workflow: importBase });
|
|
5363
|
+
}
|
|
5364
|
+
function createWorkflowDevPluginModule(workflow, importBase = workflowPackageName) {
|
|
5365
|
+
return [
|
|
5366
|
+
"import { definePlugin } from \"nitro\"",
|
|
5367
|
+
`import { setWorkflowRuntimeConfig, setWorkflowRuntimeRegistry } from ${JSON.stringify(`${importBase}/runtime/state`)}`,
|
|
5368
|
+
`import registry from ${JSON.stringify(`./${devRegistryFile}`)}`,
|
|
5369
|
+
"",
|
|
5370
|
+
"export default definePlugin(() => {",
|
|
5371
|
+
` setWorkflowRuntimeConfig(${JSON.stringify(workflow)})`,
|
|
5372
|
+
" setWorkflowRuntimeRegistry(registry)",
|
|
5373
|
+
"})",
|
|
5374
|
+
""
|
|
5375
|
+
].join("\n");
|
|
5376
|
+
}
|
|
5377
|
+
async function writeIfChanged(file, contents) {
|
|
5378
|
+
if (await readFile(file, "utf8").catch(() => void 0) === contents) return false;
|
|
5379
|
+
await writeFile(file, contents, "utf8");
|
|
5380
|
+
return true;
|
|
5381
|
+
}
|
|
5382
|
+
/**
|
|
5383
|
+
* Writes the development registry of discovered Workflow Definitions and the
|
|
5384
|
+
* Nitro plugin that installs it and the runtime configuration. Files that did
|
|
5385
|
+
* not change are not written again.
|
|
5386
|
+
*/
|
|
5387
|
+
async function writeWorkflowDevRegistryFiles(options) {
|
|
5388
|
+
const directory = resolve(options.projectRoot, workflowDevGeneratedDir);
|
|
5389
|
+
await mkdir(directory, { recursive: true });
|
|
5390
|
+
const registry = resolve(directory, devRegistryFile);
|
|
5391
|
+
const plugin = resolve(directory, devPluginFile);
|
|
5392
|
+
const files = [[registry, createWorkflowDevRegistryModule(registry, options.definitions, options.importBase)], [plugin, createWorkflowDevPluginModule(options.workflow, options.importBase)]];
|
|
5393
|
+
if (options.pluginPath && options.pluginPath !== plugin) {
|
|
5394
|
+
const pluginImport = `./${relative(dirname(options.pluginPath), plugin).replace(/\\/g, "/")}`;
|
|
5395
|
+
files.push([options.pluginPath, `export { default } from ${JSON.stringify(pluginImport)}\n`]);
|
|
5396
|
+
}
|
|
5397
|
+
const changed = [];
|
|
5398
|
+
for (const [file, contents] of files) if (await writeIfChanged(file, contents)) changed.push(file);
|
|
5399
|
+
return {
|
|
5400
|
+
changed,
|
|
5401
|
+
plugin: options.pluginPath ?? plugin
|
|
5402
|
+
};
|
|
5403
|
+
}
|
|
5404
|
+
//#endregion
|
|
5068
5405
|
//#region src/vite.ts
|
|
5069
|
-
const
|
|
5406
|
+
const noExternalAddition = createNoExternalAddition(workflowPackageName);
|
|
5407
|
+
const workflowBuildAssociation = Symbol("vitehubWorkflowBuildAssociation");
|
|
5408
|
+
const workflowEnvironmentAssociation = Symbol("vitehubWorkflowEnvironmentAssociation");
|
|
5070
5409
|
function resolveStringAliases(config) {
|
|
5071
5410
|
return encodeProviderOutputAliases(config.resolve.alias);
|
|
5072
5411
|
}
|
|
5073
5412
|
function hubWorkflow(options, internalOptions = {}) {
|
|
5074
5413
|
let providerOutput;
|
|
5075
5414
|
const providerOutputGenerations = createProviderDeploymentOutputGenerationState();
|
|
5076
|
-
let hasFinalNitroEnvironment = false;
|
|
5077
5415
|
let resolved;
|
|
5078
|
-
|
|
5416
|
+
const defaultWorkflow = internalOptions.implicitlyEnabled && normalizeHosting(internalOptions.hosting).includes("netlify") ? false : options;
|
|
5417
|
+
let workflow = defaultWorkflow;
|
|
5418
|
+
const scheduleBuildConfigs = /* @__PURE__ */ new WeakMap();
|
|
5419
|
+
const scheduledBuildConfigsByRoot = /* @__PURE__ */ new Map();
|
|
5420
|
+
const buildConfigs = /* @__PURE__ */ new WeakMap();
|
|
5079
5421
|
let serverDirs;
|
|
5080
5422
|
const stagedArtifactDirs = /* @__PURE__ */ new WeakMap();
|
|
5423
|
+
const rejectedBuilds = /* @__PURE__ */ new WeakSet();
|
|
5081
5424
|
const fallbackEnvironment = {};
|
|
5082
5425
|
const buildEnvironment = (context) => context?.environment ?? context ?? fallbackEnvironment;
|
|
5083
5426
|
const shouldSkipProviderOutputEnvironment = (context) => {
|
|
5084
5427
|
const environmentName = context?.environment?.name;
|
|
5085
|
-
const
|
|
5086
|
-
|
|
5428
|
+
const config = context?.environment?.config ?? resolved;
|
|
5429
|
+
const viteHubNitroContext = config && Reflect.get(config, "__vitehubNitroConfigContext") === true;
|
|
5430
|
+
const ownerEnvironment = config?.environments?.nitro ? "nitro" : "ssr";
|
|
5431
|
+
return Boolean(environmentName && environmentName !== ownerEnvironment && viteHubNitroContext);
|
|
5087
5432
|
};
|
|
5088
|
-
function
|
|
5089
|
-
const
|
|
5090
|
-
|
|
5433
|
+
function scheduledBuildConfig(config, environmentName) {
|
|
5434
|
+
const direct = scheduleBuildConfigs.get(config);
|
|
5435
|
+
if (direct) return direct;
|
|
5436
|
+
const candidates = scheduledBuildConfigsByRoot.get(config.root) ?? [];
|
|
5437
|
+
const catalog = getProviderOutputCatalog(config);
|
|
5438
|
+
const association = config.build && config.build[workflowBuildAssociation];
|
|
5439
|
+
const environmentAssociation = config[workflowEnvironmentAssociation];
|
|
5440
|
+
const publicDefine = JSON.stringify({
|
|
5441
|
+
publicUrl: config.define?.__VITEHUB_PUBLIC_URL__,
|
|
5442
|
+
base: config.define?.__VITEHUB_APP_BASE_URL__
|
|
5443
|
+
});
|
|
5444
|
+
const matches = candidates.filter((candidate) => {
|
|
5445
|
+
if (environmentAssociation && candidate.environmentAssociation === environmentAssociation) return true;
|
|
5446
|
+
if (environmentName && candidate.environmentNames.size > 0 && !candidate.environmentNames.has(environmentName)) return false;
|
|
5447
|
+
if (environmentName && candidate.config.environments?.[environmentName] === config) return true;
|
|
5448
|
+
if (catalog && candidate.providerOutput !== catalog) return false;
|
|
5449
|
+
if (candidate.config.build.outDir !== config.build.outDir) return false;
|
|
5450
|
+
if (JSON.stringify({
|
|
5451
|
+
publicUrl: candidate.config.define?.__VITEHUB_PUBLIC_URL__,
|
|
5452
|
+
base: candidate.config.define?.__VITEHUB_APP_BASE_URL__
|
|
5453
|
+
}) !== publicDefine) return false;
|
|
5454
|
+
if (!association) return candidate.config.build === config.build;
|
|
5455
|
+
return candidate.config.build[workflowBuildAssociation] === association;
|
|
5456
|
+
});
|
|
5457
|
+
if (matches.length !== 1) throw workflowErrorDiagnostics.WORKFLOW_B0002({ root: config.root });
|
|
5458
|
+
const match = matches[0];
|
|
5459
|
+
scheduleBuildConfigs.set(config, match);
|
|
5460
|
+
return match;
|
|
5461
|
+
}
|
|
5462
|
+
function providerRuntimeImportAliases(provider, generation, catalog = providerOutput) {
|
|
5463
|
+
const database = getProviderRuntimeModule(catalog, "database", provider, generation);
|
|
5464
|
+
const blob = getProviderRuntimeModule(catalog, "blob", provider, generation);
|
|
5465
|
+
return {
|
|
5466
|
+
...database ? { "@vite-hub/database/drizzle": database } : {},
|
|
5467
|
+
...blob ? { "@vite-hub/blob": blob } : {}
|
|
5468
|
+
};
|
|
5091
5469
|
}
|
|
5092
|
-
async function providerImportAliases() {
|
|
5093
|
-
if (!
|
|
5094
|
-
const contributedAliases = await collectViteHubProviderImportAliases(
|
|
5470
|
+
async function providerImportAliases(config = resolved) {
|
|
5471
|
+
if (!config) return { ...internalOptions?.providerImportAliases };
|
|
5472
|
+
const contributedAliases = await collectViteHubProviderImportAliases(config.plugins);
|
|
5095
5473
|
return {
|
|
5096
|
-
...resolveStringAliases(
|
|
5474
|
+
...resolveStringAliases(config),
|
|
5097
5475
|
...contributedAliases,
|
|
5098
5476
|
...internalOptions?.providerImportAliases
|
|
5099
5477
|
};
|
|
5100
5478
|
}
|
|
5101
|
-
async function prepareScheduleRuntime(artifactDir) {
|
|
5102
|
-
if (!
|
|
5103
|
-
|
|
5104
|
-
const
|
|
5105
|
-
|
|
5106
|
-
const
|
|
5479
|
+
async function prepareScheduleRuntime(artifactDir, config = resolved) {
|
|
5480
|
+
if (!config) throw workflowErrorDiagnostics.WORKFLOW_B0001({ message: "[vitehub] Workflow runtime preparation requires resolved Vite config." });
|
|
5481
|
+
const build = scheduledBuildConfig(config);
|
|
5482
|
+
const workflowOptions = config.workflow === void 0 ? build?.workflow ?? defaultWorkflow : config.workflow;
|
|
5483
|
+
if (normalizeWorkflowOptions(workflowOptions, { hosting: internalOptions?.hosting ?? "vercel" })?.provider !== "vercel") return;
|
|
5484
|
+
const rootDir = resolveViteHubProjectRoot(config.root);
|
|
5485
|
+
const aliases = await providerImportAliases(config);
|
|
5486
|
+
const workflowServerDirs = config["__vitehubServerDirs"] ?? build?.serverDirs;
|
|
5487
|
+
const providerSources = discoverWorkflowProviderSources(config.root, workflowServerDirs);
|
|
5107
5488
|
const retainedSources = artifactDir ? await retainProviderOutputSources({
|
|
5108
5489
|
artifactDir: resolve(artifactDir, "sources"),
|
|
5109
5490
|
paths: [
|
|
@@ -5111,19 +5492,19 @@ function hubWorkflow(options, internalOptions = {}) {
|
|
|
5111
5492
|
...Object.values(aliases),
|
|
5112
5493
|
...providerSources.paths
|
|
5113
5494
|
],
|
|
5114
|
-
roots: [
|
|
5495
|
+
roots: [config.root]
|
|
5115
5496
|
}) : void 0;
|
|
5116
|
-
const definitionRootDir = retainedSources?.resolve(
|
|
5117
|
-
const retainedServerDirs =
|
|
5497
|
+
const definitionRootDir = retainedSources?.resolve(config.root) ?? config.root;
|
|
5498
|
+
const retainedServerDirs = workflowServerDirs?.map((directory) => retainedSources?.resolve(directory) ?? directory);
|
|
5118
5499
|
const retainedAgentInstructions = new Map([...providerSources.agentInstructions].map(([handler, instructions]) => [retainedSources?.resolve(handler) ?? handler, instructions]));
|
|
5119
|
-
const artifacts = await writeProviderEntries(rootDir,
|
|
5500
|
+
const artifacts = await writeProviderEntries(rootDir, workflowOptions, {
|
|
5120
5501
|
agent: internalOptions?.agentImportBase,
|
|
5121
5502
|
workflow: internalOptions?.importBase,
|
|
5122
5503
|
workspace: internalOptions?.workspaceImportBase,
|
|
5123
5504
|
workspaceDependencies: internalOptions?.workspaceDependencyRuntimeImports
|
|
5124
|
-
}, retainedServerDirs, internalOptions?.includeUserAppEntry,
|
|
5505
|
+
}, retainedServerDirs, internalOptions?.includeUserAppEntry, config.plugins.find((plugin) => plugin.vitehub?.agent?.transformWorkflowRegistry)?.vitehub?.agent?.transformWorkflowRegistry, definitionRootDir, artifactDir ? resolve(artifactDir, "output") : void 0, retainedAgentInstructions);
|
|
5125
5506
|
const importBase = internalOptions?.importBase ?? "@vite-hub/workflow";
|
|
5126
|
-
const projectRequire = createRequire(resolve(
|
|
5507
|
+
const projectRequire = createRequire(resolve(config.root, "package.json"));
|
|
5127
5508
|
const retainedAliases = retainedSources ? retainProviderOutputAliases(aliases, retainedSources) : aliases;
|
|
5128
5509
|
const native = hasVercelNativeWorkflowEntry(rootDir, artifacts.providerDefinitions, retainedAliases, artifacts.vercelNativeFiles);
|
|
5129
5510
|
const workflowRequire = native ? createRequire(import.meta.url) : void 0;
|
|
@@ -5134,7 +5515,7 @@ function hubWorkflow(options, internalOptions = {}) {
|
|
|
5134
5515
|
[`${importBase}/runtime/state`]: projectRequire.resolve(`${importBase}/runtime/state`),
|
|
5135
5516
|
[`${importBase}/runtime/vercel-vite`]: projectRequire.resolve(`${importBase}/runtime/vercel-vite`),
|
|
5136
5517
|
...workflowApi && workflowRequire ? {
|
|
5137
|
-
"@workflow/core/runtime/world-target":
|
|
5518
|
+
"@workflow/core/runtime/world-target": resolveVercelWorkflowWorld(workflowApi),
|
|
5138
5519
|
"workflow/api": workflowApi,
|
|
5139
5520
|
"workflow/runtime": workflowRequire.resolve("workflow/runtime")
|
|
5140
5521
|
} : {}
|
|
@@ -5145,67 +5526,257 @@ function hubWorkflow(options, internalOptions = {}) {
|
|
|
5145
5526
|
registryFile: artifacts.registryFile
|
|
5146
5527
|
};
|
|
5147
5528
|
}
|
|
5529
|
+
let devRootDir;
|
|
5530
|
+
let devStartupPlugin;
|
|
5531
|
+
let devWorkflow;
|
|
5532
|
+
function resolveDevWorkflow() {
|
|
5533
|
+
try {
|
|
5534
|
+
return normalizeWorkflowOptions(workflow, { hosting: internalOptions.hosting ?? "vercel" });
|
|
5535
|
+
} catch {
|
|
5536
|
+
return;
|
|
5537
|
+
}
|
|
5538
|
+
}
|
|
5539
|
+
async function writeDevRegistry(rootDir, workflow) {
|
|
5540
|
+
return await writeWorkflowDevRegistryFiles({
|
|
5541
|
+
definitions: workflow === false ? [] : discoverWorkflowDevDefinitions(rootDir, serverDirs),
|
|
5542
|
+
importBase: internalOptions.importBase,
|
|
5543
|
+
projectRoot: rootDir,
|
|
5544
|
+
pluginPath: devStartupPlugin,
|
|
5545
|
+
workflow
|
|
5546
|
+
});
|
|
5547
|
+
}
|
|
5148
5548
|
return {
|
|
5149
5549
|
name: "@vite-hub/workflow/vite",
|
|
5150
|
-
config
|
|
5151
|
-
|
|
5152
|
-
|
|
5550
|
+
config: {
|
|
5551
|
+
order: "pre",
|
|
5552
|
+
async handler(config, env) {
|
|
5553
|
+
workflow = config.workflow === void 0 ? defaultWorkflow : config.workflow;
|
|
5554
|
+
serverDirs = config[VITEHUB_SERVER_DIRS];
|
|
5555
|
+
const buildConfig = config;
|
|
5556
|
+
buildConfig.__vitehubWorkflowServerDirs = serverDirs;
|
|
5557
|
+
if (env.command !== "serve") return;
|
|
5558
|
+
devWorkflow = resolveDevWorkflow();
|
|
5559
|
+
const projectRoot = Reflect.get(config, VITEHUB_PROJECT_ROOT);
|
|
5560
|
+
devRootDir = resolveViteHubProjectRoot(resolve(config.root || process.cwd()), { projectRoot: typeof projectRoot === "string" ? projectRoot : void 0 });
|
|
5561
|
+
const { plugin } = await writeDevRegistry(devRootDir, devWorkflow ?? false);
|
|
5562
|
+
devStartupPlugin = plugin;
|
|
5563
|
+
const kit = createNitroServerKit(Reflect.get(config, "nitro"));
|
|
5564
|
+
kit.addPlugin(plugin, "start");
|
|
5565
|
+
Reflect.set(config, "nitro", kit.config);
|
|
5566
|
+
}
|
|
5567
|
+
},
|
|
5568
|
+
configureServer(server) {
|
|
5569
|
+
const rootDir = devRootDir;
|
|
5570
|
+
const workflowConfig = devWorkflow;
|
|
5571
|
+
if (!rootDir || !workflowConfig) return;
|
|
5572
|
+
const watchedDirectories = (serverDirs ?? [resolve(rootDir, "server")]).map((directory) => resolve(rootDir, directory));
|
|
5573
|
+
server.watcher.add([...watchedDirectories, rootDir]);
|
|
5574
|
+
const refresh = async (path) => {
|
|
5575
|
+
const file = path.replace(/\\/g, "/");
|
|
5576
|
+
if (file.includes(`/.vitehub/nitro/workflow/`)) return;
|
|
5577
|
+
const environment = server.environments.nitro ?? server.environments.ssr;
|
|
5578
|
+
const registryPath = resolve(rootDir, workflowDevGeneratedDir, "dev-registry.mjs").replace(/\\/g, "/");
|
|
5579
|
+
const modules = [...environment?.moduleGraph.getModulesByFile(file) ?? []];
|
|
5580
|
+
const visited = /* @__PURE__ */ new Set();
|
|
5581
|
+
let registryDependency = false;
|
|
5582
|
+
while (modules.length) {
|
|
5583
|
+
const module = modules.pop();
|
|
5584
|
+
if (!module) continue;
|
|
5585
|
+
if (visited.has(module)) continue;
|
|
5586
|
+
visited.add(module);
|
|
5587
|
+
if (module.file?.replace(/\\/g, "/") === registryPath) {
|
|
5588
|
+
registryDependency = true;
|
|
5589
|
+
break;
|
|
5590
|
+
}
|
|
5591
|
+
modules.push(...module.importers);
|
|
5592
|
+
}
|
|
5593
|
+
if (!(/\.(?:c|m)?[jt]s$/i.test(file) && /(?:\/workflows\/|\.workflow\.)/i.test(file)) && !registryDependency) return;
|
|
5594
|
+
const { changed } = await writeDevRegistry(rootDir, workflowConfig);
|
|
5595
|
+
const filesToInvalidate = new Set([...changed, resolve(rootDir, workflowDevGeneratedDir, "dev-registry.mjs")].map((file) => file.replace(/\\/g, "/")));
|
|
5596
|
+
let invalidated = false;
|
|
5597
|
+
for (const changedFile of filesToInvalidate) for (const module of environment?.moduleGraph.getModulesByFile(changedFile) ?? []) {
|
|
5598
|
+
environment.moduleGraph.invalidateModule(module);
|
|
5599
|
+
invalidated = true;
|
|
5600
|
+
}
|
|
5601
|
+
if (invalidated) environment?.hot.send({
|
|
5602
|
+
type: "full-reload",
|
|
5603
|
+
triggeredBy: path
|
|
5604
|
+
});
|
|
5605
|
+
};
|
|
5606
|
+
let pendingRefresh = Promise.resolve();
|
|
5607
|
+
for (const event of [
|
|
5608
|
+
"add",
|
|
5609
|
+
"change",
|
|
5610
|
+
"unlink"
|
|
5611
|
+
]) server.watcher.on(event, (path) => {
|
|
5612
|
+
pendingRefresh = pendingRefresh.then(() => refresh(path)).catch((error) => {
|
|
5613
|
+
server.config.logger.error(`[vitehub] Workflow dev registry update failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
5614
|
+
});
|
|
5615
|
+
});
|
|
5153
5616
|
},
|
|
5154
|
-
configResolved(config) {
|
|
5617
|
+
async configResolved(config) {
|
|
5155
5618
|
resolved = config;
|
|
5156
|
-
hasFinalNitroEnvironment = Boolean(config.environments?.nitro);
|
|
5157
5619
|
providerOutput = useProviderOutputCatalog(config);
|
|
5158
|
-
workflow = config.workflow
|
|
5620
|
+
workflow = config.workflow === void 0 ? defaultWorkflow : config.workflow;
|
|
5621
|
+
const buildConfig = config;
|
|
5622
|
+
const buildWithAssociation = config.build;
|
|
5623
|
+
if (buildWithAssociation && !buildWithAssociation[workflowBuildAssociation]) Object.defineProperty(buildWithAssociation, workflowBuildAssociation, {
|
|
5624
|
+
configurable: false,
|
|
5625
|
+
enumerable: true,
|
|
5626
|
+
value: {},
|
|
5627
|
+
writable: false
|
|
5628
|
+
});
|
|
5629
|
+
const environmentAssociation = {};
|
|
5630
|
+
for (const environment of Object.values(config.environments ?? {})) Object.defineProperty(environment, workflowEnvironmentAssociation, {
|
|
5631
|
+
configurable: false,
|
|
5632
|
+
enumerable: false,
|
|
5633
|
+
value: environmentAssociation,
|
|
5634
|
+
writable: false
|
|
5635
|
+
});
|
|
5636
|
+
const buildServerDirs = buildConfig["__vitehubServerDirs"] ?? buildConfig.__vitehubWorkflowServerDirs;
|
|
5637
|
+
serverDirs = buildServerDirs;
|
|
5638
|
+
const scheduled = {
|
|
5639
|
+
config,
|
|
5640
|
+
providerOutput,
|
|
5641
|
+
workflow,
|
|
5642
|
+
serverDirs: buildServerDirs,
|
|
5643
|
+
environmentNames: /* @__PURE__ */ new Set(),
|
|
5644
|
+
environmentAssociation
|
|
5645
|
+
};
|
|
5646
|
+
scheduleBuildConfigs.set(config, scheduled);
|
|
5647
|
+
const configs = (scheduledBuildConfigsByRoot.get(config.root) ?? []).filter((previous) => previous.config !== config);
|
|
5648
|
+
configs.push(scheduled);
|
|
5649
|
+
scheduledBuildConfigsByRoot.set(config.root, configs);
|
|
5650
|
+
if (devRootDir) {
|
|
5651
|
+
const projectRoot = Reflect.get(config, VITEHUB_PROJECT_ROOT);
|
|
5652
|
+
devRootDir = resolveViteHubProjectRoot(config.root, { projectRoot: typeof projectRoot === "string" ? projectRoot : void 0 });
|
|
5653
|
+
devWorkflow = resolveDevWorkflow();
|
|
5654
|
+
await writeDevRegistry(devRootDir, devWorkflow ?? false);
|
|
5655
|
+
}
|
|
5159
5656
|
},
|
|
5160
5657
|
configEnvironment(name, config) {
|
|
5161
5658
|
if (!isServerEnvironment(name, config)) return;
|
|
5162
|
-
return { resolve: { noExternal:
|
|
5659
|
+
return { resolve: { noExternal: noExternalAddition(config.resolve?.noExternal) } };
|
|
5163
5660
|
},
|
|
5164
|
-
vitehub: {
|
|
5165
|
-
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
|
|
5170
|
-
|
|
5171
|
-
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
|
|
5175
|
-
|
|
5176
|
-
|
|
5177
|
-
|
|
5661
|
+
vitehub: {
|
|
5662
|
+
operations: [{
|
|
5663
|
+
export: "workflowOperations",
|
|
5664
|
+
load: async () => (await (import.meta.url.endsWith(".ts") ? import("./operations.js") : import("./operations.js"))).workflowOperations,
|
|
5665
|
+
module: "@vite-hub/workflow/operations"
|
|
5666
|
+
}],
|
|
5667
|
+
inspect: () => {
|
|
5668
|
+
const options = normalizeWorkflowOptions(workflow, { hosting: internalOptions?.hosting ?? "vercel" });
|
|
5669
|
+
const outputs = resolveWorkflowProviderOutputs(workflow, internalOptions?.hosting ?? "vercel");
|
|
5670
|
+
return {
|
|
5671
|
+
definitions: options ? [{
|
|
5672
|
+
kind: "workflow",
|
|
5673
|
+
label: "Workflows",
|
|
5674
|
+
list: () => {
|
|
5675
|
+
const rootDir = resolved?.root ?? process.cwd();
|
|
5676
|
+
return inspectWorkflowDefinitions({
|
|
5677
|
+
projectRoot: resolveViteHubProjectRoot(rootDir),
|
|
5678
|
+
rootDir,
|
|
5679
|
+
serverDirs
|
|
5680
|
+
});
|
|
5681
|
+
}
|
|
5682
|
+
}] : [],
|
|
5683
|
+
providerOutput: (() => {
|
|
5684
|
+
const rootDir = resolveViteHubProjectRoot(resolved?.root ?? process.cwd());
|
|
5685
|
+
if (outputs.cloudflare) return [{
|
|
5686
|
+
description: "Generated Cloudflare Workflow worker",
|
|
5687
|
+
owner: "workflow",
|
|
5688
|
+
path: resolve(createDefaultCloudflareOutputRoot(rootDir), "worker.mjs")
|
|
5689
|
+
}];
|
|
5690
|
+
if (outputs.vercel) return [{
|
|
5691
|
+
description: "Generated Vercel Workflow function",
|
|
5692
|
+
owner: "workflow",
|
|
5693
|
+
path: resolve(createDefaultVercelOutputRoot(rootDir), "functions", resolveNitroVercelFunctionName(resolved ?? {}, "workflow") ?? "__server.func", "index.mjs")
|
|
5694
|
+
}];
|
|
5695
|
+
return [];
|
|
5696
|
+
})()
|
|
5697
|
+
};
|
|
5178
5698
|
},
|
|
5179
|
-
|
|
5180
|
-
|
|
5699
|
+
workflow: {
|
|
5700
|
+
async createNitroConfig({ nitro, projectRoot, serverDirs: nitroServerDirs, transformRegistry }) {
|
|
5701
|
+
return await createCloudflareWorkflowNitroConfig({
|
|
5702
|
+
agentImportBase: internalOptions?.agentImportBase,
|
|
5703
|
+
nitro,
|
|
5704
|
+
rootDir: projectRoot,
|
|
5705
|
+
serverDirs: nitroServerDirs,
|
|
5706
|
+
includeUserAppEntry: internalOptions?.includeUserAppEntry,
|
|
5707
|
+
workflow,
|
|
5708
|
+
workflowImportBase: internalOptions?.importBase,
|
|
5709
|
+
workspaceDependencyRuntimeImports: internalOptions?.workspaceDependencyRuntimeImports,
|
|
5710
|
+
workspaceImportBase: internalOptions?.workspaceImportBase,
|
|
5711
|
+
transformRegistry
|
|
5712
|
+
});
|
|
5713
|
+
},
|
|
5714
|
+
prepareScheduleRuntime
|
|
5715
|
+
}
|
|
5716
|
+
},
|
|
5181
5717
|
buildStart() {
|
|
5182
5718
|
if (shouldSkipProviderOutputEnvironment(this)) return;
|
|
5183
|
-
|
|
5719
|
+
const context = buildEnvironment(this);
|
|
5720
|
+
rejectedBuilds.delete(context);
|
|
5721
|
+
const environmentConfig = this?.environment?.config;
|
|
5722
|
+
if (environmentConfig) {
|
|
5723
|
+
const config = environmentConfig;
|
|
5724
|
+
let scheduled = scheduleBuildConfigs.get(config);
|
|
5725
|
+
try {
|
|
5726
|
+
scheduled ??= scheduledBuildConfig(config, this.environment?.name);
|
|
5727
|
+
} catch (error) {
|
|
5728
|
+
rejectedBuilds.add(context);
|
|
5729
|
+
throw error;
|
|
5730
|
+
}
|
|
5731
|
+
scheduled ??= {
|
|
5732
|
+
config,
|
|
5733
|
+
providerOutput: useProviderOutputCatalog(config),
|
|
5734
|
+
serverDirs: config["__vitehubServerDirs"] ?? config.__vitehubWorkflowServerDirs,
|
|
5735
|
+
workflow: config.workflow ?? defaultWorkflow,
|
|
5736
|
+
environmentNames: /* @__PURE__ */ new Set()
|
|
5737
|
+
};
|
|
5738
|
+
if (this.environment?.name) scheduled.environmentNames.add(this.environment.name);
|
|
5739
|
+
buildConfigs.set(context, {
|
|
5740
|
+
config: environmentConfig,
|
|
5741
|
+
providerOutput: scheduled.providerOutput,
|
|
5742
|
+
serverDirs: scheduled.serverDirs,
|
|
5743
|
+
workflow: scheduled.workflow
|
|
5744
|
+
});
|
|
5745
|
+
} else if (resolved) buildConfigs.set(context, {
|
|
5746
|
+
config: resolved,
|
|
5747
|
+
providerOutput,
|
|
5748
|
+
serverDirs,
|
|
5749
|
+
workflow
|
|
5750
|
+
});
|
|
5751
|
+
providerOutputGenerations.capture(this, buildConfigs.get(context)?.providerOutput ?? providerOutput);
|
|
5184
5752
|
},
|
|
5185
5753
|
async buildEnd(error) {
|
|
5186
|
-
if (shouldSkipProviderOutputEnvironment(this)) return;
|
|
5754
|
+
if (rejectedBuilds.has(buildEnvironment(this)) || shouldSkipProviderOutputEnvironment(this)) return;
|
|
5755
|
+
const build = buildConfigs.get(buildEnvironment(this));
|
|
5187
5756
|
if (error) {
|
|
5188
|
-
await providerOutputGenerations.reset(this, providerOutput, error);
|
|
5757
|
+
await providerOutputGenerations.reset(this, build?.providerOutput ?? providerOutput, error);
|
|
5189
5758
|
return;
|
|
5190
5759
|
}
|
|
5191
|
-
|
|
5192
|
-
const
|
|
5760
|
+
const config = build?.config ?? resolved;
|
|
5761
|
+
const buildProviderOutput = build?.providerOutput ?? providerOutput;
|
|
5762
|
+
if (!config || shouldSkipViteProviderBuild(config.command, getViteMode())) return;
|
|
5193
5763
|
const rootDir = resolveViteHubProjectRoot(config.root);
|
|
5194
5764
|
const plugins = config.plugins;
|
|
5195
5765
|
const generation = providerOutputGenerations.get(this);
|
|
5196
5766
|
const environment = generation ?? buildEnvironment(this);
|
|
5197
5767
|
const artifactDir = resolve(rootDir, ".vitehub/workflow-generations", randomUUID());
|
|
5198
|
-
const workflowOptions = workflow;
|
|
5199
|
-
const workflowServerDirs = serverDirs;
|
|
5768
|
+
const workflowOptions = build ? build.workflow : workflow;
|
|
5769
|
+
const workflowServerDirs = build ? build.serverDirs : serverDirs;
|
|
5200
5770
|
const transformRegistry = plugins.find((plugin) => plugin.vitehub?.agent?.transformWorkflowRegistry)?.vitehub?.agent?.transformWorkflowRegistry;
|
|
5201
5771
|
try {
|
|
5202
|
-
const importAliases = await providerImportAliases();
|
|
5772
|
+
const importAliases = await providerImportAliases(config);
|
|
5203
5773
|
const runtimeImportAliases = {
|
|
5204
|
-
cloudflare: providerRuntimeImportAliases("cloudflare", generation),
|
|
5205
|
-
vercel: providerRuntimeImportAliases("vercel", generation)
|
|
5774
|
+
cloudflare: providerRuntimeImportAliases("cloudflare", generation, buildProviderOutput),
|
|
5775
|
+
vercel: providerRuntimeImportAliases("vercel", generation, buildProviderOutput)
|
|
5206
5776
|
};
|
|
5207
5777
|
const providerSources = discoverWorkflowProviderSources(config.root, workflowServerDirs);
|
|
5208
|
-
const
|
|
5778
|
+
const outputs = resolveWorkflowProviderOutputs(workflowOptions, internalOptions?.hosting);
|
|
5779
|
+
const retainedSources = !outputs.cloudflare && !outputs.vercel ? { resolve: (path) => path } : await retainProviderOutputSources({
|
|
5209
5780
|
artifactDir: resolve(artifactDir, "sources"),
|
|
5210
5781
|
paths: [
|
|
5211
5782
|
...Object.keys(importAliases),
|
|
@@ -5233,7 +5804,7 @@ function hubWorkflow(options, internalOptions = {}) {
|
|
|
5233
5804
|
workspaceDependencies: internalOptions?.workspaceDependencyRuntimeImports
|
|
5234
5805
|
}, retainedServerDirs, internalOptions?.includeUserAppEntry, transformRegistry, retainedDefinitionRoot, resolve(artifactDir, "output"), retainedAgentInstructions);
|
|
5235
5806
|
stagedArtifactDirs.set(environment, artifactDir);
|
|
5236
|
-
contributeProviderDeploymentOutput(
|
|
5807
|
+
contributeProviderDeploymentOutput(buildProviderOutput, {
|
|
5237
5808
|
discard: async () => {
|
|
5238
5809
|
await removeProviderOutputArtifactDir(artifactDir);
|
|
5239
5810
|
if (stagedArtifactDirs.get(environment) === artifactDir) stagedArtifactDirs.delete(environment);
|
|
@@ -5245,10 +5816,12 @@ function hubWorkflow(options, internalOptions = {}) {
|
|
|
5245
5816
|
agentImportBase: internalOptions?.agentImportBase,
|
|
5246
5817
|
artifacts,
|
|
5247
5818
|
clientOutDir: resolve(config.root, config.build.outDir),
|
|
5819
|
+
bundleDefines: resolveViteHubBundleDefines(config),
|
|
5248
5820
|
hosting: internalOptions?.hosting,
|
|
5249
5821
|
importBase: internalOptions?.importBase,
|
|
5250
5822
|
providerImportAliases: retainedImportAliases,
|
|
5251
5823
|
providerRuntimeImportAliases: retainedRuntimeImportAliases,
|
|
5824
|
+
vercelRuntimePackages: getVercelRuntimePackages(buildProviderOutput, "blob", generation),
|
|
5252
5825
|
rootDir,
|
|
5253
5826
|
definitionRootDir: retainedDefinitionRoot,
|
|
5254
5827
|
serverDirs: retainedServerDirs,
|
|
@@ -5265,14 +5838,15 @@ function hubWorkflow(options, internalOptions = {}) {
|
|
|
5265
5838
|
} catch (error) {
|
|
5266
5839
|
await removeProviderOutputArtifactDir(artifactDir);
|
|
5267
5840
|
if (stagedArtifactDirs.get(environment) === artifactDir) stagedArtifactDirs.delete(environment);
|
|
5268
|
-
await providerOutputGenerations.reset(this,
|
|
5841
|
+
await providerOutputGenerations.reset(this, buildProviderOutput, error);
|
|
5269
5842
|
throw error;
|
|
5270
5843
|
}
|
|
5271
5844
|
},
|
|
5272
5845
|
async renderError(error) {
|
|
5273
|
-
if (shouldSkipProviderOutputEnvironment(this)) return;
|
|
5846
|
+
if (rejectedBuilds.has(buildEnvironment(this)) || shouldSkipProviderOutputEnvironment(this)) return;
|
|
5274
5847
|
const environment = providerOutputGenerations.get(this) ?? buildEnvironment(this);
|
|
5275
|
-
|
|
5848
|
+
const build = buildConfigs.get(buildEnvironment(this));
|
|
5849
|
+
await providerOutputGenerations.reset(this, build?.providerOutput ?? providerOutput, error);
|
|
5276
5850
|
const artifactDir = stagedArtifactDirs.get(environment);
|
|
5277
5851
|
if (artifactDir) {
|
|
5278
5852
|
await removeProviderOutputArtifactDir(artifactDir);
|
|
@@ -5283,12 +5857,14 @@ function hubWorkflow(options, internalOptions = {}) {
|
|
|
5283
5857
|
order: "post",
|
|
5284
5858
|
sequential: true,
|
|
5285
5859
|
async handler() {
|
|
5286
|
-
if (shouldSkipProviderOutputEnvironment(this)) return;
|
|
5287
|
-
|
|
5288
|
-
|
|
5860
|
+
if (rejectedBuilds.has(buildEnvironment(this)) || shouldSkipProviderOutputEnvironment(this)) return;
|
|
5861
|
+
const build = buildConfigs.get(buildEnvironment(this));
|
|
5862
|
+
const config = build?.config ?? resolved;
|
|
5863
|
+
if (!config || shouldSkipViteProviderBuild(config.command, getViteMode())) return;
|
|
5864
|
+
await finalizeProviderDeploymentOutputs(build?.providerOutput ?? providerOutput);
|
|
5289
5865
|
}
|
|
5290
5866
|
}
|
|
5291
5867
|
};
|
|
5292
5868
|
}
|
|
5293
5869
|
//#endregion
|
|
5294
|
-
export { discoverWorkflowDefinitions, hubWorkflow };
|
|
5870
|
+
export { discoverWorkflowDefinitions, hubWorkflow, inspectWorkflowDefinitions, workflowConsoleSection };
|