@cedarjs/vite 4.1.1-next.14 → 4.1.1-next.55
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/apiDevMiddleware.d.ts +15 -0
- package/dist/apiDevMiddleware.d.ts.map +1 -0
- package/dist/{apiDevServer.js → apiDevMiddleware.js} +95 -107
- package/dist/build/build.d.ts +1 -1
- package/dist/build/build.d.ts.map +1 -1
- package/dist/build/build.js +2 -0
- package/dist/buildApp.d.ts +15 -0
- package/dist/buildApp.d.ts.map +1 -0
- package/dist/buildApp.js +150 -0
- package/dist/buildUDApiServer.d.ts +7 -5
- package/dist/buildUDApiServer.d.ts.map +1 -1
- package/dist/buildUDApiServer.js +8 -26
- package/dist/cedar-unified-dev.js +59 -5
- package/dist/cjs/{apiDevServer.js → apiDevMiddleware.js} +102 -110
- package/dist/cjs/build/build.js +3 -0
- package/dist/cjs/buildApp.js +181 -0
- package/dist/cjs/buildUDApiServer.js +8 -26
- package/dist/cjs/cedar-unified-dev.js +59 -5
- package/dist/cjs/index.js +3 -3
- package/dist/cjs/plugins/vite-plugin-cedar-cjs-compat.js +341 -0
- package/dist/cjs/plugins/vite-plugin-cedar-universal-deploy.js +114 -19
- package/dist/cjs/plugins/vite-plugin-cedar-wait-for-api-server.js +2 -1
- package/dist/cjs/ud-handlers/catch-all.js +65 -0
- package/dist/cjs/ud-handlers/function.js +47 -0
- package/dist/cjs/ud-handlers/graphql.js +59 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/plugins/vite-plugin-cedar-cjs-compat.d.ts +23 -0
- package/dist/plugins/vite-plugin-cedar-cjs-compat.d.ts.map +1 -0
- package/dist/plugins/vite-plugin-cedar-cjs-compat.js +307 -0
- package/dist/plugins/vite-plugin-cedar-universal-deploy.d.ts.map +1 -1
- package/dist/plugins/vite-plugin-cedar-universal-deploy.js +105 -20
- package/dist/plugins/vite-plugin-cedar-wait-for-api-server.d.ts.map +1 -1
- package/dist/plugins/vite-plugin-cedar-wait-for-api-server.js +2 -1
- package/dist/ud-handlers/catch-all.d.ts +15 -0
- package/dist/ud-handlers/catch-all.d.ts.map +1 -0
- package/dist/ud-handlers/catch-all.js +41 -0
- package/dist/ud-handlers/function.d.ts +5 -0
- package/dist/ud-handlers/function.d.ts.map +1 -0
- package/dist/ud-handlers/function.js +23 -0
- package/dist/ud-handlers/graphql.d.ts +7 -0
- package/dist/ud-handlers/graphql.d.ts.map +1 -0
- package/dist/ud-handlers/graphql.js +35 -0
- package/package.json +51 -22
- package/LICENSE +0 -21
- package/dist/apiDevServer.d.ts +0 -18
- package/dist/apiDevServer.d.ts.map +0 -1
- package/dist/cjs/plugins/vite-plugin-cedar-dev-dispatcher.js +0 -223
- package/dist/plugins/vite-plugin-cedar-dev-dispatcher.d.ts +0 -3
- package/dist/plugins/vite-plugin-cedar-dev-dispatcher.d.ts.map +0 -1
- package/dist/plugins/vite-plugin-cedar-dev-dispatcher.js +0 -189
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ViteDevServer } from 'vite';
|
|
2
|
+
export declare function loadApiFunctions(viteServer: ViteDevServer): Promise<void>;
|
|
3
|
+
export declare function createApiViteServer(): Promise<ViteDevServer>;
|
|
4
|
+
export declare function setupHmrHandlers(viteServer: ViteDevServer): void;
|
|
5
|
+
/**
|
|
6
|
+
* Creates a fetch-native handler for API requests.
|
|
7
|
+
* Routes GraphQL to Yoga and Lambda functions to their handlers.
|
|
8
|
+
*/
|
|
9
|
+
export declare function createApiFetchHandler(): (request: Request) => Promise<Response>;
|
|
10
|
+
export declare function startApiDevMiddleware(): Promise<{
|
|
11
|
+
viteServer: ViteDevServer;
|
|
12
|
+
close: () => Promise<void>;
|
|
13
|
+
handler: (request: Request) => Promise<Response>;
|
|
14
|
+
}>;
|
|
15
|
+
//# sourceMappingURL=apiDevMiddleware.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"apiDevMiddleware.d.ts","sourceRoot":"","sources":["../src/apiDevMiddleware.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAc,aAAa,EAAE,MAAM,MAAM,CAAA;AA2BrD,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,aAAa,iBAe/D;AA8GD,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,aAAa,CAAC,CAuElE;AA0BD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,aAAa,GAAG,IAAI,CA0EhE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,KAIrB,SAAS,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC,CAoEnD;AAED,wBAAsB,qBAAqB,IAAI,OAAO,CAAC;IACrD,UAAU,EAAE,aAAa,CAAA;IACzB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAA;CACjD,CAAC,CAcD"}
|
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import { glob } from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { pathToFileURL } from "node:url";
|
|
4
|
-
import fastifyUrlData from "@fastify/url-data";
|
|
5
4
|
import ansis from "ansis";
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import { createServer as createViteServer, normalizePath } from "vite";
|
|
9
|
-
import { requestHandler } from "@cedarjs/api-server/requestHandlers";
|
|
5
|
+
import { normalizePath } from "vite";
|
|
6
|
+
import { buildCedarContext, wrapLegacyHandler } from "@cedarjs/api/runtime";
|
|
10
7
|
import {
|
|
11
8
|
getApiSideBabelPlugins,
|
|
12
9
|
transformWithBabel
|
|
@@ -56,13 +53,6 @@ async function internalLoadApiFunctions(viteServer) {
|
|
|
56
53
|
} catch {
|
|
57
54
|
srcFunctions = [];
|
|
58
55
|
}
|
|
59
|
-
const graphqlFunctionIndex = srcFunctions.findIndex(
|
|
60
|
-
(f) => path.basename(f).startsWith("graphql.")
|
|
61
|
-
);
|
|
62
|
-
if (graphqlFunctionIndex > 0) {
|
|
63
|
-
const [graphqlFn] = srcFunctions.splice(graphqlFunctionIndex, 1);
|
|
64
|
-
srcFunctions.unshift(graphqlFn);
|
|
65
|
-
}
|
|
66
56
|
console.log(ansis.dim.italic("Importing Server Functions... "));
|
|
67
57
|
const tsImport = Date.now();
|
|
68
58
|
let extractedGraphqlOptions = null;
|
|
@@ -71,24 +61,33 @@ async function internalLoadApiFunctions(viteServer) {
|
|
|
71
61
|
const routeName = path.basename(fnPath).replace(/\.(ts|tsx|js|jsx)$/, "");
|
|
72
62
|
try {
|
|
73
63
|
const mod = await viteServer.ssrLoadModule(pathToFileURL(fnPath).href);
|
|
74
|
-
const
|
|
64
|
+
const cedarHandler = (() => {
|
|
65
|
+
if ("handleRequest" in mod) {
|
|
66
|
+
return mod.handleRequest;
|
|
67
|
+
}
|
|
68
|
+
if ("default" in mod && mod.default && "handleRequest" in mod.default) {
|
|
69
|
+
return mod.default.handleRequest;
|
|
70
|
+
}
|
|
71
|
+
let legacyHandler;
|
|
75
72
|
if ("handler" in mod) {
|
|
76
|
-
|
|
73
|
+
legacyHandler = mod.handler;
|
|
74
|
+
} else if ("default" in mod && mod.default && "handler" in mod.default) {
|
|
75
|
+
legacyHandler = mod.default.handler;
|
|
77
76
|
}
|
|
78
|
-
if (
|
|
79
|
-
return
|
|
77
|
+
if (legacyHandler) {
|
|
78
|
+
return wrapLegacyHandler(legacyHandler);
|
|
80
79
|
}
|
|
81
80
|
return void 0;
|
|
82
81
|
})();
|
|
83
|
-
if (
|
|
84
|
-
LAMBDA_FUNCTIONS[routeName] =
|
|
82
|
+
if (cedarHandler) {
|
|
83
|
+
LAMBDA_FUNCTIONS[routeName] = cedarHandler;
|
|
85
84
|
console.log(
|
|
86
85
|
ansis.magenta("/" + routeName),
|
|
87
86
|
ansis.dim.italic(Date.now() - ts + " ms")
|
|
88
87
|
);
|
|
89
88
|
} else {
|
|
90
89
|
console.warn(
|
|
91
|
-
`[
|
|
90
|
+
`[apiDevMiddleware] No handler or handleRequest export found in function: ${fnPath}`
|
|
92
91
|
);
|
|
93
92
|
}
|
|
94
93
|
if (routeName === "graphql" && "__rw_graphqlOptions" in mod) {
|
|
@@ -97,7 +96,7 @@ async function internalLoadApiFunctions(viteServer) {
|
|
|
97
96
|
} catch (err) {
|
|
98
97
|
viteServer.ssrFixStacktrace(err);
|
|
99
98
|
console.error(
|
|
100
|
-
`[
|
|
99
|
+
`[apiDevMiddleware] Failed to load function "${routeName}" from ${fnPath}:`,
|
|
101
100
|
err
|
|
102
101
|
);
|
|
103
102
|
}
|
|
@@ -106,56 +105,29 @@ async function internalLoadApiFunctions(viteServer) {
|
|
|
106
105
|
if (extractedGraphqlOptions) {
|
|
107
106
|
const { yoga } = await createGraphQLYoga(extractedGraphqlOptions);
|
|
108
107
|
graphqlYoga = yoga;
|
|
108
|
+
} else {
|
|
109
|
+
graphqlYoga = null;
|
|
109
110
|
}
|
|
110
111
|
console.log(
|
|
111
112
|
ansis.dim.italic("...Done importing in " + (Date.now() - tsImport) + " ms")
|
|
112
113
|
);
|
|
113
114
|
}
|
|
114
|
-
function
|
|
115
|
-
const requestBody = req.method === "GET" || req.method === "HEAD" ? void 0 : typeof req.body === "string" ? req.body : req.body ? JSON.stringify(req.body) : void 0;
|
|
116
|
-
const href = `${req.protocol}://${req.host}${req.raw.url ?? "/"}`;
|
|
117
|
-
return new Request(href, {
|
|
118
|
-
method: req.method,
|
|
119
|
-
headers: req.headers,
|
|
120
|
-
body: requestBody
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
async function startApiDevServer(port) {
|
|
115
|
+
async function createApiViteServer() {
|
|
124
116
|
const cedarPaths = getPaths();
|
|
125
117
|
const cedarConfig = getConfig();
|
|
126
|
-
const apiPort = port || cedarConfig.api.port || 8911;
|
|
127
|
-
const apiHost = cedarConfig.api.host || "::";
|
|
128
118
|
const isEsm = projectSideIsEsm("api");
|
|
129
119
|
const normalizedBase = normalizePath(cedarPaths.base);
|
|
130
|
-
const normalizedApiSrc = normalizePath(cedarPaths.api.src);
|
|
131
|
-
const normalizedApiBase = normalizePath(cedarPaths.api.base);
|
|
132
|
-
const viteServer = await createViteDevServer(
|
|
133
|
-
cedarPaths,
|
|
134
|
-
cedarConfig,
|
|
135
|
-
isEsm,
|
|
136
|
-
normalizedBase
|
|
137
|
-
);
|
|
138
|
-
console.log(ansis.dim.italic("Starting API dev server..."));
|
|
139
|
-
await loadApiFunctions(viteServer);
|
|
140
|
-
setupHmrHandlers(viteServer, normalizedApiSrc, normalizedApiBase);
|
|
141
|
-
const app = await createFastifyApp(apiPort, apiHost);
|
|
142
|
-
const close = async () => {
|
|
143
|
-
await app.close();
|
|
144
|
-
await viteServer.close();
|
|
145
|
-
};
|
|
146
|
-
return { viteServer, close };
|
|
147
|
-
}
|
|
148
|
-
async function createViteDevServer(cedarPaths, cedarConfig, projectIsEsm, normalizedBase) {
|
|
149
120
|
const babelPlugins = getApiSideBabelPlugins({
|
|
150
121
|
openTelemetry: (cedarConfig.experimental?.opentelemetry?.enabled ?? false) && (cedarConfig.experimental?.opentelemetry?.wrapApi ?? false),
|
|
151
|
-
projectIsEsm
|
|
122
|
+
projectIsEsm: isEsm
|
|
152
123
|
});
|
|
153
124
|
const workspacePkgSourceMap = Object.fromEntries(
|
|
154
125
|
Object.entries(getWorkspacePackageAliases(cedarPaths, cedarConfig)).map(
|
|
155
126
|
([name, sourceFile]) => [name, normalizePath(sourceFile)]
|
|
156
127
|
)
|
|
157
128
|
);
|
|
158
|
-
const
|
|
129
|
+
const { createServer: createViteServer } = await import("vite");
|
|
130
|
+
return createViteServer({
|
|
159
131
|
configFile: false,
|
|
160
132
|
root: cedarPaths.api.base,
|
|
161
133
|
appType: "custom",
|
|
@@ -165,10 +137,6 @@ async function createViteDevServer(cedarPaths, cedarConfig, projectIsEsm, normal
|
|
|
165
137
|
middlewareMode: true
|
|
166
138
|
},
|
|
167
139
|
resolve: {
|
|
168
|
-
// Map workspace package names directly to their TypeScript source entry
|
|
169
|
-
// files. This is processed by Vite's built-in alias plugin (enforce:
|
|
170
|
-
// 'pre') which runs before vite:resolve and correctly intercepts imports
|
|
171
|
-
// in the SSR module runner context.
|
|
172
140
|
alias: workspacePkgSourceMap
|
|
173
141
|
},
|
|
174
142
|
plugins: [
|
|
@@ -203,7 +171,6 @@ async function createViteDevServer(cedarPaths, cedarConfig, projectIsEsm, normal
|
|
|
203
171
|
}
|
|
204
172
|
]
|
|
205
173
|
});
|
|
206
|
-
return viteServer;
|
|
207
174
|
}
|
|
208
175
|
function invalidateApiModules(viteServer, normalizedApiSrc) {
|
|
209
176
|
const invalidated = /* @__PURE__ */ new Set();
|
|
@@ -223,7 +190,10 @@ function invalidateApiModules(viteServer, normalizedApiSrc) {
|
|
|
223
190
|
}
|
|
224
191
|
}
|
|
225
192
|
}
|
|
226
|
-
function setupHmrHandlers(viteServer
|
|
193
|
+
function setupHmrHandlers(viteServer) {
|
|
194
|
+
const cedarPaths = getPaths();
|
|
195
|
+
const normalizedApiSrc = normalizePath(cedarPaths.api.src);
|
|
196
|
+
const normalizedApiBase = normalizePath(cedarPaths.api.base);
|
|
227
197
|
viteServer.watcher.on("change", async (filePath) => {
|
|
228
198
|
const normalizedFilePath = normalizePath(filePath);
|
|
229
199
|
if (!normalizedFilePath.startsWith(normalizedApiSrc)) {
|
|
@@ -276,60 +246,78 @@ function setupHmrHandlers(viteServer, normalizedApiSrc, normalizedApiBase) {
|
|
|
276
246
|
await loadApiFunctions(viteServer);
|
|
277
247
|
});
|
|
278
248
|
}
|
|
279
|
-
|
|
280
|
-
const
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
249
|
+
function createApiFetchHandler() {
|
|
250
|
+
const cedarConfig = getConfig();
|
|
251
|
+
const apiUrlPrefix = cedarConfig.web.apiUrl.replace(/\/$/, "");
|
|
252
|
+
return async (request) => {
|
|
253
|
+
const url = new URL(request.url);
|
|
254
|
+
let pathname = url.pathname;
|
|
255
|
+
if (pathname.startsWith(apiUrlPrefix + "/")) {
|
|
256
|
+
pathname = pathname.slice(apiUrlPrefix.length);
|
|
257
|
+
} else if (pathname === apiUrlPrefix) {
|
|
258
|
+
pathname = "/";
|
|
259
|
+
}
|
|
260
|
+
if (pathname === "/graphql" || pathname.startsWith("/graphql/")) {
|
|
261
|
+
if (!graphqlYoga) {
|
|
262
|
+
return new Response(
|
|
263
|
+
JSON.stringify({ error: "GraphQL Yoga instance not initialized" }),
|
|
264
|
+
{ status: 503, headers: { "Content-Type": "application/json" } }
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
const yoga = graphqlYoga;
|
|
268
|
+
return getAsyncStoreInstance().run(/* @__PURE__ */ new Map(), async () => {
|
|
269
|
+
return yoga.handle(request, { request });
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
const match = pathname.match(/^\/([^/]+)(?:\/.*)?$/);
|
|
273
|
+
if (!match) {
|
|
274
|
+
return new Response("Not Found", { status: 404 });
|
|
275
|
+
}
|
|
276
|
+
const routeName = match[1];
|
|
291
277
|
const handler = LAMBDA_FUNCTIONS[routeName];
|
|
292
278
|
if (!handler) {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
279
|
+
return new Response(
|
|
280
|
+
JSON.stringify({
|
|
281
|
+
error: `Function "${routeName}" was not found.`,
|
|
282
|
+
availableFunctions: Object.keys(LAMBDA_FUNCTIONS)
|
|
283
|
+
}),
|
|
284
|
+
{ status: 404, headers: { "Content-Type": "application/json" } }
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
try {
|
|
288
|
+
const ctx = await buildCedarContext(request, {
|
|
289
|
+
params: { routeName }
|
|
299
290
|
});
|
|
300
|
-
return;
|
|
291
|
+
return await handler(request, ctx);
|
|
292
|
+
} catch (err) {
|
|
293
|
+
console.error(
|
|
294
|
+
`[apiDevMiddleware] Error handling function "${routeName}":`,
|
|
295
|
+
err
|
|
296
|
+
);
|
|
297
|
+
return new Response(
|
|
298
|
+
JSON.stringify({
|
|
299
|
+
error: err instanceof Error ? err.message : "Internal Server Error"
|
|
300
|
+
}),
|
|
301
|
+
{ status: 500, headers: { "Content-Type": "application/json" } }
|
|
302
|
+
);
|
|
301
303
|
}
|
|
302
|
-
return requestHandler(req, reply, handler);
|
|
303
304
|
};
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
});
|
|
313
|
-
return response;
|
|
305
|
+
}
|
|
306
|
+
async function startApiDevMiddleware() {
|
|
307
|
+
const viteServer = await createApiViteServer();
|
|
308
|
+
console.log(ansis.dim.italic("Starting API dev server..."));
|
|
309
|
+
await loadApiFunctions(viteServer);
|
|
310
|
+
setupHmrHandlers(viteServer);
|
|
311
|
+
const close = async () => {
|
|
312
|
+
await viteServer.close();
|
|
314
313
|
};
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
app.all("/:routeName", lambdaRequestHandler);
|
|
318
|
-
app.all("/:routeName/*", lambdaRequestHandler);
|
|
319
|
-
app.addHook("onListen", (done) => {
|
|
320
|
-
const addr = app.server.address();
|
|
321
|
-
const listenPort = addr && typeof addr === "object" ? addr.port : apiPort;
|
|
322
|
-
console.log(
|
|
323
|
-
`API dev server listening at ${ansis.magenta(`http://localhost:${listenPort}/`)}`
|
|
324
|
-
);
|
|
325
|
-
console.log(
|
|
326
|
-
`GraphQL endpoint at ${ansis.magenta(`http://localhost:${listenPort}/graphql`)}`
|
|
327
|
-
);
|
|
328
|
-
done();
|
|
329
|
-
});
|
|
330
|
-
await app.listen({ port: apiPort, host: apiHost });
|
|
331
|
-
return app;
|
|
314
|
+
const handler = createApiFetchHandler();
|
|
315
|
+
return { viteServer, close, handler };
|
|
332
316
|
}
|
|
333
317
|
export {
|
|
334
|
-
|
|
318
|
+
createApiFetchHandler,
|
|
319
|
+
createApiViteServer,
|
|
320
|
+
loadApiFunctions,
|
|
321
|
+
setupHmrHandlers,
|
|
322
|
+
startApiDevMiddleware
|
|
335
323
|
};
|
package/dist/build/build.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export { buildCedarApp } from '../buildApp.js';
|
|
1
2
|
interface BuildOptions {
|
|
2
3
|
verbose?: boolean;
|
|
3
4
|
}
|
|
@@ -6,5 +7,4 @@ interface BuildOptions {
|
|
|
6
7
|
* because we want to set the process.cwd to web.base
|
|
7
8
|
*/
|
|
8
9
|
export declare const buildWeb: ({ verbose }: BuildOptions) => Promise<import("rollup").RollupOutput | import("rollup").RollupOutput[] | import("rollup").RollupWatcher>;
|
|
9
|
-
export {};
|
|
10
10
|
//# sourceMappingURL=build.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/build/build.ts"],"names":[],"mappings":"AAEA,UAAU,YAAY;IACpB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED;;;GAGG;AACH,eAAO,MAAM,QAAQ,GAAU,aAAa,YAAY,8GAoBvD,CAAA"}
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/build/build.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAE9C,UAAU,YAAY;IACpB,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED;;;GAGG;AACH,eAAO,MAAM,QAAQ,GAAU,aAAa,YAAY,8GAoBvD,CAAA"}
|
package/dist/build/build.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getPaths } from "@cedarjs/project-config";
|
|
2
|
+
import { buildCedarApp } from "../buildApp.js";
|
|
2
3
|
const buildWeb = async ({ verbose }) => {
|
|
3
4
|
const { build } = await import("vite");
|
|
4
5
|
const viteConfig = getPaths().web.viteConfig;
|
|
@@ -17,5 +18,6 @@ const buildWeb = async ({ verbose }) => {
|
|
|
17
18
|
});
|
|
18
19
|
};
|
|
19
20
|
export {
|
|
21
|
+
buildCedarApp,
|
|
20
22
|
buildWeb
|
|
21
23
|
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface BuildCedarAppOptions {
|
|
2
|
+
verbose?: boolean;
|
|
3
|
+
workspace?: string[];
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Unified build for Cedar apps using Vite's builder API.
|
|
7
|
+
*
|
|
8
|
+
* Declares `client` and `api` environments and builds them in a single
|
|
9
|
+
* orchestrated pass. The web client is built from the project's web Vite
|
|
10
|
+
* config. The API is built as an SSR environment with Babel transforms and
|
|
11
|
+
* `src/` import redirection so it resolves correctly even though the builder
|
|
12
|
+
* root is the web source directory.
|
|
13
|
+
*/
|
|
14
|
+
export declare function buildCedarApp({ verbose, workspace, }?: BuildCedarAppOptions): Promise<void>;
|
|
15
|
+
//# sourceMappingURL=buildApp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buildApp.d.ts","sourceRoot":"","sources":["../src/buildApp.ts"],"names":[],"mappings":"AA4BA,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,EAClC,OAAe,EACf,SAA0B,GAC3B,GAAE,oBAAyB,iBA+J3B"}
|
package/dist/buildApp.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { createBuilder, normalizePath } from "vite";
|
|
4
|
+
import {
|
|
5
|
+
getApiSideBabelPlugins,
|
|
6
|
+
transformWithBabel
|
|
7
|
+
} from "@cedarjs/babel-config";
|
|
8
|
+
import { findApiFiles } from "@cedarjs/internal/dist/files.js";
|
|
9
|
+
import { getConfig, getPaths, projectSideIsEsm } from "@cedarjs/project-config";
|
|
10
|
+
import { getWorkspacePackageAliases } from "./lib/workspacePackageAliases.js";
|
|
11
|
+
function resolveWithExtensions(id) {
|
|
12
|
+
if (fs.existsSync(id)) {
|
|
13
|
+
return id;
|
|
14
|
+
}
|
|
15
|
+
for (const ext of [".js", ".ts", ".jsx", ".tsx", ".mjs", ".mts"]) {
|
|
16
|
+
const withExt = id + ext;
|
|
17
|
+
if (fs.existsSync(withExt)) {
|
|
18
|
+
return withExt;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return id;
|
|
22
|
+
}
|
|
23
|
+
async function buildCedarApp({
|
|
24
|
+
verbose = false,
|
|
25
|
+
workspace = ["api", "web"]
|
|
26
|
+
} = {}) {
|
|
27
|
+
const cedarPaths = getPaths();
|
|
28
|
+
const cedarConfig = getConfig();
|
|
29
|
+
const environments = {};
|
|
30
|
+
if (workspace.includes("web")) {
|
|
31
|
+
environments.client = {
|
|
32
|
+
build: {
|
|
33
|
+
outDir: cedarPaths.web.dist
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
if (workspace.includes("api")) {
|
|
38
|
+
const isEsm = projectSideIsEsm("api");
|
|
39
|
+
const format = isEsm ? "es" : "cjs";
|
|
40
|
+
const apiFiles = findApiFiles();
|
|
41
|
+
const input = {};
|
|
42
|
+
for (const f of apiFiles) {
|
|
43
|
+
const key = path.relative(cedarPaths.api.src, f).replace(/\.(ts|tsx|mts|js|jsx|mjs)$/, "");
|
|
44
|
+
input[key] = f;
|
|
45
|
+
}
|
|
46
|
+
environments.api = {
|
|
47
|
+
build: {
|
|
48
|
+
ssr: true,
|
|
49
|
+
sourcemap: true,
|
|
50
|
+
outDir: cedarPaths.api.dist,
|
|
51
|
+
emptyOutDir: true,
|
|
52
|
+
rollupOptions: {
|
|
53
|
+
input,
|
|
54
|
+
output: {
|
|
55
|
+
format,
|
|
56
|
+
preserveModules: true,
|
|
57
|
+
preserveModulesRoot: cedarPaths.api.src,
|
|
58
|
+
entryFileNames: "[name].js"
|
|
59
|
+
},
|
|
60
|
+
external: (id) => {
|
|
61
|
+
if (id.startsWith("node:")) {
|
|
62
|
+
return true;
|
|
63
|
+
}
|
|
64
|
+
if (!id.startsWith(".") && !path.isAbsolute(id)) {
|
|
65
|
+
return true;
|
|
66
|
+
}
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
const babelPlugins = workspace.includes("api") ? getApiSideBabelPlugins({
|
|
74
|
+
openTelemetry: (cedarConfig.experimental?.opentelemetry?.enabled ?? false) && (cedarConfig.experimental?.opentelemetry?.wrapApi ?? false),
|
|
75
|
+
projectIsEsm: projectSideIsEsm("api")
|
|
76
|
+
}) : null;
|
|
77
|
+
const workspacePkgSourceMap = workspace.includes("api") ? Object.fromEntries(
|
|
78
|
+
Object.entries(getWorkspacePackageAliases(cedarPaths, cedarConfig)).map(
|
|
79
|
+
([name, sourceFile]) => [name, normalizePath(sourceFile)]
|
|
80
|
+
)
|
|
81
|
+
) : {};
|
|
82
|
+
const plugins = [
|
|
83
|
+
{
|
|
84
|
+
name: "cedar-build-app-cleanup",
|
|
85
|
+
configResolved(config) {
|
|
86
|
+
if (!workspace.includes("web") && config.environments.client) {
|
|
87
|
+
delete config.environments.client;
|
|
88
|
+
}
|
|
89
|
+
if (!environments.ssr && config.environments.ssr) {
|
|
90
|
+
delete config.environments.ssr;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
];
|
|
95
|
+
if (workspace.includes("api")) {
|
|
96
|
+
plugins.push({
|
|
97
|
+
name: "cedar-api-src-redirect",
|
|
98
|
+
enforce: "pre",
|
|
99
|
+
resolveId(id, importer) {
|
|
100
|
+
if (!importer?.startsWith(cedarPaths.api.src)) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
if (id.startsWith("src/")) {
|
|
104
|
+
return resolveWithExtensions(
|
|
105
|
+
path.join(cedarPaths.api.src, id.slice(4))
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
if (babelPlugins) {
|
|
112
|
+
plugins.push({
|
|
113
|
+
name: "cedar-vite-api-babel-transform",
|
|
114
|
+
async transform(_code, id) {
|
|
115
|
+
if (!/\.(js|ts|tsx|jsx)$/.test(id)) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
if (id.includes("node_modules")) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
if (!normalizePath(id).startsWith(normalizePath(cedarPaths.api.base))) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
const transformedCode = await transformWithBabel(id, babelPlugins);
|
|
125
|
+
if (transformedCode?.code) {
|
|
126
|
+
return {
|
|
127
|
+
code: transformedCode.code,
|
|
128
|
+
map: transformedCode.map ?? null
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const builder = await createBuilder({
|
|
137
|
+
configFile: cedarPaths.web.viteConfig,
|
|
138
|
+
envFile: false,
|
|
139
|
+
logLevel: verbose ? "info" : "warn",
|
|
140
|
+
environments,
|
|
141
|
+
resolve: {
|
|
142
|
+
alias: workspacePkgSourceMap
|
|
143
|
+
},
|
|
144
|
+
plugins
|
|
145
|
+
});
|
|
146
|
+
return builder.buildApp();
|
|
147
|
+
}
|
|
148
|
+
export {
|
|
149
|
+
buildCedarApp
|
|
150
|
+
};
|
|
@@ -3,13 +3,15 @@ export interface BuildUDApiServerOptions {
|
|
|
3
3
|
apiRootPath?: string;
|
|
4
4
|
}
|
|
5
5
|
/**
|
|
6
|
-
* Builds the API server Universal Deploy
|
|
6
|
+
* Builds the API server Universal Deploy entry using Vite.
|
|
7
7
|
*
|
|
8
8
|
* Runs a Vite server build that:
|
|
9
|
-
* 1. Installs `cedarUniversalDeployPlugin()` to register
|
|
10
|
-
*
|
|
11
|
-
* 2. Installs `
|
|
12
|
-
*
|
|
9
|
+
* 1. Installs `cedarUniversalDeployPlugin()` to register per-route API
|
|
10
|
+
* entries (GraphQL, auth, functions) with UD's store.
|
|
11
|
+
* 2. Installs `universalDeploy()` from `@universal-deploy/vite` which
|
|
12
|
+
* provides `catchAll()` (rou3-based route dispatch), `devServer()`, and
|
|
13
|
+
* auto-detection of deployment targets (Node by default, or Netlify/
|
|
14
|
+
* Vercel/Cloudflare if the user has added the corresponding Vite plugin).
|
|
13
15
|
*
|
|
14
16
|
* The emitted entry can be launched directly: node api/dist/ud/index.js
|
|
15
17
|
* That is what `cedar serve api` does.
|
|
@@ -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
|
|
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;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,gBAAgB,GAAU,4BAGpC,uBAA4B,kBA6C9B,CAAA"}
|
package/dist/buildUDApiServer.js
CHANGED
|
@@ -6,23 +6,19 @@ const buildUDApiServer = async ({
|
|
|
6
6
|
} = {}) => {
|
|
7
7
|
const { build } = await import("vite");
|
|
8
8
|
const { cedarUniversalDeployPlugin } = await import("./plugins/vite-plugin-cedar-universal-deploy.js");
|
|
9
|
-
const {
|
|
9
|
+
const { default: universalDeploy } = await import("@universal-deploy/vite");
|
|
10
10
|
const rwPaths = getPaths();
|
|
11
11
|
const outDir = path.join(rwPaths.api.dist, "ud");
|
|
12
12
|
await build({
|
|
13
|
-
// No configFile — we configure everything inline so this build is
|
|
14
|
-
// self-contained and does not require a vite.config.ts in api/.
|
|
15
|
-
configFile: false,
|
|
16
|
-
envFile: false,
|
|
17
13
|
logLevel: verbose ? "info" : "warn",
|
|
18
14
|
plugins: [
|
|
19
|
-
// Registers
|
|
20
|
-
// virtual:ud:catch-all → virtual:cedar-api → Cedar's aggregate fetchable.
|
|
15
|
+
// Registers per-route API entries with @universal-deploy/store.
|
|
21
16
|
cedarUniversalDeployPlugin({ apiRootPath }),
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
//
|
|
25
|
-
|
|
17
|
+
// Includes catchAll(), devServer(), and auto-detection of
|
|
18
|
+
// deployment targets. Enables @universal-deploy/node by default
|
|
19
|
+
// when no other target (Netlify, Vercel, Cloudflare) is detected
|
|
20
|
+
// in the user's Vite config.
|
|
21
|
+
universalDeploy()
|
|
26
22
|
],
|
|
27
23
|
// The ssr environment is the Vite mechanism for server-side builds.
|
|
28
24
|
// Reminder: "ssr" here means "server-side module execution", NOT
|
|
@@ -30,21 +26,7 @@ const buildUDApiServer = async ({
|
|
|
30
26
|
environments: {
|
|
31
27
|
ssr: {
|
|
32
28
|
build: {
|
|
33
|
-
outDir
|
|
34
|
-
// Ensure @universal-deploy/node is bundled into the output so the
|
|
35
|
-
// emitted entry is self-contained.
|
|
36
|
-
rollupOptions: {
|
|
37
|
-
output: {
|
|
38
|
-
// Produce a single-file entry where possible; srvx chunks are
|
|
39
|
-
// split by the node() plugin automatically.
|
|
40
|
-
entryFileNames: "[name].js"
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
},
|
|
44
|
-
resolve: {
|
|
45
|
-
// Do not externalise @universal-deploy/node — the node() plugin
|
|
46
|
-
// requires it to be bundled into the server entry.
|
|
47
|
-
noExternal: ["@universal-deploy/node"]
|
|
29
|
+
outDir
|
|
48
30
|
}
|
|
49
31
|
}
|
|
50
32
|
},
|