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

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 (65) 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 +125 -6
  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 +129 -10
  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 +5 -0
  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-entry-injection.js +20 -5
  24. package/dist/cjs/plugins/vite-plugin-cedar-remove-dev-fatal-error-page.js +61 -0
  25. package/dist/cjs/plugins/vite-plugin-cedar-universal-deploy.js +194 -14
  26. package/dist/cjs/runFeServer.js +2 -1
  27. package/dist/cjs/utils.js +2 -1
  28. package/dist/devFeServer.d.ts +1 -0
  29. package/dist/devFeServer.js +2 -1
  30. package/dist/index.d.ts +1 -0
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +4 -0
  33. package/dist/lib/getMergedConfig.d.ts.map +1 -1
  34. package/dist/lib/getMergedConfig.js +12 -4
  35. package/dist/lib/workspacePackageAliases.d.ts.map +1 -1
  36. package/dist/lib/workspacePackageAliases.js +2 -8
  37. package/dist/plugins/vite-plugin-cedar-entry-injection.d.ts.map +1 -1
  38. package/dist/plugins/vite-plugin-cedar-entry-injection.js +20 -5
  39. package/dist/plugins/vite-plugin-cedar-remove-dev-fatal-error-page.d.ts +15 -0
  40. package/dist/plugins/vite-plugin-cedar-remove-dev-fatal-error-page.d.ts.map +1 -0
  41. package/dist/plugins/vite-plugin-cedar-remove-dev-fatal-error-page.js +37 -0
  42. package/dist/plugins/vite-plugin-cedar-universal-deploy.d.ts.map +1 -1
  43. package/dist/plugins/vite-plugin-cedar-universal-deploy.js +194 -14
  44. package/dist/runFeServer.d.ts +1 -0
  45. package/dist/runFeServer.d.ts.map +1 -1
  46. package/dist/runFeServer.js +2 -1
  47. package/dist/utils.d.ts.map +1 -1
  48. package/dist/utils.js +2 -1
  49. package/package.json +30 -60
  50. package/dist/buildUDApiServer.d.ts +0 -24
  51. package/dist/buildUDApiServer.d.ts.map +0 -1
  52. package/dist/buildUDApiServer.js +0 -41
  53. package/dist/cjs/buildUDApiServer.js +0 -75
  54. package/dist/cjs/ud-handlers/catch-all.js +0 -65
  55. package/dist/cjs/ud-handlers/function.js +0 -47
  56. package/dist/cjs/ud-handlers/graphql.js +0 -59
  57. package/dist/ud-handlers/catch-all.d.ts +0 -15
  58. package/dist/ud-handlers/catch-all.d.ts.map +0 -1
  59. package/dist/ud-handlers/catch-all.js +0 -41
  60. package/dist/ud-handlers/function.d.ts +0 -5
  61. package/dist/ud-handlers/function.d.ts.map +0 -1
  62. package/dist/ud-handlers/function.js +0 -23
  63. package/dist/ud-handlers/graphql.d.ts +0 -7
  64. package/dist/ud-handlers/graphql.d.ts.map +0 -1
  65. package/dist/ud-handlers/graphql.js +0 -35
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ import { startUnifiedDevServer } from '../dist/cedar-unified-dev.js'
3
+
4
+ startUnifiedDevServer().catch((err) => {
5
+ console.error('Failed to start unified dev server:', err)
6
+ process.exit(1)
7
+ })
@@ -1 +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
+ {"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;AA+GD,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,aAAa,CAAC,CAgFlE;AA0BD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,aAAa,GAAG,IAAI,CA0EhE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,KAIrB,SAAS,OAAO,KAAG,OAAO,CAAC,QAAQ,CAAC,CAoFnD;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"}
@@ -90,8 +90,8 @@ async function internalLoadApiFunctions(viteServer) {
90
90
  `[apiDevMiddleware] No handler or handleRequest export found in function: ${fnPath}`
91
91
  );
92
92
  }
93
- if (routeName === "graphql" && "__rw_graphqlOptions" in mod) {
94
- extractedGraphqlOptions = mod.__rw_graphqlOptions;
93
+ if (routeName === "graphql" && "__cedar_graphqlOptions" in mod) {
94
+ extractedGraphqlOptions = mod.__cedar_graphqlOptions;
95
95
  }
96
96
  } catch (err) {
97
97
  viteServer.ssrFixStacktrace(err);
@@ -142,7 +142,8 @@ async function createApiViteServer() {
142
142
  plugins: [
143
143
  {
144
144
  name: "cedar-api-babel-transform",
145
- async transform(_code, id) {
145
+ enforce: "pre",
146
+ async transform(code, id) {
146
147
  if (!/\.(ts|tsx|js|jsx)$/.test(id)) {
147
148
  return null;
148
149
  }
@@ -153,7 +154,12 @@ async function createApiViteServer() {
153
154
  return null;
154
155
  }
155
156
  try {
156
- const result = await transformWithBabel(id, babelPlugins);
157
+ const result = await transformWithBabel(
158
+ code,
159
+ id,
160
+ babelPlugins,
161
+ true
162
+ );
157
163
  if (!result?.code) {
158
164
  return null;
159
165
  }
@@ -266,7 +272,14 @@ function createApiFetchHandler() {
266
272
  }
267
273
  const yoga = graphqlYoga;
268
274
  return getAsyncStoreInstance().run(/* @__PURE__ */ new Map(), async () => {
269
- return yoga.handle(request, { request });
275
+ try {
276
+ return await yoga.handle(request, { request });
277
+ } catch (e) {
278
+ if (!!e && typeof e === "object" && "code" in e && e.code === "ERR_STREAM_PREMATURE_CLOSE") {
279
+ return new Response(null, { status: 499 });
280
+ }
281
+ throw e;
282
+ }
270
283
  });
271
284
  }
272
285
  const match = pathname.match(/^\/([^/]+)(?:\/.*)?$/);
@@ -1,6 +1,7 @@
1
1
  export interface BuildCedarAppOptions {
2
2
  verbose?: boolean;
3
3
  workspace?: string[];
4
+ ud?: boolean;
4
5
  }
5
6
  /**
6
7
  * Unified build for Cedar apps using Vite's builder API.
@@ -11,5 +12,5 @@ export interface BuildCedarAppOptions {
11
12
  * `src/` import redirection so it resolves correctly even though the builder
12
13
  * root is the web source directory.
13
14
  */
14
- export declare function buildCedarApp({ verbose, workspace, }?: BuildCedarAppOptions): Promise<void>;
15
+ export declare function buildCedarApp({ verbose, workspace, ud, }?: BuildCedarAppOptions): Promise<void>;
15
16
  //# sourceMappingURL=buildApp.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"buildApp.d.ts","sourceRoot":"","sources":["../src/buildApp.ts"],"names":[],"mappings":"AA8BA,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,EAAE,CAAC,EAAE,OAAO,CAAA;CACb;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,EAClC,OAAe,EACf,SAA0B,EAC1B,EAAU,GACX,GAAE,oBAAyB,iBA0U3B"}
package/dist/buildApp.js CHANGED
@@ -1,5 +1,7 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
+ import { catchAllEntry, getAllEntries } from "@universal-deploy/store";
4
+ import { catchAll } from "@universal-deploy/vite";
3
5
  import { createBuilder, normalizePath } from "vite";
4
6
  import {
5
7
  getApiSideBabelPlugins,
@@ -22,7 +24,8 @@ function resolveWithExtensions(id) {
22
24
  }
23
25
  async function buildCedarApp({
24
26
  verbose = false,
25
- workspace = ["api", "web"]
27
+ workspace = ["api", "web"],
28
+ ud = false
26
29
  } = {}) {
27
30
  const cedarPaths = getPaths();
28
31
  const cedarConfig = getConfig();
@@ -55,13 +58,13 @@ async function buildCedarApp({
55
58
  format,
56
59
  preserveModules: true,
57
60
  preserveModulesRoot: cedarPaths.api.src,
58
- entryFileNames: "[name].js"
61
+ entryFileNames: "[name].js",
62
+ exports: "named"
59
63
  },
60
64
  external: (id) => {
61
65
  if (id.startsWith("node:")) {
62
66
  return true;
63
- }
64
- if (!id.startsWith(".") && !path.isAbsolute(id)) {
67
+ } else if (!id.startsWith(".") && !path.isAbsolute(id)) {
65
68
  return true;
66
69
  }
67
70
  return false;
@@ -69,6 +72,31 @@ async function buildCedarApp({
69
72
  }
70
73
  }
71
74
  };
75
+ if (ud) {
76
+ environments["ssr"] = {
77
+ build: {
78
+ ssr: true,
79
+ outDir: path.join(cedarPaths.api.dist, "ud"),
80
+ emptyOutDir: true,
81
+ rollupOptions: {
82
+ input: catchAllEntry,
83
+ output: {
84
+ entryFileNames: "index.js"
85
+ },
86
+ external: (id) => {
87
+ if (id.startsWith("virtual:")) {
88
+ return false;
89
+ } else if (id.startsWith("node:")) {
90
+ return true;
91
+ } else if (!id.startsWith(".") && !path.isAbsolute(id)) {
92
+ return true;
93
+ }
94
+ return false;
95
+ }
96
+ }
97
+ }
98
+ };
99
+ }
72
100
  }
73
101
  const babelPlugins = workspace.includes("api") ? getApiSideBabelPlugins({
74
102
  openTelemetry: (cedarConfig.experimental?.opentelemetry?.enabled ?? false) && (cedarConfig.experimental?.opentelemetry?.wrapApi ?? false),
@@ -80,6 +108,41 @@ async function buildCedarApp({
80
108
  )
81
109
  ) : {};
82
110
  const plugins = [
111
+ // Suppress noisy warnings from third-party dependencies across all
112
+ // environments by injecting onwarn into every environment's rollupOptions.
113
+ {
114
+ name: "cedar-suppress-third-party-warnings",
115
+ configResolved(config) {
116
+ function onwarn(warning, warn) {
117
+ if (warning.code === "EVAL" && warning.id?.includes("@prisma/internals")) {
118
+ return;
119
+ }
120
+ if (warning.code === "INVALID_ANNOTATION" && warning.id?.includes("graphql-scalars")) {
121
+ return;
122
+ }
123
+ warn(warning);
124
+ }
125
+ for (const env of Object.values(config.environments ?? {})) {
126
+ env.build.rollupOptions ??= {};
127
+ const existingOnwarn = env.build.rollupOptions.onwarn;
128
+ env.build.rollupOptions.onwarn = existingOnwarn ? (warning, warn) => {
129
+ onwarn(warning, (w) => existingOnwarn(w, warn));
130
+ } : onwarn;
131
+ }
132
+ }
133
+ },
134
+ // Resolve bare-specifier dynamic imports from node_modules as external
135
+ // before Rollup attempts resolution, avoiding UNRESOLVED_IMPORT warnings
136
+ // for optional peer dependencies (e.g. @simplewebauthn/server).
137
+ {
138
+ name: "cedar-optional-peer-deps",
139
+ resolveDynamicImport(specifier, importer) {
140
+ if (typeof specifier === "string" && !specifier.startsWith(".") && !specifier.startsWith("/") && importer?.includes("node_modules") && this.environment.config.consumer === "server") {
141
+ return { id: specifier, external: true };
142
+ }
143
+ return null;
144
+ }
145
+ },
83
146
  {
84
147
  name: "cedar-build-app-cleanup",
85
148
  configResolved(config) {
@@ -90,8 +153,58 @@ async function buildCedarApp({
90
153
  delete config.environments.ssr;
91
154
  }
92
155
  }
156
+ },
157
+ {
158
+ name: "cedar-build-app",
159
+ buildApp: {
160
+ order: "pre",
161
+ async handler(builder2) {
162
+ if (workspace.includes("web") && builder2.environments.client && !builder2.environments.client.isBuilt) {
163
+ await builder2.build(builder2.environments.client);
164
+ }
165
+ if (workspace.includes("api") && builder2.environments.api && !builder2.environments.api.isBuilt) {
166
+ await builder2.build(builder2.environments.api);
167
+ }
168
+ if (workspace.includes("api") && builder2.environments["ssr"] && !builder2.environments["ssr"].isBuilt) {
169
+ await builder2.build(builder2.environments["ssr"]);
170
+ }
171
+ }
172
+ }
93
173
  }
94
174
  ];
175
+ if (ud) {
176
+ plugins.push(catchAll());
177
+ plugins.push({
178
+ name: "cedar-ud-verify-routes",
179
+ configResolved() {
180
+ const entries = getAllEntries();
181
+ if (entries.length === 0) {
182
+ console.warn(
183
+ "\n",
184
+ " Warning: No Universal Deploy API routes were registered.\n",
185
+ " The built server entry will be an empty router (404 for all\n",
186
+ " requests). Check that you have API functions under\n",
187
+ " `api/src/functions/` and that your vite config includes\n",
188
+ " `cedarUniversalDeployPlugin()`.\n"
189
+ );
190
+ }
191
+ }
192
+ });
193
+ plugins.push({
194
+ name: "cedar-ud-write-package-json",
195
+ applyToEnvironment(env) {
196
+ return env.name === "ssr";
197
+ },
198
+ closeBundle() {
199
+ const dir = path.join(cedarPaths.api.dist, "ud");
200
+ fs.mkdirSync(dir, { recursive: true });
201
+ fs.writeFileSync(
202
+ path.join(dir, "package.json"),
203
+ JSON.stringify({ type: "module" }, null, 2)
204
+ );
205
+ }
206
+ });
207
+ }
95
208
  if (workspace.includes("api")) {
96
209
  plugins.push({
97
210
  name: "cedar-api-src-redirect",
@@ -111,7 +224,8 @@ async function buildCedarApp({
111
224
  if (babelPlugins) {
112
225
  plugins.push({
113
226
  name: "cedar-vite-api-babel-transform",
114
- async transform(_code, id) {
227
+ enforce: "pre",
228
+ async transform(code, id) {
115
229
  if (!/\.(js|ts|tsx|jsx)$/.test(id)) {
116
230
  return null;
117
231
  }
@@ -121,7 +235,12 @@ async function buildCedarApp({
121
235
  if (!normalizePath(id).startsWith(normalizePath(cedarPaths.api.base))) {
122
236
  return null;
123
237
  }
124
- const transformedCode = await transformWithBabel(id, babelPlugins);
238
+ const transformedCode = await transformWithBabel(
239
+ code,
240
+ id,
241
+ babelPlugins,
242
+ true
243
+ );
125
244
  if (transformedCode?.code) {
126
245
  return {
127
246
  code: transformedCode.code,
@@ -1 +1 @@
1
- {"version":3,"file":"buildFeServer.d.ts","sourceRoot":"","sources":["../src/buildFeServer.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,eAAO,MAAM,aAAa,GAAU,sBAAqB,YAAiB,kBA0CzE,CAAA"}
1
+ {"version":3,"file":"buildFeServer.d.ts","sourceRoot":"","sources":["../src/buildFeServer.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,eAAO,MAAM,aAAa,GAAU,sBAAqB,YAAiB,kBAyCzE,CAAA"}
@@ -14,7 +14,7 @@ const buildFeServer = async ({ verbose, webDir } = {}) => {
14
14
  const streamingSsrEnabled = rwConfig.experimental?.streamingSsr?.enabled;
15
15
  if (!viteConfigPath) {
16
16
  throw new Error(
17
- "Vite config not found. You need to setup your project with Vite using `yarn cedar setup vite`"
17
+ "Vite config not found. Please set up Vite before building."
18
18
  );
19
19
  }
20
20
  if (!rwPaths.web.entryServer || !rwPaths.web.entryClient) {
@@ -1 +1 @@
1
- {"version":3,"file":"buildRouteHooks.d.ts","sourceRoot":"","sources":["../src/buildRouteHooks.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAGpD,wBAAsB,eAAe,CACnC,OAAO,EAAE,OAAO,GAAG,SAAS,EAC5B,OAAO,EAAE,KAAK,iBAuCf"}
1
+ {"version":3,"file":"buildRouteHooks.d.ts","sourceRoot":"","sources":["../src/buildRouteHooks.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAGpD,wBAAsB,eAAe,CACnC,OAAO,EAAE,OAAO,GAAG,SAAS,EAC5B,OAAO,EAAE,KAAK,iBA0Cf"}
@@ -1,3 +1,4 @@
1
+ import fs from "node:fs";
1
2
  import { build as esbuildBuild } from "esbuild";
2
3
  import {
3
4
  getRouteHookBabelPlugins,
@@ -11,9 +12,12 @@ async function buildRouteHooks(verbose, rwPaths) {
11
12
  name: "rw-esbuild-babel-transform",
12
13
  setup(build) {
13
14
  build.onLoad({ filter: /\.(js|ts|tsx|jsx)$/ }, async (args) => {
14
- const transformedCode = await transformWithBabel(args.path, [
15
- ...getRouteHookBabelPlugins()
16
- ]);
15
+ const fileContents = await fs.promises.readFile(args.path, "utf-8");
16
+ const transformedCode = await transformWithBabel(
17
+ fileContents,
18
+ args.path,
19
+ [...getRouteHookBabelPlugins()]
20
+ );
17
21
  if (transformedCode?.code) {
18
22
  return {
19
23
  contents: transformedCode.code,
@@ -1,3 +1,14 @@
1
- #!/usr/bin/env node
2
- export {};
1
+ export declare function parseCliArgs(argv?: string[]): {
2
+ forceOptimize: any;
3
+ debug: any;
4
+ portArg: any;
5
+ debugPort: any;
6
+ debugBrk: any;
7
+ serverArgs: {
8
+ [argName: string]: any;
9
+ "--"?: Array<string | number>;
10
+ };
11
+ };
12
+ export declare function openDebugger(port: number, waitForDebugger?: boolean): Promise<void>;
13
+ export declare function startUnifiedDevServer(): Promise<void>;
3
14
  //# sourceMappingURL=cedar-unified-dev.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cedar-unified-dev.d.ts","sourceRoot":"","sources":["../src/cedar-unified-dev.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"cedar-unified-dev.d.ts","sourceRoot":"","sources":["../src/cedar-unified-dev.ts"],"names":[],"mappings":"AA+BA,wBAAgB,YAAY,CAAC,IAAI,WAAe;;;;;;;;;;EAwB/C;AAuCD,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,eAAe,UAAQ,iBAkKvE;AAED,wBAAsB,qBAAqB,kBAiI1C"}
@@ -1,4 +1,3 @@
1
- #!/usr/bin/env node
2
1
  import { createServerAdapter } from "@whatwg-node/server";
3
2
  import { createServer } from "vite";
4
3
  import yargsParser from "yargs-parser";
@@ -11,25 +10,180 @@ function isViteInternalRequest(url) {
11
10
  function isApiRequest(url, apiUrl, apiGqlUrl) {
12
11
  return url === apiUrl || url.startsWith(apiUrl + "/") || url.startsWith(apiUrl + "?") || url === apiGqlUrl || url.startsWith(apiGqlUrl + "/") || url.startsWith(apiGqlUrl + "?");
13
12
  }
14
- const startUnifiedDevServer = async () => {
15
- process.env.__CEDAR_UNIFIED_DEV = "true";
16
- const rwPaths = getPaths();
17
- const cedarConfig = getConfig();
18
- const configFile = rwPaths.web.viteConfig;
19
- if (!configFile) {
20
- throw new Error("Could not locate your web/vite.config.{js,ts} file");
21
- }
13
+ function parseCliArgs(argv = process.argv) {
22
14
  const {
23
15
  force: forceOptimize,
24
16
  debug,
25
17
  port: portArg,
26
18
  apiPort: _apiPortArg,
19
+ "debug-port": debugPort,
20
+ "debug-brk": debugBrk,
27
21
  _: _positional,
28
22
  ...serverArgs
29
- } = yargsParser(process.argv.slice(2), {
30
- boolean: ["https", "open", "strictPort", "force", "cors", "debug"],
31
- number: ["port", "apiPort"]
23
+ } = yargsParser(argv.slice(2), {
24
+ boolean: [
25
+ "https",
26
+ "open",
27
+ "strictPort",
28
+ "force",
29
+ "cors",
30
+ "debug",
31
+ "debug-brk"
32
+ ],
33
+ number: ["port", "apiPort", "debug-port"]
32
34
  });
35
+ return { forceOptimize, debug, portArg, debugPort, debugBrk, serverArgs };
36
+ }
37
+ async function clearPendingPause() {
38
+ const inspector = await import("node:inspector");
39
+ const s = new inspector.Session();
40
+ try {
41
+ s.connect();
42
+ await new Promise((resolve, reject) => {
43
+ s.post("Debugger.enable", (err) => err ? reject(err) : resolve());
44
+ });
45
+ await new Promise((resolve) => {
46
+ let done = false;
47
+ s.once("Debugger.paused", () => {
48
+ s.post("Debugger.resume", () => {
49
+ done = true;
50
+ resolve();
51
+ });
52
+ });
53
+ s.post("Runtime.evaluate", { expression: "1" }, () => {
54
+ if (!done) {
55
+ resolve();
56
+ }
57
+ });
58
+ });
59
+ } catch {
60
+ } finally {
61
+ s.disconnect();
62
+ }
63
+ }
64
+ async function openDebugger(port, waitForDebugger = false) {
65
+ const inspector = await import("node:inspector");
66
+ inspector.open(port, "127.0.0.1");
67
+ if (waitForDebugger) {
68
+ inspector.waitForDebugger();
69
+ const session = new inspector.Session();
70
+ session.connect();
71
+ await session.post("Debugger.enable");
72
+ let resumedResolve;
73
+ const resumedPromise = new Promise((resolve) => {
74
+ resumedResolve = resolve;
75
+ });
76
+ const onSessionDead = () => {
77
+ if (paused) {
78
+ tryResume();
79
+ } else {
80
+ clearPendingPause().then(
81
+ () => resumedResolve?.(),
82
+ () => resumedResolve?.()
83
+ );
84
+ }
85
+ };
86
+ session.once("error", onSessionDead);
87
+ session.once("Inspector.detached", onSessionDead);
88
+ let paused = false;
89
+ session.once("Debugger.paused", () => {
90
+ paused = true;
91
+ tryResume();
92
+ });
93
+ session.once("Debugger.resumed", () => {
94
+ resumedResolve?.();
95
+ });
96
+ const FIVE_MINUTES_MS = 5 * 60 * 1e3;
97
+ const timeout = setTimeout(() => {
98
+ if (paused) {
99
+ tryResume();
100
+ } else {
101
+ resumedResolve?.();
102
+ }
103
+ }, FIVE_MINUTES_MS);
104
+ let hasTriedResume = false;
105
+ const tryResume = () => {
106
+ if (hasTriedResume) {
107
+ return;
108
+ }
109
+ if (!paused) {
110
+ return;
111
+ }
112
+ hasTriedResume = true;
113
+ (async () => {
114
+ for (let attempt = 0; attempt < 3; attempt++) {
115
+ const s = attempt === 0 ? session : new inspector.Session();
116
+ if (attempt > 0) {
117
+ try {
118
+ s.connect();
119
+ await new Promise((resolve, reject) => {
120
+ s.post(
121
+ "Debugger.enable",
122
+ (err) => err ? reject(err) : resolve()
123
+ );
124
+ });
125
+ } catch {
126
+ continue;
127
+ }
128
+ }
129
+ const ok = await new Promise((resolve) => {
130
+ s.post("Debugger.resume", (err) => resolve(!err));
131
+ });
132
+ if (attempt > 0) {
133
+ s.disconnect();
134
+ }
135
+ if (ok) {
136
+ resumedResolve?.();
137
+ return;
138
+ }
139
+ }
140
+ console.warn(
141
+ "[cedar-unified-dev] Failed to clear debugger pause after external debugger disconnect. API functions may pause on next execution."
142
+ );
143
+ resumedResolve?.();
144
+ })();
145
+ };
146
+ void new Promise((resolve, reject) => {
147
+ session.post("Debugger.pause", (err) => {
148
+ if (err) {
149
+ reject(err);
150
+ } else {
151
+ resolve();
152
+ }
153
+ });
154
+ }).catch(() => {
155
+ resumedResolve?.();
156
+ });
157
+ void new Promise((resolve, reject) => {
158
+ session.post("Runtime.evaluate", { expression: "1" }, (err) => {
159
+ if (err) {
160
+ reject(err);
161
+ } else {
162
+ resolve();
163
+ }
164
+ });
165
+ }).catch(() => {
166
+ clearPendingPause().then(
167
+ () => resumedResolve?.(),
168
+ () => resumedResolve?.()
169
+ );
170
+ });
171
+ await resumedPromise;
172
+ clearTimeout(timeout);
173
+ }
174
+ }
175
+ async function startUnifiedDevServer() {
176
+ process.env.__CEDAR_UNIFIED_DEV = "true";
177
+ const rwPaths = getPaths();
178
+ const cedarConfig = getConfig();
179
+ const configFile = rwPaths.web.viteConfig;
180
+ if (!configFile) {
181
+ throw new Error("Could not locate your web/vite.config.{js,ts} file");
182
+ }
183
+ const { forceOptimize, debug, portArg, debugPort, debugBrk, serverArgs } = parseCliArgs();
184
+ if (debugPort !== void 0) {
185
+ await openDebugger(debugPort, debugBrk);
186
+ }
33
187
  const webPort = portArg ?? cedarConfig.web.port ?? 8910;
34
188
  const { close: closeApi, handler: apiHandler } = await startApiDevMiddleware();
35
189
  const apiAdapter = createServerAdapter(apiHandler);
@@ -112,8 +266,9 @@ const startUnifiedDevServer = async () => {
112
266
  };
113
267
  process.on("SIGINT", shutdown);
114
268
  process.on("SIGTERM", shutdown);
269
+ }
270
+ export {
271
+ openDebugger,
272
+ parseCliArgs,
273
+ startUnifiedDevServer
115
274
  };
116
- startUnifiedDevServer().catch((err) => {
117
- console.error("Failed to start unified dev server:", err);
118
- process.exit(1);
119
- });
@@ -124,8 +124,8 @@ async function internalLoadApiFunctions(viteServer) {
124
124
  `[apiDevMiddleware] No handler or handleRequest export found in function: ${fnPath}`
125
125
  );
126
126
  }
127
- if (routeName === "graphql" && "__rw_graphqlOptions" in mod) {
128
- extractedGraphqlOptions = mod.__rw_graphqlOptions;
127
+ if (routeName === "graphql" && "__cedar_graphqlOptions" in mod) {
128
+ extractedGraphqlOptions = mod.__cedar_graphqlOptions;
129
129
  }
130
130
  } catch (err) {
131
131
  viteServer.ssrFixStacktrace(err);
@@ -176,7 +176,8 @@ async function createApiViteServer() {
176
176
  plugins: [
177
177
  {
178
178
  name: "cedar-api-babel-transform",
179
- async transform(_code, id) {
179
+ enforce: "pre",
180
+ async transform(code, id) {
180
181
  if (!/\.(ts|tsx|js|jsx)$/.test(id)) {
181
182
  return null;
182
183
  }
@@ -187,7 +188,12 @@ async function createApiViteServer() {
187
188
  return null;
188
189
  }
189
190
  try {
190
- const result = await (0, import_babel_config.transformWithBabel)(id, babelPlugins);
191
+ const result = await (0, import_babel_config.transformWithBabel)(
192
+ code,
193
+ id,
194
+ babelPlugins,
195
+ true
196
+ );
191
197
  if (!result?.code) {
192
198
  return null;
193
199
  }
@@ -300,7 +306,14 @@ function createApiFetchHandler() {
300
306
  }
301
307
  const yoga = graphqlYoga;
302
308
  return (0, import_store.getAsyncStoreInstance)().run(/* @__PURE__ */ new Map(), async () => {
303
- return yoga.handle(request, { request });
309
+ try {
310
+ return await yoga.handle(request, { request });
311
+ } catch (e) {
312
+ if (!!e && typeof e === "object" && "code" in e && e.code === "ERR_STREAM_PREMATURE_CLOSE") {
313
+ return new Response(null, { status: 499 });
314
+ }
315
+ throw e;
316
+ }
304
317
  });
305
318
  }
306
319
  const match = pathname.match(/^\/([^/]+)(?:\/.*)?$/);