@archie/devtools 0.0.9 → 0.0.11
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.
- package/README.md +53 -111
- package/dist/chunk-QZ7TP4HQ.mjs +7 -0
- package/dist/client/client.d.mts +41 -2
- package/dist/client/client.d.ts +41 -2
- package/dist/client/client.js +8545 -5
- package/dist/client/client.mjs +8594 -3
- package/dist/index.d.mts +28 -23
- package/dist/index.d.ts +28 -23
- package/dist/index.js +500 -8
- package/dist/index.mjs +490 -8
- package/package.json +22 -20
- package/dist/chunk-6HHNPJXA.mjs +0 -83
- package/dist/chunk-D5EA6RR5.mjs +0 -47
- package/dist/chunk-EQV632XF.mjs +0 -66
- package/dist/client/inject-inspector/auto.d.mts +0 -2
- package/dist/client/inject-inspector/auto.d.ts +0 -2
- package/dist/client/inject-inspector/auto.js +0 -1271
- package/dist/client/inject-inspector/auto.mjs +0 -7
- package/dist/client/inject-inspector/injectInspector.d.mts +0 -38
- package/dist/client/inject-inspector/injectInspector.d.ts +0 -38
- package/dist/client/inject-inspector/injectInspector.js +0 -1290
- package/dist/client/inject-inspector/injectInspector.mjs +0 -7
- package/dist/client/route-listener/routeListener.d.mts +0 -49
- package/dist/client/route-listener/routeListener.d.ts +0 -49
- package/dist/client/route-listener/routeListener.js +0 -90
- package/dist/client/route-listener/routeListener.mjs +0 -6
- package/dist/constants/archieOrigins.d.mts +0 -48
- package/dist/constants/archieOrigins.d.ts +0 -48
- package/dist/constants/archieOrigins.js +0 -77
- package/dist/constants/archieOrigins.mjs +0 -18
- package/dist/inspector-QDRZLXRP.mjs +0 -1139
package/dist/index.mjs
CHANGED
|
@@ -1,21 +1,503 @@
|
|
|
1
|
+
import "./chunk-QZ7TP4HQ.mjs";
|
|
2
|
+
|
|
3
|
+
// src/client/dnd/virtual/dndScopeVirtualModule.ts
|
|
4
|
+
var INTERNAL_DND_SCOPE_IMPORT_SOURCE = "virtual:archie-devtools/dnd-scope";
|
|
5
|
+
var RESOLVED_DND_SCOPE_MODULE_ID = `\0${INTERNAL_DND_SCOPE_IMPORT_SOURCE}`;
|
|
6
|
+
function getDndScopeVirtualModuleSource() {
|
|
7
|
+
return `
|
|
8
|
+
import React from 'react';
|
|
9
|
+
|
|
10
|
+
export function DndScope({ id, tag = 'div', tagProps = {}, items = [], direction }) {
|
|
11
|
+
void direction;
|
|
12
|
+
const children = Array.isArray(items)
|
|
13
|
+
? items.map((item) => React.createElement(React.Fragment, { key: item.id }, item.node))
|
|
14
|
+
: [];
|
|
15
|
+
|
|
16
|
+
return React.createElement(
|
|
17
|
+
tag,
|
|
18
|
+
{ ...(tagProps || {}), 'data-dnd-scope': id },
|
|
19
|
+
...children,
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// src/client/dnd/babel-plugin-dnd-auto.ts
|
|
26
|
+
var SCOPE_LOCAL = "__DndScope";
|
|
27
|
+
function babelPluginDndAuto({ types: t }, opts = {}) {
|
|
28
|
+
const {
|
|
29
|
+
fileMatch,
|
|
30
|
+
fileExclude = /node_modules/,
|
|
31
|
+
minComponents = 2,
|
|
32
|
+
importSource = INTERNAL_DND_SCOPE_IMPORT_SOURCE
|
|
33
|
+
} = opts;
|
|
34
|
+
function getJSXTagName(el) {
|
|
35
|
+
const { name } = el;
|
|
36
|
+
if (t.isJSXIdentifier(name)) return name.name;
|
|
37
|
+
if (t.isJSXMemberExpression(name)) {
|
|
38
|
+
const obj = t.isJSXIdentifier(name.object) ? name.object.name : "";
|
|
39
|
+
return `${obj}.${name.property.name}`;
|
|
40
|
+
}
|
|
41
|
+
return "";
|
|
42
|
+
}
|
|
43
|
+
function isHTMLTag(name) {
|
|
44
|
+
return name.length > 0 && name[0] === name[0].toLowerCase();
|
|
45
|
+
}
|
|
46
|
+
function isPascalTag(name) {
|
|
47
|
+
return name.length > 0 && name[0] !== name[0].toLowerCase();
|
|
48
|
+
}
|
|
49
|
+
function attrsToObject(attrs) {
|
|
50
|
+
const props = [];
|
|
51
|
+
for (const attr of attrs) {
|
|
52
|
+
if (!t.isJSXAttribute(attr)) continue;
|
|
53
|
+
const keyName = t.isJSXIdentifier(attr.name) ? attr.name.name : attr.name.name.name;
|
|
54
|
+
let value;
|
|
55
|
+
if (attr.value === null || attr.value === void 0) {
|
|
56
|
+
value = t.booleanLiteral(true);
|
|
57
|
+
} else if (t.isStringLiteral(attr.value)) {
|
|
58
|
+
value = attr.value;
|
|
59
|
+
} else if (t.isJSXExpressionContainer(attr.value)) {
|
|
60
|
+
const expr = attr.value.expression;
|
|
61
|
+
value = t.isJSXEmptyExpression(expr) ? t.booleanLiteral(true) : expr;
|
|
62
|
+
} else {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
props.push(t.objectProperty(t.identifier(keyName), value));
|
|
66
|
+
}
|
|
67
|
+
return t.objectExpression(props);
|
|
68
|
+
}
|
|
69
|
+
function buildItemObject(itemId, type, draggable, node) {
|
|
70
|
+
return t.objectExpression([
|
|
71
|
+
t.objectProperty(t.identifier("id"), t.stringLiteral(itemId)),
|
|
72
|
+
t.objectProperty(t.identifier("type"), t.stringLiteral(type)),
|
|
73
|
+
t.objectProperty(t.identifier("label"), t.stringLiteral(type)),
|
|
74
|
+
// `node` is a JSX element — valid inside a JS object literal
|
|
75
|
+
t.objectProperty(t.identifier("node"), node),
|
|
76
|
+
t.objectProperty(t.identifier("draggable"), t.booleanLiteral(draggable))
|
|
77
|
+
]);
|
|
78
|
+
}
|
|
79
|
+
function maybeTransformRoot(jsxEl, componentName, scopeCounter) {
|
|
80
|
+
const { openingElement, children } = jsxEl;
|
|
81
|
+
const tagName = getJSXTagName(openingElement);
|
|
82
|
+
if (!isHTMLTag(tagName)) return null;
|
|
83
|
+
const elementChildren = children.filter(
|
|
84
|
+
(c) => t.isJSXElement(c)
|
|
85
|
+
);
|
|
86
|
+
const pascalCount = elementChildren.filter(
|
|
87
|
+
(c) => isPascalTag(getJSXTagName(c.openingElement))
|
|
88
|
+
).length;
|
|
89
|
+
if (pascalCount < minComponents) return null;
|
|
90
|
+
scopeCounter.n += 1;
|
|
91
|
+
const scopeId = `${componentName}_s${scopeCounter.n}`;
|
|
92
|
+
const itemObjects = [];
|
|
93
|
+
elementChildren.forEach((child, idx) => {
|
|
94
|
+
const childTag = getJSXTagName(child.openingElement);
|
|
95
|
+
const draggable = isPascalTag(childTag);
|
|
96
|
+
const type = draggable ? childTag : `__html_${idx}`;
|
|
97
|
+
const itemId = `${scopeId}_${childTag}_${idx}`;
|
|
98
|
+
itemObjects.push(buildItemObject(itemId, type, draggable, child));
|
|
99
|
+
});
|
|
100
|
+
const jsxAttrs = openingElement.attributes.filter(
|
|
101
|
+
(a) => t.isJSXAttribute(a)
|
|
102
|
+
);
|
|
103
|
+
const tagPropsObj = attrsToObject(jsxAttrs);
|
|
104
|
+
const dndScopeEl = t.jsxElement(
|
|
105
|
+
t.jsxOpeningElement(
|
|
106
|
+
t.jsxIdentifier(SCOPE_LOCAL),
|
|
107
|
+
[
|
|
108
|
+
t.jsxAttribute(t.jsxIdentifier("id"), t.stringLiteral(scopeId)),
|
|
109
|
+
t.jsxAttribute(t.jsxIdentifier("tag"), t.stringLiteral(tagName)),
|
|
110
|
+
t.jsxAttribute(
|
|
111
|
+
t.jsxIdentifier("tagProps"),
|
|
112
|
+
t.jsxExpressionContainer(tagPropsObj)
|
|
113
|
+
),
|
|
114
|
+
t.jsxAttribute(
|
|
115
|
+
t.jsxIdentifier("items"),
|
|
116
|
+
t.jsxExpressionContainer(t.arrayExpression(itemObjects))
|
|
117
|
+
)
|
|
118
|
+
],
|
|
119
|
+
true
|
|
120
|
+
// self-closing
|
|
121
|
+
),
|
|
122
|
+
null,
|
|
123
|
+
// no closing element (self-closing)
|
|
124
|
+
[],
|
|
125
|
+
true
|
|
126
|
+
);
|
|
127
|
+
return dndScopeEl;
|
|
128
|
+
}
|
|
129
|
+
return {
|
|
130
|
+
name: "babel-plugin-dnd-auto",
|
|
131
|
+
visitor: {
|
|
132
|
+
ExportDefaultDeclaration(path, state) {
|
|
133
|
+
const filename = state.filename ?? "";
|
|
134
|
+
if (fileExclude.test(filename)) return;
|
|
135
|
+
if (fileMatch && !fileMatch.test(filename)) return;
|
|
136
|
+
const { declaration } = path.node;
|
|
137
|
+
if (!t.isFunctionDeclaration(declaration)) return;
|
|
138
|
+
const componentName = declaration.id?.name ?? "Component";
|
|
139
|
+
const scopeCounter = { n: 0 };
|
|
140
|
+
let didTransform = false;
|
|
141
|
+
path.traverse({
|
|
142
|
+
ReturnStatement(retPath) {
|
|
143
|
+
const fnParent = retPath.getFunctionParent();
|
|
144
|
+
if (fnParent?.node !== declaration) return;
|
|
145
|
+
const arg = retPath.node.argument;
|
|
146
|
+
if (!arg || !t.isJSXElement(arg)) return;
|
|
147
|
+
const transformed = maybeTransformRoot(arg, componentName, scopeCounter);
|
|
148
|
+
if (transformed) {
|
|
149
|
+
retPath.node.argument = transformed;
|
|
150
|
+
didTransform = true;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
if (didTransform && !state._dndInjected) {
|
|
155
|
+
state._dndInjected = true;
|
|
156
|
+
state.file.path.unshiftContainer(
|
|
157
|
+
"body",
|
|
158
|
+
t.importDeclaration(
|
|
159
|
+
[t.importSpecifier(t.identifier(SCOPE_LOCAL), t.identifier("DndScope"))],
|
|
160
|
+
t.stringLiteral(importSource)
|
|
161
|
+
)
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// src/babel-plugin-editor-meta.ts
|
|
170
|
+
import * as nodePath from "path";
|
|
171
|
+
function isPackageImport(src) {
|
|
172
|
+
if (src.startsWith(".") || src.startsWith("/")) return false;
|
|
173
|
+
if (src.startsWith("@")) {
|
|
174
|
+
const slashIdx = src.indexOf("/");
|
|
175
|
+
if (slashIdx === 1) return false;
|
|
176
|
+
if (slashIdx > 1) return true;
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
if (src.startsWith("~/") || src.startsWith("#/")) return false;
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
function babelPluginEditorMeta({ types: t }, opts = {}) {
|
|
183
|
+
const {
|
|
184
|
+
fileExclude = /node_modules/,
|
|
185
|
+
instrumentImported = true,
|
|
186
|
+
includeHostSourceRef = false
|
|
187
|
+
} = opts;
|
|
188
|
+
function getJSXTagName(el) {
|
|
189
|
+
const { name } = el;
|
|
190
|
+
if (t.isJSXIdentifier(name)) return name.name;
|
|
191
|
+
if (t.isJSXMemberExpression(name)) {
|
|
192
|
+
const parts = [];
|
|
193
|
+
let current = name;
|
|
194
|
+
while (t.isJSXMemberExpression(current)) {
|
|
195
|
+
parts.unshift(current.property.name);
|
|
196
|
+
current = current.object;
|
|
197
|
+
}
|
|
198
|
+
if (t.isJSXIdentifier(current)) parts.unshift(current.name);
|
|
199
|
+
return parts.join(".");
|
|
200
|
+
}
|
|
201
|
+
return "";
|
|
202
|
+
}
|
|
203
|
+
function computeNodeId(file, line, col, componentName) {
|
|
204
|
+
return `${file}:${line}:${col}:${componentName}`;
|
|
205
|
+
}
|
|
206
|
+
function isMovable(path) {
|
|
207
|
+
const elPath = path.parentPath;
|
|
208
|
+
if (!elPath) return false;
|
|
209
|
+
const parentEl = elPath.parentPath;
|
|
210
|
+
if (!parentEl || !parentEl.isJSXElement()) return false;
|
|
211
|
+
const siblings = parentEl.node.children.filter(
|
|
212
|
+
(c) => t.isJSXElement(c)
|
|
213
|
+
);
|
|
214
|
+
return siblings.length >= 2;
|
|
215
|
+
}
|
|
216
|
+
function getParentNodeId(path, file) {
|
|
217
|
+
const elPath = path.parentPath;
|
|
218
|
+
if (!elPath) return null;
|
|
219
|
+
let ancestor = elPath.parentPath;
|
|
220
|
+
while (ancestor) {
|
|
221
|
+
if (ancestor.isJSXElement()) {
|
|
222
|
+
const opening = ancestor.node.openingElement;
|
|
223
|
+
const loc = opening.loc?.start;
|
|
224
|
+
if (loc) {
|
|
225
|
+
const tag = getJSXTagName(opening);
|
|
226
|
+
return computeNodeId(file, loc.line, loc.column, tag);
|
|
227
|
+
}
|
|
228
|
+
return null;
|
|
229
|
+
}
|
|
230
|
+
ancestor = ancestor.parentPath;
|
|
231
|
+
}
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
function extractStaticProps(attrs) {
|
|
235
|
+
const props = [];
|
|
236
|
+
let hasAny = false;
|
|
237
|
+
for (const attr of attrs) {
|
|
238
|
+
if (t.isJSXSpreadAttribute(attr)) continue;
|
|
239
|
+
if (!t.isJSXAttribute(attr)) continue;
|
|
240
|
+
const keyName = t.isJSXIdentifier(attr.name) ? attr.name.name : attr.name.name.name;
|
|
241
|
+
if (keyName === "__editorMeta") continue;
|
|
242
|
+
let value;
|
|
243
|
+
if (attr.value === null || attr.value === void 0) {
|
|
244
|
+
value = t.booleanLiteral(true);
|
|
245
|
+
} else if (t.isStringLiteral(attr.value)) {
|
|
246
|
+
value = attr.value;
|
|
247
|
+
} else if (t.isJSXExpressionContainer(attr.value)) {
|
|
248
|
+
const expr = attr.value.expression;
|
|
249
|
+
if (t.isNumericLiteral(expr)) {
|
|
250
|
+
value = expr;
|
|
251
|
+
} else if (t.isBooleanLiteral(expr)) {
|
|
252
|
+
value = expr;
|
|
253
|
+
} else if (t.isNullLiteral(expr)) {
|
|
254
|
+
value = expr;
|
|
255
|
+
} else if (t.isStringLiteral(expr)) {
|
|
256
|
+
value = expr;
|
|
257
|
+
} else {
|
|
258
|
+
value = t.stringLiteral("__dynamic__");
|
|
259
|
+
}
|
|
260
|
+
} else {
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
props.push(t.objectProperty(t.stringLiteral(keyName), value));
|
|
264
|
+
hasAny = true;
|
|
265
|
+
}
|
|
266
|
+
return hasAny ? t.objectExpression(props) : null;
|
|
267
|
+
}
|
|
268
|
+
function isMetaStripSpreadExpression(arg) {
|
|
269
|
+
if (!t.isCallExpression(arg)) return false;
|
|
270
|
+
if (!t.isArrowFunctionExpression(arg.callee)) return false;
|
|
271
|
+
const [firstParam] = arg.callee.params;
|
|
272
|
+
if (!firstParam || !t.isObjectPattern(firstParam)) return false;
|
|
273
|
+
return firstParam.properties.some((prop) => {
|
|
274
|
+
if (!t.isObjectProperty(prop)) return false;
|
|
275
|
+
if (!t.isIdentifier(prop.key)) return false;
|
|
276
|
+
return prop.key.name === "__editorMeta";
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
function hasTruthyAsChildProp(attrs) {
|
|
280
|
+
for (const attr of attrs) {
|
|
281
|
+
if (!t.isJSXAttribute(attr) || !t.isJSXIdentifier(attr.name, { name: "asChild" })) {
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
if (attr.value == null) return true;
|
|
285
|
+
if (t.isJSXExpressionContainer(attr.value)) {
|
|
286
|
+
const expr = attr.value.expression;
|
|
287
|
+
if (t.isBooleanLiteral(expr)) return expr.value;
|
|
288
|
+
}
|
|
289
|
+
if (t.isStringLiteral(attr.value)) return attr.value.value !== "false";
|
|
290
|
+
return true;
|
|
291
|
+
}
|
|
292
|
+
return false;
|
|
293
|
+
}
|
|
294
|
+
function sanitizeSpreadAttributes(attrs) {
|
|
295
|
+
for (const attr of attrs) {
|
|
296
|
+
if (!t.isJSXSpreadAttribute(attr)) continue;
|
|
297
|
+
if (isMetaStripSpreadExpression(attr.argument)) continue;
|
|
298
|
+
const origArg = attr.argument;
|
|
299
|
+
attr.argument = t.callExpression(
|
|
300
|
+
t.arrowFunctionExpression(
|
|
301
|
+
[
|
|
302
|
+
t.objectPattern([
|
|
303
|
+
t.objectProperty(
|
|
304
|
+
t.identifier("__editorMeta"),
|
|
305
|
+
t.identifier("_$em"),
|
|
306
|
+
false,
|
|
307
|
+
false
|
|
308
|
+
),
|
|
309
|
+
t.restElement(t.identifier("_$r"))
|
|
310
|
+
])
|
|
311
|
+
],
|
|
312
|
+
t.identifier("_$r")
|
|
313
|
+
),
|
|
314
|
+
[t.objectExpression([t.spreadElement(origArg)])]
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return {
|
|
319
|
+
name: "babel-plugin-editor-meta",
|
|
320
|
+
visitor: {
|
|
321
|
+
CallExpression(path, state) {
|
|
322
|
+
const filename = state.filename ?? "";
|
|
323
|
+
if (fileExclude.test(filename)) return;
|
|
324
|
+
const callee = path.node.callee;
|
|
325
|
+
let isCreateElement = false;
|
|
326
|
+
let isCloneElement = false;
|
|
327
|
+
if (t.isIdentifier(callee, { name: "createElement" })) {
|
|
328
|
+
isCreateElement = true;
|
|
329
|
+
} else if (t.isMemberExpression(callee) && t.isIdentifier(callee.property, { name: "createElement" })) {
|
|
330
|
+
isCreateElement = true;
|
|
331
|
+
} else if (t.isIdentifier(callee, { name: "cloneElement" })) {
|
|
332
|
+
isCloneElement = true;
|
|
333
|
+
} else if (t.isMemberExpression(callee) && t.isIdentifier(callee.property, { name: "cloneElement" })) {
|
|
334
|
+
isCloneElement = true;
|
|
335
|
+
}
|
|
336
|
+
if (!isCreateElement && !isCloneElement) return;
|
|
337
|
+
const args = path.node.arguments;
|
|
338
|
+
if (args.length < 2) return;
|
|
339
|
+
if (isCreateElement && !t.isStringLiteral(args[0])) return;
|
|
340
|
+
const propsArg = args[1];
|
|
341
|
+
if (!propsArg || t.isNullLiteral(propsArg)) return;
|
|
342
|
+
if (!t.isExpression(propsArg)) return;
|
|
343
|
+
if (isMetaStripSpreadExpression(propsArg)) return;
|
|
344
|
+
args[1] = t.callExpression(
|
|
345
|
+
t.arrowFunctionExpression(
|
|
346
|
+
[
|
|
347
|
+
t.objectPattern([
|
|
348
|
+
t.objectProperty(
|
|
349
|
+
t.identifier("__editorMeta"),
|
|
350
|
+
t.identifier("_$em"),
|
|
351
|
+
false,
|
|
352
|
+
false
|
|
353
|
+
),
|
|
354
|
+
t.restElement(t.identifier("_$r"))
|
|
355
|
+
])
|
|
356
|
+
],
|
|
357
|
+
t.identifier("_$r")
|
|
358
|
+
),
|
|
359
|
+
[t.objectExpression([t.spreadElement(propsArg)])]
|
|
360
|
+
);
|
|
361
|
+
},
|
|
362
|
+
JSXOpeningElement(path, state) {
|
|
363
|
+
const filename = state.filename ?? "";
|
|
364
|
+
if (fileExclude.test(filename)) return;
|
|
365
|
+
const existing = path.node.attributes.find(
|
|
366
|
+
(a) => t.isJSXAttribute(a) && t.isJSXIdentifier(a.name, { name: "__editorMeta" })
|
|
367
|
+
);
|
|
368
|
+
if (existing) return;
|
|
369
|
+
const loc = path.node.loc?.start;
|
|
370
|
+
if (!loc) return;
|
|
371
|
+
const root = state.file.opts.root ?? "";
|
|
372
|
+
const file = root ? nodePath.relative(root, filename) : filename;
|
|
373
|
+
const line = loc.line;
|
|
374
|
+
const col = loc.column;
|
|
375
|
+
const componentName = getJSXTagName(path.node);
|
|
376
|
+
if (!componentName) return;
|
|
377
|
+
const isHostElement = componentName[0] === componentName[0].toLowerCase();
|
|
378
|
+
sanitizeSpreadAttributes(path.node.attributes);
|
|
379
|
+
if (hasTruthyAsChildProp(path.node.attributes)) {
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
let rootName = null;
|
|
383
|
+
if (t.isJSXIdentifier(path.node.name)) {
|
|
384
|
+
rootName = path.node.name.name;
|
|
385
|
+
} else if (t.isJSXMemberExpression(path.node.name)) {
|
|
386
|
+
let cur = path.node.name;
|
|
387
|
+
while (t.isJSXMemberExpression(cur)) cur = cur.object;
|
|
388
|
+
if (t.isJSXIdentifier(cur)) rootName = cur.name;
|
|
389
|
+
}
|
|
390
|
+
if (rootName) {
|
|
391
|
+
const binding = path.scope.getBinding(rootName);
|
|
392
|
+
if (binding) {
|
|
393
|
+
const bp = binding.path;
|
|
394
|
+
if (bp.isImportSpecifier() || bp.isImportDefaultSpecifier() || bp.isImportNamespaceSpecifier()) {
|
|
395
|
+
if (!instrumentImported) return;
|
|
396
|
+
const decl = bp.parentPath;
|
|
397
|
+
if (decl?.isImportDeclaration()) {
|
|
398
|
+
const src = decl.node.source.value;
|
|
399
|
+
if (isPackageImport(src)) return;
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
const programScope = path.scope.getProgramParent();
|
|
403
|
+
if (binding.scope !== programScope) return;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
const nodeId = computeNodeId(file, line, col, componentName);
|
|
407
|
+
const movable = isMovable(path);
|
|
408
|
+
const parentNodeId = getParentNodeId(path, file);
|
|
409
|
+
const staticPropsObj = extractStaticProps(path.node.attributes);
|
|
410
|
+
const metaObj = t.objectExpression([
|
|
411
|
+
t.objectProperty(t.identifier("nodeId"), t.stringLiteral(nodeId)),
|
|
412
|
+
t.objectProperty(t.identifier("file"), t.stringLiteral(file)),
|
|
413
|
+
t.objectProperty(t.identifier("line"), t.numericLiteral(line)),
|
|
414
|
+
t.objectProperty(t.identifier("col"), t.numericLiteral(col)),
|
|
415
|
+
t.objectProperty(t.identifier("componentName"), t.stringLiteral(componentName)),
|
|
416
|
+
t.objectProperty(
|
|
417
|
+
t.identifier("staticProps"),
|
|
418
|
+
staticPropsObj ?? t.nullLiteral()
|
|
419
|
+
),
|
|
420
|
+
t.objectProperty(t.identifier("movable"), t.booleanLiteral(movable)),
|
|
421
|
+
t.objectProperty(
|
|
422
|
+
t.identifier("parentNodeId"),
|
|
423
|
+
parentNodeId ? t.stringLiteral(parentNodeId) : t.nullLiteral()
|
|
424
|
+
)
|
|
425
|
+
]);
|
|
426
|
+
if (isHostElement && includeHostSourceRef) {
|
|
427
|
+
path.node.attributes.push(
|
|
428
|
+
t.jsxAttribute(
|
|
429
|
+
t.jsxIdentifier("data-archie-source-ref"),
|
|
430
|
+
t.stringLiteral(`${file}::${line}::${col}`)
|
|
431
|
+
)
|
|
432
|
+
);
|
|
433
|
+
}
|
|
434
|
+
path.node.attributes.push(
|
|
435
|
+
t.jsxAttribute(
|
|
436
|
+
t.jsxIdentifier("__editorMeta"),
|
|
437
|
+
t.jsxExpressionContainer(metaObj)
|
|
438
|
+
)
|
|
439
|
+
);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
|
|
1
445
|
// src/index.ts
|
|
2
446
|
function archieDevTools(options = {}) {
|
|
3
|
-
const {
|
|
447
|
+
const {
|
|
448
|
+
debug = false,
|
|
449
|
+
dndPages = /src\/pages\//
|
|
450
|
+
} = options;
|
|
4
451
|
const log = (...args) => {
|
|
5
|
-
if (debug)
|
|
6
|
-
console.log("[Archie DevTools]", ...args);
|
|
7
|
-
}
|
|
452
|
+
if (debug) console.log("[Archie DevTools]", ...args);
|
|
8
453
|
};
|
|
9
|
-
|
|
454
|
+
let includeHostSourceRef = false;
|
|
455
|
+
const plugin = {
|
|
10
456
|
name: "vite-plugin-archie-devtools",
|
|
11
457
|
enforce: "pre",
|
|
458
|
+
config() {
|
|
459
|
+
return {
|
|
460
|
+
resolve: {
|
|
461
|
+
dedupe: ["react", "react-dom"]
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
},
|
|
12
465
|
configResolved(config) {
|
|
13
|
-
|
|
466
|
+
includeHostSourceRef = !config.isProduction;
|
|
467
|
+
},
|
|
468
|
+
resolveId(id) {
|
|
469
|
+
if (id === INTERNAL_DND_SCOPE_IMPORT_SOURCE) {
|
|
470
|
+
return RESOLVED_DND_SCOPE_MODULE_ID;
|
|
471
|
+
}
|
|
472
|
+
return null;
|
|
473
|
+
},
|
|
474
|
+
load(id) {
|
|
475
|
+
if (id === RESOLVED_DND_SCOPE_MODULE_ID) {
|
|
476
|
+
return getDndScopeVirtualModuleSource();
|
|
477
|
+
}
|
|
478
|
+
return null;
|
|
14
479
|
},
|
|
15
|
-
|
|
16
|
-
|
|
480
|
+
api: {
|
|
481
|
+
reactBabel(babelOptions, context) {
|
|
482
|
+
if (!/node_modules/.test(context.id)) {
|
|
483
|
+
babelOptions.plugins.push(
|
|
484
|
+
(babel) => babelPluginEditorMeta(babel, {
|
|
485
|
+
includeHostSourceRef
|
|
486
|
+
})
|
|
487
|
+
);
|
|
488
|
+
}
|
|
489
|
+
if (dndPages.test(context.id)) {
|
|
490
|
+
log("Applying DnD transform to:", context.id);
|
|
491
|
+
babelOptions.plugins.push(
|
|
492
|
+
(babel) => babelPluginDndAuto(babel, {
|
|
493
|
+
importSource: INTERNAL_DND_SCOPE_IMPORT_SOURCE
|
|
494
|
+
})
|
|
495
|
+
);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
17
498
|
}
|
|
18
499
|
};
|
|
500
|
+
return plugin;
|
|
19
501
|
}
|
|
20
502
|
export {
|
|
21
503
|
archieDevTools
|
package/package.json
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@archie/devtools",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"description": "DevTools for Archie generated applications - Route synchronization and editor communication",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/8base-archie/archie-devtools.git"
|
|
8
|
+
},
|
|
9
|
+
"publishConfig": {
|
|
10
|
+
"access": "restricted",
|
|
11
|
+
"provenance": false
|
|
12
|
+
},
|
|
5
13
|
"main": "dist/index.js",
|
|
6
14
|
"module": "dist/index.mjs",
|
|
7
15
|
"types": "dist/index.d.ts",
|
|
@@ -15,23 +23,14 @@
|
|
|
15
23
|
"types": "./dist/client/client.d.ts",
|
|
16
24
|
"import": "./dist/client/client.mjs",
|
|
17
25
|
"require": "./dist/client/client.js"
|
|
18
|
-
},
|
|
19
|
-
"./client/inject-inspector/auto": {
|
|
20
|
-
"types": "./dist/client/inject-inspector/auto.d.ts",
|
|
21
|
-
"import": "./dist/client/inject-inspector/auto.mjs",
|
|
22
|
-
"require": "./dist/client/inject-inspector/auto.js"
|
|
23
|
-
},
|
|
24
|
-
"./constants": {
|
|
25
|
-
"types": "./dist/constants/archieOrigins.d.ts",
|
|
26
|
-
"import": "./dist/constants/archieOrigins.mjs",
|
|
27
|
-
"require": "./dist/constants/archieOrigins.js"
|
|
28
26
|
}
|
|
29
27
|
},
|
|
30
28
|
"scripts": {
|
|
31
29
|
"test": "vitest run",
|
|
32
30
|
"test:watch": "vitest",
|
|
33
|
-
"
|
|
34
|
-
"
|
|
31
|
+
"inspector:local": "node scripts/generate-inspector-local.js",
|
|
32
|
+
"build": "tsup",
|
|
33
|
+
"dev": "tsup --watch",
|
|
35
34
|
"typecheck": "tsc --noEmit",
|
|
36
35
|
"release": "node publish.js"
|
|
37
36
|
},
|
|
@@ -46,28 +45,31 @@
|
|
|
46
45
|
"react-router"
|
|
47
46
|
],
|
|
48
47
|
"author": "8base",
|
|
49
|
-
"license": "
|
|
48
|
+
"license": "UNLICENSED",
|
|
50
49
|
"devDependencies": {
|
|
50
|
+
"@babel/core": "^7.29.0",
|
|
51
|
+
"@babel/types": "^7.29.0",
|
|
52
|
+
"@dnd-kit/core": "^6.3.1",
|
|
53
|
+
"@dnd-kit/sortable": "^10.0.0",
|
|
54
|
+
"@dnd-kit/utilities": "^3.2.2",
|
|
51
55
|
"@remix-run/router": "^1.0.0",
|
|
56
|
+
"@types/babel__core": "^7.20.5",
|
|
52
57
|
"@types/react": "^19.0.0",
|
|
53
58
|
"@types/react-dom": "^19.0.0",
|
|
54
59
|
"happy-dom": "^20.5.0",
|
|
60
|
+
"lucide-react": "^0.577.0",
|
|
55
61
|
"react": "^19.0.0",
|
|
56
62
|
"react-dom": "^19.0.0",
|
|
57
63
|
"react-router-dom": "^7.0.0",
|
|
58
64
|
"tsup": "^8.0.0",
|
|
59
65
|
"typescript": "^5.0.0",
|
|
60
66
|
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0",
|
|
61
|
-
"vitest": "^2.1.9"
|
|
67
|
+
"vitest": "^2.1.9",
|
|
68
|
+
"zustand": "^5.0.11"
|
|
62
69
|
},
|
|
63
70
|
"peerDependencies": {
|
|
64
71
|
"react": ">=18.0.0",
|
|
65
72
|
"react-dom": ">=18.0.0",
|
|
66
73
|
"react-router-dom": ">=6.4.0"
|
|
67
|
-
},
|
|
68
|
-
"peerDependenciesMeta": {
|
|
69
|
-
"vite": {
|
|
70
|
-
"optional": true
|
|
71
|
-
}
|
|
72
74
|
}
|
|
73
75
|
}
|
package/dist/chunk-6HHNPJXA.mjs
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getAllowedOriginPatterns,
|
|
3
|
-
getAllowedOrigins,
|
|
4
|
-
isPreviewOrigin
|
|
5
|
-
} from "./chunk-D5EA6RR5.mjs";
|
|
6
|
-
|
|
7
|
-
// src/client/inject-inspector/injectInspector.ts
|
|
8
|
-
var DEFAULT_SCRIPT_ID = "archie-inspector-script";
|
|
9
|
-
function isLocalDev(referrer) {
|
|
10
|
-
if (!referrer) return true;
|
|
11
|
-
try {
|
|
12
|
-
const u = new URL(referrer);
|
|
13
|
-
return u.hostname === "localhost" || u.hostname === "127.0.0.1";
|
|
14
|
-
} catch {
|
|
15
|
-
return true;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
function injectInspector(opts = {}) {
|
|
19
|
-
if (typeof document === "undefined") return null;
|
|
20
|
-
const id = opts.id ?? DEFAULT_SCRIPT_ID;
|
|
21
|
-
const existing = document.getElementById(id);
|
|
22
|
-
if (existing) return Promise.resolve(existing);
|
|
23
|
-
const win = typeof window !== "undefined" ? window : null;
|
|
24
|
-
if (win) {
|
|
25
|
-
const referrer = typeof document.referrer === "string" ? document.referrer : "";
|
|
26
|
-
const dev = opts.dev ?? isLocalDev(referrer);
|
|
27
|
-
let allowed;
|
|
28
|
-
if (opts.allowedOrigins !== void 0 && opts.allowedOrigins !== "*") {
|
|
29
|
-
const v = opts.allowedOrigins;
|
|
30
|
-
allowed = typeof v === "string" ? [v] : Array.isArray(v) ? v : [];
|
|
31
|
-
} else {
|
|
32
|
-
allowed = getAllowedOrigins(dev);
|
|
33
|
-
}
|
|
34
|
-
if (allowed.length > 0) {
|
|
35
|
-
win["__ARCHIE_INSPECTOR_ALLOWED_ORIGINS__"] = allowed;
|
|
36
|
-
}
|
|
37
|
-
const patterns = getAllowedOriginPatterns();
|
|
38
|
-
if (patterns.length > 0) {
|
|
39
|
-
win["__ARCHIE_INSPECTOR_ALLOWED_ORIGIN_PATTERNS__"] = patterns;
|
|
40
|
-
}
|
|
41
|
-
let target;
|
|
42
|
-
if (opts.targetOrigin !== void 0 && opts.targetOrigin !== "*") {
|
|
43
|
-
target = opts.targetOrigin || void 0;
|
|
44
|
-
} else if (referrer) {
|
|
45
|
-
try {
|
|
46
|
-
const referrerOrigin = new URL(referrer).origin;
|
|
47
|
-
if (!isPreviewOrigin(referrerOrigin)) {
|
|
48
|
-
target = referrerOrigin;
|
|
49
|
-
}
|
|
50
|
-
} catch {
|
|
51
|
-
target = void 0;
|
|
52
|
-
}
|
|
53
|
-
} else {
|
|
54
|
-
target = void 0;
|
|
55
|
-
}
|
|
56
|
-
if (target) {
|
|
57
|
-
win["__ARCHIE_INSPECTOR_TARGET_ORIGIN__"] = target;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
return import("./inspector-QDRZLXRP.mjs").then((m) => {
|
|
61
|
-
try {
|
|
62
|
-
m.default();
|
|
63
|
-
} catch (err) {
|
|
64
|
-
if (typeof console !== "undefined" && console.error) {
|
|
65
|
-
console.error("[Archie DevTools] Inspector failed to run:", err);
|
|
66
|
-
}
|
|
67
|
-
throw err;
|
|
68
|
-
}
|
|
69
|
-
const script = document.createElement("script");
|
|
70
|
-
script.id = id;
|
|
71
|
-
document.head.appendChild(script);
|
|
72
|
-
return script;
|
|
73
|
-
}).catch((err) => {
|
|
74
|
-
if (typeof console !== "undefined" && console.error) {
|
|
75
|
-
console.error("[Archie DevTools] Failed to load inspector:", err);
|
|
76
|
-
}
|
|
77
|
-
throw err;
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export {
|
|
82
|
-
injectInspector
|
|
83
|
-
};
|