@cedarjs/vite 5.0.0-canary.13896 → 5.0.0-canary.13898

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.
@@ -6,8 +6,9 @@ export interface BuildUDApiServerOptions {
6
6
  * Builds the API server Universal Deploy Node entry using Vite.
7
7
  *
8
8
  * Runs a Vite server build that:
9
- * 1. Installs `cedarUniversalDeployPlugin()` to register `virtual:cedar-api`
10
- * and resolve `virtual:ud:catch-all` Cedar's aggregate fetch dispatcher
9
+ * 1. Installs `cedarUniversalDeployPlugin()` to register per-route API
10
+ * entries (GraphQL, auth, functions) with UD's store and resolve
11
+ * `virtual:ud:catch-all` → Cedar's multi-route rou3 dispatcher.
11
12
  * 2. Installs `node()` from `@universal-deploy/node/vite` to emit a
12
13
  * self-contained Node server entry at `api/dist/ud/index.js`
13
14
  *
@@ -1 +1 @@
1
- {"version":3,"file":"buildUDApiServer.d.ts","sourceRoot":"","sources":["../src/buildUDApiServer.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,uBAAuB;IACtC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,gBAAgB,GAAU,4BAGpC,uBAA4B,kBA+D9B,CAAA"}
1
+ {"version":3,"file":"buildUDApiServer.d.ts","sourceRoot":"","sources":["../src/buildUDApiServer.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,uBAAuB;IACtC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,gBAAgB,GAAU,4BAGpC,uBAA4B,kBA+D9B,CAAA"}
@@ -16,8 +16,8 @@ const buildUDApiServer = async ({
16
16
  envFile: false,
17
17
  logLevel: verbose ? "info" : "warn",
18
18
  plugins: [
19
- // Registers virtual:cedar-api with @universal-deploy/store and resolves
20
- // virtual:ud:catch-all → virtual:cedar-api → Cedar's aggregate fetchable.
19
+ // Registers per-route API entries with @universal-deploy/store and
20
+ // resolves virtual:ud:catch-all → Cedar's multi-route rou3 dispatcher.
21
21
  cedarUniversalDeployPlugin({ apiRootPath }),
22
22
  // Emits a self-contained Node server entry (api/dist/ud/index.js) that
23
23
  // imports virtual:ud:catch-all and starts an srvx HTTP server.
@@ -49,8 +49,8 @@ const buildUDApiServer = async ({
49
49
  envFile: false,
50
50
  logLevel: verbose ? "info" : "warn",
51
51
  plugins: [
52
- // Registers virtual:cedar-api with @universal-deploy/store and resolves
53
- // virtual:ud:catch-all → virtual:cedar-api → Cedar's aggregate fetchable.
52
+ // Registers per-route API entries with @universal-deploy/store and
53
+ // resolves virtual:ud:catch-all → Cedar's multi-route rou3 dispatcher.
54
54
  cedarUniversalDeployPlugin({ apiRootPath }),
55
55
  // Emits a self-contained Node server entry (api/dist/ud/index.js) that
56
56
  // imports virtual:ud:catch-all and starts an srvx HTTP server.
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
8
  var __export = (target, all) => {
7
9
  for (var name in all)
@@ -15,48 +17,170 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
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
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
  var vite_plugin_cedar_universal_deploy_exports = {};
20
30
  __export(vite_plugin_cedar_universal_deploy_exports, {
21
31
  cedarUniversalDeployPlugin: () => cedarUniversalDeployPlugin
22
32
  });
23
33
  module.exports = __toCommonJS(vite_plugin_cedar_universal_deploy_exports);
34
+ var import_node_path = __toESM(require("node:path"), 1);
24
35
  var import_store = require("@universal-deploy/store");
25
- const VIRTUAL_CEDAR_API = "virtual:cedar-api";
26
- const RESOLVED_VIRTUAL_CEDAR_API = "\0virtual:cedar-api";
36
+ var import_files = require("@cedarjs/internal/dist/files.js");
37
+ var import_project_config = require("@cedarjs/project-config");
38
+ const VIRTUAL_CEDAR_FN_PREFIX = "virtual:cedar-api:fn:";
39
+ const RESOLVED_CEDAR_FN_PREFIX = "\0virtual:cedar-api:fn:";
40
+ const RESOLVED_VIRTUAL_UD_CATCH_ALL = "\0virtual:ud:catch-all";
41
+ const GRAPHQL_METHODS = ["GET", "POST", "OPTIONS"];
42
+ function normalizeApiRootPath(rootPath) {
43
+ let normalized = rootPath;
44
+ if (!normalized.startsWith("/")) {
45
+ normalized = "/" + normalized;
46
+ }
47
+ if (!normalized.endsWith("/")) {
48
+ normalized = normalized + "/";
49
+ }
50
+ return normalized;
51
+ }
52
+ function discoverCedarRoutes() {
53
+ const srcFunctions = (0, import_project_config.getPaths)().api.functions;
54
+ const distFunctions = import_node_path.default.join((0, import_project_config.getPaths)().api.base, "dist", "functions");
55
+ const sourceFiles = (0, import_files.findApiServerFunctions)(srcFunctions);
56
+ const routes = [];
57
+ for (const sourcePath of sourceFiles) {
58
+ const relative = import_node_path.default.relative(srcFunctions, sourcePath);
59
+ const { dir, name, ext: _ext } = import_node_path.default.parse(relative);
60
+ let routeName;
61
+ if (dir === name) {
62
+ routeName = dir;
63
+ } else if (dir === "") {
64
+ routeName = name;
65
+ } else if (dir.length && name === "index") {
66
+ routeName = dir;
67
+ } else {
68
+ continue;
69
+ }
70
+ const routePath = routeName === "graphql" ? "/graphql" : `/${routeName}`;
71
+ const methods = routeName === "graphql" ? [...GRAPHQL_METHODS] : [];
72
+ const type = routeName === "graphql" ? "graphql" : routeName === "health" ? "health" : routeName.toLowerCase().includes("auth") ? "auth" : "function";
73
+ const distPath = import_node_path.default.join(distFunctions, dir, name + ".js");
74
+ routes.push({
75
+ id: routePath,
76
+ path: routePath,
77
+ methods,
78
+ type,
79
+ entry: distPath
80
+ });
81
+ }
82
+ const gqlIndex = routes.findIndex((r) => r.type === "graphql");
83
+ if (gqlIndex > 0) {
84
+ const [gqlRoute] = routes.splice(gqlIndex, 1);
85
+ routes.unshift(gqlRoute);
86
+ }
87
+ return routes;
88
+ }
89
+ function toEntryMeta(route) {
90
+ const routePatterns = route.path === "/**" ? ["/**"] : [route.path, `${route.path}/**`];
91
+ return {
92
+ id: `${VIRTUAL_CEDAR_FN_PREFIX}${route.id}`,
93
+ route: routePatterns,
94
+ ...route.methods.length > 0 && {
95
+ method: route.methods
96
+ }
97
+ };
98
+ }
27
99
  function cedarUniversalDeployPlugin(options = {}) {
28
100
  const { apiRootPath } = options;
101
+ const normalizedApiRootPath = normalizeApiRootPath(apiRootPath ?? "/");
102
+ const routes = discoverCedarRoutes();
103
+ let entriesInjected = false;
29
104
  return {
30
105
  name: "cedar-universal-deploy",
31
106
  apply: "build",
32
- buildStart() {
33
- (0, import_store.addEntry)({
34
- id: VIRTUAL_CEDAR_API,
35
- route: "/**"
36
- });
107
+ config: {
108
+ order: "pre",
109
+ handler() {
110
+ if (entriesInjected) {
111
+ return;
112
+ }
113
+ entriesInjected = true;
114
+ for (const route of routes) {
115
+ (0, import_store.addEntry)(toEntryMeta(route));
116
+ }
117
+ (0, import_store.addEntry)({
118
+ id: import_store.catchAllEntry,
119
+ route: "/**"
120
+ });
121
+ }
37
122
  },
38
123
  resolveId(id) {
39
124
  if (id === import_store.catchAllEntry) {
40
- return RESOLVED_VIRTUAL_CEDAR_API;
125
+ return RESOLVED_VIRTUAL_UD_CATCH_ALL;
41
126
  }
42
- if (id === VIRTUAL_CEDAR_API) {
43
- return RESOLVED_VIRTUAL_CEDAR_API;
127
+ if (id.startsWith(VIRTUAL_CEDAR_FN_PREFIX)) {
128
+ return "\0" + id;
44
129
  }
45
130
  return void 0;
46
131
  },
47
132
  load(id) {
48
- if (id !== RESOLVED_VIRTUAL_CEDAR_API) {
49
- return void 0;
133
+ if (id.startsWith(RESOLVED_CEDAR_FN_PREFIX)) {
134
+ const routeId = id.slice(RESOLVED_CEDAR_FN_PREFIX.length);
135
+ const route = routes.find((r) => r.id === routeId);
136
+ if (!route) {
137
+ return void 0;
138
+ }
139
+ if (route.type === "graphql") {
140
+ return generateGraphQLModule(route.entry);
141
+ }
142
+ return generateFunctionModule(route.entry);
143
+ }
144
+ if (id === RESOLVED_VIRTUAL_UD_CATCH_ALL) {
145
+ return generateCatchAllModule(routes, normalizedApiRootPath);
50
146
  }
51
- const apiRootPathArg = apiRootPath !== void 0 ? `{ apiRootPath: ${JSON.stringify(apiRootPath)} }` : "undefined";
52
- return `
53
- import { buildCedarDispatcher } from '@cedarjs/api-server/udDispatcher';
54
- const { fetchable } = await buildCedarDispatcher(${apiRootPathArg});
55
- export default fetchable;
56
- `;
147
+ return void 0;
57
148
  }
58
149
  };
59
150
  }
151
+ function generateGraphQLModule(distPath) {
152
+ return `
153
+ import { createGraphQLHandler } from '@cedarjs/vite/ud-handlers/graphql';
154
+ export default createGraphQLHandler({ distPath: ${JSON.stringify(distPath)} });
155
+ `;
156
+ }
157
+ function generateFunctionModule(distPath) {
158
+ return `
159
+ import { createFunctionHandler } from '@cedarjs/vite/ud-handlers/function';
160
+ export default createFunctionHandler({ distPath: ${JSON.stringify(distPath)} });
161
+ `;
162
+ }
163
+ function generateCatchAllModule(routes, normalizedApiRootPath) {
164
+ const imports = routes.map(
165
+ (route, i) => `import mod${i} from '${VIRTUAL_CEDAR_FN_PREFIX}${route.id}';`
166
+ ).join("\n");
167
+ const routesArray = routes.map(
168
+ (route, i) => `{
169
+ path: ${JSON.stringify(route.path)},
170
+ methods: ${JSON.stringify(route.methods)},
171
+ module: mod${i}
172
+ }`
173
+ ).join(", ");
174
+ return `
175
+ import { createCatchAllHandler } from '@cedarjs/vite/ud-handlers/catch-all';
176
+ ${imports}
177
+
178
+ export default createCatchAllHandler({
179
+ routes: [${routesArray}],
180
+ apiRootPath: ${JSON.stringify(normalizedApiRootPath)}
181
+ });
182
+ `;
183
+ }
60
184
  // Annotate the CommonJS export names for ESM import in node:
61
185
  0 && (module.exports = {
62
186
  cedarUniversalDeployPlugin
@@ -0,0 +1,65 @@
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 catch_all_exports = {};
20
+ __export(catch_all_exports, {
21
+ createCatchAllHandler: () => createCatchAllHandler
22
+ });
23
+ module.exports = __toCommonJS(catch_all_exports);
24
+ var import_rou3 = require("rou3");
25
+ function createCatchAllHandler(options) {
26
+ const router = (0, import_rou3.createRouter)();
27
+ for (const route of options.routes) {
28
+ const methods = route.methods.length > 0 ? route.methods : ["GET", "HEAD", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"];
29
+ for (const method of methods) {
30
+ (0, import_rou3.addRoute)(router, method, route.path, route.module);
31
+ (0, import_rou3.addRoute)(router, method, `${route.path}/**`, route.module);
32
+ }
33
+ }
34
+ const apiRootPath = options.apiRootPath;
35
+ function normalizePathname(requestUrl) {
36
+ const url = new URL(requestUrl);
37
+ let pathname = url.pathname;
38
+ if (apiRootPath !== "/" && pathname.startsWith(apiRootPath)) {
39
+ pathname = pathname.slice(apiRootPath.length - 1);
40
+ }
41
+ if (!pathname.startsWith("/")) {
42
+ pathname = "/" + pathname;
43
+ }
44
+ return pathname;
45
+ }
46
+ return {
47
+ async fetch(request) {
48
+ const pathname = normalizePathname(request.url);
49
+ const match = (0, import_rou3.findRoute)(router, request.method, pathname);
50
+ if (!match) {
51
+ return new Response("Not Found", { status: 404 });
52
+ }
53
+ try {
54
+ return await match.data.fetch(request);
55
+ } catch (err) {
56
+ console.error("Unhandled error in fetch handler for", pathname, err);
57
+ return new Response("Internal Server Error", { status: 500 });
58
+ }
59
+ }
60
+ };
61
+ }
62
+ // Annotate the CommonJS export names for ESM import in node:
63
+ 0 && (module.exports = {
64
+ createCatchAllHandler
65
+ });
@@ -0,0 +1,42 @@
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 function_exports = {};
20
+ __export(function_exports, {
21
+ createFunctionHandler: () => createFunctionHandler
22
+ });
23
+ module.exports = __toCommonJS(function_exports);
24
+ var import_node_url = require("node:url");
25
+ var import_udFetchable = require("@cedarjs/api-server/udFetchable");
26
+ function createFunctionHandler(options) {
27
+ const handleRequest = async (request, ctx) => {
28
+ const mod = await import((0, import_node_url.pathToFileURL)(options.distPath).href);
29
+ const handler = mod.handleRequest || mod.default?.handleRequest;
30
+ if (!handler) {
31
+ throw new Error(
32
+ `Fetch-native handler not found in ${options.distPath}. Expected \`export async function handleRequest(request, ctx)\` or \`export default { handleRequest }\`.`
33
+ );
34
+ }
35
+ return handler(request, ctx);
36
+ };
37
+ return (0, import_udFetchable.createCedarFetchable)(handleRequest);
38
+ }
39
+ // Annotate the CommonJS export names for ESM import in node:
40
+ 0 && (module.exports = {
41
+ createFunctionHandler
42
+ });
@@ -0,0 +1,59 @@
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 graphql_exports = {};
20
+ __export(graphql_exports, {
21
+ createGraphQLHandler: () => createGraphQLHandler
22
+ });
23
+ module.exports = __toCommonJS(graphql_exports);
24
+ var import_node_url = require("node:url");
25
+ var import_runtime = require("@cedarjs/api/runtime");
26
+ var import_graphql_server = require("@cedarjs/graphql-server");
27
+ function createGraphQLHandler(options) {
28
+ let yogaInitPromise = null;
29
+ async function getYoga() {
30
+ if (!yogaInitPromise) {
31
+ yogaInitPromise = (async () => {
32
+ const mod = await import((0, import_node_url.pathToFileURL)(options.distPath).href);
33
+ const opts = mod.__rw_graphqlOptions;
34
+ const { yoga } = await (0, import_graphql_server.createGraphQLYoga)(opts);
35
+ return { yoga, graphqlOptions: opts };
36
+ })();
37
+ }
38
+ return yogaInitPromise;
39
+ }
40
+ return {
41
+ async fetch(request) {
42
+ const { yoga, graphqlOptions } = await getYoga();
43
+ const cedarContext = await (0, import_runtime.buildCedarContext)(request, {
44
+ authDecoder: graphqlOptions?.authDecoder
45
+ });
46
+ const event = await (0, import_runtime.requestToLegacyEvent)(request, cedarContext);
47
+ return yoga.handle(request, {
48
+ request,
49
+ cedarContext,
50
+ event,
51
+ requestContext: void 0
52
+ });
53
+ }
54
+ };
55
+ }
56
+ // Annotate the CommonJS export names for ESM import in node:
57
+ 0 && (module.exports = {
58
+ createGraphQLHandler
59
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"vite-plugin-cedar-universal-deploy.d.ts","sourceRoot":"","sources":["../../src/plugins/vite-plugin-cedar-universal-deploy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAElC,MAAM,WAAW,iCAAiC;IAChD,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAKD,wBAAgB,0BAA0B,CACxC,OAAO,GAAE,iCAAsC,GAC9C,MAAM,CA2CR"}
1
+ {"version":3,"file":"vite-plugin-cedar-universal-deploy.d.ts","sourceRoot":"","sources":["../../src/plugins/vite-plugin-cedar-universal-deploy.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAA;AAMlC,MAAM,WAAW,iCAAiC;IAChD,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAyGD,wBAAgB,0BAA0B,CACxC,OAAO,GAAE,iCAAsC,GAC9C,MAAM,CAsER"}
@@ -1,39 +1,153 @@
1
+ import path from "node:path";
1
2
  import { addEntry, catchAllEntry } from "@universal-deploy/store";
2
- const VIRTUAL_CEDAR_API = "virtual:cedar-api";
3
- const RESOLVED_VIRTUAL_CEDAR_API = "\0virtual:cedar-api";
3
+ import { findApiServerFunctions } from "@cedarjs/internal/dist/files.js";
4
+ import { getPaths } from "@cedarjs/project-config";
5
+ const VIRTUAL_CEDAR_FN_PREFIX = "virtual:cedar-api:fn:";
6
+ const RESOLVED_CEDAR_FN_PREFIX = "\0virtual:cedar-api:fn:";
7
+ const RESOLVED_VIRTUAL_UD_CATCH_ALL = "\0virtual:ud:catch-all";
8
+ const GRAPHQL_METHODS = ["GET", "POST", "OPTIONS"];
9
+ function normalizeApiRootPath(rootPath) {
10
+ let normalized = rootPath;
11
+ if (!normalized.startsWith("/")) {
12
+ normalized = "/" + normalized;
13
+ }
14
+ if (!normalized.endsWith("/")) {
15
+ normalized = normalized + "/";
16
+ }
17
+ return normalized;
18
+ }
19
+ function discoverCedarRoutes() {
20
+ const srcFunctions = getPaths().api.functions;
21
+ const distFunctions = path.join(getPaths().api.base, "dist", "functions");
22
+ const sourceFiles = findApiServerFunctions(srcFunctions);
23
+ const routes = [];
24
+ for (const sourcePath of sourceFiles) {
25
+ const relative = path.relative(srcFunctions, sourcePath);
26
+ const { dir, name, ext: _ext } = path.parse(relative);
27
+ let routeName;
28
+ if (dir === name) {
29
+ routeName = dir;
30
+ } else if (dir === "") {
31
+ routeName = name;
32
+ } else if (dir.length && name === "index") {
33
+ routeName = dir;
34
+ } else {
35
+ continue;
36
+ }
37
+ const routePath = routeName === "graphql" ? "/graphql" : `/${routeName}`;
38
+ const methods = routeName === "graphql" ? [...GRAPHQL_METHODS] : [];
39
+ const type = routeName === "graphql" ? "graphql" : routeName === "health" ? "health" : routeName.toLowerCase().includes("auth") ? "auth" : "function";
40
+ const distPath = path.join(distFunctions, dir, name + ".js");
41
+ routes.push({
42
+ id: routePath,
43
+ path: routePath,
44
+ methods,
45
+ type,
46
+ entry: distPath
47
+ });
48
+ }
49
+ const gqlIndex = routes.findIndex((r) => r.type === "graphql");
50
+ if (gqlIndex > 0) {
51
+ const [gqlRoute] = routes.splice(gqlIndex, 1);
52
+ routes.unshift(gqlRoute);
53
+ }
54
+ return routes;
55
+ }
56
+ function toEntryMeta(route) {
57
+ const routePatterns = route.path === "/**" ? ["/**"] : [route.path, `${route.path}/**`];
58
+ return {
59
+ id: `${VIRTUAL_CEDAR_FN_PREFIX}${route.id}`,
60
+ route: routePatterns,
61
+ ...route.methods.length > 0 && {
62
+ method: route.methods
63
+ }
64
+ };
65
+ }
4
66
  function cedarUniversalDeployPlugin(options = {}) {
5
67
  const { apiRootPath } = options;
68
+ const normalizedApiRootPath = normalizeApiRootPath(apiRootPath ?? "/");
69
+ const routes = discoverCedarRoutes();
70
+ let entriesInjected = false;
6
71
  return {
7
72
  name: "cedar-universal-deploy",
8
73
  apply: "build",
9
- buildStart() {
10
- addEntry({
11
- id: VIRTUAL_CEDAR_API,
12
- route: "/**"
13
- });
74
+ config: {
75
+ order: "pre",
76
+ handler() {
77
+ if (entriesInjected) {
78
+ return;
79
+ }
80
+ entriesInjected = true;
81
+ for (const route of routes) {
82
+ addEntry(toEntryMeta(route));
83
+ }
84
+ addEntry({
85
+ id: catchAllEntry,
86
+ route: "/**"
87
+ });
88
+ }
14
89
  },
15
90
  resolveId(id) {
16
91
  if (id === catchAllEntry) {
17
- return RESOLVED_VIRTUAL_CEDAR_API;
92
+ return RESOLVED_VIRTUAL_UD_CATCH_ALL;
18
93
  }
19
- if (id === VIRTUAL_CEDAR_API) {
20
- return RESOLVED_VIRTUAL_CEDAR_API;
94
+ if (id.startsWith(VIRTUAL_CEDAR_FN_PREFIX)) {
95
+ return "\0" + id;
21
96
  }
22
97
  return void 0;
23
98
  },
24
99
  load(id) {
25
- if (id !== RESOLVED_VIRTUAL_CEDAR_API) {
26
- return void 0;
100
+ if (id.startsWith(RESOLVED_CEDAR_FN_PREFIX)) {
101
+ const routeId = id.slice(RESOLVED_CEDAR_FN_PREFIX.length);
102
+ const route = routes.find((r) => r.id === routeId);
103
+ if (!route) {
104
+ return void 0;
105
+ }
106
+ if (route.type === "graphql") {
107
+ return generateGraphQLModule(route.entry);
108
+ }
109
+ return generateFunctionModule(route.entry);
110
+ }
111
+ if (id === RESOLVED_VIRTUAL_UD_CATCH_ALL) {
112
+ return generateCatchAllModule(routes, normalizedApiRootPath);
27
113
  }
28
- const apiRootPathArg = apiRootPath !== void 0 ? `{ apiRootPath: ${JSON.stringify(apiRootPath)} }` : "undefined";
29
- return `
30
- import { buildCedarDispatcher } from '@cedarjs/api-server/udDispatcher';
31
- const { fetchable } = await buildCedarDispatcher(${apiRootPathArg});
32
- export default fetchable;
33
- `;
114
+ return void 0;
34
115
  }
35
116
  };
36
117
  }
118
+ function generateGraphQLModule(distPath) {
119
+ return `
120
+ import { createGraphQLHandler } from '@cedarjs/vite/ud-handlers/graphql';
121
+ export default createGraphQLHandler({ distPath: ${JSON.stringify(distPath)} });
122
+ `;
123
+ }
124
+ function generateFunctionModule(distPath) {
125
+ return `
126
+ import { createFunctionHandler } from '@cedarjs/vite/ud-handlers/function';
127
+ export default createFunctionHandler({ distPath: ${JSON.stringify(distPath)} });
128
+ `;
129
+ }
130
+ function generateCatchAllModule(routes, normalizedApiRootPath) {
131
+ const imports = routes.map(
132
+ (route, i) => `import mod${i} from '${VIRTUAL_CEDAR_FN_PREFIX}${route.id}';`
133
+ ).join("\n");
134
+ const routesArray = routes.map(
135
+ (route, i) => `{
136
+ path: ${JSON.stringify(route.path)},
137
+ methods: ${JSON.stringify(route.methods)},
138
+ module: mod${i}
139
+ }`
140
+ ).join(", ");
141
+ return `
142
+ import { createCatchAllHandler } from '@cedarjs/vite/ud-handlers/catch-all';
143
+ ${imports}
144
+
145
+ export default createCatchAllHandler({
146
+ routes: [${routesArray}],
147
+ apiRootPath: ${JSON.stringify(normalizedApiRootPath)}
148
+ });
149
+ `;
150
+ }
37
151
  export {
38
152
  cedarUniversalDeployPlugin
39
153
  };
@@ -0,0 +1,15 @@
1
+ export interface CatchAllRoute {
2
+ path: string;
3
+ methods: string[];
4
+ module: {
5
+ fetch: (request: Request) => Promise<Response> | Response;
6
+ };
7
+ }
8
+ export interface CatchAllHandlerOptions {
9
+ routes: CatchAllRoute[];
10
+ apiRootPath: string;
11
+ }
12
+ export declare function createCatchAllHandler(options: CatchAllHandlerOptions): {
13
+ fetch(request: Request): Promise<Response>;
14
+ };
15
+ //# sourceMappingURL=catch-all.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catch-all.d.ts","sourceRoot":"","sources":["../../src/ud-handlers/catch-all.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,MAAM,EAAE;QAAE,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAA;KAAE,CAAA;CACtE;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,aAAa,EAAE,CAAA;IACvB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB;mBAiC5C,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;EAgBnD"}
@@ -0,0 +1,41 @@
1
+ import { createRouter, addRoute, findRoute } from "rou3";
2
+ function createCatchAllHandler(options) {
3
+ const router = createRouter();
4
+ for (const route of options.routes) {
5
+ const methods = route.methods.length > 0 ? route.methods : ["GET", "HEAD", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"];
6
+ for (const method of methods) {
7
+ addRoute(router, method, route.path, route.module);
8
+ addRoute(router, method, `${route.path}/**`, route.module);
9
+ }
10
+ }
11
+ const apiRootPath = options.apiRootPath;
12
+ function normalizePathname(requestUrl) {
13
+ const url = new URL(requestUrl);
14
+ let pathname = url.pathname;
15
+ if (apiRootPath !== "/" && pathname.startsWith(apiRootPath)) {
16
+ pathname = pathname.slice(apiRootPath.length - 1);
17
+ }
18
+ if (!pathname.startsWith("/")) {
19
+ pathname = "/" + pathname;
20
+ }
21
+ return pathname;
22
+ }
23
+ return {
24
+ async fetch(request) {
25
+ const pathname = normalizePathname(request.url);
26
+ const match = findRoute(router, request.method, pathname);
27
+ if (!match) {
28
+ return new Response("Not Found", { status: 404 });
29
+ }
30
+ try {
31
+ return await match.data.fetch(request);
32
+ } catch (err) {
33
+ console.error("Unhandled error in fetch handler for", pathname, err);
34
+ return new Response("Internal Server Error", { status: 500 });
35
+ }
36
+ }
37
+ };
38
+ }
39
+ export {
40
+ createCatchAllHandler
41
+ };
@@ -0,0 +1,5 @@
1
+ export interface FunctionHandlerOptions {
2
+ distPath: string;
3
+ }
4
+ export declare function createFunctionHandler(options: FunctionHandlerOptions): import("@cedarjs/api-server/udFetchable").Fetchable;
5
+ //# sourceMappingURL=function.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"function.d.ts","sourceRoot":"","sources":["../../src/ud-handlers/function.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,sBAAsB,uDAiBpE"}
@@ -0,0 +1,18 @@
1
+ import { pathToFileURL } from "node:url";
2
+ import { createCedarFetchable } from "@cedarjs/api-server/udFetchable";
3
+ function createFunctionHandler(options) {
4
+ const handleRequest = async (request, ctx) => {
5
+ const mod = await import(pathToFileURL(options.distPath).href);
6
+ const handler = mod.handleRequest || mod.default?.handleRequest;
7
+ if (!handler) {
8
+ throw new Error(
9
+ `Fetch-native handler not found in ${options.distPath}. Expected \`export async function handleRequest(request, ctx)\` or \`export default { handleRequest }\`.`
10
+ );
11
+ }
12
+ return handler(request, ctx);
13
+ };
14
+ return createCedarFetchable(handleRequest);
15
+ }
16
+ export {
17
+ createFunctionHandler
18
+ };
@@ -0,0 +1,7 @@
1
+ export interface GraphQLHandlerOptions {
2
+ distPath: string;
3
+ }
4
+ export declare function createGraphQLHandler(options: GraphQLHandlerOptions): {
5
+ fetch(request: Request): Promise<Response>;
6
+ };
7
+ //# sourceMappingURL=graphql.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graphql.d.ts","sourceRoot":"","sources":["../../src/ud-handlers/graphql.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB;mBAiB1C,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC;EAenD"}
@@ -0,0 +1,35 @@
1
+ import { pathToFileURL } from "node:url";
2
+ import { buildCedarContext, requestToLegacyEvent } from "@cedarjs/api/runtime";
3
+ import { createGraphQLYoga } from "@cedarjs/graphql-server";
4
+ function createGraphQLHandler(options) {
5
+ let yogaInitPromise = null;
6
+ async function getYoga() {
7
+ if (!yogaInitPromise) {
8
+ yogaInitPromise = (async () => {
9
+ const mod = await import(pathToFileURL(options.distPath).href);
10
+ const opts = mod.__rw_graphqlOptions;
11
+ const { yoga } = await createGraphQLYoga(opts);
12
+ return { yoga, graphqlOptions: opts };
13
+ })();
14
+ }
15
+ return yogaInitPromise;
16
+ }
17
+ return {
18
+ async fetch(request) {
19
+ const { yoga, graphqlOptions } = await getYoga();
20
+ const cedarContext = await buildCedarContext(request, {
21
+ authDecoder: graphqlOptions?.authDecoder
22
+ });
23
+ const event = await requestToLegacyEvent(request, cedarContext);
24
+ return yoga.handle(request, {
25
+ request,
26
+ cedarContext,
27
+ event,
28
+ requestContext: void 0
29
+ });
30
+ }
31
+ };
32
+ }
33
+ export {
34
+ createGraphQLHandler
35
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cedarjs/vite",
3
- "version": "5.0.0-canary.13896+e93dd02322",
3
+ "version": "5.0.0-canary.13898+5df5497f7c",
4
4
  "description": "Vite configuration package for CedarJS",
5
5
  "repository": {
6
6
  "type": "git",
@@ -40,7 +40,37 @@
40
40
  "import": "./dist/build/build.js",
41
41
  "default": "./dist/cjs/build/build.js"
42
42
  },
43
- "./bins/cedar-vite-build.mjs": "./bins/cedar-vite-build.mjs"
43
+ "./bins/cedar-vite-build.mjs": "./bins/cedar-vite-build.mjs",
44
+ "./ud-handlers/graphql": {
45
+ "import": {
46
+ "types": "./dist/ud-handlers/graphql.d.ts",
47
+ "default": "./dist/ud-handlers/graphql.js"
48
+ },
49
+ "require": {
50
+ "types": "./dist/cjs/ud-handlers/graphql.d.ts",
51
+ "default": "./dist/cjs/ud-handlers/graphql.js"
52
+ }
53
+ },
54
+ "./ud-handlers/function": {
55
+ "import": {
56
+ "types": "./dist/ud-handlers/function.d.ts",
57
+ "default": "./dist/ud-handlers/function.js"
58
+ },
59
+ "require": {
60
+ "types": "./dist/cjs/ud-handlers/function.d.ts",
61
+ "default": "./dist/cjs/ud-handlers/function.js"
62
+ }
63
+ },
64
+ "./ud-handlers/catch-all": {
65
+ "import": {
66
+ "types": "./dist/ud-handlers/catch-all.d.ts",
67
+ "default": "./dist/ud-handlers/catch-all.js"
68
+ },
69
+ "require": {
70
+ "types": "./dist/cjs/ud-handlers/catch-all.d.ts",
71
+ "default": "./dist/cjs/ud-handlers/catch-all.js"
72
+ }
73
+ }
44
74
  },
45
75
  "bin": {
46
76
  "cedar-dev-fe": "./dist/devFeServer.js",
@@ -69,21 +99,22 @@
69
99
  "@babel/generator": "7.29.1",
70
100
  "@babel/parser": "7.29.2",
71
101
  "@babel/traverse": "7.29.0",
72
- "@cedarjs/api": "5.0.0-canary.13896",
73
- "@cedarjs/api-server": "5.0.0-canary.13896",
74
- "@cedarjs/auth": "5.0.0-canary.13896",
75
- "@cedarjs/babel-config": "5.0.0-canary.13896",
76
- "@cedarjs/context": "5.0.0-canary.13896",
77
- "@cedarjs/cookie-jar": "5.0.0-canary.13896",
78
- "@cedarjs/graphql-server": "5.0.0-canary.13896",
79
- "@cedarjs/internal": "5.0.0-canary.13896",
80
- "@cedarjs/project-config": "5.0.0-canary.13896",
81
- "@cedarjs/server-store": "5.0.0-canary.13896",
82
- "@cedarjs/testing": "5.0.0-canary.13896",
83
- "@cedarjs/web": "5.0.0-canary.13896",
102
+ "@cedarjs/api": "5.0.0-canary.13898",
103
+ "@cedarjs/api-server": "5.0.0-canary.13898",
104
+ "@cedarjs/auth": "5.0.0-canary.13898",
105
+ "@cedarjs/babel-config": "5.0.0-canary.13898",
106
+ "@cedarjs/context": "5.0.0-canary.13898",
107
+ "@cedarjs/cookie-jar": "5.0.0-canary.13898",
108
+ "@cedarjs/graphql-server": "5.0.0-canary.13898",
109
+ "@cedarjs/internal": "5.0.0-canary.13898",
110
+ "@cedarjs/project-config": "5.0.0-canary.13898",
111
+ "@cedarjs/server-store": "5.0.0-canary.13898",
112
+ "@cedarjs/testing": "5.0.0-canary.13898",
113
+ "@cedarjs/web": "5.0.0-canary.13898",
84
114
  "@fastify/url-data": "6.0.3",
85
115
  "@swc/core": "1.15.32",
86
116
  "@universal-deploy/node": "^0.1.6",
117
+ "@universal-deploy/store": "^0.2.1",
87
118
  "@vitejs/plugin-react": "4.7.0",
88
119
  "@whatwg-node/fetch": "0.10.13",
89
120
  "@whatwg-node/server": "0.10.18",
@@ -104,6 +135,7 @@
104
135
  "react": "19.2.3",
105
136
  "react-server-dom-webpack": "19.2.4",
106
137
  "rimraf": "6.1.3",
138
+ "rou3": "^0.8.1",
107
139
  "vite": "7.3.2",
108
140
  "vite-plugin-cjs-interop": "2.4.4",
109
141
  "vite-plugin-node-polyfills": "0.26.0",
@@ -134,5 +166,5 @@
134
166
  "publishConfig": {
135
167
  "access": "public"
136
168
  },
137
- "gitHead": "e93dd023221e3d5d634558031790b57cbb7b4f92"
169
+ "gitHead": "5df5497f7c5573beeae75a44ec04659171c16999"
138
170
  }