@usearazzo/parser 1.0.1-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/LICENSE +202 -0
- package/NOTICE +20 -0
- package/README.md +716 -0
- package/dist/arazzo-parser.browser.js +83807 -0
- package/dist/arazzo-parser.browser.min.js +1 -0
- package/package.json +86 -0
- package/src/errors/ParseError.cjs +18 -0
- package/src/errors/ParseError.mjs +13 -0
- package/src/index.cjs +77 -0
- package/src/index.mjs +5 -0
- package/src/options/util.cjs +30 -0
- package/src/options/util.mjs +23 -0
- package/src/parse-arazzo.cjs +209 -0
- package/src/parse-arazzo.mjs +200 -0
- package/src/parse-criterion-condition.cjs +82 -0
- package/src/parse-criterion-condition.mjs +71 -0
- package/src/parse-openapi.cjs +210 -0
- package/src/parse-openapi.mjs +201 -0
- package/src/parse-runtime-expression.cjs +84 -0
- package/src/parse-runtime-expression.mjs +73 -0
- package/src/resolve/resolvers/memory/index.cjs +52 -0
- package/src/resolve/resolvers/memory/index.mjs +47 -0
- package/types/parser.d.ts +260 -0
package/package.json
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@usearazzo/parser",
|
|
3
|
+
"version": "1.0.1-alpha.0",
|
|
4
|
+
"description": "Parser for the Arazzo Specification language: documents, runtime expressions, and criterion conditions.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"arazzo",
|
|
7
|
+
"arazzo-specification",
|
|
8
|
+
"parser",
|
|
9
|
+
"datamodel",
|
|
10
|
+
"workflow",
|
|
11
|
+
"workflows",
|
|
12
|
+
"runtime-expression",
|
|
13
|
+
"criterion"
|
|
14
|
+
],
|
|
15
|
+
"publishConfig": {
|
|
16
|
+
"access": "public",
|
|
17
|
+
"registry": "https://registry.npmjs.org",
|
|
18
|
+
"provenance": false,
|
|
19
|
+
"tag": "latest"
|
|
20
|
+
},
|
|
21
|
+
"type": "module",
|
|
22
|
+
"sideEffects": false,
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=20.10.0"
|
|
25
|
+
},
|
|
26
|
+
"unpkg": "./dist/arazzo-parser.browser.min.js",
|
|
27
|
+
"main": "./src/index.cjs",
|
|
28
|
+
"exports": {
|
|
29
|
+
"types": "./types/parser.d.ts",
|
|
30
|
+
"import": "./src/index.mjs",
|
|
31
|
+
"require": "./src/index.cjs"
|
|
32
|
+
},
|
|
33
|
+
"types": "./types/parser.d.ts",
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "npm run clean && run-p --max-parallel ${CPU_CORES:-2} typescript:declaration build:es build:cjs build:umd:browser",
|
|
36
|
+
"build:es": "cross-env BABEL_ENV=es babel src --out-dir src --extensions '.ts' --out-file-extension '.mjs' --root-mode 'upward'",
|
|
37
|
+
"build:cjs": "cross-env BABEL_ENV=cjs babel src --out-dir src --extensions '.ts' --out-file-extension '.cjs' --root-mode 'upward'",
|
|
38
|
+
"build:umd:browser": "cross-env BABEL_ENV=browser webpack --config config/webpack/browser.config.js --progress",
|
|
39
|
+
"lint": "eslint ./",
|
|
40
|
+
"lint:fix": "eslint ./ --fix",
|
|
41
|
+
"clean": "rimraf --glob 'src/**/*.mjs' 'src/**/*.cjs' 'test/**/*.mjs' ./dist ./types",
|
|
42
|
+
"typescript:check-types": "tsc --noEmit",
|
|
43
|
+
"typescript:declaration": "tsc -p tsconfig.declaration.json && api-extractor run -l -c ./config/api-extractor/api-extractor.json",
|
|
44
|
+
"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",
|
|
45
|
+
"prepack": "copyfiles -u 2 ../../LICENSE . && copyfiles -u 2 ../../NOTICE .",
|
|
46
|
+
"postpack": "rimraf NOTICE LICENSE"
|
|
47
|
+
},
|
|
48
|
+
"repository": {
|
|
49
|
+
"type": "git",
|
|
50
|
+
"url": "git+https://github.com/usearazzo/arazzo-toolkit.git"
|
|
51
|
+
},
|
|
52
|
+
"author": "Vladimir Gorej <vladimir.gorej@gmail.com>",
|
|
53
|
+
"license": "Apache-2.0",
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"@babel/runtime-corejs3": "^8.0.0",
|
|
56
|
+
"@speclynx/apidom-datamodel": "^5.2.2",
|
|
57
|
+
"@speclynx/apidom-error": "^5.2.2",
|
|
58
|
+
"@speclynx/apidom-ns-arazzo-1": "^5.2.2",
|
|
59
|
+
"@speclynx/apidom-parser-adapter-arazzo-json-1": "^5.2.2",
|
|
60
|
+
"@speclynx/apidom-parser-adapter-arazzo-yaml-1": "^5.2.2",
|
|
61
|
+
"@speclynx/apidom-parser-adapter-openapi-json-2": "^5.2.2",
|
|
62
|
+
"@speclynx/apidom-parser-adapter-openapi-json-3-0": "^5.2.2",
|
|
63
|
+
"@speclynx/apidom-parser-adapter-openapi-json-3-1": "^5.2.2",
|
|
64
|
+
"@speclynx/apidom-parser-adapter-openapi-yaml-2": "^5.2.2",
|
|
65
|
+
"@speclynx/apidom-parser-adapter-openapi-yaml-3-0": "^5.2.2",
|
|
66
|
+
"@speclynx/apidom-parser-adapter-openapi-yaml-3-1": "^5.2.2",
|
|
67
|
+
"@speclynx/apidom-reference": "^5.2.2",
|
|
68
|
+
"@swaggerexpert/arazzo-criterion": "^1.0.1",
|
|
69
|
+
"@swaggerexpert/arazzo-runtime-expression": "^3.2.0",
|
|
70
|
+
"ramda-adjunct": "^6.0.0",
|
|
71
|
+
"type-fest": "^5.4.4"
|
|
72
|
+
},
|
|
73
|
+
"devDependencies": {
|
|
74
|
+
"@speclynx/apidom-core": "^5.2.2"
|
|
75
|
+
},
|
|
76
|
+
"files": [
|
|
77
|
+
"src/**/*.mjs",
|
|
78
|
+
"src/**/*.cjs",
|
|
79
|
+
"dist/",
|
|
80
|
+
"types/parser.d.ts",
|
|
81
|
+
"LICENSE",
|
|
82
|
+
"NOTICE",
|
|
83
|
+
"README.md",
|
|
84
|
+
"CHANGELOG.md"
|
|
85
|
+
]
|
|
86
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _apidomError = require("@speclynx/apidom-error");
|
|
8
|
+
/**
|
|
9
|
+
* Error thrown by `parseArazzo` and `parseOpenAPI` when parsing fails for any
|
|
10
|
+
* reason. The original error is available via the `cause` property.
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
class ParseError extends _apidomError.ApiDOMError {
|
|
14
|
+
constructor(message, options) {
|
|
15
|
+
super(message, options);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
var _default = exports.default = ParseError;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ApiDOMError } from '@speclynx/apidom-error';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Error thrown by `parseArazzo` and `parseOpenAPI` when parsing fails for any
|
|
5
|
+
* reason. The original error is available via the `cause` property.
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
class ParseError extends ApiDOMError {
|
|
9
|
+
constructor(message, options) {
|
|
10
|
+
super(message, options);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export default ParseError;
|
package/src/index.cjs
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
Object.defineProperty(exports, "ArazzoCriterionParseError", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function () {
|
|
10
|
+
return _parseCriterionCondition.ArazzoCriterionParseError;
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
Object.defineProperty(exports, "ArazzoRuntimeExpressionParseError", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function () {
|
|
16
|
+
return _parseRuntimeExpression.ArazzoRuntimeExpressionParseError;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports, "ParseError", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function () {
|
|
22
|
+
return _ParseError.default;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
Object.defineProperty(exports, "defaultParseArazzoOptions", {
|
|
26
|
+
enumerable: true,
|
|
27
|
+
get: function () {
|
|
28
|
+
return _parseArazzo.defaultOptions;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
Object.defineProperty(exports, "defaultParseCriterionConditionOptions", {
|
|
32
|
+
enumerable: true,
|
|
33
|
+
get: function () {
|
|
34
|
+
return _parseCriterionCondition.defaultOptions;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
Object.defineProperty(exports, "defaultParseOpenAPIOptions", {
|
|
38
|
+
enumerable: true,
|
|
39
|
+
get: function () {
|
|
40
|
+
return _parseOpenapi.defaultOptions;
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
Object.defineProperty(exports, "defaultParseRuntimeExpressionOptions", {
|
|
44
|
+
enumerable: true,
|
|
45
|
+
get: function () {
|
|
46
|
+
return _parseRuntimeExpression.defaultOptions;
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
Object.defineProperty(exports, "parseArazzo", {
|
|
50
|
+
enumerable: true,
|
|
51
|
+
get: function () {
|
|
52
|
+
return _parseArazzo.parse;
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
Object.defineProperty(exports, "parseCriterionCondition", {
|
|
56
|
+
enumerable: true,
|
|
57
|
+
get: function () {
|
|
58
|
+
return _parseCriterionCondition.parse;
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
Object.defineProperty(exports, "parseOpenAPI", {
|
|
62
|
+
enumerable: true,
|
|
63
|
+
get: function () {
|
|
64
|
+
return _parseOpenapi.parse;
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
Object.defineProperty(exports, "parseRuntimeExpression", {
|
|
68
|
+
enumerable: true,
|
|
69
|
+
get: function () {
|
|
70
|
+
return _parseRuntimeExpression.parse;
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
var _ParseError = _interopRequireDefault(require("./errors/ParseError.cjs"));
|
|
74
|
+
var _parseArazzo = require("./parse-arazzo.cjs");
|
|
75
|
+
var _parseOpenapi = require("./parse-openapi.cjs");
|
|
76
|
+
var _parseRuntimeExpression = require("./parse-runtime-expression.cjs");
|
|
77
|
+
var _parseCriterionCondition = require("./parse-criterion-condition.cjs");
|
package/src/index.mjs
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { default as ParseError } from "./errors/ParseError.mjs";
|
|
2
|
+
export { parse as parseArazzo, defaultOptions as defaultParseArazzoOptions } from "./parse-arazzo.mjs";
|
|
3
|
+
export { parse as parseOpenAPI, defaultOptions as defaultParseOpenAPIOptions } from "./parse-openapi.mjs";
|
|
4
|
+
export { parse as parseRuntimeExpression, defaultOptions as defaultParseRuntimeExpressionOptions, ArazzoRuntimeExpressionParseError } from "./parse-runtime-expression.mjs";
|
|
5
|
+
export { parse as parseCriterionCondition, defaultOptions as defaultParseCriterionConditionOptions, ArazzoCriterionParseError } from "./parse-criterion-condition.mjs";
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.mergeOptions = void 0;
|
|
7
|
+
var _empty = require("@speclynx/apidom-reference/configuration/empty");
|
|
8
|
+
const isMemoryResolver = resolver => resolver.name === 'memory';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Merges reference options the same way apidom-reference does, additionally keeping
|
|
12
|
+
* memory resolvers ahead of every other resolver: they serve in-memory documents and
|
|
13
|
+
* must win over any resolver that could read the same URI from disk or network.
|
|
14
|
+
*/
|
|
15
|
+
const mergeOptions = (target, source) => {
|
|
16
|
+
const merged = (0, _empty.mergeOptions)(target, source);
|
|
17
|
+
const {
|
|
18
|
+
resolvers
|
|
19
|
+
} = merged.resolve;
|
|
20
|
+
const memoryResolvers = resolvers.filter(isMemoryResolver);
|
|
21
|
+
if (memoryResolvers.length === 0) return merged;
|
|
22
|
+
return {
|
|
23
|
+
...merged,
|
|
24
|
+
resolve: {
|
|
25
|
+
...merged.resolve,
|
|
26
|
+
resolvers: [...memoryResolvers, ...resolvers.filter(r => !isMemoryResolver(r))]
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
exports.mergeOptions = mergeOptions;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { mergeOptions as mergeReferenceOptions } from '@speclynx/apidom-reference/configuration/empty';
|
|
2
|
+
const isMemoryResolver = resolver => resolver.name === 'memory';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Merges reference options the same way apidom-reference does, additionally keeping
|
|
6
|
+
* memory resolvers ahead of every other resolver: they serve in-memory documents and
|
|
7
|
+
* must win over any resolver that could read the same URI from disk or network.
|
|
8
|
+
*/
|
|
9
|
+
export const mergeOptions = (target, source) => {
|
|
10
|
+
const merged = mergeReferenceOptions(target, source);
|
|
11
|
+
const {
|
|
12
|
+
resolvers
|
|
13
|
+
} = merged.resolve;
|
|
14
|
+
const memoryResolvers = resolvers.filter(isMemoryResolver);
|
|
15
|
+
if (memoryResolvers.length === 0) return merged;
|
|
16
|
+
return {
|
|
17
|
+
...merged,
|
|
18
|
+
resolve: {
|
|
19
|
+
...merged.resolve,
|
|
20
|
+
resolvers: [...memoryResolvers, ...resolvers.filter(r => !isMemoryResolver(r))]
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
};
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.defaultOptions = void 0;
|
|
8
|
+
exports.parse = parse;
|
|
9
|
+
var _empty = require("@speclynx/apidom-reference/configuration/empty");
|
|
10
|
+
var _arazzoJson = _interopRequireDefault(require("@speclynx/apidom-reference/parse/parsers/arazzo-json-1"));
|
|
11
|
+
var _arazzoYaml = _interopRequireDefault(require("@speclynx/apidom-reference/parse/parsers/arazzo-yaml-1"));
|
|
12
|
+
var _openapiJson = _interopRequireDefault(require("@speclynx/apidom-reference/parse/parsers/openapi-json-2"));
|
|
13
|
+
var _openapiYaml = _interopRequireDefault(require("@speclynx/apidom-reference/parse/parsers/openapi-yaml-2"));
|
|
14
|
+
var _openapiJson2 = _interopRequireDefault(require("@speclynx/apidom-reference/parse/parsers/openapi-json-3-0"));
|
|
15
|
+
var _openapiYaml2 = _interopRequireDefault(require("@speclynx/apidom-reference/parse/parsers/openapi-yaml-3-0"));
|
|
16
|
+
var _openapiJson3 = _interopRequireDefault(require("@speclynx/apidom-reference/parse/parsers/openapi-json-3-1"));
|
|
17
|
+
var _openapiYaml3 = _interopRequireDefault(require("@speclynx/apidom-reference/parse/parsers/openapi-yaml-3-1"));
|
|
18
|
+
var _file = _interopRequireDefault(require("@speclynx/apidom-reference/resolve/resolvers/file"));
|
|
19
|
+
var _httpAxios = _interopRequireDefault(require("@speclynx/apidom-reference/resolve/resolvers/http-axios"));
|
|
20
|
+
var _apidomParserAdapterArazzoJson = require("@speclynx/apidom-parser-adapter-arazzo-json-1");
|
|
21
|
+
var _apidomNsArazzo = require("@speclynx/apidom-ns-arazzo-1");
|
|
22
|
+
var _apidomParserAdapterArazzoYaml = require("@speclynx/apidom-parser-adapter-arazzo-yaml-1");
|
|
23
|
+
var _ramdaAdjunct = require("ramda-adjunct");
|
|
24
|
+
var _ParseError = _interopRequireDefault(require("./errors/ParseError.cjs"));
|
|
25
|
+
var _util = require("./options/util.cjs");
|
|
26
|
+
var _index = _interopRequireDefault(require("./resolve/resolvers/memory/index.cjs"));
|
|
27
|
+
/**
|
|
28
|
+
* Options for parsing Arazzo Documents.
|
|
29
|
+
* @public
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Default reference options for parsing Arazzo Documents.
|
|
34
|
+
* @public
|
|
35
|
+
*/
|
|
36
|
+
const defaultOptions = exports.defaultOptions = {
|
|
37
|
+
parse: {
|
|
38
|
+
parsers: [new _arazzoJson.default({
|
|
39
|
+
allowEmpty: false
|
|
40
|
+
}), new _arazzoYaml.default({
|
|
41
|
+
allowEmpty: false
|
|
42
|
+
}), new _openapiJson.default({
|
|
43
|
+
allowEmpty: false
|
|
44
|
+
}), new _openapiYaml.default({
|
|
45
|
+
allowEmpty: false
|
|
46
|
+
}), new _openapiJson2.default({
|
|
47
|
+
allowEmpty: false
|
|
48
|
+
}), new _openapiYaml2.default({
|
|
49
|
+
allowEmpty: false
|
|
50
|
+
}), new _openapiJson3.default({
|
|
51
|
+
allowEmpty: false
|
|
52
|
+
}), new _openapiYaml3.default({
|
|
53
|
+
allowEmpty: false
|
|
54
|
+
})],
|
|
55
|
+
parserOpts: {
|
|
56
|
+
sourceMap: false,
|
|
57
|
+
style: false,
|
|
58
|
+
strict: true,
|
|
59
|
+
sourceDescriptions: false
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
resolve: {
|
|
63
|
+
resolvers: [
|
|
64
|
+
// regex patterns, not glob strings - picomatch's glob matching never
|
|
65
|
+
// matches a dotfile basename (e.g. .arazzo.yaml) without `dot: true`,
|
|
66
|
+
// which FileResolver does not set.
|
|
67
|
+
new _file.default({
|
|
68
|
+
fileAllowList: [/\.json$/i, /\.ya?ml$/i]
|
|
69
|
+
}), new _httpAxios.default({
|
|
70
|
+
timeout: 15000,
|
|
71
|
+
redirects: 5,
|
|
72
|
+
withCredentials: false
|
|
73
|
+
})],
|
|
74
|
+
resolverOpts: {}
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Parses an Arazzo Document from an object.
|
|
80
|
+
* @param source - The Arazzo Document as a plain object
|
|
81
|
+
* @param options - Reference options (uses defaultOptions when not provided)
|
|
82
|
+
* @returns A promise that resolves to the parsed Arazzo Document as ApiDOM data model
|
|
83
|
+
* @throws ParseError - When parsing fails for any reason. The original error is available via the `cause` property.
|
|
84
|
+
* @public
|
|
85
|
+
*/
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Parses an Arazzo Document from a string or URI.
|
|
89
|
+
* @param source - The Arazzo Document as string content, or a file system path / HTTP(S) URL
|
|
90
|
+
* @param options - Reference options (uses defaultOptions when not provided)
|
|
91
|
+
* @returns A promise that resolves to the parsed Arazzo Document as ApiDOM data model
|
|
92
|
+
* @throws ParseError - When parsing fails for any reason. The original error is available via the `cause` property.
|
|
93
|
+
* @public
|
|
94
|
+
*/
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Parses an Arazzo Document from a string, object, or URI.
|
|
98
|
+
* @param source - The Arazzo Document as a plain object, string content, or URI
|
|
99
|
+
* @param options - Reference options (uses defaultOptions when not provided)
|
|
100
|
+
* @returns A promise that resolves to the parsed Arazzo Document as ApiDOM data model
|
|
101
|
+
* @throws ParseError - When parsing fails for any reason. The original error is available via the `cause` property.
|
|
102
|
+
* @public
|
|
103
|
+
*/
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Parses an Arazzo Document from a string, object, or URI.
|
|
107
|
+
*
|
|
108
|
+
* The function handles three types of input:
|
|
109
|
+
* 1. Object - converts to JSON string and parses (source maps supported with `strict: false`)
|
|
110
|
+
* 2. String content - uses Arazzo detection to identify and parse inline JSON or YAML content
|
|
111
|
+
* 3. URI string - if not detected as Arazzo content, treats as file system path or HTTP(S) URL
|
|
112
|
+
*
|
|
113
|
+
* @param source - The Arazzo Document as an object, string content, or a file system path / HTTP(S) URL
|
|
114
|
+
* @param options - Reference options (uses defaultOptions when not provided)
|
|
115
|
+
* @returns A promise that resolves to the parsed Arazzo Document as ApiDOM data model
|
|
116
|
+
* @throws ParseError - When parsing fails for any reason. The original error is available via the `cause` property.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* Parse from object
|
|
120
|
+
* ```typescript
|
|
121
|
+
* const result = await parseArazzo({ arazzo: '1.0.1', info: {...} });
|
|
122
|
+
* ```
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* Parse inline JSON
|
|
126
|
+
* ```typescript
|
|
127
|
+
* const result = await parseArazzo('{"arazzo": "1.0.1", "info": {...}}');
|
|
128
|
+
* ```
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* Parse from file
|
|
132
|
+
* ```typescript
|
|
133
|
+
* const result = await parseArazzo('/path/to/arazzo.json');
|
|
134
|
+
* ```
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* Parse from URL
|
|
138
|
+
* ```typescript
|
|
139
|
+
* const result = await parseArazzo('https://example.com/arazzo.yaml');
|
|
140
|
+
* ```
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* Parse with custom options
|
|
144
|
+
* ```typescript
|
|
145
|
+
* const result = await parseArazzo('/path/to/arazzo.json', customOptions);
|
|
146
|
+
* ```
|
|
147
|
+
* @public
|
|
148
|
+
*/
|
|
149
|
+
async function parse(source, options = {}) {
|
|
150
|
+
let mergedOptions = (0, _util.mergeOptions)(defaultOptions, options);
|
|
151
|
+
const strict = mergedOptions.parse?.parserOpts?.strict ?? true;
|
|
152
|
+
let sourceProvenance;
|
|
153
|
+
let document;
|
|
154
|
+
if ((0, _ramdaAdjunct.isPlainObject)(source)) {
|
|
155
|
+
document = JSON.stringify(source, null, 2);
|
|
156
|
+
source = 'memory://arazzo.json';
|
|
157
|
+
sourceProvenance = '[object]';
|
|
158
|
+
} else if (await (0, _apidomParserAdapterArazzoJson.detect)(source, {
|
|
159
|
+
strict
|
|
160
|
+
})) {
|
|
161
|
+
document = source;
|
|
162
|
+
source = 'memory://arazzo.json';
|
|
163
|
+
sourceProvenance = '[inline JSON]';
|
|
164
|
+
} else if (await (0, _apidomParserAdapterArazzoYaml.detect)(source, {
|
|
165
|
+
strict
|
|
166
|
+
})) {
|
|
167
|
+
document = source;
|
|
168
|
+
source = 'memory://arazzo.yaml';
|
|
169
|
+
sourceProvenance = '[inline YAML]';
|
|
170
|
+
} else {
|
|
171
|
+
sourceProvenance = _empty.url.isHttpUrl(source) || _empty.url.getProtocol(source) === 'file' || _empty.url.isURI(`file://${source}`) ? source : '[inline CONTENT]';
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// in-memory documents are served under their synthetic memory:// URI, or under the
|
|
175
|
+
// caller-supplied base URI so that relative source description URLs resolve against
|
|
176
|
+
// a real location
|
|
177
|
+
if (document !== undefined) {
|
|
178
|
+
// raw options, not merged: mergeOptions defaults baseURI to the current working directory
|
|
179
|
+
source = options.resolve?.baseURI || source;
|
|
180
|
+
mergedOptions = (0, _util.mergeOptions)(mergedOptions, {
|
|
181
|
+
resolve: {
|
|
182
|
+
resolvers: [...mergedOptions.resolve.resolvers, new _index.default({
|
|
183
|
+
document,
|
|
184
|
+
uri: source
|
|
185
|
+
})]
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// next we assume that source is either file system URI or HTTP(S) URL
|
|
191
|
+
try {
|
|
192
|
+
const parseResult = await (0, _empty.parse)(source, mergedOptions);
|
|
193
|
+
|
|
194
|
+
// set retrievalURI metadata for file/URL sources (not for inline content)
|
|
195
|
+
if (!source.startsWith('memory://')) {
|
|
196
|
+
parseResult.meta.set('retrievalURI', source);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// validate that the parsed document is an Arazzo specification
|
|
200
|
+
if (!(0, _apidomNsArazzo.isArazzoSpecification1Element)(parseResult.api)) {
|
|
201
|
+
throw new _empty.UnmatchedParserError(`Could not find a parser that can parse "${sourceProvenance}" as an Arazzo specification`);
|
|
202
|
+
}
|
|
203
|
+
return parseResult;
|
|
204
|
+
} catch (error) {
|
|
205
|
+
throw new _ParseError.default(`Failed to parse Arazzo Document from "${sourceProvenance}"`, {
|
|
206
|
+
cause: error
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { url, parse as parseURI, UnmatchedParserError } from '@speclynx/apidom-reference/configuration/empty';
|
|
2
|
+
import ArazzoJSON1Parser from '@speclynx/apidom-reference/parse/parsers/arazzo-json-1';
|
|
3
|
+
import ArazzoYAML1Parser from '@speclynx/apidom-reference/parse/parsers/arazzo-yaml-1';
|
|
4
|
+
import OpenApiJSON2Parser from '@speclynx/apidom-reference/parse/parsers/openapi-json-2';
|
|
5
|
+
import OpenApiYAML2Parser from '@speclynx/apidom-reference/parse/parsers/openapi-yaml-2';
|
|
6
|
+
import OpenApiJSON3_0Parser from '@speclynx/apidom-reference/parse/parsers/openapi-json-3-0';
|
|
7
|
+
import OpenApiYAML3_0Parser from '@speclynx/apidom-reference/parse/parsers/openapi-yaml-3-0';
|
|
8
|
+
import OpenApiJSON3_1Parser from '@speclynx/apidom-reference/parse/parsers/openapi-json-3-1';
|
|
9
|
+
import OpenApiYAML3_1Parser from '@speclynx/apidom-reference/parse/parsers/openapi-yaml-3-1';
|
|
10
|
+
import FileResolver from '@speclynx/apidom-reference/resolve/resolvers/file';
|
|
11
|
+
import HTTPResolverAxios from '@speclynx/apidom-reference/resolve/resolvers/http-axios';
|
|
12
|
+
import { detect as detectArazzoJSON } from '@speclynx/apidom-parser-adapter-arazzo-json-1';
|
|
13
|
+
import { isArazzoSpecification1Element } from '@speclynx/apidom-ns-arazzo-1';
|
|
14
|
+
import { detect as detectArazzoYAML } from '@speclynx/apidom-parser-adapter-arazzo-yaml-1';
|
|
15
|
+
import { isPlainObject } from 'ramda-adjunct';
|
|
16
|
+
import ParseError from "./errors/ParseError.mjs";
|
|
17
|
+
import { mergeOptions } from "./options/util.mjs";
|
|
18
|
+
import MemoryResolver from "./resolve/resolvers/memory/index.mjs";
|
|
19
|
+
/**
|
|
20
|
+
* Options for parsing Arazzo Documents.
|
|
21
|
+
* @public
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Default reference options for parsing Arazzo Documents.
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
export const defaultOptions = {
|
|
28
|
+
parse: {
|
|
29
|
+
parsers: [new ArazzoJSON1Parser({
|
|
30
|
+
allowEmpty: false
|
|
31
|
+
}), new ArazzoYAML1Parser({
|
|
32
|
+
allowEmpty: false
|
|
33
|
+
}), new OpenApiJSON2Parser({
|
|
34
|
+
allowEmpty: false
|
|
35
|
+
}), new OpenApiYAML2Parser({
|
|
36
|
+
allowEmpty: false
|
|
37
|
+
}), new OpenApiJSON3_0Parser({
|
|
38
|
+
allowEmpty: false
|
|
39
|
+
}), new OpenApiYAML3_0Parser({
|
|
40
|
+
allowEmpty: false
|
|
41
|
+
}), new OpenApiJSON3_1Parser({
|
|
42
|
+
allowEmpty: false
|
|
43
|
+
}), new OpenApiYAML3_1Parser({
|
|
44
|
+
allowEmpty: false
|
|
45
|
+
})],
|
|
46
|
+
parserOpts: {
|
|
47
|
+
sourceMap: false,
|
|
48
|
+
style: false,
|
|
49
|
+
strict: true,
|
|
50
|
+
sourceDescriptions: false
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
resolve: {
|
|
54
|
+
resolvers: [
|
|
55
|
+
// regex patterns, not glob strings - picomatch's glob matching never
|
|
56
|
+
// matches a dotfile basename (e.g. .arazzo.yaml) without `dot: true`,
|
|
57
|
+
// which FileResolver does not set.
|
|
58
|
+
new FileResolver({
|
|
59
|
+
fileAllowList: [/\.json$/i, /\.ya?ml$/i]
|
|
60
|
+
}), new HTTPResolverAxios({
|
|
61
|
+
timeout: 15000,
|
|
62
|
+
redirects: 5,
|
|
63
|
+
withCredentials: false
|
|
64
|
+
})],
|
|
65
|
+
resolverOpts: {}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Parses an Arazzo Document from an object.
|
|
71
|
+
* @param source - The Arazzo Document as a plain object
|
|
72
|
+
* @param options - Reference options (uses defaultOptions when not provided)
|
|
73
|
+
* @returns A promise that resolves to the parsed Arazzo Document as ApiDOM data model
|
|
74
|
+
* @throws ParseError - When parsing fails for any reason. The original error is available via the `cause` property.
|
|
75
|
+
* @public
|
|
76
|
+
*/
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Parses an Arazzo Document from a string or URI.
|
|
80
|
+
* @param source - The Arazzo Document as string content, or a file system path / HTTP(S) URL
|
|
81
|
+
* @param options - Reference options (uses defaultOptions when not provided)
|
|
82
|
+
* @returns A promise that resolves to the parsed Arazzo Document as ApiDOM data model
|
|
83
|
+
* @throws ParseError - When parsing fails for any reason. The original error is available via the `cause` property.
|
|
84
|
+
* @public
|
|
85
|
+
*/
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Parses an Arazzo Document from a string, object, or URI.
|
|
89
|
+
* @param source - The Arazzo Document as a plain object, string content, or URI
|
|
90
|
+
* @param options - Reference options (uses defaultOptions when not provided)
|
|
91
|
+
* @returns A promise that resolves to the parsed Arazzo Document as ApiDOM data model
|
|
92
|
+
* @throws ParseError - When parsing fails for any reason. The original error is available via the `cause` property.
|
|
93
|
+
* @public
|
|
94
|
+
*/
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Parses an Arazzo Document from a string, object, or URI.
|
|
98
|
+
*
|
|
99
|
+
* The function handles three types of input:
|
|
100
|
+
* 1. Object - converts to JSON string and parses (source maps supported with `strict: false`)
|
|
101
|
+
* 2. String content - uses Arazzo detection to identify and parse inline JSON or YAML content
|
|
102
|
+
* 3. URI string - if not detected as Arazzo content, treats as file system path or HTTP(S) URL
|
|
103
|
+
*
|
|
104
|
+
* @param source - The Arazzo Document as an object, string content, or a file system path / HTTP(S) URL
|
|
105
|
+
* @param options - Reference options (uses defaultOptions when not provided)
|
|
106
|
+
* @returns A promise that resolves to the parsed Arazzo Document as ApiDOM data model
|
|
107
|
+
* @throws ParseError - When parsing fails for any reason. The original error is available via the `cause` property.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* Parse from object
|
|
111
|
+
* ```typescript
|
|
112
|
+
* const result = await parseArazzo({ arazzo: '1.0.1', info: {...} });
|
|
113
|
+
* ```
|
|
114
|
+
*
|
|
115
|
+
* @example
|
|
116
|
+
* Parse inline JSON
|
|
117
|
+
* ```typescript
|
|
118
|
+
* const result = await parseArazzo('{"arazzo": "1.0.1", "info": {...}}');
|
|
119
|
+
* ```
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* Parse from file
|
|
123
|
+
* ```typescript
|
|
124
|
+
* const result = await parseArazzo('/path/to/arazzo.json');
|
|
125
|
+
* ```
|
|
126
|
+
*
|
|
127
|
+
* @example
|
|
128
|
+
* Parse from URL
|
|
129
|
+
* ```typescript
|
|
130
|
+
* const result = await parseArazzo('https://example.com/arazzo.yaml');
|
|
131
|
+
* ```
|
|
132
|
+
*
|
|
133
|
+
* @example
|
|
134
|
+
* Parse with custom options
|
|
135
|
+
* ```typescript
|
|
136
|
+
* const result = await parseArazzo('/path/to/arazzo.json', customOptions);
|
|
137
|
+
* ```
|
|
138
|
+
* @public
|
|
139
|
+
*/
|
|
140
|
+
export async function parse(source, options = {}) {
|
|
141
|
+
let mergedOptions = mergeOptions(defaultOptions, options);
|
|
142
|
+
const strict = mergedOptions.parse?.parserOpts?.strict ?? true;
|
|
143
|
+
let sourceProvenance;
|
|
144
|
+
let document;
|
|
145
|
+
if (isPlainObject(source)) {
|
|
146
|
+
document = JSON.stringify(source, null, 2);
|
|
147
|
+
source = 'memory://arazzo.json';
|
|
148
|
+
sourceProvenance = '[object]';
|
|
149
|
+
} else if (await detectArazzoJSON(source, {
|
|
150
|
+
strict
|
|
151
|
+
})) {
|
|
152
|
+
document = source;
|
|
153
|
+
source = 'memory://arazzo.json';
|
|
154
|
+
sourceProvenance = '[inline JSON]';
|
|
155
|
+
} else if (await detectArazzoYAML(source, {
|
|
156
|
+
strict
|
|
157
|
+
})) {
|
|
158
|
+
document = source;
|
|
159
|
+
source = 'memory://arazzo.yaml';
|
|
160
|
+
sourceProvenance = '[inline YAML]';
|
|
161
|
+
} else {
|
|
162
|
+
sourceProvenance = url.isHttpUrl(source) || url.getProtocol(source) === 'file' || url.isURI(`file://${source}`) ? source : '[inline CONTENT]';
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// in-memory documents are served under their synthetic memory:// URI, or under the
|
|
166
|
+
// caller-supplied base URI so that relative source description URLs resolve against
|
|
167
|
+
// a real location
|
|
168
|
+
if (document !== undefined) {
|
|
169
|
+
// raw options, not merged: mergeOptions defaults baseURI to the current working directory
|
|
170
|
+
source = options.resolve?.baseURI || source;
|
|
171
|
+
mergedOptions = mergeOptions(mergedOptions, {
|
|
172
|
+
resolve: {
|
|
173
|
+
resolvers: [...mergedOptions.resolve.resolvers, new MemoryResolver({
|
|
174
|
+
document,
|
|
175
|
+
uri: source
|
|
176
|
+
})]
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// next we assume that source is either file system URI or HTTP(S) URL
|
|
182
|
+
try {
|
|
183
|
+
const parseResult = await parseURI(source, mergedOptions);
|
|
184
|
+
|
|
185
|
+
// set retrievalURI metadata for file/URL sources (not for inline content)
|
|
186
|
+
if (!source.startsWith('memory://')) {
|
|
187
|
+
parseResult.meta.set('retrievalURI', source);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// validate that the parsed document is an Arazzo specification
|
|
191
|
+
if (!isArazzoSpecification1Element(parseResult.api)) {
|
|
192
|
+
throw new UnmatchedParserError(`Could not find a parser that can parse "${sourceProvenance}" as an Arazzo specification`);
|
|
193
|
+
}
|
|
194
|
+
return parseResult;
|
|
195
|
+
} catch (error) {
|
|
196
|
+
throw new ParseError(`Failed to parse Arazzo Document from "${sourceProvenance}"`, {
|
|
197
|
+
cause: error
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
}
|