@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.
Files changed (45) hide show
  1. package/README.md +34 -14
  2. package/dist/{_app-DgwN4ulW.d.ts → app-BojnC_yf.d.ts} +1 -4
  3. package/dist/{app-BZpq2cwC.js → app-CzPoP84f.js} +2 -1
  4. package/dist/client-DsGM3M4U.js +389 -0
  5. package/dist/cloudflare-env-BNrYo29x.js +113 -0
  6. package/dist/{cloudflare-D0Di-QYL.js → cloudflare-nF4abPd4.js} +20 -4
  7. package/dist/cloudflare-shared-CaxrMD1A.d.ts +1 -0
  8. package/dist/{cloudflare-vite-BkDgB6Sr.js → cloudflare-vite-B3IabBsv.js} +5 -4
  9. package/dist/{config-BHknO_rT.js → config-IJMb0eeZ.js} +38 -30
  10. package/dist/error-diagnostics-A_8Kp-48.js +116 -0
  11. package/dist/error-diagnostics-pwNFvAHP.js +67 -0
  12. package/dist/index.d.ts +20 -21
  13. package/dist/index.js +25 -369
  14. package/dist/inspect-B72iFyj-.js +70 -0
  15. package/dist/operations-B_rYG71W.js +230 -0
  16. package/dist/operations-tNUdj3G4.d.ts +212 -0
  17. package/dist/operations.d.ts +37 -0
  18. package/dist/operations.js +887 -0
  19. package/dist/out-CsaJxg8m.js +21755 -0
  20. package/dist/rolldown-runtime-CMFfr-1z.js +26 -0
  21. package/dist/runtime/cloudflare-runner.d.ts +5 -15
  22. package/dist/runtime/cloudflare-runner.js +40 -5
  23. package/dist/runtime/cloudflare-shared.d.ts +1 -0
  24. package/dist/runtime/cloudflare-shared.js +1 -1
  25. package/dist/runtime/cloudflare-vite.d.ts +8 -10
  26. package/dist/runtime/cloudflare-vite.js +1 -1
  27. package/dist/runtime/execute.d.ts +8 -7
  28. package/dist/runtime/execute.js +28 -5
  29. package/dist/runtime/openworkflow-worker.d.ts +6 -8
  30. package/dist/runtime/openworkflow-worker.js +5 -4
  31. package/dist/runtime/openworkflow.d.ts +8 -10
  32. package/dist/runtime/openworkflow.js +23 -17
  33. package/dist/runtime/state.d.ts +20 -21
  34. package/dist/runtime/state.js +90 -20
  35. package/dist/runtime/vercel-vite.d.ts +10 -12
  36. package/dist/runtime/vercel-vite.js +2 -2
  37. package/dist/runtime-type-DBCvIh5x.js +7 -0
  38. package/dist/{types-B9RdRkKh.d.ts → types-D82WmfZa.d.ts} +23 -12
  39. package/dist/{vercel-B0MuIVgJ.js → vercel-D-ZNtB_u.js} +34 -9
  40. package/dist/vite.d.ts +325 -11
  41. package/dist/vite.js +1267 -691
  42. package/package.json +79 -29
  43. package/dist/cloudflare-env-DjxQNbrx.js +0 -58
  44. package/dist/cloudflare-shared-BVVgDSdq.d.ts +0 -1
  45. package/dist/runtime-type-DGUn8Ple.js +0 -37
package/dist/vite.js CHANGED
@@ -1,44 +1,20 @@
1
- import { n as isPlainObject, r as normalizeHosting, t as normalizeWorkflowOptions } from "./config-BHknO_rT.js";
2
- import { r as getCloudflareWorkflowClassName, t as createCloudflareWorkflowBindings } from "./cloudflare-D0Di-QYL.js";
3
- import { n as isRuntimeRecord, t as hasRuntimeType } from "./runtime-type-DGUn8Ple.js";
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 { createHash, randomUUID } from "node:crypto";
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
- const VITEHUB_MODES = {
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(/[?#]/, 1)[0];
298
+ const path = id.split("?", 1)[0];
362
299
  if (queryIndex === -1) return path.endsWith(markdownTemplateFileSuffix) ? { path } : void 0;
363
- const query = id.slice(queryIndex + 1).split("#", 1)[0];
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, sourceId, imports = {}) {
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, sourceId: vitehubMarkdownTemplateSourceId, resolveImport: (specifier, importer) => vitehubMarkdownTemplateImports[`${importer}\\0${specifier}`] })",
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 (async () => {
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), { recursive: true })));
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, { recursive: true });
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 new TypeError("[vitehub] Provider output config must be a JSON object.");
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 importPath = relative$1(realpathIfExists(dirname$1(fromFile)), realpathIfExists(targetFile));
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/source-scanner.ts
787
- function isQuote(char) {
788
- return char === "\"" || char === "'" || char === "`";
789
- }
790
- function skipQuoted(source, index, controlFlowRegexes = /* @__PURE__ */ new Map()) {
791
- const quote = source[index];
792
- if (quote === "`") return skipTemplateLiteral(source, index, controlFlowRegexes);
793
- index += 1;
794
- while (index < source.length) {
795
- if (source[index] === "\\") {
796
- index += 2;
797
- continue;
798
- }
799
- if (source[index] === quote) return index + 1;
800
- index += 1;
801
- }
802
- return index;
803
- }
804
- function skipTemplateLiteral(source, index, controlFlowRegexes) {
805
- index += 1;
806
- let expressionDepth = 0;
807
- let previousSignificant = "";
808
- while (index < source.length) {
809
- const char = source[index];
810
- const next = source[index + 1];
811
- if (char === "\\") {
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 isControlFlowRegexStart(source, index, controlFlowRegexes = /* @__PURE__ */ new Map()) {
907
- const cached = controlFlowRegexes.get(index);
908
- if (cached !== void 0) return cached;
909
- if (controlFlowRegexes.has(index)) return true;
910
- controlFlowRegexes.set(index, void 0);
911
- try {
912
- const closeParen = previousCodeIndex(source, index - 1, controlFlowRegexes);
913
- if (source[closeParen] !== ")") {
914
- controlFlowRegexes.set(index, false);
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
- for (let current = closeParen; current >= 0; current--) {
918
- if (source[current] !== "(") continue;
919
- if (findMatching(source, current, "(", ")", controlFlowRegexes) !== closeParen) continue;
920
- const head = source.slice(0, current).replace(/\/\*[\s\S]*?\*\/|\/\/[^\n]*/g, " ");
921
- const result = /(?:^|[^\w$])(?:catch|for|if|while|with)\s*$/.test(head);
922
- controlFlowRegexes.set(index, result);
923
- return result;
924
- }
925
- controlFlowRegexes.set(index, false);
926
- return false;
927
- } catch (error) {
928
- controlFlowRegexes.delete(index);
929
- throw error;
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
- return `${serializedPublishedSourcesDir}${suffix.replaceAll("\\\\", serializedPublishedSeparator).replaceAll("/", serializedPublishedSeparator)}`;
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 = maskSourceLiterals(source);
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 = (expression) => {
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 = findMatching(normalized, openParen, "(", ")");
1387
- if (closeParen === void 0 || normalized.slice(closeParen + 1).trim()) return file;
1388
- const [relativeUrl, baseUrl] = splitTopLevel(normalized.slice(openParen + 1, closeParen));
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 = findMatching(masked, openParen, "(", ")");
1398
- const base = closeParen === void 0 ? file : createRequireBase(source.slice(openParen + 1, closeParen));
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 = findMatching(masked, openParen, "(", ")");
1410
- const base = closeParen === void 0 ? file : createRequireBase(source.slice(openParen + 1, closeParen));
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 = findMatching(masked, openParen, "(", ")");
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 = findMatching(masked, invocationOpenParen, "(", ")");
1206
+ const invocationCloseParen = matchingDelimiter(masked, invocationOpenParen);
1464
1207
  if (invocationCloseParen === void 0) continue;
1465
- const [target] = splitTopLevel(source.slice(invocationOpenParen + 1, invocationCloseParen));
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(source.slice(openParen + 1, closeParen)));
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
- traceComputedModuleSources(request.path, source, (runtimeRequest) => {
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 traceComputedModuleSources(file, source)) {
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 = [...new Set([
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) || relative(root, source).split(sep).includes("node_modules")) return 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
- this.#runtimeContributions.clear();
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 = [["package.json"]];
2249
- function createNoExternalMerger(packageName) {
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 true;
2252
- if (!current) return [packageName];
2086
+ if (current === true) return;
2253
2087
  const values = Array.isArray(current) ? current : [current];
2254
- return values.includes(packageName) ? values : [...values, packageName];
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)) return 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
- for (const marker of projectRootFileMarkers) try {
2307
- if (statSync(resolve(root, ...marker)).isFile()) return true;
2308
- } catch (error) {
2309
- if (error.code !== "ENOENT") throw error;
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 new TypeError(`Invalid Provider Output ownership file name: ${JSON.stringify(fileName)}`);
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 new TypeError(`Invalid Provider Output ownership file schema: ${JSON.stringify(fileName)}`);
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 new TypeError(`Provider Output ownership file for ${JSON.stringify(field)} requires array ownership.`);
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 new Error(`Invalid Netlify function name: ${functionName}`);
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
- await writeFile(outfile, `${(await readFile(outfile, "utf8")).trimEnd()}\n\nexport const config = ${stringifyProviderOutputConfig(config)}\n`, "utf8");
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 new Error(`Cloudflare output file conflicts with bundle outfile: ${workerOutfile}`);
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
- minifyIdentifiers: func.config ? true : func.bundleOptions.minifyIdentifiers,
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(/* @__PURE__ */ new Error("Provider Output finalization reset"));
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(writeOptions, controller.signal, transaction);
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/agent-workflow.ts
3275
- function getAgentInvocationRecoveryWorkflowName(agentWorkflowName) {
3276
- return `vitehub-agent-invocation-recovery-${agentWorkflowName}`;
3277
- }
3278
- //#endregion
3279
- //#region ../internal/src/build/colocated-agent-files.ts
3280
- function formatSize(bytes) {
3281
- const mebibyte = 1024 * 1024;
3282
- return bytes % mebibyte === 0 ? `${bytes / mebibyte} MiB` : `${bytes} bytes`;
3283
- }
3284
- function isFolderAgentEntry(file) {
3285
- if (!/^(?:agent|index)\.(?:c|m)?[jt]s$/i.test(basename(file))) return false;
3286
- return !(basename(file).toLowerCase().startsWith("agent.") && basename(dirname(file)) === "agents" && basename(dirname(dirname(file))) === "server");
3287
- }
3288
- function colocatedAgentFilesRoot(handler, directoryName) {
3289
- if (!isFolderAgentEntry(handler)) return;
3290
- const root = join(dirname(handler), directoryName);
3291
- return existsSync(root) ? root : void 0;
3292
- }
3293
- function resolveColocatedAgentFilesRoot(handler, directoryName) {
3294
- const root = colocatedAgentFilesRoot(handler, directoryName);
3295
- return root && statSync(root).isDirectory() ? root : void 0;
3296
- }
3297
- function readColocatedAgentFiles(handler, directoryName, options = {}) {
3298
- const root = colocatedAgentFilesRoot(handler, directoryName);
3299
- if (!root) return;
3300
- if (!(options.rejectUnsupportedEntries ? lstatSync(root) : statSync(root)).isDirectory()) {
3301
- if (options.rejectUnsupportedEntries) throw new Error(`[vitehub] ${options.label || "Colocated Agent files"} supports regular files and directories only: ${directoryName}`);
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 new Error(`Duplicate ${sourceLabel} name "${definition.name}":\n - ${existing.handler}\n - ${definition.handler}`);
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 new Error(`Duplicate ${feature} name "${definition.name}" from multiple discovery sources:\n - ${existing.handler} (${existing.source ?? "unknown"})\n - ${definition.handler} (${definition.source ?? "unknown"})`);
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) => source.pattern.test(name), { includeHidden: source.includeHidden })) {
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 new TypeError(`Expected ${label} to contain a JSON record.`);
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 = [...new Set([
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 source = dirname(dirname(dirname(createRequire(import.meta.url).resolve("workflow/internal/builtins"))));
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 = [...new Set([...definitions.map((definition) => dirname(definition.handler)), ...nativeFiles.map((file) => dirname(file))])];
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: readFileSync(file, "utf8"),
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 new Error(`Native Vercel workflow entry ${JSON.stringify(relative(rootDir, file))} must be colocated with its discovered workflow definition.`);
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 new Error(`Native Vercel Workflow output conflicts with existing unowned Workflow DevKit functions: ${externalCanonicalFiles.join(", ")}. Build all native Workflow source directories together.`);
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 new Error("Native Vercel workflows require the optional workflow and @workflow/builders peer dependencies.");
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 = [...new Set([...definitions.map((definition) => dirname(definition.handler)), ...nativeFiles.map((file) => dirname(file))])];
4203
- const builder = new builders.VercelBuildOutputAPIBuilder({
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 [...new Set([external, ...cloudflareRuntimeModules])];
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 [...new Set([...external, ...cloudflareRuntimeModules])];
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 ${getCloudflareWorkflowClassName(definition.name)} extends WorkflowEntrypoint {`,
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.map((definition) => getCloudflareWorkflowClassName(definition.name)).join(", ")} } from './${fileName}'\n`,
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
- return existsSync(instructions) && statSync(instructions).isFile() ? resolveInstructionFile(instructions, /* @__PURE__ */ new Set(), dependencies) : void 0;
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 = `skills/${path}`;
4656
+ const workspacePath = `.agents/skills/${path}`;
4390
4657
  return [`__vitehubAgentSkill:${workspacePath}`, {
4391
4658
  ...source,
4392
- materialize: "build",
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(workspaceAgentWithSourceRoot(agentWithColocatedInstructions("default" in loaded ? loaded.default : loaded, ${JSON.stringify(instructions)}), ${JSON.stringify(resolveAgentWorkspaceSourceRoot(definition.handler))}, ${JSON.stringify(instructions)}), ${JSON.stringify(readAgentSkills(definition.handler))})`,
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.sandbox ? [` sandbox: () => import(${JSON.stringify(workspaceDependencyRuntimeImports.sandbox)}),`] : [],
4504
- ...workspaceDependencyRuntimeImports.sandboxRuntimeState ? [` sandboxRuntimeState: () => import(${JSON.stringify(workspaceDependencyRuntimeImports.sandboxRuntimeState)}),`] : [],
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 ${getCloudflareWorkflowClassName(definition.name)} extends WorkflowEntrypoint {`,
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 new Error(`Workflow name ${JSON.stringify(recoveryName)} conflicts with the generated Agent invocation recovery Workflow for ${JSON.stringify(definition.name)}.`);
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
- await writeFile(entryFile, renderProviderEntry(spec, entryFile, userAppEntry, JSON.stringify(workflowConfig, null, 2), importBases.workflow ?? "@vite-hub/workflow", Boolean(importBases.workflow)), "utf8");
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 workflows = createCloudflareWorkflowBindings(workflowConfig ? artifacts.providerDefinitions : [], workflowConfig);
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 inferredWorkflowConfig = options.hosting ? resolveWorkflowConfig(options.workflow, options.hosting) : void 0;
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 mergeNoExternal = createNoExternalMerger(workflowPackageName);
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
- let workflow = internalOptions.implicitlyEnabled && normalizeHosting(internalOptions.hosting).includes("netlify") ? false : options;
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 viteHubNitroContext = resolved && Reflect.get(resolved, "__vitehubNitroConfigContext") === true;
5086
- return Boolean(environmentName && environmentName !== (hasFinalNitroEnvironment ? "nitro" : "ssr") && viteHubNitroContext);
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 providerRuntimeImportAliases(provider, generation) {
5089
- const database = getProviderRuntimeModule(providerOutput, "database", provider, generation);
5090
- return database ? { "@vite-hub/database/drizzle": database } : {};
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 (!resolved) return { ...internalOptions?.providerImportAliases };
5094
- const contributedAliases = await collectViteHubProviderImportAliases(resolved.plugins);
5470
+ async function providerImportAliases(config = resolved) {
5471
+ if (!config) return { ...internalOptions?.providerImportAliases };
5472
+ const contributedAliases = await collectViteHubProviderImportAliases(config.plugins);
5095
5473
  return {
5096
- ...resolveStringAliases(resolved),
5474
+ ...resolveStringAliases(config),
5097
5475
  ...contributedAliases,
5098
5476
  ...internalOptions?.providerImportAliases
5099
5477
  };
5100
5478
  }
5101
- async function prepareScheduleRuntime(artifactDir) {
5102
- if (!resolved) throw new Error("[vitehub] Workflow runtime preparation requires resolved Vite config.");
5103
- if (normalizeWorkflowOptions(workflow, { hosting: internalOptions?.hosting ?? "vercel" })?.provider !== "vercel") return;
5104
- const rootDir = resolveViteHubProjectRoot(resolved.root);
5105
- const aliases = await providerImportAliases();
5106
- const providerSources = discoverWorkflowProviderSources(resolved.root, serverDirs);
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: [resolved.root]
5495
+ roots: [config.root]
5115
5496
  }) : void 0;
5116
- const definitionRootDir = retainedSources?.resolve(resolved.root) ?? resolved.root;
5117
- const retainedServerDirs = serverDirs?.map((directory) => retainedSources?.resolve(directory) ?? directory);
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, workflow, {
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, resolved.plugins.find((plugin) => plugin.vitehub?.agent?.transformWorkflowRegistry)?.vitehub?.agent?.transformWorkflowRegistry, definitionRootDir, artifactDir ? resolve(artifactDir, "output") : void 0, retainedAgentInstructions);
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(resolved.root, "package.json"));
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": createRequire(workflowRequire.resolve("@workflow/builders")).resolve("@workflow/world-vercel"),
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(config) {
5151
- workflow = config.workflow ?? workflow;
5152
- serverDirs = config["__vitehubServerDirs"] ?? serverDirs;
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 ?? 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: mergeNoExternal(config.resolve?.noExternal) } };
5659
+ return { resolve: { noExternal: noExternalAddition(config.resolve?.noExternal) } };
5163
5660
  },
5164
- vitehub: { workflow: {
5165
- async createNitroConfig({ nitro, projectRoot, serverDirs: nitroServerDirs, transformRegistry }) {
5166
- return await createCloudflareWorkflowNitroConfig({
5167
- agentImportBase: internalOptions?.agentImportBase,
5168
- nitro,
5169
- rootDir: projectRoot,
5170
- serverDirs: nitroServerDirs,
5171
- includeUserAppEntry: internalOptions?.includeUserAppEntry,
5172
- workflow,
5173
- workflowImportBase: internalOptions?.importBase,
5174
- workspaceDependencyRuntimeImports: internalOptions?.workspaceDependencyRuntimeImports,
5175
- workspaceImportBase: internalOptions?.workspaceImportBase,
5176
- transformRegistry
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
- prepareScheduleRuntime
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
- providerOutputGenerations.capture(this, providerOutput);
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
- if (!resolved || shouldSkipViteProviderBuild(resolved.command, getViteMode())) return;
5192
- const config = resolved;
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 retainedSources = await retainProviderOutputSources({
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(providerOutput, {
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, providerOutput, error);
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
- await providerOutputGenerations.reset(this, providerOutput, error);
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
- if (!resolved || shouldSkipViteProviderBuild(resolved.command, getViteMode())) return;
5288
- await finalizeProviderDeploymentOutputs(providerOutput);
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 };