@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.
- package/dist/api/DomainNode.d.ts +154 -0
- package/dist/api/DomainNode.d.ts.map +1 -0
- package/dist/api/DomainNode.js +1157 -0
- package/dist/api/DomainNode.js.map +1 -0
- package/dist/api/Graph.d.ts +117 -0
- package/dist/api/Graph.d.ts.map +1 -0
- package/dist/api/Graph.js +212 -0
- package/dist/api/Graph.js.map +1 -0
- package/dist/api/PathBuilder.d.ts +76 -0
- package/dist/api/PathBuilder.d.ts.map +1 -0
- package/dist/api/PathBuilder.js +182 -0
- package/dist/api/PathBuilder.js.map +1 -0
- package/dist/api/index.d.ts +8 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +7 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/loadGraph.d.ts +57 -0
- package/dist/api/loadGraph.d.ts.map +1 -0
- package/dist/api/loadGraph.js +153 -0
- package/dist/api/loadGraph.js.map +1 -0
- package/dist/api/test-api.d.ts +9 -0
- package/dist/api/test-api.d.ts.map +1 -0
- package/dist/api/test-api.js +133 -0
- package/dist/api/test-api.js.map +1 -0
- package/dist/api/test-domain.d.ts +13 -0
- package/dist/api/test-domain.d.ts.map +1 -0
- package/dist/api/test-domain.js +105 -0
- package/dist/api/test-domain.js.map +1 -0
- package/dist/api/types.d.ts +69 -0
- package/dist/api/types.d.ts.map +1 -0
- package/dist/api/types.js +22 -0
- package/dist/api/types.js.map +1 -0
- package/dist/config/synonyms.json +25 -0
- package/dist/core/EventBus.d.ts +56 -0
- package/dist/core/EventBus.d.ts.map +1 -0
- package/dist/core/EventBus.js +147 -0
- package/dist/core/EventBus.js.map +1 -0
- package/dist/core/GraphEvents.d.ts +118 -0
- package/dist/core/GraphEvents.d.ts.map +1 -0
- package/dist/core/GraphEvents.js +23 -0
- package/dist/core/GraphEvents.js.map +1 -0
- package/dist/core/PathFinder.d.ts +43 -0
- package/dist/core/PathFinder.d.ts.map +1 -0
- package/dist/core/PathFinder.js +264 -0
- package/dist/core/PathFinder.js.map +1 -0
- package/dist/formatters/BaseFormatter.d.ts +15 -0
- package/dist/formatters/BaseFormatter.d.ts.map +1 -0
- package/dist/formatters/BaseFormatter.js +9 -0
- package/dist/formatters/BaseFormatter.js.map +1 -0
- package/dist/graph/GraphAssembler.d.ts +14 -0
- package/dist/graph/GraphAssembler.d.ts.map +1 -0
- package/dist/graph/GraphAssembler.js +44 -0
- package/dist/graph/GraphAssembler.js.map +1 -0
- package/dist/graph/GraphCompiler.d.ts +37 -0
- package/dist/graph/GraphCompiler.d.ts.map +1 -0
- package/dist/graph/GraphCompiler.js +355 -0
- package/dist/graph/GraphCompiler.js.map +1 -0
- package/dist/graph/GraphExtractor.d.ts +21 -0
- package/dist/graph/GraphExtractor.d.ts.map +1 -0
- package/dist/graph/GraphExtractor.js +145 -0
- package/dist/graph/GraphExtractor.js.map +1 -0
- package/dist/graph/GraphOptimizer.d.ts +104 -0
- package/dist/graph/GraphOptimizer.d.ts.map +1 -0
- package/dist/graph/GraphOptimizer.js +306 -0
- package/dist/graph/GraphOptimizer.js.map +1 -0
- package/dist/graph/GraphTrainer.d.ts +52 -0
- package/dist/graph/GraphTrainer.d.ts.map +1 -0
- package/dist/graph/GraphTrainer.js +188 -0
- package/dist/graph/GraphTrainer.js.map +1 -0
- package/dist/http/LinkBuilder.d.ts +82 -0
- package/dist/http/LinkBuilder.d.ts.map +1 -0
- package/dist/http/LinkBuilder.js +190 -0
- package/dist/http/LinkBuilder.js.map +1 -0
- package/dist/http/TrailRequest.d.ts +39 -0
- package/dist/http/TrailRequest.d.ts.map +1 -0
- package/dist/http/TrailRequest.js +22 -0
- package/dist/http/TrailRequest.js.map +1 -0
- package/dist/http/example-netflix.d.ts +6 -0
- package/dist/http/example-netflix.d.ts.map +1 -0
- package/dist/http/example-netflix.js +52 -0
- package/dist/http/example-netflix.js.map +1 -0
- package/dist/http/index.d.ts +32 -0
- package/dist/http/index.d.ts.map +1 -0
- package/dist/http/index.js +27 -0
- package/dist/http/index.js.map +1 -0
- package/dist/http/plugin.d.ts +110 -0
- package/dist/http/plugin.d.ts.map +1 -0
- package/dist/http/plugin.js +217 -0
- package/dist/http/plugin.js.map +1 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +71 -0
- package/dist/index.js.map +1 -0
- package/dist/instrumentation/TelemetryShim.d.ts +114 -0
- package/dist/instrumentation/TelemetryShim.d.ts.map +1 -0
- package/dist/instrumentation/TelemetryShim.js +107 -0
- package/dist/instrumentation/TelemetryShim.js.map +1 -0
- package/dist/navigation/NavigationEngine.d.ts +69 -0
- package/dist/navigation/NavigationEngine.d.ts.map +1 -0
- package/dist/navigation/NavigationEngine.js +361 -0
- package/dist/navigation/NavigationEngine.js.map +1 -0
- package/dist/navigation/Resolver.d.ts +35 -0
- package/dist/navigation/Resolver.d.ts.map +1 -0
- package/dist/navigation/Resolver.js +113 -0
- package/dist/navigation/Resolver.js.map +1 -0
- package/dist/navigation/Scheduler.d.ts +36 -0
- package/dist/navigation/Scheduler.d.ts.map +1 -0
- package/dist/navigation/Scheduler.js +107 -0
- package/dist/navigation/Scheduler.js.map +1 -0
- package/dist/navigation/Trail.d.ts +129 -0
- package/dist/navigation/Trail.d.ts.map +1 -0
- package/dist/navigation/Trail.js +202 -0
- package/dist/navigation/Trail.js.map +1 -0
- package/dist/navigation/TrailParser.d.ts +96 -0
- package/dist/navigation/TrailParser.d.ts.map +1 -0
- package/dist/navigation/TrailParser.js +180 -0
- package/dist/navigation/TrailParser.js.map +1 -0
- package/dist/navigation/index.d.ts +10 -0
- package/dist/navigation/index.d.ts.map +1 -0
- package/dist/navigation/index.js +9 -0
- package/dist/navigation/index.js.map +1 -0
- package/dist/providers/MockProvider.d.ts +29 -0
- package/dist/providers/MockProvider.d.ts.map +1 -0
- package/dist/providers/MockProvider.js +55 -0
- package/dist/providers/MockProvider.js.map +1 -0
- package/dist/providers/PostgresProvider.d.ts +46 -0
- package/dist/providers/PostgresProvider.d.ts.map +1 -0
- package/dist/providers/PostgresProvider.js +152 -0
- package/dist/providers/PostgresProvider.js.map +1 -0
- package/dist/runtime/CompiledGraphEngine.d.ts +74 -0
- package/dist/runtime/CompiledGraphEngine.d.ts.map +1 -0
- package/dist/runtime/CompiledGraphEngine.js +211 -0
- package/dist/runtime/CompiledGraphEngine.js.map +1 -0
- package/dist/runtime/DataLoader.d.ts +90 -0
- package/dist/runtime/DataLoader.d.ts.map +1 -0
- package/dist/runtime/DataLoader.js +178 -0
- package/dist/runtime/DataLoader.js.map +1 -0
- package/dist/runtime/Engine.d.ts +36 -0
- package/dist/runtime/Engine.d.ts.map +1 -0
- package/dist/runtime/Engine.js +128 -0
- package/dist/runtime/Engine.js.map +1 -0
- package/dist/runtime/QueryEngine.d.ts +80 -0
- package/dist/runtime/QueryEngine.d.ts.map +1 -0
- package/dist/runtime/QueryEngine.js +188 -0
- package/dist/runtime/QueryEngine.js.map +1 -0
- package/dist/scenarios/test-metro-paris/config.json +6 -0
- package/dist/scenarios/test-metro-paris/graph.json +16325 -0
- package/dist/scenarios/test-metro-paris/queries.d.ts +22 -0
- package/dist/scenarios/test-metro-paris/queries.d.ts.map +1 -0
- package/dist/scenarios/test-metro-paris/queries.js +128 -0
- package/dist/scenarios/test-metro-paris/queries.js.map +1 -0
- package/dist/scenarios/test-metro-paris/stack.json +1 -0
- package/dist/scenarios/test-musicians/config.json +10 -0
- package/dist/scenarios/test-musicians/graph.json +20 -0
- package/dist/scenarios/test-musicians/stack.json +1 -0
- package/dist/scenarios/test-netflix/actions.d.ts +14 -0
- package/dist/scenarios/test-netflix/actions.d.ts.map +1 -0
- package/dist/scenarios/test-netflix/actions.js +86 -0
- package/dist/scenarios/test-netflix/actions.js.map +1 -0
- package/dist/scenarios/test-netflix/config.json +6 -0
- package/dist/scenarios/test-netflix/data/categories.json +1 -0
- package/dist/scenarios/test-netflix/data/companies.json +1 -0
- package/dist/scenarios/test-netflix/data/credits.json +19797 -0
- package/dist/scenarios/test-netflix/data/departments.json +18 -0
- package/dist/scenarios/test-netflix/data/jobs.json +142 -0
- package/dist/scenarios/test-netflix/data/movies.json +3497 -0
- package/dist/scenarios/test-netflix/data/people.json +1 -0
- package/dist/scenarios/test-netflix/data/synonyms.json +7 -0
- package/dist/scenarios/test-netflix/data/users.json +70 -0
- package/dist/scenarios/test-netflix/graph.json +1017 -0
- package/dist/scenarios/test-netflix/queries.d.ts +29 -0
- package/dist/scenarios/test-netflix/queries.d.ts.map +1 -0
- package/dist/scenarios/test-netflix/queries.js +134 -0
- package/dist/scenarios/test-netflix/queries.js.map +1 -0
- package/dist/scenarios/test-netflix/stack.json +14 -0
- package/dist/schema/GraphBuilder.d.ts +9 -0
- package/dist/schema/GraphBuilder.d.ts.map +1 -0
- package/dist/schema/GraphBuilder.js +90 -0
- package/dist/schema/GraphBuilder.js.map +1 -0
- package/dist/schema/JsonSchemaExtractor.d.ts +21 -0
- package/dist/schema/JsonSchemaExtractor.d.ts.map +1 -0
- package/dist/schema/JsonSchemaExtractor.js +88 -0
- package/dist/schema/JsonSchemaExtractor.js.map +1 -0
- package/dist/schema/SchemaAnalyzer.d.ts +41 -0
- package/dist/schema/SchemaAnalyzer.d.ts.map +1 -0
- package/dist/schema/SchemaAnalyzer.js +144 -0
- package/dist/schema/SchemaAnalyzer.js.map +1 -0
- package/dist/schema/SchemaExtractor.d.ts +10 -0
- package/dist/schema/SchemaExtractor.d.ts.map +1 -0
- package/dist/schema/SchemaExtractor.js +90 -0
- package/dist/schema/SchemaExtractor.js.map +1 -0
- package/dist/schema/SynonymResolver.d.ts +55 -0
- package/dist/schema/SynonymResolver.d.ts.map +1 -0
- package/dist/schema/SynonymResolver.js +121 -0
- package/dist/schema/SynonymResolver.js.map +1 -0
- package/dist/scripts/dictionary.json +796 -0
- package/dist/scripts/graph.json +664 -0
- package/dist/scripts/regenerate.d.ts +23 -0
- package/dist/scripts/regenerate.d.ts.map +1 -0
- package/dist/scripts/regenerate.js +206 -0
- package/dist/scripts/regenerate.js.map +1 -0
- package/dist/types/index.d.ts +394 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +21 -0
- package/dist/types/index.js.map +1 -0
- 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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"}
|