@jentic/arazzo-parser 1.0.0-alpha.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/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@jentic/arazzo-parser",
3
+ "version": "1.0.0-alpha.0",
4
+ "description": "Parser for Arazzo Documents producing SpecLynx ApiDOM data model.",
5
+ "publishConfig": {
6
+ "access": "public",
7
+ "registry": "https://registry.npmjs.org",
8
+ "tag": "latest"
9
+ },
10
+ "type": "module",
11
+ "sideEffects": false,
12
+ "unpkg": "./dist/jentic-arazzo-parser.browser.min.js",
13
+ "main": "./src/index.cjs",
14
+ "exports": {
15
+ "types": "./types/arazzo-parser.d.ts",
16
+ "import": "./src/index.mjs",
17
+ "require": "./src/index.cjs"
18
+ },
19
+ "types": "./types/arazzo-parser.d.ts",
20
+ "scripts": {
21
+ "build": "npm run clean && run-p --max-parallel ${CPU_CORES:-2} typescript:declaration build:es build:cjs build:umd:browser",
22
+ "build:es": "cross-env BABEL_ENV=es babel src --out-dir src --extensions '.ts' --out-file-extension '.mjs' --root-mode 'upward'",
23
+ "build:cjs": "cross-env BABEL_ENV=cjs babel src --out-dir src --extensions '.ts' --out-file-extension '.cjs' --root-mode 'upward'",
24
+ "build:umd:browser": "cross-env BABEL_ENV=browser webpack --config config/webpack/browser.config.js --progress",
25
+ "lint": "eslint ./",
26
+ "lint:fix": "eslint ./ --fix",
27
+ "clean": "rimraf --glob 'src/**/*.mjs' 'src/**/*.cjs' 'test/**/*.mjs' ./dist ./types",
28
+ "typescript:check-types": "tsc --noEmit",
29
+ "typescript:declaration": "tsc -p tsconfig.declaration.json && api-extractor run -l -c ./config/api-extractor/api-extractor.json",
30
+ "test": "npm run build:es && cross-env BABEL_ENV=es babel test --out-dir test --extensions '.ts' --out-file-extension '.mjs' --root-mode 'upward' && cross-env NODE_ENV=test mocha",
31
+ "prepack": "copyfiles -u 2 ../../LICENSE . && copyfiles -u 2 ../../NOTICE .",
32
+ "postpack": "rimraf NOTICE LICENSE"
33
+ },
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/jentic/jentic-arazzo-tools.git"
37
+ },
38
+ "author": "Jentic <hello@jentic.com>",
39
+ "license": "Apache-2.0",
40
+ "dependencies": {
41
+ "@babel/runtime-corejs3": "^7.28.4",
42
+ "@speclynx/apidom-datamodel": "^2.3.0",
43
+ "@speclynx/apidom-error": "^2.3.0",
44
+ "@speclynx/apidom-ns-arazzo-1": "^2.3.0",
45
+ "@speclynx/apidom-parser": "^2.3.0",
46
+ "@speclynx/apidom-parser-adapter-arazzo-json-1": "^2.3.0",
47
+ "@speclynx/apidom-parser-adapter-arazzo-yaml-1": "^2.3.0",
48
+ "@speclynx/apidom-reference": "^2.3.0",
49
+ "ramda-adjunct": "^6.0.0"
50
+ },
51
+ "files": [
52
+ "src/**/*.mjs",
53
+ "src/**/*.cjs",
54
+ "dist/",
55
+ "types/arazzo-parser.d.ts",
56
+ "LICENSE",
57
+ "NOTICE",
58
+ "README.md",
59
+ "CHANGELOG.md"
60
+ ]
61
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.default = void 0;
5
+ var _apidomError = require("@speclynx/apidom-error");
6
+ class ParseError extends _apidomError.ApiDOMError {
7
+ constructor(message, options) {
8
+ super(message, options);
9
+ }
10
+ }
11
+ var _default = exports.default = ParseError;
@@ -0,0 +1,7 @@
1
+ import { ApiDOMError } from '@speclynx/apidom-error';
2
+ class ParseError extends ApiDOMError {
3
+ constructor(message, options) {
4
+ super(message, options);
5
+ }
6
+ }
7
+ export default ParseError;
package/src/index.cjs ADDED
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
4
+ var _interopRequireWildcard = require("@babel/runtime-corejs3/helpers/interopRequireWildcard").default;
5
+ exports.__esModule = true;
6
+ exports.defaultParseOptions = void 0;
7
+ exports.parse = parse;
8
+ var _apidomDatamodel = require("@speclynx/apidom-datamodel");
9
+ var _apidomNsArazzo = require("@speclynx/apidom-ns-arazzo-1");
10
+ var _apidomParser = _interopRequireWildcard(require("@speclynx/apidom-parser"));
11
+ var jsonParserAdapter = _interopRequireWildcard(require("@speclynx/apidom-parser-adapter-arazzo-json-1"));
12
+ var yamlParserAdapter = _interopRequireWildcard(require("@speclynx/apidom-parser-adapter-arazzo-yaml-1"));
13
+ var _empty = require("@speclynx/apidom-reference/configuration/empty");
14
+ var _arazzoJson = _interopRequireDefault(require("@speclynx/apidom-reference/parse/parsers/arazzo-json-1"));
15
+ var _arazzoYaml = _interopRequireDefault(require("@speclynx/apidom-reference/parse/parsers/arazzo-yaml-1"));
16
+ var _file = _interopRequireDefault(require("@speclynx/apidom-reference/resolve/resolvers/file"));
17
+ var _httpAxios = _interopRequireDefault(require("@speclynx/apidom-reference/resolve/resolvers/http-axios"));
18
+ var _ramdaAdjunct = require("ramda-adjunct");
19
+ var _ParseError = _interopRequireDefault(require("./errors/ParseError.cjs"));
20
+ /**
21
+ * Options for parsing Arazzo Documents.
22
+ * @public
23
+ */
24
+
25
+ /**
26
+ * Default options for parsing Arazzo Documents.
27
+ * @public
28
+ */
29
+ const defaultParseOptions = exports.defaultParseOptions = {
30
+ strict: true,
31
+ sourceMap: false,
32
+ parserOpts: {},
33
+ resolverOpts: {}
34
+ };
35
+ const parser = new _apidomParser.default();
36
+ parser.use(jsonParserAdapter);
37
+ parser.use(yamlParserAdapter);
38
+
39
+ /**
40
+ * Parses an Arazzo Document from an object.
41
+ * @param source - The Arazzo Document as a plain object
42
+ * @param options - Parsing options
43
+ * @returns A promise that resolves to the parsed Arazzo Document as ApiDOM data model
44
+ * @public
45
+ */
46
+
47
+ /**
48
+ * Parses an Arazzo Document from a string or URI.
49
+ * @param source - The Arazzo Document as string content, or a file system path / HTTP(S) URL
50
+ * @param options - Parsing options
51
+ * @returns A promise that resolves to the parsed Arazzo Document as ApiDOM data model
52
+ * @throws ParseError - When parsing fails for any reason. The original error is available via the `cause` property.
53
+ * @public
54
+ */
55
+
56
+ /**
57
+ * Parses an Arazzo Document from a string, object, or URI.
58
+ *
59
+ * The function handles three types of input:
60
+ * 1. Object - directly refracts the object into an Arazzo specification element
61
+ * 2. String content - attempts to parse as an inline Arazzo Document (JSON or YAML)
62
+ * 3. URI string - treats as a file system path or HTTP(S) URL and resolves the document
63
+ *
64
+ * @param source - The Arazzo Document as an object, string content, or a file system path / HTTP(S) URL
65
+ * @param options - Parsing options
66
+ * @returns A promise that resolves to the parsed Arazzo Document as ApiDOM data model
67
+ * @throws ParseError - When parsing fails for any reason. The original error is available via the `cause` property.
68
+ *
69
+ * @example
70
+ * // Parse from object
71
+ * const result = await parse(\{ arazzo: '1.0.1', info: \{...\} \});
72
+ *
73
+ * @example
74
+ * // Parse inline JSON
75
+ * const result = await parse('\{"arazzo": "1.0.1", "info": \{...\}\}');
76
+ *
77
+ * @example
78
+ * // Parse from file
79
+ * const result = await parse('/path/to/arazzo.json');
80
+ *
81
+ * @example
82
+ * // Parse from URL
83
+ * const result = await parse('https://example.com/arazzo.yaml');
84
+ * @public
85
+ */
86
+ async function parse(source, options = {}) {
87
+ const mergedOptions = {
88
+ ...defaultParseOptions,
89
+ ...options
90
+ };
91
+ const {
92
+ strict,
93
+ sourceMap,
94
+ parserOpts,
95
+ resolverOpts
96
+ } = mergedOptions;
97
+
98
+ // attempt to parse source as plain object
99
+ if ((0, _ramdaAdjunct.isPlainObject)(source)) {
100
+ if (sourceMap) {
101
+ throw new _ParseError.default('sourceMap option is not supported when parsing from object: source maps cannot be inferred from plain objects');
102
+ }
103
+ const parseResult = new _apidomDatamodel.ParseResultElement();
104
+ const element = (0, _apidomNsArazzo.refractArazzoSpecification1)(source);
105
+ element.classes.push('result');
106
+ parseResult.push(element);
107
+ return parseResult;
108
+ }
109
+
110
+ // next try to parse the source assuming it contains Arazzo Document
111
+ try {
112
+ return await parser.parse(source, {
113
+ sourceMap,
114
+ strict
115
+ });
116
+ } catch (error) {
117
+ if (error instanceof _apidomParser.ParserError && error.message !== 'Source did not match any registered parsers') {
118
+ throw new _ParseError.default('Failed to parse Arazzo Document', {
119
+ cause: error
120
+ });
121
+ }
122
+ }
123
+
124
+ // next we assume that source is either file system URI or HTTP(S) URL
125
+ try {
126
+ return await (0, _empty.parse)(source, {
127
+ parse: {
128
+ parsers: [new _arazzoJson.default({
129
+ allowEmpty: false,
130
+ sourceMap,
131
+ strict
132
+ }), new _arazzoYaml.default({
133
+ allowEmpty: false,
134
+ sourceMap,
135
+ strict
136
+ })],
137
+ parserOpts
138
+ },
139
+ resolve: {
140
+ resolvers: [new _file.default({
141
+ fileAllowList: ['*.json', '*.yaml', '*.yml']
142
+ }), new _httpAxios.default({
143
+ timeout: 5000,
144
+ redirects: 5,
145
+ withCredentials: false
146
+ })],
147
+ resolverOpts
148
+ }
149
+ });
150
+ } catch (error) {
151
+ throw new _ParseError.default('Failed to parse Arazzo Document from URI', {
152
+ cause: error
153
+ });
154
+ }
155
+ }
package/src/index.mjs ADDED
@@ -0,0 +1,147 @@
1
+ import { ParseResultElement } from '@speclynx/apidom-datamodel';
2
+ import { refractArazzoSpecification1 } from '@speclynx/apidom-ns-arazzo-1';
3
+ import ApiDOMParser, { ParserError } from '@speclynx/apidom-parser';
4
+ import * as jsonParserAdapter from '@speclynx/apidom-parser-adapter-arazzo-json-1';
5
+ import * as yamlParserAdapter from '@speclynx/apidom-parser-adapter-arazzo-yaml-1';
6
+ import { parse as parseURI } from '@speclynx/apidom-reference/configuration/empty';
7
+ import ArazzoJSON1Parser from '@speclynx/apidom-reference/parse/parsers/arazzo-json-1';
8
+ import ArazzoYAML1Parser from '@speclynx/apidom-reference/parse/parsers/arazzo-yaml-1';
9
+ import FileResolver from '@speclynx/apidom-reference/resolve/resolvers/file';
10
+ import HTTPResolverAxios from '@speclynx/apidom-reference/resolve/resolvers/http-axios';
11
+ import { isPlainObject } from 'ramda-adjunct';
12
+ import ParseError from "./errors/ParseError.mjs";
13
+ /**
14
+ * Options for parsing Arazzo Documents.
15
+ * @public
16
+ */
17
+ /**
18
+ * Default options for parsing Arazzo Documents.
19
+ * @public
20
+ */
21
+ export const defaultParseOptions = {
22
+ strict: true,
23
+ sourceMap: false,
24
+ parserOpts: {},
25
+ resolverOpts: {}
26
+ };
27
+ const parser = new ApiDOMParser();
28
+ parser.use(jsonParserAdapter);
29
+ parser.use(yamlParserAdapter);
30
+
31
+ /**
32
+ * Parses an Arazzo Document from an object.
33
+ * @param source - The Arazzo Document as a plain object
34
+ * @param options - Parsing options
35
+ * @returns A promise that resolves to the parsed Arazzo Document as ApiDOM data model
36
+ * @public
37
+ */
38
+
39
+ /**
40
+ * Parses an Arazzo Document from a string or URI.
41
+ * @param source - The Arazzo Document as string content, or a file system path / HTTP(S) URL
42
+ * @param options - Parsing options
43
+ * @returns A promise that resolves to the parsed Arazzo Document as ApiDOM data model
44
+ * @throws ParseError - When parsing fails for any reason. The original error is available via the `cause` property.
45
+ * @public
46
+ */
47
+
48
+ /**
49
+ * Parses an Arazzo Document from a string, object, or URI.
50
+ *
51
+ * The function handles three types of input:
52
+ * 1. Object - directly refracts the object into an Arazzo specification element
53
+ * 2. String content - attempts to parse as an inline Arazzo Document (JSON or YAML)
54
+ * 3. URI string - treats as a file system path or HTTP(S) URL and resolves the document
55
+ *
56
+ * @param source - The Arazzo Document as an object, string content, or a file system path / HTTP(S) URL
57
+ * @param options - Parsing options
58
+ * @returns A promise that resolves to the parsed Arazzo Document as ApiDOM data model
59
+ * @throws ParseError - When parsing fails for any reason. The original error is available via the `cause` property.
60
+ *
61
+ * @example
62
+ * // Parse from object
63
+ * const result = await parse(\{ arazzo: '1.0.1', info: \{...\} \});
64
+ *
65
+ * @example
66
+ * // Parse inline JSON
67
+ * const result = await parse('\{"arazzo": "1.0.1", "info": \{...\}\}');
68
+ *
69
+ * @example
70
+ * // Parse from file
71
+ * const result = await parse('/path/to/arazzo.json');
72
+ *
73
+ * @example
74
+ * // Parse from URL
75
+ * const result = await parse('https://example.com/arazzo.yaml');
76
+ * @public
77
+ */
78
+ export async function parse(source, options = {}) {
79
+ const mergedOptions = {
80
+ ...defaultParseOptions,
81
+ ...options
82
+ };
83
+ const {
84
+ strict,
85
+ sourceMap,
86
+ parserOpts,
87
+ resolverOpts
88
+ } = mergedOptions;
89
+
90
+ // attempt to parse source as plain object
91
+ if (isPlainObject(source)) {
92
+ if (sourceMap) {
93
+ throw new ParseError('sourceMap option is not supported when parsing from object: source maps cannot be inferred from plain objects');
94
+ }
95
+ const parseResult = new ParseResultElement();
96
+ const element = refractArazzoSpecification1(source);
97
+ element.classes.push('result');
98
+ parseResult.push(element);
99
+ return parseResult;
100
+ }
101
+
102
+ // next try to parse the source assuming it contains Arazzo Document
103
+ try {
104
+ return await parser.parse(source, {
105
+ sourceMap,
106
+ strict
107
+ });
108
+ } catch (error) {
109
+ if (error instanceof ParserError && error.message !== 'Source did not match any registered parsers') {
110
+ throw new ParseError('Failed to parse Arazzo Document', {
111
+ cause: error
112
+ });
113
+ }
114
+ }
115
+
116
+ // next we assume that source is either file system URI or HTTP(S) URL
117
+ try {
118
+ return await parseURI(source, {
119
+ parse: {
120
+ parsers: [new ArazzoJSON1Parser({
121
+ allowEmpty: false,
122
+ sourceMap,
123
+ strict
124
+ }), new ArazzoYAML1Parser({
125
+ allowEmpty: false,
126
+ sourceMap,
127
+ strict
128
+ })],
129
+ parserOpts
130
+ },
131
+ resolve: {
132
+ resolvers: [new FileResolver({
133
+ fileAllowList: ['*.json', '*.yaml', '*.yml']
134
+ }), new HTTPResolverAxios({
135
+ timeout: 5000,
136
+ redirects: 5,
137
+ withCredentials: false
138
+ })],
139
+ resolverOpts
140
+ }
141
+ });
142
+ } catch (error) {
143
+ throw new ParseError('Failed to parse Arazzo Document from URI', {
144
+ cause: error
145
+ });
146
+ }
147
+ }
@@ -0,0 +1,56 @@
1
+ import { ParseResultElement } from '@speclynx/apidom-datamodel';
2
+
3
+ /**
4
+ * Default options for parsing Arazzo Documents.
5
+ * @public
6
+ */
7
+ export declare const defaultParseOptions: Required<ParseOptions>;
8
+
9
+ /**
10
+ * Parses an Arazzo Document from an object.
11
+ * @param source - The Arazzo Document as a plain object
12
+ * @param options - Parsing options
13
+ * @returns A promise that resolves to the parsed Arazzo Document as ApiDOM data model
14
+ * @public
15
+ */
16
+ export declare function parse(source: Record<string, unknown>, options?: ParseOptions): Promise<ParseResultElement>;
17
+
18
+ /**
19
+ * Parses an Arazzo Document from a string or URI.
20
+ * @param source - The Arazzo Document as string content, or a file system path / HTTP(S) URL
21
+ * @param options - Parsing options
22
+ * @returns A promise that resolves to the parsed Arazzo Document as ApiDOM data model
23
+ * @throws ParseError - When parsing fails for any reason. The original error is available via the `cause` property.
24
+ * @public
25
+ */
26
+ export declare function parse(source: string, options?: ParseOptions): Promise<ParseResultElement>;
27
+
28
+ /**
29
+ * Options for parsing Arazzo Documents.
30
+ * @public
31
+ */
32
+ export declare interface ParseOptions {
33
+ /**
34
+ * Whether to enforce strict parsing mode.
35
+ * Strict parsing mode is using native JSON and YAML parsers without source maps and error recovery.
36
+ * @defaultValue true
37
+ */
38
+ readonly strict?: boolean;
39
+ /**
40
+ * Whether to include source maps in the parsed result.
41
+ * @defaultValue false
42
+ */
43
+ readonly sourceMap?: boolean;
44
+ /**
45
+ * Additional options passed to the underlying parsers.
46
+ * @defaultValue \{\}
47
+ */
48
+ readonly parserOpts?: Record<string, unknown>;
49
+ /**
50
+ * Additional options passed to the underlying resolvers.
51
+ * @defaultValue \{\}
52
+ */
53
+ readonly resolverOpts?: Record<string, unknown>;
54
+ }
55
+
56
+ export { }