@usearazzo/validator 0.0.0-stage → 1.0.1-alpha.5
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 +131 -2
- package/dist/arazzo-validator.browser.js +246374 -0
- package/dist/arazzo-validator.browser.min.js +7 -0
- package/package.json +75 -4
- package/src/document.cjs +39 -0
- package/src/document.mjs +28 -0
- package/src/errors/ValidateError.cjs +19 -0
- package/src/errors/ValidateError.mjs +14 -0
- package/src/index.cjs +77 -0
- package/src/index.mjs +6 -0
- package/src/validators/json-schema-provider.cjs +49 -0
- package/src/validators/json-schema-provider.mjs +42 -0
- package/src/validators/validate-uri.cjs +118 -0
- package/src/validators/validate-uri.mjs +110 -0
- package/src/validators/validate.cjs +121 -0
- package/src/validators/validate.mjs +114 -0
- package/types/validator.d.ts +170 -0
package/package.json
CHANGED
|
@@ -1,6 +1,77 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@usearazzo/validator",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.1-alpha.5",
|
|
4
|
+
"description": "Validator and linter for Arazzo documents: semantic validation, semantic linting, and opt-in JSON Schema validation.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"arazzo",
|
|
7
|
+
"arazzo-specification",
|
|
8
|
+
"validator",
|
|
9
|
+
"validation",
|
|
10
|
+
"linter",
|
|
11
|
+
"linting",
|
|
12
|
+
"workflow",
|
|
13
|
+
"workflows"
|
|
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-validator.browser.min.js",
|
|
27
|
+
"main": "./src/index.cjs",
|
|
28
|
+
"exports": {
|
|
29
|
+
"types": "./types/validator.d.ts",
|
|
30
|
+
"import": "./src/index.mjs",
|
|
31
|
+
"require": "./src/index.cjs"
|
|
32
|
+
},
|
|
33
|
+
"types": "./types/validator.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
|
+
"homepage": "https://usearazzo.com/docs/validator/",
|
|
53
|
+
"author": "Vladimir Gorej <vladimir.gorej@gmail.com>",
|
|
54
|
+
"license": "Apache-2.0",
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"@babel/runtime-corejs3": "^8.0.6",
|
|
57
|
+
"@speclynx/api-languageservice": "^2.13.2",
|
|
58
|
+
"@speclynx/apidom-error": "^5.2.6",
|
|
59
|
+
"@speclynx/apidom-ns-arazzo-1": "^5.2.6",
|
|
60
|
+
"@speclynx/apidom-reference": "^5.2.6",
|
|
61
|
+
"@usearazzo/parser": "1.0.1-alpha.5",
|
|
62
|
+
"ramda": "^0.32.0",
|
|
63
|
+
"type-fest": "^5.10.0",
|
|
64
|
+
"vscode-languageserver-textdocument": "^1.0.15",
|
|
65
|
+
"vscode-languageserver-types": "=3.18.3"
|
|
66
|
+
},
|
|
67
|
+
"files": [
|
|
68
|
+
"src/**/*.mjs",
|
|
69
|
+
"src/**/*.cjs",
|
|
70
|
+
"dist/",
|
|
71
|
+
"types/validator.d.ts",
|
|
72
|
+
"LICENSE",
|
|
73
|
+
"NOTICE",
|
|
74
|
+
"README.md",
|
|
75
|
+
"CHANGELOG.md"
|
|
76
|
+
]
|
|
77
|
+
}
|
package/src/document.cjs
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.DEFAULT_DOCUMENT_VERSION = exports.ARAZZO_LANGUAGE_ID = void 0;
|
|
7
|
+
Object.defineProperty(exports, "TextDocument", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function () {
|
|
10
|
+
return _vscodeLanguageserverTextdocument.TextDocument;
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
exports.createTextDocument = createTextDocument;
|
|
14
|
+
var _vscodeLanguageserverTextdocument = require("vscode-languageserver-textdocument");
|
|
15
|
+
/**
|
|
16
|
+
* Language ID for Arazzo documents used with TextDocument.
|
|
17
|
+
*
|
|
18
|
+
* @public
|
|
19
|
+
*/
|
|
20
|
+
const ARAZZO_LANGUAGE_ID = exports.ARAZZO_LANGUAGE_ID = 'apidom';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Default document version for TextDocument instances.
|
|
24
|
+
*
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
const DEFAULT_DOCUMENT_VERSION = exports.DEFAULT_DOCUMENT_VERSION = 1;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Creates a TextDocument for Arazzo validation.
|
|
31
|
+
*
|
|
32
|
+
* @param uri - The document URI
|
|
33
|
+
* @param content - The document content
|
|
34
|
+
* @returns A TextDocument instance
|
|
35
|
+
* @public
|
|
36
|
+
*/
|
|
37
|
+
function createTextDocument(uri, content) {
|
|
38
|
+
return _vscodeLanguageserverTextdocument.TextDocument.create(uri, ARAZZO_LANGUAGE_ID, DEFAULT_DOCUMENT_VERSION, content);
|
|
39
|
+
}
|
package/src/document.mjs
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { TextDocument } from 'vscode-languageserver-textdocument';
|
|
2
|
+
export { TextDocument };
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Language ID for Arazzo documents used with TextDocument.
|
|
6
|
+
*
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
export const ARAZZO_LANGUAGE_ID = 'apidom';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Default document version for TextDocument instances.
|
|
13
|
+
*
|
|
14
|
+
* @public
|
|
15
|
+
*/
|
|
16
|
+
export const DEFAULT_DOCUMENT_VERSION = 1;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Creates a TextDocument for Arazzo validation.
|
|
20
|
+
*
|
|
21
|
+
* @param uri - The document URI
|
|
22
|
+
* @param content - The document content
|
|
23
|
+
* @returns A TextDocument instance
|
|
24
|
+
* @public
|
|
25
|
+
*/
|
|
26
|
+
export function createTextDocument(uri, content) {
|
|
27
|
+
return TextDocument.create(uri, ARAZZO_LANGUAGE_ID, DEFAULT_DOCUMENT_VERSION, content);
|
|
28
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
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 `validateURI` when the document cannot be fetched. Problems
|
|
10
|
+
* found in the document itself are reported as diagnostics, not thrown. The
|
|
11
|
+
* original error is available via the `cause` property.
|
|
12
|
+
* @public
|
|
13
|
+
*/
|
|
14
|
+
class ValidateError extends _apidomError.ApiDOMError {
|
|
15
|
+
constructor(message, options) {
|
|
16
|
+
super(message, options);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
var _default = exports.default = ValidateError;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ApiDOMError } from '@speclynx/apidom-error';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Error thrown by `validateURI` when the document cannot be fetched. Problems
|
|
5
|
+
* found in the document itself are reported as diagnostics, not thrown. The
|
|
6
|
+
* original error is available via the `cause` property.
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
class ValidateError extends ApiDOMError {
|
|
10
|
+
constructor(message, options) {
|
|
11
|
+
super(message, options);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export default ValidateError;
|
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, "ARAZZO_LANGUAGE_ID", {
|
|
8
|
+
enumerable: true,
|
|
9
|
+
get: function () {
|
|
10
|
+
return _document.ARAZZO_LANGUAGE_ID;
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
Object.defineProperty(exports, "DEFAULT_DOCUMENT_VERSION", {
|
|
14
|
+
enumerable: true,
|
|
15
|
+
get: function () {
|
|
16
|
+
return _document.DEFAULT_DOCUMENT_VERSION;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports, "Diagnostic", {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function () {
|
|
22
|
+
return _vscodeLanguageserverTypes.Diagnostic;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
Object.defineProperty(exports, "DiagnosticSeverity", {
|
|
26
|
+
enumerable: true,
|
|
27
|
+
get: function () {
|
|
28
|
+
return _vscodeLanguageserverTypes.DiagnosticSeverity;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
Object.defineProperty(exports, "TextDocument", {
|
|
32
|
+
enumerable: true,
|
|
33
|
+
get: function () {
|
|
34
|
+
return _document.TextDocument;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
Object.defineProperty(exports, "ValidateError", {
|
|
38
|
+
enumerable: true,
|
|
39
|
+
get: function () {
|
|
40
|
+
return _ValidateError.default;
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
Object.defineProperty(exports, "createTextDocument", {
|
|
44
|
+
enumerable: true,
|
|
45
|
+
get: function () {
|
|
46
|
+
return _document.createTextDocument;
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
Object.defineProperty(exports, "defaultArazzoResolveOptions", {
|
|
50
|
+
enumerable: true,
|
|
51
|
+
get: function () {
|
|
52
|
+
return _validateUri.defaultArazzoResolveOptions;
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
Object.defineProperty(exports, "defaultLanguageServiceContext", {
|
|
56
|
+
enumerable: true,
|
|
57
|
+
get: function () {
|
|
58
|
+
return _validate.defaultLanguageServiceContext;
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
Object.defineProperty(exports, "validate", {
|
|
62
|
+
enumerable: true,
|
|
63
|
+
get: function () {
|
|
64
|
+
return _validate.validate;
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
Object.defineProperty(exports, "validateURI", {
|
|
68
|
+
enumerable: true,
|
|
69
|
+
get: function () {
|
|
70
|
+
return _validateUri.validateURI;
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
var _vscodeLanguageserverTypes = require("vscode-languageserver-types");
|
|
74
|
+
var _document = require("./document.cjs");
|
|
75
|
+
var _ValidateError = _interopRequireDefault(require("./errors/ValidateError.cjs"));
|
|
76
|
+
var _validate = require("./validators/validate.cjs");
|
|
77
|
+
var _validateUri = require("./validators/validate-uri.cjs");
|
package/src/index.mjs
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { DiagnosticSeverity, Diagnostic } from 'vscode-languageserver-types';
|
|
2
|
+
export { Diagnostic, DiagnosticSeverity };
|
|
3
|
+
export { TextDocument, ARAZZO_LANGUAGE_ID, DEFAULT_DOCUMENT_VERSION, createTextDocument } from "./document.mjs";
|
|
4
|
+
export { default as ValidateError } from "./errors/ValidateError.mjs";
|
|
5
|
+
export { validate, defaultLanguageServiceContext } from "./validators/validate.mjs";
|
|
6
|
+
export { validateURI, defaultArazzoResolveOptions } from "./validators/validate-uri.mjs";
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.Arazzo1JsonSchemaValidationProvider = exports.Arazzo11JsonSchemaValidationProvider = void 0;
|
|
7
|
+
var _apiLanguageservice = require("@speclynx/api-languageservice");
|
|
8
|
+
/**
|
|
9
|
+
* Custom JSON Schema validation provider that assigns proper diagnostic codes.
|
|
10
|
+
*
|
|
11
|
+
* Extends the base Arazzo1JsonSchemaValidationProvider to set 'json-schema'
|
|
12
|
+
* as the code for all diagnostics, making them identifiable in CLI output.
|
|
13
|
+
* Covers Arazzo 1.0.x documents.
|
|
14
|
+
*
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
17
|
+
class Arazzo1JsonSchemaValidationProvider extends _apiLanguageservice.Arazzo1JsonSchemaValidationProvider {
|
|
18
|
+
validate(jsonDocument, originalDocument, isYaml, diagnostics, validationContext) {
|
|
19
|
+
const startIndex = diagnostics.length;
|
|
20
|
+
super.validate(jsonDocument, originalDocument, isYaml, diagnostics, validationContext);
|
|
21
|
+
|
|
22
|
+
// assign 'json-schema' code only to diagnostics added by this provider
|
|
23
|
+
for (let i = startIndex; i < diagnostics.length; i++) {
|
|
24
|
+
diagnostics[i].code = 'json-schema';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The Arazzo 1.1.0 counterpart of {@link Arazzo1JsonSchemaValidationProvider}.
|
|
31
|
+
*
|
|
32
|
+
* The two upstream providers share no base that carries the Arazzo schema, so
|
|
33
|
+
* the 'json-schema' code assignment is repeated here rather than inherited.
|
|
34
|
+
*
|
|
35
|
+
* @internal
|
|
36
|
+
*/
|
|
37
|
+
exports.Arazzo1JsonSchemaValidationProvider = Arazzo1JsonSchemaValidationProvider;
|
|
38
|
+
class Arazzo11JsonSchemaValidationProvider extends _apiLanguageservice.Arazzo11JsonSchemaValidationProvider {
|
|
39
|
+
validate(jsonDocument, originalDocument, isYaml, diagnostics, validationContext) {
|
|
40
|
+
const startIndex = diagnostics.length;
|
|
41
|
+
super.validate(jsonDocument, originalDocument, isYaml, diagnostics, validationContext);
|
|
42
|
+
|
|
43
|
+
// assign 'json-schema' code only to diagnostics added by this provider
|
|
44
|
+
for (let i = startIndex; i < diagnostics.length; i++) {
|
|
45
|
+
diagnostics[i].code = 'json-schema';
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.Arazzo11JsonSchemaValidationProvider = Arazzo11JsonSchemaValidationProvider;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Arazzo1JsonSchemaValidationProvider as BaseArazzo1JsonSchemaValidationProvider, Arazzo11JsonSchemaValidationProvider as BaseArazzo11JsonSchemaValidationProvider } from '@speclynx/api-languageservice';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Custom JSON Schema validation provider that assigns proper diagnostic codes.
|
|
5
|
+
*
|
|
6
|
+
* Extends the base Arazzo1JsonSchemaValidationProvider to set 'json-schema'
|
|
7
|
+
* as the code for all diagnostics, making them identifiable in CLI output.
|
|
8
|
+
* Covers Arazzo 1.0.x documents.
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export class Arazzo1JsonSchemaValidationProvider extends BaseArazzo1JsonSchemaValidationProvider {
|
|
13
|
+
validate(jsonDocument, originalDocument, isYaml, diagnostics, validationContext) {
|
|
14
|
+
const startIndex = diagnostics.length;
|
|
15
|
+
super.validate(jsonDocument, originalDocument, isYaml, diagnostics, validationContext);
|
|
16
|
+
|
|
17
|
+
// assign 'json-schema' code only to diagnostics added by this provider
|
|
18
|
+
for (let i = startIndex; i < diagnostics.length; i++) {
|
|
19
|
+
diagnostics[i].code = 'json-schema';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The Arazzo 1.1.0 counterpart of {@link Arazzo1JsonSchemaValidationProvider}.
|
|
26
|
+
*
|
|
27
|
+
* The two upstream providers share no base that carries the Arazzo schema, so
|
|
28
|
+
* the 'json-schema' code assignment is repeated here rather than inherited.
|
|
29
|
+
*
|
|
30
|
+
* @internal
|
|
31
|
+
*/
|
|
32
|
+
export class Arazzo11JsonSchemaValidationProvider extends BaseArazzo11JsonSchemaValidationProvider {
|
|
33
|
+
validate(jsonDocument, originalDocument, isYaml, diagnostics, validationContext) {
|
|
34
|
+
const startIndex = diagnostics.length;
|
|
35
|
+
super.validate(jsonDocument, originalDocument, isYaml, diagnostics, validationContext);
|
|
36
|
+
|
|
37
|
+
// assign 'json-schema' code only to diagnostics added by this provider
|
|
38
|
+
for (let i = startIndex; i < diagnostics.length; i++) {
|
|
39
|
+
diagnostics[i].code = 'json-schema';
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
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.defaultArazzoResolveOptions = void 0;
|
|
8
|
+
exports.validateURI = validateURI;
|
|
9
|
+
var _parser = require("@usearazzo/parser");
|
|
10
|
+
var _empty = require("@speclynx/apidom-reference/configuration/empty");
|
|
11
|
+
var _ramda = require("ramda");
|
|
12
|
+
var _document = require("../document.cjs");
|
|
13
|
+
var _ValidateError = _interopRequireDefault(require("../errors/ValidateError.cjs"));
|
|
14
|
+
var _validate = require("./validate.cjs");
|
|
15
|
+
/**
|
|
16
|
+
* Default resolve options for URI resolution in validateURI.
|
|
17
|
+
*
|
|
18
|
+
* These options control how files and URLs are fetched when validating
|
|
19
|
+
* Arazzo documents from URIs.
|
|
20
|
+
*
|
|
21
|
+
* @public
|
|
22
|
+
*/
|
|
23
|
+
const defaultArazzoResolveOptions = exports.defaultArazzoResolveOptions = _parser.defaultParseArazzoOptions.resolve;
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Canonicalizes a document source (path or URL) into an absolute URI.
|
|
27
|
+
*
|
|
28
|
+
* http(s) URLs pass through untouched. A filesystem path (relative or
|
|
29
|
+
* absolute) or a `file:` URI is resolved against the current working
|
|
30
|
+
* directory (a no-op when already absolute) and normalized. Uses
|
|
31
|
+
* `@speclynx/apidom-reference`'s own isomorphic `url` utilities rather than
|
|
32
|
+
* `node:path`/`node:url`, since this module is also bundled for the browser
|
|
33
|
+
* target. This canonical URI doubles as the `baseURI` used to resolve
|
|
34
|
+
* relative external references (e.g. `sourceDescriptions[].url`) within
|
|
35
|
+
* the document.
|
|
36
|
+
*/
|
|
37
|
+
function canonicalizeDocumentURI(source) {
|
|
38
|
+
if (_empty.url.isHttpUrl(source)) {
|
|
39
|
+
return source;
|
|
40
|
+
}
|
|
41
|
+
// a leading slash or backslash (UNC, drive-rooted) is already rooted and passes through
|
|
42
|
+
// untouched; cwd is encoded first so a directory name containing `#`, `?` or `%` survives
|
|
43
|
+
// URL parsing
|
|
44
|
+
const absoluteURI = _empty.url.getProtocol(source) !== 'file' && !/^[\\/]/.test(source) ? _empty.url.resolve(_empty.url.fromFileSystemPath(_empty.url.cwd()), source) : source;
|
|
45
|
+
return _empty.url.sanitize(absoluteURI);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Validates an Arazzo Document from a URI (file path or HTTP(S) URL).
|
|
50
|
+
*
|
|
51
|
+
* This is the primary API for validation. It fetches the document from the
|
|
52
|
+
* specified URI and performs JSON Schema validation, semantic validation,
|
|
53
|
+
* and linting.
|
|
54
|
+
*
|
|
55
|
+
* @param uri - The file system path or HTTP(S) URL to the Arazzo Document
|
|
56
|
+
* @param context - Optional language service context override (deep merged with defaults)
|
|
57
|
+
* @param resolveOptions - Optional resolve options for fetching the URI
|
|
58
|
+
* @returns Promise resolving to an array of Diagnostic objects
|
|
59
|
+
* @throws ValidateError - When the document cannot be fetched. The original error is available via the `cause` property.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* Validate from file
|
|
63
|
+
* ```typescript
|
|
64
|
+
* import { validateURI, DiagnosticSeverity } from '@usearazzo/validator';
|
|
65
|
+
*
|
|
66
|
+
* const diagnostics = await validateURI('/path/to/arazzo.yaml');
|
|
67
|
+
* const errors = diagnostics.filter((d) => d.severity === DiagnosticSeverity.Error);
|
|
68
|
+
* ```
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* Validate from URL
|
|
72
|
+
* ```typescript
|
|
73
|
+
* const diagnostics = await validateURI('https://example.com/arazzo.yaml');
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* Validate with custom context
|
|
78
|
+
* ```typescript
|
|
79
|
+
* const diagnostics = await validateURI('/path/to/arazzo.yaml', {
|
|
80
|
+
* validationContext: { jsonSchemaValidation: true }
|
|
81
|
+
* });
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* Validate with custom resolve options
|
|
86
|
+
* ```typescript
|
|
87
|
+
* const diagnostics = await validateURI('/path/to/arazzo.yaml', {}, {
|
|
88
|
+
* resolverOpts: { timeout: 10000 }
|
|
89
|
+
* });
|
|
90
|
+
* ```
|
|
91
|
+
* @public
|
|
92
|
+
*/
|
|
93
|
+
async function validateURI(uri, context = {}, resolveOptions = {}) {
|
|
94
|
+
const canonicalURI = canonicalizeDocumentURI(uri);
|
|
95
|
+
const mergedOptions = (0, _empty.mergeOptions)(_parser.defaultParseArazzoOptions, {
|
|
96
|
+
resolve: resolveOptions
|
|
97
|
+
});
|
|
98
|
+
let content;
|
|
99
|
+
try {
|
|
100
|
+
const buffer = await (0, _empty.readFile)(canonicalURI, mergedOptions);
|
|
101
|
+
content = new TextDecoder().decode(buffer);
|
|
102
|
+
} catch (error) {
|
|
103
|
+
// quote `uri` rather than `canonicalURI` so the message names what the caller passed in
|
|
104
|
+
throw new _ValidateError.default(`Failed to read Arazzo Document at "${uri}"`, {
|
|
105
|
+
cause: error
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
const textDocument = (0, _document.createTextDocument)(canonicalURI, content);
|
|
109
|
+
|
|
110
|
+
// validateURI always has a real, resolvable document location, so it anchors
|
|
111
|
+
// resolution of relative source descriptions to that location.
|
|
112
|
+
const uriDefaults = {
|
|
113
|
+
validationContext: {
|
|
114
|
+
baseURI: canonicalURI
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
return (0, _validate.validate)(textDocument, (0, _ramda.mergeDeepRight)(uriDefaults, context));
|
|
118
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { defaultParseArazzoOptions } from '@usearazzo/parser';
|
|
2
|
+
import { readFile, mergeOptions, url } from '@speclynx/apidom-reference/configuration/empty';
|
|
3
|
+
import { mergeDeepRight } from 'ramda';
|
|
4
|
+
import { createTextDocument } from "../document.mjs";
|
|
5
|
+
import ValidateError from "../errors/ValidateError.mjs";
|
|
6
|
+
import { validate } from "./validate.mjs";
|
|
7
|
+
/**
|
|
8
|
+
* Default resolve options for URI resolution in validateURI.
|
|
9
|
+
*
|
|
10
|
+
* These options control how files and URLs are fetched when validating
|
|
11
|
+
* Arazzo documents from URIs.
|
|
12
|
+
*
|
|
13
|
+
* @public
|
|
14
|
+
*/
|
|
15
|
+
export const defaultArazzoResolveOptions = defaultParseArazzoOptions.resolve;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Canonicalizes a document source (path or URL) into an absolute URI.
|
|
19
|
+
*
|
|
20
|
+
* http(s) URLs pass through untouched. A filesystem path (relative or
|
|
21
|
+
* absolute) or a `file:` URI is resolved against the current working
|
|
22
|
+
* directory (a no-op when already absolute) and normalized. Uses
|
|
23
|
+
* `@speclynx/apidom-reference`'s own isomorphic `url` utilities rather than
|
|
24
|
+
* `node:path`/`node:url`, since this module is also bundled for the browser
|
|
25
|
+
* target. This canonical URI doubles as the `baseURI` used to resolve
|
|
26
|
+
* relative external references (e.g. `sourceDescriptions[].url`) within
|
|
27
|
+
* the document.
|
|
28
|
+
*/
|
|
29
|
+
function canonicalizeDocumentURI(source) {
|
|
30
|
+
if (url.isHttpUrl(source)) {
|
|
31
|
+
return source;
|
|
32
|
+
}
|
|
33
|
+
// a leading slash or backslash (UNC, drive-rooted) is already rooted and passes through
|
|
34
|
+
// untouched; cwd is encoded first so a directory name containing `#`, `?` or `%` survives
|
|
35
|
+
// URL parsing
|
|
36
|
+
const absoluteURI = url.getProtocol(source) !== 'file' && !/^[\\/]/.test(source) ? url.resolve(url.fromFileSystemPath(url.cwd()), source) : source;
|
|
37
|
+
return url.sanitize(absoluteURI);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Validates an Arazzo Document from a URI (file path or HTTP(S) URL).
|
|
42
|
+
*
|
|
43
|
+
* This is the primary API for validation. It fetches the document from the
|
|
44
|
+
* specified URI and performs JSON Schema validation, semantic validation,
|
|
45
|
+
* and linting.
|
|
46
|
+
*
|
|
47
|
+
* @param uri - The file system path or HTTP(S) URL to the Arazzo Document
|
|
48
|
+
* @param context - Optional language service context override (deep merged with defaults)
|
|
49
|
+
* @param resolveOptions - Optional resolve options for fetching the URI
|
|
50
|
+
* @returns Promise resolving to an array of Diagnostic objects
|
|
51
|
+
* @throws ValidateError - When the document cannot be fetched. The original error is available via the `cause` property.
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* Validate from file
|
|
55
|
+
* ```typescript
|
|
56
|
+
* import { validateURI, DiagnosticSeverity } from '@usearazzo/validator';
|
|
57
|
+
*
|
|
58
|
+
* const diagnostics = await validateURI('/path/to/arazzo.yaml');
|
|
59
|
+
* const errors = diagnostics.filter((d) => d.severity === DiagnosticSeverity.Error);
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* Validate from URL
|
|
64
|
+
* ```typescript
|
|
65
|
+
* const diagnostics = await validateURI('https://example.com/arazzo.yaml');
|
|
66
|
+
* ```
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* Validate with custom context
|
|
70
|
+
* ```typescript
|
|
71
|
+
* const diagnostics = await validateURI('/path/to/arazzo.yaml', {
|
|
72
|
+
* validationContext: { jsonSchemaValidation: true }
|
|
73
|
+
* });
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* Validate with custom resolve options
|
|
78
|
+
* ```typescript
|
|
79
|
+
* const diagnostics = await validateURI('/path/to/arazzo.yaml', {}, {
|
|
80
|
+
* resolverOpts: { timeout: 10000 }
|
|
81
|
+
* });
|
|
82
|
+
* ```
|
|
83
|
+
* @public
|
|
84
|
+
*/
|
|
85
|
+
export async function validateURI(uri, context = {}, resolveOptions = {}) {
|
|
86
|
+
const canonicalURI = canonicalizeDocumentURI(uri);
|
|
87
|
+
const mergedOptions = mergeOptions(defaultParseArazzoOptions, {
|
|
88
|
+
resolve: resolveOptions
|
|
89
|
+
});
|
|
90
|
+
let content;
|
|
91
|
+
try {
|
|
92
|
+
const buffer = await readFile(canonicalURI, mergedOptions);
|
|
93
|
+
content = new TextDecoder().decode(buffer);
|
|
94
|
+
} catch (error) {
|
|
95
|
+
// quote `uri` rather than `canonicalURI` so the message names what the caller passed in
|
|
96
|
+
throw new ValidateError(`Failed to read Arazzo Document at "${uri}"`, {
|
|
97
|
+
cause: error
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
const textDocument = createTextDocument(canonicalURI, content);
|
|
101
|
+
|
|
102
|
+
// validateURI always has a real, resolvable document location, so it anchors
|
|
103
|
+
// resolution of relative source descriptions to that location.
|
|
104
|
+
const uriDefaults = {
|
|
105
|
+
validationContext: {
|
|
106
|
+
baseURI: canonicalURI
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
return validate(textDocument, mergeDeepRight(uriDefaults, context));
|
|
110
|
+
}
|