@qontinui/ui-bridge 0.2.0 → 0.3.1
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/dist/ai/index.d.mts +312 -155
- package/dist/ai/index.d.ts +312 -155
- package/dist/ai/index.js +2363 -67
- package/dist/ai/index.js.map +1 -1
- package/dist/ai/index.mjs +2328 -68
- package/dist/ai/index.mjs.map +1 -1
- package/dist/annotations/index.d.mts +218 -0
- package/dist/annotations/index.d.ts +218 -0
- package/dist/annotations/index.js +246 -0
- package/dist/annotations/index.js.map +1 -0
- package/dist/annotations/index.mjs +241 -0
- package/dist/annotations/index.mjs.map +1 -0
- package/dist/assertions-BSR3afVr.d.ts +161 -0
- package/dist/assertions-CTw1hfOx.d.mts +161 -0
- package/dist/babel-plugin/index.js +504 -0
- package/dist/babel-plugin/index.js.map +1 -0
- package/dist/babel-plugin/index.mjs +488 -0
- package/dist/babel-plugin/index.mjs.map +1 -0
- package/dist/browser-capture-Bms60T6f.d.mts +47 -0
- package/dist/browser-capture-CsTU29mb.d.ts +47 -0
- package/dist/control/index.d.mts +26 -7
- package/dist/control/index.d.ts +26 -7
- package/dist/control/index.js +276 -48
- package/dist/control/index.js.map +1 -1
- package/dist/control/index.mjs +276 -48
- package/dist/control/index.mjs.map +1 -1
- package/dist/core/index.d.mts +115 -44
- package/dist/core/index.d.ts +115 -44
- package/dist/core/index.js +0 -1560
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +1 -1549
- package/dist/core/index.mjs.map +1 -1
- package/dist/debug/index.d.mts +5 -3
- package/dist/debug/index.d.ts +5 -3
- package/dist/debug/index.js +925 -1
- package/dist/debug/index.js.map +1 -1
- package/dist/debug/index.mjs +924 -2
- package/dist/debug/index.mjs.map +1 -1
- package/dist/index.d.mts +13 -9
- package/dist/index.d.ts +13 -9
- package/dist/index.js +8310 -3777
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +8246 -3766
- package/dist/index.mjs.map +1 -1
- package/dist/{metrics-NC3csD0R.d.mts → metrics-DuA2qIIz.d.mts} +2 -2
- package/dist/{metrics-C9XRi_mL.d.ts → metrics-KFAAKNEB.d.ts} +2 -2
- package/dist/native/control/index.js +448 -0
- package/dist/native/control/index.js.map +1 -0
- package/dist/native/control/index.mjs +445 -0
- package/dist/native/control/index.mjs.map +1 -0
- package/dist/native/core/index.js +486 -0
- package/dist/native/core/index.js.map +1 -0
- package/dist/native/core/index.mjs +475 -0
- package/dist/native/core/index.mjs.map +1 -0
- package/dist/native/debug/index.js +408 -0
- package/dist/native/debug/index.js.map +1 -0
- package/dist/native/debug/index.mjs +406 -0
- package/dist/native/debug/index.mjs.map +1 -0
- package/dist/native/index.js +2232 -0
- package/dist/native/index.js.map +1 -0
- package/dist/native/index.mjs +2204 -0
- package/dist/native/index.mjs.map +1 -0
- package/dist/native/react/index.js +1377 -0
- package/dist/native/react/index.js.map +1 -0
- package/dist/native/react/index.mjs +1365 -0
- package/dist/native/react/index.mjs.map +1 -0
- package/dist/native/server/index.js +440 -0
- package/dist/native/server/index.js.map +1 -0
- package/dist/native/server/index.mjs +435 -0
- package/dist/native/server/index.mjs.map +1 -0
- package/dist/react/index.d.mts +121 -9
- package/dist/react/index.d.ts +121 -9
- package/dist/react/index.js +2239 -91
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +2239 -92
- package/dist/react/index.mjs.map +1 -1
- package/dist/{registry-CIEDjbQ9.d.ts → registry-C6dDtn1v.d.ts} +34 -15
- package/dist/{registry-SsSDq46X.d.mts → registry-POtcxnal.d.mts} +34 -15
- package/dist/render-log/index.d.mts +1 -1
- package/dist/render-log/index.d.ts +1 -1
- package/dist/server/express.d.mts +37 -0
- package/dist/server/express.d.ts +37 -0
- package/dist/server/express.js +298 -0
- package/dist/server/express.js.map +1 -0
- package/dist/server/express.mjs +294 -0
- package/dist/server/express.mjs.map +1 -0
- package/dist/server/handlers.d.mts +124 -0
- package/dist/server/handlers.d.ts +124 -0
- package/dist/server/handlers.js +7183 -0
- package/dist/server/handlers.js.map +1 -0
- package/dist/server/handlers.mjs +7180 -0
- package/dist/server/handlers.mjs.map +1 -0
- package/dist/server/index.d.mts +12 -0
- package/dist/server/index.d.ts +12 -0
- package/dist/server/index.js +8384 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/index.mjs +8369 -0
- package/dist/server/index.mjs.map +1 -0
- package/dist/server/nextjs.d.mts +128 -0
- package/dist/server/nextjs.d.ts +128 -0
- package/dist/server/nextjs.js +390 -0
- package/dist/server/nextjs.js.map +1 -0
- package/dist/server/nextjs.mjs +385 -0
- package/dist/server/nextjs.mjs.map +1 -0
- package/dist/server/standalone.d.mts +7 -0
- package/dist/server/standalone.d.ts +7 -0
- package/dist/server/standalone.js +845 -0
- package/dist/server/standalone.js.map +1 -0
- package/dist/server/standalone.mjs +841 -0
- package/dist/server/standalone.mjs.map +1 -0
- package/dist/specs/index.d.mts +365 -0
- package/dist/specs/index.d.ts +365 -0
- package/dist/specs/index.js +2809 -0
- package/dist/specs/index.js.map +1 -0
- package/dist/specs/index.mjs +2786 -0
- package/dist/specs/index.mjs.map +1 -0
- package/dist/standalone-B6GLIEmR.d.ts +216 -0
- package/dist/standalone-CjdYqj3P.d.mts +216 -0
- package/dist/swc-plugin/index.d.mts +79 -0
- package/dist/swc-plugin/index.d.ts +79 -0
- package/dist/swc-plugin/index.js +15 -0
- package/dist/swc-plugin/index.js.map +1 -0
- package/dist/swc-plugin/index.mjs +9 -0
- package/dist/swc-plugin/index.mjs.map +1 -0
- package/dist/types-B2EfvEaq.d.ts +236 -0
- package/dist/{types-Dr6tH-bm.d.mts → types-C7gVYRnF.d.ts} +72 -2
- package/dist/{types-oCTrRxSw.d.ts → types-CJGrBEhC.d.mts} +72 -2
- package/dist/types-CebMQj76.d.ts +1275 -0
- package/dist/types-D_ypYl3T.d.mts +1275 -0
- package/dist/types-UBtp7R0u.d.mts +132 -0
- package/dist/types-UBtp7R0u.d.ts +132 -0
- package/dist/types-gO696T_t.d.mts +236 -0
- package/dist/{types-CPMbN_Iw.d.mts → types-suaYwWWg.d.mts} +519 -152
- package/dist/{types-CPMbN_Iw.d.ts → types-suaYwWWg.d.ts} +519 -152
- package/package.json +123 -4
- package/swc-plugin-wasm/ui_bridge_swc_plugin.wasm +0 -0
- package/dist/types-BvCfFuEV.d.ts +0 -534
- package/dist/types-CFT3Dnx4.d.mts +0 -534
- package/dist/websocket-client-CX4QJesI.d.ts +0 -124
- package/dist/websocket-client-C_Na0OSp.d.mts +0 -124
|
@@ -0,0 +1,488 @@
|
|
|
1
|
+
import { declare } from '@babel/helper-plugin-utils';
|
|
2
|
+
|
|
3
|
+
// src/babel-plugin/index.ts
|
|
4
|
+
|
|
5
|
+
// src/babel-plugin/config.ts
|
|
6
|
+
var DEFAULT_CONFIG = {
|
|
7
|
+
include: ["**/*.tsx", "**/*.jsx"],
|
|
8
|
+
exclude: ["**/node_modules/**", "**/*.test.*", "**/*.spec.*", "**/*.stories.*"],
|
|
9
|
+
elements: ["button", "input", "select", "textarea", "a", "form"],
|
|
10
|
+
idPrefix: "ui",
|
|
11
|
+
idAttribute: "data-ui-id",
|
|
12
|
+
aliasesAttribute: "data-ui-aliases",
|
|
13
|
+
typeAttribute: "data-ui-type",
|
|
14
|
+
generateAliases: true,
|
|
15
|
+
includeComponentName: true,
|
|
16
|
+
includeFilePath: false,
|
|
17
|
+
hashIds: false,
|
|
18
|
+
maxAliases: 5,
|
|
19
|
+
skipExisting: true,
|
|
20
|
+
onlyInComponents: [],
|
|
21
|
+
skipInComponents: [],
|
|
22
|
+
verbose: false
|
|
23
|
+
};
|
|
24
|
+
function mergeConfig(userConfig = {}) {
|
|
25
|
+
return {
|
|
26
|
+
...DEFAULT_CONFIG,
|
|
27
|
+
...userConfig,
|
|
28
|
+
// Ensure arrays are properly merged
|
|
29
|
+
include: userConfig.include ?? DEFAULT_CONFIG.include,
|
|
30
|
+
exclude: userConfig.exclude ?? DEFAULT_CONFIG.exclude,
|
|
31
|
+
elements: userConfig.elements ?? DEFAULT_CONFIG.elements,
|
|
32
|
+
onlyInComponents: userConfig.onlyInComponents ?? DEFAULT_CONFIG.onlyInComponents,
|
|
33
|
+
skipInComponents: userConfig.skipInComponents ?? DEFAULT_CONFIG.skipInComponents
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function shouldProcessFile(filename, config) {
|
|
37
|
+
const matchPattern = (pattern, path) => {
|
|
38
|
+
if (pattern.startsWith("**/")) {
|
|
39
|
+
const restOfPattern = pattern.slice(3);
|
|
40
|
+
if (restOfPattern.includes("/**")) {
|
|
41
|
+
const dir = restOfPattern.replace("/**", "");
|
|
42
|
+
return path.includes("/" + dir + "/") || path.startsWith(dir + "/");
|
|
43
|
+
}
|
|
44
|
+
if (restOfPattern.startsWith("*.") && restOfPattern.endsWith(".*") && restOfPattern.length > 3) {
|
|
45
|
+
const middle = restOfPattern.slice(2, -2);
|
|
46
|
+
const fileName = path.includes("/") ? path.split("/").pop() || path : path;
|
|
47
|
+
return fileName.includes("." + middle + ".");
|
|
48
|
+
}
|
|
49
|
+
if (restOfPattern.startsWith("*.") && !restOfPattern.slice(2).includes("*")) {
|
|
50
|
+
const ext = restOfPattern.slice(1);
|
|
51
|
+
return path.endsWith(ext);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return path === pattern;
|
|
55
|
+
};
|
|
56
|
+
const normalizedPath = filename.replace(/\\/g, "/");
|
|
57
|
+
for (const pattern of config.exclude) {
|
|
58
|
+
if (matchPattern(pattern, normalizedPath)) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
for (const pattern of config.include) {
|
|
63
|
+
if (matchPattern(pattern, normalizedPath)) {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// src/babel-plugin/id-generator.ts
|
|
71
|
+
function simpleHash(str) {
|
|
72
|
+
let hash = 0;
|
|
73
|
+
for (let i = 0; i < str.length; i++) {
|
|
74
|
+
const char = str.charCodeAt(i);
|
|
75
|
+
hash = (hash << 5) - hash + char;
|
|
76
|
+
hash = hash & hash;
|
|
77
|
+
}
|
|
78
|
+
return Math.abs(hash).toString(16).substring(0, 8);
|
|
79
|
+
}
|
|
80
|
+
function normalizeForId(text) {
|
|
81
|
+
return text.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").replace(/-+/g, "-").substring(0, 30);
|
|
82
|
+
}
|
|
83
|
+
function extractComponentFromPath(filePath) {
|
|
84
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
85
|
+
const match = normalized.match(/\/([^/]+)\.(tsx?|jsx?)$/);
|
|
86
|
+
if (!match) return null;
|
|
87
|
+
const filename = match[1];
|
|
88
|
+
if (filename === "index") {
|
|
89
|
+
const parentMatch = normalized.match(/\/([^/]+)\/index\.(tsx?|jsx?)$/);
|
|
90
|
+
if (parentMatch) {
|
|
91
|
+
return normalizeForId(parentMatch[1]);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return normalizeForId(filename);
|
|
95
|
+
}
|
|
96
|
+
function getSemanticType(tagName, context) {
|
|
97
|
+
const tag = tagName.toLowerCase();
|
|
98
|
+
if (tag === "input") {
|
|
99
|
+
return "input";
|
|
100
|
+
}
|
|
101
|
+
if (tag === "button") {
|
|
102
|
+
const text = context.textContent?.toLowerCase() || "";
|
|
103
|
+
if (text.includes("submit") || text.includes("save")) return "submit-button";
|
|
104
|
+
if (text.includes("cancel") || text.includes("close")) return "cancel-button";
|
|
105
|
+
if (text.includes("delete") || text.includes("remove")) return "delete-button";
|
|
106
|
+
return "button";
|
|
107
|
+
}
|
|
108
|
+
const typeMap = {
|
|
109
|
+
a: "link",
|
|
110
|
+
select: "dropdown",
|
|
111
|
+
textarea: "textarea",
|
|
112
|
+
form: "form",
|
|
113
|
+
nav: "navigation",
|
|
114
|
+
header: "header",
|
|
115
|
+
footer: "footer",
|
|
116
|
+
main: "main",
|
|
117
|
+
aside: "sidebar",
|
|
118
|
+
dialog: "dialog",
|
|
119
|
+
img: "image"
|
|
120
|
+
};
|
|
121
|
+
return typeMap[tag] || tag;
|
|
122
|
+
}
|
|
123
|
+
function generateId(context, config) {
|
|
124
|
+
const parts = [];
|
|
125
|
+
if (config.idPrefix) {
|
|
126
|
+
parts.push(config.idPrefix);
|
|
127
|
+
}
|
|
128
|
+
if (config.includeFilePath) {
|
|
129
|
+
const fileComponent = extractComponentFromPath(context.filePath);
|
|
130
|
+
if (fileComponent) {
|
|
131
|
+
parts.push(fileComponent);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (config.includeComponentName && context.componentName) {
|
|
135
|
+
parts.push(normalizeForId(context.componentName));
|
|
136
|
+
}
|
|
137
|
+
const descriptiveText = context.textContent || context.ariaLabel || context.placeholder || context.title || context.existingId;
|
|
138
|
+
if (descriptiveText) {
|
|
139
|
+
parts.push(normalizeForId(descriptiveText));
|
|
140
|
+
}
|
|
141
|
+
const semanticType = getSemanticType(context.tagName, context);
|
|
142
|
+
parts.push(semanticType);
|
|
143
|
+
let id = parts.filter(Boolean).join("-");
|
|
144
|
+
if (id.length < 5) {
|
|
145
|
+
id = `${config.idPrefix}-${context.tagName}-${context.elementIndex}`;
|
|
146
|
+
}
|
|
147
|
+
if (config.hashIds) {
|
|
148
|
+
const hash = simpleHash(id + context.filePath + context.elementIndex);
|
|
149
|
+
id = `${config.idPrefix}-${hash}`;
|
|
150
|
+
}
|
|
151
|
+
return id;
|
|
152
|
+
}
|
|
153
|
+
var fileElementCounters = /* @__PURE__ */ new Map();
|
|
154
|
+
function getNextElementIndex(filePath, tagName) {
|
|
155
|
+
if (!fileElementCounters.has(filePath)) {
|
|
156
|
+
fileElementCounters.set(filePath, /* @__PURE__ */ new Map());
|
|
157
|
+
}
|
|
158
|
+
const fileCounters = fileElementCounters.get(filePath);
|
|
159
|
+
const current = fileCounters.get(tagName) || 0;
|
|
160
|
+
fileCounters.set(tagName, current + 1);
|
|
161
|
+
return current;
|
|
162
|
+
}
|
|
163
|
+
function resetFileCounters(filePath) {
|
|
164
|
+
fileElementCounters.delete(filePath);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// src/babel-plugin/alias-generator.ts
|
|
168
|
+
var SYNONYMS = {
|
|
169
|
+
submit: ["send", "go", "confirm", "done", "ok", "apply"],
|
|
170
|
+
cancel: ["close", "dismiss", "abort", "back", "exit"],
|
|
171
|
+
delete: ["remove", "trash", "erase", "clear"],
|
|
172
|
+
edit: ["modify", "change", "update"],
|
|
173
|
+
add: ["create", "new", "plus", "insert"],
|
|
174
|
+
save: ["store", "keep", "preserve"],
|
|
175
|
+
search: ["find", "lookup", "query"],
|
|
176
|
+
login: ["signin", "sign in", "log in"],
|
|
177
|
+
logout: ["signout", "sign out", "log out"],
|
|
178
|
+
register: ["signup", "sign up", "join"],
|
|
179
|
+
next: ["continue", "forward", "proceed"],
|
|
180
|
+
previous: ["back", "prev", "prior"],
|
|
181
|
+
start: ["begin", "launch", "run"],
|
|
182
|
+
stop: ["end", "halt", "pause"],
|
|
183
|
+
upload: ["attach", "import"],
|
|
184
|
+
download: ["export", "get"],
|
|
185
|
+
settings: ["preferences", "options", "config"],
|
|
186
|
+
help: ["support", "info", "about"],
|
|
187
|
+
home: ["main", "dashboard"],
|
|
188
|
+
profile: ["account", "user"]
|
|
189
|
+
};
|
|
190
|
+
function normalizeText(text) {
|
|
191
|
+
return text.toLowerCase().trim().replace(/[^a-z0-9\s]/g, "").replace(/\s+/g, " ");
|
|
192
|
+
}
|
|
193
|
+
function tokenize(text) {
|
|
194
|
+
return normalizeText(text).split(" ").filter((word) => word.length > 1);
|
|
195
|
+
}
|
|
196
|
+
function getSynonyms(word) {
|
|
197
|
+
const normalized = word.toLowerCase();
|
|
198
|
+
if (SYNONYMS[normalized]) {
|
|
199
|
+
return SYNONYMS[normalized];
|
|
200
|
+
}
|
|
201
|
+
for (const [key, values] of Object.entries(SYNONYMS)) {
|
|
202
|
+
if (values.includes(normalized)) {
|
|
203
|
+
return [key, ...values.filter((v) => v !== normalized)];
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return [];
|
|
207
|
+
}
|
|
208
|
+
function generateNgrams(tokens, n) {
|
|
209
|
+
const ngrams = [];
|
|
210
|
+
for (let i = 0; i <= tokens.length - n; i++) {
|
|
211
|
+
ngrams.push(tokens.slice(i, i + n).join(" "));
|
|
212
|
+
}
|
|
213
|
+
return ngrams;
|
|
214
|
+
}
|
|
215
|
+
function generateAliases(context, config) {
|
|
216
|
+
const aliases = /* @__PURE__ */ new Set();
|
|
217
|
+
if (context.textContent) {
|
|
218
|
+
const normalized = normalizeText(context.textContent);
|
|
219
|
+
if (normalized) {
|
|
220
|
+
aliases.add(normalized);
|
|
221
|
+
const tokens = tokenize(context.textContent);
|
|
222
|
+
for (const token of tokens) {
|
|
223
|
+
if (token.length >= 3) {
|
|
224
|
+
aliases.add(token);
|
|
225
|
+
}
|
|
226
|
+
for (const synonym of getSynonyms(token)) {
|
|
227
|
+
aliases.add(synonym);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
if (tokens.length >= 2) {
|
|
231
|
+
for (const ngram of generateNgrams(tokens, 2)) {
|
|
232
|
+
aliases.add(ngram);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
if (context.ariaLabel) {
|
|
238
|
+
const normalized = normalizeText(context.ariaLabel);
|
|
239
|
+
if (normalized) {
|
|
240
|
+
aliases.add(normalized);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
if (context.placeholder) {
|
|
244
|
+
const normalized = normalizeText(context.placeholder);
|
|
245
|
+
if (normalized) {
|
|
246
|
+
aliases.add(normalized);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
if (context.title) {
|
|
250
|
+
const normalized = normalizeText(context.title);
|
|
251
|
+
if (normalized) {
|
|
252
|
+
aliases.add(normalized);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if (context.name) {
|
|
256
|
+
const normalized = normalizeText(context.name).replace(/-/g, " ");
|
|
257
|
+
if (normalized) {
|
|
258
|
+
aliases.add(normalized);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
const typeAlias = getElementTypeAlias(context.tagName);
|
|
262
|
+
if (typeAlias) {
|
|
263
|
+
aliases.add(typeAlias);
|
|
264
|
+
}
|
|
265
|
+
const result = Array.from(aliases).filter((alias) => alias.length >= 2 && alias.length <= 50).slice(0, config.maxAliases);
|
|
266
|
+
return result;
|
|
267
|
+
}
|
|
268
|
+
function getElementTypeAlias(tagName) {
|
|
269
|
+
const tag = tagName.toLowerCase();
|
|
270
|
+
const typeAliases = {
|
|
271
|
+
button: "button",
|
|
272
|
+
input: "input",
|
|
273
|
+
select: "dropdown",
|
|
274
|
+
textarea: "text area",
|
|
275
|
+
a: "link",
|
|
276
|
+
form: "form",
|
|
277
|
+
nav: "navigation",
|
|
278
|
+
img: "image"
|
|
279
|
+
};
|
|
280
|
+
return typeAliases[tag] || null;
|
|
281
|
+
}
|
|
282
|
+
function formatAliasesAttribute(aliases) {
|
|
283
|
+
return aliases.join(",");
|
|
284
|
+
}
|
|
285
|
+
function shouldGenerateAliases(context, config) {
|
|
286
|
+
if (!config.generateAliases) {
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
return !!(context.textContent || context.ariaLabel || context.placeholder || context.title || context.name);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// src/babel-plugin/index.ts
|
|
293
|
+
function extractTextContent(children, types) {
|
|
294
|
+
const textParts = [];
|
|
295
|
+
for (const child of children) {
|
|
296
|
+
if (types.isJSXText(child)) {
|
|
297
|
+
const text = child.value.trim();
|
|
298
|
+
if (text) {
|
|
299
|
+
textParts.push(text);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
return textParts.length > 0 ? textParts.join(" ") : null;
|
|
304
|
+
}
|
|
305
|
+
function getAttributeValue(element, attrName, types) {
|
|
306
|
+
for (const attr of element.attributes) {
|
|
307
|
+
if (types.isJSXAttribute(attr) && types.isJSXIdentifier(attr.name)) {
|
|
308
|
+
if (attr.name.name === attrName) {
|
|
309
|
+
if (types.isStringLiteral(attr.value)) {
|
|
310
|
+
return attr.value.value;
|
|
311
|
+
}
|
|
312
|
+
if (types.isJSXExpressionContainer(attr.value)) {
|
|
313
|
+
if (types.isStringLiteral(attr.value.expression)) {
|
|
314
|
+
return attr.value.expression.value;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
return null;
|
|
321
|
+
}
|
|
322
|
+
function hasAttribute(element, attrName, types) {
|
|
323
|
+
return element.attributes.some(
|
|
324
|
+
(attr) => types.isJSXAttribute(attr) && types.isJSXIdentifier(attr.name) && attr.name.name === attrName
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
function addAttribute(element, name, value, types) {
|
|
328
|
+
element.attributes.push(
|
|
329
|
+
types.jsxAttribute(types.jsxIdentifier(name), types.stringLiteral(value))
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
function getTagName(element, types) {
|
|
333
|
+
if (types.isJSXIdentifier(element.name)) {
|
|
334
|
+
return element.name.name;
|
|
335
|
+
}
|
|
336
|
+
if (types.isJSXMemberExpression(element.name)) {
|
|
337
|
+
return null;
|
|
338
|
+
}
|
|
339
|
+
return null;
|
|
340
|
+
}
|
|
341
|
+
function isHtmlElement(tagName) {
|
|
342
|
+
return tagName[0] === tagName[0].toLowerCase();
|
|
343
|
+
}
|
|
344
|
+
function findComponentName(path) {
|
|
345
|
+
let current = path;
|
|
346
|
+
while (current) {
|
|
347
|
+
const parent = current.parentPath;
|
|
348
|
+
if (!parent) break;
|
|
349
|
+
if (parent.isFunctionDeclaration()) {
|
|
350
|
+
const name = parent.node.id?.name;
|
|
351
|
+
if (name && name[0] === name[0].toUpperCase()) {
|
|
352
|
+
return name;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
if (parent.isArrowFunctionExpression() || parent.isFunctionExpression()) {
|
|
356
|
+
const varDeclarator = parent.parentPath;
|
|
357
|
+
if (varDeclarator?.isVariableDeclarator()) {
|
|
358
|
+
const id = varDeclarator.node.id;
|
|
359
|
+
if (id && id.type === "Identifier") {
|
|
360
|
+
const name = id.name;
|
|
361
|
+
if (name[0] === name[0].toUpperCase()) {
|
|
362
|
+
return name;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
if (parent.isClassMethod()) {
|
|
368
|
+
const classDecl = parent.parentPath?.parentPath;
|
|
369
|
+
if (classDecl?.isClassDeclaration()) {
|
|
370
|
+
const name = classDecl.node.id?.name;
|
|
371
|
+
if (name) {
|
|
372
|
+
return name;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
current = parent;
|
|
377
|
+
}
|
|
378
|
+
return null;
|
|
379
|
+
}
|
|
380
|
+
var uiBridgeBabelPlugin = declare(
|
|
381
|
+
(api, options) => {
|
|
382
|
+
api.assertVersion(7);
|
|
383
|
+
const types = api.types;
|
|
384
|
+
const config = mergeConfig(options);
|
|
385
|
+
return {
|
|
386
|
+
name: "ui-bridge-babel-plugin",
|
|
387
|
+
pre(file) {
|
|
388
|
+
const filename = file.opts.filename || "unknown";
|
|
389
|
+
this.filename = filename;
|
|
390
|
+
this.config = config;
|
|
391
|
+
this.componentStack = [];
|
|
392
|
+
this.processed = /* @__PURE__ */ new Set();
|
|
393
|
+
resetFileCounters(filename);
|
|
394
|
+
if (config.verbose) {
|
|
395
|
+
console.log(`[ui-bridge-babel-plugin] Processing: ${filename}`);
|
|
396
|
+
}
|
|
397
|
+
},
|
|
398
|
+
visitor: {
|
|
399
|
+
JSXElement(path) {
|
|
400
|
+
if (!shouldProcessFile(this.filename, this.config)) {
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
const openingElement = path.node.openingElement;
|
|
404
|
+
const tagName = getTagName(openingElement, types);
|
|
405
|
+
if (!tagName || !isHtmlElement(tagName)) {
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
if (!this.config.elements.includes(tagName)) {
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
if (this.config.skipExisting && hasAttribute(openingElement, this.config.idAttribute, types)) {
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
const componentName = findComponentName(path);
|
|
415
|
+
if (this.config.onlyInComponents.length > 0) {
|
|
416
|
+
if (!componentName || !this.config.onlyInComponents.includes(componentName)) {
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
if (this.config.skipInComponents.length > 0) {
|
|
421
|
+
if (componentName && this.config.skipInComponents.includes(componentName)) {
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
const textContent = extractTextContent(path.node.children, types);
|
|
426
|
+
const ariaLabel = getAttributeValue(openingElement, "aria-label", types);
|
|
427
|
+
const placeholder = getAttributeValue(openingElement, "placeholder", types);
|
|
428
|
+
const title = getAttributeValue(openingElement, "title", types);
|
|
429
|
+
const name = getAttributeValue(openingElement, "name", types);
|
|
430
|
+
const existingId = getAttributeValue(openingElement, "id", types);
|
|
431
|
+
const elementIndex = getNextElementIndex(this.filename, tagName);
|
|
432
|
+
const idContext = {
|
|
433
|
+
componentName,
|
|
434
|
+
filePath: this.filename,
|
|
435
|
+
tagName,
|
|
436
|
+
textContent,
|
|
437
|
+
ariaLabel,
|
|
438
|
+
placeholder,
|
|
439
|
+
title,
|
|
440
|
+
elementIndex,
|
|
441
|
+
existingId
|
|
442
|
+
};
|
|
443
|
+
const generatedId = generateId(idContext, this.config);
|
|
444
|
+
if (this.processed.has(generatedId)) {
|
|
445
|
+
const uniqueId = `${generatedId}-${elementIndex}`;
|
|
446
|
+
addAttribute(openingElement, this.config.idAttribute, uniqueId, types);
|
|
447
|
+
} else {
|
|
448
|
+
this.processed.add(generatedId);
|
|
449
|
+
addAttribute(openingElement, this.config.idAttribute, generatedId, types);
|
|
450
|
+
}
|
|
451
|
+
const semanticType = getSemanticType(tagName, idContext);
|
|
452
|
+
addAttribute(openingElement, this.config.typeAttribute, semanticType, types);
|
|
453
|
+
const aliasContext = {
|
|
454
|
+
tagName,
|
|
455
|
+
textContent,
|
|
456
|
+
ariaLabel,
|
|
457
|
+
placeholder,
|
|
458
|
+
title,
|
|
459
|
+
name};
|
|
460
|
+
if (shouldGenerateAliases(aliasContext, this.config)) {
|
|
461
|
+
const aliases = generateAliases(aliasContext, this.config);
|
|
462
|
+
if (aliases.length > 0) {
|
|
463
|
+
addAttribute(
|
|
464
|
+
openingElement,
|
|
465
|
+
this.config.aliasesAttribute,
|
|
466
|
+
formatAliasesAttribute(aliases),
|
|
467
|
+
types
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
if (this.config.verbose) {
|
|
472
|
+
console.log(`[ui-bridge-babel-plugin] Instrumented <${tagName}> as "${generatedId}"`);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
},
|
|
476
|
+
post() {
|
|
477
|
+
if (this.config.verbose) {
|
|
478
|
+
console.log(`[ui-bridge-babel-plugin] Finished processing: ${this.filename}`);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
);
|
|
484
|
+
var babel_plugin_default = uiBridgeBabelPlugin;
|
|
485
|
+
|
|
486
|
+
export { DEFAULT_CONFIG, babel_plugin_default as default, extractComponentFromPath, formatAliasesAttribute, generateAliases, generateId, getNextElementIndex, getSemanticType, mergeConfig, resetFileCounters, shouldGenerateAliases, shouldProcessFile, uiBridgeBabelPlugin };
|
|
487
|
+
//# sourceMappingURL=index.mjs.map
|
|
488
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/babel-plugin/config.ts","../../src/babel-plugin/id-generator.ts","../../src/babel-plugin/alias-generator.ts","../../src/babel-plugin/index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Plugin Configuration\n *\n * Configuration options for the UI Bridge Babel plugin.\n */\n\n/**\n * Elements to instrument\n */\nexport type InstrumentableElement =\n | 'button'\n | 'input'\n | 'select'\n | 'textarea'\n | 'a'\n | 'form'\n | 'label'\n | 'img'\n | 'video'\n | 'audio'\n | 'dialog'\n | 'details'\n | 'summary'\n | 'nav'\n | 'header'\n | 'footer'\n | 'main'\n | 'aside'\n | 'section'\n | 'article';\n\n/**\n * Plugin configuration options\n */\nexport interface PluginConfig {\n /**\n * Include specific file patterns (glob)\n * @default ['**\\/*.tsx', '**\\/*.jsx']\n */\n include?: string[];\n\n /**\n * Exclude specific file patterns (glob)\n * @default ['**\\/node_modules/**', '**\\/*.test.*', '**\\/*.spec.*']\n */\n exclude?: string[];\n\n /**\n * Elements to automatically instrument\n * @default ['button', 'input', 'select', 'textarea', 'a', 'form']\n */\n elements?: InstrumentableElement[];\n\n /**\n * Prefix for generated IDs\n * @default 'ui'\n */\n idPrefix?: string;\n\n /**\n * Attribute name for the generated ID\n * @default 'data-ui-id'\n */\n idAttribute?: string;\n\n /**\n * Attribute name for aliases\n * @default 'data-ui-aliases'\n */\n aliasesAttribute?: string;\n\n /**\n * Attribute name for element type\n * @default 'data-ui-type'\n */\n typeAttribute?: string;\n\n /**\n * Generate aliases from text content\n * @default true\n */\n generateAliases?: boolean;\n\n /**\n * Include component name in generated ID\n * @default true\n */\n includeComponentName?: boolean;\n\n /**\n * Include file path in generated ID\n * @default false\n */\n includeFilePath?: boolean;\n\n /**\n * Hash the generated ID for shorter strings\n * @default false\n */\n hashIds?: boolean;\n\n /**\n * Maximum alias count per element\n * @default 5\n */\n maxAliases?: number;\n\n /**\n * Skip elements that already have data-ui-id\n * @default true\n */\n skipExisting?: boolean;\n\n /**\n * Only instrument elements inside components with specific names\n * @default []\n */\n onlyInComponents?: string[];\n\n /**\n * Skip instrumentation for elements inside these components\n * @default []\n */\n skipInComponents?: string[];\n\n /**\n * Enable verbose logging during build\n * @default false\n */\n verbose?: boolean;\n}\n\n/**\n * Default configuration\n */\nexport const DEFAULT_CONFIG: Required<PluginConfig> = {\n include: ['**/*.tsx', '**/*.jsx'],\n exclude: ['**/node_modules/**', '**/*.test.*', '**/*.spec.*', '**/*.stories.*'],\n elements: ['button', 'input', 'select', 'textarea', 'a', 'form'],\n idPrefix: 'ui',\n idAttribute: 'data-ui-id',\n aliasesAttribute: 'data-ui-aliases',\n typeAttribute: 'data-ui-type',\n generateAliases: true,\n includeComponentName: true,\n includeFilePath: false,\n hashIds: false,\n maxAliases: 5,\n skipExisting: true,\n onlyInComponents: [],\n skipInComponents: [],\n verbose: false,\n};\n\n/**\n * Merge user config with defaults\n */\nexport function mergeConfig(userConfig: PluginConfig = {}): Required<PluginConfig> {\n return {\n ...DEFAULT_CONFIG,\n ...userConfig,\n // Ensure arrays are properly merged\n include: userConfig.include ?? DEFAULT_CONFIG.include,\n exclude: userConfig.exclude ?? DEFAULT_CONFIG.exclude,\n elements: userConfig.elements ?? DEFAULT_CONFIG.elements,\n onlyInComponents: userConfig.onlyInComponents ?? DEFAULT_CONFIG.onlyInComponents,\n skipInComponents: userConfig.skipInComponents ?? DEFAULT_CONFIG.skipInComponents,\n };\n}\n\n/**\n * Check if a file should be processed based on include/exclude patterns\n */\nexport function shouldProcessFile(filename: string, config: Required<PluginConfig>): boolean {\n // Simple pattern matching (for full glob support, use micromatch)\n const matchPattern = (pattern: string, path: string): boolean => {\n // Simple extension-based matching for common patterns\n // **/*.tsx -> match any .tsx file\n // **/*.test.* -> match any file with .test. in name\n\n // Handle **/*.ext pattern (match files with extension anywhere)\n if (pattern.startsWith('**/')) {\n const restOfPattern = pattern.slice(3); // Remove **/\n\n // Handle **/dir/** patterns\n if (restOfPattern.includes('/**')) {\n const dir = restOfPattern.replace('/**', '');\n return path.includes('/' + dir + '/') || path.startsWith(dir + '/');\n }\n\n // Handle **/*.test.* or **/*.spec.* (files with .test. or .spec. in name)\n // Must check this BEFORE the simple extension check\n if (\n restOfPattern.startsWith('*.') &&\n restOfPattern.endsWith('.*') &&\n restOfPattern.length > 3\n ) {\n const middle = restOfPattern.slice(2, -2); // Get middle part like \"test\" or \"spec\"\n const fileName = path.includes('/') ? path.split('/').pop() || path : path;\n return fileName.includes('.' + middle + '.');\n }\n\n // Handle **/*.ext (any file with simple extension like .tsx, .jsx)\n if (restOfPattern.startsWith('*.') && !restOfPattern.slice(2).includes('*')) {\n const ext = restOfPattern.slice(1); // Get .ext part\n return path.endsWith(ext);\n }\n }\n\n // Fallback: exact match\n return path === pattern;\n };\n\n // Normalize path\n const normalizedPath = filename.replace(/\\\\/g, '/');\n\n // Check exclude patterns first\n for (const pattern of config.exclude) {\n if (matchPattern(pattern, normalizedPath)) {\n return false;\n }\n }\n\n // Check include patterns\n for (const pattern of config.include) {\n if (matchPattern(pattern, normalizedPath)) {\n return true;\n }\n }\n\n return false;\n}\n","/**\n * ID Generator\n *\n * Generates stable, unique IDs for UI elements based on component path,\n * element type, and content.\n */\n\nimport type { PluginConfig } from './config';\n\n/**\n * Context for generating element IDs\n */\nexport interface IdGeneratorContext {\n /** Component name */\n componentName: string | null;\n /** File path */\n filePath: string;\n /** Element tag name */\n tagName: string;\n /** Element text content */\n textContent: string | null;\n /** Aria label */\n ariaLabel: string | null;\n /** Placeholder text */\n placeholder: string | null;\n /** Title attribute */\n title: string | null;\n /** Element index in component (for uniqueness) */\n elementIndex: number;\n /** Existing id attribute */\n existingId: string | null;\n}\n\n/**\n * Simple hash function for ID generation\n */\nfunction simpleHash(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash; // Convert to 32bit integer\n }\n // Convert to positive hex string\n return Math.abs(hash).toString(16).substring(0, 8);\n}\n\n/**\n * Normalize text for use in ID\n */\nfunction normalizeForId(text: string): string {\n return (\n text\n .toLowerCase()\n .trim()\n // Replace non-alphanumeric with dash\n .replace(/[^a-z0-9]+/g, '-')\n // Remove leading/trailing dashes\n .replace(/^-+|-+$/g, '')\n // Collapse multiple dashes\n .replace(/-+/g, '-')\n // Limit length\n .substring(0, 30)\n );\n}\n\n/**\n * Extract component name from file path\n */\nexport function extractComponentFromPath(filePath: string): string | null {\n // Normalize path separators\n const normalized = filePath.replace(/\\\\/g, '/');\n\n // Get filename without extension\n const match = normalized.match(/\\/([^/]+)\\.(tsx?|jsx?)$/);\n if (!match) return null;\n\n const filename = match[1];\n\n // Skip index files\n if (filename === 'index') {\n // Try to get parent folder name\n const parentMatch = normalized.match(/\\/([^/]+)\\/index\\.(tsx?|jsx?)$/);\n if (parentMatch) {\n return normalizeForId(parentMatch[1]);\n }\n }\n\n return normalizeForId(filename);\n}\n\n/**\n * Get semantic type for element\n */\nexport function getSemanticType(tagName: string, context: IdGeneratorContext): string {\n const tag = tagName.toLowerCase();\n\n // Check for specific input types\n if (tag === 'input') {\n // Would need to check type attribute, for now just return 'input'\n return 'input';\n }\n\n // Check for specific button purposes\n if (tag === 'button') {\n const text = context.textContent?.toLowerCase() || '';\n if (text.includes('submit') || text.includes('save')) return 'submit-button';\n if (text.includes('cancel') || text.includes('close')) return 'cancel-button';\n if (text.includes('delete') || text.includes('remove')) return 'delete-button';\n return 'button';\n }\n\n // Map tags to semantic types\n const typeMap: Record<string, string> = {\n a: 'link',\n select: 'dropdown',\n textarea: 'textarea',\n form: 'form',\n nav: 'navigation',\n header: 'header',\n footer: 'footer',\n main: 'main',\n aside: 'sidebar',\n dialog: 'dialog',\n img: 'image',\n };\n\n return typeMap[tag] || tag;\n}\n\n/**\n * Generate a unique ID for an element\n */\nexport function generateId(context: IdGeneratorContext, config: Required<PluginConfig>): string {\n const parts: string[] = [];\n\n // Add prefix\n if (config.idPrefix) {\n parts.push(config.idPrefix);\n }\n\n // Add file path component\n if (config.includeFilePath) {\n const fileComponent = extractComponentFromPath(context.filePath);\n if (fileComponent) {\n parts.push(fileComponent);\n }\n }\n\n // Add component name\n if (config.includeComponentName && context.componentName) {\n parts.push(normalizeForId(context.componentName));\n }\n\n // Add descriptive part from text/aria/placeholder\n const descriptiveText =\n context.textContent ||\n context.ariaLabel ||\n context.placeholder ||\n context.title ||\n context.existingId;\n\n if (descriptiveText) {\n parts.push(normalizeForId(descriptiveText));\n }\n\n // Add semantic type\n const semanticType = getSemanticType(context.tagName, context);\n parts.push(semanticType);\n\n // Generate base ID\n let id = parts.filter(Boolean).join('-');\n\n // If ID is empty or too short, use index\n if (id.length < 5) {\n id = `${config.idPrefix}-${context.tagName}-${context.elementIndex}`;\n }\n\n // Hash if configured\n if (config.hashIds) {\n const hash = simpleHash(id + context.filePath + context.elementIndex);\n id = `${config.idPrefix}-${hash}`;\n }\n\n return id;\n}\n\n/**\n * Counter for element indices per file\n */\nconst fileElementCounters = new Map<string, Map<string, number>>();\n\n/**\n * Get next element index for a file/tag combination\n */\nexport function getNextElementIndex(filePath: string, tagName: string): number {\n if (!fileElementCounters.has(filePath)) {\n fileElementCounters.set(filePath, new Map());\n }\n\n const fileCounters = fileElementCounters.get(filePath)!;\n const current = fileCounters.get(tagName) || 0;\n fileCounters.set(tagName, current + 1);\n\n return current;\n}\n\n/**\n * Reset counters for a file (call at start of file processing)\n */\nexport function resetFileCounters(filePath: string): void {\n fileElementCounters.delete(filePath);\n}\n","/**\n * Alias Generator\n *\n * Generates search aliases from element text, aria labels, and other attributes.\n */\n\nimport type { PluginConfig } from './config';\n\n/**\n * Context for generating aliases\n */\nexport interface AliasGeneratorContext {\n /** Element tag name */\n tagName: string;\n /** Text content */\n textContent: string | null;\n /** Aria label */\n ariaLabel: string | null;\n /** Placeholder text */\n placeholder: string | null;\n /** Title attribute */\n title: string | null;\n /** Name attribute */\n name: string | null;\n /** ID attribute */\n id: string | null;\n}\n\n/**\n * Common word synonyms for UI actions\n */\nconst SYNONYMS: Record<string, string[]> = {\n submit: ['send', 'go', 'confirm', 'done', 'ok', 'apply'],\n cancel: ['close', 'dismiss', 'abort', 'back', 'exit'],\n delete: ['remove', 'trash', 'erase', 'clear'],\n edit: ['modify', 'change', 'update'],\n add: ['create', 'new', 'plus', 'insert'],\n save: ['store', 'keep', 'preserve'],\n search: ['find', 'lookup', 'query'],\n login: ['signin', 'sign in', 'log in'],\n logout: ['signout', 'sign out', 'log out'],\n register: ['signup', 'sign up', 'join'],\n next: ['continue', 'forward', 'proceed'],\n previous: ['back', 'prev', 'prior'],\n start: ['begin', 'launch', 'run'],\n stop: ['end', 'halt', 'pause'],\n upload: ['attach', 'import'],\n download: ['export', 'get'],\n settings: ['preferences', 'options', 'config'],\n help: ['support', 'info', 'about'],\n home: ['main', 'dashboard'],\n profile: ['account', 'user'],\n};\n\n/**\n * Normalize text for alias matching\n */\nfunction normalizeText(text: string): string {\n return text\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9\\s]/g, '')\n .replace(/\\s+/g, ' ');\n}\n\n/**\n * Tokenize text into words\n */\nfunction tokenize(text: string): string[] {\n return normalizeText(text)\n .split(' ')\n .filter((word) => word.length > 1);\n}\n\n/**\n * Get synonyms for a word\n */\nfunction getSynonyms(word: string): string[] {\n const normalized = word.toLowerCase();\n\n // Check if word is in synonyms\n if (SYNONYMS[normalized]) {\n return SYNONYMS[normalized];\n }\n\n // Check if word is a synonym of something\n for (const [key, values] of Object.entries(SYNONYMS)) {\n if (values.includes(normalized)) {\n return [key, ...values.filter((v) => v !== normalized)];\n }\n }\n\n return [];\n}\n\n/**\n * Generate n-grams from tokens\n */\nfunction generateNgrams(tokens: string[], n: number): string[] {\n const ngrams: string[] = [];\n\n for (let i = 0; i <= tokens.length - n; i++) {\n ngrams.push(tokens.slice(i, i + n).join(' '));\n }\n\n return ngrams;\n}\n\n/**\n * Generate aliases for an element\n */\nexport function generateAliases(\n context: AliasGeneratorContext,\n config: Required<PluginConfig>\n): string[] {\n const aliases = new Set<string>();\n\n // Add text content\n if (context.textContent) {\n const normalized = normalizeText(context.textContent);\n if (normalized) {\n aliases.add(normalized);\n\n // Add individual tokens\n const tokens = tokenize(context.textContent);\n for (const token of tokens) {\n if (token.length >= 3) {\n aliases.add(token);\n }\n\n // Add synonyms\n for (const synonym of getSynonyms(token)) {\n aliases.add(synonym);\n }\n }\n\n // Add bi-grams\n if (tokens.length >= 2) {\n for (const ngram of generateNgrams(tokens, 2)) {\n aliases.add(ngram);\n }\n }\n }\n }\n\n // Add aria label\n if (context.ariaLabel) {\n const normalized = normalizeText(context.ariaLabel);\n if (normalized) {\n aliases.add(normalized);\n }\n }\n\n // Add placeholder\n if (context.placeholder) {\n const normalized = normalizeText(context.placeholder);\n if (normalized) {\n aliases.add(normalized);\n }\n }\n\n // Add title\n if (context.title) {\n const normalized = normalizeText(context.title);\n if (normalized) {\n aliases.add(normalized);\n }\n }\n\n // Add name attribute (often semantic)\n if (context.name) {\n const normalized = normalizeText(context.name).replace(/-/g, ' ');\n if (normalized) {\n aliases.add(normalized);\n }\n }\n\n // Add element type\n const typeAlias = getElementTypeAlias(context.tagName);\n if (typeAlias) {\n aliases.add(typeAlias);\n }\n\n // Convert to array and limit\n const result = Array.from(aliases)\n .filter((alias) => alias.length >= 2 && alias.length <= 50)\n .slice(0, config.maxAliases);\n\n return result;\n}\n\n/**\n * Get type alias for element\n */\nfunction getElementTypeAlias(tagName: string): string | null {\n const tag = tagName.toLowerCase();\n\n const typeAliases: Record<string, string> = {\n button: 'button',\n input: 'input',\n select: 'dropdown',\n textarea: 'text area',\n a: 'link',\n form: 'form',\n nav: 'navigation',\n img: 'image',\n };\n\n return typeAliases[tag] || null;\n}\n\n/**\n * Format aliases for attribute value\n */\nexport function formatAliasesAttribute(aliases: string[]): string {\n return aliases.join(',');\n}\n\n/**\n * Determine if aliases should be generated for this element\n */\nexport function shouldGenerateAliases(\n context: AliasGeneratorContext,\n config: Required<PluginConfig>\n): boolean {\n if (!config.generateAliases) {\n return false;\n }\n\n // Need at least some content to generate aliases\n return !!(\n context.textContent ||\n context.ariaLabel ||\n context.placeholder ||\n context.title ||\n context.name\n );\n}\n","/**\n * UI Bridge Babel Plugin\n *\n * Automatically instruments React components with UI Bridge IDs and aliases.\n *\n * @example\n * ```js\n * // babel.config.js\n * module.exports = {\n * plugins: [\n * ['@qontinui/ui-bridge/babel-plugin', {\n * elements: ['button', 'input', 'a'],\n * idPrefix: 'ui',\n * }]\n * ]\n * };\n * ```\n *\n * @example\n * ```jsx\n * // Input\n * <button onClick={handleSubmit}>Submit</button>\n *\n * // Output\n * <button\n * onClick={handleSubmit}\n * data-ui-id=\"ui-component-submit-button\"\n * data-ui-aliases=\"submit,send,go,confirm\"\n * data-ui-type=\"button\"\n * >\n * Submit\n * </button>\n * ```\n */\n\nimport { declare } from '@babel/helper-plugin-utils';\nimport type { PluginObj, NodePath, BabelFile } from '@babel/core';\nimport type * as t from '@babel/types';\nimport { type PluginConfig, mergeConfig, shouldProcessFile } from './config';\nimport {\n generateId,\n getNextElementIndex,\n resetFileCounters,\n getSemanticType,\n type IdGeneratorContext,\n} from './id-generator';\nimport {\n generateAliases,\n formatAliasesAttribute,\n shouldGenerateAliases,\n type AliasGeneratorContext,\n} from './alias-generator';\n\nexport type { PluginConfig } from './config';\n\n/**\n * State tracked during file transformation\n */\ninterface PluginState {\n filename: string;\n config: Required<PluginConfig>;\n componentStack: string[];\n processed: Set<string>;\n}\n\n/**\n * Extract text content from JSX children\n */\nfunction extractTextContent(\n children: (\n | t.JSXElement\n | t.JSXText\n | t.JSXExpressionContainer\n | t.JSXSpreadChild\n | t.JSXFragment\n )[],\n types: typeof t\n): string | null {\n const textParts: string[] = [];\n\n for (const child of children) {\n if (types.isJSXText(child)) {\n const text = child.value.trim();\n if (text) {\n textParts.push(text);\n }\n }\n }\n\n return textParts.length > 0 ? textParts.join(' ') : null;\n}\n\n/**\n * Get attribute value from JSX element\n */\nfunction getAttributeValue(\n element: t.JSXOpeningElement,\n attrName: string,\n types: typeof t\n): string | null {\n for (const attr of element.attributes) {\n if (types.isJSXAttribute(attr) && types.isJSXIdentifier(attr.name)) {\n if (attr.name.name === attrName) {\n if (types.isStringLiteral(attr.value)) {\n return attr.value.value;\n }\n if (types.isJSXExpressionContainer(attr.value)) {\n if (types.isStringLiteral(attr.value.expression)) {\n return attr.value.expression.value;\n }\n }\n }\n }\n }\n return null;\n}\n\n/**\n * Check if element has a specific attribute\n */\nfunction hasAttribute(element: t.JSXOpeningElement, attrName: string, types: typeof t): boolean {\n return element.attributes.some(\n (attr) =>\n types.isJSXAttribute(attr) && types.isJSXIdentifier(attr.name) && attr.name.name === attrName\n );\n}\n\n/**\n * Add attribute to JSX element\n */\nfunction addAttribute(\n element: t.JSXOpeningElement,\n name: string,\n value: string,\n types: typeof t\n): void {\n element.attributes.push(\n types.jsxAttribute(types.jsxIdentifier(name), types.stringLiteral(value))\n );\n}\n\n/**\n * Get tag name from JSX element\n */\nfunction getTagName(element: t.JSXOpeningElement, types: typeof t): string | null {\n if (types.isJSXIdentifier(element.name)) {\n return element.name.name;\n }\n if (types.isJSXMemberExpression(element.name)) {\n // Handle Component.SubComponent\n return null; // Skip member expressions\n }\n return null;\n}\n\n/**\n * Check if tag is a lowercase HTML element (not a React component)\n */\nfunction isHtmlElement(tagName: string): boolean {\n return tagName[0] === tagName[0].toLowerCase();\n}\n\n/**\n * Find parent component name\n */\nfunction findComponentName(path: NodePath<t.JSXElement>): string | null {\n let current: NodePath<t.Node> | null = path as NodePath<t.Node>;\n\n while (current) {\n const parent: NodePath<t.Node> | null = current.parentPath;\n\n if (!parent) break;\n\n // Check for function declaration\n if (parent.isFunctionDeclaration()) {\n const name = (parent.node as t.FunctionDeclaration).id?.name;\n if (name && name[0] === name[0].toUpperCase()) {\n return name;\n }\n }\n\n // Check for variable declarator with arrow function\n if (parent.isArrowFunctionExpression() || parent.isFunctionExpression()) {\n const varDeclarator = parent.parentPath;\n if (varDeclarator?.isVariableDeclarator()) {\n const id = (varDeclarator.node as t.VariableDeclarator).id;\n if (id && id.type === 'Identifier') {\n const name = id.name;\n if (name[0] === name[0].toUpperCase()) {\n return name;\n }\n }\n }\n }\n\n // Check for class method (render)\n if (parent.isClassMethod()) {\n const classDecl = parent.parentPath?.parentPath;\n if (classDecl?.isClassDeclaration()) {\n const name = (classDecl.node as t.ClassDeclaration).id?.name;\n if (name) {\n return name;\n }\n }\n }\n\n current = parent;\n }\n\n return null;\n}\n\n/**\n * Babel API interface\n */\ninterface BabelAPI {\n assertVersion(version: number): void;\n types: typeof t;\n}\n\n/**\n * The Babel plugin\n */\nconst uiBridgeBabelPlugin = declare<PluginConfig, PluginObj<PluginState>>(\n (api: BabelAPI, options: PluginConfig) => {\n api.assertVersion(7);\n\n const types = api.types;\n const config = mergeConfig(options);\n\n return {\n name: 'ui-bridge-babel-plugin',\n\n pre(this: PluginState, file: BabelFile) {\n const filename = file.opts.filename || 'unknown';\n this.filename = filename;\n this.config = config;\n this.componentStack = [];\n this.processed = new Set();\n\n // Reset element counters for this file\n resetFileCounters(filename);\n\n if (config.verbose) {\n console.log(`[ui-bridge-babel-plugin] Processing: ${filename}`);\n }\n },\n\n visitor: {\n JSXElement(this: PluginState, path: NodePath<t.JSXElement>) {\n // Check if file should be processed\n if (!shouldProcessFile(this.filename, this.config)) {\n return;\n }\n\n const openingElement = path.node.openingElement;\n const tagName = getTagName(openingElement, types);\n\n // Skip if no tag name or not an HTML element\n if (!tagName || !isHtmlElement(tagName)) {\n return;\n }\n\n // Check if this element type should be instrumented\n if (!this.config.elements.includes(tagName as any)) {\n return;\n }\n\n // Skip if already has ui-id (unless configured otherwise)\n if (\n this.config.skipExisting &&\n hasAttribute(openingElement, this.config.idAttribute, types)\n ) {\n return;\n }\n\n // Find component name\n const componentName = findComponentName(path);\n\n // Check component filters\n if (this.config.onlyInComponents.length > 0) {\n if (!componentName || !this.config.onlyInComponents.includes(componentName)) {\n return;\n }\n }\n\n if (this.config.skipInComponents.length > 0) {\n if (componentName && this.config.skipInComponents.includes(componentName)) {\n return;\n }\n }\n\n // Extract element info\n const textContent = extractTextContent(path.node.children as any[], types);\n const ariaLabel = getAttributeValue(openingElement, 'aria-label', types);\n const placeholder = getAttributeValue(openingElement, 'placeholder', types);\n const title = getAttributeValue(openingElement, 'title', types);\n const name = getAttributeValue(openingElement, 'name', types);\n const existingId = getAttributeValue(openingElement, 'id', types);\n\n // Get element index for uniqueness\n const elementIndex = getNextElementIndex(this.filename, tagName);\n\n // Build context for ID generation\n const idContext: IdGeneratorContext = {\n componentName,\n filePath: this.filename,\n tagName,\n textContent,\n ariaLabel,\n placeholder,\n title,\n elementIndex,\n existingId,\n };\n\n // Generate ID\n const generatedId = generateId(idContext, this.config);\n\n // Skip if this exact ID was already generated (collision)\n if (this.processed.has(generatedId)) {\n // Add index suffix for uniqueness\n const uniqueId = `${generatedId}-${elementIndex}`;\n addAttribute(openingElement, this.config.idAttribute, uniqueId, types);\n } else {\n this.processed.add(generatedId);\n addAttribute(openingElement, this.config.idAttribute, generatedId, types);\n }\n\n // Add element type\n const semanticType = getSemanticType(tagName, idContext);\n addAttribute(openingElement, this.config.typeAttribute, semanticType, types);\n\n // Generate and add aliases\n const aliasContext: AliasGeneratorContext = {\n tagName,\n textContent,\n ariaLabel,\n placeholder,\n title,\n name,\n id: existingId,\n };\n\n if (shouldGenerateAliases(aliasContext, this.config)) {\n const aliases = generateAliases(aliasContext, this.config);\n if (aliases.length > 0) {\n addAttribute(\n openingElement,\n this.config.aliasesAttribute,\n formatAliasesAttribute(aliases),\n types\n );\n }\n }\n\n if (this.config.verbose) {\n console.log(`[ui-bridge-babel-plugin] Instrumented <${tagName}> as \"${generatedId}\"`);\n }\n },\n },\n\n post(this: PluginState) {\n if (this.config.verbose) {\n console.log(`[ui-bridge-babel-plugin] Finished processing: ${this.filename}`);\n }\n },\n };\n }\n);\n\nexport default uiBridgeBabelPlugin;\n\n// Named export for ESM compatibility\nexport { uiBridgeBabelPlugin };\n\n// Re-export utilities for advanced usage\nexport { mergeConfig, shouldProcessFile, DEFAULT_CONFIG } from './config';\nexport {\n generateId,\n getSemanticType,\n extractComponentFromPath,\n resetFileCounters,\n getNextElementIndex,\n type IdGeneratorContext,\n} from './id-generator';\nexport {\n generateAliases,\n formatAliasesAttribute,\n shouldGenerateAliases,\n type AliasGeneratorContext,\n} from './alias-generator';\n"]}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { n as BrowserCaptureConfig, Q as OnBrowserEventCallback, h as AnyCapturedEvent, p as BrowserEventType, C as CapturedError } from './types-suaYwWWg.mjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Browser Event Capture Orchestrator
|
|
5
|
+
*
|
|
6
|
+
* Single entry point that delegates to focused sub-modules.
|
|
7
|
+
* Replaces the old ConsoleCapture class with unified event capture.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
declare class BrowserEventCapture {
|
|
11
|
+
private buffer;
|
|
12
|
+
private maxEntries;
|
|
13
|
+
private installed;
|
|
14
|
+
private cleanups;
|
|
15
|
+
private onEvent;
|
|
16
|
+
private config;
|
|
17
|
+
constructor(config?: BrowserCaptureConfig);
|
|
18
|
+
setOnEvent(cb: OnBrowserEventCallback | null): void;
|
|
19
|
+
/**
|
|
20
|
+
* Install all enabled capture sub-modules.
|
|
21
|
+
* Safe to call multiple times (no-ops if already installed).
|
|
22
|
+
*/
|
|
23
|
+
install(): void;
|
|
24
|
+
/**
|
|
25
|
+
* Uninstall all capture sub-modules.
|
|
26
|
+
*/
|
|
27
|
+
uninstall(): void;
|
|
28
|
+
reportReactError(error: Error, errorInfo: {
|
|
29
|
+
componentStack?: string;
|
|
30
|
+
}): void;
|
|
31
|
+
reportWsStateChange(prev: string, next: string, reconnectAttempt?: number): void;
|
|
32
|
+
getSince(ts: number): AnyCapturedEvent[];
|
|
33
|
+
getRecent(n?: number): AnyCapturedEvent[];
|
|
34
|
+
getByType(type: BrowserEventType): AnyCapturedEvent[];
|
|
35
|
+
/**
|
|
36
|
+
* Get console errors since a timestamp (backward-compat for ActionExecutor).
|
|
37
|
+
*/
|
|
38
|
+
getConsoleSince(ts: number): CapturedError[];
|
|
39
|
+
/**
|
|
40
|
+
* Get recent console errors (backward-compat for ActionExecutor).
|
|
41
|
+
*/
|
|
42
|
+
getConsoleRecent(n?: number): CapturedError[];
|
|
43
|
+
clear(): void;
|
|
44
|
+
private trim;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export { BrowserEventCapture as B };
|