@fragments-sdk/mcp 0.9.0 → 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -30016,8 +30016,8 @@ var require_traverseForScope = __commonJS({
30016
30016
  _context._forceSetScope.call(path2);
30017
30017
  const visitor = exploded[node.type];
30018
30018
  if (visitor != null && visitor.enter) {
30019
- for (const visit of visitor.enter) {
30020
- visit.call(state, path2, state);
30019
+ for (const visit2 of visitor.enter) {
30020
+ visit2.call(state, path2, state);
30021
30021
  }
30022
30022
  }
30023
30023
  if (path2.shouldSkip) {
@@ -30040,8 +30040,8 @@ var require_traverseForScope = __commonJS({
30040
30040
  }
30041
30041
  }
30042
30042
  if (visitor != null && visitor.exit) {
30043
- for (const visit of visitor.exit) {
30044
- visit.call(state, path2, state);
30043
+ for (const visit2 of visitor.exit) {
30044
+ visit2.call(state, path2, state);
30045
30045
  }
30046
30046
  }
30047
30047
  }
@@ -30946,8 +30946,8 @@ var require_scope = __commonJS({
30946
30946
  if (path.type !== "Program") {
30947
30947
  const typeVisitors = scopeVisitor[path.type];
30948
30948
  if (typeVisitors) {
30949
- for (const visit of typeVisitors.enter) {
30950
- visit.call(state, path, state);
30949
+ for (const visit2 of typeVisitors.enter) {
30950
+ visit2.call(state, path, state);
30951
30951
  }
30952
30952
  }
30953
30953
  }
@@ -31338,7 +31338,7 @@ var require_sourcemap_codec_umd = __commonJS({
31338
31338
  intToChar[i] = c;
31339
31339
  charToInt[c] = i;
31340
31340
  }
31341
- function decodeInteger(reader, relative) {
31341
+ function decodeInteger(reader, relative2) {
31342
31342
  let value = 0;
31343
31343
  let shift = 0;
31344
31344
  let integer = 0;
@@ -31353,10 +31353,10 @@ var require_sourcemap_codec_umd = __commonJS({
31353
31353
  if (shouldNegate) {
31354
31354
  value = -2147483648 | -value;
31355
31355
  }
31356
- return relative + value;
31356
+ return relative2 + value;
31357
31357
  }
31358
- function encodeInteger(builder, num, relative) {
31359
- let delta = num - relative;
31358
+ function encodeInteger(builder, num, relative2) {
31359
+ let delta = num - relative2;
31360
31360
  delta = delta < 0 ? -delta << 1 | 1 : delta << 1;
31361
31361
  do {
31362
31362
  let clamped = delta & 31;
@@ -31861,7 +31861,7 @@ var require_resolve_uri_umd = __commonJS({
31861
31861
  }
31862
31862
  url.path = path;
31863
31863
  }
31864
- function resolve4(input, base) {
31864
+ function resolve5(input, base) {
31865
31865
  if (!input && !base)
31866
31866
  return "";
31867
31867
  const url = parseUrl(input);
@@ -31914,7 +31914,7 @@ var require_resolve_uri_umd = __commonJS({
31914
31914
  return url.scheme + "//" + url.user + url.host + url.port + url.path + queryHash;
31915
31915
  }
31916
31916
  }
31917
- return resolve4;
31917
+ return resolve5;
31918
31918
  }));
31919
31919
  }
31920
31920
  });
@@ -32260,8 +32260,8 @@ var require_trace_mapping_umd = __commonJS({
32260
32260
  this.sources = sources;
32261
32261
  this.sourcesContent = sourcesContent;
32262
32262
  this.ignoreList = parsed.ignoreList || parsed.x_google_ignoreList || void 0;
32263
- const resolve4 = resolver(mapUrl, sourceRoot);
32264
- this.resolvedSources = sources.map(resolve4);
32263
+ const resolve5 = resolver(mapUrl, sourceRoot);
32264
+ this.resolvedSources = sources.map(resolve5);
32265
32265
  const { mappings } = parsed;
32266
32266
  if (typeof mappings === "string") {
32267
32267
  this._encoded = mappings;
@@ -55555,7 +55555,7 @@ var require_introspection = __commonJS({
55555
55555
  exports.isStatic = isStatic;
55556
55556
  exports.matchesPattern = matchesPattern;
55557
55557
  exports.referencesImport = referencesImport;
55558
- exports.resolve = resolve4;
55558
+ exports.resolve = resolve5;
55559
55559
  exports.willIMaybeExecuteBefore = willIMaybeExecuteBefore;
55560
55560
  var _t = require_lib4();
55561
55561
  var {
@@ -55813,7 +55813,7 @@ var require_introspection = __commonJS({
55813
55813
  nodeMap.set(target.node, result);
55814
55814
  return result;
55815
55815
  }
55816
- function resolve4(dangerous, resolved) {
55816
+ function resolve5(dangerous, resolved) {
55817
55817
  return _resolve.call(this, dangerous, resolved) || this;
55818
55818
  }
55819
55819
  function _resolve(dangerous, resolved) {
@@ -56846,7 +56846,7 @@ var require_context2 = __commonJS({
56846
56846
  exports.skip = skip;
56847
56847
  exports.skipKey = skipKey;
56848
56848
  exports.stop = stop;
56849
- exports.visit = visit;
56849
+ exports.visit = visit2;
56850
56850
  var _traverseNode = require_traverse_node();
56851
56851
  var _index = require_path();
56852
56852
  var _removal = require_removal();
@@ -56894,7 +56894,7 @@ var require_context2 = __commonJS({
56894
56894
  path.opts = context.opts;
56895
56895
  }
56896
56896
  }
56897
- function visit() {
56897
+ function visit2() {
56898
56898
  var _this$opts$shouldSkip, _this$opts;
56899
56899
  if (!this.node) {
56900
56900
  return false;
@@ -57199,6 +57199,11 @@ import {
57199
57199
  import {
57200
57200
  makeTailwindTokenResolvedFact
57201
57201
  } from "@fragments-sdk/core";
57202
+ import { createHash } from "crypto";
57203
+ import ts4 from "typescript";
57204
+ import { existsSync as existsSync4 } from "fs";
57205
+ import { dirname as dirname4, isAbsolute, relative, resolve as resolve4 } from "path";
57206
+ import ts3 from "typescript";
57202
57207
  var require2 = __banner_createRequire(import.meta.url);
57203
57208
  function createComponentExtractor(tsconfigPath) {
57204
57209
  let projectVersion = 0;
@@ -59032,7 +59037,7 @@ function handleAttributeValue(attr, ctx) {
59032
59037
  function handleExpression(expr, ctx, fallbackLocation, exprContext, origin = "attribute") {
59033
59038
  const acc = [];
59034
59039
  let emittedDynamic = false;
59035
- const visit = (node) => {
59040
+ const visit2 = (node) => {
59036
59041
  if (t2.isStringLiteral(node)) {
59037
59042
  acc.push(...splitClassString(node.value));
59038
59043
  return;
@@ -59115,7 +59120,7 @@ function handleExpression(expr, ctx, fallbackLocation, exprContext, origin = "at
59115
59120
  emittedDynamic = true;
59116
59121
  emitOpaque(ctx, node, fallbackLocation);
59117
59122
  };
59118
- visit(expr);
59123
+ visit2(expr);
59119
59124
  if (exprContext === "attribute" && acc.length > 0) {
59120
59125
  emitLiteral(ctx, origin, acc, locFromNode(expr, ctx.file) ?? fallbackLocation);
59121
59126
  }
@@ -60239,6 +60244,703 @@ function summarizeCallSites(callSites) {
60239
60244
  function compareCallSites(a, b) {
60240
60245
  return String(a.componentId).localeCompare(String(b.componentId)) || a.filePath.localeCompare(b.filePath) || a.line - b.line || a.column - b.column || a.nodePath.localeCompare(b.nodePath);
60241
60246
  }
60247
+ var HASH_LENGTH = 16;
60248
+ function ucfId(filePath, componentName, framework, sourceCommit) {
60249
+ const key = `${framework}|${filePath}|${componentName}|${sourceCommit}`;
60250
+ return createHash("sha256").update(key).digest("hex").slice(0, HASH_LENGTH);
60251
+ }
60252
+ var MAX_ROOT_BRANCHES = 4;
60253
+ var MAX_CLASSNAMES = 64;
60254
+ var REACT_HOOK_STATE = /* @__PURE__ */ new Set(["useState", "useReducer"]);
60255
+ var REACT_HOOK_EFFECT = /* @__PURE__ */ new Set(["useEffect", "useLayoutEffect", "useInsertionEffect"]);
60256
+ var WRAPPER_NAMES = /* @__PURE__ */ new Set([
60257
+ "forwardRef",
60258
+ "memo",
60259
+ "observer",
60260
+ "styled"
60261
+ ]);
60262
+ function mapDefinitionKind(declaration) {
60263
+ if (ts3.isClassDeclaration(declaration) || ts3.isClassExpression(declaration)) {
60264
+ return { kind: "class", wrappedBy: [], inner: declaration };
60265
+ }
60266
+ if (ts3.isFunctionDeclaration(declaration)) {
60267
+ return { kind: "function", wrappedBy: [], inner: declaration };
60268
+ }
60269
+ if (ts3.isArrowFunction(declaration) || ts3.isFunctionExpression(declaration)) {
60270
+ return { kind: "function", wrappedBy: [], inner: declaration };
60271
+ }
60272
+ if (ts3.isCallExpression(declaration)) {
60273
+ const wrappedBy = [];
60274
+ let cursor = declaration;
60275
+ while (ts3.isCallExpression(cursor)) {
60276
+ const name = getCalleeName(cursor.expression);
60277
+ if (name && WRAPPER_NAMES.has(name)) {
60278
+ wrappedBy.push(name);
60279
+ const first = cursor.arguments[0];
60280
+ if (!first) break;
60281
+ cursor = first;
60282
+ } else {
60283
+ break;
60284
+ }
60285
+ }
60286
+ if (wrappedBy.length > 0) {
60287
+ return { kind: "wrapper", wrappedBy, inner: cursor };
60288
+ }
60289
+ }
60290
+ return { kind: "function", wrappedBy: [], inner: null };
60291
+ }
60292
+ function getCalleeName(expr) {
60293
+ if (ts3.isIdentifier(expr)) return expr.text;
60294
+ if (ts3.isPropertyAccessExpression(expr)) return expr.name.text;
60295
+ return null;
60296
+ }
60297
+ function mapImports(sourceFile) {
60298
+ const records = [];
60299
+ for (const stmt of sourceFile.statements) {
60300
+ if (!ts3.isImportDeclaration(stmt)) continue;
60301
+ if (!ts3.isStringLiteral(stmt.moduleSpecifier)) continue;
60302
+ const moduleSpecifier = stmt.moduleSpecifier.text;
60303
+ const importedNames = [];
60304
+ if (stmt.importClause) {
60305
+ if (stmt.importClause.name) {
60306
+ importedNames.push({
60307
+ imported: "default",
60308
+ local: stmt.importClause.name.text
60309
+ });
60310
+ }
60311
+ const bindings = stmt.importClause.namedBindings;
60312
+ if (bindings) {
60313
+ if (ts3.isNamespaceImport(bindings)) {
60314
+ importedNames.push({
60315
+ imported: "*",
60316
+ local: bindings.name.text
60317
+ });
60318
+ } else if (ts3.isNamedImports(bindings)) {
60319
+ for (const element of bindings.elements) {
60320
+ importedNames.push({
60321
+ imported: element.propertyName?.text ?? element.name.text,
60322
+ local: element.name.text
60323
+ });
60324
+ }
60325
+ }
60326
+ }
60327
+ }
60328
+ records.push({
60329
+ moduleSpecifier,
60330
+ resolvedPackage: resolvePackageName(moduleSpecifier),
60331
+ importedNames
60332
+ });
60333
+ }
60334
+ return records;
60335
+ }
60336
+ function resolvePackageName(spec) {
60337
+ if (spec.startsWith(".") || spec.startsWith("/")) return void 0;
60338
+ if (spec.startsWith("@")) {
60339
+ const parts = spec.split("/");
60340
+ return parts.length >= 2 ? `${parts[0]}/${parts[1]}` : spec;
60341
+ }
60342
+ return spec.split("/")[0];
60343
+ }
60344
+ function mapFileExports(sourceFile) {
60345
+ const seen = /* @__PURE__ */ new Set();
60346
+ const exportNames = [];
60347
+ function add(name) {
60348
+ if (seen.has(name)) return;
60349
+ seen.add(name);
60350
+ exportNames.push(name);
60351
+ }
60352
+ for (const stmt of sourceFile.statements) {
60353
+ if (ts3.isVariableStatement(stmt) && hasExportModifier(stmt)) {
60354
+ for (const decl of stmt.declarationList.declarations) {
60355
+ if (ts3.isIdentifier(decl.name)) add(decl.name.text);
60356
+ }
60357
+ } else if (ts3.isFunctionDeclaration(stmt) && hasExportModifier(stmt) && stmt.name) {
60358
+ add(stmt.name.text);
60359
+ } else if (ts3.isClassDeclaration(stmt) && hasExportModifier(stmt) && stmt.name) {
60360
+ add(stmt.name.text);
60361
+ } else if (ts3.isExportAssignment(stmt)) {
60362
+ add("default");
60363
+ } else if (ts3.isExportDeclaration(stmt) && stmt.exportClause) {
60364
+ if (ts3.isNamedExports(stmt.exportClause)) {
60365
+ for (const element of stmt.exportClause.elements) {
60366
+ add(element.name.text);
60367
+ }
60368
+ }
60369
+ }
60370
+ }
60371
+ const baseName = sourceFile.fileName.split("/").pop() ?? "";
60372
+ const exportedFromBarrel = /^index\.(t|j)sx?$/.test(baseName);
60373
+ return { exportNames, exportedFromBarrel };
60374
+ }
60375
+ function hasExportModifier(node) {
60376
+ const modifiers = ts3.canHaveModifiers(node) ? ts3.getModifiers(node) : void 0;
60377
+ return modifiers?.some((m) => m.kind === ts3.SyntaxKind.ExportKeyword) ?? false;
60378
+ }
60379
+ function mapRootElements(inner) {
60380
+ if (!inner) return { rootElements: [], rootElementsTruncated: false };
60381
+ const branches = [];
60382
+ collectReturnedJsx(inner, branches, void 0);
60383
+ let truncated = false;
60384
+ if (branches.length > MAX_ROOT_BRANCHES) {
60385
+ truncated = true;
60386
+ branches.length = MAX_ROOT_BRANCHES;
60387
+ }
60388
+ const rootElements = branches.map(({ jsx, guard }) => toRootElementFact(jsx, guard));
60389
+ return { rootElements, rootElementsTruncated: truncated };
60390
+ }
60391
+ function collectReturnedJsx(node, acc, guard) {
60392
+ if (!node) return;
60393
+ if (ts3.isReturnStatement(node)) {
60394
+ if (node.expression) collectFromExpression(node.expression, acc, guard);
60395
+ return;
60396
+ }
60397
+ if (ts3.isArrowFunction(node) && !ts3.isBlock(node.body)) {
60398
+ collectFromExpression(node.body, acc, guard);
60399
+ return;
60400
+ }
60401
+ if (ts3.isIfStatement(node)) {
60402
+ const thenGuard = node.expression.getText();
60403
+ walk(node.thenStatement, acc, combineGuards(guard, thenGuard));
60404
+ if (node.elseStatement) {
60405
+ walk(node.elseStatement, acc, combineGuards(guard, `!(${thenGuard})`));
60406
+ }
60407
+ return;
60408
+ }
60409
+ ts3.forEachChild(node, (child) => walk(child, acc, guard));
60410
+ }
60411
+ function walk(node, acc, guard) {
60412
+ if (acc.length >= MAX_ROOT_BRANCHES + 1) return;
60413
+ collectReturnedJsx(node, acc, guard);
60414
+ }
60415
+ function collectFromExpression(expr, acc, guard) {
60416
+ if (acc.length >= MAX_ROOT_BRANCHES + 1) return;
60417
+ const stripped = stripParens(expr);
60418
+ if (ts3.isConditionalExpression(stripped)) {
60419
+ const condText = stripped.condition.getText();
60420
+ collectFromExpression(stripped.whenTrue, acc, combineGuards(guard, condText));
60421
+ collectFromExpression(stripped.whenFalse, acc, combineGuards(guard, `!(${condText})`));
60422
+ return;
60423
+ }
60424
+ if (ts3.isBinaryExpression(stripped) && stripped.operatorToken.kind === ts3.SyntaxKind.AmpersandAmpersandToken) {
60425
+ const condText = stripped.left.getText();
60426
+ collectFromExpression(stripped.right, acc, combineGuards(guard, condText));
60427
+ return;
60428
+ }
60429
+ if (ts3.isJsxElement(stripped) || ts3.isJsxSelfClosingElement(stripped)) {
60430
+ const opening = ts3.isJsxElement(stripped) ? stripped.openingElement : stripped;
60431
+ acc.push({ jsx: opening, guard });
60432
+ return;
60433
+ }
60434
+ if (ts3.isJsxFragment(stripped)) {
60435
+ acc.push({ jsx: stripped, guard });
60436
+ return;
60437
+ }
60438
+ }
60439
+ function stripParens(expr) {
60440
+ while (ts3.isParenthesizedExpression(expr) || ts3.isAsExpression(expr)) {
60441
+ expr = expr.expression;
60442
+ }
60443
+ return expr;
60444
+ }
60445
+ function combineGuards(prev, next) {
60446
+ return prev ? `${prev} && ${next}` : next;
60447
+ }
60448
+ function toRootElementFact(jsx, guard) {
60449
+ if (ts3.isJsxFragment(jsx)) {
60450
+ return { tag: "Fragment", attrs: {}, conditionalGuard: guard };
60451
+ }
60452
+ const tagName = jsx.tagName.getText();
60453
+ const isHtml = /^[a-z]/.test(tagName);
60454
+ const tag = isHtml ? tagName : `Custom:${tagName}`;
60455
+ const attrs = {};
60456
+ let inputType;
60457
+ for (const attr of jsx.attributes.properties) {
60458
+ if (!ts3.isJsxAttribute(attr)) continue;
60459
+ const name = attr.name.getText();
60460
+ const value = readAttrValue(attr);
60461
+ if (value !== void 0) attrs[name] = value;
60462
+ if (name === "type" && tag === "input" && typeof value === "string") {
60463
+ inputType = value;
60464
+ }
60465
+ }
60466
+ const fact = { tag, attrs };
60467
+ if (inputType) fact.inputType = inputType;
60468
+ if (guard) fact.conditionalGuard = guard;
60469
+ return fact;
60470
+ }
60471
+ function readAttrValue(attr) {
60472
+ if (!attr.initializer) return true;
60473
+ if (ts3.isStringLiteral(attr.initializer)) return attr.initializer.text;
60474
+ if (ts3.isJsxExpression(attr.initializer) && attr.initializer.expression) {
60475
+ const inner = attr.initializer.expression;
60476
+ if (ts3.isStringLiteral(inner) || ts3.isNoSubstitutionTemplateLiteral(inner)) {
60477
+ return inner.text;
60478
+ }
60479
+ }
60480
+ return void 0;
60481
+ }
60482
+ function mapAria(rootElements) {
60483
+ const roles = /* @__PURE__ */ new Set();
60484
+ const attributes = {};
60485
+ for (const root of rootElements) {
60486
+ for (const [key, value] of Object.entries(root.attrs)) {
60487
+ if (key === "role" && typeof value === "string") roles.add(value);
60488
+ if (key.startsWith("aria-")) attributes[key] = value;
60489
+ }
60490
+ }
60491
+ return { ariaRoles: [...roles], ariaAttributes: attributes };
60492
+ }
60493
+ function mapProps(inner, checker) {
60494
+ if (!inner) return [];
60495
+ const propsType = resolvePropsType(inner, checker);
60496
+ if (!propsType) return [];
60497
+ const defaults = collectDestructuredDefaults(inner);
60498
+ const facts = [];
60499
+ const ownerSourceFile = inner.getSourceFile();
60500
+ for (const symbol of propsType.getProperties()) {
60501
+ const decl = symbol.getDeclarations()?.[0];
60502
+ if (decl && !isUserDeclaration(decl, ownerSourceFile)) continue;
60503
+ const declNode = decl ?? inner;
60504
+ const propType = checker.getTypeOfSymbolAtLocation(symbol, declNode);
60505
+ const optional = (symbol.flags & ts3.SymbolFlags.Optional) !== 0;
60506
+ const typeText = checker.typeToString(propType, declNode);
60507
+ const fact = {
60508
+ name: symbol.getName(),
60509
+ typeText,
60510
+ optional,
60511
+ hasDefault: defaults.has(symbol.getName()),
60512
+ isUnion: propType.isUnion()
60513
+ };
60514
+ if (fact.hasDefault) {
60515
+ fact.defaultValueText = defaults.get(symbol.getName());
60516
+ }
60517
+ if (propType.isUnion()) {
60518
+ fact.unionMembers = unionMembers(propType, declNode, checker);
60519
+ }
60520
+ const jsdocText = getJsDocText(symbol);
60521
+ if (jsdocText) fact.jsdoc = jsdocText;
60522
+ facts.push(fact);
60523
+ }
60524
+ return facts;
60525
+ }
60526
+ function resolvePropsType(node, checker) {
60527
+ if (ts3.isFunctionDeclaration(node) || ts3.isArrowFunction(node) || ts3.isFunctionExpression(node)) {
60528
+ const param = node.parameters[0];
60529
+ if (!param) return null;
60530
+ return checker.getTypeAtLocation(param);
60531
+ }
60532
+ if (ts3.isClassDeclaration(node) || ts3.isClassExpression(node)) {
60533
+ const heritage = node.heritageClauses?.[0]?.types?.[0];
60534
+ if (heritage?.typeArguments?.[0]) {
60535
+ return checker.getTypeFromTypeNode(heritage.typeArguments[0]);
60536
+ }
60537
+ }
60538
+ return null;
60539
+ }
60540
+ function collectDestructuredDefaults(node) {
60541
+ const defaults = /* @__PURE__ */ new Map();
60542
+ if (!ts3.isFunctionDeclaration(node) && !ts3.isArrowFunction(node) && !ts3.isFunctionExpression(node)) {
60543
+ return defaults;
60544
+ }
60545
+ const param = node.parameters[0];
60546
+ if (!param || !ts3.isObjectBindingPattern(param.name)) return defaults;
60547
+ for (const element of param.name.elements) {
60548
+ if (!ts3.isIdentifier(element.name)) continue;
60549
+ if (!element.initializer) continue;
60550
+ const propName = element.propertyName ? element.propertyName.getText() : element.name.text;
60551
+ defaults.set(propName, element.initializer.getText());
60552
+ }
60553
+ return defaults;
60554
+ }
60555
+ function isUserDeclaration(decl, owner) {
60556
+ const declSource = decl.getSourceFile();
60557
+ if (declSource === owner) return true;
60558
+ return !declSource.fileName.includes("node_modules");
60559
+ }
60560
+ function unionMembers(type, location, checker) {
60561
+ if (!type.isUnion()) return [];
60562
+ const members = type.types.map((t4) => checker.typeToString(t4, location));
60563
+ return [...new Set(members)].sort();
60564
+ }
60565
+ function getJsDocText(symbol) {
60566
+ const tags = symbol.getDocumentationComment(void 0);
60567
+ if (!tags || tags.length === 0) return void 0;
60568
+ return ts3.displayPartsToString(tags).trim() || void 0;
60569
+ }
60570
+ function mapBehaviorHints(inner, props) {
60571
+ let hasInternalState = false;
60572
+ let hasEffects = false;
60573
+ if (inner) {
60574
+ visit(inner, (node) => {
60575
+ if (hasInternalState && hasEffects) return false;
60576
+ if (ts3.isCallExpression(node)) {
60577
+ const name = getCalleeName(node.expression);
60578
+ if (name && REACT_HOOK_STATE.has(name)) hasInternalState = true;
60579
+ if (name && REACT_HOOK_EFFECT.has(name)) hasEffects = true;
60580
+ }
60581
+ return true;
60582
+ });
60583
+ }
60584
+ return { hasInternalState, hasEffects, isControlled: inferControlled(props) };
60585
+ }
60586
+ function visit(node, fn) {
60587
+ if (fn(node) === false) return;
60588
+ ts3.forEachChild(node, (child) => visit(child, fn));
60589
+ }
60590
+ function inferControlled(props) {
60591
+ const names = new Set(props.map((p) => p.name));
60592
+ const hasValue = names.has("value") || names.has("checked");
60593
+ const hasOnChange = names.has("onChange") || names.has("onValueChange") || names.has("onCheckedChange");
60594
+ const hasDefault = names.has("defaultValue") || names.has("defaultChecked");
60595
+ if (hasValue && hasOnChange && hasDefault) return "mixed";
60596
+ if (hasValue && hasOnChange) return true;
60597
+ if (hasDefault && !hasValue) return false;
60598
+ return "unknown";
60599
+ }
60600
+ function mapFileCompoundChildren(sourceFile) {
60601
+ const result = /* @__PURE__ */ new Map();
60602
+ function bucket(name) {
60603
+ let set = result.get(name);
60604
+ if (!set) {
60605
+ set = /* @__PURE__ */ new Set();
60606
+ result.set(name, set);
60607
+ }
60608
+ return set;
60609
+ }
60610
+ for (const stmt of sourceFile.statements) {
60611
+ if (ts3.isExpressionStatement(stmt) && ts3.isCallExpression(stmt.expression)) {
60612
+ const target = readObjectAssignTarget(stmt.expression);
60613
+ if (target) collectAssignedMembers(stmt.expression, bucket(target.text));
60614
+ }
60615
+ if (ts3.isVariableStatement(stmt)) {
60616
+ for (const decl of stmt.declarationList.declarations) {
60617
+ if (ts3.isIdentifier(decl.name) && decl.initializer && ts3.isCallExpression(decl.initializer) && isObjectAssignCallee(decl.initializer.expression)) {
60618
+ collectAssignedMembers(decl.initializer, bucket(decl.name.text));
60619
+ }
60620
+ }
60621
+ }
60622
+ if (ts3.isExpressionStatement(stmt) && ts3.isBinaryExpression(stmt.expression)) {
60623
+ const expr = stmt.expression;
60624
+ if (expr.operatorToken.kind === ts3.SyntaxKind.EqualsToken && ts3.isPropertyAccessExpression(expr.left) && ts3.isIdentifier(expr.left.expression)) {
60625
+ bucket(expr.left.expression.text).add(expr.left.name.text);
60626
+ }
60627
+ }
60628
+ }
60629
+ const flattened = /* @__PURE__ */ new Map();
60630
+ for (const [name, set] of result) flattened.set(name, [...set]);
60631
+ return flattened;
60632
+ }
60633
+ function isObjectAssignCallee(callee) {
60634
+ return ts3.isPropertyAccessExpression(callee) && ts3.isIdentifier(callee.expression) && callee.expression.text === "Object" && callee.name.text === "assign";
60635
+ }
60636
+ function readObjectAssignTarget(call) {
60637
+ if (!isObjectAssignCallee(call.expression)) return null;
60638
+ const target = call.arguments[0];
60639
+ return target && ts3.isIdentifier(target) ? target : null;
60640
+ }
60641
+ function collectAssignedMembers(call, into) {
60642
+ const members = call.arguments[1];
60643
+ if (!members || !ts3.isObjectLiteralExpression(members)) return;
60644
+ for (const prop of members.properties) {
60645
+ if (ts3.isShorthandPropertyAssignment(prop)) {
60646
+ into.add(prop.name.text);
60647
+ } else if (ts3.isPropertyAssignment(prop) && ts3.isIdentifier(prop.name)) {
60648
+ into.add(prop.name.text);
60649
+ }
60650
+ }
60651
+ }
60652
+ function mapStyleSystem(sourceFile, imports) {
60653
+ const styleSystem = detectStyleSystem(imports);
60654
+ const classNamesUsed = collectClassNames(sourceFile);
60655
+ return { styleSystem, classNamesUsed };
60656
+ }
60657
+ function detectStyleSystem(imports) {
60658
+ for (const record of imports) {
60659
+ const spec = record.moduleSpecifier;
60660
+ if (/\.module\.(s?c|sa)ss$/.test(spec)) return "cssModules";
60661
+ if (spec === "styled-components") return "styledComponents";
60662
+ if (spec === "@emotion/styled" || spec === "@emotion/react") return "cssInJs";
60663
+ if (spec === "@stitches/react") return "cssInJs";
60664
+ if (/^@?tailwind/.test(spec) || spec === "tailwindcss") return "tailwind";
60665
+ if (/\.scss$/.test(spec) || /\.sass$/.test(spec)) return "sass";
60666
+ if (/\.css$/.test(spec)) return "plainCss";
60667
+ }
60668
+ return "unknown";
60669
+ }
60670
+ function collectClassNames(sourceFile) {
60671
+ const seen = /* @__PURE__ */ new Set();
60672
+ visit(sourceFile, (node) => {
60673
+ if (seen.size >= MAX_CLASSNAMES) return false;
60674
+ if (!ts3.isJsxAttribute(node)) return true;
60675
+ if (node.name.getText() !== "className") return true;
60676
+ if (!node.initializer) return true;
60677
+ if (ts3.isStringLiteral(node.initializer)) {
60678
+ addClasses(node.initializer.text, seen);
60679
+ return true;
60680
+ }
60681
+ if (ts3.isJsxExpression(node.initializer) && node.initializer.expression) {
60682
+ const expr = node.initializer.expression;
60683
+ if (ts3.isStringLiteral(expr) || ts3.isNoSubstitutionTemplateLiteral(expr)) {
60684
+ addClasses(expr.text, seen);
60685
+ }
60686
+ }
60687
+ return true;
60688
+ });
60689
+ return [...seen];
60690
+ }
60691
+ function addClasses(raw, seen) {
60692
+ for (const cls of raw.split(/\s+/)) {
60693
+ if (!cls) continue;
60694
+ if (seen.size >= MAX_CLASSNAMES) return;
60695
+ seen.add(cls);
60696
+ }
60697
+ }
60698
+ function mapJsdoc(declaration, sourceFile) {
60699
+ const result = {};
60700
+ if (declaration) {
60701
+ const jsDocs = ts3.getJSDocCommentsAndTags(declaration);
60702
+ for (const doc of jsDocs) {
60703
+ if (ts3.isJSDoc(doc) && doc.comment) {
60704
+ const text2 = jsdocCommentToString(doc.comment);
60705
+ const firstSentence = text2.split(/(?<=\.)\s/)[0]?.trim();
60706
+ if (firstSentence) {
60707
+ result.jsdocDescription = firstSentence;
60708
+ break;
60709
+ }
60710
+ }
60711
+ }
60712
+ }
60713
+ const text = sourceFile.getFullText();
60714
+ const headerMatch = text.match(/^\s*\/\*\*[\s\S]*?\*\//);
60715
+ if (headerMatch) {
60716
+ result.fileHeaderComment = headerMatch[0].replace(/^\s*\/\*\*/, "").replace(/\*\/\s*$/, "").replace(/^\s*\*\s?/gm, "").trim();
60717
+ }
60718
+ return result;
60719
+ }
60720
+ function jsdocCommentToString(comment) {
60721
+ if (!comment) return "";
60722
+ if (typeof comment === "string") return comment;
60723
+ return comment.map((c) => c.text ?? "").join("");
60724
+ }
60725
+ function mapEvents() {
60726
+ return [];
60727
+ }
60728
+ function mapSlots() {
60729
+ return [];
60730
+ }
60731
+ var DEFAULT_ADAPTER_VERSION = "0.1.0";
60732
+ var MAX_UNWRAP_DEPTH = 6;
60733
+ function extractUcfsForReact(opts) {
60734
+ const adapterVersion = opts.adapterVersion ?? DEFAULT_ADAPTER_VERSION;
60735
+ const cwd = opts.cwd ?? process.cwd();
60736
+ const capturedAt = (/* @__PURE__ */ new Date()).toISOString();
60737
+ const sources = collectSources(opts);
60738
+ if (sources.length === 0) return [];
60739
+ const program = createProgram(sources, opts.tsconfig, cwd);
60740
+ const checker = program.getTypeChecker();
60741
+ const results = [];
60742
+ for (const source of sources) {
60743
+ const sourceFile = program.getSourceFile(source.filePath);
60744
+ if (!sourceFile) {
60745
+ console.warn(`[ucf-adapter] skip: cannot load ${source.filePath}`);
60746
+ continue;
60747
+ }
60748
+ try {
60749
+ const facts = extractFromFile({
60750
+ sourceFile,
60751
+ checker,
60752
+ sourceCommit: opts.sourceCommit,
60753
+ adapterVersion,
60754
+ capturedAt,
60755
+ cwd
60756
+ });
60757
+ results.push(...facts);
60758
+ } catch (err) {
60759
+ console.warn(
60760
+ `[ucf-adapter] error processing ${source.filePath}: ${err.message}`
60761
+ );
60762
+ }
60763
+ }
60764
+ return results;
60765
+ }
60766
+ function collectSources(opts) {
60767
+ const map = /* @__PURE__ */ new Map();
60768
+ for (const filePath of opts.sourceFiles ?? []) {
60769
+ const abs = resolve4(filePath);
60770
+ if (!existsSync4(abs)) continue;
60771
+ map.set(abs, { filePath: abs });
60772
+ }
60773
+ for (const inline of opts.inlineSources ?? []) {
60774
+ const abs = isAbsolute(inline.filePath) ? inline.filePath : resolve4(inline.filePath);
60775
+ map.set(abs, { filePath: abs, inlineSource: inline.source });
60776
+ }
60777
+ return [...map.values()];
60778
+ }
60779
+ function createProgram(sources, tsconfigPath, cwd) {
60780
+ const options = resolveCompilerOptions(tsconfigPath, cwd);
60781
+ const overlays = /* @__PURE__ */ new Map();
60782
+ for (const { filePath, inlineSource } of sources) {
60783
+ if (inlineSource === void 0) continue;
60784
+ overlays.set(
60785
+ filePath,
60786
+ ts4.createSourceFile(filePath, inlineSource, ts4.ScriptTarget.Latest, true, ts4.ScriptKind.TSX)
60787
+ );
60788
+ }
60789
+ const baseHost = ts4.createCompilerHost(options, true);
60790
+ const host = {
60791
+ ...baseHost,
60792
+ getSourceFile: (fileName, languageVersion, onError, shouldCreateNewSourceFile) => {
60793
+ const overlay = overlays.get(resolve4(fileName));
60794
+ if (overlay) return overlay;
60795
+ return baseHost.getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile);
60796
+ },
60797
+ fileExists: (fileName) => overlays.has(resolve4(fileName)) || baseHost.fileExists(fileName),
60798
+ readFile: (fileName) => {
60799
+ const overlay = overlays.get(resolve4(fileName));
60800
+ if (overlay) return overlay.getFullText();
60801
+ return baseHost.readFile(fileName);
60802
+ },
60803
+ writeFile: () => void 0
60804
+ };
60805
+ return ts4.createProgram({
60806
+ rootNames: sources.map((s) => s.filePath),
60807
+ options,
60808
+ host
60809
+ });
60810
+ }
60811
+ function resolveCompilerOptions(tsconfigPath, cwd) {
60812
+ if (tsconfigPath && existsSync4(tsconfigPath)) {
60813
+ const resolved = resolve4(tsconfigPath);
60814
+ const configFile = ts4.readConfigFile(resolved, ts4.sys.readFile);
60815
+ if (!configFile.error) {
60816
+ const parsed = ts4.parseJsonConfigFileContent(
60817
+ configFile.config,
60818
+ ts4.sys,
60819
+ dirname4(resolved),
60820
+ void 0,
60821
+ resolved
60822
+ );
60823
+ return parsed.options;
60824
+ }
60825
+ }
60826
+ return {
60827
+ target: ts4.ScriptTarget.ES2022,
60828
+ module: ts4.ModuleKind.ESNext,
60829
+ moduleResolution: ts4.ModuleResolutionKind.Bundler,
60830
+ jsx: ts4.JsxEmit.ReactJSX,
60831
+ allowSyntheticDefaultImports: true,
60832
+ esModuleInterop: true,
60833
+ skipLibCheck: true,
60834
+ strict: false,
60835
+ noEmit: true,
60836
+ rootDir: cwd
60837
+ };
60838
+ }
60839
+ function extractFromFile(ctx) {
60840
+ const { sourceFile, checker } = ctx;
60841
+ const moduleSymbol = checker.getSymbolAtLocation(sourceFile);
60842
+ const exportSymbols = moduleSymbol ? checker.getExportsOfModule(moduleSymbol) : [];
60843
+ if (exportSymbols.length === 0) return [];
60844
+ const filePath = toRelativePath(sourceFile.fileName, ctx.cwd);
60845
+ const imports = mapImports(sourceFile);
60846
+ const fileExports = mapFileExports(sourceFile);
60847
+ const compoundMap = mapFileCompoundChildren(sourceFile);
60848
+ const style = mapStyleSystem(sourceFile, imports);
60849
+ const facts = [];
60850
+ for (const exportSymbol of exportSymbols) {
60851
+ const name = exportSymbol.getName();
60852
+ if (!isLikelyComponent(name)) continue;
60853
+ const declaration = resolveDeclaration(exportSymbol, checker);
60854
+ if (!declaration) continue;
60855
+ const definition = mapDefinitionKind(declaration);
60856
+ if (!definition.inner) continue;
60857
+ const rootResult = mapRootElements(definition.inner);
60858
+ const aria = mapAria(rootResult.rootElements);
60859
+ const props = mapProps(definition.inner, checker);
60860
+ const behavior = mapBehaviorHints(definition.inner, props);
60861
+ const docs = mapJsdoc(declaration, sourceFile);
60862
+ facts.push({
60863
+ id: ucfId(filePath, name, "react", ctx.sourceCommit),
60864
+ filePath,
60865
+ componentName: name,
60866
+ framework: "react",
60867
+ sourceCommit: ctx.sourceCommit,
60868
+ capturedAt: ctx.capturedAt,
60869
+ adapterVersion: ctx.adapterVersion,
60870
+ definitionKind: definition.kind,
60871
+ wrappedBy: definition.wrappedBy,
60872
+ imports,
60873
+ exports: buildExportRecords(fileExports.exportNames, name),
60874
+ exportedFromBarrel: fileExports.exportedFromBarrel,
60875
+ rootElements: rootResult.rootElements,
60876
+ rootElementsTruncated: rootResult.rootElementsTruncated,
60877
+ ariaRoles: aria.ariaRoles,
60878
+ ariaAttributes: aria.ariaAttributes,
60879
+ props,
60880
+ events: mapEvents(),
60881
+ slots: mapSlots(),
60882
+ hasInternalState: behavior.hasInternalState,
60883
+ hasEffects: behavior.hasEffects,
60884
+ isControlled: behavior.isControlled,
60885
+ compoundChildren: compoundMap.get(name) ?? [],
60886
+ styleSystem: style.styleSystem,
60887
+ classNamesUsed: style.classNamesUsed,
60888
+ jsdocDescription: docs.jsdocDescription,
60889
+ fileHeaderComment: docs.fileHeaderComment
60890
+ });
60891
+ }
60892
+ return facts;
60893
+ }
60894
+ function buildExportRecords(names, primaryName) {
60895
+ return names.map((exportedAs) => ({ exportedAs, isPrimary: exportedAs === primaryName }));
60896
+ }
60897
+ function isLikelyComponent(name) {
60898
+ return /^[A-Z][A-Za-z0-9_]*$/.test(name);
60899
+ }
60900
+ function resolveDeclaration(symbol, checker) {
60901
+ let target = symbol;
60902
+ if (target.flags & ts4.SymbolFlags.Alias) {
60903
+ target = checker.getAliasedSymbol(target);
60904
+ }
60905
+ const decls = target.getDeclarations();
60906
+ if (!decls || decls.length === 0) return null;
60907
+ const decl = decls[0];
60908
+ if (ts4.isVariableDeclaration(decl) && decl.initializer) {
60909
+ return unwrapToComponentNode(decl.initializer, checker);
60910
+ }
60911
+ if (ts4.isFunctionDeclaration(decl)) return decl;
60912
+ if (ts4.isClassDeclaration(decl)) return decl;
60913
+ if (ts4.isExportAssignment(decl)) return unwrapToComponentNode(decl.expression, checker);
60914
+ return null;
60915
+ }
60916
+ function unwrapToComponentNode(expression, checker) {
60917
+ let cursor = expression;
60918
+ for (let depth = 0; depth < MAX_UNWRAP_DEPTH; depth++) {
60919
+ if (ts4.isCallExpression(cursor) && ts4.isPropertyAccessExpression(cursor.expression) && ts4.isIdentifier(cursor.expression.expression) && cursor.expression.expression.text === "Object" && cursor.expression.name.text === "assign" && cursor.arguments[0]) {
60920
+ cursor = cursor.arguments[0];
60921
+ continue;
60922
+ }
60923
+ if (ts4.isIdentifier(cursor)) {
60924
+ const sym = checker.getSymbolAtLocation(cursor);
60925
+ if (!sym) break;
60926
+ const followed = sym.flags & ts4.SymbolFlags.Alias ? checker.getAliasedSymbol(sym) : sym;
60927
+ const decl = followed.getDeclarations()?.[0];
60928
+ if (decl && ts4.isFunctionDeclaration(decl)) return decl;
60929
+ if (decl && ts4.isClassDeclaration(decl)) return decl;
60930
+ if (decl && ts4.isVariableDeclaration(decl) && decl.initializer) {
60931
+ cursor = decl.initializer;
60932
+ continue;
60933
+ }
60934
+ break;
60935
+ }
60936
+ break;
60937
+ }
60938
+ return cursor;
60939
+ }
60940
+ function toRelativePath(filePath, cwd) {
60941
+ const rel = relative(cwd, filePath);
60942
+ return rel.startsWith("..") ? filePath : rel;
60943
+ }
60242
60944
  export {
60243
60945
  DEFAULT_RECOGNIZED_CLASS_HELPERS,
60244
60946
  aggregateComponentUsage,
@@ -60248,11 +60950,13 @@ export {
60248
60950
  extractClassnameSpreadFact,
60249
60951
  extractCustomPropsFromComponentFile,
60250
60952
  extractJsxFacts,
60953
+ extractUcfsForReact,
60251
60954
  parseClass,
60252
60955
  resolveComponentSourcePath,
60253
60956
  resolveRecognizedHelpers,
60254
60957
  resolveTailwindToken,
60255
60958
  resolveTailwindTokenFacts,
60256
- resolveTokensWithSass
60959
+ resolveTokensWithSass,
60960
+ ucfId
60257
60961
  };
60258
- //# sourceMappingURL=dist-BDWAHJ4K.js.map
60962
+ //# sourceMappingURL=dist-TTCI6TME.js.map