@jentic/arazzo-parser 1.0.0-alpha.5 → 1.0.0-alpha.6
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 +6 -0
- package/README.md +272 -43
- package/dist/jentic-arazzo-parser.browser.js +66825 -44042
- package/dist/jentic-arazzo-parser.browser.min.js +1 -1
- package/package.json +11 -10
- package/src/index.cjs +4 -147
- package/src/index.mjs +1 -143
- package/src/parse-arazzo.cjs +213 -0
- package/src/parse-arazzo.mjs +206 -0
- package/src/resolve/resolvers/memory/index.cjs +29 -0
- package/src/resolve/resolvers/memory/index.mjs +25 -0
- package/types/arazzo-parser.d.ts +9 -7
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { toValue } from '@speclynx/apidom-core';
|
|
2
|
+
import { AnnotationElement } from '@speclynx/apidom-datamodel';
|
|
3
|
+
import { parse as parseURI, mergeOptions } from '@speclynx/apidom-reference/configuration/empty';
|
|
4
|
+
import ArazzoJSON1Parser from '@speclynx/apidom-reference/parse/parsers/arazzo-json-1';
|
|
5
|
+
import ArazzoYAML1Parser from '@speclynx/apidom-reference/parse/parsers/arazzo-yaml-1';
|
|
6
|
+
import OpenApiJSON2Parser from '@speclynx/apidom-reference/parse/parsers/openapi-json-2';
|
|
7
|
+
import OpenApiYAML2Parser from '@speclynx/apidom-reference/parse/parsers/openapi-yaml-2';
|
|
8
|
+
import OpenApiJSON3_0Parser from '@speclynx/apidom-reference/parse/parsers/openapi-json-3-0';
|
|
9
|
+
import OpenApiYAML3_0Parser from '@speclynx/apidom-reference/parse/parsers/openapi-yaml-3-0';
|
|
10
|
+
import OpenApiJSON3_1Parser from '@speclynx/apidom-reference/parse/parsers/openapi-json-3-1';
|
|
11
|
+
import OpenApiYAML3_1Parser from '@speclynx/apidom-reference/parse/parsers/openapi-yaml-3-1';
|
|
12
|
+
import FileResolver from '@speclynx/apidom-reference/resolve/resolvers/file';
|
|
13
|
+
import HTTPResolverAxios from '@speclynx/apidom-reference/resolve/resolvers/http-axios';
|
|
14
|
+
import { detect as detectArazzoJSON } from '@speclynx/apidom-parser-adapter-arazzo-json-1';
|
|
15
|
+
import { isArazzoSpecification1Element } from '@speclynx/apidom-ns-arazzo-1';
|
|
16
|
+
import { detect as detectArazzoYAML } from '@speclynx/apidom-parser-adapter-arazzo-yaml-1';
|
|
17
|
+
import { isPlainObject } from 'ramda-adjunct';
|
|
18
|
+
import ParseError from "./errors/ParseError.mjs";
|
|
19
|
+
import MemoryResolver from "./resolve/resolvers/memory/index.mjs";
|
|
20
|
+
/**
|
|
21
|
+
* Options for parsing Arazzo Documents.
|
|
22
|
+
* @public
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Default reference options for parsing Arazzo Documents.
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
28
|
+
export const defaultOptions = {
|
|
29
|
+
parse: {
|
|
30
|
+
parsers: [new ArazzoJSON1Parser({
|
|
31
|
+
allowEmpty: false,
|
|
32
|
+
fileExtensions: ['.json'],
|
|
33
|
+
parseFn: parseURI
|
|
34
|
+
}), new ArazzoYAML1Parser({
|
|
35
|
+
allowEmpty: false,
|
|
36
|
+
fileExtensions: ['.yaml', '.yml'],
|
|
37
|
+
parseFn: parseURI
|
|
38
|
+
}), new OpenApiJSON2Parser({
|
|
39
|
+
allowEmpty: false,
|
|
40
|
+
fileExtensions: ['.json']
|
|
41
|
+
}), new OpenApiYAML2Parser({
|
|
42
|
+
allowEmpty: false,
|
|
43
|
+
fileExtensions: ['.yaml', '.yml']
|
|
44
|
+
}), new OpenApiJSON3_0Parser({
|
|
45
|
+
allowEmpty: false,
|
|
46
|
+
fileExtensions: ['.json']
|
|
47
|
+
}), new OpenApiYAML3_0Parser({
|
|
48
|
+
allowEmpty: false,
|
|
49
|
+
fileExtensions: ['.yaml', '.yml']
|
|
50
|
+
}), new OpenApiJSON3_1Parser({
|
|
51
|
+
allowEmpty: false,
|
|
52
|
+
fileExtensions: ['.json']
|
|
53
|
+
}), new OpenApiYAML3_1Parser({
|
|
54
|
+
allowEmpty: false,
|
|
55
|
+
fileExtensions: ['.yaml', '.yml']
|
|
56
|
+
})],
|
|
57
|
+
parserOpts: {
|
|
58
|
+
sourceMap: false,
|
|
59
|
+
strict: true,
|
|
60
|
+
sourceDescriptions: false
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
resolve: {
|
|
64
|
+
resolvers: [new MemoryResolver(), new FileResolver({
|
|
65
|
+
fileAllowList: ['*.json', '*.yaml', '*.yml']
|
|
66
|
+
}), new HTTPResolverAxios({
|
|
67
|
+
timeout: 5000,
|
|
68
|
+
redirects: 5,
|
|
69
|
+
withCredentials: false
|
|
70
|
+
})],
|
|
71
|
+
resolverOpts: {}
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Parses an Arazzo Document from an object.
|
|
77
|
+
* @param source - The Arazzo Document as a plain object
|
|
78
|
+
* @param options - Reference options (uses defaultOptions when not provided)
|
|
79
|
+
* @returns A promise that resolves to the parsed Arazzo Document as ApiDOM data model
|
|
80
|
+
* @throws ParseError - When parsing fails for any reason. The original error is available via the `cause` property.
|
|
81
|
+
* @public
|
|
82
|
+
*/
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Parses an Arazzo Document from a string or URI.
|
|
86
|
+
* @param source - The Arazzo Document as string content, or a file system path / HTTP(S) URL
|
|
87
|
+
* @param options - Reference options (uses defaultOptions when not provided)
|
|
88
|
+
* @returns A promise that resolves to the parsed Arazzo Document as ApiDOM data model
|
|
89
|
+
* @throws ParseError - When parsing fails for any reason. The original error is available via the `cause` property.
|
|
90
|
+
* @public
|
|
91
|
+
*/
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Parses an Arazzo Document from a string, object, or URI.
|
|
95
|
+
*
|
|
96
|
+
* The function handles three types of input:
|
|
97
|
+
* 1. Object - converts to JSON string and parses (source maps supported with `strict: false`)
|
|
98
|
+
* 2. String content - uses Arazzo detection to identify and parse inline JSON or YAML content
|
|
99
|
+
* 3. URI string - if not detected as Arazzo content, treats as file system path or HTTP(S) URL
|
|
100
|
+
*
|
|
101
|
+
* @param source - The Arazzo Document as an object, string content, or a file system path / HTTP(S) URL
|
|
102
|
+
* @param options - Reference options (uses defaultOptions when not provided)
|
|
103
|
+
* @returns A promise that resolves to the parsed Arazzo Document as ApiDOM data model
|
|
104
|
+
* @throws ParseError - When parsing fails for any reason. The original error is available via the `cause` property.
|
|
105
|
+
*
|
|
106
|
+
* @example
|
|
107
|
+
* Parse from object
|
|
108
|
+
* ```typescript
|
|
109
|
+
* const result = await parseArazzo({ arazzo: '1.0.1', info: {...} });
|
|
110
|
+
* ```
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* Parse inline JSON
|
|
114
|
+
* ```typescript
|
|
115
|
+
* const result = await parseArazzo('{"arazzo": "1.0.1", "info": {...}}');
|
|
116
|
+
* ```
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* Parse from file
|
|
120
|
+
* ```typescript
|
|
121
|
+
* const result = await parseArazzo('/path/to/arazzo.json');
|
|
122
|
+
* ```
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* Parse from URL
|
|
126
|
+
* ```typescript
|
|
127
|
+
* const result = await parseArazzo('https://example.com/arazzo.yaml');
|
|
128
|
+
* ```
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* Parse with custom options
|
|
132
|
+
* ```typescript
|
|
133
|
+
* const result = await parseArazzo('/path/to/arazzo.json', customOptions);
|
|
134
|
+
* ```
|
|
135
|
+
* @public
|
|
136
|
+
*/
|
|
137
|
+
export async function parse(source, options = {}) {
|
|
138
|
+
let mergedOptions = mergeOptions(defaultOptions, options);
|
|
139
|
+
const strict = mergedOptions.parse?.parserOpts?.strict ?? true;
|
|
140
|
+
let sourceProvenance;
|
|
141
|
+
if (isPlainObject(source)) {
|
|
142
|
+
const arazzoDocument = JSON.stringify(source, null, 2);
|
|
143
|
+
mergedOptions = mergeOptions(mergedOptions, {
|
|
144
|
+
resolve: {
|
|
145
|
+
resolverOpts: {
|
|
146
|
+
arazzoDocument
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
source = 'memory://arazzo.json';
|
|
151
|
+
sourceProvenance = '[object]';
|
|
152
|
+
} else if (await detectArazzoJSON(source, {
|
|
153
|
+
strict
|
|
154
|
+
})) {
|
|
155
|
+
mergedOptions = mergeOptions(mergedOptions, {
|
|
156
|
+
resolve: {
|
|
157
|
+
resolverOpts: {
|
|
158
|
+
arazzoDocument: source
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
source = 'memory://arazzo.json';
|
|
163
|
+
sourceProvenance = '[inline JSON]';
|
|
164
|
+
} else if (await detectArazzoYAML(source, {
|
|
165
|
+
strict
|
|
166
|
+
})) {
|
|
167
|
+
mergedOptions = mergeOptions(mergedOptions, {
|
|
168
|
+
resolve: {
|
|
169
|
+
resolverOpts: {
|
|
170
|
+
arazzoDocument: source
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
source = 'memory://arazzo.yaml';
|
|
175
|
+
sourceProvenance = '[inline YAML]';
|
|
176
|
+
} else {
|
|
177
|
+
sourceProvenance = source;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// next we assume that source is either file system URI or HTTP(S) URL
|
|
181
|
+
try {
|
|
182
|
+
const parseResult = await parseURI(source, mergedOptions);
|
|
183
|
+
|
|
184
|
+
// set retrievalURI metadata for file/URL sources (not for inline content)
|
|
185
|
+
if (!source.startsWith('memory://')) {
|
|
186
|
+
parseResult.meta.set('retrievalURI', source);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// validate that the parsed document is an Arazzo specification
|
|
190
|
+
if (!isArazzoSpecification1Element(parseResult.api)) {
|
|
191
|
+
const annotation = new AnnotationElement('Document is not a valid Arazzo specification. Expected an Arazzo document with "arazzo" version field.', {
|
|
192
|
+
classes: ['error']
|
|
193
|
+
});
|
|
194
|
+
// remove 'api' class so .api returns undefined, but keep parsed result available
|
|
195
|
+
if (parseResult.api) {
|
|
196
|
+
parseResult.api.classes = parseResult.api.classes.filter(cls => toValue(cls) !== 'api');
|
|
197
|
+
}
|
|
198
|
+
parseResult.push(annotation);
|
|
199
|
+
}
|
|
200
|
+
return parseResult;
|
|
201
|
+
} catch (error) {
|
|
202
|
+
throw new ParseError(`Failed to parse Arazzo Document from "${sourceProvenance}"`, {
|
|
203
|
+
cause: error
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.default = void 0;
|
|
5
|
+
var _empty = require("@speclynx/apidom-reference/configuration/empty");
|
|
6
|
+
/**
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
class MemoryResolver extends _empty.Resolver {
|
|
10
|
+
constructor() {
|
|
11
|
+
super({
|
|
12
|
+
name: 'memory'
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
canRead(file) {
|
|
16
|
+
return file.uri.startsWith('memory://') && typeof this.arazzoDocument === 'string';
|
|
17
|
+
}
|
|
18
|
+
async read(file) {
|
|
19
|
+
try {
|
|
20
|
+
const encoder = new TextEncoder();
|
|
21
|
+
return encoder.encode(this.arazzoDocument);
|
|
22
|
+
} catch (error) {
|
|
23
|
+
throw new _empty.ResolverError(`Error opening file "${file.uri}"`, {
|
|
24
|
+
cause: error
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
var _default = exports.default = MemoryResolver;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Resolver, ResolverError } from '@speclynx/apidom-reference/configuration/empty';
|
|
2
|
+
/**
|
|
3
|
+
* @public
|
|
4
|
+
*/
|
|
5
|
+
class MemoryResolver extends Resolver {
|
|
6
|
+
constructor() {
|
|
7
|
+
super({
|
|
8
|
+
name: 'memory'
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
canRead(file) {
|
|
12
|
+
return file.uri.startsWith('memory://') && typeof this.arazzoDocument === 'string';
|
|
13
|
+
}
|
|
14
|
+
async read(file) {
|
|
15
|
+
try {
|
|
16
|
+
const encoder = new TextEncoder();
|
|
17
|
+
return encoder.encode(this.arazzoDocument);
|
|
18
|
+
} catch (error) {
|
|
19
|
+
throw new ResolverError(`Error opening file "${file.uri}"`, {
|
|
20
|
+
cause: error
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export default MemoryResolver;
|
package/types/arazzo-parser.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ApiDOMReferenceOptions } from '@speclynx/apidom-reference';
|
|
2
2
|
import { ParseResultElement } from '@speclynx/apidom-datamodel';
|
|
3
|
+
import type { PartialDeep } from 'type-fest';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Default reference options for parsing Arazzo Documents.
|
|
@@ -7,16 +8,21 @@ import { ParseResultElement } from '@speclynx/apidom-datamodel';
|
|
|
7
8
|
*/
|
|
8
9
|
export declare const defaultOptions: Options;
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Options for parsing Arazzo Documents.
|
|
13
|
+
* @public
|
|
14
|
+
*/
|
|
15
|
+
export declare type Options = PartialDeep<ApiDOMReferenceOptions>;
|
|
11
16
|
|
|
12
17
|
/**
|
|
13
18
|
* Parses an Arazzo Document from an object.
|
|
14
19
|
* @param source - The Arazzo Document as a plain object
|
|
15
20
|
* @param options - Reference options (uses defaultOptions when not provided)
|
|
16
21
|
* @returns A promise that resolves to the parsed Arazzo Document as ApiDOM data model
|
|
22
|
+
* @throws ParseError - When parsing fails for any reason. The original error is available via the `cause` property.
|
|
17
23
|
* @public
|
|
18
24
|
*/
|
|
19
|
-
export declare function
|
|
25
|
+
export declare function parseArazzo(source: Record<string, unknown>, options?: Options): Promise<ParseResultElement>;
|
|
20
26
|
|
|
21
27
|
/**
|
|
22
28
|
* Parses an Arazzo Document from a string or URI.
|
|
@@ -26,10 +32,6 @@ export declare function parse(source: Record<string, unknown>, options?: Options
|
|
|
26
32
|
* @throws ParseError - When parsing fails for any reason. The original error is available via the `cause` property.
|
|
27
33
|
* @public
|
|
28
34
|
*/
|
|
29
|
-
export declare function
|
|
30
|
-
|
|
31
|
-
declare type PartialDeep<T> = {
|
|
32
|
-
[P in keyof T]?: T[P] extends object ? PartialDeep<T[P]> : T[P];
|
|
33
|
-
};
|
|
35
|
+
export declare function parseArazzo(source: string, options?: Options): Promise<ParseResultElement>;
|
|
34
36
|
|
|
35
37
|
export { }
|