@tanstack/start-plugin-core 1.167.35 → 1.169.0

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 (187) hide show
  1. package/dist/esm/import-protection/adapterUtils.d.ts +27 -0
  2. package/dist/esm/import-protection/adapterUtils.js +31 -0
  3. package/dist/esm/import-protection/adapterUtils.js.map +1 -0
  4. package/dist/esm/import-protection/analysis.d.ts +36 -0
  5. package/dist/esm/import-protection/analysis.js +407 -0
  6. package/dist/esm/import-protection/analysis.js.map +1 -0
  7. package/dist/esm/{import-protection-plugin → import-protection}/ast.js +1 -1
  8. package/dist/esm/import-protection/ast.js.map +1 -0
  9. package/dist/esm/import-protection/constants.d.ts +11 -0
  10. package/dist/esm/{import-protection-plugin → import-protection}/constants.js +7 -2
  11. package/dist/esm/import-protection/constants.js.map +1 -0
  12. package/dist/esm/{import-protection-plugin → import-protection}/defaults.js +1 -1
  13. package/dist/esm/import-protection/defaults.js.map +1 -0
  14. package/dist/esm/{import-protection-plugin → import-protection}/extensionlessAbsoluteIdResolver.js +2 -2
  15. package/dist/esm/import-protection/extensionlessAbsoluteIdResolver.js.map +1 -0
  16. package/dist/esm/{import-protection-plugin → import-protection}/matchers.js +1 -1
  17. package/dist/esm/import-protection/matchers.js.map +1 -0
  18. package/dist/esm/{import-protection-plugin/rewriteDeniedImports.d.ts → import-protection/rewrite.d.ts} +0 -4
  19. package/dist/esm/import-protection/rewrite.js +121 -0
  20. package/dist/esm/import-protection/rewrite.js.map +1 -0
  21. package/dist/esm/{import-protection-plugin → import-protection}/sourceLocation.d.ts +32 -3
  22. package/dist/esm/{import-protection-plugin → import-protection}/sourceLocation.js +65 -10
  23. package/dist/esm/import-protection/sourceLocation.js.map +1 -0
  24. package/dist/esm/{import-protection-plugin → import-protection}/trace.d.ts +0 -1
  25. package/dist/esm/{import-protection-plugin → import-protection}/trace.js +1 -1
  26. package/dist/esm/import-protection/trace.js.map +1 -0
  27. package/dist/esm/{import-protection-plugin → import-protection}/utils.d.ts +18 -1
  28. package/dist/esm/{import-protection-plugin → import-protection}/utils.js +13 -20
  29. package/dist/esm/import-protection/utils.js.map +1 -0
  30. package/dist/esm/import-protection/virtualModules.d.ts +25 -0
  31. package/dist/esm/{import-protection-plugin → import-protection}/virtualModules.js +5 -117
  32. package/dist/esm/import-protection/virtualModules.js.map +1 -0
  33. package/dist/esm/index.d.ts +1 -5
  34. package/dist/esm/index.js +2 -4
  35. package/dist/esm/post-build.d.ts +9 -0
  36. package/dist/esm/post-build.js +37 -0
  37. package/dist/esm/post-build.js.map +1 -0
  38. package/dist/esm/prerender.d.ts +11 -0
  39. package/dist/esm/prerender.js +159 -0
  40. package/dist/esm/prerender.js.map +1 -0
  41. package/dist/esm/rsbuild/dev-server.d.ts +21 -0
  42. package/dist/esm/rsbuild/dev-server.js +76 -0
  43. package/dist/esm/rsbuild/dev-server.js.map +1 -0
  44. package/dist/esm/rsbuild/import-protection.d.ts +10 -0
  45. package/dist/esm/rsbuild/import-protection.js +775 -0
  46. package/dist/esm/rsbuild/import-protection.js.map +1 -0
  47. package/dist/esm/rsbuild/index.d.ts +4 -0
  48. package/dist/esm/rsbuild/index.js +3 -0
  49. package/dist/esm/rsbuild/normalized-client-build.d.ts +18 -0
  50. package/dist/esm/rsbuild/normalized-client-build.js +207 -0
  51. package/dist/esm/rsbuild/normalized-client-build.js.map +1 -0
  52. package/dist/esm/rsbuild/planning.d.ts +52 -0
  53. package/dist/esm/rsbuild/planning.js +108 -0
  54. package/dist/esm/rsbuild/planning.js.map +1 -0
  55. package/dist/esm/rsbuild/plugin.d.ts +4 -0
  56. package/dist/esm/rsbuild/plugin.js +344 -0
  57. package/dist/esm/rsbuild/plugin.js.map +1 -0
  58. package/dist/esm/rsbuild/post-build.d.ts +6 -0
  59. package/dist/esm/rsbuild/post-build.js +57 -0
  60. package/dist/esm/rsbuild/post-build.js.map +1 -0
  61. package/dist/esm/rsbuild/schema.d.ts +3372 -0
  62. package/dist/esm/rsbuild/schema.js +12 -0
  63. package/dist/esm/rsbuild/schema.js.map +1 -0
  64. package/dist/esm/rsbuild/start-compiler-host.d.ts +20 -0
  65. package/dist/esm/rsbuild/start-compiler-host.js +150 -0
  66. package/dist/esm/rsbuild/start-compiler-host.js.map +1 -0
  67. package/dist/esm/rsbuild/start-router-plugin.d.ts +18 -0
  68. package/dist/esm/rsbuild/start-router-plugin.js +63 -0
  69. package/dist/esm/rsbuild/start-router-plugin.js.map +1 -0
  70. package/dist/esm/rsbuild/swc-rsc.d.ts +14 -0
  71. package/dist/esm/rsbuild/swc-rsc.js +93 -0
  72. package/dist/esm/rsbuild/swc-rsc.js.map +1 -0
  73. package/dist/esm/rsbuild/types.d.ts +17 -0
  74. package/dist/esm/rsbuild/types.js +0 -0
  75. package/dist/esm/rsbuild/virtual-modules.d.ts +53 -0
  76. package/dist/esm/rsbuild/virtual-modules.js +287 -0
  77. package/dist/esm/rsbuild/virtual-modules.js.map +1 -0
  78. package/dist/esm/schema.d.ts +43 -43
  79. package/dist/esm/start-compiler/compiler.d.ts +1 -1
  80. package/dist/esm/start-compiler/compiler.js +80 -9
  81. package/dist/esm/start-compiler/compiler.js.map +1 -1
  82. package/dist/esm/start-compiler/handleCreateServerFn.js +9 -0
  83. package/dist/esm/start-compiler/handleCreateServerFn.js.map +1 -1
  84. package/dist/esm/start-compiler/host.js +5 -1
  85. package/dist/esm/start-compiler/host.js.map +1 -1
  86. package/dist/esm/start-compiler/types.d.ts +1 -0
  87. package/dist/esm/utils.d.ts +1 -0
  88. package/dist/esm/utils.js +10 -1
  89. package/dist/esm/utils.js.map +1 -1
  90. package/dist/esm/{import-protection-plugin → vite/import-protection-plugin}/plugin.js +41 -92
  91. package/dist/esm/vite/import-protection-plugin/plugin.js.map +1 -0
  92. package/dist/esm/{import-protection-plugin → vite/import-protection-plugin}/types.d.ts +5 -5
  93. package/dist/esm/vite/import-protection-plugin/virtualModules.d.ts +8 -0
  94. package/dist/esm/vite/import-protection-plugin/virtualModules.js +49 -0
  95. package/dist/esm/vite/import-protection-plugin/virtualModules.js.map +1 -0
  96. package/dist/esm/vite/index.d.ts +5 -0
  97. package/dist/esm/vite/index.js +4 -0
  98. package/dist/esm/vite/plugin.js +1 -1
  99. package/dist/esm/vite/plugin.js.map +1 -1
  100. package/dist/esm/vite/post-server-build.js +14 -32
  101. package/dist/esm/vite/post-server-build.js.map +1 -1
  102. package/dist/esm/vite/prerender.d.ts +2 -2
  103. package/dist/esm/vite/prerender.js +17 -147
  104. package/dist/esm/vite/prerender.js.map +1 -1
  105. package/dist/esm/vite/schema.d.ts +23 -23
  106. package/dist/esm/vite/start-compiler-plugin/hot-update.d.ts +2 -0
  107. package/dist/esm/vite/start-compiler-plugin/hot-update.js +16 -0
  108. package/dist/esm/vite/start-compiler-plugin/hot-update.js.map +1 -0
  109. package/dist/esm/vite/start-compiler-plugin/module-specifier.js +9 -4
  110. package/dist/esm/vite/start-compiler-plugin/module-specifier.js.map +1 -1
  111. package/dist/esm/vite/start-compiler-plugin/plugin.js +86 -13
  112. package/dist/esm/vite/start-compiler-plugin/plugin.js.map +1 -1
  113. package/package.json +32 -4
  114. package/src/import-protection/INTERNALS.md +266 -0
  115. package/src/import-protection/adapterUtils.ts +94 -0
  116. package/src/import-protection/analysis.ts +853 -0
  117. package/src/{import-protection-plugin → import-protection}/constants.ts +7 -0
  118. package/src/import-protection/rewrite.ts +229 -0
  119. package/src/{import-protection-plugin → import-protection}/sourceLocation.ts +125 -9
  120. package/src/{import-protection-plugin → import-protection}/trace.ts +0 -1
  121. package/src/{import-protection-plugin → import-protection}/utils.ts +36 -21
  122. package/src/{import-protection-plugin → import-protection}/virtualModules.ts +30 -177
  123. package/src/index.ts +1 -8
  124. package/src/post-build.ts +64 -0
  125. package/src/prerender.ts +292 -0
  126. package/src/rsbuild/INTERNALS-import-protection.md +169 -0
  127. package/src/rsbuild/dev-server.ts +129 -0
  128. package/src/rsbuild/import-protection.ts +1599 -0
  129. package/src/rsbuild/index.ts +4 -0
  130. package/src/rsbuild/normalized-client-build.ts +346 -0
  131. package/src/rsbuild/planning.ts +234 -0
  132. package/src/rsbuild/plugin.ts +754 -0
  133. package/src/rsbuild/post-build.ts +96 -0
  134. package/src/rsbuild/schema.ts +31 -0
  135. package/src/rsbuild/start-compiler-host.ts +250 -0
  136. package/src/rsbuild/start-router-plugin.ts +86 -0
  137. package/src/rsbuild/swc-rsc.ts +166 -0
  138. package/src/rsbuild/types.ts +20 -0
  139. package/src/rsbuild/virtual-modules.ts +565 -0
  140. package/src/start-compiler/compiler.ts +153 -19
  141. package/src/start-compiler/handleCreateServerFn.ts +18 -0
  142. package/src/start-compiler/types.ts +1 -0
  143. package/src/utils.ts +14 -0
  144. package/src/vite/import-protection-plugin/INTERNALS.md +187 -0
  145. package/src/{import-protection-plugin → vite/import-protection-plugin}/plugin.ts +73 -158
  146. package/src/{import-protection-plugin → vite/import-protection-plugin}/types.ts +5 -5
  147. package/src/vite/import-protection-plugin/virtualModules.ts +122 -0
  148. package/src/vite/index.ts +8 -0
  149. package/src/vite/plugin.ts +1 -1
  150. package/src/vite/post-server-build.ts +14 -57
  151. package/src/vite/prerender.ts +19 -260
  152. package/src/vite/start-compiler-plugin/hot-update.ts +24 -0
  153. package/src/vite/start-compiler-plugin/module-specifier.ts +15 -5
  154. package/src/vite/start-compiler-plugin/plugin.ts +193 -18
  155. package/dist/esm/import-protection-plugin/ast.js.map +0 -1
  156. package/dist/esm/import-protection-plugin/constants.d.ts +0 -6
  157. package/dist/esm/import-protection-plugin/constants.js.map +0 -1
  158. package/dist/esm/import-protection-plugin/defaults.js.map +0 -1
  159. package/dist/esm/import-protection-plugin/extensionlessAbsoluteIdResolver.js.map +0 -1
  160. package/dist/esm/import-protection-plugin/matchers.js.map +0 -1
  161. package/dist/esm/import-protection-plugin/plugin.js.map +0 -1
  162. package/dist/esm/import-protection-plugin/postCompileUsage.d.ts +0 -13
  163. package/dist/esm/import-protection-plugin/postCompileUsage.js +0 -63
  164. package/dist/esm/import-protection-plugin/postCompileUsage.js.map +0 -1
  165. package/dist/esm/import-protection-plugin/rewriteDeniedImports.js +0 -205
  166. package/dist/esm/import-protection-plugin/rewriteDeniedImports.js.map +0 -1
  167. package/dist/esm/import-protection-plugin/sourceLocation.js.map +0 -1
  168. package/dist/esm/import-protection-plugin/trace.js.map +0 -1
  169. package/dist/esm/import-protection-plugin/utils.js.map +0 -1
  170. package/dist/esm/import-protection-plugin/virtualModules.d.ts +0 -78
  171. package/dist/esm/import-protection-plugin/virtualModules.js.map +0 -1
  172. package/dist/esm/start-compiler/load-module.d.ts +0 -14
  173. package/dist/esm/start-compiler/load-module.js +0 -18
  174. package/dist/esm/start-compiler/load-module.js.map +0 -1
  175. package/src/import-protection-plugin/INTERNALS.md +0 -700
  176. package/src/import-protection-plugin/postCompileUsage.ts +0 -100
  177. package/src/import-protection-plugin/rewriteDeniedImports.ts +0 -379
  178. package/src/start-compiler/load-module.ts +0 -31
  179. /package/dist/esm/{import-protection-plugin → import-protection}/ast.d.ts +0 -0
  180. /package/dist/esm/{import-protection-plugin → import-protection}/defaults.d.ts +0 -0
  181. /package/dist/esm/{import-protection-plugin → import-protection}/extensionlessAbsoluteIdResolver.d.ts +0 -0
  182. /package/dist/esm/{import-protection-plugin → import-protection}/matchers.d.ts +0 -0
  183. /package/dist/esm/{import-protection-plugin → vite/import-protection-plugin}/plugin.d.ts +0 -0
  184. /package/src/{import-protection-plugin → import-protection}/ast.ts +0 -0
  185. /package/src/{import-protection-plugin → import-protection}/defaults.ts +0 -0
  186. /package/src/{import-protection-plugin → import-protection}/extensionlessAbsoluteIdResolver.ts +0 -0
  187. /package/src/{import-protection-plugin → import-protection}/matchers.ts +0 -0
@@ -1,100 +0,0 @@
1
- import babel from '@babel/core'
2
- import * as t from '@babel/types'
3
- import { parseImportProtectionAst } from './ast'
4
- import type { ParsedAst } from './ast'
5
-
6
- type UsagePos = { line: number; column0: number }
7
-
8
- /**
9
- * Given transformed code, returns the first "meaningful" usage position for an
10
- * import from `source` that survives compilation.
11
- *
12
- * "Preferred" positions (call, new, member-access) take priority over bare
13
- * identifier references. The returned column is 0-based (Babel loc semantics).
14
- */
15
- export function findPostCompileUsagePos(
16
- code: string,
17
- source: string,
18
- ): UsagePos | undefined {
19
- return findPostCompileUsagePosFromAst(parseImportProtectionAst(code), source)
20
- }
21
-
22
- function findPostCompileUsagePosFromAst(
23
- ast: ParsedAst,
24
- source: string,
25
- ): UsagePos | undefined {
26
- // Collect local names bound from this specifier
27
- const imported = new Set<string>()
28
- for (const node of ast.program.body) {
29
- if (t.isImportDeclaration(node) && node.source.value === source) {
30
- if (node.importKind === 'type') continue
31
- for (const s of node.specifiers) {
32
- if (t.isImportSpecifier(s) && s.importKind === 'type') continue
33
- imported.add(s.local.name)
34
- }
35
- }
36
- }
37
- if (imported.size === 0) return undefined
38
-
39
- let preferred: UsagePos | undefined
40
- let anyUsage: UsagePos | undefined
41
-
42
- // babel.traverse can throw on malformed scopes (e.g. duplicate bindings from
43
- // import + const re-declaration) because parseAst doesn't attach a hub
44
- try {
45
- babel.traverse(ast, {
46
- ImportDeclaration(path) {
47
- path.skip()
48
- },
49
-
50
- Identifier(path: babel.NodePath<t.Identifier>) {
51
- if (preferred && anyUsage) {
52
- path.stop()
53
- return
54
- }
55
-
56
- const { node, parent, scope } = path
57
- if (!imported.has(node.name)) return
58
-
59
- // Skip binding positions (declarations, import specifiers, etc.)
60
- if (path.isBindingIdentifier()) return
61
-
62
- // Skip non-shorthand object property keys — they don't reference the import
63
- if (
64
- t.isObjectProperty(parent) &&
65
- parent.key === node &&
66
- !parent.computed &&
67
- !parent.shorthand
68
- )
69
- return
70
- if (t.isObjectMethod(parent) && parent.key === node && !parent.computed)
71
- return
72
- if (t.isExportSpecifier(parent) && parent.exported === node) return
73
-
74
- // Skip if shadowed by a closer binding
75
- const binding = scope.getBinding(node.name)
76
- if (binding && binding.kind !== 'module') return
77
-
78
- const loc = node.loc?.start
79
- if (!loc) return
80
- const pos: UsagePos = { line: loc.line, column0: loc.column }
81
-
82
- const isPreferred =
83
- (t.isCallExpression(parent) && parent.callee === node) ||
84
- (t.isNewExpression(parent) && parent.callee === node) ||
85
- (t.isMemberExpression(parent) && parent.object === node)
86
-
87
- if (isPreferred) {
88
- preferred ||= pos
89
- } else {
90
- anyUsage ||= pos
91
- }
92
- },
93
- })
94
- } catch {
95
- // Scope analysis failed — cannot determine usage positions reliably
96
- return undefined
97
- }
98
-
99
- return preferred ?? anyUsage
100
- }
@@ -1,379 +0,0 @@
1
- import * as t from '@babel/types'
2
- import { generateFromAst } from '@tanstack/router-utils'
3
-
4
- import { MOCK_MODULE_ID } from './virtualModules'
5
- import { getOrCreate } from './utils'
6
- import { parseImportProtectionAst } from './ast'
7
- import type { SourceMapLike } from './sourceLocation'
8
- import type { ParsedAst } from './ast'
9
-
10
- export function isValidExportName(name: string): boolean {
11
- if (name === 'default' || name.length === 0) return false
12
- const first = name.charCodeAt(0)
13
- // First char: A-Z (65-90), a-z (97-122), _ (95), $ (36)
14
- if (
15
- !(
16
- (first >= 65 && first <= 90) ||
17
- (first >= 97 && first <= 122) ||
18
- first === 95 ||
19
- first === 36
20
- )
21
- )
22
- return false
23
- for (let i = 1; i < name.length; i++) {
24
- const ch = name.charCodeAt(i)
25
- // Subsequent: A-Z, a-z, 0-9 (48-57), _, $
26
- if (
27
- !(
28
- (ch >= 65 && ch <= 90) ||
29
- (ch >= 97 && ch <= 122) ||
30
- (ch >= 48 && ch <= 57) ||
31
- ch === 95 ||
32
- ch === 36
33
- )
34
- )
35
- return false
36
- }
37
- return true
38
- }
39
-
40
- export function collectMockExportNamesBySource(
41
- code: string,
42
- ): Map<string, Array<string>> {
43
- return collectMockExportNamesBySourceFromAst(parseImportProtectionAst(code))
44
- }
45
-
46
- function collectMockExportNamesBySourceFromAst(
47
- ast: ParsedAst,
48
- ): Map<string, Array<string>> {
49
- const namesBySource = new Map<string, Set<string>>()
50
- const memberBindingToSource = new Map<string, string>()
51
- const add = (source: string, name: string) => {
52
- if (name === 'default' || name.length === 0) return
53
- getOrCreate(namesBySource, source, () => new Set<string>()).add(name)
54
- }
55
-
56
- for (const node of ast.program.body) {
57
- if (t.isImportDeclaration(node)) {
58
- if (node.importKind === 'type') continue
59
- const source = node.source.value
60
- for (const s of node.specifiers) {
61
- if (t.isImportNamespaceSpecifier(s)) {
62
- memberBindingToSource.set(s.local.name, source)
63
- continue
64
- }
65
- if (t.isImportDefaultSpecifier(s)) {
66
- memberBindingToSource.set(s.local.name, source)
67
- continue
68
- }
69
- if (!t.isImportSpecifier(s)) continue
70
- if (s.importKind === 'type') continue
71
- const importedName = t.isIdentifier(s.imported)
72
- ? s.imported.name
73
- : s.imported.value
74
- // `import { default as x } from 'm'` only requires a default export.
75
- if (importedName === 'default') continue
76
- add(source, importedName)
77
- }
78
- }
79
-
80
- if (t.isExportNamedDeclaration(node) && node.source?.value) {
81
- if (node.exportKind === 'type') continue
82
- const source = node.source.value
83
- for (const s of node.specifiers) {
84
- if (!t.isExportSpecifier(s)) continue
85
- if (s.exportKind === 'type') continue
86
- add(source, s.local.name)
87
- }
88
- }
89
- }
90
-
91
- // For namespace/default imports, collect property names used as
92
- // `binding.foo`/`binding?.foo` so mock-edge modules can expose explicit ESM
93
- // named exports required by Rolldown/native ESM.
94
- if (memberBindingToSource.size > 0) {
95
- const visit = (node: t.Node): void => {
96
- if (t.isMemberExpression(node)) {
97
- const object = node.object
98
- if (t.isIdentifier(object)) {
99
- const source = memberBindingToSource.get(object.name)
100
- if (source) {
101
- const property = node.property
102
- if (!node.computed && t.isIdentifier(property)) {
103
- add(source, property.name)
104
- } else if (node.computed && t.isStringLiteral(property)) {
105
- add(source, property.value)
106
- }
107
- }
108
- }
109
- }
110
-
111
- const keys = t.VISITOR_KEYS[node.type]
112
- if (!keys) return
113
- for (const key of keys) {
114
- const child = (node as unknown as Record<string, unknown>)[key]
115
- if (Array.isArray(child)) {
116
- for (const item of child) {
117
- if (item && typeof item === 'object' && 'type' in item) {
118
- visit(item as t.Node)
119
- }
120
- }
121
- } else if (child && typeof child === 'object' && 'type' in child) {
122
- visit(child as t.Node)
123
- }
124
- }
125
- }
126
-
127
- visit(ast.program)
128
- }
129
-
130
- const out = new Map<string, Array<string>>()
131
- for (const [source, set] of namesBySource) {
132
- out.set(source, Array.from(set).sort())
133
- }
134
- return out
135
- }
136
-
137
- /** Collect all valid named export identifiers from the given code. */
138
- export function collectNamedExports(code: string): Array<string> {
139
- return collectNamedExportsFromAst(parseImportProtectionAst(code))
140
- }
141
-
142
- function collectIdentifiersFromPattern(
143
- pattern: t.LVal,
144
- add: (name: string) => void,
145
- ): void {
146
- if (t.isIdentifier(pattern)) {
147
- add(pattern.name)
148
- } else if (t.isObjectPattern(pattern)) {
149
- for (const prop of pattern.properties) {
150
- if (t.isRestElement(prop)) {
151
- collectIdentifiersFromPattern(prop.argument as t.LVal, add)
152
- } else {
153
- collectIdentifiersFromPattern(prop.value as t.LVal, add)
154
- }
155
- }
156
- } else if (t.isArrayPattern(pattern)) {
157
- for (const elem of pattern.elements) {
158
- if (elem) collectIdentifiersFromPattern(elem as t.LVal, add)
159
- }
160
- } else if (t.isAssignmentPattern(pattern)) {
161
- collectIdentifiersFromPattern(pattern.left, add)
162
- } else if (t.isRestElement(pattern)) {
163
- collectIdentifiersFromPattern(pattern.argument as t.LVal, add)
164
- }
165
- }
166
-
167
- function collectNamedExportsFromAst(ast: ParsedAst): Array<string> {
168
- const names = new Set<string>()
169
- const add = (name: string) => {
170
- if (isValidExportName(name)) names.add(name)
171
- }
172
-
173
- for (const node of ast.program.body) {
174
- if (t.isExportNamedDeclaration(node)) {
175
- if (node.exportKind === 'type') continue
176
-
177
- if (node.declaration) {
178
- const decl = node.declaration
179
- if (t.isFunctionDeclaration(decl) || t.isClassDeclaration(decl)) {
180
- if (decl.id?.name) add(decl.id.name)
181
- } else if (t.isVariableDeclaration(decl)) {
182
- for (const d of decl.declarations) {
183
- collectIdentifiersFromPattern(d.id as t.LVal, add)
184
- }
185
- }
186
- }
187
-
188
- for (const s of node.specifiers) {
189
- if (!t.isExportSpecifier(s)) continue
190
- if (s.exportKind === 'type') continue
191
- const exportedName = t.isIdentifier(s.exported)
192
- ? s.exported.name
193
- : s.exported.value
194
- add(exportedName)
195
- }
196
- }
197
- }
198
-
199
- return Array.from(names).sort()
200
- }
201
-
202
- /**
203
- * Rewrite static imports/re-exports from denied sources using Babel AST transforms.
204
- *
205
- * Transforms:
206
- * import { a as b, c } from 'denied'
207
- * Into:
208
- * import __tss_deny_0 from 'tanstack-start-import-protection:mock'
209
- * const b = __tss_deny_0.a
210
- * const c = __tss_deny_0.c
211
- *
212
- * Also handles:
213
- * import def from 'denied' -> import def from mock
214
- * import * as ns from 'denied' -> import ns from mock
215
- * export { x } from 'denied' -> export const x = mock.x
216
- * export * from 'denied' -> removed
217
- * export { x as y } from 'denied' -> export const y = mock.x
218
- */
219
- export function rewriteDeniedImports(
220
- code: string,
221
- id: string,
222
- deniedSources: Set<string>,
223
- getMockModuleId: (source: string) => string = () => MOCK_MODULE_ID,
224
- ): { code: string; map?: SourceMapLike } | undefined {
225
- return rewriteDeniedImportsFromAst(
226
- parseImportProtectionAst(code),
227
- id,
228
- deniedSources,
229
- getMockModuleId,
230
- )
231
- }
232
-
233
- function rewriteDeniedImportsFromAst(
234
- ast: ParsedAst,
235
- id: string,
236
- deniedSources: Set<string>,
237
- getMockModuleId: (source: string) => string = () => MOCK_MODULE_ID,
238
- ): { code: string; map?: SourceMapLike } | undefined {
239
- let modified = false
240
- let mockCounter = 0
241
-
242
- // Walk program body in reverse so splice indices stay valid
243
- for (let i = ast.program.body.length - 1; i >= 0; i--) {
244
- const node = ast.program.body[i]!
245
-
246
- if (t.isImportDeclaration(node)) {
247
- if (node.importKind === 'type') continue
248
- if (!deniedSources.has(node.source.value)) continue
249
-
250
- const mockVar = `__tss_deny_${mockCounter++}`
251
- const replacements: Array<t.Statement> = []
252
-
253
- replacements.push(
254
- t.importDeclaration(
255
- [t.importDefaultSpecifier(t.identifier(mockVar))],
256
- t.stringLiteral(getMockModuleId(node.source.value)),
257
- ),
258
- )
259
-
260
- for (const specifier of node.specifiers) {
261
- if (
262
- t.isImportDefaultSpecifier(specifier) ||
263
- t.isImportNamespaceSpecifier(specifier)
264
- ) {
265
- replacements.push(
266
- t.variableDeclaration('const', [
267
- t.variableDeclarator(
268
- t.identifier(specifier.local.name),
269
- t.identifier(mockVar),
270
- ),
271
- ]),
272
- )
273
- } else if (t.isImportSpecifier(specifier)) {
274
- if (specifier.importKind === 'type') continue
275
- const importedName = t.isIdentifier(specifier.imported)
276
- ? specifier.imported.name
277
- : specifier.imported.value
278
- replacements.push(
279
- t.variableDeclaration('const', [
280
- t.variableDeclarator(
281
- t.identifier(specifier.local.name),
282
- t.memberExpression(
283
- t.identifier(mockVar),
284
- t.identifier(importedName),
285
- ),
286
- ),
287
- ]),
288
- )
289
- }
290
- }
291
-
292
- ast.program.body.splice(i, 1, ...replacements)
293
- modified = true
294
- continue
295
- }
296
-
297
- if (t.isExportNamedDeclaration(node) && node.source) {
298
- if (node.exportKind === 'type') continue
299
- if (!deniedSources.has(node.source.value)) continue
300
-
301
- const mockVar = `__tss_deny_${mockCounter++}`
302
- const replacements: Array<t.Statement> = []
303
-
304
- replacements.push(
305
- t.importDeclaration(
306
- [t.importDefaultSpecifier(t.identifier(mockVar))],
307
- t.stringLiteral(getMockModuleId(node.source.value)),
308
- ),
309
- )
310
- const exportSpecifiers: Array<{
311
- localName: string
312
- exportedName: string
313
- }> = []
314
- for (const specifier of node.specifiers) {
315
- if (t.isExportSpecifier(specifier)) {
316
- if (specifier.exportKind === 'type') continue
317
- const localName = specifier.local.name
318
- const exportedName = t.isIdentifier(specifier.exported)
319
- ? specifier.exported.name
320
- : specifier.exported.value
321
-
322
- const internalVar = `__tss_reexport_${localName}`
323
- replacements.push(
324
- t.variableDeclaration('const', [
325
- t.variableDeclarator(
326
- t.identifier(internalVar),
327
- t.memberExpression(
328
- t.identifier(mockVar),
329
- t.identifier(localName),
330
- ),
331
- ),
332
- ]),
333
- )
334
- exportSpecifiers.push({ localName: internalVar, exportedName })
335
- }
336
- }
337
-
338
- if (exportSpecifiers.length > 0) {
339
- replacements.push(
340
- t.exportNamedDeclaration(
341
- null,
342
- exportSpecifiers.map((s) =>
343
- t.exportSpecifier(
344
- t.identifier(s.localName),
345
- t.identifier(s.exportedName),
346
- ),
347
- ),
348
- ),
349
- )
350
- }
351
-
352
- ast.program.body.splice(i, 1, ...replacements)
353
- modified = true
354
- continue
355
- }
356
-
357
- if (t.isExportAllDeclaration(node)) {
358
- if (node.exportKind === 'type') continue
359
- if (!deniedSources.has(node.source.value)) continue
360
-
361
- ast.program.body.splice(i, 1)
362
- modified = true
363
- continue
364
- }
365
- }
366
-
367
- if (!modified) return undefined
368
-
369
- const result = generateFromAst(ast, {
370
- sourceMaps: true,
371
- sourceFileName: id,
372
- filename: id,
373
- })
374
-
375
- return {
376
- code: result.code,
377
- ...(result.map ? { map: result.map as SourceMapLike } : {}),
378
- }
379
- }
@@ -1,31 +0,0 @@
1
- import { SERVER_FN_LOOKUP } from '../constants'
2
- import type { StartCompiler } from './compiler'
3
-
4
- interface ViteCompilerModuleLoaderOptions {
5
- compiler: StartCompiler
6
- mode: string
7
- fetchModule?: (id: string) => Promise<unknown>
8
- loadModule: (opts: { id: string }) => Promise<{ code?: string | null }>
9
- id: string
10
- }
11
-
12
- export async function loadModuleForViteCompiler(
13
- opts: ViteCompilerModuleLoaderOptions,
14
- ): Promise<void> {
15
- if (opts.mode === 'build') {
16
- const loaded = await opts.loadModule({ id: opts.id })
17
- const code = loaded.code ?? ''
18
-
19
- opts.compiler.ingestModule({ code, id: opts.id })
20
-
21
- return
22
- }
23
-
24
- if (opts.mode !== 'dev' || !opts.fetchModule) {
25
- throw new Error(
26
- `could not load module ${opts.id}: unknown environment mode ${opts.mode}`,
27
- )
28
- }
29
-
30
- await opts.fetchModule(`${opts.id}?${SERVER_FN_LOOKUP}`)
31
- }