@linklabjs/core 0.1.0 → 0.1.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 (206) hide show
  1. package/dist/api/DomainNode.d.ts +154 -0
  2. package/dist/api/DomainNode.d.ts.map +1 -0
  3. package/dist/api/DomainNode.js +1157 -0
  4. package/dist/api/DomainNode.js.map +1 -0
  5. package/dist/api/Graph.d.ts +117 -0
  6. package/dist/api/Graph.d.ts.map +1 -0
  7. package/dist/api/Graph.js +212 -0
  8. package/dist/api/Graph.js.map +1 -0
  9. package/dist/api/PathBuilder.d.ts +76 -0
  10. package/dist/api/PathBuilder.d.ts.map +1 -0
  11. package/dist/api/PathBuilder.js +182 -0
  12. package/dist/api/PathBuilder.js.map +1 -0
  13. package/dist/api/index.d.ts +8 -0
  14. package/dist/api/index.d.ts.map +1 -0
  15. package/dist/api/index.js +7 -0
  16. package/dist/api/index.js.map +1 -0
  17. package/dist/api/loadGraph.d.ts +57 -0
  18. package/dist/api/loadGraph.d.ts.map +1 -0
  19. package/dist/api/loadGraph.js +153 -0
  20. package/dist/api/loadGraph.js.map +1 -0
  21. package/dist/api/test-api.d.ts +9 -0
  22. package/dist/api/test-api.d.ts.map +1 -0
  23. package/dist/api/test-api.js +133 -0
  24. package/dist/api/test-api.js.map +1 -0
  25. package/dist/api/test-domain.d.ts +13 -0
  26. package/dist/api/test-domain.d.ts.map +1 -0
  27. package/dist/api/test-domain.js +105 -0
  28. package/dist/api/test-domain.js.map +1 -0
  29. package/dist/api/types.d.ts +69 -0
  30. package/dist/api/types.d.ts.map +1 -0
  31. package/dist/api/types.js +22 -0
  32. package/dist/api/types.js.map +1 -0
  33. package/dist/config/synonyms.json +25 -0
  34. package/dist/core/EventBus.d.ts +56 -0
  35. package/dist/core/EventBus.d.ts.map +1 -0
  36. package/dist/core/EventBus.js +147 -0
  37. package/dist/core/EventBus.js.map +1 -0
  38. package/dist/core/GraphEvents.d.ts +118 -0
  39. package/dist/core/GraphEvents.d.ts.map +1 -0
  40. package/dist/core/GraphEvents.js +23 -0
  41. package/dist/core/GraphEvents.js.map +1 -0
  42. package/dist/core/PathFinder.d.ts +43 -0
  43. package/dist/core/PathFinder.d.ts.map +1 -0
  44. package/dist/core/PathFinder.js +264 -0
  45. package/dist/core/PathFinder.js.map +1 -0
  46. package/dist/formatters/BaseFormatter.d.ts +15 -0
  47. package/dist/formatters/BaseFormatter.d.ts.map +1 -0
  48. package/dist/formatters/BaseFormatter.js +9 -0
  49. package/dist/formatters/BaseFormatter.js.map +1 -0
  50. package/dist/graph/GraphAssembler.d.ts +14 -0
  51. package/dist/graph/GraphAssembler.d.ts.map +1 -0
  52. package/dist/graph/GraphAssembler.js +44 -0
  53. package/dist/graph/GraphAssembler.js.map +1 -0
  54. package/dist/graph/GraphCompiler.d.ts +37 -0
  55. package/dist/graph/GraphCompiler.d.ts.map +1 -0
  56. package/dist/graph/GraphCompiler.js +355 -0
  57. package/dist/graph/GraphCompiler.js.map +1 -0
  58. package/dist/graph/GraphExtractor.d.ts +21 -0
  59. package/dist/graph/GraphExtractor.d.ts.map +1 -0
  60. package/dist/graph/GraphExtractor.js +145 -0
  61. package/dist/graph/GraphExtractor.js.map +1 -0
  62. package/dist/graph/GraphOptimizer.d.ts +104 -0
  63. package/dist/graph/GraphOptimizer.d.ts.map +1 -0
  64. package/dist/graph/GraphOptimizer.js +306 -0
  65. package/dist/graph/GraphOptimizer.js.map +1 -0
  66. package/dist/graph/GraphTrainer.d.ts +52 -0
  67. package/dist/graph/GraphTrainer.d.ts.map +1 -0
  68. package/dist/graph/GraphTrainer.js +188 -0
  69. package/dist/graph/GraphTrainer.js.map +1 -0
  70. package/dist/http/LinkBuilder.d.ts +82 -0
  71. package/dist/http/LinkBuilder.d.ts.map +1 -0
  72. package/dist/http/LinkBuilder.js +190 -0
  73. package/dist/http/LinkBuilder.js.map +1 -0
  74. package/dist/http/TrailRequest.d.ts +39 -0
  75. package/dist/http/TrailRequest.d.ts.map +1 -0
  76. package/dist/http/TrailRequest.js +22 -0
  77. package/dist/http/TrailRequest.js.map +1 -0
  78. package/dist/http/example-netflix.d.ts +6 -0
  79. package/dist/http/example-netflix.d.ts.map +1 -0
  80. package/dist/http/example-netflix.js +52 -0
  81. package/dist/http/example-netflix.js.map +1 -0
  82. package/dist/http/index.d.ts +32 -0
  83. package/dist/http/index.d.ts.map +1 -0
  84. package/dist/http/index.js +27 -0
  85. package/dist/http/index.js.map +1 -0
  86. package/dist/http/plugin.d.ts +110 -0
  87. package/dist/http/plugin.d.ts.map +1 -0
  88. package/dist/http/plugin.js +217 -0
  89. package/dist/http/plugin.js.map +1 -0
  90. package/dist/index.d.ts +55 -0
  91. package/dist/index.d.ts.map +1 -0
  92. package/dist/index.js +71 -0
  93. package/dist/index.js.map +1 -0
  94. package/dist/instrumentation/TelemetryShim.d.ts +114 -0
  95. package/dist/instrumentation/TelemetryShim.d.ts.map +1 -0
  96. package/dist/instrumentation/TelemetryShim.js +107 -0
  97. package/dist/instrumentation/TelemetryShim.js.map +1 -0
  98. package/dist/navigation/NavigationEngine.d.ts +69 -0
  99. package/dist/navigation/NavigationEngine.d.ts.map +1 -0
  100. package/dist/navigation/NavigationEngine.js +361 -0
  101. package/dist/navigation/NavigationEngine.js.map +1 -0
  102. package/dist/navigation/Resolver.d.ts +35 -0
  103. package/dist/navigation/Resolver.d.ts.map +1 -0
  104. package/dist/navigation/Resolver.js +113 -0
  105. package/dist/navigation/Resolver.js.map +1 -0
  106. package/dist/navigation/Scheduler.d.ts +36 -0
  107. package/dist/navigation/Scheduler.d.ts.map +1 -0
  108. package/dist/navigation/Scheduler.js +107 -0
  109. package/dist/navigation/Scheduler.js.map +1 -0
  110. package/dist/navigation/Trail.d.ts +129 -0
  111. package/dist/navigation/Trail.d.ts.map +1 -0
  112. package/dist/navigation/Trail.js +202 -0
  113. package/dist/navigation/Trail.js.map +1 -0
  114. package/dist/navigation/TrailParser.d.ts +96 -0
  115. package/dist/navigation/TrailParser.d.ts.map +1 -0
  116. package/dist/navigation/TrailParser.js +180 -0
  117. package/dist/navigation/TrailParser.js.map +1 -0
  118. package/dist/navigation/index.d.ts +10 -0
  119. package/dist/navigation/index.d.ts.map +1 -0
  120. package/dist/navigation/index.js +9 -0
  121. package/dist/navigation/index.js.map +1 -0
  122. package/dist/providers/MockProvider.d.ts +29 -0
  123. package/dist/providers/MockProvider.d.ts.map +1 -0
  124. package/dist/providers/MockProvider.js +55 -0
  125. package/dist/providers/MockProvider.js.map +1 -0
  126. package/dist/providers/PostgresProvider.d.ts +46 -0
  127. package/dist/providers/PostgresProvider.d.ts.map +1 -0
  128. package/dist/providers/PostgresProvider.js +152 -0
  129. package/dist/providers/PostgresProvider.js.map +1 -0
  130. package/dist/runtime/CompiledGraphEngine.d.ts +74 -0
  131. package/dist/runtime/CompiledGraphEngine.d.ts.map +1 -0
  132. package/dist/runtime/CompiledGraphEngine.js +211 -0
  133. package/dist/runtime/CompiledGraphEngine.js.map +1 -0
  134. package/dist/runtime/DataLoader.d.ts +90 -0
  135. package/dist/runtime/DataLoader.d.ts.map +1 -0
  136. package/dist/runtime/DataLoader.js +178 -0
  137. package/dist/runtime/DataLoader.js.map +1 -0
  138. package/dist/runtime/Engine.d.ts +36 -0
  139. package/dist/runtime/Engine.d.ts.map +1 -0
  140. package/dist/runtime/Engine.js +128 -0
  141. package/dist/runtime/Engine.js.map +1 -0
  142. package/dist/runtime/QueryEngine.d.ts +80 -0
  143. package/dist/runtime/QueryEngine.d.ts.map +1 -0
  144. package/dist/runtime/QueryEngine.js +188 -0
  145. package/dist/runtime/QueryEngine.js.map +1 -0
  146. package/dist/scenarios/test-metro-paris/config.json +6 -0
  147. package/dist/scenarios/test-metro-paris/graph.json +16325 -0
  148. package/dist/scenarios/test-metro-paris/queries.d.ts +22 -0
  149. package/dist/scenarios/test-metro-paris/queries.d.ts.map +1 -0
  150. package/dist/scenarios/test-metro-paris/queries.js +128 -0
  151. package/dist/scenarios/test-metro-paris/queries.js.map +1 -0
  152. package/dist/scenarios/test-metro-paris/stack.json +1 -0
  153. package/dist/scenarios/test-musicians/config.json +10 -0
  154. package/dist/scenarios/test-musicians/graph.json +20 -0
  155. package/dist/scenarios/test-musicians/stack.json +1 -0
  156. package/dist/scenarios/test-netflix/actions.d.ts +14 -0
  157. package/dist/scenarios/test-netflix/actions.d.ts.map +1 -0
  158. package/dist/scenarios/test-netflix/actions.js +86 -0
  159. package/dist/scenarios/test-netflix/actions.js.map +1 -0
  160. package/dist/scenarios/test-netflix/config.json +6 -0
  161. package/dist/scenarios/test-netflix/data/categories.json +1 -0
  162. package/dist/scenarios/test-netflix/data/companies.json +1 -0
  163. package/dist/scenarios/test-netflix/data/credits.json +19797 -0
  164. package/dist/scenarios/test-netflix/data/departments.json +18 -0
  165. package/dist/scenarios/test-netflix/data/jobs.json +142 -0
  166. package/dist/scenarios/test-netflix/data/movies.json +3497 -0
  167. package/dist/scenarios/test-netflix/data/people.json +1 -0
  168. package/dist/scenarios/test-netflix/data/synonyms.json +7 -0
  169. package/dist/scenarios/test-netflix/data/users.json +70 -0
  170. package/dist/scenarios/test-netflix/graph.json +1017 -0
  171. package/dist/scenarios/test-netflix/queries.d.ts +29 -0
  172. package/dist/scenarios/test-netflix/queries.d.ts.map +1 -0
  173. package/dist/scenarios/test-netflix/queries.js +134 -0
  174. package/dist/scenarios/test-netflix/queries.js.map +1 -0
  175. package/dist/scenarios/test-netflix/stack.json +14 -0
  176. package/dist/schema/GraphBuilder.d.ts +9 -0
  177. package/dist/schema/GraphBuilder.d.ts.map +1 -0
  178. package/dist/schema/GraphBuilder.js +90 -0
  179. package/dist/schema/GraphBuilder.js.map +1 -0
  180. package/dist/schema/JsonSchemaExtractor.d.ts +21 -0
  181. package/dist/schema/JsonSchemaExtractor.d.ts.map +1 -0
  182. package/dist/schema/JsonSchemaExtractor.js +88 -0
  183. package/dist/schema/JsonSchemaExtractor.js.map +1 -0
  184. package/dist/schema/SchemaAnalyzer.d.ts +41 -0
  185. package/dist/schema/SchemaAnalyzer.d.ts.map +1 -0
  186. package/dist/schema/SchemaAnalyzer.js +144 -0
  187. package/dist/schema/SchemaAnalyzer.js.map +1 -0
  188. package/dist/schema/SchemaExtractor.d.ts +10 -0
  189. package/dist/schema/SchemaExtractor.d.ts.map +1 -0
  190. package/dist/schema/SchemaExtractor.js +90 -0
  191. package/dist/schema/SchemaExtractor.js.map +1 -0
  192. package/dist/schema/SynonymResolver.d.ts +55 -0
  193. package/dist/schema/SynonymResolver.d.ts.map +1 -0
  194. package/dist/schema/SynonymResolver.js +121 -0
  195. package/dist/schema/SynonymResolver.js.map +1 -0
  196. package/dist/scripts/dictionary.json +796 -0
  197. package/dist/scripts/graph.json +664 -0
  198. package/dist/scripts/regenerate.d.ts +23 -0
  199. package/dist/scripts/regenerate.d.ts.map +1 -0
  200. package/dist/scripts/regenerate.js +206 -0
  201. package/dist/scripts/regenerate.js.map +1 -0
  202. package/dist/types/index.d.ts +394 -0
  203. package/dist/types/index.d.ts.map +1 -0
  204. package/dist/types/index.js +21 -0
  205. package/dist/types/index.js.map +1 -0
  206. package/package.json +1 -1
@@ -0,0 +1,90 @@
1
+ import fs from 'fs';
2
+ export class SchemaExtractor {
3
+ provider;
4
+ constructor(provider) {
5
+ this.provider = provider;
6
+ }
7
+ async extract(databaseName) {
8
+ console.log(`🔍 Extraction du schéma technique pour : ${databaseName}`);
9
+ const tables = await this.getTables();
10
+ const entities = [];
11
+ for (const tableName of tables) {
12
+ const properties = await this.getProperties(tableName);
13
+ const rowCount = await this.getRowCount(tableName);
14
+ entities.push({
15
+ name: tableName,
16
+ properties,
17
+ rowCount
18
+ });
19
+ }
20
+ const schema = {
21
+ source: {
22
+ type: 'postgresql',
23
+ name: databaseName,
24
+ generatedAt: new Date().toISOString()
25
+ },
26
+ entities
27
+ };
28
+ fs.writeFileSync('./schema.json', JSON.stringify(schema, null, 2));
29
+ return schema;
30
+ }
31
+ async getTables() {
32
+ const query = `
33
+ SELECT table_name FROM information_schema.tables
34
+ WHERE table_schema = 'public' AND table_type = 'BASE TABLE'
35
+ `;
36
+ const rows = await this.provider.query(query);
37
+ return rows.map(r => r.table_name);
38
+ }
39
+ async getProperties(tableName) {
40
+ const query = `
41
+ SELECT
42
+ cols.column_name as name,
43
+ cols.data_type as type,
44
+ -- Détection Primary Key
45
+ EXISTS (
46
+ SELECT 1 FROM information_schema.table_constraints tc
47
+ JOIN information_schema.key_column_usage kcu ON tc.constraint_name = kcu.constraint_name
48
+ WHERE tc.table_name = cols.table_name AND kcu.column_name = cols.column_name
49
+ AND tc.constraint_type = 'PRIMARY KEY'
50
+ ) as is_pk,
51
+ -- Détection Foreign Key Target
52
+ ccu.table_name as fk_target_table,
53
+ ccu.column_name as fk_target_column,
54
+ -- Détection Index
55
+ EXISTS (
56
+ SELECT 1 FROM pg_index i
57
+ JOIN pg_class c ON c.oid = i.indrelid
58
+ JOIN pg_attribute a ON a.attrelid = c.oid AND a.attnum = ANY(i.indkey)
59
+ WHERE c.relname = cols.table_name AND a.attname = cols.column_name
60
+ ) as is_indexed
61
+ FROM information_schema.columns cols
62
+ LEFT JOIN information_schema.key_column_usage kcu
63
+ ON cols.table_name = kcu.table_name AND cols.column_name = kcu.column_name
64
+ LEFT JOIN information_schema.referential_constraints rc
65
+ ON kcu.constraint_name = rc.constraint_name
66
+ LEFT JOIN information_schema.constraint_column_usage ccu
67
+ ON rc.unique_constraint_name = ccu.constraint_name
68
+ WHERE cols.table_name = $1
69
+ `;
70
+ const rows = await this.provider.query(query, [tableName]);
71
+ return rows.map(r => ({
72
+ name: r.name,
73
+ type: r.type,
74
+ isPK: r.is_pk,
75
+ isFK: !!r.fk_target_table,
76
+ references: r.fk_target_table
77
+ ? {
78
+ table: r.fk_target_table,
79
+ column: r.fk_target_column
80
+ }
81
+ : undefined,
82
+ isIndexed: r.is_indexed
83
+ }));
84
+ }
85
+ async getRowCount(tableName) {
86
+ const res = await this.provider.query(`SELECT reltuples::bigint as count FROM pg_class WHERE relname = $1`, [tableName]);
87
+ return parseInt(res[0]?.count || '0', 10);
88
+ }
89
+ }
90
+ //# sourceMappingURL=SchemaExtractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SchemaExtractor.js","sourceRoot":"","sources":["../../src/schema/SchemaExtractor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAA;AAGnB,MAAM,OAAO,eAAe;IACN;IAApB,YAAoB,QAAkB;QAAlB,aAAQ,GAAR,QAAQ,CAAU;IAAG,CAAC;IAE1C,KAAK,CAAC,OAAO,CAAC,YAAoB;QAChC,OAAO,CAAC,GAAG,CAAC,4CAA4C,YAAY,EAAE,CAAC,CAAA;QAEvE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAA;QACrC,MAAM,QAAQ,GAAiB,EAAE,CAAA;QAEjC,KAAK,MAAM,SAAS,IAAI,MAAM,EAAE,CAAC;YAC/B,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAA;YACtD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAA;YAElD,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,SAAS;gBACf,UAAU;gBACV,QAAQ;aACT,CAAC,CAAA;QACJ,CAAC;QAED,MAAM,MAAM,GAAoB;YAC9B,MAAM,EAAE;gBACN,IAAI,EAAE,YAAY;gBAClB,IAAI,EAAE,YAAY;gBAClB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACtC;YACD,QAAQ;SACT,CAAA;QAED,EAAE,CAAC,aAAa,CAAC,eAAe,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;QAClE,OAAO,MAAM,CAAA;IACf,CAAC;IAEO,KAAK,CAAC,SAAS;QACrB,MAAM,KAAK,GAAG;;;KAGb,CAAA;QACD,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAyB,KAAK,CAAC,CAAA;QACrE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAA;IACpC,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,SAAiB;QAC3C,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA6Bb,CAAA;QAED,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAM,KAAK,EAAE,CAAC,SAAS,CAAC,CAAC,CAAA;QAE/D,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACpB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,IAAI,EAAE,CAAC,CAAC,KAAK;YACb,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,eAAe;YACzB,UAAU,EAAE,CAAC,CAAC,eAAe;gBAC3B,CAAC,CAAC;oBACE,KAAK,EAAE,CAAC,CAAC,eAAe;oBACxB,MAAM,EAAE,CAAC,CAAC,gBAAgB;iBAC3B;gBACH,CAAC,CAAC,SAAS;YACb,SAAS,EAAE,CAAC,CAAC,UAAU;SACxB,CAAC,CAAC,CAAA;IACL,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,SAAiB;QACzC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CACnC,oEAAoE,EACpE,CAAC,SAAS,CAAC,CACZ,CAAA;QACD,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,GAAG,EAAE,EAAE,CAAC,CAAA;IAC3C,CAAC;CACF"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * SynonymResolver — Résolution de noms de tables par convention et synonymes
3
+ *
4
+ * Utilisé par :
5
+ * JsonSchemaExtractor — résolution FK par convention de nommage
6
+ * SchemaAnalyzer — détection FK implicites (store_id → store)
7
+ * GraphBuilder — à venir
8
+ *
9
+ * Sources de synonymes (fusionnées dans l'ordre) :
10
+ * 1. config/synonyms.json — irréguliers universels (livré avec LinkLab)
11
+ * 2. <projectPath>/synonyms.json — spécifiques au projet (optionnel)
12
+ *
13
+ * Stratégies de résolution dans l'ordre :
14
+ * 1. Correspondance directe prefix === tableName
15
+ * 2. Synonyme explicite synonyms[prefix] === tableName
16
+ * 3. Pluriel régulier +s prefix + 's'
17
+ * 4. Pluriel en -ies category → categories
18
+ * 5. Pluriel en -es address → addresses
19
+ */
20
+ export declare class SynonymResolver {
21
+ private configPath;
22
+ private projectPath?;
23
+ private synonyms;
24
+ constructor(configPath?: string, projectPath?: string | undefined);
25
+ private load;
26
+ /** Filtre les clés de commentaire (_comment, etc.) */
27
+ private filter;
28
+ /**
29
+ * Résout un préfixe vers un nom de table existant.
30
+ * Retourne null si aucune table ne correspond.
31
+ *
32
+ * @param prefix Préfixe extrait du nom de colonne (ex: "person" depuis "personId")
33
+ * @param tableNames Liste des noms de tables disponibles
34
+ */
35
+ resolve(prefix: string, tableNames: string[]): string | null;
36
+ /**
37
+ * Extrait le préfixe d'un nom de colonne FK.
38
+ * Gère les conventions camelCase et snake_case.
39
+ *
40
+ * Exemples :
41
+ * personId → person
42
+ * person_id → person
43
+ * movieId → movie
44
+ * manager_staff_id → manager_staff (FK complexe — peut ne pas résoudre)
45
+ */
46
+ extractPrefix(columnName: string): string;
47
+ /**
48
+ * Résout directement depuis un nom de colonne FK.
49
+ * Combine extractPrefix + resolve.
50
+ */
51
+ resolveColumn(columnName: string, tableNames: string[]): string | null;
52
+ getSynonyms(): Record<string, string>;
53
+ has(prefix: string): boolean;
54
+ }
55
+ //# sourceMappingURL=SynonymResolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SynonymResolver.d.ts","sourceRoot":"","sources":["../../src/schema/SynonymResolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAKH,qBAAa,eAAe;IAKxB,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,WAAW,CAAC;IAJtB,OAAO,CAAC,QAAQ,CAAwB;gBAG9B,UAAU,GAAE,MAA2C,EACvD,WAAW,CAAC,EAAE,MAAM,YAAA;IAO9B,OAAO,CAAC,IAAI;IA+BZ,sDAAsD;IACtD,OAAO,CAAC,MAAM;IAQd;;;;;;OAMG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI;IAwB5D;;;;;;;;;OASG;IACH,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAOzC;;;OAGG;IACH,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI;IAOtE,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAIrC,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;CAG7B"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * SynonymResolver — Résolution de noms de tables par convention et synonymes
3
+ *
4
+ * Utilisé par :
5
+ * JsonSchemaExtractor — résolution FK par convention de nommage
6
+ * SchemaAnalyzer — détection FK implicites (store_id → store)
7
+ * GraphBuilder — à venir
8
+ *
9
+ * Sources de synonymes (fusionnées dans l'ordre) :
10
+ * 1. config/synonyms.json — irréguliers universels (livré avec LinkLab)
11
+ * 2. <projectPath>/synonyms.json — spécifiques au projet (optionnel)
12
+ *
13
+ * Stratégies de résolution dans l'ordre :
14
+ * 1. Correspondance directe prefix === tableName
15
+ * 2. Synonyme explicite synonyms[prefix] === tableName
16
+ * 3. Pluriel régulier +s prefix + 's'
17
+ * 4. Pluriel en -ies category → categories
18
+ * 5. Pluriel en -es address → addresses
19
+ */
20
+ import fs from 'fs';
21
+ import path from 'path';
22
+ export class SynonymResolver {
23
+ configPath;
24
+ projectPath;
25
+ synonyms;
26
+ constructor(configPath = path.join(process.cwd(), 'config'), projectPath) {
27
+ this.configPath = configPath;
28
+ this.projectPath = projectPath;
29
+ this.synonyms = this.load();
30
+ }
31
+ // ─── Chargement ────────────────────────────────────────────────────────────
32
+ load() {
33
+ const universalPath = path.join(this.configPath, 'synonyms.json');
34
+ const projectPath = this.projectPath
35
+ ? path.join(this.projectPath, 'synonyms.json')
36
+ : null;
37
+ let universal = {};
38
+ let project = {};
39
+ if (fs.existsSync(universalPath)) {
40
+ universal = this.filter(JSON.parse(fs.readFileSync(universalPath, 'utf-8')));
41
+ }
42
+ else {
43
+ console.warn(` ⚠️ SynonymResolver — config/synonyms.json introuvable : ${universalPath}`);
44
+ }
45
+ if (projectPath && fs.existsSync(projectPath)) {
46
+ project = this.filter(JSON.parse(fs.readFileSync(projectPath, 'utf-8')));
47
+ }
48
+ const merged = { ...universal, ...project };
49
+ const counts = [
50
+ `universels: ${Object.keys(universal).length}`,
51
+ Object.keys(project).length ? `projet: ${Object.keys(project).length}` : null,
52
+ `total: ${Object.keys(merged).length}`
53
+ ].filter(Boolean).join(', ');
54
+ console.log(` 📖 Synonymes (${counts})`);
55
+ return merged;
56
+ }
57
+ /** Filtre les clés de commentaire (_comment, etc.) */
58
+ filter(raw) {
59
+ return Object.fromEntries(Object.entries(raw).filter(([k]) => !k.startsWith('_')));
60
+ }
61
+ // ─── Résolution ────────────────────────────────────────────────────────────
62
+ /**
63
+ * Résout un préfixe vers un nom de table existant.
64
+ * Retourne null si aucune table ne correspond.
65
+ *
66
+ * @param prefix Préfixe extrait du nom de colonne (ex: "person" depuis "personId")
67
+ * @param tableNames Liste des noms de tables disponibles
68
+ */
69
+ resolve(prefix, tableNames) {
70
+ const lc = (s) => s.toLowerCase();
71
+ const p = prefix.toLowerCase();
72
+ const pluralIes = p.endsWith('y') ? p.slice(0, -1) + 'ies' : null;
73
+ const pluralEs = p.endsWith('s') || p.endsWith('x') || p.endsWith('z')
74
+ || p.endsWith('ch') || p.endsWith('sh')
75
+ ? p + 'es' : null;
76
+ return (
77
+ // 1. Correspondance directe
78
+ tableNames.find(t => lc(t) === p) ??
79
+ // 2. Synonyme explicite
80
+ tableNames.find(t => lc(t) === lc(this.synonyms[p] ?? '__none__')) ??
81
+ // 3. Pluriel régulier +s
82
+ tableNames.find(t => lc(t) === p + 's') ??
83
+ // 4. Pluriel en -ies (category → categories)
84
+ (pluralIes ? tableNames.find(t => lc(t) === pluralIes) : null) ??
85
+ // 5. Pluriel en -es (address → addresses)
86
+ (pluralEs ? tableNames.find(t => lc(t) === pluralEs) : null) ??
87
+ null);
88
+ }
89
+ /**
90
+ * Extrait le préfixe d'un nom de colonne FK.
91
+ * Gère les conventions camelCase et snake_case.
92
+ *
93
+ * Exemples :
94
+ * personId → person
95
+ * person_id → person
96
+ * movieId → movie
97
+ * manager_staff_id → manager_staff (FK complexe — peut ne pas résoudre)
98
+ */
99
+ extractPrefix(columnName) {
100
+ return columnName
101
+ .replace(/Id$/, '')
102
+ .replace(/_id$/i, '')
103
+ .toLowerCase();
104
+ }
105
+ /**
106
+ * Résout directement depuis un nom de colonne FK.
107
+ * Combine extractPrefix + resolve.
108
+ */
109
+ resolveColumn(columnName, tableNames) {
110
+ const prefix = this.extractPrefix(columnName);
111
+ return this.resolve(prefix, tableNames);
112
+ }
113
+ // ─── Inspection ────────────────────────────────────────────────────────────
114
+ getSynonyms() {
115
+ return { ...this.synonyms };
116
+ }
117
+ has(prefix) {
118
+ return prefix.toLowerCase() in this.synonyms;
119
+ }
120
+ }
121
+ //# sourceMappingURL=SynonymResolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SynonymResolver.js","sourceRoot":"","sources":["../../src/schema/SynonymResolver.ts"],"names":[],"mappings":"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"}