@cedarjs/vite 4.2.1-next.0 → 4.2.1-next.269

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 (73) hide show
  1. package/bins/cedar-unified-dev.mjs +7 -0
  2. package/dist/apiDevMiddleware.d.ts.map +1 -1
  3. package/dist/apiDevMiddleware.js +18 -5
  4. package/dist/buildApp.d.ts +2 -1
  5. package/dist/buildApp.d.ts.map +1 -1
  6. package/dist/buildApp.js +151 -26
  7. package/dist/buildFeServer.d.ts.map +1 -1
  8. package/dist/buildFeServer.js +1 -1
  9. package/dist/buildRouteHooks.d.ts.map +1 -1
  10. package/dist/buildRouteHooks.js +7 -3
  11. package/dist/cedar-unified-dev.d.ts +13 -2
  12. package/dist/cedar-unified-dev.d.ts.map +1 -1
  13. package/dist/cedar-unified-dev.js +171 -16
  14. package/dist/cjs/apiDevMiddleware.js +18 -5
  15. package/dist/cjs/buildApp.js +154 -29
  16. package/dist/cjs/buildFeServer.js +1 -1
  17. package/dist/cjs/buildRouteHooks.js +17 -3
  18. package/dist/cjs/cedar-unified-dev.js +184 -16
  19. package/dist/cjs/devFeServer.js +2 -1
  20. package/dist/cjs/index.js +18 -8
  21. package/dist/cjs/lib/getMergedConfig.js +12 -4
  22. package/dist/cjs/lib/workspacePackageAliases.js +2 -8
  23. package/dist/cjs/plugins/vite-plugin-cedar-context-wrapping.js +95 -0
  24. package/dist/cjs/plugins/vite-plugin-cedar-entry-injection.js +20 -5
  25. package/dist/cjs/plugins/vite-plugin-cedar-remove-dev-fatal-error-page.js +61 -0
  26. package/dist/cjs/plugins/vite-plugin-cedar-routes-auto-loader.js +126 -0
  27. package/dist/cjs/plugins/vite-plugin-cedar-universal-deploy.js +202 -14
  28. package/dist/cjs/runFeServer.js +2 -1
  29. package/dist/cjs/utils.js +2 -1
  30. package/dist/devFeServer.d.ts +1 -0
  31. package/dist/devFeServer.js +2 -1
  32. package/dist/index.d.ts +4 -0
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +14 -8
  35. package/dist/lib/getMergedConfig.d.ts.map +1 -1
  36. package/dist/lib/getMergedConfig.js +12 -4
  37. package/dist/lib/workspacePackageAliases.d.ts.map +1 -1
  38. package/dist/lib/workspacePackageAliases.js +2 -8
  39. package/dist/plugins/vite-plugin-cedar-context-wrapping.d.ts +44 -0
  40. package/dist/plugins/vite-plugin-cedar-context-wrapping.d.ts.map +1 -0
  41. package/dist/plugins/vite-plugin-cedar-context-wrapping.js +60 -0
  42. package/dist/plugins/vite-plugin-cedar-entry-injection.d.ts.map +1 -1
  43. package/dist/plugins/vite-plugin-cedar-entry-injection.js +20 -5
  44. package/dist/plugins/vite-plugin-cedar-remove-dev-fatal-error-page.d.ts +15 -0
  45. package/dist/plugins/vite-plugin-cedar-remove-dev-fatal-error-page.d.ts.map +1 -0
  46. package/dist/plugins/vite-plugin-cedar-remove-dev-fatal-error-page.js +37 -0
  47. package/dist/plugins/vite-plugin-cedar-routes-auto-loader.d.ts +24 -0
  48. package/dist/plugins/vite-plugin-cedar-routes-auto-loader.d.ts.map +1 -0
  49. package/dist/plugins/vite-plugin-cedar-routes-auto-loader.js +98 -0
  50. package/dist/plugins/vite-plugin-cedar-universal-deploy.d.ts.map +1 -1
  51. package/dist/plugins/vite-plugin-cedar-universal-deploy.js +202 -14
  52. package/dist/runFeServer.d.ts +1 -0
  53. package/dist/runFeServer.d.ts.map +1 -1
  54. package/dist/runFeServer.js +2 -1
  55. package/dist/utils.d.ts.map +1 -1
  56. package/dist/utils.js +2 -1
  57. package/package.json +31 -61
  58. package/dist/buildUDApiServer.d.ts +0 -24
  59. package/dist/buildUDApiServer.d.ts.map +0 -1
  60. package/dist/buildUDApiServer.js +0 -41
  61. package/dist/cjs/buildUDApiServer.js +0 -75
  62. package/dist/cjs/ud-handlers/catch-all.js +0 -65
  63. package/dist/cjs/ud-handlers/function.js +0 -47
  64. package/dist/cjs/ud-handlers/graphql.js +0 -59
  65. package/dist/ud-handlers/catch-all.d.ts +0 -15
  66. package/dist/ud-handlers/catch-all.d.ts.map +0 -1
  67. package/dist/ud-handlers/catch-all.js +0 -41
  68. package/dist/ud-handlers/function.d.ts +0 -5
  69. package/dist/ud-handlers/function.d.ts.map +0 -1
  70. package/dist/ud-handlers/function.js +0 -23
  71. package/dist/ud-handlers/graphql.d.ts +0 -7
  72. package/dist/ud-handlers/graphql.d.ts.map +0 -1
  73. package/dist/ud-handlers/graphql.js +0 -35
@@ -50,9 +50,14 @@ function getMergedConfig(cedarConfig, cedarPaths) {
50
50
  apiPort = cedarConfig.api.port;
51
51
  }
52
52
  const defaultCedarViteConfig = {
53
- root: cedarPaths.web.src,
53
+ root: cedarPaths.web.base,
54
54
  resolve: {
55
- alias: workspaceAliases
55
+ alias: {
56
+ ...workspaceAliases,
57
+ // In test mode, register the virtual module alias so that
58
+ // MockProviders can resolve the user's Routes file
59
+ ...env.mode === "test" ? { "~__CEDAR__USER_ROUTES_FOR_MOCK": cedarPaths.web.routes } : {}
60
+ }
56
61
  },
57
62
  // @MARK: when we have these aliases, the warnings from the FE server go
58
63
  // away BUT, if you have imports like this:
@@ -104,7 +109,7 @@ function getMergedConfig(cedarConfig, cedarPaths) {
104
109
  // Note that sourcemap can be boolean or 'inline'
105
110
  sourcemap: !env.isSsrBuild && cedarConfig.web.sourceMap,
106
111
  rollupOptions: {
107
- input: getRollupInput(!!env.isSsrBuild)
112
+ input: getRollupInput(userConfig, !!env.isSsrBuild)
108
113
  }
109
114
  },
110
115
  // @MARK: do not set buildSsrCjsExternalHeuristics here
@@ -137,9 +142,12 @@ function getMergedConfig(cedarConfig, cedarPaths) {
137
142
  return (0, import_vite.mergeConfig)(defaultCedarViteConfig, userConfig);
138
143
  };
139
144
  }
140
- function getRollupInput(ssr) {
145
+ function getRollupInput(userConfig, ssr) {
141
146
  const cedarConfig = (0, import_project_config.getConfig)();
142
147
  const cedarPaths = (0, import_project_config.getPaths)();
148
+ if (userConfig.build?.rollupOptions?.input) {
149
+ return userConfig.build.rollupOptions.input;
150
+ }
143
151
  if (!cedarPaths.web.entryClient) {
144
152
  throw new Error("entryClient not defined");
145
153
  }
@@ -34,6 +34,7 @@ module.exports = __toCommonJS(workspacePackageAliases_exports);
34
34
  var import_node_fs = __toESM(require("node:fs"), 1);
35
35
  var import_node_path = __toESM(require("node:path"), 1);
36
36
  var import_vite = require("vite");
37
+ var import_workspaces = require("@cedarjs/project-config/workspaces");
37
38
  function findSourceEntry(pkgDir, pkgJson) {
38
39
  let distEntry = null;
39
40
  if (typeof pkgJson.main === "string") {
@@ -71,14 +72,7 @@ function getWorkspacePackageAliases(cedarPaths, cedarConfig) {
71
72
  return {};
72
73
  }
73
74
  try {
74
- const rootPkgPath = import_node_path.default.join(cedarPaths.base, "package.json");
75
- const rootPkg = JSON.parse(import_node_fs.default.readFileSync(rootPkgPath, "utf-8"));
76
- if (!Array.isArray(rootPkg.workspaces) || rootPkg.workspaces.length <= 2) {
77
- return {};
78
- }
79
- const nonApiWebWorkspaces = rootPkg.workspaces.filter(
80
- (w) => w !== "api" && w !== "web"
81
- );
75
+ const nonApiWebWorkspaces = (0, import_workspaces.getNonApiWebWorkspaces)(cedarPaths.base);
82
76
  if (nonApiWebWorkspaces.length === 0) {
83
77
  return {};
84
78
  }
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var vite_plugin_cedar_context_wrapping_exports = {};
30
+ __export(vite_plugin_cedar_context_wrapping_exports, {
31
+ applyContextWrapping: () => applyContextWrapping,
32
+ cedarContextWrappingPlugin: () => cedarContextWrappingPlugin
33
+ });
34
+ module.exports = __toCommonJS(vite_plugin_cedar_context_wrapping_exports);
35
+ var import_node_path = __toESM(require("node:path"), 1);
36
+ var import_vite = require("vite");
37
+ var import_project_config = require("@cedarjs/project-config");
38
+ function cedarContextWrappingPlugin({
39
+ projectIsEsm = false
40
+ } = {}) {
41
+ return {
42
+ name: "cedar-context-wrapping",
43
+ transform(code, id) {
44
+ let paths;
45
+ try {
46
+ paths = (0, import_project_config.getPaths)();
47
+ } catch {
48
+ return null;
49
+ }
50
+ const functionsDir = (0, import_vite.normalizePath)(import_node_path.default.join(paths.api.src, "functions"));
51
+ if (!(0, import_vite.normalizePath)(id).startsWith(functionsDir + "/")) {
52
+ return null;
53
+ }
54
+ const wrapped = applyContextWrapping(code, { projectIsEsm });
55
+ return wrapped ? { code: wrapped, map: null } : null;
56
+ }
57
+ };
58
+ }
59
+ function applyContextWrapping(code, { projectIsEsm = false } = {}) {
60
+ const handlerRe = /^export\s+(?:const|let|var)\s+handler(?:[^=]|=>)*?=(?![>=])/m;
61
+ const handlerMatch = handlerRe.exec(code);
62
+ if (!handlerMatch) {
63
+ return null;
64
+ }
65
+ const afterEquals = code.slice(handlerMatch.index + handlerMatch[0].length).trimStart();
66
+ const isAsync = /^async(?:\s*[\(\*]|\s+function)/.test(afterEquals);
67
+ const storePath = projectIsEsm ? "@cedarjs/context/dist/store.js" : "@cedarjs/context/dist/store";
68
+ const importStatement = `import { getAsyncStoreInstance as __rw_getAsyncStoreInstance } from '${storePath}'
69
+ `;
70
+ const handlerStart = handlerMatch.index;
71
+ const before = code.slice(0, handlerStart);
72
+ const after = code.slice(handlerStart);
73
+ const renamed = after.replace(handlerRe, "const __rw_handler =");
74
+ const wrappedHandler = `
75
+ export const handler = ${isAsync ? "async " : ""}(__rw_event, __rw__context) => {
76
+ // The store will be undefined if no context isolation has been performed yet
77
+ const __rw_contextStore = __rw_getAsyncStoreInstance().getStore()
78
+ if (__rw_contextStore === undefined) {
79
+ return __rw_getAsyncStoreInstance().run(
80
+ new Map(),
81
+ __rw_handler,
82
+ __rw_event,
83
+ __rw__context
84
+ )
85
+ }
86
+ return __rw_handler(__rw_event, __rw__context)
87
+ }
88
+ `;
89
+ return before + importStatement + renamed + wrappedHandler;
90
+ }
91
+ // Annotate the CommonJS export names for ESM import in node:
92
+ 0 && (module.exports = {
93
+ applyContextWrapping,
94
+ cedarContextWrappingPlugin
95
+ });
@@ -36,21 +36,36 @@ var import_node_path = __toESM(require("node:path"), 1);
36
36
  var import_vite = require("vite");
37
37
  var import_project_config = require("@cedarjs/project-config");
38
38
  function cedarEntryInjectionPlugin() {
39
- const rwPaths = (0, import_project_config.getPaths)();
40
- const clientEntryPath = rwPaths.web.entryClient;
39
+ const cedarPaths = (0, import_project_config.getPaths)();
40
+ const clientEntryPath = cedarPaths.web.entryClient;
41
41
  if (!clientEntryPath) {
42
42
  throw new Error(
43
43
  "Vite client entry point not found. Please check that your project has an entry.client.{jsx,tsx} file in the web/src directory."
44
44
  );
45
45
  }
46
- const relativeEntryPath = import_node_path.default.relative(rwPaths.web.src, clientEntryPath);
46
+ const relativeEntryPath = (0, import_vite.normalizePath)(
47
+ import_node_path.default.relative(cedarPaths.web.base, clientEntryPath)
48
+ );
47
49
  return {
48
50
  name: "cedar-entry-injection",
51
+ // Vite's dependency optimizer and dev server resolve the script tag
52
+ // src="/src/entry.client.{tsx,jsx}" as an absolute filesystem path
53
+ // (/src/entry.client.tsx) instead of relative to the Vite root.
54
+ // This hook maps it to the real file path so Vite can find it.
55
+ resolveId(id) {
56
+ if (id === "/" + relativeEntryPath) {
57
+ return clientEntryPath;
58
+ }
59
+ return null;
60
+ },
49
61
  // ---------- Bundle injection ----------
50
62
  // Used by Vite during dev, to inject the entrypoint.
51
63
  transformIndexHtml: {
52
64
  order: "pre",
53
- handler: (html) => {
65
+ handler: (html, ctx) => {
66
+ if (!ctx.filename || (0, import_vite.normalizePath)(ctx.filename) !== (0, import_vite.normalizePath)(cedarPaths.web.html)) {
67
+ return html;
68
+ }
54
69
  if (import_node_fs.default.existsSync(clientEntryPath)) {
55
70
  return html.replace(
56
71
  "</head>",
@@ -67,7 +82,7 @@ function cedarEntryInjectionPlugin() {
67
82
  // Used by rollup during build to inject the entrypoint
68
83
  // but note index.html does not come through as an id during dev
69
84
  transform: (code, id) => {
70
- if (import_node_fs.default.existsSync(clientEntryPath) && (0, import_vite.normalizePath)(id) === (0, import_vite.normalizePath)(rwPaths.web.html)) {
85
+ if (import_node_fs.default.existsSync(clientEntryPath) && (0, import_vite.normalizePath)(id) === (0, import_vite.normalizePath)(cedarPaths.web.html)) {
71
86
  return {
72
87
  code: code.replace(
73
88
  "</head>",
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var vite_plugin_cedar_remove_dev_fatal_error_page_exports = {};
20
+ __export(vite_plugin_cedar_remove_dev_fatal_error_page_exports, {
21
+ cedarRemoveDevFatalErrorPage: () => cedarRemoveDevFatalErrorPage
22
+ });
23
+ module.exports = __toCommonJS(vite_plugin_cedar_remove_dev_fatal_error_page_exports);
24
+ const DEV_FATAL_ERROR_PAGE_MODULE = "@cedarjs/web/dist/components/DevFatalErrorPage";
25
+ function escapeRegExp(s) {
26
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
27
+ }
28
+ const ESCAPED_MODULE = escapeRegExp(DEV_FATAL_ERROR_PAGE_MODULE);
29
+ const IMPORT_PATTERN = new RegExp(
30
+ `import\\s*\\{[^}]*\\bDevFatalErrorPage\\b[^}]*\\}\\s*from\\s*['"]${ESCAPED_MODULE}['"]`
31
+ );
32
+ function cedarRemoveDevFatalErrorPage() {
33
+ let config;
34
+ return {
35
+ name: "cedar-remove-dev-fatal-error-page",
36
+ apply: "build",
37
+ configResolved(resolvedConfig) {
38
+ config = resolvedConfig;
39
+ },
40
+ transform(code) {
41
+ if (config.command === "build" && config.mode === "development") {
42
+ return null;
43
+ }
44
+ if (!code.includes(DEV_FATAL_ERROR_PAGE_MODULE)) {
45
+ return null;
46
+ }
47
+ const newCode = code.replace(
48
+ IMPORT_PATTERN,
49
+ "const DevFatalErrorPage = undefined"
50
+ );
51
+ if (newCode === code) {
52
+ return null;
53
+ }
54
+ return { code: newCode, map: null };
55
+ }
56
+ };
57
+ }
58
+ // Annotate the CommonJS export names for ESM import in node:
59
+ 0 && (module.exports = {
60
+ cedarRemoveDevFatalErrorPage
61
+ });
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var vite_plugin_cedar_routes_auto_loader_exports = {};
30
+ __export(vite_plugin_cedar_routes_auto_loader_exports, {
31
+ cedarRoutesAutoLoaderPlugin: () => cedarRoutesAutoLoaderPlugin
32
+ });
33
+ module.exports = __toCommonJS(vite_plugin_cedar_routes_auto_loader_exports);
34
+ var import_node_fs = __toESM(require("node:fs"), 1);
35
+ var import_node_path = __toESM(require("node:path"), 1);
36
+ var import_vite = require("vite");
37
+ var import_project_config = require("@cedarjs/project-config");
38
+ function getPathRelativeToSrc(maybeAbsolutePath) {
39
+ const withoutExt = maybeAbsolutePath.replace(/\.[^/.]+$/, "");
40
+ if (withoutExt.startsWith("src/")) {
41
+ const basePath = import_node_path.default.join((0, import_project_config.getPaths)().web.base, withoutExt);
42
+ const resolved = (0, import_project_config.resolveFile)(basePath) || (0, import_project_config.resolveFile)(import_node_path.default.join(basePath, "index")) || (0, import_project_config.resolveFile)(import_node_path.default.join(basePath, import_node_path.default.basename(basePath)));
43
+ if (resolved) {
44
+ const resolvedWithoutExt = resolved.replace(/\.[^/.]+$/, "");
45
+ return "./" + import_node_path.default.relative((0, import_project_config.getPaths)().web.src, resolvedWithoutExt);
46
+ }
47
+ return "./" + withoutExt.slice("src/".length);
48
+ }
49
+ if (!import_node_path.default.isAbsolute(withoutExt)) {
50
+ return withoutExt;
51
+ }
52
+ return `./${import_node_path.default.relative((0, import_project_config.getPaths)().web.src, withoutExt)}`;
53
+ }
54
+ function withRelativeImports(page) {
55
+ return {
56
+ ...page,
57
+ relativeImport: (0, import_project_config.ensurePosixPath)(getPathRelativeToSrc(page.importPath))
58
+ };
59
+ }
60
+ function cedarRoutesAutoLoaderPlugin() {
61
+ const routesFileId = (0, import_vite.normalizePath)((0, import_project_config.getPaths)().web.routes);
62
+ const initialPages = (0, import_project_config.processPagesDir)().map(withRelativeImports);
63
+ const duplicatePageImportNames = /* @__PURE__ */ new Set();
64
+ const sortedPageImportNames = initialPages.map((page) => page.importName).sort();
65
+ for (let i = 0; i < sortedPageImportNames.length - 1; i++) {
66
+ if (sortedPageImportNames[i + 1] === sortedPageImportNames[i]) {
67
+ duplicatePageImportNames.add(sortedPageImportNames[i]);
68
+ }
69
+ }
70
+ if (duplicatePageImportNames.size > 0) {
71
+ const pageNames = Array.from(duplicatePageImportNames).map((name) => `'${name}'`).join(", ");
72
+ throw new Error(
73
+ `Unable to find only a single file ending in 'Page.{js,jsx,ts,tsx}' in the following page directories: ${pageNames}`
74
+ );
75
+ }
76
+ return {
77
+ name: "cedar-routes-auto-loader",
78
+ transform(code, id) {
79
+ if ((0, import_vite.normalizePath)(id) !== routesFileId) {
80
+ return null;
81
+ }
82
+ let pages = (0, import_project_config.processPagesDir)().map(withRelativeImports);
83
+ const importRe = /^import\s+\w+\s+from\s+['"]([^'"]+)['"]/gm;
84
+ const appPath = (0, import_project_config.resolveFile)(import_node_path.default.join((0, import_project_config.getPaths)().web.src, "App"));
85
+ if (appPath) {
86
+ const appSource = import_node_fs.default.readFileSync(appPath, "utf8");
87
+ let appMatch;
88
+ while ((appMatch = importRe.exec(appSource)) !== null) {
89
+ const rel = (0, import_project_config.ensurePosixPath)(
90
+ getPathRelativeToSrc((0, import_project_config.importStatementPath)(appMatch[1]))
91
+ );
92
+ pages = pages.filter((page) => page.relativeImport !== rel);
93
+ }
94
+ }
95
+ importRe.lastIndex = 0;
96
+ let routesMatch;
97
+ while ((routesMatch = importRe.exec(code)) !== null) {
98
+ const rel = (0, import_project_config.ensurePosixPath)(
99
+ getPathRelativeToSrc((0, import_project_config.importStatementPath)(routesMatch[1]))
100
+ );
101
+ pages = pages.filter((page) => page.relativeImport !== rel);
102
+ }
103
+ if (pages.length === 0) {
104
+ return null;
105
+ }
106
+ const lines = [`import { lazy } from 'react'`];
107
+ for (const { importName, relativeImport } of pages) {
108
+ lines.push(
109
+ `const ${importName} = {`,
110
+ ` name: "${importName}",`,
111
+ ` prerenderLoader: (name) => ({ default: globalThis.__REDWOOD__PRERENDER_PAGES[name] }),`,
112
+ ` LazyComponent: lazy(() => import("${relativeImport}")),`,
113
+ `}`
114
+ );
115
+ }
116
+ return {
117
+ code: lines.join("\n") + "\n\n" + code,
118
+ map: null
119
+ };
120
+ }
121
+ };
122
+ }
123
+ // Annotate the CommonJS export names for ESM import in node:
124
+ 0 && (module.exports = {
125
+ cedarRoutesAutoLoaderPlugin
126
+ });
@@ -97,25 +97,39 @@ function toEntryMeta(route) {
97
97
  };
98
98
  }
99
99
  function cedarUniversalDeployPlugin(options = {}) {
100
- const { apiRootPath } = options;
101
- const routes = discoverCedarRoutes(apiRootPath ?? "/");
102
- let entriesInjected = false;
100
+ const effectiveApiRootPath = process.env.CEDAR_API_ROOT_PATH ?? options.apiRootPath;
101
+ const routes = discoverCedarRoutes(effectiveApiRootPath ?? "/");
103
102
  return {
104
103
  name: "cedar-universal-deploy",
105
104
  apply: "build",
106
105
  config: {
107
106
  order: "pre",
108
107
  handler() {
109
- if (entriesInjected) {
110
- return;
111
- }
112
- entriesInjected = true;
113
108
  for (const route of routes) {
114
109
  (0, import_store.addEntry)(toEntryMeta(route));
115
110
  }
116
111
  }
117
112
  },
113
+ buildStart() {
114
+ if (this.environment.name !== "ssr") {
115
+ return;
116
+ }
117
+ for (const route of routes) {
118
+ const resolvedId = RESOLVED_CEDAR_FN_PREFIX + route.id;
119
+ const safeName = route.id.replace(/[/\\?%*:|"<>]/g, "_").replace(/^_+/, "");
120
+ this.emitFile({
121
+ type: "chunk",
122
+ id: resolvedId,
123
+ // Emit the functions into a sub-dir to "hide" them from Netlify
124
+ fileName: "chunks/" + safeName + "-handler.js"
125
+ });
126
+ }
127
+ },
118
128
  resolveId(id) {
129
+ const viteEnv = this.environment;
130
+ if (viteEnv.config.consumer === "client" || viteEnv.name === "api") {
131
+ return void 0;
132
+ }
119
133
  if (id.startsWith(RESOLVED_CEDAR_FN_PREFIX)) {
120
134
  return id;
121
135
  }
@@ -124,7 +138,11 @@ function cedarUniversalDeployPlugin(options = {}) {
124
138
  }
125
139
  return void 0;
126
140
  },
127
- load(id) {
141
+ async load(id) {
142
+ const viteEnv = this.environment;
143
+ if (viteEnv.config.consumer === "client" || viteEnv.name === "api") {
144
+ return void 0;
145
+ }
128
146
  if (id.startsWith(RESOLVED_CEDAR_FN_PREFIX)) {
129
147
  const routeId = id.slice(RESOLVED_CEDAR_FN_PREFIX.length);
130
148
  const route = routes.find((r) => r.id === routeId);
@@ -140,16 +158,186 @@ function cedarUniversalDeployPlugin(options = {}) {
140
158
  }
141
159
  };
142
160
  }
143
- function generateGraphQLModule(distPath) {
161
+ async function bundleDistFile(distPath, options = {}) {
162
+ const { build } = await import("esbuild");
163
+ const buildOptions = {
164
+ bundle: true,
165
+ write: false,
166
+ format: "esm",
167
+ platform: "node",
168
+ target: "node24",
169
+ plugins: [
170
+ {
171
+ name: "ud-external",
172
+ setup(build2) {
173
+ build2.onResolve({ filter: /^[^.]/ }, (args) => {
174
+ if (import_node_path.default.isAbsolute(args.path)) {
175
+ return;
176
+ }
177
+ if (args.path.startsWith("api/")) {
178
+ return;
179
+ }
180
+ return { external: true };
181
+ });
182
+ }
183
+ }
184
+ ],
185
+ logLevel: "silent"
186
+ };
187
+ if (options.include && options.include.length > 0) {
188
+ const resolveDir = import_node_path.default.dirname(distPath);
189
+ const relativeDistPath = "./" + import_node_path.default.basename(distPath);
190
+ const exportList = options.include.join(", ");
191
+ buildOptions.stdin = {
192
+ // Use stdin to define a synthetic entry point that exports only the
193
+ // requested named exports
194
+ contents: `export { ${exportList} } from ${JSON.stringify(relativeDistPath)}`,
195
+ resolveDir,
196
+ loader: "js"
197
+ };
198
+ } else {
199
+ buildOptions.entryPoints = [distPath];
200
+ }
201
+ const result = await build(buildOptions);
202
+ if (!result.outputFiles || result.outputFiles.length === 0) {
203
+ throw new Error("esbuild bundle produced no output files");
204
+ }
205
+ let text = result.outputFiles[0].text;
206
+ const exportBlock = text.match(/\nexport\s*\{([^}]*)\};\s*$/);
207
+ if (exportBlock) {
208
+ const defaultExportMatch = exportBlock[1].match(
209
+ /(?:^|,)\s*(\w+)\s+as\s+default\s*(?:,|$)/
210
+ );
211
+ if (defaultExportMatch) {
212
+ const defaultBinding = defaultExportMatch[1];
213
+ text = text.replace(/\nexport\s*\{[^}]*\};\s*$/, "") + `
214
+ const __cedar_default = ${defaultBinding};`;
215
+ } else {
216
+ text = text.replace(/\nexport\s*\{[^}]*\};\s*$/, "");
217
+ }
218
+ }
219
+ return text;
220
+ }
221
+ async function generateGraphQLModule(distPath) {
222
+ const bundledCode = await bundleDistFile(distPath, {
223
+ include: ["__cedar_graphqlOptions"]
224
+ });
144
225
  return `
145
- import { createGraphQLHandler } from '@cedarjs/vite/ud-handlers/graphql';
146
- export default createGraphQLHandler({ distPath: ${JSON.stringify(distPath)} });
226
+ import { buildCedarContext, requestToLegacyEvent } from '@cedarjs/api/runtime';
227
+ import { createGraphQLYoga } from '@cedarjs/graphql-server';
228
+
229
+ // Inlined bundle of ${import_node_path.default.basename(distPath)} (node_modules kept external)
230
+ ${bundledCode}
231
+
232
+ let yogaInitPromise = null;
233
+
234
+ function getYoga() {
235
+ if (!yogaInitPromise) {
236
+ yogaInitPromise = createGraphQLYoga(__cedar_graphqlOptions).then(
237
+ ({ yoga }) => ({ yoga, graphqlOptions: __cedar_graphqlOptions })
238
+ );
239
+ }
240
+ return yogaInitPromise;
241
+ }
242
+
243
+ export default {
244
+ async fetch(request) {
245
+ const { yoga, graphqlOptions } = await getYoga();
246
+ const cedarContext = await buildCedarContext(request, {
247
+ authDecoder: graphqlOptions ? graphqlOptions.authDecoder : undefined,
248
+ });
249
+ const event = await requestToLegacyEvent(request, cedarContext);
250
+ // Wrap yoga.handle in an AsyncLocalStorage run so directive
251
+ // validators can read from the global @cedarjs/context. Without
252
+ // this, the auth plugin's setContext() call writes to a store
253
+ // that's only visible inside the plugin's own callback \u2014 not
254
+ // during directive validation.
255
+ const { getAsyncStoreInstance } = await import('@cedarjs/context/dist/store')
256
+ const store = getAsyncStoreInstance()
257
+
258
+ return store.run(new Map(), () => {
259
+ return yoga.handle(request, {
260
+ request,
261
+ cedarContext,
262
+ event,
263
+ requestContext: undefined,
264
+ })
265
+ }).then((response) => {
266
+ // GraphQL Yoga returns a PonyfillResponse from @whatwg-node/fetch
267
+ // which is not an instanceof the native Response class. Netlify's
268
+ // bootstrap checks instanceof Response, so we wrap it.
269
+ return new Response(response.body, {
270
+ status: response.status,
271
+ statusText: response.statusText,
272
+ headers: response.headers,
273
+ })
274
+ }).catch((e) => {
275
+ if (e?.code === 'ERR_STREAM_PREMATURE_CLOSE') {
276
+ // Client disconnected while the request was being processed (e.g.,
277
+ // page navigation, tab close). Return a 499 so the runtime doesn't
278
+ // treat this as a 500.
279
+ return new Response(null, { status: 499 })
280
+ }
281
+
282
+ throw e
283
+ })
284
+ }
285
+ };
147
286
  `;
148
287
  }
149
- function generateFunctionModule(distPath) {
288
+ async function generateFunctionModule(distPath) {
289
+ const bundledCode = await bundleDistFile(distPath);
290
+ const notFoundMsg = JSON.stringify(
291
+ `Handler not found in ${import_node_path.default.basename(distPath)}. Expected \`export async function handleRequest(request, ctx)\`, \`export default async (request, ctx) => Response\`, \`export default { handleRequest }\`, or a legacy Lambda-shaped \`handler\`.`
292
+ );
150
293
  return `
151
- import { createFunctionHandler } from '@cedarjs/vite/ud-handlers/function';
152
- export default createFunctionHandler({ distPath: ${JSON.stringify(distPath)} });
294
+ import { wrapLegacyHandler, buildCedarContext } from '@cedarjs/api/runtime';
295
+
296
+ // Inlined bundle of ${import_node_path.default.basename(distPath)} (node_modules kept external)
297
+ ${bundledCode}
298
+
299
+ const nativeHandler = (() => {
300
+ // Prefer named handleRequest export
301
+ if (typeof handleRequest !== 'undefined') { return handleRequest; }
302
+ // Handle export default { handleRequest } pattern
303
+ if (typeof __cedar_default !== 'undefined' && __cedar_default && typeof __cedar_default.handleRequest === 'function') {
304
+ return __cedar_default.handleRequest;
305
+ }
306
+ // Handle plain default-exported async function: export default async (req) => Response
307
+ if (typeof __cedar_default !== 'undefined' && typeof __cedar_default === 'function') {
308
+ return __cedar_default;
309
+ }
310
+ return undefined;
311
+ })();
312
+
313
+ const legacyFn = (() => {
314
+ if (typeof handler !== 'undefined') { return handler; }
315
+ if (typeof __cedar_default !== 'undefined' && __cedar_default && typeof __cedar_default.handler === 'function') {
316
+ return __cedar_default.handler;
317
+ }
318
+ return undefined;
319
+ })();
320
+
321
+ if (!nativeHandler && !legacyFn) {
322
+ throw new Error(${notFoundMsg});
323
+ }
324
+
325
+ const _handler = nativeHandler ?? wrapLegacyHandler(legacyFn);
326
+
327
+ export default {
328
+ async fetch(request) {
329
+ const ctx = await buildCedarContext(request);
330
+ // Wrap the handler in an AsyncLocalStorage run so the global
331
+ // @cedarjs/context is available inside it (and isolated per request).
332
+ // Mirrors the GraphQL module above and the cedarContextWrappingPlugin
333
+ // used for non-UD builds.
334
+ const { getAsyncStoreInstance } = await import(
335
+ '@cedarjs/context/dist/store'
336
+ );
337
+ const store = getAsyncStoreInstance();
338
+ return store.run(new Map(), () => _handler(request, ctx));
339
+ }
340
+ };
153
341
  `;
154
342
  }
155
343
  // Annotate the CommonJS export names for ESM import in node:
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env node
1
2
  "use strict";
2
3
  var __create = Object.create;
3
4
  var __defProp = Object.defineProperty;
@@ -74,7 +75,7 @@ async function runFeServer() {
74
75
  import_node_path.default.join(rwPaths.web.distBrowser, "client-build-manifest.json")
75
76
  ).href;
76
77
  const clientBuildManifest = (await import(clientBuildManifestUrl, { with: { type: "json" } })).default;
77
- const clientEntry = rscEnabled ? clientBuildManifest["entry.client.tsx"] || clientBuildManifest["entry.client.jsx"] : Object.values(clientBuildManifest).find(
78
+ const clientEntry = rscEnabled ? clientBuildManifest["src/entry.client.tsx"] || clientBuildManifest["src/entry.client.jsx"] : Object.values(clientBuildManifest).find(
78
79
  (manifestItem) => manifestItem.isEntry
79
80
  );
80
81
  if (!clientEntry) {