forked from microsoft/typespec
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvalidate.ts
63 lines (60 loc) · 1.94 KB
/
validate.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import type { Program } from "@typespec/compiler";
import { reportDiagnostic } from "./lib.js";
import { getAllHttpServices } from "./operations.js";
import { isSharedRoute } from "./route.js";
import { HttpOperation, HttpService } from "./types.js";
export function $onValidate(program: Program) {
// Pass along any diagnostics that might be returned from the HTTP library
const [services, diagnostics] = getAllHttpServices(program);
if (diagnostics.length > 0) {
program.reportDiagnostics(diagnostics);
}
validateSharedRouteConsistency(program, services);
}
function groupHttpOperations(
operations: HttpOperation[]
): Map<string, Map<string, HttpOperation[]>> {
const paths = new Map<string, Map<string, HttpOperation[]>>();
for (const operation of operations) {
const { verb, path } = operation;
let pathOps = paths.get(path);
if (pathOps === undefined) {
pathOps = new Map<string, HttpOperation[]>();
paths.set(path, pathOps);
}
const ops = pathOps.get(verb);
if (ops === undefined) {
pathOps.set(verb, [operation]);
} else {
ops.push(operation);
}
}
return paths;
}
function validateSharedRouteConsistency(program: Program, services: HttpService[]) {
for (const service of services) {
const paths = groupHttpOperations(service.operations);
for (const pathOps of paths.values()) {
for (const ops of pathOps.values()) {
let hasShared = false;
let hasNonShared = false;
for (const op of ops) {
if (isSharedRoute(program, op.operation)) {
hasShared = true;
} else {
hasNonShared = true;
}
}
if (hasShared && hasNonShared) {
for (const op of ops) {
reportDiagnostic(program, {
code: "shared-inconsistency",
target: op.operation,
format: { verb: op.verb, path: op.path },
});
}
}
}
}
}
}