@superblocksteam/sdk 2.0.130-next.1 → 2.0.130-next.3

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.
@@ -1,4 +1,5 @@
1
1
  import path from "node:path";
2
+ const SERVER_APIS_DIR = "server/apis";
2
3
  /**
3
4
  * Build a sourcemap `mappings` string for a simple prepend operation.
4
5
  *
@@ -18,24 +19,84 @@ function buildPrependMappings(prependLineCount, originalLineCount) {
18
19
  .join(";");
19
20
  return empty + original;
20
21
  }
22
+ function qualifyAnchoredServerApisRelative(relative) {
23
+ if (relative === `${SERVER_APIS_DIR}/index.ts`) {
24
+ return null;
25
+ }
26
+ const baseName = path.posix.basename(relative);
27
+ if (baseName === "index.ts") {
28
+ return null;
29
+ }
30
+ if (!relative.endsWith(".ts") && !relative.endsWith(".tsx")) {
31
+ return null;
32
+ }
33
+ return relative;
34
+ }
35
+ function qualifySegmentFallbackRelative(relative) {
36
+ if (!relative.startsWith(`${SERVER_APIS_DIR}/`)) {
37
+ return null;
38
+ }
39
+ // Reject false positives when appRootDir sits under a server/apis/ path.
40
+ if (relative.includes("/client/")) {
41
+ return null;
42
+ }
43
+ const baseName = path.posix.basename(relative);
44
+ if (baseName !== "api.ts" && baseName !== "api.tsx") {
45
+ return null;
46
+ }
47
+ return relative;
48
+ }
49
+ /**
50
+ * Resolve the app-root-relative entry point path for a Vite module id.
51
+ *
52
+ * Fullstack apps keep `server/apis/` at the app root while `vite.config.ts`
53
+ * often sets `root: "./client"`. Dev server and build already pass the true
54
+ * app root into the plugin; failures are intermittent and depend on how Vite
55
+ * resolves module ids for files outside the client subtree (for example
56
+ * `../server/apis/...` relatives or `/@fs/...` absolute ids). Plain absolute
57
+ * paths under `<appRoot>/server/apis/` already matched before this helper.
58
+ */
59
+ export function resolveSdkApiEntryPointRelativePath(appRootDir, moduleId) {
60
+ const normalizedId = path.normalize(moduleId);
61
+ const normalizedRoot = path.normalize(appRootDir);
62
+ const relative = path
63
+ .relative(normalizedRoot, normalizedId)
64
+ .replace(/\\/g, "/");
65
+ if (relative.startsWith(`${SERVER_APIS_DIR}/`)) {
66
+ return qualifyAnchoredServerApisRelative(relative);
67
+ }
68
+ // Plugin base is client/ or Vite passes a ../server/apis/... module id.
69
+ if (relative.startsWith(`../${SERVER_APIS_DIR}/`)) {
70
+ return qualifyAnchoredServerApisRelative(relative.slice("../".length));
71
+ }
72
+ // Fallback for module ids not matched above: /@fs/ prefixed ids, standard
73
+ // absolute paths when appRootDir is 2+ levels above server/apis/, etc.
74
+ // NOTE: unanchored to appRootDir — matches any id containing /server/apis/
75
+ // with an api.ts/api.tsx basename. lastIndexOf picks the deepest segment.
76
+ const posixId = normalizedId.replace(/\\/g, "/");
77
+ const segment = `/${SERVER_APIS_DIR}/`;
78
+ const segmentIndex = posixId.lastIndexOf(segment);
79
+ if (segmentIndex !== -1) {
80
+ return qualifySegmentFallbackRelative(posixId.slice(segmentIndex + 1));
81
+ }
82
+ return null;
83
+ }
21
84
  /**
22
85
  * Vite plugin that prepends `__setEntryPoint(relativePath)` to SDK API files
23
86
  * so that `api()` can stamp the authoritative source file
24
87
  * path onto the compiled API object.
25
88
  *
89
+ * @param appRootDir - App root (parent of `client/` and `server/`).
90
+ *
26
91
  * Runs in both dev and build. The user's source code is never modified on disk.
27
92
  */
28
- export function sdkApiEntryPointPlugin(root) {
93
+ export function sdkApiEntryPointPlugin(appRootDir) {
29
94
  return {
30
95
  name: "sb-sdk-api-entry-point",
31
96
  enforce: "pre",
32
97
  transform(code, id) {
33
- const relative = path.relative(root, id).replace(/\\/g, "/");
34
- if (!relative.startsWith("server/apis/") ||
35
- relative === "server/apis/index.ts") {
36
- return null;
37
- }
38
- if (!relative.endsWith(".ts") && !relative.endsWith(".tsx")) {
98
+ const relative = resolveSdkApiEntryPointRelativePath(appRootDir, id);
99
+ if (!relative) {
39
100
  return null;
40
101
  }
41
102
  const prependLines = [
@@ -1 +1 @@
1
- {"version":3,"file":"vite-plugin-sdk-api-entry-point.mjs","sourceRoot":"","sources":["../src/vite-plugin-sdk-api-entry-point.mts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B;;;;;;;;;GASG;AACH,SAAS,oBAAoB,CAC3B,gBAAwB,EACxB,iBAAyB;IAEzB,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAC3C,IAAI,iBAAiB,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,MAAM,QAAQ,GAAG,CAAC,MAAM,CAAC;SACtB,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,iBAAiB,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;SAC9D,IAAI,CAAC,GAAG,CAAC,CAAC;IACb,OAAO,KAAK,GAAG,QAAQ,CAAC;AAC1B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,OAAO;QACL,IAAI,EAAE,wBAAwB;QAC9B,OAAO,EAAE,KAAK;QAEd,SAAS,CAAC,IAAI,EAAE,EAAE;YAChB,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAC7D,IACE,CAAC,QAAQ,CAAC,UAAU,CAAC,cAAc,CAAC;gBACpC,QAAQ,KAAK,sBAAsB,EACnC,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5D,OAAO,IAAI,CAAC;YACd,CAAC;YAED,MAAM,YAAY,GAAG;gBACnB,4EAA4E;gBAC5E,eAAe,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI;gBAC3C,EAAE;aACH,CAAC;YACF,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACxC,MAAM,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;YAElD,MAAM,mBAAmB,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC;YAEpD,OAAO;gBACL,IAAI,EAAE,OAAO,GAAG,IAAI;gBACpB,GAAG,EAAE;oBACH,OAAO,EAAE,CAAC;oBACV,IAAI,EAAE,EAAE;oBACR,OAAO,EAAE,CAAC,EAAE,CAAC;oBACb,cAAc,EAAE,CAAC,IAAI,CAAC;oBACtB,KAAK,EAAE,EAAE;oBACT,QAAQ,EAAE,oBAAoB,CAC5B,mBAAmB,EACnB,iBAAiB,CAClB;iBACF;aACF,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"vite-plugin-sdk-api-entry-point.mjs","sourceRoot":"","sources":["../src/vite-plugin-sdk-api-entry-point.mts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import path from "node:path";
2
2
  import { describe, it, expect } from "vitest";
3
- import { sdkApiEntryPointPlugin } from "./vite-plugin-sdk-api-entry-point.mjs";
3
+ import { resolveSdkApiEntryPointRelativePath, sdkApiEntryPointPlugin, } from "./vite-plugin-sdk-api-entry-point.mjs";
4
4
  function createPlugin(root) {
5
5
  const plugin = sdkApiEntryPointPlugin(root);
6
6
  const transform = plugin.transform;
@@ -60,6 +60,38 @@ function expectValidSourcemap(result, originalCode) {
60
60
  expect(sourceLine).toBe(i);
61
61
  });
62
62
  }
63
+ describe("resolveSdkApiEntryPointRelativePath", () => {
64
+ it("resolves server API paths from the true app root", () => {
65
+ expect(resolveSdkApiEntryPointRelativePath("/app", "/app/server/apis/GetUsers/api.ts")).toBe("server/apis/GetUsers/api.ts");
66
+ });
67
+ it("resolves server API paths when the base dir is vite client/", () => {
68
+ expect(resolveSdkApiEntryPointRelativePath("/app/client", "/app/server/apis/GetPastAnalyses/api.ts")).toBe("server/apis/GetPastAnalyses/api.ts");
69
+ });
70
+ it("resolves server API paths from absolute /@fs module ids", () => {
71
+ expect(resolveSdkApiEntryPointRelativePath("/app", "/@fs/Users/me/app/server/apis/GetFeedback/api.ts")).toBe("server/apis/GetFeedback/api.ts");
72
+ });
73
+ it("returns null for the registry barrel file", () => {
74
+ expect(resolveSdkApiEntryPointRelativePath("/app", "/app/server/apis/index.ts")).toBeNull();
75
+ });
76
+ it("returns null when app root contains server/apis and module is a client file", () => {
77
+ expect(resolveSdkApiEntryPointRelativePath("/home/server/apis/myapp", "/home/server/apis/myapp/client/components/Button.tsx")).toBeNull();
78
+ });
79
+ it("uses the deepest server/apis segment in /@fs fallback", () => {
80
+ expect(resolveSdkApiEntryPointRelativePath("/app", "/@fs/home/server/apis/decoy/server/apis/GetReal/api.ts")).toBe("server/apis/GetReal/api.ts");
81
+ });
82
+ it("resolves server API paths for api.tsx entry points", () => {
83
+ expect(resolveSdkApiEntryPointRelativePath("/app", "/app/server/apis/Render/api.tsx")).toBe("server/apis/Render/api.tsx");
84
+ });
85
+ it("resolves Clark-style API entry points that are not named api.ts", () => {
86
+ expect(resolveSdkApiEntryPointRelativePath("/app", "/app/server/apis/issues/list-issues.ts")).toBe("server/apis/issues/list-issues.ts");
87
+ });
88
+ it("resolves helper modules under server/apis/ on anchored paths", () => {
89
+ expect(resolveSdkApiEntryPointRelativePath("/app", "/app/server/apis/GetFoo/helper.ts")).toBe("server/apis/GetFoo/helper.ts");
90
+ });
91
+ it("returns null for index.ts under an API directory", () => {
92
+ expect(resolveSdkApiEntryPointRelativePath("/app", "/app/server/apis/GetFoo/index.ts")).toBeNull();
93
+ });
94
+ });
63
95
  describe("sdkApiEntryPointPlugin", () => {
64
96
  const root = "/app";
65
97
  it("has the correct plugin name and enforce order", () => {
@@ -68,6 +100,12 @@ describe("sdkApiEntryPointPlugin", () => {
68
100
  expect(plugin.enforce).toBe("pre");
69
101
  });
70
102
  describe("transform", () => {
103
+ it("prepends __setEntryPoint for Clark-style list-issues.ts entry points", () => {
104
+ const { transform } = createPlugin(root);
105
+ const result = transform('export default api({ name: "ListIssues" });', path.join(root, "server/apis/issues/list-issues.ts"));
106
+ expect(result).not.toBeNull();
107
+ expect(result.code).toContain('__sb_set_ep("server/apis/issues/list-issues.ts");');
108
+ });
71
109
  it("prepends __setEntryPoint for a standard API file", () => {
72
110
  const { transform } = createPlugin(root);
73
111
  const result = transform('export default api({ name: "GetUsers" });', path.join(root, "server/apis/GetUsers/api.ts"));
@@ -103,6 +141,20 @@ describe("sdkApiEntryPointPlugin", () => {
103
141
  expect(result).not.toBeNull();
104
142
  expect(result.code).toContain('__sb_set_ep("server/apis/v2/GetUsers/api.ts");');
105
143
  });
144
+ it("prepends __setEntryPoint when plugin root is vite client/ subdir (fullstack)", () => {
145
+ const appRoot = "/app";
146
+ const viteRoot = path.join(appRoot, "client");
147
+ const { transform } = createPlugin(viteRoot);
148
+ const result = transform('export default api({ name: "GetPastAnalyses" });', path.join(appRoot, "server/apis/GetPastAnalyses/api.ts"));
149
+ expect(result).not.toBeNull();
150
+ expect(result.code).toContain('__sb_set_ep("server/apis/GetPastAnalyses/api.ts");');
151
+ });
152
+ it("prepends __setEntryPoint for /@fs/ module ids", () => {
153
+ const { transform } = createPlugin(root);
154
+ const result = transform('export default api({ name: "GetFeedback" });', "/@fs/Users/me/app/server/apis/GetFeedback/api.ts");
155
+ expect(result).not.toBeNull();
156
+ expect(result.code).toContain('__sb_set_ep("server/apis/GetFeedback/api.ts");');
157
+ });
106
158
  it("preserves original code after the prepend", () => {
107
159
  const { transform } = createPlugin(root);
108
160
  const originalCode = [
@@ -1 +1 @@
1
- {"version":3,"file":"vite-plugin-sdk-api-entry-point.test.mjs","sourceRoot":"","sources":["../src/vite-plugin-sdk-api-entry-point.test.mts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAc/E,SAAS,YAAY,CAAC,IAAY;IAChC,MAAM,MAAM,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,MAAM,CAAC,SAGL,CAAC;IACrB,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AAC/B,CAAC;AAED,MAAM,SAAS,GACb,kEAAkE,CAAC;AAErE,SAAS,gBAAgB,CAAC,OAAe;IACvC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACtC,KAAK,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,IAAI,KAAK,CAAC;QAC/B,IAAI,KAAK,GAAG,EAAE,EAAE,CAAC;YACf,KAAK,IAAI,CAAC,CAAC;QACb,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC;YACpD,KAAK,GAAG,CAAC,CAAC;YACV,KAAK,GAAG,CAAC,CAAC;QACZ,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,SAAS,cAAc,CAAC,QAAgB;IACtC,IAAI,iBAAiB,GAAG,CAAC,CAAC;IAC1B,OAAO,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACvC,IAAI,KAAK,KAAK,EAAE;YAAE,OAAO,IAAI,CAAC;QAC9B,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACrD,IAAI,MAAM,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;YACvB,iBAAiB,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC;YAC/B,OAAO,iBAAiB,CAAC;QAC3B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,SAAS,oBAAoB,CAC3B,MAAoC,EACpC,YAAoB;IAEpB,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;IACvD,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAE9C,MAAM,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC;IAE7C,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACpD,MAAM,iBAAiB,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;IAC1D,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IAE5E,MAAM,CAAC,WAAW,CAAC,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;IACpD,WAAW,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,CAAC,EAAE,EAAE;QACpC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,MAAM,IAAI,GAAG,MAAM,CAAC;IAEpB,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,EAAE,MAAM,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QACnD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;QACzB,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;YAC1D,MAAM,EAAE,SAAS,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,MAAM,GAAG,SAAS,CACtB,2CAA2C,EAC3C,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,6BAA6B,CAAC,CAC/C,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;YAC9B,MAAM,CAAC,MAAO,CAAC,IAAI,CAAC,CAAC,SAAS,CAC5B,4EAA4E,CAC7E,CAAC;YACF,MAAM,CAAC,MAAO,CAAC,IAAI,CAAC,CAAC,SAAS,CAC5B,6CAA6C,CAC9C,CAAC;YACF,MAAM,CAAC,MAAO,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,uCAAuC,CAAC,CAAC;QAC1E,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;YACtD,MAAM,EAAE,SAAS,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,MAAM,GAAG,SAAS,CACtB,yCAAyC,EACzC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,4BAA4B,CAAC,CAC9C,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;YAC9B,MAAM,CAAC,MAAO,CAAC,IAAI,CAAC,CAAC,SAAS,CAC5B,4CAA4C,CAC7C,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4BAA4B,EAAE,GAAG,EAAE;YACpC,MAAM,EAAE,SAAS,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,MAAM,GAAG,SAAS,CACtB,oBAAoB,EACpB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,sBAAsB,CAAC,CACxC,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;YAC1C,MAAM,EAAE,SAAS,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,MAAM,GAAG,SAAS,CACtB,oBAAoB,EACpB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,uBAAuB,CAAC,CACzC,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;YACrD,MAAM,EAAE,SAAS,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,MAAM,GAAG,SAAS,CACtB,IAAI,EACJ,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,kCAAkC,CAAC,CACpD,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;YACxC,MAAM,EAAE,SAAS,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,MAAM,GAAG,SAAS,CACtB,yBAAyB,EACzB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,gCAAgC,CAAC,CAClD,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;YAC9B,MAAM,CAAC,MAAO,CAAC,IAAI,CAAC,CAAC,SAAS,CAC5B,gDAAgD,CACjD,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2CAA2C,EAAE,GAAG,EAAE;YACnD,MAAM,EAAE,SAAS,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,YAAY,GAAG;gBACnB,oDAAoD;gBACpD,sBAAsB;gBACtB,qBAAqB;gBACrB,wBAAwB;gBACxB,qDAAqD;gBACrD,0CAA0C;gBAC1C,KAAK;aACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEb,MAAM,MAAM,GAAG,SAAS,CACtB,YAAY,EACZ,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,6BAA6B,CAAC,CAC/C,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;YAC9B,MAAM,CAAC,MAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;QACzB,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;YACtC,MAAM,EAAE,SAAS,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,6BAA6B,CAAC,CAAC;YAC1D,MAAM,MAAM,GAAG,SAAS,CAAC,yBAAyB,EAAE,EAAE,CAAC,CAAC;YAExD,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;YAC9B,MAAM,CAAC,MAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACpC,MAAM,CAAC,MAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAClC,MAAM,CAAC,MAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;YACxD,MAAM,EAAE,SAAS,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,YAAY,GAAG,sCAAsC,CAAC;YAC5D,MAAM,MAAM,GAAG,SAAS,CACtB,YAAY,EACZ,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAC1C,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;YAC9B,MAAM,CAAC,MAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;QAC7D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;YAChE,MAAM,EAAE,SAAS,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,YAAY,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC5D,MAAM,MAAM,GAAG,SAAS,CACtB,YAAY,EACZ,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,yBAAyB,CAAC,CAC3C,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;YAC9B,oBAAoB,CAAC,MAAO,EAAE,YAAY,CAAC,CAAC;YAE5C,MAAM,OAAO,GAAG,cAAc,CAAC,MAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACrD,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;YAC1C,MAAM,EAAE,SAAS,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,YAAY,GAAG,yBAAyB,CAAC;YAC/C,MAAM,MAAM,GAAG,SAAS,CACtB,YAAY,EACZ,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,wBAAwB,CAAC,CAC1C,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;YAC9B,oBAAoB,CAAC,MAAO,EAAE,YAAY,CAAC,CAAC;YAE5C,MAAM,OAAO,GAAG,cAAc,CAAC,MAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACrD,MAAM,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CACvB,iEAAiE,EACjE,CAAC,SAAS,EAAE,EAAE;YACZ,MAAM,EAAE,SAAS,EAAE,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YACzC,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAC7B,EAAE,MAAM,EAAE,SAAS,EAAE,EACrB,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAChC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACb,MAAM,MAAM,GAAG,SAAS,CACtB,YAAY,EACZ,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,0BAA0B,CAAC,CAC5C,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;YAC9B,oBAAoB,CAAC,MAAO,EAAE,YAAY,CAAC,CAAC;QAC9C,CAAC,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"vite-plugin-sdk-api-entry-point.test.mjs","sourceRoot":"","sources":["../src/vite-plugin-sdk-api-entry-point.test.mts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@superblocksteam/sdk",
3
- "version": "2.0.130-next.1",
3
+ "version": "2.0.130-next.3",
4
4
  "description": "Superblocks JS SDK",
5
5
  "homepage": "https://www.superblocks.com",
6
6
  "license": "Superblocks Community Software License",
@@ -17,14 +17,14 @@
17
17
  "@babel/plugin-proposal-decorators": "^7.28.0",
18
18
  "@babel/plugin-transform-typescript": "7.28.0",
19
19
  "@opentelemetry/api": "^1.9.1",
20
- "@opentelemetry/api-logs": "^0.214.0",
20
+ "@opentelemetry/api-logs": "^0.217.0",
21
21
  "@opentelemetry/context-async-hooks": "^2.6.1",
22
- "@opentelemetry/exporter-logs-otlp-http": "^0.214.0",
23
- "@opentelemetry/exporter-trace-otlp-http": "^0.214.0",
22
+ "@opentelemetry/exporter-logs-otlp-http": "^0.217.0",
23
+ "@opentelemetry/exporter-trace-otlp-http": "^0.217.0",
24
24
  "@opentelemetry/instrumentation-express": "^0.62.0",
25
- "@opentelemetry/instrumentation-http": "^0.214.0",
25
+ "@opentelemetry/instrumentation-http": "^0.217.0",
26
26
  "@opentelemetry/resources": "^2.6.1",
27
- "@opentelemetry/sdk-node": "^0.214.0",
27
+ "@opentelemetry/sdk-node": "^0.217.0",
28
28
  "@opentelemetry/semantic-conventions": "^1.36.0",
29
29
  "@superblocksteam/bucketeer-sdk": "1.1.0",
30
30
  "@vitejs/plugin-react": "4.3.4",
@@ -48,11 +48,11 @@
48
48
  "vite-tsconfig-paths": "^6.0.4",
49
49
  "winston": "^3.17.0",
50
50
  "yaml": "^2.7.1",
51
- "@superblocksteam/library-shared": "2.0.130-next.1",
52
- "@superblocksteam/shared": "0.9591.1",
53
- "@superblocksteam/telemetry": "2.0.130-next.1",
54
- "@superblocksteam/util": "2.0.130-next.1",
55
- "@superblocksteam/vite-plugin-file-sync": "2.0.130-next.1"
51
+ "@superblocksteam/library-shared": "2.0.130-next.3",
52
+ "@superblocksteam/shared": "0.9591.3",
53
+ "@superblocksteam/telemetry": "2.0.130-next.3",
54
+ "@superblocksteam/util": "2.0.130-next.3",
55
+ "@superblocksteam/vite-plugin-file-sync": "2.0.130-next.3"
56
56
  },
57
57
  "devDependencies": {
58
58
  "@eslint/js": "^9.39.2",
@@ -65,6 +65,7 @@ import {
65
65
  type DevServerFailureType,
66
66
  devServerMetrics,
67
67
  } from "./dev-server-metrics.mjs";
68
+ import { buildFatalExitLog, parseIsWarm } from "./fatal-exit.mjs";
68
69
  import {
69
70
  formatViteDevServerStartedLog,
70
71
  logViteBuildError,
@@ -1101,6 +1102,18 @@ export async function createDevServer({
1101
1102
  }
1102
1103
  });
1103
1104
 
1105
+ // Read once at startup. The pod's warm-or-cold launch mode is set when the pod
1106
+ // starts and never changes, so this flag stays correct in the fatal-exit log
1107
+ // even if the pod is activated later.
1108
+ const isWarm = parseIsWarm(process.env.SUPERBLOCKS_WARM_STANDBY);
1109
+
1110
+ // Only the first fatal event writes a fatal-exit line and starts shutdown.
1111
+ // Without this, one crash could write several lines: an unhandled rejection
1112
+ // fires once per rejected promise, so a burst of failures (say a dead DB pool
1113
+ // rejecting every in-flight query) would each write a line and each start
1114
+ // shutdown, making one crash look like many in the logs and the crash count.
1115
+ let fatalExitHandled = false;
1116
+
1104
1117
  // Signal handlers attach `.catch` so a synchronous throw in
1105
1118
  // `runGracefulShutdown` (e.g. logger init or lockService shutdown throwing
1106
1119
  // before the first `await`) is logged rather than surfacing as an
@@ -1139,13 +1152,25 @@ export async function createDevServer({
1139
1152
  );
1140
1153
  });
1141
1154
 
1142
- // `uncaughtException` always force-exits in `.finally`, even when the
1143
- // underlying shutdown promise was already resolved by a prior signal. With
1144
- // the dedupe in place, awaiting the cached resolved promise short-circuits
1145
- // through `.then` without firing `.catch`; without the `.finally` the
1146
- // process would linger in event-loop limbo until the OS killed it.
1155
+ // The `.finally` always ends the process once shutdown settles. If an earlier
1156
+ // signal already ran shutdown, this handler still needs to exit; without the
1157
+ // final `process.exit` the process could hang instead of stopping.
1147
1158
  process.on("uncaughtException", (error) => {
1148
- logger.error(`Uncaught exception: ${error.message}`, getErrorMeta(error));
1159
+ if (fatalExitHandled) {
1160
+ return;
1161
+ }
1162
+ fatalExitHandled = true;
1163
+ // Write the fatal-exit line first, and synchronously, so the reason reaches
1164
+ // the logs before anything else runs. Shutdown below may finish first and
1165
+ // call `process.exit(0)`, so the container's real exit code can be 0 even
1166
+ // though this was a crash. That is why `exit_code=1` here is the code this
1167
+ // handler means to use, not a promise of what the container reports: for the
1168
+ // JS-handler lines, trust that the line exists (and the `signal` field) over
1169
+ // its `exit_code` when comparing against the pod's exit status.
1170
+ logger.error(
1171
+ buildFatalExitLog({ handler: "uncaughtException", exitCode: 1, isWarm }),
1172
+ getErrorMeta(error),
1173
+ );
1149
1174
  gracefulShutdown({
1150
1175
  logger,
1151
1176
  serverInitiated: false,
@@ -1154,7 +1179,34 @@ export async function createDevServer({
1154
1179
  .catch((shutdownError) => {
1155
1180
  logger.error(
1156
1181
  "Error during shutdown after uncaught exception:",
1157
- shutdownError,
1182
+ getErrorMeta(shutdownError),
1183
+ );
1184
+ })
1185
+ .finally(() => process.exit(1));
1186
+ });
1187
+
1188
+ // Without its own listener, Node turns an unhandled promise rejection into an
1189
+ // uncaught exception, which would log it under the wrong cause. Handle it here
1190
+ // so a rejection is labelled as a rejection, then exit through the same
1191
+ // shutdown path as an uncaught exception.
1192
+ process.on("unhandledRejection", (reason) => {
1193
+ if (fatalExitHandled) {
1194
+ return;
1195
+ }
1196
+ fatalExitHandled = true;
1197
+ logger.error(
1198
+ buildFatalExitLog({ handler: "unhandledRejection", exitCode: 1, isWarm }),
1199
+ getErrorMeta(reason),
1200
+ );
1201
+ gracefulShutdown({
1202
+ logger,
1203
+ serverInitiated: false,
1204
+ source: "unhandledRejection",
1205
+ })
1206
+ .catch((shutdownError) => {
1207
+ logger.error(
1208
+ "Error during shutdown after unhandled rejection:",
1209
+ getErrorMeta(shutdownError),
1158
1210
  );
1159
1211
  })
1160
1212
  .finally(() => process.exit(1));
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Structured fatal-exit logging for the dev server.
3
+ *
4
+ * The most common cause of live-edit pod deaths is a bare Node exit code 1 with
5
+ * no reason attached: the supervisor only sees the container exit code from
6
+ * Kubernetes, and the gVisor runtime reports no CPU/memory/event-loop metrics,
7
+ * so there is no way to tell why the process stopped. These helpers build one
8
+ * log line, easy to search for, that says why the process is exiting. It is
9
+ * written right before the process exits so the reason still lands in the pod
10
+ * logs even when the batched telemetry export never gets flushed.
11
+ *
12
+ * The fields go in the message body as `key=value` markers instead of as
13
+ * telemetry attributes, on purpose: at exit time the synchronous stdout write is
14
+ * the only sink we can rely on, while the batched OTel log exporter is usually
15
+ * dropped by `process.exit`. The existing warm-standby failure path in
16
+ * dev-server.mts already puts its markers in the body for the same reason. And
17
+ * for the same reason there is deliberately no OTel counter for fatal exits (a
18
+ * counter increment would be dropped at exit); `FATAL_EXIT_EVENT` below is the
19
+ * log token to query and alert on.
20
+ *
21
+ * Counting note for alerting: one crash can produce up to two of these lines.
22
+ * When a JS handler runs and its own `process.exit(1)` runs before shutdown can
23
+ * exit, the child emits a `handler=uncaughtException`/`unhandledRejection` line
24
+ * AND the supervisor (CLI parent, or the warm entrypoint shell) emits a
25
+ * `handler=containerExit` line for the same exit. A signal kill / OOM emits only
26
+ * the `containerExit` line (no JS handler ran); a JS crash where shutdown exits
27
+ * first with code 0 emits only the JS-handler line (the supervisor sees a clean
28
+ * exit). So a raw `count(event=dev_server_fatal_exit)` over-counts the double
29
+ * case: deduplicate by pod within a short time window for a true unique-crash
30
+ * count.
31
+ *
32
+ * Signal-kill field note: for a signal kill the cold parent emits
33
+ * `exit_code=null signal=SIGKILL` (Node's `child.on("exit")` gives a null code +
34
+ * the signal), while the warm entrypoint shell emits `exit_code=128+N
35
+ * signal=SIGKILL` (its `wait` returns the raw 128+N status). Both are correct
36
+ * for their context; query on the `signal` field, not `exit_code`, for
37
+ * signal-kill alerts.
38
+ */
39
+
40
+ /**
41
+ * Where the fatal exit came from, so each kind can be told apart in the logs.
42
+ *
43
+ * uncaughtException / unhandledRejection A JS handler ran and knows the error
44
+ * name/message/stack.
45
+ * containerExit No JS handler ran (signal kill / OOM,
46
+ * or the graceful-shutdown exit race);
47
+ * the supervisor only knows the code +
48
+ * signal. The CLI parent (dev-parent.mts)
49
+ * and the warm entrypoint shell emit this
50
+ * value. They cannot import this module,
51
+ * so they repeat the same string.
52
+ */
53
+ export type FatalExitHandler =
54
+ | "uncaughtException"
55
+ | "unhandledRejection"
56
+ | "containerExit";
57
+
58
+ /** Fixed token so a log-based metric or a log search can pick out these lines. */
59
+ export const FATAL_EXIT_EVENT = "dev_server_fatal_exit";
60
+
61
+ export interface FatalExitFields {
62
+ /** Where the fatal exit came from. */
63
+ handler: FatalExitHandler;
64
+ /**
65
+ * Exit code the process is about to use (JS handler path) or the code the
66
+ * supervisor saw (container-exit path). `null` when the child was killed by a
67
+ * signal and has no exit code.
68
+ */
69
+ exitCode: number | null;
70
+ /** Signal that killed the process; absent for a JS-level exit. */
71
+ signal?: string | null;
72
+ /** Whether this pod was started as a warm-standby pod (entrypoint `--warm`). */
73
+ isWarm: boolean;
74
+ }
75
+
76
+ /**
77
+ * Parse the entrypoint's warm-standby env var the same way
78
+ * `scripts/dev-server-entrypoint.sh` does, so `is_warm` in the log matches the
79
+ * pod's launch mode whether or not it was activated later.
80
+ */
81
+ export function parseIsWarm(value: string | undefined): boolean {
82
+ switch ((value ?? "").trim().toLowerCase()) {
83
+ case "true":
84
+ case "1":
85
+ case "yes":
86
+ case "on":
87
+ return true;
88
+ default:
89
+ return false;
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Build the fatal-exit log message body. Every value is a simple primitive
95
+ * (enum / number / boolean), so the line is safe to write as-is even on the CSB
96
+ * log path.
97
+ *
98
+ * SYNC: this format is reproduced in two places that cannot import this module —
99
+ * `buildFatalExitLog` in `packages/cli/packages/cli/src/commands/dev-parent.mts`
100
+ * (the parent stays on `node:` builtins) and the `echo` line in
101
+ * `scripts/dev-server-entrypoint.sh` (bash). A field added here must be added in
102
+ * both, or `event=dev_server_fatal_exit` queries will miss one emitter.
103
+ */
104
+ export function buildFatalExitLog(fields: FatalExitFields): string {
105
+ return [
106
+ "Dev server fatal exit",
107
+ `event=${FATAL_EXIT_EVENT}`,
108
+ `handler=${fields.handler}`,
109
+ `exit_code=${fields.exitCode ?? "null"}`,
110
+ `signal=${fields.signal ?? "none"}`,
111
+ `is_warm=${fields.isWarm}`,
112
+ ].join(" ");
113
+ }
@@ -0,0 +1,81 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ import {
4
+ buildFatalExitLog,
5
+ FATAL_EXIT_EVENT,
6
+ parseIsWarm,
7
+ } from "./fatal-exit.mjs";
8
+
9
+ describe("parseIsWarm", () => {
10
+ it("treats the same truthy spellings as the entrypoint shell", () => {
11
+ for (const value of ["true", "1", "yes", "on", "TRUE", "Yes", " on "]) {
12
+ expect(parseIsWarm(value)).toBe(true);
13
+ }
14
+ });
15
+
16
+ it("treats anything else (including undefined) as not warm", () => {
17
+ for (const value of ["false", "0", "no", "off", "", "cold", undefined]) {
18
+ expect(parseIsWarm(value)).toBe(false);
19
+ }
20
+ });
21
+ });
22
+
23
+ describe("buildFatalExitLog", () => {
24
+ it("carries the stable event marker so a log-based metric can isolate the line", () => {
25
+ const line = buildFatalExitLog({
26
+ handler: "uncaughtException",
27
+ exitCode: 1,
28
+ isWarm: true,
29
+ });
30
+ expect(line).toContain(`event=${FATAL_EXIT_EVENT}`);
31
+ });
32
+
33
+ it("encodes the handler, exit code, signal, and warm flag as snake_case markers", () => {
34
+ const line = buildFatalExitLog({
35
+ handler: "uncaughtException",
36
+ exitCode: 1,
37
+ signal: "SIGABRT",
38
+ isWarm: true,
39
+ });
40
+ expect(line).toContain("handler=uncaughtException");
41
+ expect(line).toContain("exit_code=1");
42
+ expect(line).toContain("signal=SIGABRT");
43
+ expect(line).toContain("is_warm=true");
44
+ });
45
+
46
+ it("defaults the signal to none for a JS-level exit and renders a null code", () => {
47
+ const line = buildFatalExitLog({
48
+ handler: "containerExit",
49
+ exitCode: null,
50
+ isWarm: false,
51
+ });
52
+ expect(line).toContain("signal=none");
53
+ expect(line).toContain("exit_code=null");
54
+ expect(line).toContain("is_warm=false");
55
+ });
56
+
57
+ it("renders an explicit null signal as none (interface allows null and undefined)", () => {
58
+ const line = buildFatalExitLog({
59
+ handler: "uncaughtException",
60
+ exitCode: 1,
61
+ signal: null,
62
+ isWarm: false,
63
+ });
64
+ expect(line).toContain("signal=none");
65
+ });
66
+
67
+ it("produces the exact format-contract string (field names, order, separators)", () => {
68
+ // The full line is the log-query/alerting contract shared across the three
69
+ // emitters. A reordered field, changed separator, or added prefix would slip
70
+ // past the per-field toContain checks but break queries; this locks it.
71
+ const line = buildFatalExitLog({
72
+ handler: "uncaughtException",
73
+ exitCode: 1,
74
+ signal: null,
75
+ isWarm: false,
76
+ });
77
+ expect(line).toBe(
78
+ "Dev server fatal exit event=dev_server_fatal_exit handler=uncaughtException exit_code=1 signal=none is_warm=false",
79
+ );
80
+ });
81
+ });