@archie/devtools 0.1.10 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,1019 +0,0 @@
1
- // node_modules/tsup/assets/esm_shims.js
2
- import path from "path";
3
- import { fileURLToPath } from "url";
4
- var getFilename = () => fileURLToPath(import.meta.url);
5
- var getDirname = () => path.dirname(getFilename());
6
- var __dirname = /* @__PURE__ */ getDirname();
7
-
8
- // src/babel-plugin-editor-meta.ts
9
- import { VID_ATTR, VID_PATTERN } from "@8base-archie/editor-protocol";
10
- import * as nodePath from "path";
11
- function meaningfulChildren(t, children) {
12
- return children.filter((child) => {
13
- if (t.isJSXText(child)) return child.value.trim() !== "";
14
- if (t.isJSXExpressionContainer(child)) return !t.isJSXEmptyExpression(child.expression);
15
- return true;
16
- });
17
- }
18
- var KIT_SLOT_ATTR = "data-kit-slot";
19
- var MAX_SLOT_SEGMENTS = 4;
20
- var NON_BINDING_ATTRS = /* @__PURE__ */ new Set(["__editorMeta", "key", "ref", KIT_SLOT_ATTR]);
21
- var STRUCTURAL_ATTRS = /* @__PURE__ */ new Set([
22
- "id",
23
- "htmlFor",
24
- "slot",
25
- "name",
26
- "type",
27
- "role",
28
- // The camelCase carrier of the SAME durable key as `data-agent-id`: kit
29
- // components take `agentId` and render it as the data attribute. Found on the
30
- // real corpus (×4) — blocking only the dashed form would have left the prop
31
- // form routable, and a durable key with a string-literal usage value sails
32
- // straight through the usage-value law.
33
- "agentId"
34
- ]);
35
- function isNonContentAttribute(name) {
36
- if (/^on[A-Z]/.test(name)) return true;
37
- if (name.startsWith("data-")) return true;
38
- return STRUCTURAL_ATTRS.has(name);
39
- }
40
- function normalizeSlot(raw) {
41
- const value = raw.trim();
42
- if (!value) return null;
43
- const segments = value.split("/");
44
- if (segments.length > MAX_SLOT_SEGMENTS) return null;
45
- if (segments.some((segment) => segment.trim() === "")) return null;
46
- return value;
47
- }
48
- function isPackageImport(src) {
49
- if (src.startsWith(".") || src.startsWith("/")) return false;
50
- if (src.startsWith("@")) {
51
- const slashIdx = src.indexOf("/");
52
- if (slashIdx === 1) return false;
53
- if (slashIdx > 1) return true;
54
- return true;
55
- }
56
- if (src.startsWith("~/") || src.startsWith("#/")) return false;
57
- return true;
58
- }
59
- function babelPluginEditorMeta({ types: t }, opts = {}) {
60
- const {
61
- fileExclude = /node_modules/,
62
- instrumentImported = true,
63
- includeHostSourceRef = false,
64
- origin = "screen",
65
- templateOrigin = false,
66
- allowLegacyIds = true,
67
- onMissingVid
68
- } = opts;
69
- let missingVidWarned = false;
70
- function getJSXTagName(el) {
71
- const { name } = el;
72
- if (t.isJSXIdentifier(name)) return name.name;
73
- if (t.isJSXMemberExpression(name)) {
74
- const parts = [];
75
- let current = name;
76
- while (t.isJSXMemberExpression(current)) {
77
- parts.unshift(current.property.name);
78
- current = current.object;
79
- }
80
- if (t.isJSXIdentifier(current)) parts.unshift(current.name);
81
- return parts.join(".");
82
- }
83
- return "";
84
- }
85
- function isIntrinsicTagName(name) {
86
- return t.isJSXIdentifier(name) && /^[a-z]/.test(name.name);
87
- }
88
- function isHostLikeMemberExpressionName(name) {
89
- if (!t.isJSXMemberExpression(name)) return false;
90
- const propertyName = name.property.name;
91
- return propertyName[0] === propertyName[0].toLowerCase();
92
- }
93
- function isStaticNamespaceDestructure(binding) {
94
- const bp = binding.path;
95
- if (!bp.isVariableDeclarator()) return false;
96
- if (!t.isObjectPattern(bp.node.id)) return false;
97
- if (!binding.constant) return false;
98
- const decl = bp.parentPath;
99
- if (decl?.isVariableDeclaration() && decl.node.kind !== "const") return false;
100
- let init = bp.node.init;
101
- while (init && (t.isTSAsExpression(init) || t.isTSNonNullExpression(init) || t.isTypeCastExpression(init))) {
102
- init = init.expression;
103
- }
104
- while (init && t.isMemberExpression(init) && !init.computed) {
105
- init = init.object;
106
- }
107
- if (!init || !t.isIdentifier(init)) return false;
108
- const rootBinding = bp.scope.getBinding(init.name);
109
- if (!rootBinding) return true;
110
- if (!rootBinding.constant) return false;
111
- return rootBinding.scope === rootBinding.scope.getProgramParent();
112
- }
113
- function computeNodeId(file, line, col, componentName) {
114
- return `${file}:${line}:${col}:${componentName}`;
115
- }
116
- function readVidAttr(attrs) {
117
- for (const attr of attrs) {
118
- if (!t.isJSXAttribute(attr)) continue;
119
- if (!t.isJSXIdentifier(attr.name, { name: VID_ATTR })) continue;
120
- const { value } = attr;
121
- let raw = null;
122
- if (t.isStringLiteral(value)) {
123
- raw = value.value;
124
- } else if (t.isJSXExpressionContainer(value) && t.isStringLiteral(value.expression)) {
125
- raw = value.expression.value;
126
- }
127
- if (raw !== null && VID_PATTERN.test(raw)) return raw;
128
- return null;
129
- }
130
- return null;
131
- }
132
- function computeDynamicType(path2) {
133
- let current = path2.parentPath;
134
- while (current) {
135
- if (current.isJSXExpressionContainer()) {
136
- const expr = current.node.expression;
137
- if (t.isConditionalExpression(expr) || t.isLogicalExpression(expr)) {
138
- return "CONDITIONAL";
139
- }
140
- }
141
- if (current.isArrowFunctionExpression() || current.isFunctionExpression()) {
142
- const call = current.parentPath;
143
- if (call?.isCallExpression()) {
144
- const callee = call.node.callee;
145
- if (t.isMemberExpression(callee) && !callee.computed && t.isIdentifier(callee.property) && /^(map|flatMap|forEach)$/.test(callee.property.name)) {
146
- return "ARRAY";
147
- }
148
- }
149
- break;
150
- }
151
- if (current.isFunctionDeclaration()) break;
152
- current = current.parentPath;
153
- }
154
- return "STATIC";
155
- }
156
- const SHELL_FILE_RE = /(^|\/)shell\.(jsx|tsx)$/;
157
- const SHELL_DIR_RE = /(^|\/)components\/shell\//;
158
- const SHELL_BASENAME_RE = /shell/i;
159
- const CHROME_ANCESTOR_TAGS = /* @__PURE__ */ new Set(["nav", "aside", "header"]);
160
- function isChromeFilePath(file) {
161
- if (SHELL_FILE_RE.test(file) || SHELL_DIR_RE.test(file)) return true;
162
- const base = file.split("/").pop() ?? file;
163
- return SHELL_BASENAME_RE.test(base);
164
- }
165
- function computeIsChrome(file, path2) {
166
- if (isChromeFilePath(file)) return true;
167
- let current = path2.parentPath;
168
- while (current) {
169
- if (current.isJSXElement()) {
170
- const tag = getJSXTagName(current.node.openingElement);
171
- if (CHROME_ANCESTOR_TAGS.has(tag)) return true;
172
- }
173
- current = current.parentPath;
174
- }
175
- return false;
176
- }
177
- function computeContainerKind(path2) {
178
- const elPath = path2.parentPath;
179
- if (!elPath?.isJSXElement()) return "none";
180
- if (!elPath.node.closingElement) return "none";
181
- const children = elPath.node.children;
182
- const allPlain = children.every((c) => {
183
- if (t.isJSXElement(c)) return true;
184
- if (t.isJSXText(c)) return c.value.trim() === "";
185
- if (t.isJSXExpressionContainer(c) && t.isJSXEmptyExpression(c.expression)) return true;
186
- return false;
187
- });
188
- return allPlain ? "plain" : "expression";
189
- }
190
- const kitBoundNamesCache = /* @__PURE__ */ new WeakMap();
191
- function computeKitBoundNames(programPath) {
192
- const cached = kitBoundNamesCache.get(programPath.node);
193
- if (cached) return cached;
194
- const names = /* @__PURE__ */ new Set();
195
- for (const stmt of programPath.node.body) {
196
- if (!t.isVariableDeclaration(stmt)) continue;
197
- for (const decl of stmt.declarations) {
198
- if (!t.isObjectPattern(decl.id)) continue;
199
- if (!decl.init || !t.isIdentifier(decl.init) || decl.init.name !== "Kit") continue;
200
- for (const prop of decl.id.properties) {
201
- if (!t.isObjectProperty(prop)) continue;
202
- const value = t.isIdentifier(prop.value) ? prop.value : t.isIdentifier(prop.key) ? prop.key : null;
203
- if (value) names.add(value.name);
204
- }
205
- }
206
- }
207
- kitBoundNamesCache.set(programPath.node, names);
208
- return names;
209
- }
210
- function isKitComponentTagName(path2) {
211
- const name = path2.node.name;
212
- let head = null;
213
- if (t.isJSXIdentifier(name)) {
214
- head = name.name;
215
- } else if (t.isJSXMemberExpression(name)) {
216
- let cur = name;
217
- while (t.isJSXMemberExpression(cur)) cur = cur.object;
218
- if (t.isJSXIdentifier(cur)) head = cur.name;
219
- }
220
- if (!head || !/^[A-Z]/.test(head)) return false;
221
- if (head === "Kit") return true;
222
- const programPath = path2.scope.getProgramParent().path;
223
- if (programPath.isProgram() && computeKitBoundNames(programPath).has(head)) return true;
224
- const binding = path2.scope.getBinding(head);
225
- if (binding) {
226
- const bp = binding.path;
227
- const isImport = bp.isImportSpecifier() || bp.isImportDefaultSpecifier() || bp.isImportNamespaceSpecifier();
228
- if (isImport) {
229
- const decl = bp.parentPath;
230
- if (decl?.isImportDeclaration() && /kit-runtime/.test(decl.node.source.value)) return true;
231
- }
232
- }
233
- return false;
234
- }
235
- function computeLockReason(isKitOrigin, isChrome, dynamicType) {
236
- if (isKitOrigin) return "KIT_INTERNAL";
237
- if (isChrome) return "CHROME_STRUCTURAL";
238
- if (dynamicType === "ARRAY") return "DYNAMIC_ARRAY";
239
- if (dynamicType === "CONDITIONAL") return "DYNAMIC_CONDITIONAL";
240
- return void 0;
241
- }
242
- function isMovable(path2) {
243
- const elPath = path2.parentPath;
244
- if (!elPath) return false;
245
- const parentEl = elPath.parentPath;
246
- if (!parentEl || !parentEl.isJSXElement()) return false;
247
- const siblings = parentEl.node.children.filter(
248
- (c) => t.isJSXElement(c)
249
- );
250
- return siblings.length >= 2;
251
- }
252
- function getParentNodeId(path2, file) {
253
- const elPath = path2.parentPath;
254
- if (!elPath) return null;
255
- let ancestor = elPath.parentPath;
256
- while (ancestor) {
257
- if (ancestor.isJSXElement()) {
258
- const opening = ancestor.node.openingElement;
259
- const parentVid = readVidAttr(opening.attributes);
260
- if (parentVid) return parentVid;
261
- if (!allowLegacyIds) return null;
262
- const loc = opening.loc?.start;
263
- if (loc) {
264
- const tag = getJSXTagName(opening);
265
- return computeNodeId(file, loc.line, loc.column + 1, tag);
266
- }
267
- return null;
268
- }
269
- ancestor = ancestor.parentPath;
270
- }
271
- return null;
272
- }
273
- function extractStaticProps(attrs) {
274
- const props = [];
275
- let hasAny = false;
276
- for (const attr of attrs) {
277
- if (t.isJSXSpreadAttribute(attr)) continue;
278
- if (!t.isJSXAttribute(attr)) continue;
279
- const keyName = t.isJSXIdentifier(attr.name) ? attr.name.name : attr.name.name.name;
280
- if (keyName === "__editorMeta") continue;
281
- let value;
282
- if (attr.value === null || attr.value === void 0) {
283
- value = t.booleanLiteral(true);
284
- } else if (t.isStringLiteral(attr.value)) {
285
- value = attr.value;
286
- } else if (t.isJSXExpressionContainer(attr.value)) {
287
- const expr = attr.value.expression;
288
- if (t.isNumericLiteral(expr)) {
289
- value = expr;
290
- } else if (t.isBooleanLiteral(expr)) {
291
- value = expr;
292
- } else if (t.isNullLiteral(expr)) {
293
- value = expr;
294
- } else if (t.isStringLiteral(expr)) {
295
- value = expr;
296
- } else {
297
- value = t.stringLiteral("__dynamic__");
298
- }
299
- } else {
300
- continue;
301
- }
302
- props.push(t.objectProperty(t.stringLiteral(keyName), value));
303
- hasAny = true;
304
- }
305
- return hasAny ? t.objectExpression(props) : null;
306
- }
307
- function describeChildrenText(opening) {
308
- const elementPath = opening.parentPath;
309
- if (!elementPath || !elementPath.isJSXElement()) return null;
310
- const element = elementPath.node;
311
- if (!element.closingElement) return null;
312
- const children = element.children;
313
- if (children.length === 0) return "";
314
- if (children.length !== 1) return "__dynamic__";
315
- const [only] = children;
316
- if (!t.isJSXText(only)) return "__dynamic__";
317
- return only.value.trim();
318
- }
319
- function literalInitText(init) {
320
- if (t.isStringLiteral(init)) return init.value;
321
- if (t.isTemplateLiteral(init) && init.expressions.length === 0) {
322
- const [quasi] = init.quasis;
323
- if (!quasi) return null;
324
- return quasi.value.cooked ?? quasi.value.raw;
325
- }
326
- return null;
327
- }
328
- function describeLocalConstSource(name, binding) {
329
- const declarator = binding.path;
330
- if (!declarator.isVariableDeclarator()) return null;
331
- const declaration = declarator.parentPath;
332
- if (!declaration?.isVariableDeclaration()) return null;
333
- if (declaration.node.kind !== "const" && declaration.node.kind !== "let") return null;
334
- const init = declarator.node.init;
335
- if (!init) return null;
336
- const literal = literalInitText(init);
337
- if (literal === null) return null;
338
- const loc = init.loc?.start;
339
- if (!loc) return null;
340
- return {
341
- kind: "local-const",
342
- name,
343
- // The init lives in the SAME file being transformed by construction —
344
- // `scope.getBinding` never crosses a file boundary — so the caller's
345
- // own `file` (computed once per visited node) is correct here too.
346
- file: currentFile,
347
- line: loc.line,
348
- col: loc.column + 1,
349
- literal,
350
- // FE MINOR-5: how many places in the FILE read this const — every
351
- // reference, not only the one this call is describing. `refs > 1`
352
- // means one initializer feeds more than one rendered element, so a
353
- // consumer must warn/refuse rather than treat a rewrite as scoped to
354
- // just this usage (see `PropSource`'s docstring for the full contract).
355
- refs: binding.referencePaths.length
356
- };
357
- }
358
- function resolvableSameFileBinding(name, scope) {
359
- const binding = scope.getBinding(name);
360
- if (!binding) return null;
361
- if (!binding.constant) return null;
362
- const bp = binding.path;
363
- if (bp.isImportSpecifier() || bp.isImportDefaultSpecifier() || bp.isImportNamespaceSpecifier()) {
364
- return null;
365
- }
366
- return binding;
367
- }
368
- function memberChain(expr) {
369
- const path2 = [];
370
- let current = expr;
371
- while (t.isMemberExpression(current)) {
372
- if (current.computed) return null;
373
- if (!t.isIdentifier(current.property)) return null;
374
- path2.unshift(current.property.name);
375
- current = current.object;
376
- }
377
- if (!t.isIdentifier(current)) return null;
378
- return { root: current.name, path: path2 };
379
- }
380
- let currentFile = "";
381
- function describeSource(expr, scope) {
382
- if (t.isIdentifier(expr)) {
383
- const binding = resolvableSameFileBinding(expr.name, scope);
384
- if (!binding) return { kind: "other" };
385
- const local = describeLocalConstSource(expr.name, binding);
386
- if (local) return local;
387
- return { kind: "identifier", name: expr.name };
388
- }
389
- if (t.isMemberExpression(expr) && !expr.computed) {
390
- const chain = memberChain(expr);
391
- if (chain && resolvableSameFileBinding(chain.root, scope)) {
392
- return { kind: "member", root: chain.root, path: chain.path };
393
- }
394
- }
395
- return { kind: "other" };
396
- }
397
- function isStaticPropsLiteral(expr) {
398
- return t.isStringLiteral(expr) || t.isNumericLiteral(expr) || t.isBooleanLiteral(expr) || t.isNullLiteral(expr);
399
- }
400
- function describeChildrenSource(opening) {
401
- const elementPath = opening.parentPath;
402
- if (!elementPath || !elementPath.isJSXElement()) return null;
403
- const children = elementPath.node.children;
404
- if (children.length !== 1) return null;
405
- const [only] = children;
406
- if (!t.isJSXExpressionContainer(only)) return null;
407
- if (t.isJSXEmptyExpression(only.expression)) return null;
408
- return describeSource(only.expression, opening.scope);
409
- }
410
- function collectPropSources(attrs, scope) {
411
- const entries = [];
412
- for (const attr of attrs) {
413
- if (!t.isJSXAttribute(attr)) continue;
414
- const name = t.isJSXIdentifier(attr.name) ? attr.name.name : `${attr.name.namespace.name}:${attr.name.name.name}`;
415
- if (NON_BINDING_ATTRS.has(name)) continue;
416
- const value = attr.value;
417
- if (!t.isJSXExpressionContainer(value)) continue;
418
- const expression = value.expression;
419
- if (t.isJSXEmptyExpression(expression)) continue;
420
- if (isStaticPropsLiteral(expression)) continue;
421
- entries.push([name, describeSource(expression, scope)]);
422
- }
423
- return entries;
424
- }
425
- function propSourceToAst(source) {
426
- switch (source.kind) {
427
- case "identifier":
428
- return t.objectExpression([
429
- t.objectProperty(t.identifier("kind"), t.stringLiteral("identifier")),
430
- t.objectProperty(t.identifier("name"), t.stringLiteral(source.name))
431
- ]);
432
- case "local-const":
433
- return t.objectExpression([
434
- t.objectProperty(t.identifier("kind"), t.stringLiteral("local-const")),
435
- t.objectProperty(t.identifier("name"), t.stringLiteral(source.name)),
436
- t.objectProperty(t.identifier("file"), t.stringLiteral(source.file)),
437
- t.objectProperty(t.identifier("line"), t.numericLiteral(source.line)),
438
- t.objectProperty(t.identifier("col"), t.numericLiteral(source.col)),
439
- t.objectProperty(
440
- t.identifier("literal"),
441
- source.literal === null ? t.nullLiteral() : t.stringLiteral(source.literal)
442
- ),
443
- t.objectProperty(t.identifier("refs"), t.numericLiteral(source.refs))
444
- ]);
445
- case "member":
446
- return t.objectExpression([
447
- t.objectProperty(t.identifier("kind"), t.stringLiteral("member")),
448
- t.objectProperty(t.identifier("root"), t.stringLiteral(source.root)),
449
- t.objectProperty(
450
- t.identifier("path"),
451
- t.arrayExpression(source.path.map((segment) => t.stringLiteral(segment)))
452
- )
453
- ]);
454
- case "other":
455
- default:
456
- return t.objectExpression([t.objectProperty(t.identifier("kind"), t.stringLiteral("other"))]);
457
- }
458
- }
459
- function isMetaStripSpreadExpression(arg) {
460
- if (!t.isCallExpression(arg)) return false;
461
- if (!t.isArrowFunctionExpression(arg.callee)) return false;
462
- const [firstParam] = arg.callee.params;
463
- if (!firstParam || !t.isObjectPattern(firstParam)) return false;
464
- return firstParam.properties.some((prop) => {
465
- if (!t.isObjectProperty(prop)) return false;
466
- if (!t.isIdentifier(prop.key)) return false;
467
- return prop.key.name === "__editorMeta";
468
- });
469
- }
470
- function hasTruthyAsChildProp(attrs) {
471
- for (const attr of attrs) {
472
- if (!t.isJSXAttribute(attr) || !t.isJSXIdentifier(attr.name, { name: "asChild" })) {
473
- continue;
474
- }
475
- if (attr.value == null) return true;
476
- if (t.isJSXExpressionContainer(attr.value)) {
477
- const expr = attr.value.expression;
478
- if (t.isBooleanLiteral(expr)) return expr.value;
479
- }
480
- if (t.isStringLiteral(attr.value)) return attr.value.value !== "false";
481
- return true;
482
- }
483
- return false;
484
- }
485
- function buildPayloadFilter(payload) {
486
- return t.callExpression(
487
- t.arrowFunctionExpression(
488
- [
489
- t.objectPattern([
490
- t.objectProperty(
491
- t.identifier("__editorMeta"),
492
- t.identifier("_$em"),
493
- false,
494
- false
495
- ),
496
- t.objectProperty(
497
- t.stringLiteral(KIT_SLOT_ATTR),
498
- t.identifier("_$ks"),
499
- false,
500
- false
501
- ),
502
- t.restElement(t.identifier("_$r"))
503
- ])
504
- ],
505
- t.identifier("_$r")
506
- ),
507
- [t.objectExpression([t.spreadElement(payload)])]
508
- );
509
- }
510
- function sanitizeSpreadAttributes(attrs) {
511
- for (const attr of attrs) {
512
- if (!t.isJSXSpreadAttribute(attr)) continue;
513
- if (isMetaStripSpreadExpression(attr.argument)) continue;
514
- attr.argument = buildPayloadFilter(attr.argument);
515
- }
516
- }
517
- function consumeKitSlot(attrs) {
518
- let slot = null;
519
- let found = false;
520
- for (const attr of attrs) {
521
- if (!t.isJSXAttribute(attr)) continue;
522
- if (!t.isJSXIdentifier(attr.name, { name: KIT_SLOT_ATTR })) continue;
523
- found = true;
524
- if (slot !== null) continue;
525
- const { value } = attr;
526
- if (t.isStringLiteral(value)) {
527
- slot = normalizeSlot(value.value);
528
- } else if (t.isJSXExpressionContainer(value) && t.isStringLiteral(value.expression)) {
529
- slot = normalizeSlot(value.expression.value);
530
- }
531
- }
532
- if (!found) return { slot: null, found: false, attrs };
533
- return {
534
- slot,
535
- found: true,
536
- attrs: attrs.filter(
537
- (attr) => !(t.isJSXAttribute(attr) && t.isJSXIdentifier(attr.name, { name: KIT_SLOT_ATTR }))
538
- )
539
- };
540
- }
541
- function getFunctionName(fn) {
542
- const node = fn.node;
543
- if (t.isFunctionDeclaration(node) && node.id) return node.id.name;
544
- if (t.isFunctionExpression(node) && node.id) return node.id.name;
545
- const parent = fn.parentPath;
546
- if (parent?.isVariableDeclarator() && t.isIdentifier(parent.node.id)) {
547
- return parent.node.id.name;
548
- }
549
- return null;
550
- }
551
- function buildPropMap(pattern) {
552
- const map = /* @__PURE__ */ new Map();
553
- for (const prop of pattern.properties) {
554
- if (!t.isObjectProperty(prop) || prop.computed) continue;
555
- const key = t.isIdentifier(prop.key) ? prop.key.name : t.isStringLiteral(prop.key) ? prop.key.value : null;
556
- if (!key) continue;
557
- const value = prop.value;
558
- if (t.isIdentifier(value)) {
559
- map.set(value.name, key);
560
- } else if (t.isAssignmentPattern(value) && t.isIdentifier(value.left)) {
561
- map.set(value.left.name, key);
562
- }
563
- }
564
- return map;
565
- }
566
- function restParamName(pattern) {
567
- for (const prop of pattern.properties) {
568
- if (!t.isRestElement(prop)) continue;
569
- if (t.isIdentifier(prop.argument)) return prop.argument.name;
570
- return null;
571
- }
572
- return null;
573
- }
574
- function resolvePropContext(path2) {
575
- let fn = path2.getFunctionParent();
576
- while (fn) {
577
- const [first] = fn.node.params;
578
- if (first && t.isObjectPattern(first) && fn.scope.parent === fn.scope.getProgramParent()) {
579
- return {
580
- componentScope: fn.scope,
581
- propMap: buildPropMap(first),
582
- componentName: getFunctionName(fn),
583
- restParam: restParamName(first),
584
- componentPath: fn
585
- };
586
- }
587
- fn = fn.getFunctionParent();
588
- }
589
- return null;
590
- }
591
- function resolveProp(name, scope, ctx) {
592
- const prop = ctx.propMap.get(name);
593
- if (!prop) return null;
594
- const binding = scope.getBinding(name);
595
- if (!binding) return null;
596
- if (binding.scope !== ctx.componentScope) return null;
597
- if (!binding.constant) return null;
598
- return prop;
599
- }
600
- function isScopeWithinComponent(scope, ctx) {
601
- let current = scope;
602
- while (current) {
603
- if (current === ctx.componentScope) return true;
604
- current = current.parent;
605
- }
606
- return false;
607
- }
608
- function resolveLocalConstInit(name, scope, ctx) {
609
- const binding = scope.getBinding(name);
610
- if (!binding) return null;
611
- if (!binding.constant) return null;
612
- const declarator = binding.path;
613
- if (!declarator.isVariableDeclarator()) return null;
614
- if (!isScopeWithinComponent(binding.scope, ctx)) return null;
615
- const init = declarator.node.init;
616
- if (!init || !t.isExpression(init)) return null;
617
- return { init, scope: declarator.scope };
618
- }
619
- function isStaticStringLiteral(node) {
620
- if (t.isStringLiteral(node)) return true;
621
- return t.isTemplateLiteral(node) && node.expressions.length === 0;
622
- }
623
- function collectPropIdentifiers(node, scope, ctx, out = []) {
624
- if (!node) return out;
625
- const visit = (child) => collectPropIdentifiers(child, scope, ctx, out);
626
- if (t.isIdentifier(node)) {
627
- const prop = resolveProp(node.name, scope, ctx);
628
- if (prop && !out.includes(prop)) out.push(prop);
629
- return out;
630
- }
631
- if (t.isMemberExpression(node) || t.isOptionalMemberExpression(node)) {
632
- visit(node.object);
633
- if (node.computed) visit(node.property);
634
- return out;
635
- }
636
- if (t.isCallExpression(node) || t.isOptionalCallExpression(node)) {
637
- visit(node.callee);
638
- node.arguments.forEach((arg) => visit(arg));
639
- return out;
640
- }
641
- if (t.isTemplateLiteral(node)) {
642
- node.expressions.forEach((expr) => visit(expr));
643
- return out;
644
- }
645
- if (t.isConditionalExpression(node)) {
646
- visit(node.test);
647
- visit(node.consequent);
648
- visit(node.alternate);
649
- return out;
650
- }
651
- if (t.isLogicalExpression(node) || t.isBinaryExpression(node)) {
652
- visit(node.left);
653
- visit(node.right);
654
- return out;
655
- }
656
- if (t.isUnaryExpression(node) || t.isAwaitExpression(node)) {
657
- visit(node.argument);
658
- return out;
659
- }
660
- if (t.isArrayExpression(node)) {
661
- node.elements.forEach((el) => visit(el));
662
- return out;
663
- }
664
- if (t.isObjectExpression(node)) {
665
- for (const prop of node.properties) {
666
- if (t.isObjectProperty(prop)) {
667
- if (prop.computed) visit(prop.key);
668
- visit(prop.value);
669
- } else if (t.isSpreadElement(prop)) {
670
- visit(prop.argument);
671
- }
672
- }
673
- return out;
674
- }
675
- if (t.isSpreadElement(node)) {
676
- visit(node.argument);
677
- return out;
678
- }
679
- if (t.isTSAsExpression(node) || t.isTSNonNullExpression(node) || t.isTypeCastExpression(node)) {
680
- visit(node.expression);
681
- return out;
682
- }
683
- return out;
684
- }
685
- function classifyExpression(expr, scope, ctx, hop) {
686
- if (t.isIdentifier(expr)) {
687
- const prop = resolveProp(expr.name, scope, ctx);
688
- if (prop) return { kind: "direct", prop };
689
- if (hop > 0) return null;
690
- const local = resolveLocalConstInit(expr.name, scope, ctx);
691
- if (!local) return null;
692
- const inner = classifyExpression(local.init, local.scope, ctx, hop + 1);
693
- if (!inner) return null;
694
- return { kind: inner.kind === "formatted" ? "formatted" : "derived", prop: inner.prop };
695
- }
696
- if (t.isLogicalExpression(expr) && (expr.operator === "||" || expr.operator === "??") && isStaticStringLiteral(expr.right)) {
697
- const left = classifyExpression(expr.left, scope, ctx, hop);
698
- if (!left) return null;
699
- return { kind: left.kind === "formatted" ? "formatted" : "derived", prop: left.prop };
700
- }
701
- const props = collectPropIdentifiers(expr, scope, ctx);
702
- return props.length > 0 ? { kind: "formatted", prop: props[0] } : null;
703
- }
704
- function unwrapSanitizedSpread(arg) {
705
- if (!t.isCallExpression(arg)) return arg;
706
- if (!isMetaStripSpreadExpression(arg)) return arg;
707
- if (arg.arguments.length !== 1) return arg;
708
- const [payload] = arg.arguments;
709
- if (!t.isObjectExpression(payload) || payload.properties.length !== 1) return arg;
710
- const [only] = payload.properties;
711
- if (!t.isSpreadElement(only)) return arg;
712
- return only.argument;
713
- }
714
- function forwardsOwnerRestChildren(opening, ctx) {
715
- if (ctx.restParam === null) return false;
716
- const elementPath = opening.parentPath;
717
- if (!elementPath || !elementPath.isJSXElement()) return false;
718
- if (meaningfulChildren(t, elementPath.node.children).length > 0) return false;
719
- let spreadsRest = 0;
720
- for (const attr of opening.node.attributes) {
721
- if (t.isJSXAttribute(attr)) {
722
- if (t.isJSXIdentifier(attr.name, { name: "children" })) return false;
723
- continue;
724
- }
725
- if (!t.isJSXSpreadAttribute(attr)) continue;
726
- const payload = unwrapSanitizedSpread(attr.argument);
727
- if (!t.isIdentifier(payload, { name: ctx.restParam })) return false;
728
- spreadsRest += 1;
729
- }
730
- if (spreadsRest !== 1) return false;
731
- const binding = opening.scope.getBinding(ctx.restParam);
732
- if (!binding) return false;
733
- if (binding.scope !== ctx.componentScope) return false;
734
- return binding.constant;
735
- }
736
- const restForwarderCounts = /* @__PURE__ */ new WeakMap();
737
- function countRestForwarders(ctx) {
738
- const cached = restForwarderCounts.get(ctx.componentPath.node);
739
- if (cached !== void 0) return cached;
740
- let count = 0;
741
- ctx.componentPath.traverse({
742
- JSXOpeningElement(inner) {
743
- if (forwardsOwnerRestChildren(inner, ctx)) count += 1;
744
- }
745
- });
746
- restForwarderCounts.set(ctx.componentPath.node, count);
747
- return count;
748
- }
749
- function collectPropBindings(path2, attrs) {
750
- const ctx = resolvePropContext(path2);
751
- if (!ctx || ctx.propMap.size === 0 && ctx.restParam === null) {
752
- return { bindings: [], owner: null };
753
- }
754
- if (ctx.componentName === null) return { bindings: [], owner: null };
755
- const scope = path2.scope;
756
- const bindings = [];
757
- if (forwardsOwnerRestChildren(path2, ctx) && countRestForwarders(ctx) === 1) {
758
- bindings.push({ target: "children", prop: "children", kind: "direct" });
759
- }
760
- const elementPath = path2.parentPath;
761
- if (elementPath && elementPath.isJSXElement()) {
762
- const children = meaningfulChildren(t, elementPath.node.children);
763
- const isSoleChild = children.length === 1;
764
- for (const child of children) {
765
- if (!t.isJSXExpressionContainer(child)) continue;
766
- const expression = child.expression;
767
- if (t.isJSXEmptyExpression(expression)) continue;
768
- const verdict = classifyExpression(expression, scope, ctx, 0);
769
- if (!verdict) continue;
770
- bindings.push({
771
- target: "children",
772
- prop: verdict.prop,
773
- kind: isSoleChild ? verdict.kind : "formatted"
774
- });
775
- }
776
- }
777
- for (const attr of attrs) {
778
- if (!t.isJSXAttribute(attr)) continue;
779
- const name = t.isJSXIdentifier(attr.name) ? attr.name.name : `${attr.name.namespace.name}:${attr.name.name.name}`;
780
- if (NON_BINDING_ATTRS.has(name)) continue;
781
- const value = attr.value;
782
- if (!t.isJSXExpressionContainer(value)) continue;
783
- const expression = value.expression;
784
- if (t.isJSXEmptyExpression(expression)) continue;
785
- const verdict = classifyExpression(expression, scope, ctx, 0);
786
- if (!verdict) continue;
787
- bindings.push({
788
- target: `attr:${name}`,
789
- prop: verdict.prop,
790
- // M2b: machine-contract attributes are reported, never offered.
791
- kind: isNonContentAttribute(name) ? "formatted" : verdict.kind
792
- });
793
- }
794
- return { bindings, owner: bindings.length > 0 ? ctx.componentName : null };
795
- }
796
- function propBindingsToAst(bindings) {
797
- return t.arrayExpression(
798
- bindings.map(
799
- (binding) => t.objectExpression([
800
- t.objectProperty(t.identifier("target"), t.stringLiteral(binding.target)),
801
- t.objectProperty(t.identifier("prop"), t.stringLiteral(binding.prop)),
802
- t.objectProperty(t.identifier("kind"), t.stringLiteral(binding.kind))
803
- ])
804
- )
805
- );
806
- }
807
- return {
808
- name: "babel-plugin-editor-meta",
809
- visitor: {
810
- CallExpression(path2, state) {
811
- const filename = state.filename ?? "";
812
- if (fileExclude.test(filename)) return;
813
- const callee = path2.node.callee;
814
- let isCreateElement = false;
815
- let isCloneElement = false;
816
- if (t.isIdentifier(callee, { name: "createElement" })) {
817
- isCreateElement = true;
818
- } else if (t.isMemberExpression(callee) && t.isIdentifier(callee.property, { name: "createElement" })) {
819
- isCreateElement = true;
820
- } else if (t.isIdentifier(callee, { name: "cloneElement" })) {
821
- isCloneElement = true;
822
- } else if (t.isMemberExpression(callee) && t.isIdentifier(callee.property, { name: "cloneElement" })) {
823
- isCloneElement = true;
824
- }
825
- if (!isCreateElement && !isCloneElement) return;
826
- const args = path2.node.arguments;
827
- if (args.length < 2) return;
828
- if (isCreateElement && !t.isStringLiteral(args[0])) return;
829
- const propsArg = args[1];
830
- if (!propsArg || t.isNullLiteral(propsArg)) return;
831
- if (!t.isExpression(propsArg)) return;
832
- if (isMetaStripSpreadExpression(propsArg)) return;
833
- args[1] = buildPayloadFilter(propsArg);
834
- },
835
- JSXOpeningElement(path2, state) {
836
- const consumed = consumeKitSlot(path2.node.attributes);
837
- path2.node.attributes = consumed.attrs;
838
- const slot = consumed.slot;
839
- const hasSlotAttr = consumed.found;
840
- const filename = state.filename ?? "";
841
- if (fileExclude.test(filename)) return;
842
- const existing = path2.node.attributes.find(
843
- (a) => t.isJSXAttribute(a) && t.isJSXIdentifier(a.name, { name: "__editorMeta" })
844
- );
845
- if (existing) return;
846
- const loc = path2.node.loc?.start;
847
- if (!loc) return;
848
- const root = state.file.opts.root ?? "";
849
- const file = root ? nodePath.relative(root, filename) : filename;
850
- currentFile = file;
851
- const line = loc.line;
852
- const col = loc.column + 1;
853
- const componentName = getJSXTagName(path2.node);
854
- if (!componentName) return;
855
- const isHostLikeMemberExpression = isHostLikeMemberExpressionName(path2.node.name);
856
- const isHostElement = componentName[0] === componentName[0].toLowerCase();
857
- sanitizeSpreadAttributes(path2.node.attributes);
858
- if (hasTruthyAsChildProp(path2.node.attributes)) {
859
- return;
860
- }
861
- let rootName = null;
862
- if (isIntrinsicTagName(path2.node.name)) {
863
- rootName = null;
864
- } else if (t.isJSXIdentifier(path2.node.name)) {
865
- rootName = path2.node.name.name;
866
- } else if (t.isJSXMemberExpression(path2.node.name)) {
867
- let cur = path2.node.name;
868
- while (t.isJSXMemberExpression(cur)) cur = cur.object;
869
- if (t.isJSXIdentifier(cur)) rootName = cur.name;
870
- }
871
- if (rootName) {
872
- const binding = path2.scope.getBinding(rootName);
873
- if (binding) {
874
- const bp = binding.path;
875
- if (bp.isImportSpecifier() || bp.isImportDefaultSpecifier() || bp.isImportNamespaceSpecifier()) {
876
- if (!instrumentImported) return;
877
- const decl = bp.parentPath;
878
- if (decl?.isImportDeclaration()) {
879
- const src = decl.node.source.value;
880
- if (isPackageImport(src) && !isHostLikeMemberExpression) return;
881
- }
882
- }
883
- const programScope = path2.scope.getProgramParent();
884
- if (binding.scope !== programScope && !isStaticNamespaceDestructure(binding))
885
- return;
886
- }
887
- }
888
- const vid = readVidAttr(path2.node.attributes);
889
- if (!vid && onMissingVid && !missingVidWarned) {
890
- missingVidWarned = true;
891
- onMissingVid({ file, line, col, componentName, instrumented: allowLegacyIds });
892
- }
893
- if (!vid && !allowLegacyIds) return;
894
- const nodeId = vid ?? computeNodeId(file, line, col, componentName);
895
- const isKitOrigin = origin === "kit" || hasSlotAttr;
896
- const movable = isKitOrigin ? false : isMovable(path2);
897
- const parentNodeId = getParentNodeId(path2, file);
898
- const staticPropsObj = extractStaticProps(path2.node.attributes);
899
- const { bindings, owner } = collectPropBindings(path2, path2.node.attributes);
900
- const metaObj = t.objectExpression([
901
- t.objectProperty(t.identifier("nodeId"), t.stringLiteral(nodeId)),
902
- t.objectProperty(t.identifier("file"), t.stringLiteral(file)),
903
- t.objectProperty(t.identifier("line"), t.numericLiteral(line)),
904
- t.objectProperty(t.identifier("col"), t.numericLiteral(col)),
905
- t.objectProperty(t.identifier("componentName"), t.stringLiteral(componentName)),
906
- t.objectProperty(
907
- t.identifier("staticProps"),
908
- staticPropsObj ?? t.nullLiteral()
909
- ),
910
- t.objectProperty(t.identifier("movable"), t.booleanLiteral(movable)),
911
- t.objectProperty(
912
- t.identifier("parentNodeId"),
913
- parentNodeId ? t.stringLiteral(parentNodeId) : t.nullLiteral()
914
- )
915
- ]);
916
- if (vid) {
917
- const dynamicType = computeDynamicType(path2);
918
- const isChrome = computeIsChrome(file, path2);
919
- const containerKind = computeContainerKind(path2);
920
- const isKitComponentContainer = isKitComponentTagName(path2);
921
- const lockReason = computeLockReason(isKitOrigin, isChrome, dynamicType);
922
- metaObj.properties.push(
923
- t.objectProperty(t.identifier("vid"), t.stringLiteral(vid)),
924
- t.objectProperty(t.identifier("isKitOrigin"), t.booleanLiteral(isKitOrigin)),
925
- t.objectProperty(t.identifier("dynamicType"), t.stringLiteral(dynamicType)),
926
- t.objectProperty(t.identifier("isChrome"), t.booleanLiteral(isChrome)),
927
- t.objectProperty(t.identifier("containerKind"), t.stringLiteral(containerKind))
928
- );
929
- if (isKitComponentContainer) {
930
- metaObj.properties.push(
931
- t.objectProperty(t.identifier("isKitContainer"), t.booleanLiteral(true))
932
- );
933
- }
934
- if (lockReason) {
935
- metaObj.properties.push(
936
- t.objectProperty(t.identifier("lockReason"), t.stringLiteral(lockReason))
937
- );
938
- }
939
- }
940
- if (isKitOrigin) {
941
- if (templateOrigin) {
942
- metaObj.properties.push(
943
- t.objectProperty(t.identifier("template"), t.booleanLiteral(true))
944
- );
945
- } else {
946
- metaObj.properties.push(
947
- t.objectProperty(t.identifier("origin"), t.stringLiteral("kit"))
948
- );
949
- }
950
- }
951
- if (slot !== null) {
952
- metaObj.properties.push(
953
- t.objectProperty(t.identifier("slot"), t.stringLiteral(slot))
954
- );
955
- }
956
- if (!isHostElement) {
957
- const childrenText = describeChildrenText(path2);
958
- metaObj.properties.push(
959
- t.objectProperty(
960
- t.identifier("childrenText"),
961
- childrenText === null ? t.nullLiteral() : t.stringLiteral(childrenText)
962
- )
963
- );
964
- const childrenSource = describeChildrenSource(path2);
965
- if (childrenSource) {
966
- metaObj.properties.push(
967
- t.objectProperty(t.identifier("childrenSource"), propSourceToAst(childrenSource))
968
- );
969
- }
970
- }
971
- if (bindings.length > 0) {
972
- metaObj.properties.push(
973
- t.objectProperty(t.identifier("propBindings"), propBindingsToAst(bindings))
974
- );
975
- metaObj.properties.push(
976
- t.objectProperty(
977
- t.identifier("propOwner"),
978
- owner ? t.stringLiteral(owner) : t.nullLiteral()
979
- )
980
- );
981
- }
982
- const propSourceEntries = collectPropSources(path2.node.attributes, path2.scope);
983
- if (propSourceEntries.length > 0) {
984
- metaObj.properties.push(
985
- t.objectProperty(
986
- t.identifier("propSources"),
987
- t.objectExpression(
988
- propSourceEntries.map(
989
- ([name, source]) => t.objectProperty(t.stringLiteral(name), propSourceToAst(source))
990
- )
991
- )
992
- )
993
- );
994
- }
995
- if (isHostElement && includeHostSourceRef) {
996
- path2.node.attributes.push(
997
- t.jsxAttribute(
998
- t.jsxIdentifier("data-archie-source-ref"),
999
- t.stringLiteral(`${file}::${line}::${col}`)
1000
- )
1001
- );
1002
- }
1003
- const metaThunk = t.arrowFunctionExpression([], metaObj);
1004
- path2.node.attributes.push(
1005
- t.jsxAttribute(
1006
- t.jsxIdentifier("__editorMeta"),
1007
- t.jsxExpressionContainer(metaThunk)
1008
- )
1009
- );
1010
- }
1011
- }
1012
- };
1013
- }
1014
-
1015
- export {
1016
- __dirname,
1017
- meaningfulChildren,
1018
- babelPluginEditorMeta
1019
- };