@databehave/openapi 0.0.0-stage → 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.
- package/CHANGELOG.md +18 -0
- package/LICENSE +21 -0
- package/README.md +93 -2
- package/dist/catalog.d.ts +51 -0
- package/dist/catalog.d.ts.map +1 -0
- package/dist/catalog.js +90 -0
- package/dist/catalog.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/request-validation.d.ts +65 -0
- package/dist/middleware/request-validation.d.ts.map +1 -0
- package/dist/middleware/request-validation.js +353 -0
- package/dist/middleware/request-validation.js.map +1 -0
- package/dist/mock-mode-plugin.d.ts +5 -0
- package/dist/mock-mode-plugin.d.ts.map +1 -0
- package/dist/mock-mode-plugin.js +20 -0
- package/dist/mock-mode-plugin.js.map +1 -0
- package/dist/mock-mode.d.ts +76 -0
- package/dist/mock-mode.d.ts.map +1 -0
- package/dist/mock-mode.js +93 -0
- package/dist/mock-mode.js.map +1 -0
- package/dist/openapi/auto-schema.d.ts +3 -0
- package/dist/openapi/auto-schema.d.ts.map +1 -0
- package/dist/openapi/auto-schema.js +10 -0
- package/dist/openapi/auto-schema.js.map +1 -0
- package/dist/openapi/generate.d.ts +8 -0
- package/dist/openapi/generate.d.ts.map +1 -0
- package/dist/openapi/generate.js +121 -0
- package/dist/openapi/generate.js.map +1 -0
- package/dist/openapi/loader.d.ts +18 -0
- package/dist/openapi/loader.d.ts.map +1 -0
- package/dist/openapi/loader.js +32 -0
- package/dist/openapi/loader.js.map +1 -0
- package/dist/openapi/seed.d.ts +17 -0
- package/dist/openapi/seed.d.ts.map +1 -0
- package/dist/openapi/seed.js +58 -0
- package/dist/openapi/seed.js.map +1 -0
- package/dist/openapi/translate.d.ts +14 -0
- package/dist/openapi/translate.d.ts.map +1 -0
- package/dist/openapi/translate.js +312 -0
- package/dist/openapi/translate.js.map +1 -0
- package/dist/openapi/walker.d.ts +37 -0
- package/dist/openapi/walker.d.ts.map +1 -0
- package/dist/openapi/walker.js +2 -0
- package/dist/openapi/walker.js.map +1 -0
- package/dist/placeholder.d.ts +7 -0
- package/dist/placeholder.d.ts.map +1 -0
- package/dist/placeholder.js +17 -0
- package/dist/placeholder.js.map +1 -0
- package/dist/plugin.d.ts +10 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +43 -0
- package/dist/plugin.js.map +1 -0
- package/dist/request-validation-plugin.d.ts +8 -0
- package/dist/request-validation-plugin.d.ts.map +1 -0
- package/dist/request-validation-plugin.js +24 -0
- package/dist/request-validation-plugin.js.map +1 -0
- package/dist/schema.d.ts +18 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +26 -0
- package/dist/schema.js.map +1 -0
- package/dist/validation/validate.d.ts +40 -0
- package/dist/validation/validate.d.ts.map +1 -0
- package/dist/validation/validate.js +378 -0
- package/dist/validation/validate.js.map +1 -0
- package/package.json +55 -3
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
const FORMAT_STRINGS = {
|
|
2
|
+
date: '2024-01-01',
|
|
3
|
+
'date-time': '2024-01-01T00:00:00Z',
|
|
4
|
+
email: 'user@example.com',
|
|
5
|
+
uuid: '00000000-0000-4000-8000-000000000000',
|
|
6
|
+
uri: 'https://example.com/',
|
|
7
|
+
};
|
|
8
|
+
const KNOWN_TYPES = new Set([
|
|
9
|
+
'string',
|
|
10
|
+
'integer',
|
|
11
|
+
'number',
|
|
12
|
+
'boolean',
|
|
13
|
+
'array',
|
|
14
|
+
'object',
|
|
15
|
+
'null',
|
|
16
|
+
]);
|
|
17
|
+
const isPlainObject = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
18
|
+
const resolveRef = (doc, ref) => {
|
|
19
|
+
if (!ref.startsWith('#/')) {
|
|
20
|
+
throw new Error(`@databehave/openapi: remote $ref not supported by OAS-only generator: ${ref}`);
|
|
21
|
+
}
|
|
22
|
+
const m = /^#\/components\/schemas\/(.+)$/.exec(ref);
|
|
23
|
+
if (!m) {
|
|
24
|
+
throw new Error(`@databehave/openapi: unsupported $ref: ${ref}`);
|
|
25
|
+
}
|
|
26
|
+
const name = decodeURIComponent(m[1]);
|
|
27
|
+
const target = doc.components?.schemas?.[name];
|
|
28
|
+
if (!target) {
|
|
29
|
+
throw new Error(`@databehave/openapi: $ref not found: ${ref}`);
|
|
30
|
+
}
|
|
31
|
+
return target;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Pick the concrete (non-`null`) type when OAS 3.1 declares
|
|
35
|
+
* `["string","null"]`. OAS 3.0 `nullable: true` is treated the same
|
|
36
|
+
* way: the generator never emits `null` from a nullable widening —
|
|
37
|
+
* callers that want explicit `null` use `examples` or `enum`.
|
|
38
|
+
*/
|
|
39
|
+
const pickType = (node) => {
|
|
40
|
+
if (Array.isArray(node.type)) {
|
|
41
|
+
return node.type.find((t) => t !== 'null');
|
|
42
|
+
}
|
|
43
|
+
return node.type;
|
|
44
|
+
};
|
|
45
|
+
export const generateFromOasSchema = (node, doc = {},
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
47
|
+
_opts = {}, seen = new Set()) => {
|
|
48
|
+
const ex = node.example;
|
|
49
|
+
if (ex !== undefined)
|
|
50
|
+
return ex;
|
|
51
|
+
const examples = node.examples;
|
|
52
|
+
if (Array.isArray(examples) && examples.length > 0)
|
|
53
|
+
return examples[0];
|
|
54
|
+
if (Array.isArray(node.enum) && node.enum.length > 0)
|
|
55
|
+
return node.enum[0];
|
|
56
|
+
if (node.const !== undefined)
|
|
57
|
+
return node.const;
|
|
58
|
+
if (node.$ref) {
|
|
59
|
+
if (seen.has(node.$ref))
|
|
60
|
+
return {};
|
|
61
|
+
const next = new Set(seen);
|
|
62
|
+
next.add(node.$ref);
|
|
63
|
+
return generateFromOasSchema(resolveRef(doc, node.$ref), doc, _opts, next);
|
|
64
|
+
}
|
|
65
|
+
if (Array.isArray(node.allOf) && node.allOf.length > 0) {
|
|
66
|
+
let merged = {};
|
|
67
|
+
for (const branch of node.allOf) {
|
|
68
|
+
const v = generateFromOasSchema(branch, doc, _opts, seen);
|
|
69
|
+
if (isPlainObject(v))
|
|
70
|
+
merged = { ...merged, ...v };
|
|
71
|
+
else
|
|
72
|
+
return v;
|
|
73
|
+
}
|
|
74
|
+
return merged;
|
|
75
|
+
}
|
|
76
|
+
if (Array.isArray(node.oneOf) && node.oneOf.length > 0) {
|
|
77
|
+
return generateFromOasSchema(node.oneOf[0], doc, _opts, seen);
|
|
78
|
+
}
|
|
79
|
+
if (Array.isArray(node.anyOf) && node.anyOf.length > 0) {
|
|
80
|
+
return generateFromOasSchema(node.anyOf[0], doc, _opts, seen);
|
|
81
|
+
}
|
|
82
|
+
let t = pickType(node);
|
|
83
|
+
if (!t && node.properties)
|
|
84
|
+
t = 'object';
|
|
85
|
+
if (!t && node.items !== undefined)
|
|
86
|
+
t = 'array';
|
|
87
|
+
if (!t)
|
|
88
|
+
return {};
|
|
89
|
+
if (typeof t === 'string' && !KNOWN_TYPES.has(t)) {
|
|
90
|
+
throw new Error(`@databehave/openapi: unsupported OpenAPI node: ${JSON.stringify(node)}`);
|
|
91
|
+
}
|
|
92
|
+
if (t === 'null')
|
|
93
|
+
return null;
|
|
94
|
+
if (t === 'string') {
|
|
95
|
+
if (node.format && FORMAT_STRINGS[node.format]) {
|
|
96
|
+
return FORMAT_STRINGS[node.format];
|
|
97
|
+
}
|
|
98
|
+
return 'string';
|
|
99
|
+
}
|
|
100
|
+
if (t === 'integer' || t === 'number') {
|
|
101
|
+
return typeof node.minimum === 'number' ? node.minimum : 0;
|
|
102
|
+
}
|
|
103
|
+
if (t === 'boolean')
|
|
104
|
+
return false;
|
|
105
|
+
if (t === 'array') {
|
|
106
|
+
const itemNode = node.items ?? {};
|
|
107
|
+
const count = typeof node.minItems === 'number' && node.minItems > 0 ? node.minItems : 1;
|
|
108
|
+
const out = [];
|
|
109
|
+
for (let i = 0; i < count; i += 1) {
|
|
110
|
+
out.push(generateFromOasSchema(itemNode, doc, _opts, seen));
|
|
111
|
+
}
|
|
112
|
+
return out;
|
|
113
|
+
}
|
|
114
|
+
// object
|
|
115
|
+
const out = {};
|
|
116
|
+
for (const [k, v] of Object.entries(node.properties ?? {})) {
|
|
117
|
+
out[k] = generateFromOasSchema(v, doc, _opts, seen);
|
|
118
|
+
}
|
|
119
|
+
return out;
|
|
120
|
+
};
|
|
121
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/openapi/generate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse a JSON OpenAPI document.
|
|
3
|
+
*
|
|
4
|
+
* Consumers hand `@databehave/openapi` the raw text — how they obtained it
|
|
5
|
+
* (`fs.readFile`, `fetch`, bundler `?raw` import) is up to them.
|
|
6
|
+
*
|
|
7
|
+
* `@databehave/openapi` is JSON-only. Convert YAML up-front
|
|
8
|
+
* (`yq -o=json spec.yaml > spec.json`) and pass the JSON bytes through.
|
|
9
|
+
*/
|
|
10
|
+
import type { OasDoc } from './walker.js';
|
|
11
|
+
/**
|
|
12
|
+
* Parse a JSON OpenAPI document.
|
|
13
|
+
*
|
|
14
|
+
* `sourcePath` is optional metadata used only to enrich error messages
|
|
15
|
+
* and to refuse YAML inputs by extension with an actionable hint.
|
|
16
|
+
*/
|
|
17
|
+
export declare const parseOpenApi: (text: string, sourcePath?: string) => OasDoc;
|
|
18
|
+
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/openapi/loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC;;;;;GAKG;AACH,eAAO,MAAM,YAAY,GAAI,MAAM,MAAM,EAAE,aAAa,MAAM,KAAG,MA2BhE,CAAA"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse a JSON OpenAPI document.
|
|
3
|
+
*
|
|
4
|
+
* `sourcePath` is optional metadata used only to enrich error messages
|
|
5
|
+
* and to refuse YAML inputs by extension with an actionable hint.
|
|
6
|
+
*/
|
|
7
|
+
export const parseOpenApi = (text, sourcePath) => {
|
|
8
|
+
// Strip a leading UTF-8 BOM (U+FEFF) if present — common when the
|
|
9
|
+
// OAS document was authored in Windows tooling or saved as
|
|
10
|
+
// "UTF-8 with BOM". Without this, the very first `JSON.parse`
|
|
11
|
+
// throws "Unexpected token" with no actionable hint.
|
|
12
|
+
const stripped = text.charCodeAt(0) === 0xfeff ? text.slice(1) : text;
|
|
13
|
+
if (sourcePath !== undefined && /\.ya?ml$/i.test(sourcePath)) {
|
|
14
|
+
throw new Error('JSON-only spec loader. Convert YAML first: yq -o=json <file>.yaml > <file>.json');
|
|
15
|
+
}
|
|
16
|
+
const where = sourcePath !== undefined ? ` at ${sourcePath}` : '';
|
|
17
|
+
try {
|
|
18
|
+
const parsed = JSON.parse(stripped);
|
|
19
|
+
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
|
|
20
|
+
throw new Error('document must be an object');
|
|
21
|
+
}
|
|
22
|
+
if ('paths' in parsed && (typeof parsed.paths !== 'object' || parsed.paths === null || Array.isArray(parsed.paths))) {
|
|
23
|
+
throw new Error('paths must be an object');
|
|
24
|
+
}
|
|
25
|
+
return parsed;
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
29
|
+
throw new Error(`@databehave/openapi/openapi: failed to parse JSON OpenAPI document${where}: ${msg}`);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/openapi/loader.ts"],"names":[],"mappings":"AAWA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAAY,EAAE,UAAmB,EAAU,EAAE;IACxE,kEAAkE;IAClE,2DAA2D;IAC3D,8DAA8D;IAC9D,qDAAqD;IACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IACrE,IAAI,UAAU,KAAK,SAAS,IAAI,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC7D,MAAM,IAAI,KAAK,CACb,iFAAiF,CAClF,CAAA;IACH,CAAC;IACD,MAAM,KAAK,GAAG,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;IACjE,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAA;QAC5C,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC3E,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAA;QAC/C,CAAC;QACD,IAAI,OAAO,IAAI,MAAM,IAAI,CAAC,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YACpH,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAA;QAC5C,CAAC;QACD,OAAO,MAAgB,CAAA;IACzB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAC5D,MAAM,IAAI,KAAK,CACb,qEAAqE,KAAK,KAAK,GAAG,EAAE,CACrF,CAAA;IACH,CAAC;AACH,CAAC,CAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helper for building deterministic databehave seed strings.
|
|
3
|
+
*
|
|
4
|
+
* Seed format: `<endpoint>|<sortedKey>=<val>|...|date=<YYYY-MM-DD>|day=<n>`.
|
|
5
|
+
* Same input → same string → databehave yields byte-identical JSON. Re-exported
|
|
6
|
+
* from `@databehave/openapi` so consumers can derive their own seeds without
|
|
7
|
+
* reimplementing the format.
|
|
8
|
+
*/
|
|
9
|
+
/** Components used to derive a stable seed string. */
|
|
10
|
+
export type SeedInput = {
|
|
11
|
+
endpoint: string;
|
|
12
|
+
from?: string;
|
|
13
|
+
dayOffset?: number;
|
|
14
|
+
extra?: Record<string, unknown>;
|
|
15
|
+
};
|
|
16
|
+
export declare const seedFor: (i: SeedInput) => string;
|
|
17
|
+
//# sourceMappingURL=seed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../../src/openapi/seed.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,sDAAsD;AACtD,MAAM,MAAM,SAAS,GAAG;IACtB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAChC,CAAA;AAmCD,eAAO,MAAM,OAAO,GAAI,GAAG,SAAS,KAAG,MAWtC,CAAA"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure helper for building deterministic databehave seed strings.
|
|
3
|
+
*
|
|
4
|
+
* Seed format: `<endpoint>|<sortedKey>=<val>|...|date=<YYYY-MM-DD>|day=<n>`.
|
|
5
|
+
* Same input → same string → databehave yields byte-identical JSON. Re-exported
|
|
6
|
+
* from `@databehave/openapi` so consumers can derive their own seeds without
|
|
7
|
+
* reimplementing the format.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Recursively rebuild `v` with object keys sorted so two structurally
|
|
11
|
+
* identical objects with different insertion orders serialise to the
|
|
12
|
+
* same string. Arrays preserve order (semantic), plain objects are
|
|
13
|
+
* key-sorted, primitives are returned as-is.
|
|
14
|
+
*/
|
|
15
|
+
const sortKeys = (v) => {
|
|
16
|
+
if (v === null || typeof v !== 'object')
|
|
17
|
+
return v;
|
|
18
|
+
if (Array.isArray(v))
|
|
19
|
+
return v.map(sortKeys);
|
|
20
|
+
const out = {};
|
|
21
|
+
for (const k of Object.keys(v).sort()) {
|
|
22
|
+
out[k] = sortKeys(v[k]);
|
|
23
|
+
}
|
|
24
|
+
return out;
|
|
25
|
+
};
|
|
26
|
+
const stringifyExtra = (v) => {
|
|
27
|
+
if (v === null || v === undefined)
|
|
28
|
+
return String(v);
|
|
29
|
+
const t = typeof v;
|
|
30
|
+
if (t === 'string' || t === 'number' || t === 'boolean' || t === 'bigint') {
|
|
31
|
+
return String(v);
|
|
32
|
+
}
|
|
33
|
+
// Objects / arrays — use JSON so distinct shapes produce distinct
|
|
34
|
+
// seeds. Keys are sorted recursively so insertion-order doesn't
|
|
35
|
+
// perturb the seed. Falls back to `String()` if stringify fails
|
|
36
|
+
// (cycles).
|
|
37
|
+
try {
|
|
38
|
+
return JSON.stringify(sortKeys(v));
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return String(v);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
export const seedFor = (i) => {
|
|
45
|
+
const parts = [i.endpoint];
|
|
46
|
+
if (i.extra) {
|
|
47
|
+
const keys = Object.keys(i.extra).sort();
|
|
48
|
+
if (keys.length > 0) {
|
|
49
|
+
parts.push(keys.map((k) => `${k}=${stringifyExtra(i.extra[k])}`).join('|'));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (i.from !== undefined)
|
|
53
|
+
parts.push(`date=${i.from}`);
|
|
54
|
+
if (i.dayOffset !== undefined)
|
|
55
|
+
parts.push(`day=${i.dayOffset}`);
|
|
56
|
+
return parts.join('|');
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=seed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seed.js","sourceRoot":"","sources":["../../src/openapi/seed.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAUH;;;;;GAKG;AACH,MAAM,QAAQ,GAAG,CAAC,CAAU,EAAW,EAAE;IACvC,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAA;IACjD,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IAC5C,MAAM,GAAG,GAA4B,EAAE,CAAA;IACvC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAA4B,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QACjE,GAAG,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAE,CAA6B,CAAC,CAAC,CAAC,CAAC,CAAA;IACtD,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA;AAED,MAAM,cAAc,GAAG,CAAC,CAAU,EAAU,EAAE;IAC5C,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,MAAM,CAAC,CAAC,CAAC,CAAA;IACnD,MAAM,CAAC,GAAG,OAAO,CAAC,CAAA;IAClB,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC1E,OAAO,MAAM,CAAC,CAAC,CAAC,CAAA;IAClB,CAAC;IACD,kEAAkE;IAClE,gEAAgE;IAChE,gEAAgE;IAChE,YAAY;IACZ,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,MAAM,CAAC,CAAC,CAAC,CAAA;IAClB,CAAC;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,CAAY,EAAU,EAAE;IAC9C,MAAM,KAAK,GAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAA;IACpC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAA;QACxC,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,KAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;QAC9E,CAAC;IACH,CAAC;IACD,IAAI,CAAC,CAAC,IAAI,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;IACtD,IAAI,CAAC,CAAC,SAAS,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAA;IAC/D,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACxB,CAAC,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** OpenAPI schemas translated through an explicitly supplied schema builder API. */
|
|
2
|
+
import type { Schema } from '@databehave/schema';
|
|
3
|
+
import type { OasDoc as OasDocument, OasNode as OasSchemaNode } from './walker.js';
|
|
4
|
+
/** Builders are metadata carriers; generation uses the caller's separate runtime instance. */
|
|
5
|
+
export type SchemaBuilderApi = Pick<typeof import('@databehave/schema'), 'literal' | 'tuple' | 'obj' | 'arr' | 'enum_' | 'union' | 'bool' | 'null_' | 'StringSchema' | 'NumberSchema' | 'ObjectSchema' | 'discriminated'>;
|
|
6
|
+
/**
|
|
7
|
+
* Translate an OpenAPI schema node into a `@databehave/schema` IR
|
|
8
|
+
* Schema instance. Throws at translate time on unsupported keywords,
|
|
9
|
+
* malformed `$ref`s, `$ref` cycles, ReDoS-vulnerable patterns, and
|
|
10
|
+
* schemas that exceed the depth cap. See the file header for the
|
|
11
|
+
* full keyword matrix and security guarantees.
|
|
12
|
+
*/
|
|
13
|
+
export declare function translateOasToIR(node: OasSchemaNode, doc: OasDocument, m: SchemaBuilderApi): Promise<Schema<unknown>>;
|
|
14
|
+
//# sourceMappingURL=translate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translate.d.ts","sourceRoot":"","sources":["../../src/openapi/translate.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,OAAO,KAAK,EAAE,MAAM,EAAgB,MAAM,oBAAoB,CAAA;AAC9D,OAAO,KAAK,EAAE,MAAM,IAAI,WAAW,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,aAAa,CAAA;AAElF,8FAA8F;AAC9F,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,cAAc,oBAAoB,CAAC,EACrE,SAAS,GAAG,OAAO,GAAG,KAAK,GAAG,KAAK,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,GAC1E,cAAc,GAAG,cAAc,GAAG,cAAc,GAAG,eAAe,CAAC,CAAA;AA8UrE;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,aAAa,EACnB,GAAG,EAAE,WAAW,EAChB,CAAC,EAAE,gBAAgB,GAClB,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAE1B"}
|
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
const DEPTH_CAP = 64;
|
|
2
|
+
const PATTERN_MAX_LENGTH = 1024;
|
|
3
|
+
const UNSUPPORTED_KEYWORDS = new Set([
|
|
4
|
+
'if', 'then', 'else',
|
|
5
|
+
'dependentSchemas', 'dependentRequired',
|
|
6
|
+
'unevaluatedProperties', 'unevaluatedItems',
|
|
7
|
+
'contentEncoding', 'contentMediaType',
|
|
8
|
+
'propertyNames', 'patternProperties',
|
|
9
|
+
]);
|
|
10
|
+
const FORMAT_MAP = {
|
|
11
|
+
date: 'date',
|
|
12
|
+
'date-time': 'datetime',
|
|
13
|
+
email: 'email',
|
|
14
|
+
uuid: 'uuid',
|
|
15
|
+
uri: 'url',
|
|
16
|
+
};
|
|
17
|
+
const isObj = (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
18
|
+
const buildErr = (pointer, message) => new Error(`@databehave/openapi: ${message} (at ${pointer})`);
|
|
19
|
+
const resolveRef = (ref, doc, pointer) => {
|
|
20
|
+
if (ref.includes('://'))
|
|
21
|
+
throw buildErr(pointer, `unsupported $ref: ${ref}`);
|
|
22
|
+
const m = /^#\/components\/schemas\/(.+)$/.exec(ref);
|
|
23
|
+
if (!m)
|
|
24
|
+
throw buildErr(pointer, `unsupported $ref: ${ref}`);
|
|
25
|
+
const name = decodeURIComponent(m[1]);
|
|
26
|
+
const target = doc.components?.schemas?.[name];
|
|
27
|
+
if (!target)
|
|
28
|
+
throw buildErr(pointer, `$ref not found: ${ref}`);
|
|
29
|
+
return target;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Build a databehave Schema from an arbitrary JSON value, used when
|
|
33
|
+
* an OAS node carries a literal `example` / `examples[0]` / `const`
|
|
34
|
+
* payload. Recursively maps objects → `obj({...})` and arrays →
|
|
35
|
+
* `tuple(...)` so the entire value is preserved in the IR.
|
|
36
|
+
*/
|
|
37
|
+
const literalize = (value, m, pointer, depth) => {
|
|
38
|
+
if (depth > DEPTH_CAP) {
|
|
39
|
+
throw buildErr(pointer, `schema nesting exceeds depth cap of ${DEPTH_CAP}`);
|
|
40
|
+
}
|
|
41
|
+
if (value === null ||
|
|
42
|
+
typeof value === 'string' ||
|
|
43
|
+
typeof value === 'number' ||
|
|
44
|
+
typeof value === 'boolean') {
|
|
45
|
+
return m.literal(value);
|
|
46
|
+
}
|
|
47
|
+
if (Array.isArray(value)) {
|
|
48
|
+
if (value.length === 0)
|
|
49
|
+
return m.tuple();
|
|
50
|
+
return m.tuple(...value.map((v) => literalize(v, m, pointer, depth + 1)));
|
|
51
|
+
}
|
|
52
|
+
if (isObj(value)) {
|
|
53
|
+
const fields = {};
|
|
54
|
+
for (const [k, v] of Object.entries(value)) {
|
|
55
|
+
fields[k] = literalize(v, m, pointer, depth + 1);
|
|
56
|
+
}
|
|
57
|
+
return m.obj(fields);
|
|
58
|
+
}
|
|
59
|
+
throw buildErr(pointer, `cannot literalize value of type ${typeof value}`);
|
|
60
|
+
};
|
|
61
|
+
const enterPtr = (ctx, segment) => ({
|
|
62
|
+
...ctx,
|
|
63
|
+
pointer: `${ctx.pointer}/${segment}`,
|
|
64
|
+
depth: ctx.depth + 1,
|
|
65
|
+
});
|
|
66
|
+
const pickType = (node) => {
|
|
67
|
+
if (Array.isArray(node.type))
|
|
68
|
+
return node.type.find((t) => t !== 'null');
|
|
69
|
+
return node.type;
|
|
70
|
+
};
|
|
71
|
+
const isNullable = (node) => node.nullable === true || (Array.isArray(node.type) && node.type.includes('null'));
|
|
72
|
+
const buildString = (node, ctx) => {
|
|
73
|
+
if (typeof node.pattern === 'string') {
|
|
74
|
+
if (node.pattern.length > PATTERN_MAX_LENGTH) {
|
|
75
|
+
throw buildErr(ctx.pointer, `pattern length ${node.pattern.length} exceeds cap of ${PATTERN_MAX_LENGTH} (ReDoS guard)`);
|
|
76
|
+
}
|
|
77
|
+
if (typeof node.maxLength !== 'number') {
|
|
78
|
+
throw buildErr(ctx.pointer, 'pattern requires maxLength on the same schema (footgun: ReDoS)');
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
new RegExp(node.pattern);
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
throw buildErr(ctx.pointer, `invalid pattern: ${err instanceof Error ? err.message : String(err)}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const fmt = typeof node.format === 'string' ? FORMAT_MAP[node.format] : undefined;
|
|
88
|
+
return new ctx.m.StringSchema({
|
|
89
|
+
kind: 'string', format: fmt ?? 'plain',
|
|
90
|
+
...(typeof node.minLength === 'number' ? { min: node.minLength } : {}),
|
|
91
|
+
...(typeof node.maxLength === 'number' ? { max: node.maxLength } : {}),
|
|
92
|
+
...(typeof node.pattern === 'string' ? { pattern: node.pattern } : {}),
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
const buildNumber = (node, ctx, isInt) => {
|
|
96
|
+
// schema's IR has only min/max (inclusive). exclusiveMinimum/Maximum are
|
|
97
|
+
// approximated as inclusive for IR mock-generation purposes — the
|
|
98
|
+
// generated value drift is at most one ulp / one int and acceptable for
|
|
99
|
+
// placeholder fixtures. The validator (validate.ts) still enforces the
|
|
100
|
+
// exact exclusive semantics on real inbound requests.
|
|
101
|
+
const numNode = { kind: 'number', int: isInt };
|
|
102
|
+
if (typeof node.minimum === 'number')
|
|
103
|
+
numNode.min = node.minimum;
|
|
104
|
+
else if (typeof node.exclusiveMinimum === 'number') {
|
|
105
|
+
numNode.min = node.exclusiveMinimum;
|
|
106
|
+
}
|
|
107
|
+
if (typeof node.maximum === 'number')
|
|
108
|
+
numNode.max = node.maximum;
|
|
109
|
+
else if (typeof node.exclusiveMaximum === 'number') {
|
|
110
|
+
numNode.max = node.exclusiveMaximum;
|
|
111
|
+
}
|
|
112
|
+
return new ctx.m.NumberSchema(numNode);
|
|
113
|
+
};
|
|
114
|
+
const buildArray = (node, ctx) => {
|
|
115
|
+
const itemNode = node.items ?? {};
|
|
116
|
+
const itemSchema = translate(itemNode, enterPtr(ctx, 'items'));
|
|
117
|
+
let arr = ctx.m.arr(itemSchema);
|
|
118
|
+
if (typeof node.minItems === 'number')
|
|
119
|
+
arr = arr.min(node.minItems);
|
|
120
|
+
if (typeof node.maxItems === 'number')
|
|
121
|
+
arr = arr.max(node.maxItems);
|
|
122
|
+
return arr;
|
|
123
|
+
};
|
|
124
|
+
const buildObject = (node, ctx) => {
|
|
125
|
+
const required = new Set(Array.isArray(node.required) ? node.required : []);
|
|
126
|
+
const fields = {};
|
|
127
|
+
for (const [k, child] of Object.entries(node.properties ?? {})) {
|
|
128
|
+
const childSchema = translate(child, enterPtr(ctx, `properties/${k}`));
|
|
129
|
+
fields[k] = required.has(k) ? childSchema : childSchema.optional();
|
|
130
|
+
}
|
|
131
|
+
// `additionalProperties` is a no-op for *generation* — we only ever
|
|
132
|
+
// emit the declared `properties` above, so we never invent extra
|
|
133
|
+
// keys regardless of the keyword's value. We still acknowledge it
|
|
134
|
+
// explicitly so the translator's keyword surface mirrors
|
|
135
|
+
// `validation/validate.ts` (which DOES enforce it on inbound bodies).
|
|
136
|
+
const ap = node.additionalProperties;
|
|
137
|
+
if (ap === false) {
|
|
138
|
+
// Strict-extra-keys: aligned with validator behaviour. No-op here.
|
|
139
|
+
}
|
|
140
|
+
else if (ap === true || ap === undefined) {
|
|
141
|
+
// Open object: no-op — generator never invents undeclared keys.
|
|
142
|
+
}
|
|
143
|
+
else if (isObj(ap)) {
|
|
144
|
+
// Schema form: translate-and-discard. We don't use the result for
|
|
145
|
+
// generation (we never emit extra keys), but recursing now means
|
|
146
|
+
// an unsupported nested keyword (e.g. `if`) FAILS LOUD at build
|
|
147
|
+
// time instead of being silently accepted.
|
|
148
|
+
translate(ap, enterPtr(ctx, 'additionalProperties'));
|
|
149
|
+
}
|
|
150
|
+
return ctx.m.obj(fields);
|
|
151
|
+
};
|
|
152
|
+
const isObjectSchema = (schema, builders) => schema instanceof builders.ObjectSchema;
|
|
153
|
+
const buildDiscriminated = (ctx, disc) => {
|
|
154
|
+
const branches = {};
|
|
155
|
+
for (const [tag, ref] of Object.entries(disc.mapping)) {
|
|
156
|
+
const childCtx = enterPtr(ctx, `discriminator/mapping/${tag}`);
|
|
157
|
+
if (childCtx.refStack.includes(ref)) {
|
|
158
|
+
throw buildErr(childCtx.pointer, `$ref cycle detected: ${ref}`);
|
|
159
|
+
}
|
|
160
|
+
const target = resolveRef(ref, ctx.doc, childCtx.pointer);
|
|
161
|
+
const branchSchema = translate(target, {
|
|
162
|
+
...childCtx,
|
|
163
|
+
refStack: [...childCtx.refStack, ref],
|
|
164
|
+
pointer: ref,
|
|
165
|
+
});
|
|
166
|
+
if (!isObjectSchema(branchSchema, ctx.m)) {
|
|
167
|
+
throw buildErr(childCtx.pointer, `discriminator branch ${JSON.stringify(tag)} must be an object schema`);
|
|
168
|
+
}
|
|
169
|
+
// Force the discriminator field to literal(tag) so `discriminated()`
|
|
170
|
+
// accepts the branch — OAS schemas typically declare it as
|
|
171
|
+
// `type: 'string'` rather than constraining to the tag value.
|
|
172
|
+
const objBranch = branchSchema;
|
|
173
|
+
const newFields = {
|
|
174
|
+
...objBranch._fields,
|
|
175
|
+
[disc.propertyName]: ctx.m.literal(tag),
|
|
176
|
+
};
|
|
177
|
+
branches[tag] = ctx.m.obj(newFields);
|
|
178
|
+
}
|
|
179
|
+
return ctx.m.discriminated(disc.propertyName, branches);
|
|
180
|
+
};
|
|
181
|
+
const buildAllOfMerge = (node, ctx) => {
|
|
182
|
+
// Mirror generate.ts: shallow-merge object-typed branches into a
|
|
183
|
+
// single obj schema. If any branch isn't object-typed once translated
|
|
184
|
+
// we bail and let the caller fall through to other precedence rules.
|
|
185
|
+
const merged = {};
|
|
186
|
+
let allObjects = true;
|
|
187
|
+
for (let i = 0; i < node.allOf.length; i++) {
|
|
188
|
+
const branch = translate(node.allOf[i], enterPtr(ctx, `allOf/${i}`));
|
|
189
|
+
if (!isObjectSchema(branch, ctx.m)) {
|
|
190
|
+
allObjects = false;
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
const fields = branch._fields;
|
|
194
|
+
for (const [k, v] of Object.entries(fields))
|
|
195
|
+
merged[k] = v;
|
|
196
|
+
}
|
|
197
|
+
if (!allObjects)
|
|
198
|
+
return null;
|
|
199
|
+
return ctx.m.obj(merged);
|
|
200
|
+
};
|
|
201
|
+
const translate = (node, ctx) => {
|
|
202
|
+
if (ctx.depth > DEPTH_CAP) {
|
|
203
|
+
throw buildErr(ctx.pointer, `schema nesting exceeds depth cap of ${DEPTH_CAP}`);
|
|
204
|
+
}
|
|
205
|
+
if (!isObj(node))
|
|
206
|
+
throw buildErr(ctx.pointer, 'schema node must be an object');
|
|
207
|
+
for (const key of Object.keys(node)) {
|
|
208
|
+
if (UNSUPPORTED_KEYWORDS.has(key)) {
|
|
209
|
+
throw buildErr(ctx.pointer, `unsupported JSON Schema keyword: ${key}`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
// Precedence (mirrors generate.ts):
|
|
213
|
+
// example > examples[0] > enum > const > $ref > allOf > oneOf > anyOf > type
|
|
214
|
+
if (node.example !== undefined) {
|
|
215
|
+
return literalize(node.example, ctx.m, ctx.pointer, ctx.depth);
|
|
216
|
+
}
|
|
217
|
+
if (Array.isArray(node.examples) && node.examples.length > 0) {
|
|
218
|
+
return literalize(node.examples[0], ctx.m, ctx.pointer, ctx.depth);
|
|
219
|
+
}
|
|
220
|
+
if (Array.isArray(node.enum) && node.enum.length > 0) {
|
|
221
|
+
const allStrNum = node.enum.every((v) => typeof v === 'string' || typeof v === 'number');
|
|
222
|
+
return allStrNum
|
|
223
|
+
? ctx.m.enum_(node.enum)
|
|
224
|
+
: ctx.m.union(...node.enum.map((v) => literalize(v, ctx.m, ctx.pointer, ctx.depth)));
|
|
225
|
+
}
|
|
226
|
+
if (node.const !== undefined) {
|
|
227
|
+
return literalize(node.const, ctx.m, ctx.pointer, ctx.depth);
|
|
228
|
+
}
|
|
229
|
+
if (typeof node.$ref === 'string') {
|
|
230
|
+
if (ctx.refStack.includes(node.$ref)) {
|
|
231
|
+
throw buildErr(ctx.pointer, `$ref cycle detected: ${[...ctx.refStack, node.$ref].join(' -> ')}`);
|
|
232
|
+
}
|
|
233
|
+
const target = resolveRef(node.$ref, ctx.doc, ctx.pointer);
|
|
234
|
+
const out = translate(target, {
|
|
235
|
+
...ctx,
|
|
236
|
+
refStack: [...ctx.refStack, node.$ref],
|
|
237
|
+
depth: ctx.depth + 1,
|
|
238
|
+
pointer: node.$ref,
|
|
239
|
+
});
|
|
240
|
+
return isNullable(node) ? out.nullable() : out;
|
|
241
|
+
}
|
|
242
|
+
if (Array.isArray(node.allOf) && node.allOf.length > 0) {
|
|
243
|
+
const merged = buildAllOfMerge(node, ctx);
|
|
244
|
+
if (merged !== null)
|
|
245
|
+
return isNullable(node) ? merged.nullable() : merged;
|
|
246
|
+
}
|
|
247
|
+
const disc = node.discriminator;
|
|
248
|
+
if (Array.isArray(node.oneOf) && node.oneOf.length > 0) {
|
|
249
|
+
if (disc && disc.mapping) {
|
|
250
|
+
const out = buildDiscriminated(ctx, { propertyName: disc.propertyName, mapping: disc.mapping });
|
|
251
|
+
return isNullable(node) ? out.nullable() : out;
|
|
252
|
+
}
|
|
253
|
+
const branches = node.oneOf.map((b, i) => translate(b, enterPtr(ctx, `oneOf/${i}`)));
|
|
254
|
+
const out = ctx.m.union(...branches);
|
|
255
|
+
return isNullable(node) ? out.nullable() : out;
|
|
256
|
+
}
|
|
257
|
+
if (Array.isArray(node.anyOf) && node.anyOf.length > 0) {
|
|
258
|
+
const branches = node.anyOf.map((b, i) => translate(b, enterPtr(ctx, `anyOf/${i}`)));
|
|
259
|
+
const out = ctx.m.union(...branches);
|
|
260
|
+
return isNullable(node) ? out.nullable() : out;
|
|
261
|
+
}
|
|
262
|
+
// type-fallback
|
|
263
|
+
let t = pickType(node);
|
|
264
|
+
if (!t && node.properties)
|
|
265
|
+
t = 'object';
|
|
266
|
+
if (!t && node.items !== undefined)
|
|
267
|
+
t = 'array';
|
|
268
|
+
if (!t) {
|
|
269
|
+
// Unknown / open node: best-effort — empty object schema, with
|
|
270
|
+
// nullable applied if requested.
|
|
271
|
+
const empty = ctx.m.obj({});
|
|
272
|
+
return isNullable(node) ? empty.nullable() : empty;
|
|
273
|
+
}
|
|
274
|
+
let built;
|
|
275
|
+
switch (t) {
|
|
276
|
+
case 'string':
|
|
277
|
+
built = buildString(node, ctx);
|
|
278
|
+
break;
|
|
279
|
+
case 'integer':
|
|
280
|
+
built = buildNumber(node, ctx, true);
|
|
281
|
+
break;
|
|
282
|
+
case 'number':
|
|
283
|
+
built = buildNumber(node, ctx, false);
|
|
284
|
+
break;
|
|
285
|
+
case 'boolean':
|
|
286
|
+
built = ctx.m.bool();
|
|
287
|
+
break;
|
|
288
|
+
case 'null':
|
|
289
|
+
built = ctx.m.null_();
|
|
290
|
+
break;
|
|
291
|
+
case 'array':
|
|
292
|
+
built = buildArray(node, ctx);
|
|
293
|
+
break;
|
|
294
|
+
case 'object':
|
|
295
|
+
built = buildObject(node, ctx);
|
|
296
|
+
break;
|
|
297
|
+
default:
|
|
298
|
+
throw buildErr(ctx.pointer, `unsupported OpenAPI type: ${t}`);
|
|
299
|
+
}
|
|
300
|
+
return isNullable(node) ? built.nullable() : built;
|
|
301
|
+
};
|
|
302
|
+
/**
|
|
303
|
+
* Translate an OpenAPI schema node into a `@databehave/schema` IR
|
|
304
|
+
* Schema instance. Throws at translate time on unsupported keywords,
|
|
305
|
+
* malformed `$ref`s, `$ref` cycles, ReDoS-vulnerable patterns, and
|
|
306
|
+
* schemas that exceed the depth cap. See the file header for the
|
|
307
|
+
* full keyword matrix and security guarantees.
|
|
308
|
+
*/
|
|
309
|
+
export async function translateOasToIR(node, doc, m) {
|
|
310
|
+
return translate(node, { doc, refStack: [], depth: 0, pointer: '#', m });
|
|
311
|
+
}
|
|
312
|
+
//# sourceMappingURL=translate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translate.js","sourceRoot":"","sources":["../../src/openapi/translate.ts"],"names":[],"mappings":"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"}
|