@tanstack/start-plugin-core 1.166.12 → 1.166.13

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 (87) hide show
  1. package/dist/esm/build-sitemap.js +94 -123
  2. package/dist/esm/build-sitemap.js.map +1 -1
  3. package/dist/esm/constants.js +15 -20
  4. package/dist/esm/constants.js.map +1 -1
  5. package/dist/esm/dev-server-plugin/dev-styles.js +137 -150
  6. package/dist/esm/dev-server-plugin/dev-styles.js.map +1 -1
  7. package/dist/esm/dev-server-plugin/extract-html-scripts.js +16 -15
  8. package/dist/esm/dev-server-plugin/extract-html-scripts.js.map +1 -1
  9. package/dist/esm/dev-server-plugin/plugin.js +125 -195
  10. package/dist/esm/dev-server-plugin/plugin.js.map +1 -1
  11. package/dist/esm/import-protection-plugin/ast.js +6 -5
  12. package/dist/esm/import-protection-plugin/ast.js.map +1 -1
  13. package/dist/esm/import-protection-plugin/constants.js +20 -22
  14. package/dist/esm/import-protection-plugin/constants.js.map +1 -1
  15. package/dist/esm/import-protection-plugin/defaults.js +35 -25
  16. package/dist/esm/import-protection-plugin/defaults.js.map +1 -1
  17. package/dist/esm/import-protection-plugin/extensionlessAbsoluteIdResolver.js +93 -92
  18. package/dist/esm/import-protection-plugin/extensionlessAbsoluteIdResolver.js.map +1 -1
  19. package/dist/esm/import-protection-plugin/matchers.js +23 -24
  20. package/dist/esm/import-protection-plugin/matchers.js.map +1 -1
  21. package/dist/esm/import-protection-plugin/plugin.js +1045 -1361
  22. package/dist/esm/import-protection-plugin/plugin.js.map +1 -1
  23. package/dist/esm/import-protection-plugin/postCompileUsage.js +58 -55
  24. package/dist/esm/import-protection-plugin/postCompileUsage.js.map +1 -1
  25. package/dist/esm/import-protection-plugin/rewriteDeniedImports.js +187 -259
  26. package/dist/esm/import-protection-plugin/rewriteDeniedImports.js.map +1 -1
  27. package/dist/esm/import-protection-plugin/sourceLocation.js +238 -248
  28. package/dist/esm/import-protection-plugin/sourceLocation.js.map +1 -1
  29. package/dist/esm/import-protection-plugin/trace.js +173 -184
  30. package/dist/esm/import-protection-plugin/trace.js.map +1 -1
  31. package/dist/esm/import-protection-plugin/utils.js +132 -111
  32. package/dist/esm/import-protection-plugin/utils.js.map +1 -1
  33. package/dist/esm/import-protection-plugin/virtualModules.js +216 -196
  34. package/dist/esm/import-protection-plugin/virtualModules.js.map +1 -1
  35. package/dist/esm/index.js +2 -7
  36. package/dist/esm/load-env-plugin/plugin.js +12 -11
  37. package/dist/esm/load-env-plugin/plugin.js.map +1 -1
  38. package/dist/esm/output-directory.js +10 -10
  39. package/dist/esm/output-directory.js.map +1 -1
  40. package/dist/esm/plugin.js +275 -355
  41. package/dist/esm/plugin.js.map +1 -1
  42. package/dist/esm/post-server-build.js +39 -53
  43. package/dist/esm/post-server-build.js.map +1 -1
  44. package/dist/esm/prerender.js +177 -239
  45. package/dist/esm/prerender.js.map +1 -1
  46. package/dist/esm/preview-server-plugin/plugin.js +41 -44
  47. package/dist/esm/preview-server-plugin/plugin.js.map +1 -1
  48. package/dist/esm/queue.js +115 -126
  49. package/dist/esm/queue.js.map +1 -1
  50. package/dist/esm/resolve-entries.js +31 -32
  51. package/dist/esm/resolve-entries.js.map +1 -1
  52. package/dist/esm/schema.js +156 -179
  53. package/dist/esm/schema.js.map +1 -1
  54. package/dist/esm/start-compiler-plugin/compiler.js +655 -812
  55. package/dist/esm/start-compiler-plugin/compiler.js.map +1 -1
  56. package/dist/esm/start-compiler-plugin/handleClientOnlyJSX.js +25 -8
  57. package/dist/esm/start-compiler-plugin/handleClientOnlyJSX.js.map +1 -1
  58. package/dist/esm/start-compiler-plugin/handleCreateIsomorphicFn.js +22 -19
  59. package/dist/esm/start-compiler-plugin/handleCreateIsomorphicFn.js.map +1 -1
  60. package/dist/esm/start-compiler-plugin/handleCreateMiddleware.js +20 -22
  61. package/dist/esm/start-compiler-plugin/handleCreateMiddleware.js.map +1 -1
  62. package/dist/esm/start-compiler-plugin/handleCreateServerFn.js +187 -255
  63. package/dist/esm/start-compiler-plugin/handleCreateServerFn.js.map +1 -1
  64. package/dist/esm/start-compiler-plugin/handleEnvOnly.js +23 -33
  65. package/dist/esm/start-compiler-plugin/handleEnvOnly.js.map +1 -1
  66. package/dist/esm/start-compiler-plugin/plugin.js +247 -291
  67. package/dist/esm/start-compiler-plugin/plugin.js.map +1 -1
  68. package/dist/esm/start-compiler-plugin/utils.js +27 -27
  69. package/dist/esm/start-compiler-plugin/utils.js.map +1 -1
  70. package/dist/esm/start-manifest-plugin/manifestBuilder.js +272 -378
  71. package/dist/esm/start-manifest-plugin/manifestBuilder.js.map +1 -1
  72. package/dist/esm/start-manifest-plugin/plugin.js +35 -44
  73. package/dist/esm/start-manifest-plugin/plugin.js.map +1 -1
  74. package/dist/esm/start-router-plugin/constants.js +6 -5
  75. package/dist/esm/start-router-plugin/constants.js.map +1 -1
  76. package/dist/esm/start-router-plugin/generator-plugins/prerender-routes-plugin.js +24 -19
  77. package/dist/esm/start-router-plugin/generator-plugins/prerender-routes-plugin.js.map +1 -1
  78. package/dist/esm/start-router-plugin/generator-plugins/routes-manifest-plugin.js +28 -29
  79. package/dist/esm/start-router-plugin/generator-plugins/routes-manifest-plugin.js.map +1 -1
  80. package/dist/esm/start-router-plugin/plugin.js +146 -199
  81. package/dist/esm/start-router-plugin/plugin.js.map +1 -1
  82. package/dist/esm/start-router-plugin/pruneServerOnlySubtrees.js +32 -31
  83. package/dist/esm/start-router-plugin/pruneServerOnlySubtrees.js.map +1 -1
  84. package/dist/esm/utils.js +14 -14
  85. package/dist/esm/utils.js.map +1 -1
  86. package/package.json +7 -7
  87. package/dist/esm/index.js.map +0 -1
@@ -1,190 +1,179 @@
1
- import { relativizePath, getOrCreate } from "./utils.js";
2
- class ImportGraph {
3
- /**
4
- * resolvedId -> Map<importer, specifier>
5
- *
6
- * We use a Map instead of a Set of objects so edges dedupe correctly.
7
- */
8
- reverseEdges = /* @__PURE__ */ new Map();
9
- /**
10
- * Forward-edge index: importer -> Set<resolvedId>.
11
- *
12
- * Maintained alongside reverseEdges so that {@link invalidate} can remove
13
- * all outgoing edges for a file in O(outgoing-edges) instead of scanning
14
- * every reverse-edge map in the graph.
15
- */
16
- forwardEdges = /* @__PURE__ */ new Map();
17
- entries = /* @__PURE__ */ new Set();
18
- addEdge(resolved, importer, specifier) {
19
- getOrCreate(this.reverseEdges, resolved, () => /* @__PURE__ */ new Map()).set(
20
- importer,
21
- specifier
22
- );
23
- getOrCreate(this.forwardEdges, importer, () => /* @__PURE__ */ new Set()).add(resolved);
24
- }
25
- /** Convenience for tests/debugging. */
26
- getEdges(resolved) {
27
- const importers = this.reverseEdges.get(resolved);
28
- if (!importers) return void 0;
29
- const out = /* @__PURE__ */ new Set();
30
- for (const [importer, specifier] of importers) {
31
- out.add({ importer, specifier });
32
- }
33
- return out;
34
- }
35
- addEntry(id) {
36
- this.entries.add(id);
37
- }
38
- clear() {
39
- this.reverseEdges.clear();
40
- this.forwardEdges.clear();
41
- this.entries.clear();
42
- }
43
- invalidate(id) {
44
- const targets = this.forwardEdges.get(id);
45
- if (targets) {
46
- for (const resolved of targets) {
47
- this.reverseEdges.get(resolved)?.delete(id);
48
- }
49
- this.forwardEdges.delete(id);
50
- }
51
- this.reverseEdges.delete(id);
52
- }
53
- }
1
+ import { getOrCreate, relativizePath } from "./utils.js";
2
+ //#region src/import-protection-plugin/trace.ts
3
+ /**
4
+ * Per-environment reverse import graph.
5
+ * Maps a resolved module id to the set of modules that import it.
6
+ */
7
+ var ImportGraph = class {
8
+ /**
9
+ * resolvedId -> Map<importer, specifier>
10
+ *
11
+ * We use a Map instead of a Set of objects so edges dedupe correctly.
12
+ */
13
+ reverseEdges = /* @__PURE__ */ new Map();
14
+ /**
15
+ * Forward-edge index: importer -> Set<resolvedId>.
16
+ *
17
+ * Maintained alongside reverseEdges so that {@link invalidate} can remove
18
+ * all outgoing edges for a file in O(outgoing-edges) instead of scanning
19
+ * every reverse-edge map in the graph.
20
+ */
21
+ forwardEdges = /* @__PURE__ */ new Map();
22
+ entries = /* @__PURE__ */ new Set();
23
+ addEdge(resolved, importer, specifier) {
24
+ getOrCreate(this.reverseEdges, resolved, () => /* @__PURE__ */ new Map()).set(importer, specifier);
25
+ getOrCreate(this.forwardEdges, importer, () => /* @__PURE__ */ new Set()).add(resolved);
26
+ }
27
+ /** Convenience for tests/debugging. */
28
+ getEdges(resolved) {
29
+ const importers = this.reverseEdges.get(resolved);
30
+ if (!importers) return void 0;
31
+ const out = /* @__PURE__ */ new Set();
32
+ for (const [importer, specifier] of importers) out.add({
33
+ importer,
34
+ specifier
35
+ });
36
+ return out;
37
+ }
38
+ addEntry(id) {
39
+ this.entries.add(id);
40
+ }
41
+ clear() {
42
+ this.reverseEdges.clear();
43
+ this.forwardEdges.clear();
44
+ this.entries.clear();
45
+ }
46
+ invalidate(id) {
47
+ const targets = this.forwardEdges.get(id);
48
+ if (targets) {
49
+ for (const resolved of targets) this.reverseEdges.get(resolved)?.delete(id);
50
+ this.forwardEdges.delete(id);
51
+ }
52
+ this.reverseEdges.delete(id);
53
+ }
54
+ };
55
+ /**
56
+ * BFS from a node upward through reverse edges to find the shortest
57
+ * path to an entry module.
58
+ */
54
59
  function buildTrace(graph, startNode, maxDepth = 20) {
55
- const visited = /* @__PURE__ */ new Set([startNode]);
56
- const depthByNode = /* @__PURE__ */ new Map([[startNode, 0]]);
57
- const down = /* @__PURE__ */ new Map();
58
- const queue = [startNode];
59
- let qi = 0;
60
- let root = null;
61
- while (qi < queue.length) {
62
- const node = queue[qi++];
63
- const depth = depthByNode.get(node);
64
- const importers = graph.reverseEdges.get(node);
65
- if (node !== startNode) {
66
- const isEntry = graph.entries.has(node) || !importers || importers.size === 0;
67
- if (isEntry) {
68
- root = node;
69
- break;
70
- }
71
- }
72
- if (depth >= maxDepth) {
73
- continue;
74
- }
75
- if (!importers || importers.size === 0) {
76
- continue;
77
- }
78
- for (const [importer, specifier] of importers) {
79
- if (visited.has(importer)) continue;
80
- visited.add(importer);
81
- depthByNode.set(importer, depth + 1);
82
- down.set(importer, { next: node, specifier });
83
- queue.push(importer);
84
- }
85
- }
86
- if (!root) {
87
- root = startNode;
88
- }
89
- const trace = [];
90
- let current = root;
91
- for (let i = 0; i <= maxDepth + 1; i++) {
92
- const link = down.get(current);
93
- trace.push({ file: current, specifier: link?.specifier });
94
- if (!link) break;
95
- current = link.next;
96
- }
97
- return trace;
60
+ const visited = new Set([startNode]);
61
+ const depthByNode = new Map([[startNode, 0]]);
62
+ const down = /* @__PURE__ */ new Map();
63
+ const queue = [startNode];
64
+ let qi = 0;
65
+ let root = null;
66
+ while (qi < queue.length) {
67
+ const node = queue[qi++];
68
+ const depth = depthByNode.get(node);
69
+ const importers = graph.reverseEdges.get(node);
70
+ if (node !== startNode) {
71
+ if (graph.entries.has(node) || !importers || importers.size === 0) {
72
+ root = node;
73
+ break;
74
+ }
75
+ }
76
+ if (depth >= maxDepth) continue;
77
+ if (!importers || importers.size === 0) continue;
78
+ for (const [importer, specifier] of importers) {
79
+ if (visited.has(importer)) continue;
80
+ visited.add(importer);
81
+ depthByNode.set(importer, depth + 1);
82
+ down.set(importer, {
83
+ next: node,
84
+ specifier
85
+ });
86
+ queue.push(importer);
87
+ }
88
+ }
89
+ if (!root) root = startNode;
90
+ const trace = [];
91
+ let current = root;
92
+ for (let i = 0; i <= maxDepth + 1; i++) {
93
+ const link = down.get(current);
94
+ trace.push({
95
+ file: current,
96
+ specifier: link?.specifier
97
+ });
98
+ if (!link) break;
99
+ current = link.next;
100
+ }
101
+ return trace;
98
102
  }
99
- const CLIENT_ENV_SUGGESTIONS = [
100
- "Use createServerFn().handler(() => ...) to keep the logic on the server and call it from the client via an RPC bridge",
101
- "Use createServerOnlyFn(() => ...) to mark it as server-only (it will throw if accidentally called from the client)",
102
- "Use createIsomorphicFn().client(() => ...).server(() => ...) to provide separate client and server implementations",
103
- "Move the server-only import out of this file into a separate .server.ts module that is not imported by any client code"
103
+ /**
104
+ * Suggestion strings for server-only code leaking into client environments.
105
+ * Used by both `formatViolation` (terminal) and runtime mock modules (browser).
106
+ */
107
+ var CLIENT_ENV_SUGGESTIONS = [
108
+ "Use createServerFn().handler(() => ...) to keep the logic on the server and call it from the client via an RPC bridge",
109
+ "Use createServerOnlyFn(() => ...) to mark it as server-only (it will throw if accidentally called from the client)",
110
+ "Use createIsomorphicFn().client(() => ...).server(() => ...) to provide separate client and server implementations",
111
+ "Move the server-only import out of this file into a separate .server.ts module that is not imported by any client code"
104
112
  ];
105
- const SERVER_ENV_SUGGESTIONS = [
106
- "Use createClientOnlyFn(() => ...) to mark it as client-only (returns undefined on the server)",
107
- "Use createIsomorphicFn().client(() => ...).server(() => ...) to provide separate client and server implementations",
108
- "Move the client-only import out of this file into a separate .client.ts module that is not imported by any server code"
113
+ /**
114
+ * Suggestion strings for client-only code leaking into server environments.
115
+ * The JSX-specific suggestion is conditionally prepended by `formatViolation`.
116
+ */
117
+ var SERVER_ENV_SUGGESTIONS = [
118
+ "Use createClientOnlyFn(() => ...) to mark it as client-only (returns undefined on the server)",
119
+ "Use createIsomorphicFn().client(() => ...).server(() => ...) to provide separate client and server implementations",
120
+ "Move the client-only import out of this file into a separate .client.ts module that is not imported by any server code"
109
121
  ];
110
122
  function formatViolation(info, root) {
111
- const rel = (p) => relativizePath(p, root);
112
- const relLoc = (p, loc) => {
113
- const r = rel(p);
114
- const file = loc?.file ? rel(loc.file) : r;
115
- return loc ? `${file}:${loc.line}:${loc.column}` : r;
116
- };
117
- const relTraceStep = (step) => {
118
- const file = rel(step.file);
119
- if (step.line == null) return file;
120
- const col = step.column ?? 1;
121
- return `${file}:${step.line}:${col}`;
122
- };
123
- const lines = [];
124
- lines.push(``);
125
- lines.push(`[import-protection] Import denied in ${info.envType} environment`);
126
- lines.push(``);
127
- if (info.type === "specifier") {
128
- lines.push(` Denied by specifier pattern: ${String(info.pattern)}`);
129
- } else if (info.type === "file") {
130
- lines.push(` Denied by file pattern: ${String(info.pattern)}`);
131
- } else {
132
- lines.push(
133
- ` Denied by marker: module is restricted to the opposite environment`
134
- );
135
- }
136
- lines.push(` Importer: ${relLoc(info.importer, info.importerLoc)}`);
137
- lines.push(` Import: "${rel(info.specifier)}"`);
138
- if (info.resolved) {
139
- lines.push(` Resolved: ${rel(info.resolved)}`);
140
- }
141
- if (info.trace.length > 0) {
142
- lines.push(``);
143
- lines.push(` Trace:`);
144
- for (let i = 0; i < info.trace.length; i++) {
145
- const step = info.trace[i];
146
- const isEntry = i === 0;
147
- const tag = isEntry ? " (entry)" : "";
148
- const spec = step.specifier ? ` (import "${rel(step.specifier)}")` : "";
149
- lines.push(` ${i + 1}. ${relTraceStep(step)}${tag}${spec}`);
150
- }
151
- }
152
- if (info.snippet) {
153
- lines.push(``);
154
- lines.push(` Code:`);
155
- for (const snippetLine of info.snippet.lines) {
156
- lines.push(snippetLine);
157
- }
158
- lines.push(``);
159
- lines.push(` ${rel(info.snippet.location)}`);
160
- }
161
- lines.push(``);
162
- if (info.envType === "client") {
163
- lines.push(` Suggestions:`);
164
- for (const s of CLIENT_ENV_SUGGESTIONS) {
165
- lines.push(` - ${s}`);
166
- }
167
- } else {
168
- const snippetText = info.snippet?.lines.join("\n") ?? "";
169
- const looksLikeJsx = /<[A-Z]/.test(snippetText) || /\{.*\(.*\).*\}/.test(snippetText) && /</.test(snippetText);
170
- lines.push(` Suggestions:`);
171
- if (looksLikeJsx) {
172
- lines.push(
173
- ` - Wrap the JSX in <ClientOnly fallback={<Loading />}>...</ClientOnly> so it only renders in the browser after hydration`
174
- );
175
- }
176
- for (const s of SERVER_ENV_SUGGESTIONS) {
177
- lines.push(` - ${s}`);
178
- }
179
- }
180
- lines.push(``);
181
- return lines.join("\n");
123
+ const rel = (p) => relativizePath(p, root);
124
+ const relLoc = (p, loc) => {
125
+ const r = rel(p);
126
+ const file = loc?.file ? rel(loc.file) : r;
127
+ return loc ? `${file}:${loc.line}:${loc.column}` : r;
128
+ };
129
+ const relTraceStep = (step) => {
130
+ const file = rel(step.file);
131
+ if (step.line == null) return file;
132
+ const col = step.column ?? 1;
133
+ return `${file}:${step.line}:${col}`;
134
+ };
135
+ const lines = [];
136
+ lines.push(``);
137
+ lines.push(`[import-protection] Import denied in ${info.envType} environment`);
138
+ lines.push(``);
139
+ if (info.type === "specifier") lines.push(` Denied by specifier pattern: ${String(info.pattern)}`);
140
+ else if (info.type === "file") lines.push(` Denied by file pattern: ${String(info.pattern)}`);
141
+ else lines.push(` Denied by marker: module is restricted to the opposite environment`);
142
+ lines.push(` Importer: ${relLoc(info.importer, info.importerLoc)}`);
143
+ lines.push(` Import: "${rel(info.specifier)}"`);
144
+ if (info.resolved) lines.push(` Resolved: ${rel(info.resolved)}`);
145
+ if (info.trace.length > 0) {
146
+ lines.push(``);
147
+ lines.push(` Trace:`);
148
+ for (let i = 0; i < info.trace.length; i++) {
149
+ const step = info.trace[i];
150
+ const tag = i === 0 ? " (entry)" : "";
151
+ const spec = step.specifier ? ` (import "${rel(step.specifier)}")` : "";
152
+ lines.push(` ${i + 1}. ${relTraceStep(step)}${tag}${spec}`);
153
+ }
154
+ }
155
+ if (info.snippet) {
156
+ lines.push(``);
157
+ lines.push(` Code:`);
158
+ for (const snippetLine of info.snippet.lines) lines.push(snippetLine);
159
+ lines.push(``);
160
+ lines.push(` ${rel(info.snippet.location)}`);
161
+ }
162
+ lines.push(``);
163
+ if (info.envType === "client") {
164
+ lines.push(` Suggestions:`);
165
+ for (const s of CLIENT_ENV_SUGGESTIONS) lines.push(` - ${s}`);
166
+ } else {
167
+ const snippetText = info.snippet?.lines.join("\n") ?? "";
168
+ const looksLikeJsx = /<[A-Z]/.test(snippetText) || /\{.*\(.*\).*\}/.test(snippetText) && /</.test(snippetText);
169
+ lines.push(` Suggestions:`);
170
+ if (looksLikeJsx) lines.push(` - Wrap the JSX in <ClientOnly fallback={<Loading />}>...</ClientOnly> so it only renders in the browser after hydration`);
171
+ for (const s of SERVER_ENV_SUGGESTIONS) lines.push(` - ${s}`);
172
+ }
173
+ lines.push(``);
174
+ return lines.join("\n");
182
175
  }
183
- export {
184
- CLIENT_ENV_SUGGESTIONS,
185
- ImportGraph,
186
- SERVER_ENV_SUGGESTIONS,
187
- buildTrace,
188
- formatViolation
189
- };
190
- //# sourceMappingURL=trace.js.map
176
+ //#endregion
177
+ export { CLIENT_ENV_SUGGESTIONS, ImportGraph, buildTrace, formatViolation };
178
+
179
+ //# sourceMappingURL=trace.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"trace.js","sources":["../../../src/import-protection-plugin/trace.ts"],"sourcesContent":["import { getOrCreate, relativizePath } from './utils'\n\nexport interface TraceEdge {\n importer: string\n specifier?: string\n}\n\n/**\n * Per-environment reverse import graph.\n * Maps a resolved module id to the set of modules that import it.\n */\nexport class ImportGraph {\n /**\n * resolvedId -> Map<importer, specifier>\n *\n * We use a Map instead of a Set of objects so edges dedupe correctly.\n */\n readonly reverseEdges: Map<string, Map<string, string | undefined>> =\n new Map()\n\n /**\n * Forward-edge index: importer -> Set<resolvedId>.\n *\n * Maintained alongside reverseEdges so that {@link invalidate} can remove\n * all outgoing edges for a file in O(outgoing-edges) instead of scanning\n * every reverse-edge map in the graph.\n */\n private readonly forwardEdges: Map<string, Set<string>> = new Map()\n\n readonly entries: Set<string> = new Set()\n\n addEdge(resolved: string, importer: string, specifier?: string): void {\n getOrCreate(this.reverseEdges, resolved, () => new Map()).set(\n importer,\n specifier,\n )\n getOrCreate(this.forwardEdges, importer, () => new Set()).add(resolved)\n }\n\n /** Convenience for tests/debugging. */\n getEdges(resolved: string): Set<TraceEdge> | undefined {\n const importers = this.reverseEdges.get(resolved)\n if (!importers) return undefined\n const out = new Set<TraceEdge>()\n for (const [importer, specifier] of importers) {\n out.add({ importer, specifier })\n }\n return out\n }\n\n addEntry(id: string): void {\n this.entries.add(id)\n }\n\n clear(): void {\n this.reverseEdges.clear()\n this.forwardEdges.clear()\n this.entries.clear()\n }\n\n invalidate(id: string): void {\n // Remove all outgoing edges (id as importer) using the forward index.\n const targets = this.forwardEdges.get(id)\n if (targets) {\n for (const resolved of targets) {\n this.reverseEdges.get(resolved)?.delete(id)\n }\n this.forwardEdges.delete(id)\n }\n // Remove as a target (id as resolved module)\n this.reverseEdges.delete(id)\n }\n}\n\nexport interface TraceStep {\n file: string\n specifier?: string\n line?: number\n column?: number\n}\n\nexport interface Loc {\n file?: string\n line: number\n column: number\n}\n\n/**\n * BFS from a node upward through reverse edges to find the shortest\n * path to an entry module.\n */\nexport function buildTrace(\n graph: ImportGraph,\n startNode: string,\n maxDepth: number = 20,\n): Array<TraceStep> {\n // BFS upward (startNode -> importers -> ...)\n const visited = new Set<string>([startNode])\n const depthByNode = new Map<string, number>([[startNode, 0]])\n\n // For any importer we visit, store the \"down\" link back toward startNode.\n // importer --(specifier)--> next\n const down = new Map<string, { next: string; specifier?: string }>()\n\n const queue: Array<string> = [startNode]\n let qi = 0\n\n let root: string | null = null\n\n while (qi < queue.length) {\n const node = queue[qi++]!\n const depth = depthByNode.get(node)!\n const importers = graph.reverseEdges.get(node)\n\n if (node !== startNode) {\n const isEntry =\n graph.entries.has(node) || !importers || importers.size === 0\n if (isEntry) {\n root = node\n break\n }\n }\n\n if (depth >= maxDepth) {\n continue\n }\n\n if (!importers || importers.size === 0) {\n continue\n }\n\n for (const [importer, specifier] of importers) {\n if (visited.has(importer)) continue\n visited.add(importer)\n depthByNode.set(importer, depth + 1)\n down.set(importer, { next: node, specifier })\n queue.push(importer)\n }\n }\n\n // Best-effort: if we never found a root, just start from the original node.\n if (!root) {\n root = startNode\n }\n\n const trace: Array<TraceStep> = []\n let current = root\n for (let i = 0; i <= maxDepth + 1; i++) {\n const link = down.get(current)\n trace.push({ file: current, specifier: link?.specifier })\n if (!link) break\n current = link.next\n }\n\n return trace\n}\n\nexport interface ViolationInfo {\n env: string\n envType: 'client' | 'server'\n type: 'specifier' | 'file' | 'marker'\n behavior: 'error' | 'mock'\n pattern?: string | RegExp\n specifier: string\n importer: string\n importerLoc?: Loc\n resolved?: string\n trace: Array<TraceStep>\n message: string\n /** Vitest-style code snippet showing the offending usage in the leaf module. */\n snippet?: {\n lines: Array<string>\n highlightLine: number\n location: string\n }\n}\n\n/**\n * Suggestion strings for server-only code leaking into client environments.\n * Used by both `formatViolation` (terminal) and runtime mock modules (browser).\n */\nexport const CLIENT_ENV_SUGGESTIONS = [\n 'Use createServerFn().handler(() => ...) to keep the logic on the server and call it from the client via an RPC bridge',\n 'Use createServerOnlyFn(() => ...) to mark it as server-only (it will throw if accidentally called from the client)',\n 'Use createIsomorphicFn().client(() => ...).server(() => ...) to provide separate client and server implementations',\n 'Move the server-only import out of this file into a separate .server.ts module that is not imported by any client code',\n] as const\n\n/**\n * Suggestion strings for client-only code leaking into server environments.\n * The JSX-specific suggestion is conditionally prepended by `formatViolation`.\n */\nexport const SERVER_ENV_SUGGESTIONS = [\n 'Use createClientOnlyFn(() => ...) to mark it as client-only (returns undefined on the server)',\n 'Use createIsomorphicFn().client(() => ...).server(() => ...) to provide separate client and server implementations',\n 'Move the client-only import out of this file into a separate .client.ts module that is not imported by any server code',\n] as const\n\nexport function formatViolation(info: ViolationInfo, root: string): string {\n const rel = (p: string) => relativizePath(p, root)\n\n const relLoc = (p: string, loc?: Loc) => {\n const r = rel(p)\n const file = loc?.file ? rel(loc.file) : r\n return loc ? `${file}:${loc.line}:${loc.column}` : r\n }\n\n const relTraceStep = (step: TraceStep): string => {\n const file = rel(step.file)\n if (step.line == null) return file\n const col = step.column ?? 1\n return `${file}:${step.line}:${col}`\n }\n\n const lines: Array<string> = []\n lines.push(``)\n lines.push(`[import-protection] Import denied in ${info.envType} environment`)\n lines.push(``)\n\n if (info.type === 'specifier') {\n lines.push(` Denied by specifier pattern: ${String(info.pattern)}`)\n } else if (info.type === 'file') {\n lines.push(` Denied by file pattern: ${String(info.pattern)}`)\n } else {\n lines.push(\n ` Denied by marker: module is restricted to the opposite environment`,\n )\n }\n\n lines.push(` Importer: ${relLoc(info.importer, info.importerLoc)}`)\n lines.push(` Import: \"${rel(info.specifier)}\"`)\n if (info.resolved) {\n lines.push(` Resolved: ${rel(info.resolved)}`)\n }\n\n if (info.trace.length > 0) {\n lines.push(``)\n lines.push(` Trace:`)\n for (let i = 0; i < info.trace.length; i++) {\n const step = info.trace[i]!\n const isEntry = i === 0\n const tag = isEntry ? ' (entry)' : ''\n const spec = step.specifier ? ` (import \"${rel(step.specifier)}\")` : ''\n lines.push(` ${i + 1}. ${relTraceStep(step)}${tag}${spec}`)\n }\n }\n\n if (info.snippet) {\n lines.push(``)\n lines.push(` Code:`)\n for (const snippetLine of info.snippet.lines) {\n lines.push(snippetLine)\n }\n lines.push(``)\n lines.push(` ${rel(info.snippet.location)}`)\n }\n\n lines.push(``)\n\n // Add suggestions\n if (info.envType === 'client') {\n lines.push(` Suggestions:`)\n for (const s of CLIENT_ENV_SUGGESTIONS) {\n lines.push(` - ${s}`)\n }\n } else {\n const snippetText = info.snippet?.lines.join('\\n') ?? ''\n const looksLikeJsx =\n /<[A-Z]/.test(snippetText) ||\n (/\\{.*\\(.*\\).*\\}/.test(snippetText) && /</.test(snippetText))\n\n lines.push(` Suggestions:`)\n if (looksLikeJsx) {\n lines.push(\n ` - Wrap the JSX in <ClientOnly fallback={<Loading />}>...</ClientOnly> so it only renders in the browser after hydration`,\n )\n }\n for (const s of SERVER_ENV_SUGGESTIONS) {\n lines.push(` - ${s}`)\n }\n }\n\n lines.push(``)\n return lines.join('\\n')\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"trace.js","names":[],"sources":["../../../src/import-protection-plugin/trace.ts"],"sourcesContent":["import { getOrCreate, relativizePath } from './utils'\n\nexport interface TraceEdge {\n importer: string\n specifier?: string\n}\n\n/**\n * Per-environment reverse import graph.\n * Maps a resolved module id to the set of modules that import it.\n */\nexport class ImportGraph {\n /**\n * resolvedId -> Map<importer, specifier>\n *\n * We use a Map instead of a Set of objects so edges dedupe correctly.\n */\n readonly reverseEdges: Map<string, Map<string, string | undefined>> =\n new Map()\n\n /**\n * Forward-edge index: importer -> Set<resolvedId>.\n *\n * Maintained alongside reverseEdges so that {@link invalidate} can remove\n * all outgoing edges for a file in O(outgoing-edges) instead of scanning\n * every reverse-edge map in the graph.\n */\n private readonly forwardEdges: Map<string, Set<string>> = new Map()\n\n readonly entries: Set<string> = new Set()\n\n addEdge(resolved: string, importer: string, specifier?: string): void {\n getOrCreate(this.reverseEdges, resolved, () => new Map()).set(\n importer,\n specifier,\n )\n getOrCreate(this.forwardEdges, importer, () => new Set()).add(resolved)\n }\n\n /** Convenience for tests/debugging. */\n getEdges(resolved: string): Set<TraceEdge> | undefined {\n const importers = this.reverseEdges.get(resolved)\n if (!importers) return undefined\n const out = new Set<TraceEdge>()\n for (const [importer, specifier] of importers) {\n out.add({ importer, specifier })\n }\n return out\n }\n\n addEntry(id: string): void {\n this.entries.add(id)\n }\n\n clear(): void {\n this.reverseEdges.clear()\n this.forwardEdges.clear()\n this.entries.clear()\n }\n\n invalidate(id: string): void {\n // Remove all outgoing edges (id as importer) using the forward index.\n const targets = this.forwardEdges.get(id)\n if (targets) {\n for (const resolved of targets) {\n this.reverseEdges.get(resolved)?.delete(id)\n }\n this.forwardEdges.delete(id)\n }\n // Remove as a target (id as resolved module)\n this.reverseEdges.delete(id)\n }\n}\n\nexport interface TraceStep {\n file: string\n specifier?: string\n line?: number\n column?: number\n}\n\nexport interface Loc {\n file?: string\n line: number\n column: number\n}\n\n/**\n * BFS from a node upward through reverse edges to find the shortest\n * path to an entry module.\n */\nexport function buildTrace(\n graph: ImportGraph,\n startNode: string,\n maxDepth: number = 20,\n): Array<TraceStep> {\n // BFS upward (startNode -> importers -> ...)\n const visited = new Set<string>([startNode])\n const depthByNode = new Map<string, number>([[startNode, 0]])\n\n // For any importer we visit, store the \"down\" link back toward startNode.\n // importer --(specifier)--> next\n const down = new Map<string, { next: string; specifier?: string }>()\n\n const queue: Array<string> = [startNode]\n let qi = 0\n\n let root: string | null = null\n\n while (qi < queue.length) {\n const node = queue[qi++]!\n const depth = depthByNode.get(node)!\n const importers = graph.reverseEdges.get(node)\n\n if (node !== startNode) {\n const isEntry =\n graph.entries.has(node) || !importers || importers.size === 0\n if (isEntry) {\n root = node\n break\n }\n }\n\n if (depth >= maxDepth) {\n continue\n }\n\n if (!importers || importers.size === 0) {\n continue\n }\n\n for (const [importer, specifier] of importers) {\n if (visited.has(importer)) continue\n visited.add(importer)\n depthByNode.set(importer, depth + 1)\n down.set(importer, { next: node, specifier })\n queue.push(importer)\n }\n }\n\n // Best-effort: if we never found a root, just start from the original node.\n if (!root) {\n root = startNode\n }\n\n const trace: Array<TraceStep> = []\n let current = root\n for (let i = 0; i <= maxDepth + 1; i++) {\n const link = down.get(current)\n trace.push({ file: current, specifier: link?.specifier })\n if (!link) break\n current = link.next\n }\n\n return trace\n}\n\nexport interface ViolationInfo {\n env: string\n envType: 'client' | 'server'\n type: 'specifier' | 'file' | 'marker'\n behavior: 'error' | 'mock'\n pattern?: string | RegExp\n specifier: string\n importer: string\n importerLoc?: Loc\n resolved?: string\n trace: Array<TraceStep>\n message: string\n /** Vitest-style code snippet showing the offending usage in the leaf module. */\n snippet?: {\n lines: Array<string>\n highlightLine: number\n location: string\n }\n}\n\n/**\n * Suggestion strings for server-only code leaking into client environments.\n * Used by both `formatViolation` (terminal) and runtime mock modules (browser).\n */\nexport const CLIENT_ENV_SUGGESTIONS = [\n 'Use createServerFn().handler(() => ...) to keep the logic on the server and call it from the client via an RPC bridge',\n 'Use createServerOnlyFn(() => ...) to mark it as server-only (it will throw if accidentally called from the client)',\n 'Use createIsomorphicFn().client(() => ...).server(() => ...) to provide separate client and server implementations',\n 'Move the server-only import out of this file into a separate .server.ts module that is not imported by any client code',\n] as const\n\n/**\n * Suggestion strings for client-only code leaking into server environments.\n * The JSX-specific suggestion is conditionally prepended by `formatViolation`.\n */\nexport const SERVER_ENV_SUGGESTIONS = [\n 'Use createClientOnlyFn(() => ...) to mark it as client-only (returns undefined on the server)',\n 'Use createIsomorphicFn().client(() => ...).server(() => ...) to provide separate client and server implementations',\n 'Move the client-only import out of this file into a separate .client.ts module that is not imported by any server code',\n] as const\n\nexport function formatViolation(info: ViolationInfo, root: string): string {\n const rel = (p: string) => relativizePath(p, root)\n\n const relLoc = (p: string, loc?: Loc) => {\n const r = rel(p)\n const file = loc?.file ? rel(loc.file) : r\n return loc ? `${file}:${loc.line}:${loc.column}` : r\n }\n\n const relTraceStep = (step: TraceStep): string => {\n const file = rel(step.file)\n if (step.line == null) return file\n const col = step.column ?? 1\n return `${file}:${step.line}:${col}`\n }\n\n const lines: Array<string> = []\n lines.push(``)\n lines.push(`[import-protection] Import denied in ${info.envType} environment`)\n lines.push(``)\n\n if (info.type === 'specifier') {\n lines.push(` Denied by specifier pattern: ${String(info.pattern)}`)\n } else if (info.type === 'file') {\n lines.push(` Denied by file pattern: ${String(info.pattern)}`)\n } else {\n lines.push(\n ` Denied by marker: module is restricted to the opposite environment`,\n )\n }\n\n lines.push(` Importer: ${relLoc(info.importer, info.importerLoc)}`)\n lines.push(` Import: \"${rel(info.specifier)}\"`)\n if (info.resolved) {\n lines.push(` Resolved: ${rel(info.resolved)}`)\n }\n\n if (info.trace.length > 0) {\n lines.push(``)\n lines.push(` Trace:`)\n for (let i = 0; i < info.trace.length; i++) {\n const step = info.trace[i]!\n const isEntry = i === 0\n const tag = isEntry ? ' (entry)' : ''\n const spec = step.specifier ? ` (import \"${rel(step.specifier)}\")` : ''\n lines.push(` ${i + 1}. ${relTraceStep(step)}${tag}${spec}`)\n }\n }\n\n if (info.snippet) {\n lines.push(``)\n lines.push(` Code:`)\n for (const snippetLine of info.snippet.lines) {\n lines.push(snippetLine)\n }\n lines.push(``)\n lines.push(` ${rel(info.snippet.location)}`)\n }\n\n lines.push(``)\n\n // Add suggestions\n if (info.envType === 'client') {\n lines.push(` Suggestions:`)\n for (const s of CLIENT_ENV_SUGGESTIONS) {\n lines.push(` - ${s}`)\n }\n } else {\n const snippetText = info.snippet?.lines.join('\\n') ?? ''\n const looksLikeJsx =\n /<[A-Z]/.test(snippetText) ||\n (/\\{.*\\(.*\\).*\\}/.test(snippetText) && /</.test(snippetText))\n\n lines.push(` Suggestions:`)\n if (looksLikeJsx) {\n lines.push(\n ` - Wrap the JSX in <ClientOnly fallback={<Loading />}>...</ClientOnly> so it only renders in the browser after hydration`,\n )\n }\n for (const s of SERVER_ENV_SUGGESTIONS) {\n lines.push(` - ${s}`)\n }\n }\n\n lines.push(``)\n return lines.join('\\n')\n}\n"],"mappings":"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"}