@concordance-wiki/inference 0.1.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.
Files changed (139) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +15 -0
  3. package/dist/combine/confidence.d.ts +16 -0
  4. package/dist/combine/confidence.d.ts.map +1 -0
  5. package/dist/combine/confidence.js +24 -0
  6. package/dist/combine/confidence.js.map +1 -0
  7. package/dist/combine/links.d.ts +15 -0
  8. package/dist/combine/links.d.ts.map +1 -0
  9. package/dist/combine/links.js +0 -0
  10. package/dist/combine/links.js.map +1 -0
  11. package/dist/display/neighbourhood.d.ts +15 -0
  12. package/dist/display/neighbourhood.d.ts.map +1 -0
  13. package/dist/display/neighbourhood.js +83 -0
  14. package/dist/display/neighbourhood.js.map +1 -0
  15. package/dist/display/options.d.ts +5 -0
  16. package/dist/display/options.d.ts.map +1 -0
  17. package/dist/display/options.js +6 -0
  18. package/dist/display/options.js.map +1 -0
  19. package/dist/display/serialize.d.ts +7 -0
  20. package/dist/display/serialize.d.ts.map +1 -0
  21. package/dist/display/serialize.js +13 -0
  22. package/dist/display/serialize.js.map +1 -0
  23. package/dist/display/types.d.ts +44 -0
  24. package/dist/display/types.d.ts.map +1 -0
  25. package/dist/display/types.js +2 -0
  26. package/dist/display/types.js.map +1 -0
  27. package/dist/duplicates/content.d.ts +29 -0
  28. package/dist/duplicates/content.d.ts.map +1 -0
  29. package/dist/duplicates/content.js +42 -0
  30. package/dist/duplicates/content.js.map +1 -0
  31. package/dist/duplicates/lsh.d.ts +8 -0
  32. package/dist/duplicates/lsh.d.ts.map +1 -0
  33. package/dist/duplicates/lsh.js +38 -0
  34. package/dist/duplicates/lsh.js.map +1 -0
  35. package/dist/duplicates/minhash.d.ts +11 -0
  36. package/dist/duplicates/minhash.d.ts.map +1 -0
  37. package/dist/duplicates/minhash.js +51 -0
  38. package/dist/duplicates/minhash.js.map +1 -0
  39. package/dist/duplicates/options.d.ts +6 -0
  40. package/dist/duplicates/options.d.ts.map +1 -0
  41. package/dist/duplicates/options.js +23 -0
  42. package/dist/duplicates/options.js.map +1 -0
  43. package/dist/duplicates/resolve.d.ts +13 -0
  44. package/dist/duplicates/resolve.d.ts.map +1 -0
  45. package/dist/duplicates/resolve.js +257 -0
  46. package/dist/duplicates/resolve.js.map +1 -0
  47. package/dist/duplicates/score.d.ts +22 -0
  48. package/dist/duplicates/score.d.ts.map +1 -0
  49. package/dist/duplicates/score.js +190 -0
  50. package/dist/duplicates/score.js.map +1 -0
  51. package/dist/duplicates/shingles.d.ts +15 -0
  52. package/dist/duplicates/shingles.d.ts.map +1 -0
  53. package/dist/duplicates/shingles.js +35 -0
  54. package/dist/duplicates/shingles.js.map +1 -0
  55. package/dist/duplicates/similarity.d.ts +23 -0
  56. package/dist/duplicates/similarity.d.ts.map +1 -0
  57. package/dist/duplicates/similarity.js +86 -0
  58. package/dist/duplicates/similarity.js.map +1 -0
  59. package/dist/duplicates/types.d.ts +97 -0
  60. package/dist/duplicates/types.d.ts.map +1 -0
  61. package/dist/duplicates/types.js +2 -0
  62. package/dist/duplicates/types.js.map +1 -0
  63. package/dist/explicit/links.d.ts +30 -0
  64. package/dist/explicit/links.d.ts.map +1 -0
  65. package/dist/explicit/links.js +173 -0
  66. package/dist/explicit/links.js.map +1 -0
  67. package/dist/explicit/types.d.ts +35 -0
  68. package/dist/explicit/types.d.ts.map +1 -0
  69. package/dist/explicit/types.js +2 -0
  70. package/dist/explicit/types.js.map +1 -0
  71. package/dist/frontmatter/links.d.ts +21 -0
  72. package/dist/frontmatter/links.d.ts.map +1 -0
  73. package/dist/frontmatter/links.js +131 -0
  74. package/dist/frontmatter/links.js.map +1 -0
  75. package/dist/frontmatter/resolve.d.ts +32 -0
  76. package/dist/frontmatter/resolve.d.ts.map +1 -0
  77. package/dist/frontmatter/resolve.js +62 -0
  78. package/dist/frontmatter/resolve.js.map +1 -0
  79. package/dist/index.d.ts +26 -0
  80. package/dist/index.d.ts.map +1 -0
  81. package/dist/index.js +19 -0
  82. package/dist/index.js.map +1 -0
  83. package/dist/mentions/links.d.ts +43 -0
  84. package/dist/mentions/links.d.ts.map +1 -0
  85. package/dist/mentions/links.js +106 -0
  86. package/dist/mentions/links.js.map +1 -0
  87. package/dist/mentions/sections.d.ts +17 -0
  88. package/dist/mentions/sections.d.ts.map +1 -0
  89. package/dist/mentions/sections.js +26 -0
  90. package/dist/mentions/sections.js.map +1 -0
  91. package/dist/neighbourhood/accumulate.d.ts +11 -0
  92. package/dist/neighbourhood/accumulate.d.ts.map +1 -0
  93. package/dist/neighbourhood/accumulate.js +73 -0
  94. package/dist/neighbourhood/accumulate.js.map +1 -0
  95. package/dist/neighbourhood/links.d.ts +13 -0
  96. package/dist/neighbourhood/links.d.ts.map +1 -0
  97. package/dist/neighbourhood/links.js +35 -0
  98. package/dist/neighbourhood/links.js.map +1 -0
  99. package/dist/neighbourhood/options.d.ts +5 -0
  100. package/dist/neighbourhood/options.d.ts.map +1 -0
  101. package/dist/neighbourhood/options.js +6 -0
  102. package/dist/neighbourhood/options.js.map +1 -0
  103. package/dist/neighbourhood/order.d.ts +5 -0
  104. package/dist/neighbourhood/order.d.ts.map +1 -0
  105. package/dist/neighbourhood/order.js +9 -0
  106. package/dist/neighbourhood/order.js.map +1 -0
  107. package/dist/neighbourhood/serialize.d.ts +4 -0
  108. package/dist/neighbourhood/serialize.d.ts.map +1 -0
  109. package/dist/neighbourhood/serialize.js +10 -0
  110. package/dist/neighbourhood/serialize.js.map +1 -0
  111. package/dist/neighbourhood/types.d.ts +24 -0
  112. package/dist/neighbourhood/types.d.ts.map +1 -0
  113. package/dist/neighbourhood/types.js +2 -0
  114. package/dist/neighbourhood/types.js.map +1 -0
  115. package/dist/operations/index.d.ts +30 -0
  116. package/dist/operations/index.d.ts.map +1 -0
  117. package/dist/operations/index.js +118 -0
  118. package/dist/operations/index.js.map +1 -0
  119. package/dist/operations/match.d.ts +64 -0
  120. package/dist/operations/match.d.ts.map +1 -0
  121. package/dist/operations/match.js +251 -0
  122. package/dist/operations/match.js.map +1 -0
  123. package/dist/operations/merge.d.ts +14 -0
  124. package/dist/operations/merge.d.ts.map +1 -0
  125. package/dist/operations/merge.js +60 -0
  126. package/dist/operations/merge.js.map +1 -0
  127. package/dist/relations/index.d.ts +3 -0
  128. package/dist/relations/index.d.ts.map +1 -0
  129. package/dist/relations/index.js +3 -0
  130. package/dist/relations/index.js.map +1 -0
  131. package/dist/relations/labels.d.ts +14 -0
  132. package/dist/relations/labels.d.ts.map +1 -0
  133. package/dist/relations/labels.js +22 -0
  134. package/dist/relations/labels.js.map +1 -0
  135. package/dist/relations/type.d.ts +40 -0
  136. package/dist/relations/type.d.ts.map +1 -0
  137. package/dist/relations/type.js +161 -0
  138. package/dist/relations/type.js.map +1 -0
  139. package/package.json +46 -0
@@ -0,0 +1,24 @@
1
+ /** What the accumulation needs of an occurrence: the entity it names and the paragraph it sits in. */
2
+ export interface OccurrenceLike {
3
+ target: {
4
+ id: string;
5
+ };
6
+ source?: string;
7
+ /** Forward-slash path relative to the source root. */
8
+ path: string;
9
+ line: number;
10
+ }
11
+ export interface Neighbour {
12
+ id: string;
13
+ /** Number of paragraphs where both entities appear. */
14
+ count: number;
15
+ }
16
+ export interface Neighbourhood {
17
+ k: number;
18
+ /** Nodes in identifier order; each holds at most `k` neighbours, by count then by identifier. */
19
+ nodes: ReadonlyMap<string, Neighbour[]>;
20
+ }
21
+ export interface NeighbourhoodOptions {
22
+ k: number;
23
+ }
24
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/neighbourhood/types.ts"],"names":[],"mappings":"AAAA,sGAAsG;AACtG,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sDAAsD;IACtD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,CAAC,EAAE,MAAM,CAAC;IACV,iGAAiG;IACjG,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,oBAAoB;IACnC,CAAC,EAAE,MAAM,CAAC;CACX"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/neighbourhood/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,30 @@
1
+ import { type Entity, type Finding, type Link } from "@concordance-wiki/core";
2
+ import type { Profile } from "@concordance-wiki/profile";
3
+ export declare const OPERATION_AMBIGUOUS = "W-OPERATION-AMBIGUOUS";
4
+ export declare const OPERATION_UNMATCHED = "W-OPERATION-UNMATCHED";
5
+ export interface AttachOperationsInput {
6
+ entities: readonly Entity[];
7
+ /** The links recorded so far, the `exposes` links of the contract import among them. */
8
+ links: readonly Link[];
9
+ profile: Profile;
10
+ /** The comparison form of a text; the language pack of the project provides it. */
11
+ normalize: (text: string) => string;
12
+ }
13
+ export interface AttachOperationsResult {
14
+ entities: Entity[];
15
+ links: Link[];
16
+ findings: Finding[];
17
+ }
18
+ /**
19
+ * Attaches the hand-written `endpoint` notes to the operations imported from the contracts:
20
+ * a matched pair merges into the note, which keeps its identifier, its markdown and its frontmatter
21
+ * and gains the contract attributes it does not set, the contract as a representation and the rung
22
+ * as `grouped_by`; the imported operation disappears and every link that named it, the `exposes`
23
+ * link first of all, now names the note. An ambiguous match attaches nothing and is reported as
24
+ * `W-OPERATION-AMBIGUOUS`; a note that names an API with a contract and matches nothing is
25
+ * reported as `W-OPERATION-UNMATCHED`. Pure and deterministic: every output is in canonical order.
26
+ */
27
+ export declare function attachOperations(input: AttachOperationsInput): AttachOperationsResult;
28
+ export { MATCH_RUNGS, importedOperations, matchOperations, operationNotes, type Ambiguity, type ImportedOperation, type MatchResult, type MatchRung, type OperationMatch, type OperationNote, } from "./match.js";
29
+ export { CONTRACT_REPRESENTATION, mergeOperation, redirectLinks } from "./merge.js";
30
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/operations/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,MAAM,EACX,KAAK,OAAO,EACZ,KAAK,IAAI,EACV,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAczD,eAAO,MAAM,mBAAmB,0BAA0B,CAAC;AAC3D,eAAO,MAAM,mBAAmB,0BAA0B,CAAC;AAe3D,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,wFAAwF;IACxF,KAAK,EAAE,SAAS,IAAI,EAAE,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,mFAAmF;IACnF,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;CACrC;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAyED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,sBAAsB,CAuBrF;AAED,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,KAAK,SAAS,EACd,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,aAAa,GACnB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,uBAAuB,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,118 @@
1
+ import { compareEntities, compareFindings, compareLinks, } from "@concordance-wiki/core";
2
+ import { importedOperations, matchOperations, operationNotes, } from "./match.js";
3
+ import { mergeOperation, redirectLinks } from "./merge.js";
4
+ export const OPERATION_AMBIGUOUS = "W-OPERATION-AMBIGUOUS";
5
+ export const OPERATION_UNMATCHED = "W-OPERATION-UNMATCHED";
6
+ const REMEDIATION = "Give each operation note the operation_id of exactly one operation of its API, name the API in the api attribute when the source declares several contracts, or remove the note that duplicates another.";
7
+ const UNMATCHED_REMEDIATION = "Compare the note with the contract: when the operation is gone, retire the note or point it at the operation that replaced it; when the note is ahead of the contract, keep it and give it the operation_id the next version will declare, so that it attaches then.";
8
+ /** How a finding names the rung an ambiguity was met at. */
9
+ const RUNG_LABELS = {
10
+ operation_id: "the operation identifier",
11
+ method_path: "the method and path",
12
+ title: "the title",
13
+ };
14
+ function ambiguityFinding(ambiguity) {
15
+ const rung = RUNG_LABELS[ambiguity.rung];
16
+ if (ambiguity.kind === "note") {
17
+ const { note, operations } = ambiguity;
18
+ const named = operations.map((operation) => operation.entity.id).join(", ");
19
+ return {
20
+ check: OPERATION_AMBIGUOUS,
21
+ severity: "warning",
22
+ message: `operation note ${note.id} matches ${String(operations.length)} operations on ${rung}: ${named}; none is attached`,
23
+ remediation: REMEDIATION,
24
+ source: note.source.name,
25
+ path: note.source.path,
26
+ line: 1,
27
+ entity: note.id,
28
+ };
29
+ }
30
+ const { operation, notes } = ambiguity;
31
+ const named = notes.map((note) => note.id).join(", ");
32
+ return {
33
+ check: OPERATION_AMBIGUOUS,
34
+ severity: "warning",
35
+ message: `operation ${operation.entity.id} of ${operation.api} is claimed by ${String(notes.length)} notes on ${rung}: ${named}; none is attached`,
36
+ remediation: REMEDIATION,
37
+ source: operation.entity.source.name,
38
+ path: operation.location,
39
+ entity: operation.entity.id,
40
+ };
41
+ }
42
+ /** The candidate APIs of a note with their contract, as the imported operations name it, in identifier order. */
43
+ function candidatesOf(note, operations) {
44
+ const locations = new Map();
45
+ for (const operation of operations) {
46
+ if (note.apis.includes(operation.api))
47
+ locations.set(operation.api, operation.location);
48
+ }
49
+ return [...locations].map(([api, location]) => `${api} (${location})`).join(", ");
50
+ }
51
+ function unmatchedFinding(note, operations) {
52
+ const apis = candidatesOf(note, operations);
53
+ return {
54
+ check: OPERATION_UNMATCHED,
55
+ severity: "warning",
56
+ message: `operation note ${note.entity.id} matches no operation of ${apis}: the operation disappeared from the contract, or the note is ahead of it`,
57
+ remediation: UNMATCHED_REMEDIATION,
58
+ source: note.entity.source.name,
59
+ path: note.entity.source.path,
60
+ line: 1,
61
+ entity: note.entity.id,
62
+ };
63
+ }
64
+ /**
65
+ * The notes that name an API with an imported contract and neither matched nor took part in an
66
+ * ambiguity: either their operation left the contract or the note is ahead of it. A note that
67
+ * names no API is a candidate for every contract of its source and is not reported: it may
68
+ * describe an API without a contract.
69
+ */
70
+ function unmatchedNotes(notes, { matches, ambiguities }) {
71
+ const settled = new Set();
72
+ for (const match of matches)
73
+ settled.add(match.note.id);
74
+ for (const ambiguity of ambiguities) {
75
+ if (ambiguity.kind === "note")
76
+ settled.add(ambiguity.note.id);
77
+ else
78
+ for (const claimant of ambiguity.notes)
79
+ settled.add(claimant.id);
80
+ }
81
+ return notes.filter((note) => note.declared && !settled.has(note.entity.id));
82
+ }
83
+ /**
84
+ * Attaches the hand-written `endpoint` notes to the operations imported from the contracts:
85
+ * a matched pair merges into the note, which keeps its identifier, its markdown and its frontmatter
86
+ * and gains the contract attributes it does not set, the contract as a representation and the rung
87
+ * as `grouped_by`; the imported operation disappears and every link that named it, the `exposes`
88
+ * link first of all, now names the note. An ambiguous match attaches nothing and is reported as
89
+ * `W-OPERATION-AMBIGUOUS`; a note that names an API with a contract and matches nothing is
90
+ * reported as `W-OPERATION-UNMATCHED`. Pure and deterministic: every output is in canonical order.
91
+ */
92
+ export function attachOperations(input) {
93
+ const { entities, links, profile, normalize } = input;
94
+ const operations = importedOperations(entities, links);
95
+ const notes = operationNotes(entities, links, operations, profile);
96
+ const result = matchOperations(notes, operations, normalize);
97
+ const { matches, ambiguities } = result;
98
+ const merged = new Map();
99
+ const redirections = new Map();
100
+ for (const match of matches) {
101
+ merged.set(match.note.id, mergeOperation(match.note, match.operation, match.rung));
102
+ redirections.set(match.operation.entity.id, match.note.id);
103
+ }
104
+ return {
105
+ entities: entities
106
+ .filter((entity) => !redirections.has(entity.id))
107
+ .map((entity) => merged.get(entity.id) ?? entity)
108
+ .sort(compareEntities),
109
+ links: redirectLinks(links, redirections).sort(compareLinks),
110
+ findings: [
111
+ ...ambiguities.map(ambiguityFinding),
112
+ ...unmatchedNotes(notes, result).map((note) => unmatchedFinding(note, operations)),
113
+ ].sort(compareFindings),
114
+ };
115
+ }
116
+ export { MATCH_RUNGS, importedOperations, matchOperations, operationNotes, } from "./match.js";
117
+ export { CONTRACT_REPRESENTATION, mergeOperation, redirectLinks } from "./merge.js";
118
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/operations/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import { type Entity, type Link } from "@concordance-wiki/core";
2
+ import type { Profile } from "@concordance-wiki/profile";
3
+ /** The three rungs of the matching, tried in this order; a note stops at the first one that matches. */
4
+ export type MatchRung = "operation_id" | "method_path" | "title";
5
+ export declare const MATCH_RUNGS: readonly MatchRung[];
6
+ /** An `endpoint` entity a contract plugin produced, with what the `exposes` link says about it. */
7
+ export interface ImportedOperation {
8
+ entity: Entity;
9
+ /** Identifier of the `api` entity that declares the contract. */
10
+ api: string;
11
+ /** The contract location as written in the API note. */
12
+ location: string;
13
+ /** The operation name as the contract writes it. */
14
+ name: string;
15
+ }
16
+ /** A hand-written `endpoint` note and the APIs whose operations it may describe. */
17
+ export interface OperationNote {
18
+ entity: Entity;
19
+ /** Identifiers of the candidate APIs, sorted; every API of the source when the note names none. */
20
+ apis: readonly string[];
21
+ /** Whether the note names its API, in frontmatter or through a recorded link. */
22
+ declared: boolean;
23
+ }
24
+ export interface OperationMatch {
25
+ note: Entity;
26
+ operation: ImportedOperation;
27
+ rung: MatchRung;
28
+ }
29
+ /** A note that matches several operations, or an operation that several notes claim, at one rung; candidates are in identifier order. */
30
+ export type Ambiguity = {
31
+ kind: "note";
32
+ rung: MatchRung;
33
+ note: Entity;
34
+ operations: ImportedOperation[];
35
+ } | {
36
+ kind: "operation";
37
+ rung: MatchRung;
38
+ operation: ImportedOperation;
39
+ notes: Entity[];
40
+ };
41
+ export interface MatchResult {
42
+ matches: OperationMatch[];
43
+ ambiguities: Ambiguity[];
44
+ }
45
+ /** The imported operations of the entities: the `endpoint` entities of contract origin that an `exposes` link attaches to an API. */
46
+ export declare function importedOperations(entities: readonly Entity[], links: readonly Link[]): ImportedOperation[];
47
+ /**
48
+ * The hand-written `endpoint` notes with their candidate APIs: the API a reference attribute of
49
+ * the profile names, else the APIs a recorded link joins to the note, else every API of the note's
50
+ * source that has imported operations. Only APIs with imported operations count.
51
+ */
52
+ export declare function operationNotes(entities: readonly Entity[], links: readonly Link[], operations: readonly ImportedOperation[], profile: Profile): OperationNote[];
53
+ type Normalize = (text: string) => string;
54
+ /**
55
+ * Matches the notes to the operations rung by rung: the operation identifier, then the method and
56
+ * path (or the port and the operation name for SOAP), then the title in comparison form. At each
57
+ * rung a note claims the operations of its candidate APIs whose key equals one of its own; a note
58
+ * claiming several operations, or an operation claimed by several notes, is an ambiguity that
59
+ * attaches nothing and takes its entities out of the later rungs. The rest attach one to one and
60
+ * leave the later rungs to the notes and operations still free.
61
+ */
62
+ export declare function matchOperations(notes: readonly OperationNote[], operations: readonly ImportedOperation[], normalize: Normalize): MatchResult;
63
+ export {};
64
+ //# sourceMappingURL=match.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"match.d.ts","sourceRoot":"","sources":["../../src/operations/match.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,MAAM,EACX,KAAK,IAAI,EACV,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AAIzD,wGAAwG;AACxG,MAAM,MAAM,SAAS,GAAG,cAAc,GAAG,aAAa,GAAG,OAAO,CAAC;AAEjE,eAAO,MAAM,WAAW,EAAE,SAAS,SAAS,EAA6C,CAAC;AAE1F,mGAAmG;AACnG,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAC;IACZ,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,oFAAoF;AACpF,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,mGAAmG;IACnG,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,iFAAiF;IACjF,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,iBAAiB,CAAC;IAC7B,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,yIAAyI;AACzI,MAAM,MAAM,SAAS,GACjB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,iBAAiB,EAAE,CAAA;CAAE,GAChF;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,SAAS,CAAC;IAAC,SAAS,EAAE,iBAAiB,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAE1F,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,WAAW,EAAE,SAAS,EAAE,CAAC;CAC1B;AAWD,qIAAqI;AACrI,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,KAAK,EAAE,SAAS,IAAI,EAAE,GACrB,iBAAiB,EAAE,CAmBrB;AA4CD;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,KAAK,EAAE,SAAS,IAAI,EAAE,EACtB,UAAU,EAAE,SAAS,iBAAiB,EAAE,EACxC,OAAO,EAAE,OAAO,GACf,aAAa,EAAE,CA0BjB;AAOD,KAAK,SAAS,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;AAyK1C;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,SAAS,aAAa,EAAE,EAC/B,UAAU,EAAE,SAAS,iBAAiB,EAAE,EACxC,SAAS,EAAE,SAAS,GACnB,WAAW,CAeb"}
@@ -0,0 +1,251 @@
1
+ import { CONTRACT_METHOD, CONTRACT_RELATION, compareEntities, } from "@concordance-wiki/core";
2
+ import { indexEntities, resolveReference } from "../frontmatter/resolve.js";
3
+ export const MATCH_RUNGS = ["operation_id", "method_path", "title"];
4
+ function byCodeUnit(a, b) {
5
+ return Number(a > b) - Number(a < b);
6
+ }
7
+ function stringAttribute(entity, key) {
8
+ const value = entity.attributes[key];
9
+ return typeof value === "string" && value.trim() !== "" ? value.trim() : undefined;
10
+ }
11
+ /** The imported operations of the entities: the `endpoint` entities of contract origin that an `exposes` link attaches to an API. */
12
+ export function importedOperations(entities, links) {
13
+ const exposed = new Map();
14
+ for (const link of links) {
15
+ if (link.relation === CONTRACT_RELATION)
16
+ exposed.set(link.to, link);
17
+ }
18
+ const operations = [];
19
+ for (const entity of entities) {
20
+ if (entity.type !== "endpoint" || entity.type_origin !== "contract")
21
+ continue;
22
+ const link = exposed.get(entity.id);
23
+ if (link === undefined)
24
+ continue;
25
+ const imported = link.provenance.find((provenance) => provenance.method === CONTRACT_METHOD);
26
+ operations.push({
27
+ entity,
28
+ api: link.from,
29
+ location: entity.source.path,
30
+ name: imported?.operation ?? entity.title,
31
+ });
32
+ }
33
+ return operations.sort((a, b) => compareEntities(a.entity, b.entity));
34
+ }
35
+ /** The names of the `endpoint` attributes that reference an `api`, `api` in the default profile. */
36
+ function apiAttributes(profile) {
37
+ const attributes = profile.types["endpoint"]?.attributes ?? {};
38
+ return Object.entries(attributes)
39
+ .filter(([, definition]) => {
40
+ if (definition.type !== "ref" && definition.type !== "ref[]")
41
+ return false;
42
+ const { target } = definition;
43
+ const targets = typeof target === "string" ? [target] : (target ?? []);
44
+ return targets.includes("api");
45
+ })
46
+ .map(([name]) => name)
47
+ .sort(byCodeUnit);
48
+ }
49
+ function declaredApi(note, attributes, entities, apis) {
50
+ const index = indexEntities(entities);
51
+ for (const attribute of attributes) {
52
+ const value = stringAttribute(note, attribute);
53
+ if (value === undefined)
54
+ continue;
55
+ const resolution = resolveReference(value, { from: note, index });
56
+ if (resolution.kind === "resolved" && apis.has(resolution.entity.id)) {
57
+ return resolution.entity.id;
58
+ }
59
+ }
60
+ return undefined;
61
+ }
62
+ /** The APIs a recorded link joins to the note, in either direction: a markdown link to the API note, typically. */
63
+ function linkedApis(note, links, apis) {
64
+ const linked = new Set();
65
+ for (const link of links) {
66
+ if (link.from === note.id && apis.has(link.to))
67
+ linked.add(link.to);
68
+ if (link.to === note.id && apis.has(link.from))
69
+ linked.add(link.from);
70
+ }
71
+ return [...linked].sort(byCodeUnit);
72
+ }
73
+ /**
74
+ * The hand-written `endpoint` notes with their candidate APIs: the API a reference attribute of
75
+ * the profile names, else the APIs a recorded link joins to the note, else every API of the note's
76
+ * source that has imported operations. Only APIs with imported operations count.
77
+ */
78
+ export function operationNotes(entities, links, operations, profile) {
79
+ const apis = new Set(operations.map((operation) => operation.api));
80
+ const byApi = new Map(entities.filter((entity) => apis.has(entity.id)).map((entity) => [entity.id, entity]));
81
+ const attributes = apiAttributes(profile);
82
+ const notes = [];
83
+ for (const entity of [...entities].sort(compareEntities)) {
84
+ if (entity.type !== "endpoint" || entity.type_origin === "contract")
85
+ continue;
86
+ const declared = declaredApi(entity, attributes, entities, apis);
87
+ if (declared !== undefined) {
88
+ notes.push({ entity, apis: [declared], declared: true });
89
+ continue;
90
+ }
91
+ const linked = linkedApis(entity, links, apis);
92
+ if (linked.length > 0) {
93
+ notes.push({ entity, apis: linked, declared: true });
94
+ continue;
95
+ }
96
+ const sameSource = [...byApi.values()]
97
+ .filter((api) => api.source.name === entity.source.name)
98
+ .map((api) => api.id)
99
+ .sort(byCodeUnit);
100
+ notes.push({ entity, apis: sameSource, declared: false });
101
+ }
102
+ return notes;
103
+ }
104
+ /** The comparison form without spaces or punctuation, so that `List entities` equals `listEntities`. */
105
+ function compact(text, normalize) {
106
+ return normalize(text).replace(/[^\p{L}\p{N}]+/gu, "");
107
+ }
108
+ /** The keys an imported operation answers to at a rung; an operation without the attributes of a rung has none. */
109
+ function operationKeys(operation, rung, normalize) {
110
+ const { entity, name } = operation;
111
+ const id = stringAttribute(entity, "operation_id");
112
+ if (rung === "operation_id")
113
+ return id === undefined ? [] : [id];
114
+ if (rung === "method_path") {
115
+ const method = stringAttribute(entity, "method");
116
+ const path = stringAttribute(entity, "path");
117
+ const port = stringAttribute(entity, "port");
118
+ return [
119
+ ...(method !== undefined && path !== undefined
120
+ ? [`http ${method.toUpperCase()} ${path}`]
121
+ : []),
122
+ ...(port === undefined ? [] : [`soap ${port} ${compact(name, normalize)}`]),
123
+ ];
124
+ }
125
+ const titles = [entity.title, name, ...(id === undefined ? [] : [id])];
126
+ return [...new Set(titles.map((title) => compact(title, normalize)))].filter((key) => key !== "");
127
+ }
128
+ /** The keys a note offers at a rung: the operation identifier, the method and path or the port and title, the title. */
129
+ function noteKeys(note, rung, normalize) {
130
+ if (rung === "operation_id") {
131
+ const id = stringAttribute(note, "operation_id");
132
+ return id === undefined ? [] : [id];
133
+ }
134
+ if (rung === "method_path") {
135
+ const method = stringAttribute(note, "method");
136
+ const path = stringAttribute(note, "path");
137
+ const port = stringAttribute(note, "port");
138
+ return [
139
+ ...(method !== undefined && path !== undefined
140
+ ? [`http ${method.toUpperCase()} ${path}`]
141
+ : []),
142
+ ...(port === undefined ? [] : [`soap ${port} ${compact(note.title, normalize)}`]),
143
+ ];
144
+ }
145
+ const title = compact(note.title, normalize);
146
+ return title === "" ? [] : [title];
147
+ }
148
+ /** The operations by API and key at the rung; an operation with several keys sits under each. */
149
+ function keyedOperations(operations, rung, normalize) {
150
+ const keyed = new Map();
151
+ for (const operation of operations) {
152
+ for (const key of operationKeys(operation, rung, normalize)) {
153
+ const bucket = keyed.get(`${operation.api}\n${key}`) ?? [];
154
+ bucket.push(operation);
155
+ keyed.set(`${operation.api}\n${key}`, bucket);
156
+ }
157
+ }
158
+ return keyed;
159
+ }
160
+ /** The operations of the note's candidate APIs whose key equals one of the note's, in entity order. */
161
+ function claimedBy(note, keyed, rung, normalize) {
162
+ const claimed = new Map();
163
+ for (const api of note.apis) {
164
+ for (const key of noteKeys(note.entity, rung, normalize)) {
165
+ for (const operation of keyed.get(`${api}\n${key}`) ?? []) {
166
+ claimed.set(operation.entity.id, operation);
167
+ }
168
+ }
169
+ }
170
+ return [...claimed.values()].sort((a, b) => compareEntities(a.entity, b.entity));
171
+ }
172
+ function claimsAt(rung, notes, operations, normalize) {
173
+ const keyed = keyedOperations(operations, rung, normalize);
174
+ const byNote = new Map();
175
+ const byOperation = new Map();
176
+ for (const note of notes) {
177
+ const found = claimedBy(note, keyed, rung, normalize);
178
+ if (found.length === 0)
179
+ continue;
180
+ byNote.set(note.entity.id, found);
181
+ for (const operation of found) {
182
+ const claimants = byOperation.get(operation.entity.id) ?? [];
183
+ claimants.push(note.entity);
184
+ byOperation.set(operation.entity.id, claimants);
185
+ }
186
+ }
187
+ return { byNote, byOperation };
188
+ }
189
+ /** A note claiming several operations is an ambiguity that settles the note and every operation it claims. */
190
+ function hesitantNotes(rung, notes, claims, out) {
191
+ for (const note of notes) {
192
+ const claimed = claims.byNote.get(note.entity.id);
193
+ if (claimed !== undefined && claimed.length > 1) {
194
+ out.ids.add(note.entity.id);
195
+ for (const operation of claimed)
196
+ out.ids.add(operation.entity.id);
197
+ out.ambiguities.push({ kind: "note", rung, note: note.entity, operations: claimed });
198
+ }
199
+ }
200
+ }
201
+ /** An operation claimed by several notes is an ambiguity that settles the operation and every claimant. */
202
+ function contestedOperations(rung, operations, claims, out) {
203
+ for (const operation of operations) {
204
+ const claimants = claims.byOperation.get(operation.entity.id);
205
+ if (claimants !== undefined && claimants.length > 1) {
206
+ out.ids.add(operation.entity.id);
207
+ for (const note of claimants)
208
+ out.ids.add(note.id);
209
+ out.ambiguities.push({ kind: "operation", rung, operation, notes: claimants });
210
+ }
211
+ }
212
+ }
213
+ /**
214
+ * A note left unsettled claims exactly one operation, which nobody else claims: the ambiguities
215
+ * settled every note of a contested operation and every operation of a hesitant note.
216
+ */
217
+ function oneToOne(rung, notes, claims, out) {
218
+ for (const note of notes) {
219
+ const [operation] = claims.byNote.get(note.entity.id) ?? [];
220
+ if (operation === undefined || out.ids.has(note.entity.id))
221
+ continue;
222
+ out.ids.add(note.entity.id);
223
+ out.ids.add(operation.entity.id);
224
+ out.matches.push({ note: note.entity, operation, rung });
225
+ }
226
+ }
227
+ /**
228
+ * Matches the notes to the operations rung by rung: the operation identifier, then the method and
229
+ * path (or the port and the operation name for SOAP), then the title in comparison form. At each
230
+ * rung a note claims the operations of its candidate APIs whose key equals one of its own; a note
231
+ * claiming several operations, or an operation claimed by several notes, is an ambiguity that
232
+ * attaches nothing and takes its entities out of the later rungs. The rest attach one to one and
233
+ * leave the later rungs to the notes and operations still free.
234
+ */
235
+ export function matchOperations(notes, operations, normalize) {
236
+ const matches = [];
237
+ const ambiguities = [];
238
+ let freeNotes = [...notes];
239
+ let freeOperations = [...operations];
240
+ for (const rung of MATCH_RUNGS) {
241
+ const claims = claimsAt(rung, freeNotes, freeOperations, normalize);
242
+ const settled = { ids: new Set(), matches, ambiguities };
243
+ hesitantNotes(rung, freeNotes, claims, settled);
244
+ contestedOperations(rung, freeOperations, claims, settled);
245
+ oneToOne(rung, freeNotes, claims, settled);
246
+ freeNotes = freeNotes.filter((note) => !settled.ids.has(note.entity.id));
247
+ freeOperations = freeOperations.filter((operation) => !settled.ids.has(operation.entity.id));
248
+ }
249
+ return { matches, ambiguities };
250
+ }
251
+ //# sourceMappingURL=match.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"match.js","sourceRoot":"","sources":["../../src/operations/match.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { Entity, Link } from "@concordance-wiki/core";
2
+ import type { ImportedOperation, MatchRung } from "./match.js";
3
+ /** The `kind` of the representation an imported operation becomes. */
4
+ export declare const CONTRACT_REPRESENTATION = "contract";
5
+ /**
6
+ * The note absorbs the operation: it keeps its identifier, its file, its title and its frontmatter,
7
+ * takes the contract attributes it does not set itself, the operation's aliases and its summary
8
+ * when it has none, and lists the contract as a representation next to its own file, the way twin
9
+ * resources are listed; `grouped_by` names the rung, after any criterion the note already carried.
10
+ */
11
+ export declare function mergeOperation(note: Entity, operation: ImportedOperation, rung: MatchRung): Entity;
12
+ /** Every link that named the imported operation now names the note, the `exposes` link of the API first of all. */
13
+ export declare function redirectLinks(links: readonly Link[], redirections: ReadonlyMap<string, string>): Link[];
14
+ //# sourceMappingURL=merge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/operations/merge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAwB,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAEjF,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE/D,sEAAsE;AACtE,eAAO,MAAM,uBAAuB,aAAa,CAAC;AAqBlD;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,iBAAiB,EAC5B,IAAI,EAAE,SAAS,GACd,MAAM,CAwBR;AAED,mHAAmH;AACnH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,SAAS,IAAI,EAAE,EACtB,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GACxC,IAAI,EAAE,CAMR"}
@@ -0,0 +1,60 @@
1
+ /** The `kind` of the representation an imported operation becomes. */
2
+ export const CONTRACT_REPRESENTATION = "contract";
3
+ function representationFormat(path) {
4
+ const name = path.slice(path.lastIndexOf("/") + 1);
5
+ const dot = name.lastIndexOf(".");
6
+ if (dot === -1)
7
+ return "file";
8
+ const extension = name.slice(dot + 1).toLowerCase();
9
+ return extension === "md" ? "markdown" : extension;
10
+ }
11
+ // Code-unit order, not locale order: the output must not depend on the collation data of the runtime.
12
+ function byCodeUnit(a, b) {
13
+ return Number(a > b) - Number(a < b);
14
+ }
15
+ function sortedAttributes(attributes) {
16
+ const sorted = {};
17
+ for (const key of Object.keys(attributes).sort(byCodeUnit))
18
+ sorted[key] = attributes[key];
19
+ return sorted;
20
+ }
21
+ /**
22
+ * The note absorbs the operation: it keeps its identifier, its file, its title and its frontmatter,
23
+ * takes the contract attributes it does not set itself, the operation's aliases and its summary
24
+ * when it has none, and lists the contract as a representation next to its own file, the way twin
25
+ * resources are listed; `grouped_by` names the rung, after any criterion the note already carried.
26
+ */
27
+ export function mergeOperation(note, operation, rung) {
28
+ const imported = operation.entity;
29
+ const summary = note.summary ?? imported.summary;
30
+ const aliases = [
31
+ ...note.aliases,
32
+ ...imported.aliases.filter((alias) => !note.aliases.includes(alias)),
33
+ ];
34
+ const own = note.representations ?? [
35
+ { path: note.source.path, format: representationFormat(note.source.path) },
36
+ ];
37
+ const contract = {
38
+ path: operation.location,
39
+ format: representationFormat(operation.location),
40
+ kind: CONTRACT_REPRESENTATION,
41
+ operation: operation.name,
42
+ };
43
+ return {
44
+ ...note,
45
+ aliases,
46
+ ...(summary === undefined ? {} : { summary }),
47
+ attributes: sortedAttributes({ ...imported.attributes, ...note.attributes }),
48
+ representations: [...own, contract],
49
+ grouped_by: note.grouped_by === undefined ? rung : `${note.grouped_by}, ${rung}`,
50
+ };
51
+ }
52
+ /** Every link that named the imported operation now names the note, the `exposes` link of the API first of all. */
53
+ export function redirectLinks(links, redirections) {
54
+ return links.map((link) => {
55
+ const from = redirections.get(link.from) ?? link.from;
56
+ const to = redirections.get(link.to) ?? link.to;
57
+ return from === link.from && to === link.to ? link : { ...link, from, to };
58
+ });
59
+ }
60
+ //# sourceMappingURL=merge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merge.js","sourceRoot":"","sources":["../../src/operations/merge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { relationLabel, type RelationLabelOptions } from "./labels.js";
2
+ export { FALLBACK_RELATION, RELATION_ORIGIN, typeRelations, type TypedEntity, type TypeRelationsInput, type TypeRelationsResult, } from "./type.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/relations/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACvE,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,mBAAmB,GACzB,MAAM,WAAW,CAAC"}