@specverse/engines 6.42.3 → 6.60.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/ai/analyse-runner.d.ts.map +1 -1
- package/dist/ai/analyse-runner.js +53 -1
- package/dist/ai/analyse-runner.js.map +1 -1
- package/dist/ai/prompt-runner.d.ts +39 -1
- package/dist/ai/prompt-runner.d.ts.map +1 -1
- package/dist/ai/prompt-runner.js +44 -3
- package/dist/ai/prompt-runner.js.map +1 -1
- package/dist/ai/providers/claude-cli.d.ts.map +1 -1
- package/dist/ai/providers/claude-cli.js +8 -1
- package/dist/ai/providers/claude-cli.js.map +1 -1
- package/dist/ai/skill-loader.d.ts +50 -0
- package/dist/ai/skill-loader.d.ts.map +1 -0
- package/dist/ai/skill-loader.js +96 -0
- package/dist/ai/skill-loader.js.map +1 -0
- package/dist/analyse-prepass/adapters/index.d.ts +2 -0
- package/dist/analyse-prepass/adapters/index.d.ts.map +1 -1
- package/dist/analyse-prepass/adapters/index.js +2 -0
- package/dist/analyse-prepass/adapters/index.js.map +1 -1
- package/dist/analyse-prepass/adapters/module-functions.d.ts +95 -0
- package/dist/analyse-prepass/adapters/module-functions.d.ts.map +1 -0
- package/dist/analyse-prepass/adapters/module-functions.js +358 -0
- package/dist/analyse-prepass/adapters/module-functions.js.map +1 -0
- package/dist/analyse-prepass/adapters/naming-convention-fks.d.ts +90 -0
- package/dist/analyse-prepass/adapters/naming-convention-fks.d.ts.map +1 -0
- package/dist/analyse-prepass/adapters/naming-convention-fks.js +181 -0
- package/dist/analyse-prepass/adapters/naming-convention-fks.js.map +1 -0
- package/dist/analyse-prepass/index.d.ts +8 -0
- package/dist/analyse-prepass/index.d.ts.map +1 -1
- package/dist/analyse-prepass/index.js +130 -0
- package/dist/analyse-prepass/index.js.map +1 -1
- package/dist/libs/instance-factories/cli/templates/commander/cli-entry-generator.js +11 -12
- package/dist/libs/instance-factories/cli/templates/commander/command-generator.js +2 -2
- package/dist/libs/instance-factories/controllers/templates/fastify/routes-generator.js +29 -10
- package/dist/libs/instance-factories/services/templates/prisma/ai-behaviors-generator.js +10 -9
- package/dist/libs/instance-factories/services/templates/prisma/behavior-generator.js +24 -2
- package/dist/libs/instance-factories/services/templates/prisma/controller-generator.js +28 -20
- package/dist/normalise/index.d.ts +14 -0
- package/dist/normalise/index.d.ts.map +1 -0
- package/dist/normalise/index.js +14 -0
- package/dist/normalise/index.js.map +1 -0
- package/dist/normalise/load-overrides.d.ts +43 -0
- package/dist/normalise/load-overrides.d.ts.map +1 -0
- package/dist/normalise/load-overrides.js +121 -0
- package/dist/normalise/load-overrides.js.map +1 -0
- package/dist/normalise/normalise-rules.d.ts +181 -0
- package/dist/normalise/normalise-rules.d.ts.map +1 -0
- package/dist/normalise/normalise-rules.js +79 -0
- package/dist/normalise/normalise-rules.js.map +1 -0
- package/dist/normalise/rules/cluster-module-functions.d.ts +31 -0
- package/dist/normalise/rules/cluster-module-functions.d.ts.map +1 -0
- package/dist/normalise/rules/cluster-module-functions.js +238 -0
- package/dist/normalise/rules/cluster-module-functions.js.map +1 -0
- package/dist/normalise/rules/crud-into-curved.d.ts +117 -0
- package/dist/normalise/rules/crud-into-curved.d.ts.map +1 -0
- package/dist/normalise/rules/crud-into-curved.js +303 -0
- package/dist/normalise/rules/crud-into-curved.js.map +1 -0
- package/dist/normalise/rules/drop-trivial-passthrough.d.ts +92 -0
- package/dist/normalise/rules/drop-trivial-passthrough.d.ts.map +1 -0
- package/dist/normalise/rules/drop-trivial-passthrough.js +217 -0
- package/dist/normalise/rules/drop-trivial-passthrough.js.map +1 -0
- package/dist/normalise/runner.d.ts +58 -0
- package/dist/normalise/runner.d.ts.map +1 -0
- package/dist/normalise/runner.js +114 -0
- package/dist/normalise/runner.js.map +1 -0
- package/dist/parser/import-resolver/resolver.js +1 -1
- package/dist/parser/import-resolver/resolver.js.map +1 -1
- package/dist/realize/engines/typescript-engine.js +1 -1
- package/dist/realize/engines/typescript-engine.js.map +1 -1
- package/dist/realize/index.d.ts.map +1 -1
- package/dist/realize/index.js +221 -88
- package/dist/realize/index.js.map +1 -1
- package/dist/realize/library/library.js +1 -1
- package/dist/realize/library/library.js.map +1 -1
- package/dist/realize/library/resolver.d.ts.map +1 -1
- package/dist/realize/library/resolver.js +14 -1
- package/dist/realize/library/resolver.js.map +1 -1
- package/dist/realize/owner-emit-shared.d.ts +114 -0
- package/dist/realize/owner-emit-shared.d.ts.map +1 -0
- package/dist/realize/owner-emit-shared.js +227 -0
- package/dist/realize/owner-emit-shared.js.map +1 -0
- package/dist/realize/per-action-recovery.d.ts +74 -0
- package/dist/realize/per-action-recovery.d.ts.map +1 -0
- package/dist/realize/per-action-recovery.js +268 -0
- package/dist/realize/per-action-recovery.js.map +1 -0
- package/dist/realize/per-owner-emit.d.ts +7 -58
- package/dist/realize/per-owner-emit.d.ts.map +1 -1
- package/dist/realize/per-owner-emit.js +67 -215
- package/dist/realize/per-owner-emit.js.map +1 -1
- package/dist/realize/per-owner-runner.d.ts +24 -4
- package/dist/realize/per-owner-runner.d.ts.map +1 -1
- package/dist/realize/per-owner-runner.js +77 -19
- package/dist/realize/per-owner-runner.js.map +1 -1
- package/dist/realize/post-emit-verify/diagnostics.d.ts +107 -0
- package/dist/realize/post-emit-verify/diagnostics.d.ts.map +1 -0
- package/dist/realize/post-emit-verify/diagnostics.js +148 -0
- package/dist/realize/post-emit-verify/diagnostics.js.map +1 -0
- package/dist/realize/post-emit-verify/feedback-runner.d.ts +123 -0
- package/dist/realize/post-emit-verify/feedback-runner.d.ts.map +1 -0
- package/dist/realize/post-emit-verify/feedback-runner.js +232 -0
- package/dist/realize/post-emit-verify/feedback-runner.js.map +1 -0
- package/dist/realize/post-emit-verify/index.d.ts +19 -0
- package/dist/realize/post-emit-verify/index.d.ts.map +1 -0
- package/dist/realize/post-emit-verify/index.js +18 -0
- package/dist/realize/post-emit-verify/index.js.map +1 -0
- package/dist/realize/post-emit-verify/reemit.d.ts +82 -0
- package/dist/realize/post-emit-verify/reemit.d.ts.map +1 -0
- package/dist/realize/post-emit-verify/reemit.js +124 -0
- package/dist/realize/post-emit-verify/reemit.js.map +1 -0
- package/dist/realize/post-emit-verify/types.d.ts +187 -0
- package/dist/realize/post-emit-verify/types.d.ts.map +1 -0
- package/dist/realize/post-emit-verify/types.js +28 -0
- package/dist/realize/post-emit-verify/types.js.map +1 -0
- package/dist/realize/post-emit-verify/verifier-manifest.d.ts +29 -0
- package/dist/realize/post-emit-verify/verifier-manifest.d.ts.map +1 -0
- package/dist/realize/post-emit-verify/verifier-manifest.js +57 -0
- package/dist/realize/post-emit-verify/verifier-manifest.js.map +1 -0
- package/dist/realize/post-emit-verify/verifiers/stub-completeness.d.ts +85 -0
- package/dist/realize/post-emit-verify/verifiers/stub-completeness.d.ts.map +1 -0
- package/dist/realize/post-emit-verify/verifiers/stub-completeness.js +298 -0
- package/dist/realize/post-emit-verify/verifiers/stub-completeness.js.map +1 -0
- package/dist/realize/post-emit-verify/verifiers/tsc.d.ts +24 -0
- package/dist/realize/post-emit-verify/verifiers/tsc.d.ts.map +1 -0
- package/dist/realize/post-emit-verify/verifiers/tsc.js +148 -0
- package/dist/realize/post-emit-verify/verifiers/tsc.js.map +1 -0
- package/dist/realize/realize-context-snapshot.d.ts +70 -0
- package/dist/realize/realize-context-snapshot.d.ts.map +1 -0
- package/dist/realize/realize-context-snapshot.js +96 -0
- package/dist/realize/realize-context-snapshot.js.map +1 -0
- package/dist/realize/realize-rules.d.ts +113 -0
- package/dist/realize/realize-rules.d.ts.map +1 -0
- package/dist/realize/realize-rules.js +271 -0
- package/dist/realize/realize-rules.js.map +1 -0
- package/dist/realize/structural-validator.d.ts +36 -2
- package/dist/realize/structural-validator.d.ts.map +1 -1
- package/dist/realize/structural-validator.js +50 -7
- package/dist/realize/structural-validator.js.map +1 -1
- package/libs/instance-factories/cli/templates/commander/cli-entry-generator.ts +11 -12
- package/libs/instance-factories/cli/templates/commander/command-generator.ts +2 -2
- package/libs/instance-factories/controllers/templates/fastify/routes-generator.ts +49 -15
- package/libs/instance-factories/services/templates/prisma/ai-behaviors-generator.ts +19 -3
- package/libs/instance-factories/services/templates/prisma/behavior-generator.ts +62 -2
- package/libs/instance-factories/services/templates/prisma/controller-generator.ts +47 -20
- package/package.json +9 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-loader.js","sourceRoot":"","sources":["../../src/ai/skill-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,4 +7,6 @@
|
|
|
7
7
|
*/
|
|
8
8
|
export { extractTypeScriptPrisma, type PrismaFacts, type PrismaEntity, type PrismaField, type PrismaRelation, } from './typescript-prisma.js';
|
|
9
9
|
export { extractTypeScriptDecorators, type DecoratorFacts, type DecoratorEntity, type DecoratorRelationship, } from './typescript-decorators.js';
|
|
10
|
+
export { inferNamingConventionFks, type NamingConventionFkFacts, type NamingConventionFkInferred, type NamingConventionFkOptions, type NamingConventionFkInputEntity, type NamingConventionFkInputRelationship, } from './naming-convention-fks.js';
|
|
11
|
+
export { parseFunctionTerminalId, groupTerminalsByFile, findExportedFunctionBody, synthesizeServiceClass, deriveServiceName, type ModuleFunctionTerminal, } from './module-functions.js';
|
|
10
12
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/analyse-prepass/adapters/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EACL,uBAAuB,EACvB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,cAAc,GACpB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,2BAA2B,EAC3B,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,qBAAqB,GAC3B,MAAM,4BAA4B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/analyse-prepass/adapters/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EACL,uBAAuB,EACvB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,cAAc,GACpB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,2BAA2B,EAC3B,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,qBAAqB,GAC3B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,wBAAwB,EACxB,KAAK,uBAAuB,EAC5B,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,EAC9B,KAAK,6BAA6B,EAClC,KAAK,mCAAmC,GACzC,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,wBAAwB,EACxB,sBAAsB,EACtB,iBAAiB,EACjB,KAAK,sBAAsB,GAC5B,MAAM,uBAAuB,CAAC"}
|
|
@@ -7,4 +7,6 @@
|
|
|
7
7
|
*/
|
|
8
8
|
export { extractTypeScriptPrisma, } from './typescript-prisma.js';
|
|
9
9
|
export { extractTypeScriptDecorators, } from './typescript-decorators.js';
|
|
10
|
+
export { inferNamingConventionFks, } from './naming-convention-fks.js';
|
|
11
|
+
export { parseFunctionTerminalId, groupTerminalsByFile, findExportedFunctionBody, synthesizeServiceClass, deriveServiceName, } from './module-functions.js';
|
|
10
12
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/analyse-prepass/adapters/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EACL,uBAAuB,GAKxB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,2BAA2B,GAI5B,MAAM,4BAA4B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/analyse-prepass/adapters/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EACL,uBAAuB,GAKxB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,2BAA2B,GAI5B,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,wBAAwB,GAMzB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,wBAAwB,EACxB,sBAAsB,EACtB,iBAAiB,GAElB,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `module-functions` adapter — surfaces module-level exported functions
|
|
3
|
+
* as synthetic service classes via the candidate-step pipeline.
|
|
4
|
+
*
|
|
5
|
+
* Why this exists: PowerSync / hand-rolled Drizzle / Supabase-queries
|
|
6
|
+
* style codebases keep their business logic in modules of exported
|
|
7
|
+
* async functions:
|
|
8
|
+
*
|
|
9
|
+
* // db/queries/smc-rounds.ts
|
|
10
|
+
* export async function smcCreateRound(db, params) { ... }
|
|
11
|
+
* export async function smcGetRound(db, id) { ... }
|
|
12
|
+
* export async function smcUpdateRoundStatus(db, id, status) { ... }
|
|
13
|
+
*
|
|
14
|
+
* The class walker only sees classes — module functions are invisible
|
|
15
|
+
* to it. But GitNexus traces cross-method call flows AND captures
|
|
16
|
+
* function terminals as `Process` nodes (`Function:<filePath>:<fnName>`).
|
|
17
|
+
* That signal is already in `facts.processes` at the point the
|
|
18
|
+
* orchestrator finishes structural extraction.
|
|
19
|
+
*
|
|
20
|
+
* This adapter consumes the process terminals, groups them by file,
|
|
21
|
+
* and synthesizes one service class per file — exactly mirroring the
|
|
22
|
+
* `express-routes` pattern. The synthetic class body feeds into the
|
|
23
|
+
* existing `extractCandidateSteps` classifier, so module-function
|
|
24
|
+
* services get pre-classified timelines just like real class methods.
|
|
25
|
+
*
|
|
26
|
+
* Phase 0 of `2026-05-13-NORMALISE-PHASE.md`.
|
|
27
|
+
*
|
|
28
|
+
* Filed in proposal section §3.
|
|
29
|
+
*/
|
|
30
|
+
export interface ModuleFunctionTerminal {
|
|
31
|
+
/** Function name (suitable as a yaml key — preserved verbatim from source). */
|
|
32
|
+
methodName: string;
|
|
33
|
+
/** Whether the function is declared async. */
|
|
34
|
+
isAsync: boolean;
|
|
35
|
+
/** Function body between matching braces, no wrapping. */
|
|
36
|
+
body: string;
|
|
37
|
+
/** Source line range of the full declaration (export keyword → closing brace). */
|
|
38
|
+
sourceLineRange: [number, number];
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Parse a `Function:<filePath>:<fnName>` terminalId. Returns null if
|
|
42
|
+
* the ID doesn't match (e.g. it's a class method).
|
|
43
|
+
*
|
|
44
|
+
* Examples:
|
|
45
|
+
* "Function:db/queries/smc-rounds.ts:smcCreateRound" → { filePath, functionName }
|
|
46
|
+
* "Method:UserController:create" → null
|
|
47
|
+
*/
|
|
48
|
+
export declare function parseFunctionTerminalId(id: string): {
|
|
49
|
+
filePath: string;
|
|
50
|
+
functionName: string;
|
|
51
|
+
} | null;
|
|
52
|
+
/**
|
|
53
|
+
* Walk `facts.processes`-shaped input for function terminals. Returns a
|
|
54
|
+
* map: filePath → Set<functionName>. Skips:
|
|
55
|
+
* - Non-Function: terminals (class methods, etc.)
|
|
56
|
+
* - Files outside common source extensions
|
|
57
|
+
* - Files in node_modules / dist / build output
|
|
58
|
+
*/
|
|
59
|
+
export declare function groupTerminalsByFile(processes: Array<{
|
|
60
|
+
terminalId: string;
|
|
61
|
+
}>): Map<string, Set<string>>;
|
|
62
|
+
/**
|
|
63
|
+
* Find an exported top-level function in source. Handles four common
|
|
64
|
+
* declaration shapes:
|
|
65
|
+
*
|
|
66
|
+
* export async function <name>(...) { ... }
|
|
67
|
+
* export function <name>(...) { ... }
|
|
68
|
+
* export const <name> = async (...) => { ... }
|
|
69
|
+
* export const <name> = (...) => { ... }
|
|
70
|
+
*
|
|
71
|
+
* Returns null if not found or if the declaration's body can't be
|
|
72
|
+
* isolated (single-expression arrow `=> expr` without a brace block).
|
|
73
|
+
*/
|
|
74
|
+
export declare function findExportedFunctionBody(source: string, fnName: string): ModuleFunctionTerminal | null;
|
|
75
|
+
/**
|
|
76
|
+
* Wrap a list of module functions in a synthetic class body. The output
|
|
77
|
+
* is suitable for `walkMethodBodies` / `extractCandidateSteps` to
|
|
78
|
+
* consume. Each function becomes a `<methodName>(...) { <body> }` member.
|
|
79
|
+
*
|
|
80
|
+
* Mirrors `synthesizeControllerClass` in `express-routes.ts`.
|
|
81
|
+
*/
|
|
82
|
+
export declare function synthesizeServiceClass(serviceName: string, functions: ModuleFunctionTerminal[]): string;
|
|
83
|
+
/**
|
|
84
|
+
* Derive a service class name from a file path.
|
|
85
|
+
*
|
|
86
|
+
* "db/queries/smc-rounds.ts" → "SmcRoundsService"
|
|
87
|
+
* "lib/round-guards.ts" → "RoundGuardsService"
|
|
88
|
+
* "providers/AuthProvider.tsx" → "AuthProviderService"
|
|
89
|
+
*
|
|
90
|
+
* The file basename (no extension) is split on `-`, `_`, `.`, `/` and
|
|
91
|
+
* each segment is PascalCased. `Service` suffix is appended unless the
|
|
92
|
+
* derived name already ends in `Service` / `Controller`.
|
|
93
|
+
*/
|
|
94
|
+
export declare function deriveServiceName(filePath: string): string;
|
|
95
|
+
//# sourceMappingURL=module-functions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-functions.d.ts","sourceRoot":"","sources":["../../../src/analyse-prepass/adapters/module-functions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,MAAM,WAAW,sBAAsB;IACrC,+EAA+E;IAC/E,UAAU,EAAE,MAAM,CAAC;IACnB,8CAA8C;IAC9C,OAAO,EAAE,OAAO,CAAC;IACjB,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC;IACb,kFAAkF;IAClF,eAAe,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CACrC,EAAE,EAAE,MAAM,GACT;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAanD;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,KAAK,CAAC;IAAE,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,GACvC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAqB1B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb,sBAAsB,GAAG,IAAI,CA4C/B;AAqED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,sBAAsB,EAAE,GAClC,MAAM,CAYR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAU1D"}
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `module-functions` adapter — surfaces module-level exported functions
|
|
3
|
+
* as synthetic service classes via the candidate-step pipeline.
|
|
4
|
+
*
|
|
5
|
+
* Why this exists: PowerSync / hand-rolled Drizzle / Supabase-queries
|
|
6
|
+
* style codebases keep their business logic in modules of exported
|
|
7
|
+
* async functions:
|
|
8
|
+
*
|
|
9
|
+
* // db/queries/smc-rounds.ts
|
|
10
|
+
* export async function smcCreateRound(db, params) { ... }
|
|
11
|
+
* export async function smcGetRound(db, id) { ... }
|
|
12
|
+
* export async function smcUpdateRoundStatus(db, id, status) { ... }
|
|
13
|
+
*
|
|
14
|
+
* The class walker only sees classes — module functions are invisible
|
|
15
|
+
* to it. But GitNexus traces cross-method call flows AND captures
|
|
16
|
+
* function terminals as `Process` nodes (`Function:<filePath>:<fnName>`).
|
|
17
|
+
* That signal is already in `facts.processes` at the point the
|
|
18
|
+
* orchestrator finishes structural extraction.
|
|
19
|
+
*
|
|
20
|
+
* This adapter consumes the process terminals, groups them by file,
|
|
21
|
+
* and synthesizes one service class per file — exactly mirroring the
|
|
22
|
+
* `express-routes` pattern. The synthetic class body feeds into the
|
|
23
|
+
* existing `extractCandidateSteps` classifier, so module-function
|
|
24
|
+
* services get pre-classified timelines just like real class methods.
|
|
25
|
+
*
|
|
26
|
+
* Phase 0 of `2026-05-13-NORMALISE-PHASE.md`.
|
|
27
|
+
*
|
|
28
|
+
* Filed in proposal section §3.
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Parse a `Function:<filePath>:<fnName>` terminalId. Returns null if
|
|
32
|
+
* the ID doesn't match (e.g. it's a class method).
|
|
33
|
+
*
|
|
34
|
+
* Examples:
|
|
35
|
+
* "Function:db/queries/smc-rounds.ts:smcCreateRound" → { filePath, functionName }
|
|
36
|
+
* "Method:UserController:create" → null
|
|
37
|
+
*/
|
|
38
|
+
export function parseFunctionTerminalId(id) {
|
|
39
|
+
// Format: Function:<filePath>:<functionName>. The filePath may contain
|
|
40
|
+
// colons (drive letters on Windows, ports in URLs — rare in practice
|
|
41
|
+
// but defensive). The functionName is always the LAST `:`-separated
|
|
42
|
+
// segment. Anchor on `Function:` prefix.
|
|
43
|
+
if (!id.startsWith('Function:'))
|
|
44
|
+
return null;
|
|
45
|
+
const rest = id.slice('Function:'.length);
|
|
46
|
+
const lastColon = rest.lastIndexOf(':');
|
|
47
|
+
if (lastColon < 0)
|
|
48
|
+
return null;
|
|
49
|
+
const filePath = rest.slice(0, lastColon);
|
|
50
|
+
const functionName = rest.slice(lastColon + 1);
|
|
51
|
+
if (!filePath || !functionName)
|
|
52
|
+
return null;
|
|
53
|
+
return { filePath, functionName };
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Walk `facts.processes`-shaped input for function terminals. Returns a
|
|
57
|
+
* map: filePath → Set<functionName>. Skips:
|
|
58
|
+
* - Non-Function: terminals (class methods, etc.)
|
|
59
|
+
* - Files outside common source extensions
|
|
60
|
+
* - Files in node_modules / dist / build output
|
|
61
|
+
*/
|
|
62
|
+
export function groupTerminalsByFile(processes) {
|
|
63
|
+
const out = new Map();
|
|
64
|
+
for (const p of processes) {
|
|
65
|
+
const parsed = parseFunctionTerminalId(p.terminalId);
|
|
66
|
+
if (!parsed)
|
|
67
|
+
continue;
|
|
68
|
+
// Skip files that look like generated / vendored output.
|
|
69
|
+
if (/node_modules|\.d\.ts$|dist\/|build\//.test(parsed.filePath))
|
|
70
|
+
continue;
|
|
71
|
+
// Stick to backend source extensions. `.tsx`/`.jsx` are React/JSX
|
|
72
|
+
// files — those are frontend components + hooks, NOT backend
|
|
73
|
+
// service modules. The react-views adapter handles them; this
|
|
74
|
+
// adapter must not double-claim them as services.
|
|
75
|
+
if (!/\.(ts|js|mjs|cjs)$/.test(parsed.filePath))
|
|
76
|
+
continue;
|
|
77
|
+
if (/\.d\.ts$/.test(parsed.filePath))
|
|
78
|
+
continue;
|
|
79
|
+
let set = out.get(parsed.filePath);
|
|
80
|
+
if (!set) {
|
|
81
|
+
set = new Set();
|
|
82
|
+
out.set(parsed.filePath, set);
|
|
83
|
+
}
|
|
84
|
+
set.add(parsed.functionName);
|
|
85
|
+
}
|
|
86
|
+
return out;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Find an exported top-level function in source. Handles four common
|
|
90
|
+
* declaration shapes:
|
|
91
|
+
*
|
|
92
|
+
* export async function <name>(...) { ... }
|
|
93
|
+
* export function <name>(...) { ... }
|
|
94
|
+
* export const <name> = async (...) => { ... }
|
|
95
|
+
* export const <name> = (...) => { ... }
|
|
96
|
+
*
|
|
97
|
+
* Returns null if not found or if the declaration's body can't be
|
|
98
|
+
* isolated (single-expression arrow `=> expr` without a brace block).
|
|
99
|
+
*/
|
|
100
|
+
export function findExportedFunctionBody(source, fnName) {
|
|
101
|
+
// Shape A: `export (async )? function <fnName>(...) { ... }`
|
|
102
|
+
// The space-or-newline between `function` and the name allows for
|
|
103
|
+
// multiline declarations with intervening whitespace.
|
|
104
|
+
const funcRe = new RegExp(`\\bexport\\s+(async\\s+)?function\\s+${escapeRegex(fnName)}\\s*\\(`, 'm');
|
|
105
|
+
const funcMatch = funcRe.exec(source);
|
|
106
|
+
if (funcMatch) {
|
|
107
|
+
const openParenIdx = funcMatch.index + funcMatch[0].length - 1;
|
|
108
|
+
const closeParenIdx = findMatchingParen(source, openParenIdx);
|
|
109
|
+
if (closeParenIdx < 0)
|
|
110
|
+
return null;
|
|
111
|
+
// Body opening brace = first `{` after `)` at angle-bracket depth 0
|
|
112
|
+
// (skips `{` inside a return type generic like `Promise<{ ... }>`).
|
|
113
|
+
const braceIdx = findBodyBrace(source, closeParenIdx + 1);
|
|
114
|
+
if (braceIdx < 0)
|
|
115
|
+
return null;
|
|
116
|
+
return extractBody(source, funcMatch.index, braceIdx, !!funcMatch[1]);
|
|
117
|
+
}
|
|
118
|
+
// Shape B: `export const <fnName> = (async )? (...) [: Type]? => { ... }`
|
|
119
|
+
const constRe = new RegExp(`\\bexport\\s+const\\s+${escapeRegex(fnName)}\\s*=\\s*(async\\s+)?\\(`, 'm');
|
|
120
|
+
const constMatch = constRe.exec(source);
|
|
121
|
+
if (constMatch) {
|
|
122
|
+
const openParenIdx = constMatch.index + constMatch[0].length - 1;
|
|
123
|
+
const closeParenIdx = findMatchingParen(source, openParenIdx);
|
|
124
|
+
if (closeParenIdx < 0)
|
|
125
|
+
return null;
|
|
126
|
+
// After the `)`, expect optionally `: <ReturnType>` then `=>` then `{`.
|
|
127
|
+
// The return type can contain `>`, `<`, `,`, generics, etc., so we
|
|
128
|
+
// can't use a simple regex. Walk forward through angle-bracket-aware
|
|
129
|
+
// chars until we hit `=>`.
|
|
130
|
+
const arrowIdx = findArrowAfterParen(source, closeParenIdx + 1);
|
|
131
|
+
if (arrowIdx < 0)
|
|
132
|
+
return null;
|
|
133
|
+
// After `=>`, skip whitespace, expect `{`.
|
|
134
|
+
let i = arrowIdx + 2;
|
|
135
|
+
while (i < source.length && /\s/.test(source[i]))
|
|
136
|
+
i++;
|
|
137
|
+
if (source[i] !== '{')
|
|
138
|
+
return null;
|
|
139
|
+
return extractBody(source, constMatch.index, i, !!constMatch[1]);
|
|
140
|
+
}
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Find the first `{` after `fromIdx` that's at angle-bracket depth 0.
|
|
145
|
+
* This skips over generic-parameter braces like `Promise<{rows: Row[]}>`
|
|
146
|
+
* which would otherwise be mistakenly identified as the function body.
|
|
147
|
+
*/
|
|
148
|
+
function findBodyBrace(source, fromIdx) {
|
|
149
|
+
let angleDepth = 0;
|
|
150
|
+
let strChar = null;
|
|
151
|
+
for (let i = fromIdx; i < source.length; i++) {
|
|
152
|
+
const c = source[i];
|
|
153
|
+
if (strChar) {
|
|
154
|
+
if (c === '\\') {
|
|
155
|
+
i++;
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
if (c === strChar)
|
|
159
|
+
strChar = null;
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
if (c === '"' || c === "'" || c === '`') {
|
|
163
|
+
strChar = c;
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
if (c === '<')
|
|
167
|
+
angleDepth++;
|
|
168
|
+
else if (c === '>')
|
|
169
|
+
angleDepth = Math.max(0, angleDepth - 1);
|
|
170
|
+
else if (c === '{' && angleDepth === 0)
|
|
171
|
+
return i;
|
|
172
|
+
}
|
|
173
|
+
return -1;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Find the `=>` after `fromIdx` at angle-bracket depth 0. Lets us walk
|
|
177
|
+
* past a `: Type<...>` return-type annotation on a const arrow form.
|
|
178
|
+
*/
|
|
179
|
+
function findArrowAfterParen(source, fromIdx) {
|
|
180
|
+
let angleDepth = 0;
|
|
181
|
+
let strChar = null;
|
|
182
|
+
for (let i = fromIdx; i < source.length - 1; i++) {
|
|
183
|
+
const c = source[i];
|
|
184
|
+
const next = source[i + 1];
|
|
185
|
+
if (strChar) {
|
|
186
|
+
if (c === '\\') {
|
|
187
|
+
i++;
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
if (c === strChar)
|
|
191
|
+
strChar = null;
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
if (c === '"' || c === "'" || c === '`') {
|
|
195
|
+
strChar = c;
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
if (c === '<')
|
|
199
|
+
angleDepth++;
|
|
200
|
+
else if (c === '>')
|
|
201
|
+
angleDepth = Math.max(0, angleDepth - 1);
|
|
202
|
+
else if (c === '=' && next === '>' && angleDepth === 0)
|
|
203
|
+
return i;
|
|
204
|
+
// Bail if we hit `{` or `;` at depth 0 without seeing `=>` — not an arrow form.
|
|
205
|
+
else if ((c === '{' || c === ';') && angleDepth === 0)
|
|
206
|
+
return -1;
|
|
207
|
+
}
|
|
208
|
+
return -1;
|
|
209
|
+
}
|
|
210
|
+
function extractBody(source, declStartIdx, openBraceIdx, isAsync) {
|
|
211
|
+
const closeBraceIdx = findMatchingBrace(source, openBraceIdx);
|
|
212
|
+
if (closeBraceIdx < 0)
|
|
213
|
+
return null;
|
|
214
|
+
const body = source.slice(openBraceIdx + 1, closeBraceIdx);
|
|
215
|
+
const startLine = source.slice(0, declStartIdx).split('\n').length;
|
|
216
|
+
const endLine = source.slice(0, closeBraceIdx + 1).split('\n').length;
|
|
217
|
+
return {
|
|
218
|
+
methodName: '', // filled by caller; we don't have the name here
|
|
219
|
+
isAsync,
|
|
220
|
+
body,
|
|
221
|
+
sourceLineRange: [startLine, endLine],
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Wrap a list of module functions in a synthetic class body. The output
|
|
226
|
+
* is suitable for `walkMethodBodies` / `extractCandidateSteps` to
|
|
227
|
+
* consume. Each function becomes a `<methodName>(...) { <body> }` member.
|
|
228
|
+
*
|
|
229
|
+
* Mirrors `synthesizeControllerClass` in `express-routes.ts`.
|
|
230
|
+
*/
|
|
231
|
+
export function synthesizeServiceClass(serviceName, functions) {
|
|
232
|
+
const lines = [];
|
|
233
|
+
lines.push(`class ${serviceName} {`);
|
|
234
|
+
for (const f of functions) {
|
|
235
|
+
const asyncWord = f.isAsync ? 'async ' : '';
|
|
236
|
+
lines.push(` ${asyncWord}${f.methodName}() {`);
|
|
237
|
+
const bodyLines = f.body.split('\n').map((l) => ' ' + l);
|
|
238
|
+
lines.push(...bodyLines);
|
|
239
|
+
lines.push(' }');
|
|
240
|
+
}
|
|
241
|
+
lines.push('}');
|
|
242
|
+
return lines.join('\n');
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Derive a service class name from a file path.
|
|
246
|
+
*
|
|
247
|
+
* "db/queries/smc-rounds.ts" → "SmcRoundsService"
|
|
248
|
+
* "lib/round-guards.ts" → "RoundGuardsService"
|
|
249
|
+
* "providers/AuthProvider.tsx" → "AuthProviderService"
|
|
250
|
+
*
|
|
251
|
+
* The file basename (no extension) is split on `-`, `_`, `.`, `/` and
|
|
252
|
+
* each segment is PascalCased. `Service` suffix is appended unless the
|
|
253
|
+
* derived name already ends in `Service` / `Controller`.
|
|
254
|
+
*/
|
|
255
|
+
export function deriveServiceName(filePath) {
|
|
256
|
+
const basename = filePath.split('/').pop() ?? filePath;
|
|
257
|
+
const noExt = basename.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/, '');
|
|
258
|
+
const pascal = noExt
|
|
259
|
+
.split(/[-_./]+/)
|
|
260
|
+
.filter((p) => p.length > 0)
|
|
261
|
+
.map((p) => p.charAt(0).toUpperCase() + p.slice(1))
|
|
262
|
+
.join('');
|
|
263
|
+
if (/Service$/.test(pascal) || /Controller$/.test(pascal))
|
|
264
|
+
return pascal;
|
|
265
|
+
return `${pascal}Service`;
|
|
266
|
+
}
|
|
267
|
+
// ── Brace / paren matching helpers ───────────────────────────────────
|
|
268
|
+
// Inlined (not imported from express-routes) to keep this adapter
|
|
269
|
+
// self-contained. Same logic, same edge cases.
|
|
270
|
+
function findMatchingParen(source, openIdx) {
|
|
271
|
+
if (source[openIdx] !== '(')
|
|
272
|
+
return -1;
|
|
273
|
+
let depth = 0;
|
|
274
|
+
let strChar = null;
|
|
275
|
+
for (let i = openIdx; i < source.length; i++) {
|
|
276
|
+
const c = source[i];
|
|
277
|
+
if (strChar) {
|
|
278
|
+
if (c === '\\') {
|
|
279
|
+
i++;
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
if (c === strChar)
|
|
283
|
+
strChar = null;
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
if (c === '"' || c === "'" || c === '`') {
|
|
287
|
+
strChar = c;
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
if (c === '(')
|
|
291
|
+
depth++;
|
|
292
|
+
else if (c === ')') {
|
|
293
|
+
depth--;
|
|
294
|
+
if (depth === 0)
|
|
295
|
+
return i;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return -1;
|
|
299
|
+
}
|
|
300
|
+
function findMatchingBrace(source, openIdx) {
|
|
301
|
+
if (source[openIdx] !== '{')
|
|
302
|
+
return -1;
|
|
303
|
+
let depth = 0;
|
|
304
|
+
let strChar = null;
|
|
305
|
+
let inLineComment = false;
|
|
306
|
+
let inBlockComment = false;
|
|
307
|
+
for (let i = openIdx; i < source.length; i++) {
|
|
308
|
+
const c = source[i];
|
|
309
|
+
const next = source[i + 1];
|
|
310
|
+
if (inLineComment) {
|
|
311
|
+
if (c === '\n')
|
|
312
|
+
inLineComment = false;
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
if (inBlockComment) {
|
|
316
|
+
if (c === '*' && next === '/') {
|
|
317
|
+
inBlockComment = false;
|
|
318
|
+
i++;
|
|
319
|
+
}
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
if (strChar) {
|
|
323
|
+
if (c === '\\') {
|
|
324
|
+
i++;
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
if (c === strChar)
|
|
328
|
+
strChar = null;
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
if (c === '/' && next === '/') {
|
|
332
|
+
inLineComment = true;
|
|
333
|
+
i++;
|
|
334
|
+
continue;
|
|
335
|
+
}
|
|
336
|
+
if (c === '/' && next === '*') {
|
|
337
|
+
inBlockComment = true;
|
|
338
|
+
i++;
|
|
339
|
+
continue;
|
|
340
|
+
}
|
|
341
|
+
if (c === '"' || c === "'" || c === '`') {
|
|
342
|
+
strChar = c;
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
345
|
+
if (c === '{')
|
|
346
|
+
depth++;
|
|
347
|
+
else if (c === '}') {
|
|
348
|
+
depth--;
|
|
349
|
+
if (depth === 0)
|
|
350
|
+
return i;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
return -1;
|
|
354
|
+
}
|
|
355
|
+
function escapeRegex(s) {
|
|
356
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
357
|
+
}
|
|
358
|
+
//# sourceMappingURL=module-functions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"module-functions.js","sourceRoot":"","sources":["../../../src/analyse-prepass/adapters/module-functions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `naming-convention-fks` adapter — convention-FK relationship inference.
|
|
3
|
+
*
|
|
4
|
+
* Some codebases carry no explicit FK metadata: PowerSync (`column.text`
|
|
5
|
+
* without `.references()`), hand-rolled Drizzle without relations, plain
|
|
6
|
+
* SQL migrations without REFERENCES clauses. The relationship lives in the
|
|
7
|
+
* column NAME (`club_id`, `userId`) by convention only. None of the
|
|
8
|
+
* structural adapters (typescript-prisma / typescript-decorators /
|
|
9
|
+
* typescript-interfaces / express-routes / react-views) catches this
|
|
10
|
+
* pattern — typescript-interfaces sees `club_id: string` as a plain string
|
|
11
|
+
* field, not a relationship.
|
|
12
|
+
*
|
|
13
|
+
* This adapter is a POST-EXTRACTION inference pass. It runs after all
|
|
14
|
+
* structural adapters have populated `facts.entities[].attributes[]` and
|
|
15
|
+
* walks those attributes for the `*_id` / `*Id` pattern, resolving the
|
|
16
|
+
* prefix against the entity name set (singular OR plural form). When a
|
|
17
|
+
* match resolves cleanly to a known entity, it emits a belongsTo
|
|
18
|
+
* relationship from the owning entity to the target plus a reverse hasMany.
|
|
19
|
+
*
|
|
20
|
+
* Surfaced as a gap by the scoremyclays full-pipeline run 2026-05-12: 10
|
|
21
|
+
* entities extracted, 0 relationships, because Supabase + PowerSync uses
|
|
22
|
+
* convention FKs throughout (`club_id: column.text`).
|
|
23
|
+
*
|
|
24
|
+
* Cut 1 patterns:
|
|
25
|
+
* - `<entity>_id` (snake_case) or `<entity>Id` (camelCase), where the
|
|
26
|
+
* prefix maps to a known entity name (case-insensitive, singular OR
|
|
27
|
+
* plural via a small english heuristic).
|
|
28
|
+
*
|
|
29
|
+
* Out of scope (deferred to follow-up):
|
|
30
|
+
* - `created_by` / `assigned_to` / `owner_id` — target entity not named
|
|
31
|
+
* in the column (needs a curated semantic map OR LLM inference).
|
|
32
|
+
* - Composite FKs — same shape produces independent belongsTos; downstream
|
|
33
|
+
* can combine if it cares.
|
|
34
|
+
*
|
|
35
|
+
* Cardinality: forward `belongsTo` for every matched `*_id`. The reverse
|
|
36
|
+
* `hasMany` is emitted ONLY when this adapter discovered the forward edge
|
|
37
|
+
* itself — i.e. when a prior adapter hadn't already declared that
|
|
38
|
+
* belongsTo. Rationale: rich-metadata codebases (TypeORM with explicit
|
|
39
|
+
* @ManyToOne) decline to declare the inverse @OneToMany when they don't
|
|
40
|
+
* navigate that way, and we shouldn't second-guess that omission. For
|
|
41
|
+
* convention-only codebases (PowerSync) where no prior adapter saw the
|
|
42
|
+
* relationship, BOTH directions are emitted so downstream gets a complete
|
|
43
|
+
* cardinality view.
|
|
44
|
+
*
|
|
45
|
+
* Self-references (`parent_id` on Category → Category) emit only the
|
|
46
|
+
* belongsTo regardless — `Category hasMany Category` is legal but rarely
|
|
47
|
+
* the intended shape.
|
|
48
|
+
*
|
|
49
|
+
* Dedup: skip a candidate when the same `from|to|type` already exists in
|
|
50
|
+
* the input relationships list (a higher-fidelity adapter wins).
|
|
51
|
+
*/
|
|
52
|
+
export interface NamingConventionFkInputEntity {
|
|
53
|
+
name: string;
|
|
54
|
+
attributes?: Array<{
|
|
55
|
+
name: string;
|
|
56
|
+
isPrimary?: boolean;
|
|
57
|
+
}>;
|
|
58
|
+
}
|
|
59
|
+
export interface NamingConventionFkInputRelationship {
|
|
60
|
+
from: string;
|
|
61
|
+
to: string;
|
|
62
|
+
type: 'belongsTo' | 'hasMany' | 'hasOne' | 'manyToMany';
|
|
63
|
+
}
|
|
64
|
+
export interface NamingConventionFkInferred {
|
|
65
|
+
from: string;
|
|
66
|
+
to: string;
|
|
67
|
+
type: 'belongsTo' | 'hasMany';
|
|
68
|
+
/** Source attribute that triggered the inference. Kept for downstream
|
|
69
|
+
* attribution + tests; the orchestrator drops this before merging into
|
|
70
|
+
* facts.relationships (which has no `fieldName` field on its canonical
|
|
71
|
+
* shape). */
|
|
72
|
+
fieldName: string;
|
|
73
|
+
}
|
|
74
|
+
export interface NamingConventionFkFacts {
|
|
75
|
+
relationships: NamingConventionFkInferred[];
|
|
76
|
+
/** How many attributes matched the `*_id` / `*Id` pattern. */
|
|
77
|
+
matchedAttributes: number;
|
|
78
|
+
/** Matches that were skipped because the attribute is the entity's PK. */
|
|
79
|
+
ignoredPrimaryKeys: number;
|
|
80
|
+
/** Matches that resolved to no entity name. */
|
|
81
|
+
unresolvedTargets: number;
|
|
82
|
+
}
|
|
83
|
+
export interface NamingConventionFkOptions {
|
|
84
|
+
/** Override pluralization. Default: simple english heuristic. */
|
|
85
|
+
pluralize?: (singular: string) => string;
|
|
86
|
+
/** Override singularization. Default: simple english heuristic. */
|
|
87
|
+
singularize?: (plural: string) => string;
|
|
88
|
+
}
|
|
89
|
+
export declare function inferNamingConventionFks(entities: NamingConventionFkInputEntity[], existingRelationships: NamingConventionFkInputRelationship[], options?: NamingConventionFkOptions): NamingConventionFkFacts;
|
|
90
|
+
//# sourceMappingURL=naming-convention-fks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"naming-convention-fks.d.ts","sourceRoot":"","sources":["../../../src/analyse-prepass/adapters/naming-convention-fks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkDG;AAEH,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,KAAK,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,OAAO,CAAC;KACrB,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,mCAAmC;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,YAAY,CAAC;CACzD;AAED,MAAM,WAAW,0BAA0B;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,WAAW,GAAG,SAAS,CAAC;IAC9B;;;kBAGc;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACtC,aAAa,EAAE,0BAA0B,EAAE,CAAC;IAC5C,8DAA8D;IAC9D,iBAAiB,EAAE,MAAM,CAAC;IAC1B,0EAA0E;IAC1E,kBAAkB,EAAE,MAAM,CAAC;IAC3B,+CAA+C;IAC/C,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,yBAAyB;IACxC,iEAAiE;IACjE,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,mEAAmE;IACnE,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;CAC1C;AAID,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,6BAA6B,EAAE,EACzC,qBAAqB,EAAE,mCAAmC,EAAE,EAC5D,OAAO,GAAE,yBAA8B,GACtC,uBAAuB,CA6EzB"}
|