|
1 | 1 | import * as fg from 'fast-glob'; |
2 | 2 | import * as path from 'path'; |
3 | 3 | import { Namespace, NamespaceBase, Root, Service } from 'protobufjs'; |
4 | | -import { SERVICE_ENDPOINTS_LIST } from '../src/service-endpoints'; |
| 4 | +import SERVICE_ENDPOINTS_MAP from '../src/service-endpoints-map.json'; |
5 | 5 |
|
6 | | -const PROTO_DIR = path.resolve('./cloudapi'); |
7 | | - |
8 | | -const protoFiles = fg.sync('**/*.proto', { cwd: PROTO_DIR }); |
9 | | - |
10 | | -const pbRoot = new Root(); |
11 | | - |
12 | | -pbRoot.resolvePath = (origin, target) => { |
13 | | - const targets = target.split('/'); |
14 | | - |
15 | | - switch (targets[0]) { |
16 | | - case 'google': { |
17 | | - switch (targets[1]) { |
18 | | - case 'protobuf': { |
19 | | - return `./node_modules/protobufjs/${target}`; |
20 | | - } |
21 | | - default: { |
22 | | - return `./cloudapi/third_party/googleapis/${target}`; |
23 | | - } |
24 | | - } |
25 | | - } |
26 | | - case 'third_party': { |
27 | | - return `./cloudapi/${target}`; |
28 | | - } |
29 | | - case 'yandex': { |
30 | | - return `./cloudapi/${target}`; |
31 | | - } |
32 | | - default: { |
33 | | - return target; |
34 | | - } |
35 | | - } |
36 | | -}; |
37 | | - |
38 | | -const SERVICES: Service[] = []; |
39 | | -const findServices = <T extends NamespaceBase>(node: T) => { |
| 6 | +const detectServices = <T extends NamespaceBase>( |
| 7 | + node: T, |
| 8 | + onService: (service: Service) => void, |
| 9 | +) => { |
40 | 10 | for (const child of Object.values(node.nested ?? {}).sort((a, b) => |
41 | 11 | a.name < b.name ? -1 : a.name === b.name ? 0 : 1, |
42 | 12 | )) { |
43 | 13 | if (child instanceof Service) { |
44 | | - SERVICES.push(child); |
| 14 | + onService(child); |
45 | 15 | } else if (child instanceof Namespace) { |
46 | | - findServices(child); |
| 16 | + detectServices(child, onService); |
47 | 17 | } |
48 | 18 | } |
49 | 19 | }; |
50 | 20 |
|
51 | | -pbRoot.load(protoFiles, { alternateCommentMode: true }).then((loadedRoot) => { |
52 | | - const SERVICE_IDS = new Set<string>(); |
53 | | - let hasMissing = false; |
| 21 | +const newProtobufjsRoot = () => { |
| 22 | + const pbRoot = new Root(); |
| 23 | + |
| 24 | + pbRoot.resolvePath = (_origin, target) => { |
| 25 | + const targets = target.split('/'); |
54 | 26 |
|
55 | | - for (const serviceEndpoint of SERVICE_ENDPOINTS_LIST) { |
56 | | - for (const service of serviceEndpoint.serviceIds) { |
57 | | - SERVICE_IDS.add(service); |
| 27 | + switch (targets[0]) { |
| 28 | + case 'google': { |
| 29 | + switch (targets[1]) { |
| 30 | + case 'protobuf': { |
| 31 | + return `./node_modules/protobufjs/${target}`; |
| 32 | + } |
| 33 | + default: { |
| 34 | + return `./cloudapi/third_party/googleapis/${target}`; |
| 35 | + } |
| 36 | + } |
| 37 | + } |
| 38 | + case 'third_party': { |
| 39 | + return `./cloudapi/${target}`; |
| 40 | + } |
| 41 | + case 'yandex': { |
| 42 | + return `./cloudapi/${target}`; |
| 43 | + } |
| 44 | + default: { |
| 45 | + return target; |
| 46 | + } |
58 | 47 | } |
59 | | - } |
| 48 | + }; |
| 49 | + |
| 50 | + return pbRoot; |
| 51 | +}; |
| 52 | + |
| 53 | +const main = () => { |
| 54 | + const PROTO_DIR = path.resolve('./cloudapi'); |
| 55 | + const protoFiles = fg.sync('**/*.proto', { cwd: PROTO_DIR }); |
| 56 | + |
| 57 | + const pbRoot = newProtobufjsRoot(); |
| 58 | + |
| 59 | + const SERVICES: Service[] = []; |
| 60 | + const findServices = <T extends NamespaceBase>(node: T) => { |
| 61 | + detectServices(node, (service) => SERVICES.push(service)); |
| 62 | + }; |
| 63 | + |
| 64 | + pbRoot.load(protoFiles, { alternateCommentMode: true }).then((loadedRoot) => { |
| 65 | + const SERVICE_IDS = new Set<string>(); |
| 66 | + let hasMissing = false; |
| 67 | + |
| 68 | + const map = SERVICE_ENDPOINTS_MAP as Record<string, string>; |
| 69 | + |
| 70 | + Object.keys(map).forEach((service) => SERVICE_IDS.add(service)); |
| 71 | + |
| 72 | + findServices(loadedRoot); |
| 73 | + console.log('Missing services:'); |
| 74 | + for (const s of SERVICES) { |
| 75 | + // full name without leading dot |
| 76 | + const fullName = s.fullName.slice(1); |
60 | 77 |
|
61 | | - findServices(loadedRoot); |
62 | | - console.log('Missing services:'); |
63 | | - for (const s of SERVICES) { |
64 | | - // full name without leading dot |
65 | | - const fullName = s.fullName.slice(1); |
| 78 | + if (!SERVICE_IDS.has(fullName)) { |
| 79 | + console.log(fullName); |
| 80 | + hasMissing = true; |
| 81 | + } |
| 82 | + } |
66 | 83 |
|
67 | | - if (!SERVICE_IDS.has(fullName)) { |
68 | | - console.log(fullName); |
69 | | - hasMissing = true; |
| 84 | + if (hasMissing) { |
| 85 | + process.exit(1); |
70 | 86 | } |
71 | | - } |
| 87 | + }); |
| 88 | +}; |
72 | 89 |
|
73 | | - if (hasMissing) { |
74 | | - process.exit(1); |
75 | | - } |
76 | | -}); |
| 90 | +if (require.main === module) { |
| 91 | + main(); |
| 92 | +} |
| 93 | + |
| 94 | +export const getServiceList = async () => { |
| 95 | + const PROTO_DIR = path.resolve('./cloudapi'); |
| 96 | + const protoFiles = fg.sync('**/*.proto', { cwd: PROTO_DIR }); |
| 97 | + |
| 98 | + const pbRoot = newProtobufjsRoot(); |
| 99 | + |
| 100 | + const serviceList: Service[] = []; |
| 101 | + |
| 102 | + return pbRoot.load(protoFiles, { alternateCommentMode: true }).then((loadedRoot) => { |
| 103 | + detectServices(loadedRoot, (service) => serviceList.push(service)); |
| 104 | + return serviceList; |
| 105 | + }); |
| 106 | +}; |
0 commit comments