@tanstack/start-plugin-core 1.166.12 → 1.166.14

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,137 +1,158 @@
1
- import { isAbsolute, resolve, relative, extname } from "node:path";
1
+ import { IMPORT_PROTECTION_DEBUG, IMPORT_PROTECTION_DEBUG_FILTER, KNOWN_SOURCE_EXTENSIONS } from "./constants.js";
2
2
  import { normalizePath } from "vite";
3
- import { IMPORT_PROTECTION_DEBUG_FILTER, IMPORT_PROTECTION_DEBUG, KNOWN_SOURCE_EXTENSIONS } from "./constants.js";
3
+ import { extname, isAbsolute, relative, resolve } from "node:path";
4
+ //#region src/import-protection-plugin/utils.ts
4
5
  function dedupePatterns(patterns) {
5
- const out = [];
6
- const seen = /* @__PURE__ */ new Set();
7
- for (const p of patterns) {
8
- const key = typeof p === "string" ? `s:${p}` : `r:${p.toString()}`;
9
- if (seen.has(key)) continue;
10
- seen.add(key);
11
- out.push(p);
12
- }
13
- return out;
14
- }
6
+ const out = [];
7
+ const seen = /* @__PURE__ */ new Set();
8
+ for (const p of patterns) {
9
+ const key = typeof p === "string" ? `s:${p}` : `r:${p.toString()}`;
10
+ if (seen.has(key)) continue;
11
+ seen.add(key);
12
+ out.push(p);
13
+ }
14
+ return out;
15
+ }
16
+ /** Strip both `?query` and `#hash` from a module ID. */
15
17
  function stripQueryAndHash(id) {
16
- const q = id.indexOf("?");
17
- const h = id.indexOf("#");
18
- if (q === -1 && h === -1) return id;
19
- if (q === -1) return id.slice(0, h);
20
- if (h === -1) return id.slice(0, q);
21
- return id.slice(0, Math.min(q, h));
22
- }
23
- const normalizeFilePathCache = /* @__PURE__ */ new Map();
18
+ const q = id.indexOf("?");
19
+ const h = id.indexOf("#");
20
+ if (q === -1 && h === -1) return id;
21
+ if (q === -1) return id.slice(0, h);
22
+ if (h === -1) return id.slice(0, q);
23
+ return id.slice(0, Math.min(q, h));
24
+ }
25
+ /**
26
+ * Strip Vite query/hash parameters and normalize the path in one step.
27
+ *
28
+ * Results are memoized because the same module IDs are processed many
29
+ * times across resolveId, transform, and trace-building hooks.
30
+ */
31
+ var normalizeFilePathCache = /* @__PURE__ */ new Map();
24
32
  function normalizeFilePath(id) {
25
- let result = normalizeFilePathCache.get(id);
26
- if (result === void 0) {
27
- result = normalizePath(stripQueryAndHash(id));
28
- normalizeFilePathCache.set(id, result);
29
- }
30
- return result;
31
- }
33
+ let result = normalizeFilePathCache.get(id);
34
+ if (result === void 0) {
35
+ result = normalizePath(stripQueryAndHash(id));
36
+ normalizeFilePathCache.set(id, result);
37
+ }
38
+ return result;
39
+ }
40
+ /** Clear the memoization cache (call from buildStart to bound growth). */
32
41
  function clearNormalizeFilePathCache() {
33
- normalizeFilePathCache.clear();
34
- }
35
- const importSourceRe = /\bfrom\s+(?:"([^"]+)"|'([^']+)')|import\s*\(\s*(?:"([^"]+)"|'([^']+)')\s*\)/g;
42
+ normalizeFilePathCache.clear();
43
+ }
44
+ /**
45
+ * Lightweight regex to extract all import/re-export source strings from
46
+ * post-transform code. Matches:
47
+ * - `from "..."` / `from '...'` (static import/export)
48
+ * - `import("...")` / `import('...')` (dynamic import)
49
+ */
50
+ var importSourceRe = /\bfrom\s+(?:"([^"]+)"|'([^']+)')|import\s*\(\s*(?:"([^"]+)"|'([^']+)')\s*\)/g;
36
51
  function escapeRegExp(s) {
37
- return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
52
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
38
53
  }
54
+ /** Get a value from a Map, creating it with `factory` if absent. */
39
55
  function getOrCreate(map, key, factory) {
40
- let value = map.get(key);
41
- if (value === void 0) {
42
- value = factory();
43
- map.set(key, value);
44
- }
45
- return value;
46
- }
56
+ let value = map.get(key);
57
+ if (value === void 0) {
58
+ value = factory();
59
+ map.set(key, value);
60
+ }
61
+ return value;
62
+ }
63
+ /** Make a path relative to `root`, keeping non-rooted paths as-is. */
47
64
  function relativizePath(p, root) {
48
- if (!p.startsWith(root)) return p;
49
- const ch = p.charCodeAt(root.length);
50
- if (ch !== 47 && !Number.isNaN(ch)) return p;
51
- return ch === 47 ? p.slice(root.length + 1) : p.slice(root.length);
65
+ if (!p.startsWith(root)) return p;
66
+ const ch = p.charCodeAt(root.length);
67
+ if (ch !== 47 && !Number.isNaN(ch)) return p;
68
+ return ch === 47 ? p.slice(root.length + 1) : p.slice(root.length);
52
69
  }
53
70
  function extractImportSources(code) {
54
- const sources = [];
55
- let m;
56
- importSourceRe.lastIndex = 0;
57
- while ((m = importSourceRe.exec(code)) !== null) {
58
- const src = m[1] ?? m[2] ?? m[3] ?? m[4];
59
- if (src) sources.push(src);
60
- }
61
- return sources;
62
- }
71
+ const sources = [];
72
+ let m;
73
+ importSourceRe.lastIndex = 0;
74
+ while ((m = importSourceRe.exec(code)) !== null) {
75
+ const src = m[1] ?? m[2] ?? m[3] ?? m[4];
76
+ if (src) sources.push(src);
77
+ }
78
+ return sources;
79
+ }
80
+ /** Log import-protection debug output when debug mode is enabled. */
63
81
  function debugLog(...args) {
64
- if (!IMPORT_PROTECTION_DEBUG) return;
65
- console.warn("[import-protection:debug]", ...args);
82
+ if (!IMPORT_PROTECTION_DEBUG) return;
83
+ console.warn("[import-protection:debug]", ...args);
66
84
  }
85
+ /** Check if any value matches the configured debug filter (if present). */
67
86
  function matchesDebugFilter(...values) {
68
- const debugFilter = IMPORT_PROTECTION_DEBUG_FILTER;
69
- if (!debugFilter) return true;
70
- return values.some((v) => v.includes(debugFilter));
87
+ const debugFilter = IMPORT_PROTECTION_DEBUG_FILTER;
88
+ if (!debugFilter) return true;
89
+ return values.some((v) => v.includes(debugFilter));
71
90
  }
91
+ /** Strip `?query` (but not `#hash`) from a module ID. */
72
92
  function stripQuery(id) {
73
- const queryIndex = id.indexOf("?");
74
- return queryIndex === -1 ? id : id.slice(0, queryIndex);
93
+ const queryIndex = id.indexOf("?");
94
+ return queryIndex === -1 ? id : id.slice(0, queryIndex);
75
95
  }
76
96
  function withoutKnownExtension(id) {
77
- const ext = extname(id);
78
- return KNOWN_SOURCE_EXTENSIONS.has(ext) ? id.slice(0, -ext.length) : id;
79
- }
97
+ const ext = extname(id);
98
+ return KNOWN_SOURCE_EXTENSIONS.has(ext) ? id.slice(0, -ext.length) : id;
99
+ }
100
+ /**
101
+ * Check whether `filePath` is contained inside `directory` using a
102
+ * boundary-safe comparison. A naïve `filePath.startsWith(directory)`
103
+ * would incorrectly treat `/app/src2/foo.ts` as inside `/app/src`.
104
+ */
80
105
  function isInsideDirectory(filePath, directory) {
81
- const rel = relative(resolve(directory), resolve(filePath));
82
- return rel.length > 0 && !rel.startsWith("..") && !isAbsolute(rel);
83
- }
106
+ const rel = relative(resolve(directory), resolve(filePath));
107
+ return rel.length > 0 && !rel.startsWith("..") && !isAbsolute(rel);
108
+ }
109
+ /**
110
+ * Decide whether a violation should be deferred for later verification
111
+ * rather than reported immediately.
112
+ *
113
+ * Build mode: always defer — generateBundle checks tree-shaking.
114
+ * Dev mock mode: always defer — edge-survival verifies whether the Start
115
+ * compiler strips the import (factory-safe pattern). All violation
116
+ * types and specifier formats are handled uniformly by the
117
+ * edge-survival mechanism in processPendingViolations.
118
+ * Dev error mode: never defer — throw immediately (no mock fallback).
119
+ */
84
120
  function shouldDeferViolation(opts) {
85
- return opts.isBuild || opts.isDevMock;
121
+ return opts.isBuild || opts.isDevMock;
86
122
  }
87
123
  function buildSourceCandidates(source, resolved, root) {
88
- const candidates = /* @__PURE__ */ new Set();
89
- const push = (value) => {
90
- if (!value) return;
91
- candidates.add(value);
92
- candidates.add(stripQuery(value));
93
- candidates.add(withoutKnownExtension(stripQuery(value)));
94
- };
95
- push(source);
96
- if (resolved) {
97
- push(resolved);
98
- const relativeResolved = relativizePath(resolved, root);
99
- push(relativeResolved);
100
- push(`./${relativeResolved}`);
101
- push(`/${relativeResolved}`);
102
- }
103
- return candidates;
124
+ const candidates = /* @__PURE__ */ new Set();
125
+ const push = (value) => {
126
+ if (!value) return;
127
+ candidates.add(value);
128
+ candidates.add(stripQuery(value));
129
+ candidates.add(withoutKnownExtension(stripQuery(value)));
130
+ };
131
+ push(source);
132
+ if (resolved) {
133
+ push(resolved);
134
+ const relativeResolved = relativizePath(resolved, root);
135
+ push(relativeResolved);
136
+ push(`./${relativeResolved}`);
137
+ push(`/${relativeResolved}`);
138
+ }
139
+ return candidates;
104
140
  }
105
141
  function buildResolutionCandidates(id) {
106
- const normalized = normalizeFilePath(id);
107
- const stripped = stripQuery(normalized);
108
- return [.../* @__PURE__ */ new Set([id, normalized, stripped])];
142
+ const normalized = normalizeFilePath(id);
143
+ const stripped = stripQuery(normalized);
144
+ return [...new Set([
145
+ id,
146
+ normalized,
147
+ stripped
148
+ ])];
109
149
  }
110
150
  function canonicalizeResolvedId(id, root, resolveExtensionlessAbsoluteId) {
111
- const stripped = stripQuery(id);
112
- let normalized = normalizeFilePath(stripped);
113
- if (!isAbsolute(normalized) && !normalized.startsWith(".") && !normalized.startsWith("\0") && !/^[a-zA-Z]+:/.test(normalized)) {
114
- normalized = normalizeFilePath(resolve(root, normalized));
115
- }
116
- return resolveExtensionlessAbsoluteId(normalized);
117
- }
118
- export {
119
- buildResolutionCandidates,
120
- buildSourceCandidates,
121
- canonicalizeResolvedId,
122
- clearNormalizeFilePathCache,
123
- debugLog,
124
- dedupePatterns,
125
- escapeRegExp,
126
- extractImportSources,
127
- getOrCreate,
128
- isInsideDirectory,
129
- matchesDebugFilter,
130
- normalizeFilePath,
131
- relativizePath,
132
- shouldDeferViolation,
133
- stripQuery,
134
- stripQueryAndHash,
135
- withoutKnownExtension
136
- };
137
- //# sourceMappingURL=utils.js.map
151
+ let normalized = normalizeFilePath(stripQuery(id));
152
+ if (!isAbsolute(normalized) && !normalized.startsWith(".") && !normalized.startsWith("\0") && !/^[a-zA-Z]+:/.test(normalized)) normalized = normalizeFilePath(resolve(root, normalized));
153
+ return resolveExtensionlessAbsoluteId(normalized);
154
+ }
155
+ //#endregion
156
+ export { buildResolutionCandidates, buildSourceCandidates, canonicalizeResolvedId, clearNormalizeFilePathCache, debugLog, dedupePatterns, escapeRegExp, extractImportSources, getOrCreate, isInsideDirectory, matchesDebugFilter, normalizeFilePath, relativizePath, shouldDeferViolation };
157
+
158
+ //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../../src/import-protection-plugin/utils.ts"],"sourcesContent":["import {\n extname,\n isAbsolute,\n relative,\n resolve as resolvePath,\n} from 'node:path'\nimport { normalizePath } from 'vite'\n\nimport {\n IMPORT_PROTECTION_DEBUG,\n IMPORT_PROTECTION_DEBUG_FILTER,\n KNOWN_SOURCE_EXTENSIONS,\n} from './constants'\n\nexport type Pattern = string | RegExp\n\nexport function dedupePatterns(patterns: Array<Pattern>): Array<Pattern> {\n const out: Array<Pattern> = []\n const seen = new Set<string>()\n for (const p of patterns) {\n const key = typeof p === 'string' ? `s:${p}` : `r:${p.toString()}`\n if (seen.has(key)) continue\n seen.add(key)\n out.push(p)\n }\n return out\n}\n\n/** Strip both `?query` and `#hash` from a module ID. */\nexport function stripQueryAndHash(id: string): string {\n const q = id.indexOf('?')\n const h = id.indexOf('#')\n if (q === -1 && h === -1) return id\n if (q === -1) return id.slice(0, h)\n if (h === -1) return id.slice(0, q)\n return id.slice(0, Math.min(q, h))\n}\n\n/**\n * Strip Vite query/hash parameters and normalize the path in one step.\n *\n * Results are memoized because the same module IDs are processed many\n * times across resolveId, transform, and trace-building hooks.\n */\nconst normalizeFilePathCache = new Map<string, string>()\nexport function normalizeFilePath(id: string): string {\n let result = normalizeFilePathCache.get(id)\n if (result === undefined) {\n result = normalizePath(stripQueryAndHash(id))\n normalizeFilePathCache.set(id, result)\n }\n return result\n}\n\n/** Clear the memoization cache (call from buildStart to bound growth). */\nexport function clearNormalizeFilePathCache(): void {\n normalizeFilePathCache.clear()\n}\n\n/**\n * Lightweight regex to extract all import/re-export source strings from\n * post-transform code. Matches:\n * - `from \"...\"` / `from '...'` (static import/export)\n * - `import(\"...\")` / `import('...')` (dynamic import)\n */\nconst importSourceRe =\n /\\bfrom\\s+(?:\"([^\"]+)\"|'([^']+)')|import\\s*\\(\\s*(?:\"([^\"]+)\"|'([^']+)')\\s*\\)/g\n\nexport function escapeRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\n/** Get a value from a Map, creating it with `factory` if absent. */\nexport function getOrCreate<TKey, TValue>(\n map: Map<TKey, TValue>,\n key: TKey,\n factory: () => TValue,\n): TValue {\n let value = map.get(key)\n if (value === undefined) {\n value = factory()\n map.set(key, value)\n }\n return value\n}\n\n/** Make a path relative to `root`, keeping non-rooted paths as-is. */\nexport function relativizePath(p: string, root: string): string {\n if (!p.startsWith(root)) return p\n const ch = p.charCodeAt(root.length)\n // Must be followed by a separator or end-of-string to be a true child\n if (ch !== 47 && !Number.isNaN(ch)) return p\n return ch === 47 ? p.slice(root.length + 1) : p.slice(root.length)\n}\n\nexport function extractImportSources(code: string): Array<string> {\n const sources: Array<string> = []\n let m: RegExpExecArray | null\n importSourceRe.lastIndex = 0\n while ((m = importSourceRe.exec(code)) !== null) {\n const src = m[1] ?? m[2] ?? m[3] ?? m[4]\n if (src) sources.push(src)\n }\n return sources\n}\n\n/** Log import-protection debug output when debug mode is enabled. */\nexport function debugLog(...args: Array<unknown>): void {\n if (!IMPORT_PROTECTION_DEBUG) return\n console.warn('[import-protection:debug]', ...args)\n}\n\n/** Check if any value matches the configured debug filter (if present). */\nexport function matchesDebugFilter(...values: Array<string>): boolean {\n const debugFilter = IMPORT_PROTECTION_DEBUG_FILTER\n if (!debugFilter) return true\n return values.some((v) => v.includes(debugFilter))\n}\n\n/** Strip `?query` (but not `#hash`) from a module ID. */\nexport function stripQuery(id: string): string {\n const queryIndex = id.indexOf('?')\n return queryIndex === -1 ? id : id.slice(0, queryIndex)\n}\n\nexport function withoutKnownExtension(id: string): string {\n const ext = extname(id)\n return KNOWN_SOURCE_EXTENSIONS.has(ext) ? id.slice(0, -ext.length) : id\n}\n\n/**\n * Check whether `filePath` is contained inside `directory` using a\n * boundary-safe comparison. A naïve `filePath.startsWith(directory)`\n * would incorrectly treat `/app/src2/foo.ts` as inside `/app/src`.\n */\nexport function isInsideDirectory(\n filePath: string,\n directory: string,\n): boolean {\n const rel = relative(resolvePath(directory), resolvePath(filePath))\n return rel.length > 0 && !rel.startsWith('..') && !isAbsolute(rel)\n}\n\n/**\n * Decide whether a violation should be deferred for later verification\n * rather than reported immediately.\n *\n * Build mode: always defer — generateBundle checks tree-shaking.\n * Dev mock mode: always defer — edge-survival verifies whether the Start\n * compiler strips the import (factory-safe pattern). All violation\n * types and specifier formats are handled uniformly by the\n * edge-survival mechanism in processPendingViolations.\n * Dev error mode: never defer — throw immediately (no mock fallback).\n */\nexport function shouldDeferViolation(opts: {\n isBuild: boolean\n isDevMock: boolean\n}): boolean {\n return opts.isBuild || opts.isDevMock\n}\n\nexport function buildSourceCandidates(\n source: string,\n resolved: string | undefined,\n root: string,\n): Set<string> {\n const candidates = new Set<string>()\n const push = (value: string | undefined) => {\n if (!value) return\n candidates.add(value)\n candidates.add(stripQuery(value))\n candidates.add(withoutKnownExtension(stripQuery(value)))\n }\n\n push(source)\n if (resolved) {\n push(resolved)\n const relativeResolved = relativizePath(resolved, root)\n push(relativeResolved)\n push(`./${relativeResolved}`)\n push(`/${relativeResolved}`)\n }\n\n return candidates\n}\n\nexport function buildResolutionCandidates(id: string): Array<string> {\n const normalized = normalizeFilePath(id)\n const stripped = stripQuery(normalized)\n\n return [...new Set([id, normalized, stripped])]\n}\n\nexport function canonicalizeResolvedId(\n id: string,\n root: string,\n resolveExtensionlessAbsoluteId: (value: string) => string,\n): string {\n const stripped = stripQuery(id)\n let normalized = normalizeFilePath(stripped)\n\n if (\n !isAbsolute(normalized) &&\n !normalized.startsWith('.') &&\n !normalized.startsWith('\\0') &&\n !/^[a-zA-Z]+:/.test(normalized)\n ) {\n normalized = normalizeFilePath(resolvePath(root, normalized))\n }\n\n return resolveExtensionlessAbsoluteId(normalized)\n}\n"],"names":["resolvePath"],"mappings":"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"}
1
+ {"version":3,"file":"utils.js","names":[],"sources":["../../../src/import-protection-plugin/utils.ts"],"sourcesContent":["import {\n extname,\n isAbsolute,\n relative,\n resolve as resolvePath,\n} from 'node:path'\nimport { normalizePath } from 'vite'\n\nimport {\n IMPORT_PROTECTION_DEBUG,\n IMPORT_PROTECTION_DEBUG_FILTER,\n KNOWN_SOURCE_EXTENSIONS,\n} from './constants'\n\nexport type Pattern = string | RegExp\n\nexport function dedupePatterns(patterns: Array<Pattern>): Array<Pattern> {\n const out: Array<Pattern> = []\n const seen = new Set<string>()\n for (const p of patterns) {\n const key = typeof p === 'string' ? `s:${p}` : `r:${p.toString()}`\n if (seen.has(key)) continue\n seen.add(key)\n out.push(p)\n }\n return out\n}\n\n/** Strip both `?query` and `#hash` from a module ID. */\nexport function stripQueryAndHash(id: string): string {\n const q = id.indexOf('?')\n const h = id.indexOf('#')\n if (q === -1 && h === -1) return id\n if (q === -1) return id.slice(0, h)\n if (h === -1) return id.slice(0, q)\n return id.slice(0, Math.min(q, h))\n}\n\n/**\n * Strip Vite query/hash parameters and normalize the path in one step.\n *\n * Results are memoized because the same module IDs are processed many\n * times across resolveId, transform, and trace-building hooks.\n */\nconst normalizeFilePathCache = new Map<string, string>()\nexport function normalizeFilePath(id: string): string {\n let result = normalizeFilePathCache.get(id)\n if (result === undefined) {\n result = normalizePath(stripQueryAndHash(id))\n normalizeFilePathCache.set(id, result)\n }\n return result\n}\n\n/** Clear the memoization cache (call from buildStart to bound growth). */\nexport function clearNormalizeFilePathCache(): void {\n normalizeFilePathCache.clear()\n}\n\n/**\n * Lightweight regex to extract all import/re-export source strings from\n * post-transform code. Matches:\n * - `from \"...\"` / `from '...'` (static import/export)\n * - `import(\"...\")` / `import('...')` (dynamic import)\n */\nconst importSourceRe =\n /\\bfrom\\s+(?:\"([^\"]+)\"|'([^']+)')|import\\s*\\(\\s*(?:\"([^\"]+)\"|'([^']+)')\\s*\\)/g\n\nexport function escapeRegExp(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n}\n\n/** Get a value from a Map, creating it with `factory` if absent. */\nexport function getOrCreate<TKey, TValue>(\n map: Map<TKey, TValue>,\n key: TKey,\n factory: () => TValue,\n): TValue {\n let value = map.get(key)\n if (value === undefined) {\n value = factory()\n map.set(key, value)\n }\n return value\n}\n\n/** Make a path relative to `root`, keeping non-rooted paths as-is. */\nexport function relativizePath(p: string, root: string): string {\n if (!p.startsWith(root)) return p\n const ch = p.charCodeAt(root.length)\n // Must be followed by a separator or end-of-string to be a true child\n if (ch !== 47 && !Number.isNaN(ch)) return p\n return ch === 47 ? p.slice(root.length + 1) : p.slice(root.length)\n}\n\nexport function extractImportSources(code: string): Array<string> {\n const sources: Array<string> = []\n let m: RegExpExecArray | null\n importSourceRe.lastIndex = 0\n while ((m = importSourceRe.exec(code)) !== null) {\n const src = m[1] ?? m[2] ?? m[3] ?? m[4]\n if (src) sources.push(src)\n }\n return sources\n}\n\n/** Log import-protection debug output when debug mode is enabled. */\nexport function debugLog(...args: Array<unknown>): void {\n if (!IMPORT_PROTECTION_DEBUG) return\n console.warn('[import-protection:debug]', ...args)\n}\n\n/** Check if any value matches the configured debug filter (if present). */\nexport function matchesDebugFilter(...values: Array<string>): boolean {\n const debugFilter = IMPORT_PROTECTION_DEBUG_FILTER\n if (!debugFilter) return true\n return values.some((v) => v.includes(debugFilter))\n}\n\n/** Strip `?query` (but not `#hash`) from a module ID. */\nexport function stripQuery(id: string): string {\n const queryIndex = id.indexOf('?')\n return queryIndex === -1 ? id : id.slice(0, queryIndex)\n}\n\nexport function withoutKnownExtension(id: string): string {\n const ext = extname(id)\n return KNOWN_SOURCE_EXTENSIONS.has(ext) ? id.slice(0, -ext.length) : id\n}\n\n/**\n * Check whether `filePath` is contained inside `directory` using a\n * boundary-safe comparison. A naïve `filePath.startsWith(directory)`\n * would incorrectly treat `/app/src2/foo.ts` as inside `/app/src`.\n */\nexport function isInsideDirectory(\n filePath: string,\n directory: string,\n): boolean {\n const rel = relative(resolvePath(directory), resolvePath(filePath))\n return rel.length > 0 && !rel.startsWith('..') && !isAbsolute(rel)\n}\n\n/**\n * Decide whether a violation should be deferred for later verification\n * rather than reported immediately.\n *\n * Build mode: always defer — generateBundle checks tree-shaking.\n * Dev mock mode: always defer — edge-survival verifies whether the Start\n * compiler strips the import (factory-safe pattern). All violation\n * types and specifier formats are handled uniformly by the\n * edge-survival mechanism in processPendingViolations.\n * Dev error mode: never defer — throw immediately (no mock fallback).\n */\nexport function shouldDeferViolation(opts: {\n isBuild: boolean\n isDevMock: boolean\n}): boolean {\n return opts.isBuild || opts.isDevMock\n}\n\nexport function buildSourceCandidates(\n source: string,\n resolved: string | undefined,\n root: string,\n): Set<string> {\n const candidates = new Set<string>()\n const push = (value: string | undefined) => {\n if (!value) return\n candidates.add(value)\n candidates.add(stripQuery(value))\n candidates.add(withoutKnownExtension(stripQuery(value)))\n }\n\n push(source)\n if (resolved) {\n push(resolved)\n const relativeResolved = relativizePath(resolved, root)\n push(relativeResolved)\n push(`./${relativeResolved}`)\n push(`/${relativeResolved}`)\n }\n\n return candidates\n}\n\nexport function buildResolutionCandidates(id: string): Array<string> {\n const normalized = normalizeFilePath(id)\n const stripped = stripQuery(normalized)\n\n return [...new Set([id, normalized, stripped])]\n}\n\nexport function canonicalizeResolvedId(\n id: string,\n root: string,\n resolveExtensionlessAbsoluteId: (value: string) => string,\n): string {\n const stripped = stripQuery(id)\n let normalized = normalizeFilePath(stripped)\n\n if (\n !isAbsolute(normalized) &&\n !normalized.startsWith('.') &&\n !normalized.startsWith('\\0') &&\n !/^[a-zA-Z]+:/.test(normalized)\n ) {\n normalized = normalizeFilePath(resolvePath(root, normalized))\n }\n\n return resolveExtensionlessAbsoluteId(normalized)\n}\n"],"mappings":"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"}