@descryy/core 0.6.3 → 0.8.0
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/contracts/index.d.ts +3 -1
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts/index.js +2 -1
- package/dist/contracts/index.js.map +1 -1
- package/dist/contracts/paths.d.ts +7 -0
- package/dist/contracts/paths.d.ts.map +1 -1
- package/dist/contracts/paths.js +7 -4
- package/dist/contracts/paths.js.map +1 -1
- package/dist/contracts/shapes.d.ts +12 -1
- package/dist/contracts/shapes.d.ts.map +1 -1
- package/dist/contracts/shapes.js +68 -0
- package/dist/contracts/shapes.js.map +1 -1
- package/dist/contracts/workspace-join.d.ts +104 -0
- package/dist/contracts/workspace-join.d.ts.map +1 -0
- package/dist/contracts/workspace-join.js +208 -0
- package/dist/contracts/workspace-join.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/query/index.d.ts +7 -3
- package/dist/query/index.d.ts.map +1 -1
- package/dist/query/index.js +4 -2
- package/dist/query/index.js.map +1 -1
- package/dist/query/model-table.d.ts +7 -0
- package/dist/query/model-table.d.ts.map +1 -1
- package/dist/query/model-table.js +7 -4
- package/dist/query/model-table.js.map +1 -1
- package/dist/query/persistence-reach.d.ts +150 -0
- package/dist/query/persistence-reach.d.ts.map +1 -0
- package/dist/query/persistence-reach.js +393 -0
- package/dist/query/persistence-reach.js.map +1 -0
- package/dist/query/queries.d.ts +5 -0
- package/dist/query/queries.d.ts.map +1 -1
- package/dist/query/queries.js +58 -0
- package/dist/query/queries.js.map +1 -1
- package/dist/query/user-chain.d.ts +89 -0
- package/dist/query/user-chain.d.ts.map +1 -0
- package/dist/query/user-chain.js +203 -0
- package/dist/query/user-chain.js.map +1 -0
- package/dist/sources/git/history.d.ts +12 -0
- package/dist/sources/git/history.d.ts.map +1 -1
- package/dist/sources/git/history.js +27 -0
- package/dist/sources/git/history.js.map +1 -1
- package/dist/sources/git/index.d.ts +1 -1
- package/dist/sources/git/index.d.ts.map +1 -1
- package/dist/sources/git/index.js +1 -1
- package/dist/sources/git/index.js.map +1 -1
- package/dist/store/incremental-cache.d.ts +120 -0
- package/dist/store/incremental-cache.d.ts.map +1 -0
- package/dist/store/incremental-cache.js +161 -0
- package/dist/store/incremental-cache.js.map +1 -0
- package/dist/store/index.d.ts +2 -0
- package/dist/store/index.d.ts.map +1 -1
- package/dist/store/index.js +1 -0
- package/dist/store/index.js.map +1 -1
- package/dist/store/reader.d.ts.map +1 -1
- package/dist/store/reader.js +6 -1
- package/dist/store/reader.js.map +1 -1
- package/dist/store/schema.d.ts +4 -4
- package/dist/store/schema.d.ts.map +1 -1
- package/dist/store/schema.js +46 -1
- package/dist/store/schema.js.map +1 -1
- package/dist/store/writer.d.ts.map +1 -1
- package/dist/store/writer.js +4 -3
- package/dist/store/writer.js.map +1 -1
- package/dist/tiers/certify.d.ts +174 -0
- package/dist/tiers/certify.d.ts.map +1 -1
- package/dist/tiers/certify.js +309 -5
- package/dist/tiers/certify.js.map +1 -1
- package/dist/tiers/index.d.ts +1 -1
- package/dist/tiers/index.d.ts.map +1 -1
- package/dist/tiers/index.js.map +1 -1
- package/dist/workspace/graph-layout.d.ts +85 -0
- package/dist/workspace/graph-layout.d.ts.map +1 -0
- package/dist/workspace/graph-layout.js +90 -0
- package/dist/workspace/graph-layout.js.map +1 -0
- package/dist/workspace/index.d.ts +3 -0
- package/dist/workspace/index.d.ts.map +1 -0
- package/dist/workspace/index.js +2 -0
- package/dist/workspace/index.js.map +1 -0
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { nearestMiss, sameEndpoint, templateMatchesPath } from "./paths.ts";
|
|
1
|
+
export { nearestMiss, sameEndpoint, templateMatchesPath, editDistance, nearlyTheSameWord } from "./paths.ts";
|
|
2
2
|
export type { EndpointKey, NearMiss, NearMissKind } from "./paths.ts";
|
|
3
3
|
export { readShape, compareShapes } from "./shapes.ts";
|
|
4
4
|
export type { Shape, ShapeField, ShapeComparison, ShapeDifference, ShapeDifferenceKind, } from "./shapes.ts";
|
|
@@ -8,4 +8,6 @@ export { checkObservedRoutes, declaredRoutesFrom } from "./observed-routes.ts";
|
|
|
8
8
|
export type { DeclaredRoute, ObservedRouteEvidence, ObservedRouteFinding, ObservedRouteFindingKind, ObservedRouteReport, } from "./observed-routes.ts";
|
|
9
9
|
export { checkContracts } from "./engine.ts";
|
|
10
10
|
export type { ContractCheck, ContractOptions, ShapeCheck, ShapeDirection, ShapeMismatch, } from "./engine.ts";
|
|
11
|
+
export { originMatchesRepo, repoOfEndpoint, resolveWorkspaceApiJoins } from "./workspace-join.ts";
|
|
12
|
+
export type { AmbiguousApiJoin, ResolvedApiJoin, WorkspaceApiJoinOptions, WorkspaceApiJoinResult, } from "./workspace-join.ts";
|
|
11
13
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/contracts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/contracts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,mBAAmB,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC7G,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEtE,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACvD,YAAY,EACV,KAAK,EACL,UAAU,EACV,eAAe,EACf,eAAe,EACf,mBAAmB,GACpB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,YAAY,EACV,aAAa,EACb,eAAe,EACf,mBAAmB,EACnB,cAAc,EACd,aAAa,GACd,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC/E,YAAY,EACV,aAAa,EACb,qBAAqB,EACrB,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,YAAY,EACV,aAAa,EACb,eAAe,EACf,UAAU,EACV,cAAc,EACd,aAAa,GACd,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAClG,YAAY,EACV,gBAAgB,EAChB,eAAe,EACf,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,qBAAqB,CAAC"}
|
package/dist/contracts/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export { nearestMiss, sameEndpoint, templateMatchesPath } from "./paths.js";
|
|
1
|
+
export { nearestMiss, sameEndpoint, templateMatchesPath, editDistance, nearlyTheSameWord } from "./paths.js";
|
|
2
2
|
export { readShape, compareShapes } from "./shapes.js";
|
|
3
3
|
export { findContractOrphans } from "./orphans.js";
|
|
4
4
|
export { checkObservedRoutes, declaredRoutesFrom } from "./observed-routes.js";
|
|
5
5
|
export { checkContracts } from "./engine.js";
|
|
6
|
+
export { originMatchesRepo, repoOfEndpoint, resolveWorkspaceApiJoins } from "./workspace-join.js";
|
|
6
7
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/contracts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/contracts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,mBAAmB,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAG7G,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AASvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AASnD,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAS/E,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAS7C,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
* differs" alone was 51% false positives on 3,524 routes). Floor `1 - distance/max(len) >= 0.4` (transposition
|
|
4
4
|
* = 1 edit not 2) rejects 87.4% of those, keeps 100% of a 49,405-case seeded typo set. Not an oracle.
|
|
5
5
|
*/
|
|
6
|
+
/** Damerau-Levenshtein distance. Adjacent transposition costs 1 edit, not 2 — else `api`/`aip` scores 0.33.
|
|
7
|
+
* Exported for `shapes.ts`'s `FIELD_RENAMED` detection, which needs the same name-similarity
|
|
8
|
+
* measure this module already validated against a seeded typo set — not a second, unvalidated one. */
|
|
9
|
+
export declare function editDistance(a: string, b: string): number;
|
|
10
|
+
/** Close enough to be a mistyping, not just a different word? Distance-1 always admitted, so `/v1`/`/v2` isn't scored away.
|
|
11
|
+
* Exported alongside `editDistance` — see that function's comment. */
|
|
12
|
+
export declare function nearlyTheSameWord(a: string, b: string): boolean;
|
|
6
13
|
export interface EndpointKey {
|
|
7
14
|
readonly method: string;
|
|
8
15
|
/** Normalised: `:id`, `{id}` and `<int:id>` have all become `{param}`. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/contracts/paths.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/contracts/paths.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH;;uGAEuG;AACvG,wBAAgB,YAAY,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAyBzD;AAED;uEACuE;AACvE,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAI/D;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,0EAA0E;IAC1E,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,aAAa,CAAC;AAEpD,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,mDAAmD;IACnD,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC;IAC9B,+EAA+E;IAC/E,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAWD,wBAAgB,YAAY,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,WAAW,GAAG,OAAO,CAEpE;AAED,uGAAuG;AACvG,wBAAgB,WAAW,CACzB,MAAM,EAAE,WAAW,EACnB,MAAM,EAAE,SAAS,WAAW,EAAE,GAC7B,QAAQ,GAAG,IAAI,CA0DjB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAKnF"}
|
package/dist/contracts/paths.js
CHANGED
|
@@ -7,8 +7,10 @@
|
|
|
7
7
|
const PARAM = "{param}";
|
|
8
8
|
/** How alike rule 2's two differing segments must be. Measured, not chosen — see module header. */
|
|
9
9
|
const SEGMENT_SIMILARITY_FLOOR = 0.4;
|
|
10
|
-
/** Damerau-Levenshtein distance. Adjacent transposition costs 1 edit, not 2 — else `api`/`aip` scores 0.33.
|
|
11
|
-
|
|
10
|
+
/** Damerau-Levenshtein distance. Adjacent transposition costs 1 edit, not 2 — else `api`/`aip` scores 0.33.
|
|
11
|
+
* Exported for `shapes.ts`'s `FIELD_RENAMED` detection, which needs the same name-similarity
|
|
12
|
+
* measure this module already validated against a seeded typo set — not a second, unvalidated one. */
|
|
13
|
+
export function editDistance(a, b) {
|
|
12
14
|
if (a === b)
|
|
13
15
|
return 0;
|
|
14
16
|
if (a.length === 0)
|
|
@@ -34,8 +36,9 @@ function editDistance(a, b) {
|
|
|
34
36
|
}
|
|
35
37
|
return rows[a.length][b.length];
|
|
36
38
|
}
|
|
37
|
-
/** Close enough to be a mistyping, not just a different word? Distance-1 always admitted, so `/v1`/`/v2` isn't scored away.
|
|
38
|
-
function
|
|
39
|
+
/** Close enough to be a mistyping, not just a different word? Distance-1 always admitted, so `/v1`/`/v2` isn't scored away.
|
|
40
|
+
* Exported alongside `editDistance` — see that function's comment. */
|
|
41
|
+
export function nearlyTheSameWord(a, b) {
|
|
39
42
|
const distance = editDistance(a, b);
|
|
40
43
|
if (distance <= 1)
|
|
41
44
|
return true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/contracts/paths.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,oFAAoF;AACpF,MAAM,KAAK,GAAG,SAAS,CAAC;AAExB,mGAAmG;AACnG,MAAM,wBAAwB,GAAG,GAAG,CAAC;AAErC
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/contracts/paths.ts"],"names":[],"mappings":"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"}
|
|
@@ -23,7 +23,7 @@ export interface Shape {
|
|
|
23
23
|
* facts from a type checker/schema) is preferred, `fields` is the name-level fallback.
|
|
24
24
|
* Anything else is not a shape and is not guessed at. */
|
|
25
25
|
export declare function readShape(node: IRNode): Shape | null;
|
|
26
|
-
export type ShapeDifferenceKind = "FIELD_MISSING" | "TYPE_DIFFERS" | "NULLABILITY_DIFFERS" | "REQUIREDNESS_DIFFERS" | "LIST_DIFFERS";
|
|
26
|
+
export type ShapeDifferenceKind = "FIELD_MISSING" | "TYPE_DIFFERS" | "NULLABILITY_DIFFERS" | "REQUIREDNESS_DIFFERS" | "LIST_DIFFERS" | "FIELD_RENAMED";
|
|
27
27
|
export interface ShapeDifference {
|
|
28
28
|
readonly kind: ShapeDifferenceKind;
|
|
29
29
|
readonly field: string;
|
|
@@ -32,6 +32,17 @@ export interface ShapeDifference {
|
|
|
32
32
|
/** What the providing side declares. */
|
|
33
33
|
readonly provided: string;
|
|
34
34
|
readonly detail: string;
|
|
35
|
+
/** Set only on `FIELD_RENAMED` — the unmatched "want" name, the unmatched "have" name it
|
|
36
|
+
* was paired with, and `nearlyTheSameWord`'s similarity score for that pair (1 -
|
|
37
|
+
* distance/max(len)). Rule 2 (precision over recall): a wrong rename claim corrupts a
|
|
38
|
+
* consumer's understanding worse than two separate FIELD_MISSING/extra-field findings
|
|
39
|
+
* would, so this is reported as a disclosed *lead* — carrying the score that produced it —
|
|
40
|
+
* never silently substituted as fact for the pair it replaces. */
|
|
41
|
+
readonly rename?: {
|
|
42
|
+
readonly from: string;
|
|
43
|
+
readonly to: string;
|
|
44
|
+
readonly similarity: number;
|
|
45
|
+
};
|
|
35
46
|
}
|
|
36
47
|
export interface ShapeComparison {
|
|
37
48
|
readonly differences: readonly ShapeDifference[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shapes.d.ts","sourceRoot":"","sources":["../../src/contracts/shapes.ts"],"names":[],"mappings":"AAAA;;oGAEoG;AAEpG,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"shapes.d.ts","sourceRoot":"","sources":["../../src/contracts/shapes.ts"],"names":[],"mappings":"AAAA;;oGAEoG;AAEpG,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAI1C,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACxC;;2GAEuG;IACvG,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACrC;AAED,MAAM,WAAW,KAAK;IACpB,gFAAgF;IAChF,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC;IACvC,+EAA+E;IAC/E,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAED;;0DAE0D;AAC1D,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAUpD;AAoCD,MAAM,MAAM,mBAAmB,GAC3B,eAAe,GACf,cAAc,GACd,qBAAqB,GACrB,sBAAsB,GACtB,cAAc,GACd,eAAe,CAAC;AAEpB,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IACnC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,uCAAuC;IACvC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,wCAAwC;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;;uEAKmE;IACnE,QAAQ,CAAC,MAAM,CAAC,EAAE;QAChB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;KAC7B,CAAC;CACH;AAUD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,WAAW,EAAE,SAAS,eAAe,EAAE,CAAC;IACjD;gGAC4F;IAC5F,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED;qDACqD;AACrD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,GAAG,eAAe,CA6J/E"}
|
package/dist/contracts/shapes.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/** R3 half of §13: comparing two declared shapes, pure over `attrs`, no language named (IR
|
|
2
2
|
* boundary). Asymmetric by design — a field only in `provided` is fine; one only in `expected`
|
|
3
3
|
* is broken. `comparedDetail` false means "no detail to compare," never "types agree" (rule 3). */
|
|
4
|
+
import { editDistance, nearlyTheSameWord } from "./paths.js";
|
|
4
5
|
/** Reads a shape from `attrs`, or null if none declared. Two forms: `fieldDetail` (per-field
|
|
5
6
|
* facts from a type checker/schema) is preferred, `fields` is the name-level fallback.
|
|
6
7
|
* Anything else is not a shape and is not guessed at. */
|
|
@@ -47,13 +48,80 @@ function readEntries(raw) {
|
|
|
47
48
|
}
|
|
48
49
|
return { fields, detailed };
|
|
49
50
|
}
|
|
51
|
+
/** How close two unmatched fields' array positions must be to count as "close in array-index
|
|
52
|
+
* position" per the rename rule below, when type alone does not already make the pair unique.
|
|
53
|
+
* 0 means the same index in each side's field list — the tightest defensible reading, since
|
|
54
|
+
* `ShapeField` carries no explicit order/position field (only array index implies one), and a
|
|
55
|
+
* looser tolerance risks pairing two fields that only happen to sit a few slots apart in an
|
|
56
|
+
* otherwise-unrelated schema. */
|
|
57
|
+
const RENAME_POSITION_TOLERANCE = 0;
|
|
50
58
|
/** What the consumer expects that the provider doesn't deliver. `expected`: what the consumer
|
|
51
59
|
* reads. `provided`: what the producer declares. */
|
|
52
60
|
export function compareShapes(expected, provided) {
|
|
53
61
|
const byName = new Map(provided.fields.map((f) => [f.name, f]));
|
|
62
|
+
const wantByName = new Map(expected.fields.map((f) => [f.name, f]));
|
|
54
63
|
const comparedDetail = expected.detailed && provided.detailed;
|
|
55
64
|
const differences = [];
|
|
65
|
+
// Rename detection runs once, up front, over every field unmatched by exact name on
|
|
66
|
+
// *both* sides — before the per-`want`-field loop below, so a rename is reported as one
|
|
67
|
+
// finding rather than as an independent FIELD_MISSING (the want side) plus a silently
|
|
68
|
+
// dropped extra field (the have side). Gated on `comparedDetail`: a name-only shape has no
|
|
69
|
+
// type/nullability to match a candidate on, and name-similarity alone is far weaker
|
|
70
|
+
// evidence — matching the same gate every other structural check below already uses.
|
|
71
|
+
const renameByWant = new Map();
|
|
72
|
+
if (comparedDetail) {
|
|
73
|
+
const unmatchedWant = expected.fields.filter((w) => !byName.has(w.name));
|
|
74
|
+
const unmatchedHave = provided.fields.filter((h) => !wantByName.has(h.name));
|
|
75
|
+
for (const want of unmatchedWant) {
|
|
76
|
+
// No declared type on the "want" side gives nothing to match a candidate against —
|
|
77
|
+
// name similarity alone is not enough (rule 2).
|
|
78
|
+
if (want.type === undefined)
|
|
79
|
+
continue;
|
|
80
|
+
const sameTypeHave = unmatchedHave.filter((h) => h.type === want.type &&
|
|
81
|
+
(want.nullable === undefined || h.nullable === undefined || h.nullable === want.nullable));
|
|
82
|
+
if (sameTypeHave.length === 0)
|
|
83
|
+
continue;
|
|
84
|
+
const sameTypeWant = unmatchedWant.filter((w) => w.type === want.type);
|
|
85
|
+
let candidate;
|
|
86
|
+
if (sameTypeHave.length === 1 && sameTypeWant.length === 1) {
|
|
87
|
+
// The only unmatched field of this type on each side — unambiguous.
|
|
88
|
+
candidate = sameTypeHave[0];
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
// More than one same-type candidate: fall back to array position. Only a field
|
|
92
|
+
// sitting at the *same* index (see `RENAME_POSITION_TOLERANCE`) counts, and only
|
|
93
|
+
// when exactly one same-type candidate on each side sits there — otherwise which
|
|
94
|
+
// field renamed to which is a guess, not a lead, and none is reported (rule 2).
|
|
95
|
+
const wantIndex = expected.fields.indexOf(want);
|
|
96
|
+
const positional = sameTypeHave.filter((h) => Math.abs(provided.fields.indexOf(h) - wantIndex) <= RENAME_POSITION_TOLERANCE);
|
|
97
|
+
const positionalWant = sameTypeWant.filter((w) => Math.abs(expected.fields.indexOf(w) - wantIndex) <= RENAME_POSITION_TOLERANCE);
|
|
98
|
+
if (positional.length === 1 && positionalWant.length === 1)
|
|
99
|
+
candidate = positional[0];
|
|
100
|
+
}
|
|
101
|
+
if (candidate === undefined)
|
|
102
|
+
continue;
|
|
103
|
+
if (!nearlyTheSameWord(want.name, candidate.name))
|
|
104
|
+
continue;
|
|
105
|
+
const distance = editDistance(want.name, candidate.name);
|
|
106
|
+
const similarity = 1 - distance / Math.max(want.name.length, candidate.name.length);
|
|
107
|
+
renameByWant.set(want.name, { have: candidate, similarity });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
56
110
|
for (const want of expected.fields) {
|
|
111
|
+
const renamed = renameByWant.get(want.name);
|
|
112
|
+
if (renamed !== undefined) {
|
|
113
|
+
differences.push({
|
|
114
|
+
kind: "FIELD_RENAMED",
|
|
115
|
+
field: want.name,
|
|
116
|
+
expected: want.name,
|
|
117
|
+
provided: renamed.have.name,
|
|
118
|
+
detail: `"${want.name}" is not declared by ${provided.source.name}, which instead declares ` +
|
|
119
|
+
`"${renamed.have.name}" of the same type — likely a rename, not confirmed ` +
|
|
120
|
+
`(name similarity ${renamed.similarity.toFixed(2)}).`,
|
|
121
|
+
rename: { from: want.name, to: renamed.have.name, similarity: renamed.similarity },
|
|
122
|
+
});
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
57
125
|
const have = byName.get(want.name);
|
|
58
126
|
if (have === undefined) {
|
|
59
127
|
differences.push({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shapes.js","sourceRoot":"","sources":["../../src/contracts/shapes.ts"],"names":[],"mappings":"AAAA;;oGAEoG;
|
|
1
|
+
{"version":3,"file":"shapes.js","sourceRoot":"","sources":["../../src/contracts/shapes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Frontend-to-backend `API_ENDPOINT` join, as a separate resolution step —
|
|
3
|
+
* Gap 10 of `documents/plans/site-claims-closure-production-plan.md`, built
|
|
4
|
+
* on the ruling in
|
|
5
|
+
* `documents/decisions-inbox/DEC-NEXT-endpoint-identity-repo-scoping.md`.
|
|
6
|
+
*
|
|
7
|
+
* `packages/ir/src/identity.ts`'s `NODE_SCOPE` now folds `repo` into every
|
|
8
|
+
* `API_ENDPOINT` id unconditionally (flipped from `"workspace"` to
|
|
9
|
+
* `"repo"`), so a frontend's caller-side endpoint (minted by
|
|
10
|
+
* `adapter-typescript`'s `extractApiUses`, using the frontend's OWN repo —
|
|
11
|
+
* this repo cannot change that, it lives in `descry-adapters`) and a real
|
|
12
|
+
* backend's `API_ENDPOINT` node (`SERVES_API`-reachable from an
|
|
13
|
+
* `API_ROUTE`, minted with the backend's own repo) no longer share an id
|
|
14
|
+
* just because method+path agree. That is the defect fixed, not a
|
|
15
|
+
* regression — two backends in one workspace serving the identical path
|
|
16
|
+
* used to collide onto one node with no way to tell that apart from a real
|
|
17
|
+
* shared contract.
|
|
18
|
+
*
|
|
19
|
+
* What used to be free — identity equality did the join, silently, whether
|
|
20
|
+
* or not it was correct — now needs an actual resolution pass, run once per
|
|
21
|
+
* workspace build (`packages/mcp/src/workspace-index.ts`), before the
|
|
22
|
+
* merged graph is queried by `contracts/orphans.ts` or anything else:
|
|
23
|
+
*
|
|
24
|
+
* - Exactly one backend in the workspace serves a caller's method+path →
|
|
25
|
+
* resolved directly: every `USES_API` edge that targeted the caller's own
|
|
26
|
+
* placeholder endpoint is rewritten to target the real served node
|
|
27
|
+
* instead. From there down the graph looks exactly as it did before this
|
|
28
|
+
* change (one `API_ENDPOINT` node, both `USES_API` and `SERVES_API`
|
|
29
|
+
* incoming) — the single-backend case is unchanged by design, and
|
|
30
|
+
* `contracts/orphans.ts` needs no changes to keep working.
|
|
31
|
+
* - More than one backend serves the same method+path → resolved via a
|
|
32
|
+
* caller-side hint (`USES_API.attrs.origin`, written by
|
|
33
|
+
* `extractApiUses`) matched against each candidate's own repo name. This
|
|
34
|
+
* is a best-effort proxy, not a real service-discovery signal — no
|
|
35
|
+
* adapter records a backend's own listening origin/base URL anywhere in
|
|
36
|
+
* the graph today (checked: `API_ROUTE`/`API_ENDPOINT` nodes carry only
|
|
37
|
+
* `method`/`pathTemplate`). Disclosed as exactly that, not silently
|
|
38
|
+
* trusted: `originMatchesRepo`'s default only fires on an exact,
|
|
39
|
+
* normalised hostname match, never a substring — a substring match would
|
|
40
|
+
* trade a disclosed ambiguity for a silently wrong single pick, which
|
|
41
|
+
* rule 2 forbids.
|
|
42
|
+
* - No hint resolves, or more than one candidate still matches → never
|
|
43
|
+
* silently picked. Reported as `AmbiguousApiJoin`, "N services expose
|
|
44
|
+
* this path" — the same precision-first pattern `nearestMiss()` already
|
|
45
|
+
* uses for a near-miss caller (`paths.ts`).
|
|
46
|
+
*
|
|
47
|
+
* Caller-only endpoints matching zero served endpoints are left untouched —
|
|
48
|
+
* `contracts/orphans.ts`'s own near-miss/unmatched handling already covers
|
|
49
|
+
* that case on the merged graph, unchanged by this pass.
|
|
50
|
+
*
|
|
51
|
+
* Never deletes a node: an unresolved or ambiguous placeholder stays in the
|
|
52
|
+
* graph exactly as the adapter minted it (rule 7 — a fallback is disclosed,
|
|
53
|
+
* never silently dropped).
|
|
54
|
+
*/
|
|
55
|
+
import type { IRBatch, IREdge, IRNode } from "@descryy/ir";
|
|
56
|
+
import type { EndpointKey } from "./paths.ts";
|
|
57
|
+
export interface ResolvedApiJoin {
|
|
58
|
+
readonly callerEndpointId: string;
|
|
59
|
+
readonly servedEndpointId: string;
|
|
60
|
+
readonly key: EndpointKey;
|
|
61
|
+
readonly via: "single-candidate" | "caller-hint";
|
|
62
|
+
/** How many `USES_API` edges were rewritten from the placeholder onto the real node. */
|
|
63
|
+
readonly rewrittenEdges: number;
|
|
64
|
+
}
|
|
65
|
+
export interface AmbiguousApiJoin {
|
|
66
|
+
readonly callerEndpointId: string;
|
|
67
|
+
readonly key: EndpointKey;
|
|
68
|
+
readonly candidateServedEndpointIds: readonly string[];
|
|
69
|
+
/** The repo each candidate was minted by, `"unknown"` when `repoOf` had no entry for it. */
|
|
70
|
+
readonly candidateRepos: readonly string[];
|
|
71
|
+
readonly detail: string;
|
|
72
|
+
}
|
|
73
|
+
export interface WorkspaceApiJoinResult {
|
|
74
|
+
/** The input edges, with every resolved `USES_API` edge's `to` rewritten
|
|
75
|
+
* onto the real served endpoint. Every other edge is returned unchanged. */
|
|
76
|
+
readonly edges: readonly IREdge[];
|
|
77
|
+
readonly resolved: readonly ResolvedApiJoin[];
|
|
78
|
+
readonly ambiguous: readonly AmbiguousApiJoin[];
|
|
79
|
+
/** Caller-only endpoints whose key matched zero served endpoints. */
|
|
80
|
+
readonly unmatched: number;
|
|
81
|
+
/** Caller-only endpoints missing `method`/`pathTemplate` attrs entirely. */
|
|
82
|
+
readonly unkeyed: number;
|
|
83
|
+
}
|
|
84
|
+
/** Best-effort hostname-vs-repo match. See this module's header for why it
|
|
85
|
+
* is a proxy, not a real signal, and why it only fires on an exact,
|
|
86
|
+
* normalised match rather than a substring one. Exported so a caller with a
|
|
87
|
+
* stronger real signal (e.g. once a backend's own base URL is captured
|
|
88
|
+
* somewhere in the graph) can inject its own matcher instead. */
|
|
89
|
+
export declare function originMatchesRepo(origin: string, repo: string): boolean;
|
|
90
|
+
/** Which repo minted each `API_ENDPOINT` node — read directly off each
|
|
91
|
+
* batch's own (pre-merge) nodes. An adapter's own emitted `id` already
|
|
92
|
+
* equals the merged graph's id for anything that survived merging
|
|
93
|
+
* unmodified (id-preserving merge, DEC-012), so this needs no access to the
|
|
94
|
+
* built graph itself. */
|
|
95
|
+
export declare function repoOfEndpoint(batches: readonly IRBatch[]): ReadonlyMap<string, string>;
|
|
96
|
+
export interface WorkspaceApiJoinOptions {
|
|
97
|
+
/** Overrides the default `originMatchesRepo` hint matcher. */
|
|
98
|
+
readonly matchHint?: (origin: string, repo: string) => boolean;
|
|
99
|
+
}
|
|
100
|
+
/** Resolve every caller-only `API_ENDPOINT` placeholder in a merged graph
|
|
101
|
+
* against the real served endpoints in the same workspace. Pure: no store,
|
|
102
|
+
* no IO, same posture as `buildGraph` itself. */
|
|
103
|
+
export declare function resolveWorkspaceApiJoins(nodes: readonly IRNode[], edges: readonly IREdge[], repoOf: ReadonlyMap<string, string>, options?: WorkspaceApiJoinOptions): WorkspaceApiJoinResult;
|
|
104
|
+
//# sourceMappingURL=workspace-join.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-join.d.ts","sourceRoot":"","sources":["../../src/contracts/workspace-join.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAc9C,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC;IAC1B,QAAQ,CAAC,GAAG,EAAE,kBAAkB,GAAG,aAAa,CAAC;IACjD,wFAAwF;IACxF,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,GAAG,EAAE,WAAW,CAAC;IAC1B,QAAQ,CAAC,0BAA0B,EAAE,SAAS,MAAM,EAAE,CAAC;IACvD,4FAA4F;IAC5F,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,sBAAsB;IACrC;iFAC6E;IAC7E,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;IAC9C,QAAQ,CAAC,SAAS,EAAE,SAAS,gBAAgB,EAAE,CAAC;IAChD,qEAAqE;IACrE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,4EAA4E;IAC5E,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED;;;;kEAIkE;AAClE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CASvE;AAED;;;;0BAI0B;AAC1B,wBAAgB,cAAc,CAAC,OAAO,EAAE,SAAS,OAAO,EAAE,GAAG,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAQvF;AAED,MAAM,WAAW,uBAAuB;IACtC,8DAA8D;IAC9D,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;CAChE;AAED;;kDAEkD;AAClD,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,OAAO,GAAE,uBAA4B,GACpC,sBAAsB,CA8GxB"}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Frontend-to-backend `API_ENDPOINT` join, as a separate resolution step —
|
|
3
|
+
* Gap 10 of `documents/plans/site-claims-closure-production-plan.md`, built
|
|
4
|
+
* on the ruling in
|
|
5
|
+
* `documents/decisions-inbox/DEC-NEXT-endpoint-identity-repo-scoping.md`.
|
|
6
|
+
*
|
|
7
|
+
* `packages/ir/src/identity.ts`'s `NODE_SCOPE` now folds `repo` into every
|
|
8
|
+
* `API_ENDPOINT` id unconditionally (flipped from `"workspace"` to
|
|
9
|
+
* `"repo"`), so a frontend's caller-side endpoint (minted by
|
|
10
|
+
* `adapter-typescript`'s `extractApiUses`, using the frontend's OWN repo —
|
|
11
|
+
* this repo cannot change that, it lives in `descry-adapters`) and a real
|
|
12
|
+
* backend's `API_ENDPOINT` node (`SERVES_API`-reachable from an
|
|
13
|
+
* `API_ROUTE`, minted with the backend's own repo) no longer share an id
|
|
14
|
+
* just because method+path agree. That is the defect fixed, not a
|
|
15
|
+
* regression — two backends in one workspace serving the identical path
|
|
16
|
+
* used to collide onto one node with no way to tell that apart from a real
|
|
17
|
+
* shared contract.
|
|
18
|
+
*
|
|
19
|
+
* What used to be free — identity equality did the join, silently, whether
|
|
20
|
+
* or not it was correct — now needs an actual resolution pass, run once per
|
|
21
|
+
* workspace build (`packages/mcp/src/workspace-index.ts`), before the
|
|
22
|
+
* merged graph is queried by `contracts/orphans.ts` or anything else:
|
|
23
|
+
*
|
|
24
|
+
* - Exactly one backend in the workspace serves a caller's method+path →
|
|
25
|
+
* resolved directly: every `USES_API` edge that targeted the caller's own
|
|
26
|
+
* placeholder endpoint is rewritten to target the real served node
|
|
27
|
+
* instead. From there down the graph looks exactly as it did before this
|
|
28
|
+
* change (one `API_ENDPOINT` node, both `USES_API` and `SERVES_API`
|
|
29
|
+
* incoming) — the single-backend case is unchanged by design, and
|
|
30
|
+
* `contracts/orphans.ts` needs no changes to keep working.
|
|
31
|
+
* - More than one backend serves the same method+path → resolved via a
|
|
32
|
+
* caller-side hint (`USES_API.attrs.origin`, written by
|
|
33
|
+
* `extractApiUses`) matched against each candidate's own repo name. This
|
|
34
|
+
* is a best-effort proxy, not a real service-discovery signal — no
|
|
35
|
+
* adapter records a backend's own listening origin/base URL anywhere in
|
|
36
|
+
* the graph today (checked: `API_ROUTE`/`API_ENDPOINT` nodes carry only
|
|
37
|
+
* `method`/`pathTemplate`). Disclosed as exactly that, not silently
|
|
38
|
+
* trusted: `originMatchesRepo`'s default only fires on an exact,
|
|
39
|
+
* normalised hostname match, never a substring — a substring match would
|
|
40
|
+
* trade a disclosed ambiguity for a silently wrong single pick, which
|
|
41
|
+
* rule 2 forbids.
|
|
42
|
+
* - No hint resolves, or more than one candidate still matches → never
|
|
43
|
+
* silently picked. Reported as `AmbiguousApiJoin`, "N services expose
|
|
44
|
+
* this path" — the same precision-first pattern `nearestMiss()` already
|
|
45
|
+
* uses for a near-miss caller (`paths.ts`).
|
|
46
|
+
*
|
|
47
|
+
* Caller-only endpoints matching zero served endpoints are left untouched —
|
|
48
|
+
* `contracts/orphans.ts`'s own near-miss/unmatched handling already covers
|
|
49
|
+
* that case on the merged graph, unchanged by this pass.
|
|
50
|
+
*
|
|
51
|
+
* Never deletes a node: an unresolved or ambiguous placeholder stays in the
|
|
52
|
+
* graph exactly as the adapter minted it (rule 7 — a fallback is disclosed,
|
|
53
|
+
* never silently dropped).
|
|
54
|
+
*/
|
|
55
|
+
function keyOf(endpoint) {
|
|
56
|
+
const method = endpoint.attrs["method"];
|
|
57
|
+
const pathTemplate = endpoint.attrs["pathTemplate"];
|
|
58
|
+
return typeof method === "string" && typeof pathTemplate === "string"
|
|
59
|
+
? { method, pathTemplate }
|
|
60
|
+
: null;
|
|
61
|
+
}
|
|
62
|
+
function keyString(key) {
|
|
63
|
+
return `${key.method} ${key.pathTemplate}`;
|
|
64
|
+
}
|
|
65
|
+
/** Best-effort hostname-vs-repo match. See this module's header for why it
|
|
66
|
+
* is a proxy, not a real signal, and why it only fires on an exact,
|
|
67
|
+
* normalised match rather than a substring one. Exported so a caller with a
|
|
68
|
+
* stronger real signal (e.g. once a backend's own base URL is captured
|
|
69
|
+
* somewhere in the graph) can inject its own matcher instead. */
|
|
70
|
+
export function originMatchesRepo(origin, repo) {
|
|
71
|
+
const withoutScheme = origin.replace(/^[a-z][a-z0-9+.-]*:\/\//i, "");
|
|
72
|
+
const host = withoutScheme.split(/[/:]/, 1)[0] ?? "";
|
|
73
|
+
const firstLabel = host.split(".")[0] ?? "";
|
|
74
|
+
const repoLastSegment = repo.split("/").pop() ?? repo;
|
|
75
|
+
const normalise = (s) => s.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
76
|
+
const normalisedHost = normalise(firstLabel);
|
|
77
|
+
const normalisedRepo = normalise(repoLastSegment);
|
|
78
|
+
return normalisedHost !== "" && normalisedHost === normalisedRepo;
|
|
79
|
+
}
|
|
80
|
+
/** Which repo minted each `API_ENDPOINT` node — read directly off each
|
|
81
|
+
* batch's own (pre-merge) nodes. An adapter's own emitted `id` already
|
|
82
|
+
* equals the merged graph's id for anything that survived merging
|
|
83
|
+
* unmodified (id-preserving merge, DEC-012), so this needs no access to the
|
|
84
|
+
* built graph itself. */
|
|
85
|
+
export function repoOfEndpoint(batches) {
|
|
86
|
+
const map = new Map();
|
|
87
|
+
for (const batch of batches) {
|
|
88
|
+
for (const node of batch.nodes) {
|
|
89
|
+
if (node.type === "API_ENDPOINT")
|
|
90
|
+
map.set(node.id, batch.repo);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return map;
|
|
94
|
+
}
|
|
95
|
+
/** Resolve every caller-only `API_ENDPOINT` placeholder in a merged graph
|
|
96
|
+
* against the real served endpoints in the same workspace. Pure: no store,
|
|
97
|
+
* no IO, same posture as `buildGraph` itself. */
|
|
98
|
+
export function resolveWorkspaceApiJoins(nodes, edges, repoOf, options = {}) {
|
|
99
|
+
const matchHint = options.matchHint ?? originMatchesRepo;
|
|
100
|
+
const servedIds = new Set();
|
|
101
|
+
const calledIds = new Set();
|
|
102
|
+
for (const edge of edges) {
|
|
103
|
+
if (edge.type === "SERVES_API")
|
|
104
|
+
servedIds.add(edge.to);
|
|
105
|
+
else if (edge.type === "USES_API")
|
|
106
|
+
calledIds.add(edge.to);
|
|
107
|
+
}
|
|
108
|
+
const endpointsById = new Map();
|
|
109
|
+
for (const node of nodes)
|
|
110
|
+
if (node.type === "API_ENDPOINT")
|
|
111
|
+
endpointsById.set(node.id, node);
|
|
112
|
+
const servedByKey = new Map();
|
|
113
|
+
for (const id of servedIds) {
|
|
114
|
+
const node = endpointsById.get(id);
|
|
115
|
+
if (node === undefined)
|
|
116
|
+
continue;
|
|
117
|
+
const key = keyOf(node);
|
|
118
|
+
if (key === null)
|
|
119
|
+
continue;
|
|
120
|
+
const list = servedByKey.get(keyString(key));
|
|
121
|
+
if (list === undefined)
|
|
122
|
+
servedByKey.set(keyString(key), [node]);
|
|
123
|
+
else
|
|
124
|
+
list.push(node);
|
|
125
|
+
}
|
|
126
|
+
const callerOnlyIds = [...calledIds].filter((id) => !servedIds.has(id));
|
|
127
|
+
const resolved = [];
|
|
128
|
+
const ambiguous = [];
|
|
129
|
+
let unmatched = 0;
|
|
130
|
+
let unkeyed = 0;
|
|
131
|
+
const rewrite = new Map();
|
|
132
|
+
for (const callerId of callerOnlyIds) {
|
|
133
|
+
const callerNode = endpointsById.get(callerId);
|
|
134
|
+
if (callerNode === undefined)
|
|
135
|
+
continue;
|
|
136
|
+
const key = keyOf(callerNode);
|
|
137
|
+
if (key === null) {
|
|
138
|
+
unkeyed += 1;
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
const candidates = servedByKey.get(keyString(key)) ?? [];
|
|
142
|
+
if (candidates.length === 0) {
|
|
143
|
+
unmatched += 1;
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
if (candidates.length === 1) {
|
|
147
|
+
rewrite.set(callerId, candidates[0].id);
|
|
148
|
+
resolved.push({
|
|
149
|
+
callerEndpointId: callerId,
|
|
150
|
+
servedEndpointId: candidates[0].id,
|
|
151
|
+
key,
|
|
152
|
+
via: "single-candidate",
|
|
153
|
+
rewrittenEdges: 0,
|
|
154
|
+
});
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
// Multiple backends serve this exact method+path. Try the caller-side
|
|
158
|
+
// hint on every USES_API edge that targets this placeholder.
|
|
159
|
+
const callerEdges = edges.filter((e) => e.type === "USES_API" && e.to === callerId);
|
|
160
|
+
const hintMatches = new Set();
|
|
161
|
+
for (const candidate of candidates) {
|
|
162
|
+
const repo = repoOf.get(candidate.id);
|
|
163
|
+
if (repo === undefined)
|
|
164
|
+
continue;
|
|
165
|
+
const matchesAnyEdge = callerEdges.some((e) => {
|
|
166
|
+
const origin = e.attrs?.["origin"];
|
|
167
|
+
return typeof origin === "string" && origin !== "" && matchHint(origin, repo);
|
|
168
|
+
});
|
|
169
|
+
if (matchesAnyEdge)
|
|
170
|
+
hintMatches.add(candidate);
|
|
171
|
+
}
|
|
172
|
+
if (hintMatches.size === 1) {
|
|
173
|
+
const [only] = hintMatches;
|
|
174
|
+
rewrite.set(callerId, only.id);
|
|
175
|
+
resolved.push({
|
|
176
|
+
callerEndpointId: callerId,
|
|
177
|
+
servedEndpointId: only.id,
|
|
178
|
+
key,
|
|
179
|
+
via: "caller-hint",
|
|
180
|
+
rewrittenEdges: 0,
|
|
181
|
+
});
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
ambiguous.push({
|
|
185
|
+
callerEndpointId: callerId,
|
|
186
|
+
key,
|
|
187
|
+
candidateServedEndpointIds: candidates.map((c) => c.id),
|
|
188
|
+
candidateRepos: candidates.map((c) => repoOf.get(c.id) ?? "unknown"),
|
|
189
|
+
detail: `${candidates.length} services in this workspace expose ${key.method} ${key.pathTemplate}, and ` +
|
|
190
|
+
(hintMatches.size === 0
|
|
191
|
+
? "no caller-reported origin matched any of them"
|
|
192
|
+
: `${hintMatches.size} matched, not exactly one`) +
|
|
193
|
+
" — reported as ambiguous rather than silently picking one.",
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
const rewrittenEdges = edges.map((edge) => {
|
|
197
|
+
if (edge.type !== "USES_API")
|
|
198
|
+
return edge;
|
|
199
|
+
const target = rewrite.get(edge.to);
|
|
200
|
+
return target === undefined ? edge : { ...edge, to: target };
|
|
201
|
+
});
|
|
202
|
+
const finalResolved = resolved.map((r) => ({
|
|
203
|
+
...r,
|
|
204
|
+
rewrittenEdges: edges.filter((e) => e.type === "USES_API" && e.to === r.callerEndpointId).length,
|
|
205
|
+
}));
|
|
206
|
+
return { edges: rewrittenEdges, resolved: finalResolved, ambiguous, unmatched, unkeyed };
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=workspace-join.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-join.js","sourceRoot":"","sources":["../../src/contracts/workspace-join.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export * from "./sources/git/index.ts";
|
|
|
7
7
|
export * from "./sources/migrations/index.ts";
|
|
8
8
|
export * from "./sources/workspace/index.ts";
|
|
9
9
|
export * from "./sources/confirmed/index.ts";
|
|
10
|
+
export * from "./workspace/index.ts";
|
|
10
11
|
export * from "./scoping/index.ts";
|
|
11
12
|
export * from "./contracts/index.ts";
|
|
12
13
|
export * from "./capabilities/index.ts";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,YAAY,kBAAkB,CAAC;AAE5C,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,YAAY,kBAAkB,CAAC;AAE5C,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,wBAAwB,CAAC;AACvC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,8BAA8B,CAAC;AAI7C,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -8,6 +8,10 @@ export * from "./sources/git/index.js";
|
|
|
8
8
|
export * from "./sources/migrations/index.js";
|
|
9
9
|
export * from "./sources/workspace/index.js";
|
|
10
10
|
export * from "./sources/confirmed/index.js";
|
|
11
|
+
// Gap 1 (site-claims-closure-production-plan.md): the shared-graph layout for
|
|
12
|
+
// a workspace's own store, distinct from `./sources/workspace/` above, which
|
|
13
|
+
// is the declared-pairing reader (`descry.json`) and shares no names with it.
|
|
14
|
+
export * from "./workspace/index.js";
|
|
11
15
|
export * from "./scoping/index.js";
|
|
12
16
|
export * from "./contracts/index.js";
|
|
13
17
|
export * from "./capabilities/index.js";
|