@c4a/extract-ts 0.5.41-beta.6 → 0.6.0-alpha.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.
Files changed (3) hide show
  1. package/README.md +36 -4
  2. package/index.js +266 -129
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,6 +1,9 @@
1
1
  # @c4a/extract-ts
2
2
 
3
- TypeScript/TSX extraction plugin for C4A. It implements the `ExtractionPlugin` protocol from `@c4a/extract` and is the default plugin used by `context capture --code` for npm-style packages.
3
+ TypeScript/TSX extraction plugin for Context. It implements the
4
+ `ExtractionPlugin` protocol from `@c4a/extract` and is the default plugin used
5
+ by the SDK `extractTs({ source, collection: "wikis" })` phase for npm-style
6
+ packages.
4
7
 
5
8
  ## Role in the Monorepo
6
9
 
@@ -82,7 +85,9 @@ The plugin returns `ExtractionResult` v2. The `@c4a/extract` runner turns that i
82
85
  - `edges.jsonl` receives relation rows with package/module/version/hash metadata.
83
86
  - `digests.jsonl` receives versioned module digest rows.
84
87
 
85
- `context compile --code` consumes those rows to build package/category/symbol Nodes. The important projection inputs are:
88
+ The Context CLI consumes those rows during `context run extract:<source>:wikis`
89
+ to build review candidates for package/category/symbol knowledge Nodes. The
90
+ important projection inputs are:
86
91
 
87
92
  - stable package names and versions
88
93
  - stable exported symbol names
@@ -92,7 +97,8 @@ The plugin returns `ExtractionResult` v2. The `@c4a/extract` runner turns that i
92
97
  - relation `from` / `to` values
93
98
  - JSDoc and type/member metadata
94
99
 
95
- Obsidian Render reads compiled Markdown and graph YAML after projection; it does not read `@c4a/extract-ts` output directly.
100
+ Package build reads approved Markdown and generated project metadata after
101
+ review/apply and close; it does not read `@c4a/extract-ts` output directly.
96
102
 
97
103
  ## Usage
98
104
 
@@ -106,7 +112,33 @@ const registry = new ExtractionPluginRegistry();
106
112
  registry.register(new TypeScriptPlugin());
107
113
  ```
108
114
 
109
- Runner usage normally goes through `context capture --code`; agents should not hand-build runner input or raw snapshots.
115
+ Workspace usage normally goes through a declared project phase:
116
+
117
+ ```ts
118
+ import { defineProject, extractTs, reviewValidity, source } from "@c4a/context";
119
+
120
+ const componentLib = source("component-lib");
121
+
122
+ export default defineProject({
123
+ sources: [componentLib],
124
+ phases: [
125
+ extractTs({ source: componentLib, collection: "wikis" }),
126
+ reviewValidity({ collection: "wikis" }),
127
+ ],
128
+ packages: [],
129
+ });
130
+ ```
131
+
132
+ The source boundary is registered first, then the phase is previewed or run:
133
+
134
+ ```bash
135
+ context source add repo component-lib --local ../packages/component-lib
136
+ context run extract:component-lib:wikis --dry-run
137
+ context run extract:component-lib:wikis
138
+ ```
139
+
140
+ Agents should not hand-build runner input or raw snapshots for normal Context
141
+ workspace operation.
110
142
 
111
143
  ## Internal Modules
112
144
 
package/index.js CHANGED
@@ -6981,7 +6981,7 @@ var require_dist = __commonJS((exports) => {
6981
6981
 
6982
6982
  // ../../node_modules/.bun/web-tree-sitter@0.20.8/node_modules/web-tree-sitter/tree-sitter.js
6983
6983
  var require_tree_sitter = __commonJS((exports, module2) => {
6984
- var __dirname = "/Users/bytedance/github/c4a/node_modules/.bun/web-tree-sitter@0.20.8/node_modules/web-tree-sitter";
6984
+ var __dirname = "/Users/bytedance/github/c4a/context/node_modules/.bun/web-tree-sitter@0.20.8/node_modules/web-tree-sitter";
6985
6985
  var Module = Module !== undefined ? Module : {};
6986
6986
  var TreeSitter = function() {
6987
6987
  var initPromise, document = typeof window == "object" ? { currentScript: window.document.currentScript } : null;
@@ -13808,7 +13808,9 @@ var symbolInfoSchema = exports_external.lazy(() => exports_external.object({
13808
13808
  implements: exports_external.array(exports_external.string().min(1)).optional(),
13809
13809
  doc: exports_external.string().nullable().optional(),
13810
13810
  propsType: exports_external.string().min(1).nullable().optional(),
13811
- unionValues: exports_external.array(exports_external.string()).optional()
13811
+ unionValues: exports_external.array(exports_external.string()).optional(),
13812
+ initializer: exports_external.string().min(1).nullable().optional(),
13813
+ signature: exports_external.string().min(1).nullable().optional()
13812
13814
  }));
13813
13815
  var relationInfoSchema = exports_external.object({
13814
13816
  type: relationTypeSchema,
@@ -14298,7 +14300,7 @@ var traceExports = async (entryPath, fs2) => {
14298
14300
  };
14299
14301
  };
14300
14302
 
14301
- // src/symbolExtractor.ts
14303
+ // src/symbolExtractorAst.ts
14302
14304
  var DECLARATION_TYPES2 = new Set([
14303
14305
  "function_declaration",
14304
14306
  "class_declaration",
@@ -14368,6 +14370,47 @@ var getReturnType = (node2) => {
14368
14370
  const returnNode = node2.childForFieldName("return_type") ?? node2.namedChildren.find((child) => child.type === "type_annotation") ?? null;
14369
14371
  return extractTypeAnnotation(returnNode);
14370
14372
  };
14373
+ var getInitializer = (node2) => node2.childForFieldName("value") ?? node2.namedChildren.find((child) => child.type === "arrow_function" || child.type === "function" || child.type === "call_expression") ?? null;
14374
+ var getCallableFromInitializer = (node2) => {
14375
+ if (!node2)
14376
+ return null;
14377
+ if (node2.type === "arrow_function" || node2.type === "function")
14378
+ return node2;
14379
+ if (node2.type === "call_expression") {
14380
+ return node2.namedChildren.find((child) => child.type === "arrow_function" || child.type === "function") ?? null;
14381
+ }
14382
+ return null;
14383
+ };
14384
+ var getInitializerTypeAnnotation = (node2) => {
14385
+ if (!node2 || node2.type !== "call_expression")
14386
+ return null;
14387
+ const typeArguments = node2.namedChildren.find((child) => child.type === "type_arguments") ?? null;
14388
+ if (!typeArguments)
14389
+ return null;
14390
+ const callee = node2.namedChildren.find((child) => child.type !== "type_arguments" && child.type !== "arguments") ?? null;
14391
+ const calleeText = callee?.text?.trim();
14392
+ return calleeText ? `${calleeText}${typeArguments.text}` : typeArguments.text;
14393
+ };
14394
+ var getInitializerText = (node2, options = {}) => {
14395
+ if (!node2)
14396
+ return null;
14397
+ if ((node2.type === "arrow_function" || node2.type === "function") && !options.includeCallable)
14398
+ return null;
14399
+ const text = node2.text.trim();
14400
+ if ((node2.type === "arrow_function" || node2.type === "function") && text.length > 600)
14401
+ return null;
14402
+ return text.length > 0 ? text : null;
14403
+ };
14404
+ var inferReturnType = (node2) => {
14405
+ if (!node2)
14406
+ return null;
14407
+ return containsJsx(node2) ? "JSX.Element" : null;
14408
+ };
14409
+ var containsJsx = (node2) => {
14410
+ if (node2.type.startsWith("jsx_"))
14411
+ return true;
14412
+ return node2.namedChildren.some(containsJsx);
14413
+ };
14371
14414
  var getTypeNames = (typeText) => {
14372
14415
  if (!typeText)
14373
14416
  return [];
@@ -14433,9 +14476,15 @@ var collectMembers = (node2, declarations, importBindings, ownerName, relations)
14433
14476
  appendTypeRelations(relations, "of_type" /* OfType */, ownerName, typeAnnotation, importBindings, declarations, getLine(child));
14434
14477
  continue;
14435
14478
  }
14479
+ const indexMember = indexSignatureMember(child);
14480
+ if (indexMember) {
14481
+ members.push(indexMember.info);
14482
+ appendTypeRelations(relations, "of_type" /* OfType */, ownerName, indexMember.typeAnnotation, importBindings, declarations, getLine(child));
14483
+ continue;
14484
+ }
14436
14485
  if (child.type === "method_definition" || child.type === "method_signature") {
14437
14486
  const nameNode = child.childForFieldName("name") ?? child.namedChildren.find((candidate) => candidate.type === "property_identifier" || candidate.type === "identifier");
14438
- if (!nameNode || nameNode.text === "constructor")
14487
+ if (!nameNode)
14439
14488
  continue;
14440
14489
  const paramsNode = child.childForFieldName("parameters") ?? child.namedChildren.find((candidate) => candidate.type === "formal_parameters") ?? null;
14441
14490
  const params = collectParams(paramsNode);
@@ -14460,6 +14509,48 @@ var collectMembers = (node2, declarations, importBindings, ownerName, relations)
14460
14509
  }
14461
14510
  return members.length > 0 ? members : undefined;
14462
14511
  };
14512
+ var indexSignatureMember = (node2) => {
14513
+ if (node2.type !== "index_signature")
14514
+ return null;
14515
+ const match = /^\s*(\[[^\]]+\])\s*:?\s*([^;]+)?;?\s*$/u.exec(node2.text);
14516
+ const name = match?.[1]?.trim();
14517
+ const typeAnnotation = match?.[2]?.trim();
14518
+ if (!name)
14519
+ return null;
14520
+ const propDoc = extractJSDoc(node2);
14521
+ return {
14522
+ info: {
14523
+ name,
14524
+ kind: "prop" /* Prop */,
14525
+ visibility: "internal" /* Internal */,
14526
+ file: "",
14527
+ line: getLine(node2),
14528
+ endLine: getEndLine(node2),
14529
+ ...typeAnnotation ? { typeAnnotation } : {},
14530
+ ...propDoc ? { doc: propDoc } : {}
14531
+ },
14532
+ typeAnnotation
14533
+ };
14534
+ };
14535
+ var collectEnumValues = (node2) => {
14536
+ const body2 = node2.namedChildren.find((child) => child.type === "enum_body") ?? null;
14537
+ if (!body2)
14538
+ return;
14539
+ const values = [];
14540
+ for (const member of body2.namedChildren.filter((child) => child.type === "enum_assignment" || child.type === "property_identifier")) {
14541
+ if (member.type === "property_identifier") {
14542
+ values.push(member.text);
14543
+ continue;
14544
+ }
14545
+ const name = member.childForFieldName("name")?.text ?? member.namedChildren[0]?.text;
14546
+ if (!name)
14547
+ continue;
14548
+ const valueNode = member.childForFieldName("value") ?? member.namedChildren.find((child) => child !== member.childForFieldName("name")) ?? null;
14549
+ const rawValue = valueNode?.text.replace(/^['"]|['"]$/gu, "");
14550
+ values.push(rawValue ? `${name} = ${rawValue}` : name);
14551
+ }
14552
+ return values.length > 0 ? values : undefined;
14553
+ };
14463
14554
  var extractUnionLiteralValues = (typeNode) => {
14464
14555
  if (!typeNode)
14465
14556
  return;
@@ -14500,152 +14591,197 @@ var findObjectTypeNodes = (node2) => {
14500
14591
  }
14501
14592
  return [];
14502
14593
  };
14594
+
14595
+ // src/symbolExtractorAnalyze.ts
14503
14596
  var analyzeDeclaration = (node2, filePath, declarations, importBindings, relations) => {
14504
14597
  if (node2.type === "lexical_declaration") {
14505
- for (const declarator of node2.namedChildren.filter((child) => child.type === "variable_declarator")) {
14506
- const nameNode2 = declarator.childForFieldName("name") ?? declarator.namedChildren[0];
14507
- if (!nameNode2)
14508
- continue;
14509
- const typeNode = declarator.childForFieldName("type") ?? declarator.namedChildren.find((child) => child.type === "type_annotation") ?? null;
14510
- const typeAnnotation = extractTypeAnnotation(typeNode);
14511
- const varDoc = extractJSDoc(node2);
14512
- declarations.set(nameNode2.text, {
14513
- info: {
14514
- name: nameNode2.text,
14515
- kind: classifyVariable(nameNode2.text, filePath),
14516
- visibility: "internal" /* Internal */,
14517
- file: filePath,
14518
- line: getLine(declarator),
14519
- endLine: getEndLine(declarator),
14520
- ...typeAnnotation ? { typeAnnotation } : {},
14521
- ...varDoc ? { doc: varDoc } : {}
14522
- }
14523
- });
14524
- appendTypeRelations(relations, "of_type" /* OfType */, nameNode2.text, typeAnnotation, importBindings, declarations, getLine(declarator));
14525
- }
14598
+ analyzeLexicalDeclaration(node2, filePath, declarations, importBindings, relations);
14526
14599
  return;
14527
14600
  }
14528
- const nameNode = node2.childForFieldName("name") ?? node2.namedChildren.find((child) => child.type === "identifier" || child.type === "type_identifier");
14529
- const name = getNameNodeText(nameNode);
14530
- if (!name)
14601
+ const named = getNamedDeclaration(node2);
14602
+ if (!named)
14531
14603
  return;
14604
+ const { name } = named;
14532
14605
  if (node2.type === "function_declaration") {
14533
- const paramsNode = node2.childForFieldName("parameters") ?? node2.namedChildren.find((child) => child.type === "formal_parameters") ?? null;
14534
- const params = collectParams(paramsNode);
14535
- const returnType = getReturnType(node2);
14536
- const funcDoc = extractJSDoc(node2);
14537
- declarations.set(name, {
14538
- info: {
14539
- name,
14540
- kind: "function" /* Function */,
14541
- visibility: "internal" /* Internal */,
14542
- file: filePath,
14543
- line: getLine(node2),
14544
- endLine: getEndLine(node2),
14545
- ...params.length > 0 ? { params } : {},
14546
- ...returnType ? { returnType } : {},
14547
- ...funcDoc ? { doc: funcDoc } : {}
14548
- }
14549
- });
14550
- for (const param of params) {
14551
- appendTypeRelations(relations, "param_type" /* ParamType */, name, param.type, importBindings, declarations, getLine(node2));
14552
- }
14553
- appendTypeRelations(relations, "return_type" /* ReturnType */, name, returnType, importBindings, declarations, getLine(node2));
14606
+ analyzeFunctionDeclaration(node2, name, filePath, declarations, importBindings, relations);
14554
14607
  return;
14555
14608
  }
14556
14609
  const symbolDoc = extractJSDoc(node2);
14557
14610
  if (node2.type === "class_declaration") {
14558
- const heritage = node2.namedChildren.find((child) => child.type === "class_heritage") ?? null;
14559
- const extendsClause = heritage?.namedChildren.find((child) => child.type === "extends_clause") ?? null;
14560
- const implementsClause = heritage?.namedChildren.find((child) => child.type === "implements_clause") ?? null;
14561
- const extendsValue = extendsClause?.namedChildren[0]?.text ?? null;
14562
- const implementsValues = implementsClause?.namedChildren.map((child) => child.text) ?? [];
14563
- const body2 = node2.namedChildren.find((child) => child.type === "class_body") ?? null;
14564
- const members = collectMembers(body2, declarations, importBindings, name, relations);
14565
- declarations.set(name, {
14566
- info: {
14567
- name,
14568
- kind: "class" /* Class */,
14569
- visibility: "internal" /* Internal */,
14570
- file: filePath,
14571
- line: getLine(node2),
14572
- endLine: getEndLine(node2),
14573
- ...members ? { members: members.map((member) => ({ ...member, file: filePath })) } : {},
14574
- ...extendsValue ? { extends: extendsValue } : {},
14575
- ...implementsValues.length > 0 ? { implements: implementsValues } : {},
14576
- ...symbolDoc ? { doc: symbolDoc } : {}
14577
- }
14578
- });
14579
- if (extendsValue) {
14580
- relations.push(createRelation("extends" /* Extends */, name, extendsValue, resolveTypeBinding(extendsValue, importBindings, declarations), getLine(node2)));
14581
- }
14582
- for (const item of implementsValues) {
14583
- relations.push(createRelation("implements" /* Implements */, name, item, resolveTypeBinding(item, importBindings, declarations), getLine(node2)));
14584
- }
14611
+ analyzeClassDeclaration(node2, name, symbolDoc, filePath, declarations, importBindings, relations);
14585
14612
  return;
14586
14613
  }
14587
14614
  if (node2.type === "interface_declaration") {
14588
- const body2 = node2.namedChildren.find((child) => child.type === "interface_body") ?? null;
14589
- const members = collectMembers(body2, declarations, importBindings, name, relations);
14590
- declarations.set(name, {
14591
- info: {
14592
- name,
14593
- kind: "interface" /* Interface */,
14594
- visibility: "internal" /* Internal */,
14595
- file: filePath,
14596
- line: getLine(node2),
14597
- endLine: getEndLine(node2),
14598
- ...members ? { members: members.map((member) => ({ ...member, file: filePath })) } : {},
14599
- ...symbolDoc ? { doc: symbolDoc } : {}
14600
- }
14601
- });
14615
+ analyzeInterfaceDeclaration(node2, name, symbolDoc, filePath, declarations, importBindings, relations);
14602
14616
  return;
14603
14617
  }
14604
14618
  if (node2.type === "type_alias_declaration") {
14605
- const typeNode = node2.childForFieldName("value") ?? node2.namedChildren.find((c) => c.type !== "type_identifier" && c.type !== "type_parameters") ?? null;
14606
- const typeAnnotation = typeNode?.text ?? null;
14607
- const objectTypeNodes = findObjectTypeNodes(typeNode);
14608
- let members;
14609
- if (objectTypeNodes.length > 0) {
14610
- const allMembers = [];
14611
- for (const objNode of objectTypeNodes) {
14612
- const m = collectMembers(objNode, declarations, importBindings, name, relations);
14613
- if (m)
14614
- allMembers.push(...m);
14615
- }
14616
- members = allMembers.length > 0 ? allMembers : undefined;
14617
- }
14618
- const unionValues = extractUnionLiteralValues(typeNode);
14619
- declarations.set(name, {
14620
- info: {
14621
- name,
14622
- kind: "type" /* Type */,
14623
- visibility: "internal" /* Internal */,
14624
- file: filePath,
14625
- line: getLine(node2),
14626
- endLine: getEndLine(node2),
14627
- ...members ? { members: members.map((member) => ({ ...member, file: filePath })) } : {},
14628
- ...unionValues ? { unionValues } : {},
14629
- ...typeAnnotation && !unionValues ? { typeAnnotation } : {},
14630
- ...symbolDoc ? { doc: symbolDoc } : {}
14631
- }
14632
- });
14633
- appendTypeRelations(relations, "of_type" /* OfType */, name, typeAnnotation, importBindings, declarations, getLine(node2));
14619
+ analyzeTypeAliasDeclaration(node2, name, symbolDoc, filePath, declarations, importBindings, relations);
14634
14620
  return;
14635
14621
  }
14636
14622
  if (node2.type === "enum_declaration") {
14637
- declarations.set(name, {
14623
+ analyzeEnumDeclaration(node2, name, symbolDoc, filePath, declarations);
14624
+ }
14625
+ };
14626
+ var getNamedDeclaration = (node2) => {
14627
+ const nameNode = node2.childForFieldName("name") ?? node2.namedChildren.find((child) => child.type === "identifier" || child.type === "type_identifier");
14628
+ const name = getNameNodeText(nameNode);
14629
+ return name ? { name } : null;
14630
+ };
14631
+ var analyzeLexicalDeclaration = (node2, filePath, declarations, importBindings, relations) => {
14632
+ for (const declarator of node2.namedChildren.filter((child) => child.type === "variable_declarator")) {
14633
+ const nameNode = declarator.childForFieldName("name") ?? declarator.namedChildren[0];
14634
+ if (!nameNode)
14635
+ continue;
14636
+ const typeNode = declarator.childForFieldName("type") ?? declarator.namedChildren.find((child) => child.type === "type_annotation") ?? null;
14637
+ const initializer = getInitializer(declarator);
14638
+ const callable = getCallableFromInitializer(initializer);
14639
+ const paramsNode = callable?.childForFieldName("parameters") ?? callable?.namedChildren.find((child) => child.type === "formal_parameters") ?? null;
14640
+ const params = collectParams(paramsNode);
14641
+ const returnType = callable ? getReturnType(callable) ?? inferReturnType(callable) : null;
14642
+ const initializerTypeAnnotation = getInitializerTypeAnnotation(initializer);
14643
+ const typeAnnotation = extractTypeAnnotation(typeNode) ?? initializerTypeAnnotation;
14644
+ const initializerText = getInitializerText(initializer, {
14645
+ includeCallable: params.length === 0 && !returnType && !typeAnnotation
14646
+ });
14647
+ const varDoc = extractJSDoc(node2);
14648
+ declarations.set(nameNode.text, {
14638
14649
  info: {
14639
- name,
14640
- kind: "enum" /* Enum */,
14650
+ name: nameNode.text,
14651
+ kind: classifyVariable(nameNode.text, filePath),
14641
14652
  visibility: "internal" /* Internal */,
14642
14653
  file: filePath,
14643
- line: getLine(node2),
14644
- endLine: getEndLine(node2),
14645
- ...symbolDoc ? { doc: symbolDoc } : {}
14654
+ line: getLine(declarator),
14655
+ endLine: getEndLine(declarator),
14656
+ ...typeAnnotation ? { typeAnnotation } : {},
14657
+ ...params.length > 0 ? { params } : {},
14658
+ ...returnType ? { returnType } : {},
14659
+ ...initializerText ? { initializer: initializerText } : {},
14660
+ ...varDoc ? { doc: varDoc } : {}
14646
14661
  }
14647
14662
  });
14663
+ for (const param of params) {
14664
+ appendTypeRelations(relations, "param_type" /* ParamType */, nameNode.text, param.type, importBindings, declarations, getLine(declarator));
14665
+ }
14666
+ appendTypeRelations(relations, "return_type" /* ReturnType */, nameNode.text, returnType, importBindings, declarations, getLine(declarator));
14667
+ appendTypeRelations(relations, "of_type" /* OfType */, nameNode.text, typeAnnotation, importBindings, declarations, getLine(declarator));
14668
+ }
14669
+ };
14670
+ var analyzeFunctionDeclaration = (node2, name, filePath, declarations, importBindings, relations) => {
14671
+ const paramsNode = node2.childForFieldName("parameters") ?? node2.namedChildren.find((child) => child.type === "formal_parameters") ?? null;
14672
+ const params = collectParams(paramsNode);
14673
+ const returnType = getReturnType(node2);
14674
+ const funcDoc = extractJSDoc(node2);
14675
+ const signature = `${name}(${params.map((param) => `${param.name}${param.type ? `: ${param.type}` : ""}`).join(", ")})`;
14676
+ declarations.set(name, {
14677
+ info: {
14678
+ name,
14679
+ kind: "function" /* Function */,
14680
+ visibility: "internal" /* Internal */,
14681
+ file: filePath,
14682
+ line: getLine(node2),
14683
+ endLine: getEndLine(node2),
14684
+ signature,
14685
+ ...params.length > 0 ? { params } : {},
14686
+ ...returnType ? { returnType } : {},
14687
+ ...funcDoc ? { doc: funcDoc } : {}
14688
+ }
14689
+ });
14690
+ for (const param of params) {
14691
+ appendTypeRelations(relations, "param_type" /* ParamType */, name, param.type, importBindings, declarations, getLine(node2));
14692
+ }
14693
+ appendTypeRelations(relations, "return_type" /* ReturnType */, name, returnType, importBindings, declarations, getLine(node2));
14694
+ };
14695
+ var analyzeClassDeclaration = (node2, name, symbolDoc, filePath, declarations, importBindings, relations) => {
14696
+ const heritage = node2.namedChildren.find((child) => child.type === "class_heritage") ?? null;
14697
+ const extendsClause = heritage?.namedChildren.find((child) => child.type === "extends_clause") ?? null;
14698
+ const implementsClause = heritage?.namedChildren.find((child) => child.type === "implements_clause") ?? null;
14699
+ const extendsValue = extendsClause?.namedChildren[0]?.text ?? null;
14700
+ const implementsValues = implementsClause?.namedChildren.map((child) => child.text) ?? [];
14701
+ const body2 = node2.namedChildren.find((child) => child.type === "class_body") ?? null;
14702
+ const members = collectMembers(body2, declarations, importBindings, name, relations);
14703
+ declarations.set(name, {
14704
+ info: {
14705
+ name,
14706
+ kind: "class" /* Class */,
14707
+ visibility: "internal" /* Internal */,
14708
+ file: filePath,
14709
+ line: getLine(node2),
14710
+ endLine: getEndLine(node2),
14711
+ ...members ? { members: members.map((member) => ({ ...member, file: filePath })) } : {},
14712
+ ...extendsValue ? { extends: extendsValue } : {},
14713
+ ...implementsValues.length > 0 ? { implements: implementsValues } : {},
14714
+ ...symbolDoc ? { doc: symbolDoc } : {}
14715
+ }
14716
+ });
14717
+ if (extendsValue) {
14718
+ relations.push(createRelation("extends" /* Extends */, name, extendsValue, resolveTypeBinding(extendsValue, importBindings, declarations), getLine(node2)));
14648
14719
  }
14720
+ for (const item of implementsValues) {
14721
+ relations.push(createRelation("implements" /* Implements */, name, item, resolveTypeBinding(item, importBindings, declarations), getLine(node2)));
14722
+ }
14723
+ };
14724
+ var analyzeInterfaceDeclaration = (node2, name, symbolDoc, filePath, declarations, importBindings, relations) => {
14725
+ const body2 = node2.namedChildren.find((child) => child.type === "interface_body") ?? null;
14726
+ const members = collectMembers(body2, declarations, importBindings, name, relations);
14727
+ declarations.set(name, {
14728
+ info: {
14729
+ name,
14730
+ kind: "interface" /* Interface */,
14731
+ visibility: "internal" /* Internal */,
14732
+ file: filePath,
14733
+ line: getLine(node2),
14734
+ endLine: getEndLine(node2),
14735
+ ...members ? { members: members.map((member) => ({ ...member, file: filePath })) } : {},
14736
+ ...symbolDoc ? { doc: symbolDoc } : {}
14737
+ }
14738
+ });
14739
+ };
14740
+ var analyzeTypeAliasDeclaration = (node2, name, symbolDoc, filePath, declarations, importBindings, relations) => {
14741
+ const typeNode = node2.childForFieldName("value") ?? node2.namedChildren.find((c) => c.type !== "type_identifier" && c.type !== "type_parameters") ?? null;
14742
+ const typeAnnotation = typeNode?.text ?? null;
14743
+ const objectTypeNodes = findObjectTypeNodes(typeNode);
14744
+ let members;
14745
+ if (objectTypeNodes.length > 0) {
14746
+ const allMembers = [];
14747
+ for (const objNode of objectTypeNodes) {
14748
+ const extractedMembers = collectMembers(objNode, declarations, importBindings, name, relations);
14749
+ if (extractedMembers)
14750
+ allMembers.push(...extractedMembers);
14751
+ }
14752
+ members = allMembers.length > 0 ? allMembers : undefined;
14753
+ }
14754
+ const unionValues = extractUnionLiteralValues(typeNode);
14755
+ declarations.set(name, {
14756
+ info: {
14757
+ name,
14758
+ kind: "type" /* Type */,
14759
+ visibility: "internal" /* Internal */,
14760
+ file: filePath,
14761
+ line: getLine(node2),
14762
+ endLine: getEndLine(node2),
14763
+ ...members ? { members: members.map((member) => ({ ...member, file: filePath })) } : {},
14764
+ ...unionValues ? { unionValues } : {},
14765
+ ...typeAnnotation && !unionValues ? { typeAnnotation } : {},
14766
+ ...symbolDoc ? { doc: symbolDoc } : {}
14767
+ }
14768
+ });
14769
+ appendTypeRelations(relations, "of_type" /* OfType */, name, typeAnnotation, importBindings, declarations, getLine(node2));
14770
+ };
14771
+ var analyzeEnumDeclaration = (node2, name, symbolDoc, filePath, declarations) => {
14772
+ const enumValues = collectEnumValues(node2);
14773
+ declarations.set(name, {
14774
+ info: {
14775
+ name,
14776
+ kind: "enum" /* Enum */,
14777
+ visibility: "internal" /* Internal */,
14778
+ file: filePath,
14779
+ line: getLine(node2),
14780
+ endLine: getEndLine(node2),
14781
+ ...enumValues ? { unionValues: enumValues } : {},
14782
+ ...symbolDoc ? { doc: symbolDoc } : {}
14783
+ }
14784
+ });
14649
14785
  };
14650
14786
  var collectImportBindings2 = (root, relations) => {
14651
14787
  const bindings = new Map;
@@ -14732,6 +14868,8 @@ var analyzeFile = async (filePath, fs2) => {
14732
14868
  lines: countLines(source2)
14733
14869
  };
14734
14870
  };
14871
+
14872
+ // src/symbolExtractor.ts
14735
14873
  var extractSymbols = async (entries, fs2, options) => {
14736
14874
  const exportedSymbols = [];
14737
14875
  const internalSymbols = [];
@@ -14790,10 +14928,9 @@ var extractSymbols = async (entries, fs2, options) => {
14790
14928
  continue;
14791
14929
  let propsTypeName;
14792
14930
  if (sym.typeAnnotation) {
14793
- const match = sym.typeAnnotation.match(/<([A-Z]\w+)(?:\s*,\s*[A-Z]\w+)*\s*>/);
14794
- if (match?.[1] && typeDeclarations.has(match[1])) {
14795
- propsTypeName = match[1];
14796
- }
14931
+ const genericBody = /<(.+)>/u.exec(sym.typeAnnotation)?.[1];
14932
+ const genericNames = genericBody?.match(/\b[A-Z][A-Za-z0-9_]*\b/gu) ?? [];
14933
+ propsTypeName = genericNames.filter((name) => typeDeclarations.has(name)).at(-1);
14797
14934
  }
14798
14935
  if (!propsTypeName) {
14799
14936
  const conventionName = `${sym.name}Props`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c4a/extract-ts",
3
- "version": "0.5.41-beta.6",
3
+ "version": "0.6.0-alpha.1",
4
4
  "type": "module",
5
5
  "dependencies": {
6
6
  "web-tree-sitter": "^0.20.8"