@trojanbox-vcp-test/site-edit-engine 0.1.0 → 0.2.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 (163) hide show
  1. package/dist/index.d.ts +3 -0
  2. package/dist/index.js +127 -2
  3. package/dist/internal/protocol/operation.d.ts +2 -0
  4. package/dist/internal/protocol/render.d.ts +3 -30
  5. package/dist/internal/protocol.d.ts +1 -1
  6. package/dist/next-app-router.js +1 -140
  7. package/dist/preview-runtime.d.ts +249 -303
  8. package/dist/runtime-sync.d.ts +8 -8
  9. package/dist/runtime.d.ts +1 -127
  10. package/dist/site-edit-instrumentation.d.ts +1 -1
  11. package/dist/source-watcher.js +1 -150
  12. package/dist/types.d.ts +12 -14
  13. package/dist/webpack-loader.cjs +50 -588
  14. package/package.json +2 -2
  15. package/dist/execute-integration/execute-fixture-harness.d.ts +0 -25
  16. package/dist/execute-integration/execute-fixture-harness.js +0 -37
  17. package/dist/internal/ast/diagnostics/index.d.ts +0 -5
  18. package/dist/internal/ast/diagnostics/index.js +0 -25
  19. package/dist/internal/ast/history/index.d.ts +0 -15
  20. package/dist/internal/ast/history/index.js +0 -62
  21. package/dist/internal/ast/index.d.ts +0 -8
  22. package/dist/internal/ast/index.js +0 -5
  23. package/dist/internal/ast/locators/index.d.ts +0 -1
  24. package/dist/internal/ast/locators/index.js +0 -1
  25. package/dist/internal/ast/locators/resolve-locator.d.ts +0 -16
  26. package/dist/internal/ast/locators/resolve-locator.js +0 -920
  27. package/dist/internal/ast/parser/SourceParser.d.ts +0 -30
  28. package/dist/internal/ast/parser/SourceParser.js +0 -49
  29. package/dist/internal/ast/parser/index.d.ts +0 -21
  30. package/dist/internal/ast/parser/index.js +0 -64
  31. package/dist/internal/ast/primitives/conditional/conditional-primitives.d.ts +0 -18
  32. package/dist/internal/ast/primitives/conditional/conditional-primitives.js +0 -237
  33. package/dist/internal/ast/primitives/conditional/index.d.ts +0 -1
  34. package/dist/internal/ast/primitives/conditional/index.js +0 -1
  35. package/dist/internal/ast/primitives/imports/add-import.d.ts +0 -18
  36. package/dist/internal/ast/primitives/imports/add-import.js +0 -111
  37. package/dist/internal/ast/primitives/imports/index.d.ts +0 -2
  38. package/dist/internal/ast/primitives/imports/index.js +0 -2
  39. package/dist/internal/ast/primitives/imports/remove-import.d.ts +0 -15
  40. package/dist/internal/ast/primitives/imports/remove-import.js +0 -72
  41. package/dist/internal/ast/primitives/index.d.ts +0 -10
  42. package/dist/internal/ast/primitives/index.js +0 -10
  43. package/dist/internal/ast/primitives/jsx/index.d.ts +0 -4
  44. package/dist/internal/ast/primitives/jsx/index.js +0 -4
  45. package/dist/internal/ast/primitives/jsx/insert-child.d.ts +0 -11
  46. package/dist/internal/ast/primitives/jsx/insert-child.js +0 -69
  47. package/dist/internal/ast/primitives/jsx/move-node.d.ts +0 -9
  48. package/dist/internal/ast/primitives/jsx/move-node.js +0 -76
  49. package/dist/internal/ast/primitives/jsx/remove-node.d.ts +0 -7
  50. package/dist/internal/ast/primitives/jsx/remove-node.js +0 -36
  51. package/dist/internal/ast/primitives/jsx/update-text.d.ts +0 -8
  52. package/dist/internal/ast/primitives/jsx/update-text.js +0 -81
  53. package/dist/internal/ast/primitives/next/index.d.ts +0 -1
  54. package/dist/internal/ast/primitives/next/index.js +0 -1
  55. package/dist/internal/ast/primitives/next/next-primitives.d.ts +0 -43
  56. package/dist/internal/ast/primitives/next/next-primitives.js +0 -211
  57. package/dist/internal/ast/primitives/shared.d.ts +0 -60
  58. package/dist/internal/ast/primitives/shared.js +0 -176
  59. package/dist/internal/ast/primitives/style/class-expression.d.ts +0 -23
  60. package/dist/internal/ast/primitives/style/class-expression.js +0 -174
  61. package/dist/internal/ast/primitives/style/index.d.ts +0 -1
  62. package/dist/internal/ast/primitives/style/index.js +0 -1
  63. package/dist/internal/ast/primitives/style/style-primitives.d.ts +0 -49
  64. package/dist/internal/ast/primitives/style/style-primitives.js +0 -555
  65. package/dist/internal/ast/primitives/values/index.d.ts +0 -1
  66. package/dist/internal/ast/primitives/values/index.js +0 -1
  67. package/dist/internal/ast/primitives/values/value-primitives.d.ts +0 -42
  68. package/dist/internal/ast/primitives/values/value-primitives.js +0 -158
  69. package/dist/internal/ast/printer/SourcePrinter.d.ts +0 -21
  70. package/dist/internal/ast/printer/SourcePrinter.js +0 -76
  71. package/dist/internal/ast/printer/index.d.ts +0 -6
  72. package/dist/internal/ast/printer/index.js +0 -126
  73. package/dist/internal/ast/types.d.ts +0 -190
  74. package/dist/internal/ast/types.js +0 -1
  75. package/dist/internal/capability/capability-resolver.d.ts +0 -16
  76. package/dist/internal/capability/capability-resolver.js +0 -127
  77. package/dist/internal/classname-source.d.ts +0 -24
  78. package/dist/internal/classname-source.js +0 -220
  79. package/dist/internal/contracts/IEditEngineRuntime.d.ts +0 -18
  80. package/dist/internal/contracts/IEditEngineRuntime.js +0 -1
  81. package/dist/internal/domain/EditDiagnostic.d.ts +0 -38
  82. package/dist/internal/domain/EditDiagnostic.js +0 -43
  83. package/dist/internal/events/event-bus.d.ts +0 -14
  84. package/dist/internal/events/event-bus.js +0 -21
  85. package/dist/internal/graph/graph-builder.d.ts +0 -12
  86. package/dist/internal/graph/graph-builder.js +0 -1371
  87. package/dist/internal/graph/import-resolver.d.ts +0 -31
  88. package/dist/internal/graph/import-resolver.js +0 -109
  89. package/dist/internal/graph/project-graph-builder.d.ts +0 -32
  90. package/dist/internal/graph/project-graph-builder.js +0 -133
  91. package/dist/internal/graph/types.d.ts +0 -114
  92. package/dist/internal/graph/types.js +0 -6
  93. package/dist/internal/history/undo-redo.d.ts +0 -28
  94. package/dist/internal/history/undo-redo.js +0 -42
  95. package/dist/internal/index.d.ts +0 -2
  96. package/dist/internal/index.js +0 -1
  97. package/dist/internal/planner/planner.d.ts +0 -104
  98. package/dist/internal/planner/planner.js +0 -2533
  99. package/dist/internal/planner/types.d.ts +0 -275
  100. package/dist/internal/planner/types.js +0 -6
  101. package/dist/internal/protocol/boundary.js +0 -3
  102. package/dist/internal/protocol/capability.js +0 -8
  103. package/dist/internal/protocol/error.js +0 -38
  104. package/dist/internal/protocol/event.js +0 -3
  105. package/dist/internal/protocol/identity.js +0 -30
  106. package/dist/internal/protocol/operation.js +0 -8
  107. package/dist/internal/protocol/render.js +0 -3
  108. package/dist/internal/protocol.js +0 -2
  109. package/dist/internal/provenance/binding-graph.d.ts +0 -39
  110. package/dist/internal/provenance/binding-graph.js +0 -184
  111. package/dist/internal/provenance/capability-policy.d.ts +0 -15
  112. package/dist/internal/provenance/capability-policy.js +0 -96
  113. package/dist/internal/provenance/data-source-classifier.d.ts +0 -14
  114. package/dist/internal/provenance/data-source-classifier.js +0 -281
  115. package/dist/internal/provenance/resolve-text-provenance.d.ts +0 -45
  116. package/dist/internal/provenance/resolve-text-provenance.js +0 -3090
  117. package/dist/internal/provenance/types.d.ts +0 -89
  118. package/dist/internal/provenance/types.js +0 -1
  119. package/dist/internal/render/component-semantic.d.ts +0 -11
  120. package/dist/internal/render/component-semantic.js +0 -141
  121. package/dist/internal/render/content-model.d.ts +0 -3
  122. package/dist/internal/render/content-model.js +0 -89
  123. package/dist/internal/render/media-model.d.ts +0 -3
  124. package/dist/internal/render/media-model.js +0 -45
  125. package/dist/internal/render/provenance-types.d.ts +0 -33
  126. package/dist/internal/render/provenance-types.js +0 -1
  127. package/dist/internal/render/render-projection.d.ts +0 -24
  128. package/dist/internal/render/render-projection.js +0 -281
  129. package/dist/internal/render/tailwind-style-model.d.ts +0 -19
  130. package/dist/internal/render/tailwind-style-model.js +0 -1187
  131. package/dist/internal/runtime/EditEngineRuntime.d.ts +0 -25
  132. package/dist/internal/runtime/EditEngineRuntime.js +0 -89
  133. package/dist/internal/runtime/EditEngineRuntimeSnapshot.d.ts +0 -31
  134. package/dist/internal/runtime/EditEngineRuntimeSnapshot.js +0 -15
  135. package/dist/internal/runtime/InternalEditEngine.d.ts +0 -44
  136. package/dist/internal/runtime/InternalEditEngine.js +0 -1391
  137. package/dist/internal/runtime.d.ts +0 -3
  138. package/dist/internal/runtime.js +0 -1
  139. package/dist/internal/topology/topology.d.ts +0 -6
  140. package/dist/internal/topology/topology.js +0 -98
  141. package/dist/internal/topology/types.d.ts +0 -35
  142. package/dist/internal/topology/types.js +0 -5
  143. package/dist/internal/types.d.ts +0 -1
  144. package/dist/internal/types.js +0 -1
  145. package/dist/internal/writeback/in-memory-fs.d.ts +0 -7
  146. package/dist/internal/writeback/in-memory-fs.js +0 -44
  147. package/dist/internal/writeback/types.d.ts +0 -45
  148. package/dist/internal/writeback/types.js +0 -7
  149. package/dist/internal/writeback/writeback-service.d.ts +0 -7
  150. package/dist/internal/writeback/writeback-service.js +0 -568
  151. package/dist/internal-adapter.d.ts +0 -18
  152. package/dist/internal-adapter.js +0 -350
  153. package/dist/next-app-router-fs.js +0 -64
  154. package/dist/preview-runtime.js +0 -102
  155. package/dist/public-file-system.js +0 -1
  156. package/dist/runtime-sync.js +0 -321
  157. package/dist/runtime.js +0 -134
  158. package/dist/site-edit-instrumentation.js +0 -322
  159. package/dist/snapshot-file-system.d.ts +0 -19
  160. package/dist/snapshot-file-system.js +0 -49
  161. package/dist/source-writeback-test-harness.d.ts +0 -244
  162. package/dist/source-writeback-test-harness.js +0 -119
  163. package/dist/types.js +0 -1
@@ -1,920 +0,0 @@
1
- import _traverse from "@babel/traverse";
2
- import { createDiagnostic, locatorFailure } from "../diagnostics/index.js";
3
- import { parseForLocator } from "../parser/index.js";
4
- /* node:coverage ignore next */
5
- const traverse = (typeof _traverse === "function" ? _traverse : _traverse.default);
6
- const siblingOrdinalCache = new WeakMap();
7
- const structuralChildrenCache = new WeakMap();
8
- export function resolveLocator(source, locator) {
9
- const parsed = parseForLocator(source, locator);
10
- if (!parsed.ok) {
11
- return locatorFailure(source, parsed.diagnostic.code, parsed.diagnostic.message, locator.kind);
12
- }
13
- const result = resolveLocatorPath(parsed.ast, locator);
14
- if (!result.ok) {
15
- return locatorFailure(source, result.diagnostic.code, result.diagnostic.message, locator.kind, result.diagnostic.details);
16
- }
17
- return {
18
- ok: true,
19
- match: {
20
- locatorKind: result.match.locatorKind,
21
- node: result.match.node,
22
- start: result.match.start,
23
- end: result.match.end,
24
- },
25
- };
26
- }
27
- export function resolveLocatorPath(ast, locator) {
28
- if (locator.kind === "jsx-node") {
29
- return resolveJsxNodeLocator(ast, locator);
30
- }
31
- if (locator.kind === "jsx-attribute") {
32
- return resolveJsxAttributeLocator(ast, locator);
33
- }
34
- if (locator.kind === "value") {
35
- return resolveValueLocator(ast, locator);
36
- }
37
- if (locator.kind === "expression") {
38
- return resolveExpressionLocator(ast, locator);
39
- }
40
- if (locator.kind === "directive") {
41
- return resolveDirectiveLocator(ast, locator);
42
- }
43
- if (locator.kind === "export") {
44
- return resolveExportLocator(ast, locator);
45
- }
46
- return {
47
- ok: false,
48
- diagnostic: createDiagnostic("unsupported-syntax", `Unsupported locator kind: ${locator.kind}`),
49
- };
50
- }
51
- function resolveJsxNodeLocator(ast, locator) {
52
- return locator.strategy === "source-range"
53
- ? resolveJsxNodeBySourceRange(ast, locator)
54
- : resolveJsxNodeByStructuralPath(ast, locator);
55
- }
56
- function resolveJsxNodeBySourceRange(ast, locator) {
57
- let best = null;
58
- traverse(ast, {
59
- JSXElement(path) {
60
- if (!hasExactRange(path.node, locator.sourceRange)) {
61
- return;
62
- }
63
- const candidate = toInternalMatch("jsx-node", path);
64
- if (!candidate) {
65
- return;
66
- }
67
- if (!best) {
68
- best = candidate;
69
- return;
70
- }
71
- if (candidate.end - candidate.start < best.end - best.start) {
72
- best = candidate;
73
- }
74
- },
75
- });
76
- if (!best)
77
- return failLocator("jsx-node", "locator-miss", "JSX node not found for source-range locator");
78
- const bestMatch = best;
79
- if (locator.expectedIdentity &&
80
- !matchesExpectedJsxIdentity(bestMatch.path, locator.expectedIdentity)) {
81
- return failLocator("jsx-node", "locator-miss", "JSX node failed expected identity validation");
82
- }
83
- return { ok: true, match: bestMatch };
84
- }
85
- function resolveJsxNodeByStructuralPath(ast, locator) {
86
- // 检测 fragment root 作为编辑目标 — 返回明确 unsupported-syntax
87
- if (locator.structuralPath === "") {
88
- const componentFuncPath = findComponentFunctionPath(ast, locator.component);
89
- if (componentFuncPath) {
90
- const fragmentResult = checkComponentFragmentRoot(componentFuncPath);
91
- if (fragmentResult) {
92
- return fragmentResult;
93
- }
94
- }
95
- }
96
- let match = null;
97
- traverse(ast, {
98
- JSXElement(path) {
99
- const candidateComponent = getEnclosingComponentName(path);
100
- if (candidateComponent !== locator.component) {
101
- return;
102
- }
103
- if (computeJsxStructuralPath(path) !== locator.structuralPath) {
104
- return;
105
- }
106
- const candidate = toInternalMatch("jsx-node", path);
107
- if (!candidate) {
108
- return;
109
- }
110
- if (locator.expectedRange &&
111
- !matchesRange(path.node.loc, locator.expectedRange)) {
112
- return;
113
- }
114
- /* node:coverage ignore start */
115
- match = candidate;
116
- path.stop();
117
- /* node:coverage ignore stop */
118
- },
119
- JSXFragment(path) {
120
- const candidateComponent = getEnclosingComponentName(path);
121
- if (candidateComponent !== locator.component) {
122
- return;
123
- }
124
- if (computeJsxStructuralPath(path) !==
125
- locator.structuralPath) {
126
- return;
127
- }
128
- const candidate = toInternalMatch("jsx-node", path);
129
- if (!candidate) {
130
- return;
131
- }
132
- if (locator.expectedRange &&
133
- !matchesRange(path.node.loc, locator.expectedRange)) {
134
- return;
135
- }
136
- /* node:coverage ignore start */
137
- match = candidate;
138
- path.stop();
139
- /* node:coverage ignore stop */
140
- },
141
- });
142
- if (!match) {
143
- return failLocator("jsx-node", "locator-miss", "JSX node not found for structural-path locator");
144
- }
145
- return { ok: true, match };
146
- }
147
- /**
148
- * 查找组件对应的函数节点路径
149
- * 支持 FunctionDeclaration、ArrowFunctionExpression、FunctionExpression
150
- */
151
- function findComponentFunctionPath(ast, componentName) {
152
- let result = null;
153
- traverse(ast, {
154
- FunctionDeclaration(path) {
155
- if (path.node.id?.name === componentName) {
156
- result = path;
157
- path.stop();
158
- }
159
- },
160
- VariableDeclarator(path) {
161
- if (path.node.id.type === "Identifier" &&
162
- path.node.id.name === componentName) {
163
- const init = path.get("init");
164
- if (init.isArrowFunctionExpression() || init.isFunctionExpression()) {
165
- result = init;
166
- }
167
- path.stop();
168
- }
169
- },
170
- });
171
- return result;
172
- }
173
- /**
174
- * 检查组件函数是否返回 JSXFragment 作为根节点
175
- * 返回 unsupported-syntax diagnostic 或 null
176
- */
177
- function checkComponentFragmentRoot(funcPath) {
178
- if (funcPath.isArrowFunctionExpression()) {
179
- const body = funcPath.get("body");
180
- // 块体箭头函数:检查 return 语句
181
- if (body.isBlockStatement()) {
182
- const returnStmt = body
183
- .get("body")
184
- .find((stmt) => stmt.isReturnStatement());
185
- if (returnStmt) {
186
- const argument = returnStmt.get("argument");
187
- const target = argument.isParenthesizedExpression()
188
- ? argument.get("expression")
189
- : argument;
190
- if (target.isJSXFragment()) {
191
- return failLocator("jsx-node", "unsupported-syntax", "JSXFragment is not a supported edit target");
192
- }
193
- }
194
- return null;
195
- }
196
- // 简洁体箭头函数:直接检查 body
197
- const target = body.isParenthesizedExpression()
198
- ? body.get("expression")
199
- : body;
200
- if (target.isJSXFragment()) {
201
- return failLocator("jsx-node", "unsupported-syntax", "JSXFragment is not a supported edit target");
202
- }
203
- return null;
204
- }
205
- if (funcPath.isFunctionDeclaration() || funcPath.isFunctionExpression()) {
206
- const body = funcPath.get("body");
207
- if (body.isBlockStatement()) {
208
- const returnStmt = body
209
- .get("body")
210
- .find((stmt) => stmt.isReturnStatement());
211
- if (returnStmt) {
212
- const argument = returnStmt.get("argument");
213
- // 处理 return ( <></> ) 的 ParenthesizedExpression 包裹
214
- const target = argument.isParenthesizedExpression()
215
- ? argument.get("expression")
216
- : argument;
217
- if (target.isJSXFragment()) {
218
- return failLocator("jsx-node", "unsupported-syntax", "JSXFragment is not a supported edit target");
219
- }
220
- }
221
- }
222
- }
223
- return null;
224
- }
225
- function resolveJsxAttributeLocator(ast, locator) {
226
- const elementMatch = resolveJsxNodeLocator(ast, locator.element);
227
- if (!elementMatch.ok) {
228
- return elementMatch;
229
- }
230
- const elementPath = elementMatch.match.path;
231
- const openingElement = elementPath.get("openingElement");
232
- const attributes = openingElement.get("attributes");
233
- const attributePath = attributes.find((attribute) => isNamedJsxAttributePath(attribute, locator.name));
234
- if (!attributePath || !attributePath.isJSXAttribute()) {
235
- return failLocator("jsx-attribute", "locator-miss", `JSX attribute '${locator.name}' not found`);
236
- }
237
- const match = toInternalMatch("jsx-attribute", attributePath);
238
- if (!match) {
239
- return failLocator("jsx-attribute", "locator-miss", `JSX attribute '${locator.name}' has no source range`);
240
- }
241
- return { ok: true, match };
242
- }
243
- function resolveValueLocator(ast, locator) {
244
- const rootPath = resolveValueRootPath(ast, locator);
245
- if (!rootPath.ok) {
246
- return rootPath;
247
- }
248
- const resolvedPath = followValuePath(rootPath.match.path, locator.path ?? []);
249
- if (!resolvedPath.ok) {
250
- return resolvedPath;
251
- }
252
- if (locator.expectedRange &&
253
- !matchesRange(resolvedPath.match.path.node.loc, locator.expectedRange)) {
254
- return failLocator("value", "locator-miss", "Resolved value does not match expected range");
255
- }
256
- return { ok: true, match: resolvedPath.match };
257
- }
258
- function resolveExpressionLocator(ast, locator) {
259
- let match = null;
260
- traverse(ast, {
261
- Identifier(path) {
262
- if (!isExpressionPath(path)) {
263
- return;
264
- }
265
- const normalized = normalizeExpressionPath(path);
266
- if (!normalized) {
267
- return;
268
- }
269
- if (!matchesExpressionLocator(normalized, locator)) {
270
- return;
271
- }
272
- const candidate = toInternalMatch("expression", path);
273
- if (!candidate) {
274
- return;
275
- }
276
- if (locator.expectedRange &&
277
- !matchesRange(path.node.loc, locator.expectedRange)) {
278
- return;
279
- }
280
- match = candidate;
281
- path.stop();
282
- },
283
- MemberExpression(path) {
284
- const normalized = normalizeExpressionPath(path);
285
- if (!normalized) {
286
- return;
287
- }
288
- if (!matchesExpressionLocator(normalized, locator)) {
289
- return;
290
- }
291
- const candidate = toInternalMatch("expression", path);
292
- if (!candidate) {
293
- return;
294
- }
295
- if (locator.expectedRange &&
296
- !matchesRange(path.node.loc, locator.expectedRange)) {
297
- return;
298
- }
299
- match = candidate;
300
- path.stop();
301
- },
302
- });
303
- if (!match) {
304
- return failLocator("expression", "locator-miss", "Expression not found");
305
- }
306
- return { ok: true, match };
307
- }
308
- function resolveDirectiveLocator(ast, locator) {
309
- let match = null;
310
- traverse(ast, {
311
- Program(path) {
312
- const directives = path.get("directives");
313
- const directivePath = directives.find((directive) => directive.node.value.value === locator.value);
314
- if (!directivePath) {
315
- return;
316
- }
317
- if (locator.expectedRange &&
318
- !matchesRange(directivePath.node.loc, locator.expectedRange)) {
319
- return;
320
- }
321
- const candidate = toInternalMatch("directive", directivePath);
322
- if (!candidate) {
323
- return;
324
- }
325
- match = candidate;
326
- path.stop();
327
- },
328
- });
329
- if (!match) {
330
- return failLocator("directive", "locator-miss", `Directive '${locator.value}' not found`);
331
- }
332
- return { ok: true, match };
333
- }
334
- function resolveExportLocator(ast, locator) {
335
- let match = null;
336
- traverse(ast, {
337
- ExportNamedDeclaration(path) {
338
- if (locator.exportKind === "generate-metadata") {
339
- const declaration = path.get("declaration");
340
- if (declaration.isFunctionDeclaration() &&
341
- declaration.node.id?.name === "generateMetadata") {
342
- const candidate = toInternalMatch("export", declaration);
343
- if (!candidate) {
344
- return;
345
- }
346
- if (locator.expectedRange &&
347
- !matchesRange(declaration.node.loc, locator.expectedRange)) {
348
- return;
349
- }
350
- match = candidate;
351
- path.stop();
352
- return;
353
- }
354
- if (!declaration.isVariableDeclaration()) {
355
- return;
356
- }
357
- const declarator = findNamedVariableDeclarator(declaration, "generateMetadata");
358
- if (!declarator || !declarator.isVariableDeclarator()) {
359
- return;
360
- }
361
- const initPath = declarator.get("init");
362
- if (!initPath.node) {
363
- return;
364
- }
365
- const candidate = toInternalMatch("export", initPath);
366
- if (!candidate) {
367
- return;
368
- }
369
- if (locator.expectedRange &&
370
- !matchesRange(initPath.node.loc, locator.expectedRange)) {
371
- return;
372
- }
373
- match = candidate;
374
- path.stop();
375
- return;
376
- }
377
- const declaration = path.get("declaration");
378
- if (!declaration.isVariableDeclaration()) {
379
- return;
380
- }
381
- const declarator = findNamedVariableDeclarator(declaration, locator.exportKind === "named" ? locator.name : "metadata");
382
- if (!declarator || !declarator.isVariableDeclarator()) {
383
- return;
384
- }
385
- const initPath = declarator.get("init");
386
- if (!initPath.node) {
387
- return;
388
- }
389
- if (locator.expectedRange &&
390
- !matchesRange(initPath.node.loc, locator.expectedRange)) {
391
- return;
392
- }
393
- const candidate = toInternalMatch("export", initPath);
394
- if (!candidate) {
395
- return;
396
- }
397
- match = candidate;
398
- path.stop();
399
- },
400
- ExportDefaultDeclaration(path) {
401
- if (locator.exportKind !== "default") {
402
- return;
403
- }
404
- const declaration = path.get("declaration");
405
- const candidate = toInternalMatch("export", declaration);
406
- if (!candidate) {
407
- return;
408
- }
409
- if (locator.expectedRange &&
410
- !matchesRange(declaration.node.loc, locator.expectedRange)) {
411
- return;
412
- }
413
- match = candidate;
414
- path.stop();
415
- },
416
- });
417
- if (!match) {
418
- return failLocator("export", "export-not-found", `Export '${describeExport(locator)}' not found`);
419
- }
420
- return { ok: true, match };
421
- }
422
- function resolveValueRootPath(ast, locator) {
423
- let match = null;
424
- traverse(ast, {
425
- Expression(path) {
426
- if (match || locator.root.kind !== "expression") {
427
- return;
428
- }
429
- if (!hasExactRange(path.node, locator.root.sourceRange)) {
430
- return;
431
- }
432
- const candidate = toInternalMatch("value", path);
433
- if (!candidate) {
434
- return;
435
- }
436
- match = candidate;
437
- path.stop();
438
- },
439
- VariableDeclarator(path) {
440
- if (match) {
441
- return;
442
- }
443
- if (locator.root.kind === "binding") {
444
- if (path.node.id.type !== "Identifier" ||
445
- path.node.id.name !== locator.root.name) {
446
- return;
447
- }
448
- const initPath = path.get("init");
449
- if (!initPath.node) {
450
- return;
451
- }
452
- const candidate = toInternalMatch("value", initPath);
453
- if (!candidate) {
454
- return;
455
- }
456
- match = candidate;
457
- path.stop();
458
- return;
459
- }
460
- if (locator.root.kind !== "hook-state") {
461
- return;
462
- }
463
- const hookStateRoot = locator.root;
464
- const idPath = path.get("id");
465
- const initPath = path.get("init");
466
- if (!idPath.isArrayPattern() || !initPath.isCallExpression()) {
467
- return;
468
- }
469
- const stateIndex = idPath.node.elements.findIndex((element) => element?.type === "Identifier" && element.name === hookStateRoot.name);
470
- if (stateIndex !== 0) {
471
- return;
472
- }
473
- const callee = initPath.node.callee;
474
- const hookName = callee.type === "Identifier"
475
- ? callee.name
476
- : callee.type === "MemberExpression" &&
477
- callee.property.type === "Identifier"
478
- ? callee.property.name
479
- : null;
480
- if (hookName !== hookStateRoot.hook) {
481
- return;
482
- }
483
- const argIndex = hookStateRoot.hook === "useReducer" ? 1 : 0;
484
- const argPath = path.get(`init.arguments.${argIndex}`);
485
- if (!argPath || Array.isArray(argPath) || !argPath.node) {
486
- return;
487
- }
488
- const candidate = toInternalMatch("value", argPath);
489
- if (!candidate) {
490
- return;
491
- }
492
- match = candidate;
493
- path.stop();
494
- },
495
- ExportNamedDeclaration(path) {
496
- if (match || locator.root.kind !== "named-export") {
497
- return;
498
- }
499
- const declaration = path.get("declaration");
500
- if (!declaration.isVariableDeclaration()) {
501
- return;
502
- }
503
- const declarator = findNamedVariableDeclarator(declaration, locator.root.name);
504
- if (!declarator || !declarator.isVariableDeclarator()) {
505
- return;
506
- }
507
- const initPath = declarator.get("init");
508
- if (!initPath.node) {
509
- return;
510
- }
511
- const candidate = toInternalMatch("value", initPath);
512
- if (!candidate) {
513
- return;
514
- }
515
- match = candidate;
516
- path.stop();
517
- },
518
- ExportDefaultDeclaration(path) {
519
- if (match || locator.root.kind !== "default-export") {
520
- return;
521
- }
522
- const declaration = path.get("declaration");
523
- const candidate = toInternalMatch("value", declaration);
524
- if (!candidate) {
525
- return;
526
- }
527
- match = candidate;
528
- path.stop();
529
- },
530
- });
531
- if (!match)
532
- return failLocator("value", locator.root.kind === "named-export" ||
533
- locator.root.kind === "default-export"
534
- ? "export-not-found"
535
- : locator.root.kind === "expression"
536
- ? "locator-miss"
537
- : "binding-not-found", "Value root was not found");
538
- return { ok: true, match };
539
- }
540
- function followValuePath(path, segments) {
541
- let current = unwrapValueAssertion(path);
542
- for (const segment of segments) {
543
- current = unwrapValueAssertion(current);
544
- if (segment.kind === "property") {
545
- if (!current.isObjectExpression()) {
546
- return failLocator("value", "unsupported-syntax", "Property path requires object expression");
547
- }
548
- const properties = current.get("properties");
549
- if (properties.some((property) => !property.isObjectProperty())) {
550
- return failLocator("value", "unsupported-syntax", "Spread properties are not supported");
551
- }
552
- const propertyPath = properties.find((property) => matchesObjectPropertyName(property, segment.name));
553
- if (!propertyPath || !propertyPath.isObjectProperty()) {
554
- return failLocator("value", "property-not-found", `Property '${segment.name}' not found`);
555
- }
556
- current = propertyPath.get("value");
557
- continue;
558
- }
559
- if (!current.isArrayExpression()) {
560
- return failLocator("value", "unsupported-syntax", "Array index path requires array expression");
561
- }
562
- const elements = current.get("elements");
563
- if (elements.some((element) => element.node?.type === "SpreadElement")) {
564
- return failLocator("value", "unsupported-syntax", "Spread array elements are not supported");
565
- }
566
- const elementPath = elements[segment.index];
567
- if (!elementPath?.node) {
568
- return failLocator("value", "array-index-out-of-range", `Array index ${segment.index} is out of range`);
569
- }
570
- current = elementPath;
571
- }
572
- current = unwrapValueAssertion(current);
573
- /* node:coverage ignore start */
574
- const match = toInternalMatch("value", current);
575
- if (!match) {
576
- return failLocator("value", "locator-miss", "Resolved value has no source range");
577
- }
578
- return { ok: true, match };
579
- /* node:coverage ignore stop */
580
- }
581
- function unwrapValueAssertion(path) {
582
- let current = path;
583
- while (current.isTSAsExpression() ||
584
- current.isTSSatisfiesExpression() ||
585
- current.isTSNonNullExpression()) {
586
- current = current.get("expression");
587
- }
588
- return current;
589
- }
590
- function toInternalMatch(locatorKind, path) {
591
- const node = path.node;
592
- if (node.start == null || node.end == null) {
593
- return null;
594
- }
595
- return {
596
- locatorKind,
597
- node,
598
- start: node.start,
599
- end: node.end,
600
- path,
601
- };
602
- }
603
- function hasExactRange(node, sourceRange) {
604
- return matchesRange(node.loc, sourceRange);
605
- }
606
- function matchesRange(loc, range) {
607
- if (!loc) {
608
- return false;
609
- }
610
- return (loc.start.line === range.startLine &&
611
- loc.start.column === range.startColumn &&
612
- loc.end.line === range.endLine &&
613
- loc.end.column === range.endColumn);
614
- }
615
- function computeJsxStructuralPath(path) {
616
- const segments = [];
617
- let current = path;
618
- const targetNode = path.node;
619
- while (current) {
620
- if (current.isJSXElement()) {
621
- const tagName = getJsxTagName(current.node.openingElement);
622
- if (tagName) {
623
- if (/^[A-Z]/.test(tagName)) {
624
- segments.unshift(`component:${tagName}#${computeSiblingOrdinal(current, tagName)}`);
625
- }
626
- else {
627
- segments.unshift(`${tagName}#${computeSiblingOrdinal(current, tagName)}`);
628
- }
629
- }
630
- }
631
- else if (current.isJSXFragment() && current.node === targetNode) {
632
- segments.unshift("fragment");
633
- }
634
- if (!current.parentPath || isComponentBoundary(current.parentPath))
635
- break;
636
- current = current.parentPath;
637
- }
638
- return segments.join("/");
639
- }
640
- function computeSiblingOrdinal(path, tagName) {
641
- const owner = findStructuralParent(path);
642
- if (!owner) {
643
- return 0;
644
- }
645
- const cached = siblingOrdinalCache
646
- .get(owner.node)
647
- ?.get(tagName)
648
- ?.get(path.node);
649
- if (cached !== undefined) {
650
- return cached;
651
- }
652
- let ordinal = 0;
653
- let tagOrdinals = siblingOrdinalCache.get(owner.node)?.get(tagName);
654
- if (!tagOrdinals) {
655
- let containerCache = siblingOrdinalCache.get(owner.node);
656
- if (!containerCache) {
657
- containerCache = new Map();
658
- siblingOrdinalCache.set(owner.node, containerCache);
659
- }
660
- tagOrdinals = new WeakMap();
661
- containerCache.set(tagName, tagOrdinals);
662
- }
663
- for (const sibling of collectStructuralChildren(owner)) {
664
- if (getJsxTagName(sibling.node.openingElement) === tagName) {
665
- tagOrdinals.set(sibling.node, ordinal);
666
- if (sibling.node === path.node) {
667
- return ordinal;
668
- }
669
- ordinal++;
670
- }
671
- }
672
- return tagOrdinals.get(path.node) ?? 0;
673
- }
674
- function findStructuralParent(path) {
675
- let current = path.parentPath;
676
- let fragmentOwner = null;
677
- while (current) {
678
- if (current.isJSXFragment()) {
679
- fragmentOwner = current;
680
- current = current.parentPath;
681
- continue;
682
- }
683
- if (current.isJSXElement()) {
684
- return current;
685
- }
686
- current = current.parentPath;
687
- }
688
- return fragmentOwner;
689
- }
690
- function collectStructuralChildren(owner) {
691
- const cached = structuralChildrenCache.get(owner.node);
692
- if (cached) {
693
- return cached;
694
- }
695
- const structuralChildren = [];
696
- const children = owner.get("children");
697
- for (const child of children) {
698
- if (Array.isArray(child)) {
699
- continue;
700
- }
701
- if (child.isJSXElement()) {
702
- structuralChildren.push(child);
703
- continue;
704
- }
705
- if (child.isJSXFragment()) {
706
- structuralChildren.push(...collectStructuralChildren(child));
707
- continue;
708
- }
709
- if (child.isJSXExpressionContainer()) {
710
- structuralChildren.push(...collectExpressionStructuralChildren(child.get("expression")));
711
- }
712
- }
713
- structuralChildrenCache.set(owner.node, structuralChildren);
714
- return structuralChildren;
715
- }
716
- function collectExpressionStructuralChildren(expression) {
717
- if (expression.isJSXElement()) {
718
- return [expression];
719
- }
720
- if (expression.isJSXFragment()) {
721
- return collectStructuralChildren(expression);
722
- }
723
- if (expression.isParenthesizedExpression()) {
724
- return collectExpressionStructuralChildren(expression.get("expression"));
725
- }
726
- if (expression.isLogicalExpression() && expression.node.operator === "&&") {
727
- return collectExpressionStructuralChildren(expression.get("right"));
728
- }
729
- if (expression.isConditionalExpression()) {
730
- return [
731
- ...collectExpressionStructuralChildren(expression.get("consequent")),
732
- ...collectExpressionStructuralChildren(expression.get("alternate")),
733
- ];
734
- }
735
- if (expression.isArrayExpression()) {
736
- return expression.get("elements").flatMap((element) => {
737
- if (Array.isArray(element) || !element.node || !element.isExpression()) {
738
- return [];
739
- }
740
- return collectExpressionStructuralChildren(element);
741
- });
742
- }
743
- return [];
744
- }
745
- function getJsxTagName(openingElement) {
746
- if (openingElement.name.type === "JSXIdentifier") {
747
- return openingElement.name.name;
748
- }
749
- if (openingElement.name.type === "JSXMemberExpression") {
750
- return flattenJsxMemberExpression(openingElement.name);
751
- }
752
- return null;
753
- }
754
- function flattenJsxMemberExpression(expression) {
755
- const parts = [];
756
- let current = expression;
757
- while (current.type === "JSXMemberExpression") {
758
- parts.unshift(current.property.name);
759
- current = current.object;
760
- }
761
- parts.unshift(current.name);
762
- return parts.join(".");
763
- }
764
- function getEnclosingComponentName(path) {
765
- let current = path;
766
- while (current) {
767
- if (current.isFunctionDeclaration()) {
768
- return current.node.id?.name ?? null;
769
- }
770
- if ((current.isArrowFunctionExpression() || current.isFunctionExpression()) &&
771
- current.parentPath?.isVariableDeclarator()) {
772
- const id = current.parentPath.node.id;
773
- return id.type === "Identifier" ? id.name : null;
774
- }
775
- current = current.parentPath;
776
- }
777
- return null;
778
- }
779
- function isComponentBoundary(path) {
780
- if (path.isFunctionDeclaration() ||
781
- path.isFunctionExpression() ||
782
- path.isArrowFunctionExpression()) {
783
- return true;
784
- }
785
- return false;
786
- }
787
- function isExpressionPath(path) {
788
- if (!path.isExpression()) {
789
- return false;
790
- }
791
- if (path.parentPath?.isMemberExpression({ property: path.node })) {
792
- return false;
793
- }
794
- return true;
795
- }
796
- function normalizeExpressionPath(path) {
797
- if (path.isIdentifier()) {
798
- return {
799
- base: path.node.name,
800
- path: [],
801
- };
802
- }
803
- if (!path.isMemberExpression()) {
804
- return null;
805
- }
806
- const segments = [];
807
- let current = path.node;
808
- while (current.type === "MemberExpression") {
809
- if (current.computed) {
810
- if (current.property.type === "NumericLiteral") {
811
- segments.unshift({ kind: "index", index: current.property.value });
812
- }
813
- else if (current.property.type === "StringLiteral") {
814
- segments.unshift({ kind: "property", name: current.property.value });
815
- }
816
- else {
817
- return null;
818
- }
819
- }
820
- else if (current.property.type === "Identifier") {
821
- segments.unshift({ kind: "property", name: current.property.name });
822
- }
823
- else {
824
- return null;
825
- }
826
- if (current.object.type === "Identifier") {
827
- return {
828
- base: current.object.name,
829
- path: segments,
830
- };
831
- }
832
- if (current.object.type !== "MemberExpression") {
833
- return null;
834
- }
835
- current = current.object;
836
- }
837
- return null;
838
- }
839
- function matchesExpressionLocator(expression, locator) {
840
- return (expression.base === locator.base &&
841
- sameValuePath(expression.path, locator.path ?? []));
842
- }
843
- function sameValuePath(left, right) {
844
- if (left.length !== right.length) {
845
- return false;
846
- }
847
- for (let index = 0; index < left.length; index += 1) {
848
- const leftSegment = left[index];
849
- const rightSegment = right[index];
850
- if (leftSegment.kind !== rightSegment.kind) {
851
- return false;
852
- }
853
- if (leftSegment.kind === "property") {
854
- if (rightSegment.kind !== "property" ||
855
- leftSegment.name !== rightSegment.name) {
856
- return false;
857
- }
858
- continue;
859
- }
860
- if (rightSegment.kind !== "index" ||
861
- leftSegment.index !== rightSegment.index) {
862
- return false;
863
- }
864
- }
865
- return true;
866
- }
867
- function getObjectPropertyKey(node) {
868
- if (node.key.type === "Identifier") {
869
- return node.key.name;
870
- }
871
- if (node.key.type === "StringLiteral") {
872
- return node.key.value;
873
- }
874
- return null;
875
- }
876
- function describeExport(locator) {
877
- if (locator.exportKind === "named") {
878
- return locator.name;
879
- }
880
- return locator.exportKind;
881
- }
882
- function failLocator(locatorKind, code, message, details) {
883
- return {
884
- ok: false,
885
- diagnostic: createDiagnostic(code, message, locatorKind, details),
886
- };
887
- }
888
- function matchesExpectedJsxIdentity(path, expectedIdentity) {
889
- const component = getEnclosingComponentName(path);
890
- if (component !== expectedIdentity.component) {
891
- return false;
892
- }
893
- return computeJsxStructuralPath(path) === expectedIdentity.structuralPath;
894
- }
895
- function isNamedJsxAttributePath(attribute, name) {
896
- if (!attribute.isJSXAttribute()) {
897
- return false;
898
- }
899
- if (attribute.node.name.type !== "JSXIdentifier") {
900
- return false;
901
- }
902
- return attribute.node.name.name === name;
903
- }
904
- function findNamedVariableDeclarator(declaration, name) {
905
- return declaration.get("declarations").find((item) => {
906
- if (!item.isVariableDeclarator()) {
907
- return false;
908
- }
909
- if (item.node.id.type !== "Identifier") {
910
- return false;
911
- }
912
- return item.node.id.name === name;
913
- });
914
- }
915
- function matchesObjectPropertyName(property, name) {
916
- if (!property.isObjectProperty()) {
917
- return false;
918
- }
919
- return getObjectPropertyKey(property.node) === name;
920
- }