1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | const tslib_1 = require("tslib");
|
4 | require("cross-fetch/polyfill");
|
5 | const debug_1 = tslib_1.__importDefault(require("debug"));
|
6 | const jsonSchema_1 = require("./jsonSchema");
|
7 | const schemaId_1 = tslib_1.__importDefault(require("./schemaId"));
|
8 | const type_1 = require("./type");
|
9 | const debug = (0, debug_1.default)('dtsgen');
|
10 | class ReferenceResolver {
|
11 | constructor() {
|
12 | this.schemaCache = new Map();
|
13 | this.referenceCache = new Map();
|
14 | }
|
15 | dereference(refId) {
|
16 | const result = this.referenceCache.get(refId);
|
17 | if (result == null) {
|
18 | throw new Error('Target reference is not found: ' + refId);
|
19 | }
|
20 | return result;
|
21 | }
|
22 | getAllRegisteredSchema() {
|
23 | return this.schemaCache.values();
|
24 | }
|
25 | getAllRegisteredIdAndSchema() {
|
26 | return this.schemaCache.entries();
|
27 | }
|
28 | async resolve() {
|
29 | debug(`resolve reference: reference schema count=${this.referenceCache.size}.`);
|
30 | const error = [];
|
31 | for (const [key, schema] of this.referenceCache.entries()) {
|
32 | if (schema != null) {
|
33 | continue;
|
34 | }
|
35 | const id = new schemaId_1.default(key);
|
36 | const fileId = id.getFileId();
|
37 | let result = this.schemaCache.get(id.getAbsoluteId());
|
38 | if (result == null) {
|
39 | const refSchema = this.schemaCache.get(fileId);
|
40 | debug(`get from schema cache, fileId=${fileId}, exists=${String(!!refSchema)}, ${id.getAbsoluteId()}`);
|
41 | if (refSchema == null && id.isFetchable()) {
|
42 | try {
|
43 | debug(`fetch remote schema: id=[${fileId}].`);
|
44 | const s = await (0, type_1.readSchemaFromUrl)(fileId);
|
45 | this.registerSchema(s);
|
46 | }
|
47 | catch (e) {
|
48 | error.push(`Fail to fetch the $ref target: ${id.getAbsoluteId()}, ${String(e)}`);
|
49 | continue;
|
50 | }
|
51 | }
|
52 | result = this.schemaCache.get(id.getAbsoluteId());
|
53 | }
|
54 | debug(`resolve reference: ref=[${id.getAbsoluteId()}]`);
|
55 | if (result != null) {
|
56 | this.referenceCache.set(id.getAbsoluteId(), result);
|
57 | }
|
58 | else {
|
59 | if (id.existsJsonPointerHash()) {
|
60 | const rootSchema = this.searchParentSchema(id);
|
61 | if (rootSchema == null) {
|
62 | error.push(`The $ref targets root is not found: ${id.getAbsoluteId()}`);
|
63 | continue;
|
64 | }
|
65 | const targetSchema = (0, jsonSchema_1.getSubSchema)(rootSchema, id.getJsonPointerHash(), id);
|
66 | this.addSchema(targetSchema);
|
67 | this.registerSchema(targetSchema);
|
68 | this.referenceCache.set(id.getAbsoluteId(), targetSchema);
|
69 | }
|
70 | else {
|
71 | error.push(`The $ref target is not found: ${id.getAbsoluteId()}`);
|
72 | continue;
|
73 | }
|
74 | }
|
75 | }
|
76 | if (error.length > 0) {
|
77 | throw new Error(error.join('\n'));
|
78 | }
|
79 | }
|
80 | searchParentSchema(id) {
|
81 | const fileId = id.getFileId();
|
82 | const rootSchema = this.schemaCache.get(fileId);
|
83 | if (rootSchema != null) {
|
84 | return rootSchema;
|
85 | }
|
86 | const key = id.getAbsoluteId();
|
87 | for (const k of this.schemaCache.keys()) {
|
88 | if (key.startsWith(k)) {
|
89 | const s = this.schemaCache.get(k);
|
90 | if (s === null || s === void 0 ? void 0 : s.rootSchema) {
|
91 | return s.rootSchema;
|
92 | }
|
93 | }
|
94 | }
|
95 | return;
|
96 | }
|
97 | registerSchema(schema) {
|
98 | debug(`register schema: schemaId=[${schema.id.getAbsoluteId()}].`);
|
99 | (0, jsonSchema_1.searchAllSubSchema)(schema, (subSchema) => {
|
100 | this.addSchema(subSchema);
|
101 | }, (refId) => {
|
102 | this.addReference(refId);
|
103 | });
|
104 | }
|
105 | addSchema(schema) {
|
106 | const id = schema.id;
|
107 | const key = id.getAbsoluteId();
|
108 | if (!this.schemaCache.has(key)) {
|
109 | debug(` add schema: id=${key}`);
|
110 | this.schemaCache.set(key, schema);
|
111 | if (schema.rootSchema == null) {
|
112 | const fileId = id.getFileId();
|
113 | if (!this.schemaCache.has(fileId)) {
|
114 | this.schemaCache.set(fileId, schema);
|
115 | }
|
116 | }
|
117 | }
|
118 | }
|
119 | addReference(refId) {
|
120 | if (!this.referenceCache.has(refId.getAbsoluteId())) {
|
121 | debug(` add reference: id=${refId.getAbsoluteId()}`);
|
122 | this.referenceCache.set(refId.getAbsoluteId(), undefined);
|
123 | }
|
124 | }
|
125 | clear() {
|
126 | debug('clear resolver cache.');
|
127 | this.schemaCache.clear();
|
128 | this.referenceCache.clear();
|
129 | }
|
130 | }
|
131 | exports.default = ReferenceResolver;
|