@living-architecture/riviere-extract-ts 0.2.0 → 0.2.2

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.
@@ -0,0 +1,27 @@
1
+ import type { Project } from 'ts-morph';
2
+ import type { ResolvedExtractionConfig } from '@living-architecture/riviere-extract-config';
3
+ import type { DraftComponent, GlobMatcher } from '../component-extraction/extractor';
4
+ type MetadataValue = string | number | boolean | string[];
5
+ export interface EnrichedComponent {
6
+ type: string;
7
+ name: string;
8
+ location: {
9
+ file: string;
10
+ line: number;
11
+ };
12
+ domain: string;
13
+ metadata: Record<string, MetadataValue>;
14
+ _missing?: string[];
15
+ }
16
+ export interface EnrichmentFailure {
17
+ component: DraftComponent;
18
+ field: string;
19
+ error: string;
20
+ }
21
+ export interface EnrichmentResult {
22
+ components: EnrichedComponent[];
23
+ failures: EnrichmentFailure[];
24
+ }
25
+ export declare function enrichComponents(draftComponents: DraftComponent[], config: ResolvedExtractionConfig, project: Project, globMatcher: GlobMatcher, configDir: string): EnrichmentResult;
26
+ export {};
27
+ //# sourceMappingURL=enrich-components.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enrich-components.d.ts","sourceRoot":"","sources":["../../../src/domain/value-extraction/enrich-components.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACQ,OAAO,EAC1B,MAAM,UAAU,CAAA;AAEjB,OAAO,KAAK,EACV,wBAAwB,EAQzB,MAAM,6CAA6C,CAAA;AACpD,OAAO,KAAK,EACV,cAAc,EAAE,WAAW,EAC5B,MAAM,mCAAmC,CAAA;AAU1C,KAAK,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,CAAA;AAEzD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,EAAE,MAAM,CAAA;KACb,CAAA;IACD,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAA;IACvC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,cAAc,CAAA;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,iBAAiB,EAAE,CAAA;IAC/B,QAAQ,EAAE,iBAAiB,EAAE,CAAA;CAC9B;AAuND,wBAAgB,gBAAgB,CAC9B,eAAe,EAAE,cAAc,EAAE,EACjC,MAAM,EAAE,wBAAwB,EAChC,OAAO,EAAE,OAAO,EAChB,WAAW,EAAE,WAAW,EACxB,SAAS,EAAE,MAAM,GAChB,gBAAgB,CAclB"}
@@ -0,0 +1,158 @@
1
+ import { posix } from 'node:path';
2
+ import { evaluateLiteralRule, evaluateFromClassNameRule, evaluateFromFilePathRule, evaluateFromPropertyRule, } from './evaluate-extraction-rule';
3
+ import { ExtractionError } from '../../platform/domain/ast-literals/literal-detection';
4
+ function findMatchingModule(filePath, modules, globMatcher, configDir) {
5
+ const normalized = filePath.replaceAll(/\\+/g, '/');
6
+ const pathToMatch = posix.relative(configDir.replaceAll(/\\+/g, '/'), normalized);
7
+ return modules.find((m) => globMatcher(pathToMatch, m.path));
8
+ }
9
+ function isDetectionRule(rule) {
10
+ /* istanbul ignore if -- @preserve: unreachable with typed ResolvedExtractionConfig; defensive guard */
11
+ if (typeof rule !== 'object' || rule === null) {
12
+ return false;
13
+ }
14
+ return 'find' in rule && 'where' in rule;
15
+ }
16
+ function getBuiltInRule(module, componentType) {
17
+ const ruleMap = {
18
+ api: module.api,
19
+ useCase: module.useCase,
20
+ domainOp: module.domainOp,
21
+ event: module.event,
22
+ eventHandler: module.eventHandler,
23
+ ui: module.ui,
24
+ };
25
+ const rule = ruleMap[componentType];
26
+ if (isDetectionRule(rule)) {
27
+ return rule;
28
+ }
29
+ return undefined;
30
+ }
31
+ function findDetectionRule(module, componentType) {
32
+ const builtInTypes = [
33
+ 'api',
34
+ 'useCase',
35
+ 'domainOp',
36
+ 'event',
37
+ 'eventHandler',
38
+ 'ui',
39
+ ];
40
+ if (builtInTypes.includes(componentType)) {
41
+ return getBuiltInRule(module, componentType);
42
+ }
43
+ return module.customTypes?.[componentType];
44
+ }
45
+ function isLiteralRule(rule) {
46
+ return 'literal' in rule;
47
+ }
48
+ function isFromClassNameRule(rule) {
49
+ return 'fromClassName' in rule;
50
+ }
51
+ function isFromFilePathRule(rule) {
52
+ return 'fromFilePath' in rule;
53
+ }
54
+ function isFromPropertyRule(rule) {
55
+ return 'fromProperty' in rule;
56
+ }
57
+ function findClassAtLine(project, draft) {
58
+ const sourceFile = project.getSourceFile(draft.location.file);
59
+ if (sourceFile === undefined) {
60
+ throw new ExtractionError(`Source file '${draft.location.file}' not found in project`, draft.location.file, draft.location.line);
61
+ }
62
+ const classDecl = sourceFile
63
+ .getClasses()
64
+ .find((c) => c.getStartLineNumber() === draft.location.line);
65
+ if (classDecl === undefined) {
66
+ throw new ExtractionError(`No class declaration found at line ${draft.location.line}`, draft.location.file, draft.location.line);
67
+ }
68
+ return classDecl;
69
+ }
70
+ function evaluateClassRule(rule, classDecl) {
71
+ if (isFromClassNameRule(rule)) {
72
+ return evaluateFromClassNameRule(rule, classDecl);
73
+ }
74
+ /* istanbul ignore next -- @preserve: only fromProperty reaches here; defensive guard */
75
+ if (!isFromPropertyRule(rule)) {
76
+ throw new ExtractionError('Unsupported extraction rule type for class-based component', classDecl.getSourceFile().getFilePath(), classDecl.getStartLineNumber());
77
+ }
78
+ return evaluateFromPropertyRule(rule, classDecl);
79
+ }
80
+ function evaluateRule(rule, draft, project) {
81
+ if (isLiteralRule(rule)) {
82
+ return evaluateLiteralRule(rule);
83
+ }
84
+ if (isFromFilePathRule(rule)) {
85
+ return evaluateFromFilePathRule(rule, draft.location.file);
86
+ }
87
+ const classDecl = findClassAtLine(project, draft);
88
+ return evaluateClassRule(rule, classDecl);
89
+ }
90
+ function componentWithEmptyMetadata(draft) {
91
+ return {
92
+ enriched: {
93
+ ...draft,
94
+ metadata: {},
95
+ },
96
+ failures: [],
97
+ };
98
+ }
99
+ function extractMetadataFields(extractBlock, draft, project) {
100
+ const metadata = {};
101
+ const missing = [];
102
+ const failures = [];
103
+ for (const [fieldName, extractionRule] of Object.entries(extractBlock)) {
104
+ try {
105
+ metadata[fieldName] = evaluateRule(extractionRule, draft, project).value;
106
+ }
107
+ catch (error) {
108
+ /* istanbul ignore next -- @preserve: catch always receives Error instances from ExtractionError */
109
+ const errorMessage = error instanceof Error ? error.message : String(error);
110
+ failures.push({
111
+ component: draft,
112
+ field: fieldName,
113
+ error: errorMessage,
114
+ });
115
+ missing.push(fieldName);
116
+ }
117
+ }
118
+ return {
119
+ metadata,
120
+ missing,
121
+ failures,
122
+ };
123
+ }
124
+ function enrichSingleComponent(draft, config, project, globMatcher, configDir) {
125
+ const module = findMatchingModule(draft.location.file, config.modules, globMatcher, configDir);
126
+ if (module === undefined) {
127
+ return componentWithEmptyMetadata(draft);
128
+ }
129
+ const detectionRule = findDetectionRule(module, draft.type);
130
+ if (detectionRule?.extract === undefined) {
131
+ return componentWithEmptyMetadata(draft);
132
+ }
133
+ const extracted = extractMetadataFields(detectionRule.extract, draft, project);
134
+ const enriched = {
135
+ ...draft,
136
+ metadata: extracted.metadata,
137
+ };
138
+ if (extracted.missing.length > 0) {
139
+ enriched._missing = extracted.missing;
140
+ }
141
+ return {
142
+ enriched,
143
+ failures: extracted.failures,
144
+ };
145
+ }
146
+ export function enrichComponents(draftComponents, config, project, globMatcher, configDir) {
147
+ const allComponents = [];
148
+ const allFailures = [];
149
+ for (const draft of draftComponents) {
150
+ const result = enrichSingleComponent(draft, config, project, globMatcher, configDir);
151
+ allComponents.push(result.enriched);
152
+ allFailures.push(...result.failures);
153
+ }
154
+ return {
155
+ components: allComponents,
156
+ failures: allFailures,
157
+ };
158
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"evaluate-extraction-rule-generic.d.ts","sourceRoot":"","sources":["../../../src/domain/value-extraction/evaluate-extraction-rule-generic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,6CAA6C,CAAA;AAC/F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAKhD,KAAK,uBAAuB,GAAG;IAAE,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAA;AA+BlD,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,4BAA4B,EAClC,SAAS,EAAE,gBAAgB,GAC1B,uBAAuB,CAqDzB"}
1
+ {"version":3,"file":"evaluate-extraction-rule-generic.d.ts","sourceRoot":"","sources":["../../../src/domain/value-extraction/evaluate-extraction-rule-generic.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,6CAA6C,CAAA;AAC/F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAA;AAKhD,KAAK,uBAAuB,GAAG;IAAE,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAA;AAmClD,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,4BAA4B,EAClC,SAAS,EAAE,gBAAgB,GAC1B,uBAAuB,CAqDzB"}
@@ -9,11 +9,15 @@ function getInterfaceTypeArgs(classDecl, interfaceName) {
9
9
  return impl.getTypeArguments();
10
10
  }
11
11
  }
12
- const baseClass = classDecl.getBaseClass();
13
- if (baseClass !== undefined) {
14
- return getInterfaceTypeArgs(baseClass, interfaceName);
12
+ const extendsClause = classDecl.getExtends();
13
+ if (extendsClause === undefined) {
14
+ return undefined;
15
15
  }
16
- return undefined;
16
+ const baseClass = classDecl.getBaseClass();
17
+ /* v8 ignore next -- @preserve: getExtends() !== undefined guarantees getBaseClass() returns a value */
18
+ if (baseClass === undefined)
19
+ return undefined;
20
+ return getInterfaceTypeArgs(baseClass, interfaceName);
17
21
  }
18
22
  function extractTypeNames(typeNode) {
19
23
  if (typeNode.getKind() === SyntaxKind.UnionType) {
@@ -1 +1 @@
1
- {"version":3,"file":"evaluate-extraction-rule.d.ts","sourceRoot":"","sources":["../../../src/domain/value-extraction/evaluate-extraction-rule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,qBAAqB,EACrB,2BAA2B,EAC3B,4BAA4B,EAC5B,0BAA0B,EAC1B,0BAA0B,EAC1B,8BAA8B,EAC9B,+BAA+B,EAChC,MAAM,6CAA6C,CAAA;AAEpD,OAAO,EACL,+BAA+B,EAC/B,iCAAiC,EACjC,6BAA6B,EAC7B,KAAK,aAAa,EAClB,KAAK,eAAe,GACrB,MAAM,mCAAmC,CAAA;AAE1C,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAA;AAC/E,OAAO,KAAK,EACV,gBAAgB,EAAE,iBAAiB,EAAE,SAAS,EAC/C,MAAM,UAAU,CAAA;AAQjB,MAAM,MAAM,iBAAiB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAA;AAEpD,KAAK,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,CAAA;AAE3D,MAAM,MAAM,gBAAgB,GAAG;IAAE,KAAK,EAAE,eAAe,CAAA;CAAE,CAAA;AAMzD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,qBAAqB,GAAG,gBAAgB,CAEjF;AAED,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,2BAA2B,EACjC,SAAS,EAAE,gBAAgB,GAC1B,gBAAgB,CAalB;AAED,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,4BAA4B,EAClC,UAAU,EAAE,iBAAiB,GAC5B,gBAAgB,CAalB;AAED,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,0BAA0B,EAChC,QAAQ,EAAE,MAAM,GACf,gBAAgB,CA6BlB;AAkCD,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,0BAA0B,EAChC,SAAS,EAAE,gBAAgB,GAC1B,gBAAgB,CAgClB;AA8GD,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,8BAA8B,EACpC,SAAS,EAAE,SAAS,GACnB,gBAAgB,CAelB;AAED,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,+BAA+B,EACrC,SAAS,EAAE,SAAS,GACnB,gBAAgB,CAkBlB"}
1
+ {"version":3,"file":"evaluate-extraction-rule.d.ts","sourceRoot":"","sources":["../../../src/domain/value-extraction/evaluate-extraction-rule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,qBAAqB,EACrB,2BAA2B,EAC3B,4BAA4B,EAC5B,0BAA0B,EAC1B,0BAA0B,EAC1B,8BAA8B,EAC9B,+BAA+B,EAChC,MAAM,6CAA6C,CAAA;AAEpD,OAAO,EACL,+BAA+B,EAC/B,iCAAiC,EACjC,6BAA6B,EAC7B,KAAK,aAAa,EAClB,KAAK,eAAe,GACrB,MAAM,mCAAmC,CAAA;AAE1C,OAAO,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAA;AAC/E,OAAO,KAAK,EACV,gBAAgB,EAAE,iBAAiB,EAAE,SAAS,EAC/C,MAAM,UAAU,CAAA;AAQjB,MAAM,MAAM,iBAAiB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAA;AAEpD,KAAK,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,CAAA;AAE3D,MAAM,MAAM,gBAAgB,GAAG;IAAE,KAAK,EAAE,eAAe,CAAA;CAAE,CAAA;AAMzD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,qBAAqB,GAAG,gBAAgB,CAEjF;AAED,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,2BAA2B,EACjC,SAAS,EAAE,gBAAgB,GAC1B,gBAAgB,CAalB;AAED,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,4BAA4B,EAClC,UAAU,EAAE,iBAAiB,GAC5B,gBAAgB,CAalB;AAED,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,0BAA0B,EAChC,QAAQ,EAAE,MAAM,GACf,gBAAgB,CA6BlB;AAqCD,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,0BAA0B,EAChC,SAAS,EAAE,gBAAgB,GAC1B,gBAAgB,CAgClB;AA8GD,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,8BAA8B,EACpC,SAAS,EAAE,SAAS,GACnB,gBAAgB,CAelB;AAED,wBAAgB,6BAA6B,CAC3C,IAAI,EAAE,+BAA+B,EACrC,SAAS,EAAE,SAAS,GACnB,gBAAgB,CAkBlB"}
@@ -58,10 +58,13 @@ function findPropertyInHierarchy(classDecl, propertyName, isStatic) {
58
58
  line: property.getStartLineNumber(),
59
59
  };
60
60
  }
61
- const baseClass = classDecl.getBaseClass();
62
- if (baseClass === undefined) {
61
+ if (classDecl.getExtends() === undefined) {
63
62
  return undefined;
64
63
  }
64
+ const baseClass = classDecl.getBaseClass();
65
+ /* v8 ignore next -- @preserve: getExtends() !== undefined guarantees getBaseClass() returns a value */
66
+ if (baseClass === undefined)
67
+ return undefined;
65
68
  return findPropertyInHierarchy(baseClass, propertyName, isStatic);
66
69
  }
67
70
  export function evaluateFromPropertyRule(rule, classDecl) {
@@ -4,4 +4,5 @@ export { resolveConfig, type ConfigLoader } from '../domain/config-resolution/re
4
4
  export { ConfigLoaderRequiredError, MissingComponentRuleError, } from '../domain/config-resolution/config-resolution-errors';
5
5
  export { evaluateLiteralRule, evaluateFromClassNameRule, evaluateFromMethodNameRule, evaluateFromFilePathRule, evaluateFromPropertyRule, evaluateFromDecoratorArgRule, evaluateFromDecoratorNameRule, evaluateFromGenericArgRule, evaluateFromMethodSignatureRule, evaluateFromConstructorParamsRule, evaluateFromParameterTypeRule, applyTransforms, ExtractionError, type ExtractionContext, type ExtractionResult, type ParameterInfo, type MethodSignature, } from '../domain/value-extraction';
6
6
  export { matchesGlob } from '../platform/infra/glob-matching/minimatch-glob';
7
+ export { enrichComponents, type EnrichedComponent, type EnrichmentFailure, type EnrichmentResult, } from '../domain/value-extraction/enrich-components';
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/shell/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,KAAK,cAAc,EACnB,KAAK,WAAW,GACjB,MAAM,0CAA0C,CAAA;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mDAAmD,CAAA;AACrF,OAAO,EACL,aAAa,EAAE,KAAK,YAAY,EACjC,MAAM,4CAA4C,CAAA;AACnD,OAAO,EACL,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,sDAAsD,CAAA;AAC7D,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,0BAA0B,EAC1B,wBAAwB,EACxB,wBAAwB,EACxB,4BAA4B,EAC5B,6BAA6B,EAC7B,0BAA0B,EAC1B,+BAA+B,EAC/B,iCAAiC,EACjC,6BAA6B,EAC7B,eAAe,EACf,eAAe,EACf,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,eAAe,GACrB,MAAM,4BAA4B,CAAA;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,gDAAgD,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/shell/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,KAAK,cAAc,EACnB,KAAK,WAAW,GACjB,MAAM,0CAA0C,CAAA;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mDAAmD,CAAA;AACrF,OAAO,EACL,aAAa,EAAE,KAAK,YAAY,EACjC,MAAM,4CAA4C,CAAA;AACnD,OAAO,EACL,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,sDAAsD,CAAA;AAC7D,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,0BAA0B,EAC1B,wBAAwB,EACxB,wBAAwB,EACxB,4BAA4B,EAC5B,6BAA6B,EAC7B,0BAA0B,EAC1B,+BAA+B,EAC/B,iCAAiC,EACjC,6BAA6B,EAC7B,eAAe,EACf,eAAe,EACf,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,eAAe,GACrB,MAAM,4BAA4B,CAAA;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,gDAAgD,CAAA;AAC5E,OAAO,EACL,gBAAgB,EAChB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,GACtB,MAAM,8CAA8C,CAAA"}
@@ -4,3 +4,4 @@ export { resolveConfig } from '../domain/config-resolution/resolve-config';
4
4
  export { ConfigLoaderRequiredError, MissingComponentRuleError, } from '../domain/config-resolution/config-resolution-errors';
5
5
  export { evaluateLiteralRule, evaluateFromClassNameRule, evaluateFromMethodNameRule, evaluateFromFilePathRule, evaluateFromPropertyRule, evaluateFromDecoratorArgRule, evaluateFromDecoratorNameRule, evaluateFromGenericArgRule, evaluateFromMethodSignatureRule, evaluateFromConstructorParamsRule, evaluateFromParameterTypeRule, applyTransforms, ExtractionError, } from '../domain/value-extraction';
6
6
  export { matchesGlob } from '../platform/infra/glob-matching/minimatch-glob';
7
+ export { enrichComponents, } from '../domain/value-extraction/enrich-components';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@living-architecture/riviere-extract-ts",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -24,6 +24,6 @@
24
24
  "dependencies": {
25
25
  "minimatch": "^10.0.1",
26
26
  "ts-morph": "^24.0.0",
27
- "@living-architecture/riviere-extract-config": "0.4.0"
27
+ "@living-architecture/riviere-extract-config": "0.4.1"
28
28
  }
29
29
  }