@usearazzo/validator 0.0.0-stage → 1.0.1-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 +14 -0
- 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 +76 -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
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.defaultLanguageServiceContext = void 0;
|
|
7
|
+
exports.validate = validate;
|
|
8
|
+
var _vscodeLanguageserverTypes = require("vscode-languageserver-types");
|
|
9
|
+
var _apidomNsArazzo = require("@speclynx/apidom-ns-arazzo-1");
|
|
10
|
+
var _apiLanguageservice = require("@speclynx/api-languageservice");
|
|
11
|
+
var _ramda = require("ramda");
|
|
12
|
+
var _jsonSchemaProvider = require("./json-schema-provider.cjs");
|
|
13
|
+
/**
|
|
14
|
+
* Default language service context for validation.
|
|
15
|
+
*
|
|
16
|
+
* Controls validation behavior: semantic validation, reference validation and
|
|
17
|
+
* semantic linting are enabled, JSON Schema validation is opt-in.
|
|
18
|
+
*
|
|
19
|
+
* @public
|
|
20
|
+
*/
|
|
21
|
+
const defaultLanguageServiceContext = exports.defaultLanguageServiceContext = {
|
|
22
|
+
logLevel: _apiLanguageservice.LogLevel.NONE,
|
|
23
|
+
defaultContentLanguage: {
|
|
24
|
+
namespace: 'arazzo',
|
|
25
|
+
version: '1.0.1',
|
|
26
|
+
mediaType: _apidomNsArazzo.mediaTypes.findBy('1.0.1')
|
|
27
|
+
},
|
|
28
|
+
// the language service registers no providers of its own, so each Arazzo version whose JSON
|
|
29
|
+
// Schema should be checked needs one here; a version without one is silently skipped
|
|
30
|
+
validatorProviders: [new _jsonSchemaProvider.Arazzo1JsonSchemaValidationProvider(), new _jsonSchemaProvider.Arazzo11JsonSchemaValidationProvider()],
|
|
31
|
+
// semantic validation, reference validation and semantic linting are always
|
|
32
|
+
// on, while JSON Schema (AJV) validation is opt-in. `betterAjvErrors` is kept
|
|
33
|
+
// on so opting in also gets the friendlier AJV messages.
|
|
34
|
+
validationContext: {
|
|
35
|
+
jsonSchemaValidation: false,
|
|
36
|
+
semanticValidation: true,
|
|
37
|
+
referenceValidation: true,
|
|
38
|
+
semanticLinting: true,
|
|
39
|
+
betterAjvErrors: true
|
|
40
|
+
},
|
|
41
|
+
parseContext: {
|
|
42
|
+
// regex patterns, not glob strings - picomatch's glob matching never matches a dotfile
|
|
43
|
+
// basename (e.g. .petstore.yaml) without `dot: true`, which FileResolver does not set,
|
|
44
|
+
// and `*` would admit any file at all. FileResolver accepts RegExp at runtime even though
|
|
45
|
+
// api-languageservice types the option as string[].
|
|
46
|
+
fileAllowList: [/\.json$/i, /\.ya?ml$/i],
|
|
47
|
+
arazzo: {
|
|
48
|
+
sourceDescriptionsResolution: true
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Validates an Arazzo Document from a TextDocument.
|
|
55
|
+
*
|
|
56
|
+
* This is a lower-level API for advanced use cases such as IDE integrations
|
|
57
|
+
* or when you already have document content in memory.
|
|
58
|
+
*
|
|
59
|
+
* @param textDocument - The TextDocument containing the Arazzo Document content
|
|
60
|
+
* @param context - Optional language service context override (deep merged with defaults)
|
|
61
|
+
* @returns Promise resolving to an array of Diagnostic objects
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* Basic usage
|
|
65
|
+
* ```typescript
|
|
66
|
+
* import { validate, TextDocument, DiagnosticSeverity, ARAZZO_LANGUAGE_ID, DEFAULT_DOCUMENT_VERSION } from '@usearazzo/validator';
|
|
67
|
+
*
|
|
68
|
+
* const textDocument = TextDocument.create(
|
|
69
|
+
* 'file:///path/to/arazzo.yaml',
|
|
70
|
+
* ARAZZO_LANGUAGE_ID,
|
|
71
|
+
* DEFAULT_DOCUMENT_VERSION,
|
|
72
|
+
* content
|
|
73
|
+
* );
|
|
74
|
+
* const diagnostics = await validate(textDocument);
|
|
75
|
+
* const errors = diagnostics.filter((d) => d.severity === DiagnosticSeverity.Error);
|
|
76
|
+
* ```
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* Enable JSON Schema validation (opt-in)
|
|
80
|
+
* ```typescript
|
|
81
|
+
* const diagnostics = await validate(textDocument, {
|
|
82
|
+
* validationContext: { jsonSchemaValidation: true }
|
|
83
|
+
* });
|
|
84
|
+
* ```
|
|
85
|
+
* @public
|
|
86
|
+
*/
|
|
87
|
+
async function validate(textDocument, context = {}) {
|
|
88
|
+
const content = textDocument.getText();
|
|
89
|
+
// classify with the language service's own detector so the two cannot diverge.
|
|
90
|
+
// `defaultContentLanguage` is deliberately not passed - it would make arrays,
|
|
91
|
+
// empty files and plain objects fall back to Arazzo.
|
|
92
|
+
const {
|
|
93
|
+
namespace
|
|
94
|
+
} = await (0, _apiLanguageservice.findNamespace)(content);
|
|
95
|
+
if (namespace !== 'arazzo') {
|
|
96
|
+
const lastChar = textDocument.positionAt(content.length);
|
|
97
|
+
return [{
|
|
98
|
+
range: {
|
|
99
|
+
start: {
|
|
100
|
+
line: 0,
|
|
101
|
+
character: 0
|
|
102
|
+
},
|
|
103
|
+
end: {
|
|
104
|
+
line: lastChar.line,
|
|
105
|
+
character: lastChar.character
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
message: 'Document content is not recognized as an Arazzo Specification',
|
|
109
|
+
severity: _vscodeLanguageserverTypes.DiagnosticSeverity.Error,
|
|
110
|
+
code: _apiLanguageservice.ApilintCodes.ARAZZO_NOT_DETECTED,
|
|
111
|
+
source: 'apilint'
|
|
112
|
+
}];
|
|
113
|
+
}
|
|
114
|
+
const mergedContext = (0, _ramda.mergeDeepRight)(defaultLanguageServiceContext, context);
|
|
115
|
+
const languageService = (0, _apiLanguageservice.getLanguageService)(mergedContext);
|
|
116
|
+
try {
|
|
117
|
+
return await languageService.doValidation(textDocument);
|
|
118
|
+
} finally {
|
|
119
|
+
languageService.terminate();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { DiagnosticSeverity } from 'vscode-languageserver-types';
|
|
2
|
+
import { mediaTypes } from '@speclynx/apidom-ns-arazzo-1';
|
|
3
|
+
import { getLanguageService, findNamespace, ApilintCodes, LogLevel } from '@speclynx/api-languageservice';
|
|
4
|
+
import { mergeDeepRight } from 'ramda';
|
|
5
|
+
import { Arazzo1JsonSchemaValidationProvider, Arazzo11JsonSchemaValidationProvider } from "./json-schema-provider.mjs";
|
|
6
|
+
/**
|
|
7
|
+
* Default language service context for validation.
|
|
8
|
+
*
|
|
9
|
+
* Controls validation behavior: semantic validation, reference validation and
|
|
10
|
+
* semantic linting are enabled, JSON Schema validation is opt-in.
|
|
11
|
+
*
|
|
12
|
+
* @public
|
|
13
|
+
*/
|
|
14
|
+
export const defaultLanguageServiceContext = {
|
|
15
|
+
logLevel: LogLevel.NONE,
|
|
16
|
+
defaultContentLanguage: {
|
|
17
|
+
namespace: 'arazzo',
|
|
18
|
+
version: '1.0.1',
|
|
19
|
+
mediaType: mediaTypes.findBy('1.0.1')
|
|
20
|
+
},
|
|
21
|
+
// the language service registers no providers of its own, so each Arazzo version whose JSON
|
|
22
|
+
// Schema should be checked needs one here; a version without one is silently skipped
|
|
23
|
+
validatorProviders: [new Arazzo1JsonSchemaValidationProvider(), new Arazzo11JsonSchemaValidationProvider()],
|
|
24
|
+
// semantic validation, reference validation and semantic linting are always
|
|
25
|
+
// on, while JSON Schema (AJV) validation is opt-in. `betterAjvErrors` is kept
|
|
26
|
+
// on so opting in also gets the friendlier AJV messages.
|
|
27
|
+
validationContext: {
|
|
28
|
+
jsonSchemaValidation: false,
|
|
29
|
+
semanticValidation: true,
|
|
30
|
+
referenceValidation: true,
|
|
31
|
+
semanticLinting: true,
|
|
32
|
+
betterAjvErrors: true
|
|
33
|
+
},
|
|
34
|
+
parseContext: {
|
|
35
|
+
// regex patterns, not glob strings - picomatch's glob matching never matches a dotfile
|
|
36
|
+
// basename (e.g. .petstore.yaml) without `dot: true`, which FileResolver does not set,
|
|
37
|
+
// and `*` would admit any file at all. FileResolver accepts RegExp at runtime even though
|
|
38
|
+
// api-languageservice types the option as string[].
|
|
39
|
+
fileAllowList: [/\.json$/i, /\.ya?ml$/i],
|
|
40
|
+
arazzo: {
|
|
41
|
+
sourceDescriptionsResolution: true
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Validates an Arazzo Document from a TextDocument.
|
|
48
|
+
*
|
|
49
|
+
* This is a lower-level API for advanced use cases such as IDE integrations
|
|
50
|
+
* or when you already have document content in memory.
|
|
51
|
+
*
|
|
52
|
+
* @param textDocument - The TextDocument containing the Arazzo Document content
|
|
53
|
+
* @param context - Optional language service context override (deep merged with defaults)
|
|
54
|
+
* @returns Promise resolving to an array of Diagnostic objects
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* Basic usage
|
|
58
|
+
* ```typescript
|
|
59
|
+
* import { validate, TextDocument, DiagnosticSeverity, ARAZZO_LANGUAGE_ID, DEFAULT_DOCUMENT_VERSION } from '@usearazzo/validator';
|
|
60
|
+
*
|
|
61
|
+
* const textDocument = TextDocument.create(
|
|
62
|
+
* 'file:///path/to/arazzo.yaml',
|
|
63
|
+
* ARAZZO_LANGUAGE_ID,
|
|
64
|
+
* DEFAULT_DOCUMENT_VERSION,
|
|
65
|
+
* content
|
|
66
|
+
* );
|
|
67
|
+
* const diagnostics = await validate(textDocument);
|
|
68
|
+
* const errors = diagnostics.filter((d) => d.severity === DiagnosticSeverity.Error);
|
|
69
|
+
* ```
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* Enable JSON Schema validation (opt-in)
|
|
73
|
+
* ```typescript
|
|
74
|
+
* const diagnostics = await validate(textDocument, {
|
|
75
|
+
* validationContext: { jsonSchemaValidation: true }
|
|
76
|
+
* });
|
|
77
|
+
* ```
|
|
78
|
+
* @public
|
|
79
|
+
*/
|
|
80
|
+
export async function validate(textDocument, context = {}) {
|
|
81
|
+
const content = textDocument.getText();
|
|
82
|
+
// classify with the language service's own detector so the two cannot diverge.
|
|
83
|
+
// `defaultContentLanguage` is deliberately not passed - it would make arrays,
|
|
84
|
+
// empty files and plain objects fall back to Arazzo.
|
|
85
|
+
const {
|
|
86
|
+
namespace
|
|
87
|
+
} = await findNamespace(content);
|
|
88
|
+
if (namespace !== 'arazzo') {
|
|
89
|
+
const lastChar = textDocument.positionAt(content.length);
|
|
90
|
+
return [{
|
|
91
|
+
range: {
|
|
92
|
+
start: {
|
|
93
|
+
line: 0,
|
|
94
|
+
character: 0
|
|
95
|
+
},
|
|
96
|
+
end: {
|
|
97
|
+
line: lastChar.line,
|
|
98
|
+
character: lastChar.character
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
message: 'Document content is not recognized as an Arazzo Specification',
|
|
102
|
+
severity: DiagnosticSeverity.Error,
|
|
103
|
+
code: ApilintCodes.ARAZZO_NOT_DETECTED,
|
|
104
|
+
source: 'apilint'
|
|
105
|
+
}];
|
|
106
|
+
}
|
|
107
|
+
const mergedContext = mergeDeepRight(defaultLanguageServiceContext, context);
|
|
108
|
+
const languageService = getLanguageService(mergedContext);
|
|
109
|
+
try {
|
|
110
|
+
return await languageService.doValidation(textDocument);
|
|
111
|
+
} finally {
|
|
112
|
+
languageService.terminate();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { ApiDOMError } from '@speclynx/apidom-error';
|
|
2
|
+
import { ApiDOMErrorOptions } from '@speclynx/apidom-error';
|
|
3
|
+
import { ApiDOMReferenceResolveOptions } from '@speclynx/apidom-reference/configuration/empty';
|
|
4
|
+
import { Diagnostic } from 'vscode-languageserver-types';
|
|
5
|
+
import { DiagnosticSeverity } from 'vscode-languageserver-types';
|
|
6
|
+
import { LanguageServiceContext } from '@speclynx/api-languageservice';
|
|
7
|
+
import type { PartialDeep } from 'type-fest';
|
|
8
|
+
import { Resolver } from '@speclynx/apidom-reference/configuration/empty';
|
|
9
|
+
import { ResolveStrategy } from '@speclynx/apidom-reference/configuration/empty';
|
|
10
|
+
import { TextDocument } from 'vscode-languageserver-textdocument';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Language ID for Arazzo documents used with TextDocument.
|
|
14
|
+
*
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
17
|
+
export declare const ARAZZO_LANGUAGE_ID = "apidom";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Creates a TextDocument for Arazzo validation.
|
|
21
|
+
*
|
|
22
|
+
* @param uri - The document URI
|
|
23
|
+
* @param content - The document content
|
|
24
|
+
* @returns A TextDocument instance
|
|
25
|
+
* @public
|
|
26
|
+
*/
|
|
27
|
+
export declare function createTextDocument(uri: string, content: string): TextDocument;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Default document version for TextDocument instances.
|
|
31
|
+
*
|
|
32
|
+
* @public
|
|
33
|
+
*/
|
|
34
|
+
export declare const DEFAULT_DOCUMENT_VERSION = 1;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Default resolve options for URI resolution in validateURI.
|
|
38
|
+
*
|
|
39
|
+
* These options control how files and URLs are fetched when validating
|
|
40
|
+
* Arazzo documents from URIs.
|
|
41
|
+
*
|
|
42
|
+
* @public
|
|
43
|
+
*/
|
|
44
|
+
export declare const defaultArazzoResolveOptions: {
|
|
45
|
+
baseURI?: string | undefined;
|
|
46
|
+
resolvers?: Resolver[] | undefined;
|
|
47
|
+
resolverOpts?: {
|
|
48
|
+
[x: string]: any;
|
|
49
|
+
} | undefined;
|
|
50
|
+
strategies?: ResolveStrategy[] | undefined;
|
|
51
|
+
strategyOpts?: {
|
|
52
|
+
[x: string]: any;
|
|
53
|
+
} | undefined;
|
|
54
|
+
internal?: boolean | undefined;
|
|
55
|
+
external?: boolean | undefined;
|
|
56
|
+
maxDepth?: number | undefined;
|
|
57
|
+
} | undefined;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Default language service context for validation.
|
|
61
|
+
*
|
|
62
|
+
* Controls validation behavior: semantic validation, reference validation and
|
|
63
|
+
* semantic linting are enabled, JSON Schema validation is opt-in.
|
|
64
|
+
*
|
|
65
|
+
* @public
|
|
66
|
+
*/
|
|
67
|
+
export declare const defaultLanguageServiceContext: Partial<LanguageServiceContext>;
|
|
68
|
+
|
|
69
|
+
export { Diagnostic }
|
|
70
|
+
|
|
71
|
+
export { DiagnosticSeverity }
|
|
72
|
+
|
|
73
|
+
export { LanguageServiceContext }
|
|
74
|
+
|
|
75
|
+
export { TextDocument }
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Validates an Arazzo Document from a TextDocument.
|
|
79
|
+
*
|
|
80
|
+
* This is a lower-level API for advanced use cases such as IDE integrations
|
|
81
|
+
* or when you already have document content in memory.
|
|
82
|
+
*
|
|
83
|
+
* @param textDocument - The TextDocument containing the Arazzo Document content
|
|
84
|
+
* @param context - Optional language service context override (deep merged with defaults)
|
|
85
|
+
* @returns Promise resolving to an array of Diagnostic objects
|
|
86
|
+
*
|
|
87
|
+
* @example
|
|
88
|
+
* Basic usage
|
|
89
|
+
* ```typescript
|
|
90
|
+
* import { validate, TextDocument, DiagnosticSeverity, ARAZZO_LANGUAGE_ID, DEFAULT_DOCUMENT_VERSION } from '@usearazzo/validator';
|
|
91
|
+
*
|
|
92
|
+
* const textDocument = TextDocument.create(
|
|
93
|
+
* 'file:///path/to/arazzo.yaml',
|
|
94
|
+
* ARAZZO_LANGUAGE_ID,
|
|
95
|
+
* DEFAULT_DOCUMENT_VERSION,
|
|
96
|
+
* content
|
|
97
|
+
* );
|
|
98
|
+
* const diagnostics = await validate(textDocument);
|
|
99
|
+
* const errors = diagnostics.filter((d) => d.severity === DiagnosticSeverity.Error);
|
|
100
|
+
* ```
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* Enable JSON Schema validation (opt-in)
|
|
104
|
+
* ```typescript
|
|
105
|
+
* const diagnostics = await validate(textDocument, {
|
|
106
|
+
* validationContext: { jsonSchemaValidation: true }
|
|
107
|
+
* });
|
|
108
|
+
* ```
|
|
109
|
+
* @public
|
|
110
|
+
*/
|
|
111
|
+
export declare function validate(textDocument: TextDocument, context?: PartialDeep<LanguageServiceContext>): Promise<Diagnostic[]>;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Error thrown by `validateURI` when the document cannot be fetched. Problems
|
|
115
|
+
* found in the document itself are reported as diagnostics, not thrown. The
|
|
116
|
+
* original error is available via the `cause` property.
|
|
117
|
+
* @public
|
|
118
|
+
*/
|
|
119
|
+
export declare class ValidateError extends ApiDOMError {
|
|
120
|
+
constructor(message?: string, options?: ApiDOMErrorOptions);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Validates an Arazzo Document from a URI (file path or HTTP(S) URL).
|
|
125
|
+
*
|
|
126
|
+
* This is the primary API for validation. It fetches the document from the
|
|
127
|
+
* specified URI and performs JSON Schema validation, semantic validation,
|
|
128
|
+
* and linting.
|
|
129
|
+
*
|
|
130
|
+
* @param uri - The file system path or HTTP(S) URL to the Arazzo Document
|
|
131
|
+
* @param context - Optional language service context override (deep merged with defaults)
|
|
132
|
+
* @param resolveOptions - Optional resolve options for fetching the URI
|
|
133
|
+
* @returns Promise resolving to an array of Diagnostic objects
|
|
134
|
+
* @throws ValidateError - When the document cannot be fetched. The original error is available via the `cause` property.
|
|
135
|
+
*
|
|
136
|
+
* @example
|
|
137
|
+
* Validate from file
|
|
138
|
+
* ```typescript
|
|
139
|
+
* import { validateURI, DiagnosticSeverity } from '@usearazzo/validator';
|
|
140
|
+
*
|
|
141
|
+
* const diagnostics = await validateURI('/path/to/arazzo.yaml');
|
|
142
|
+
* const errors = diagnostics.filter((d) => d.severity === DiagnosticSeverity.Error);
|
|
143
|
+
* ```
|
|
144
|
+
*
|
|
145
|
+
* @example
|
|
146
|
+
* Validate from URL
|
|
147
|
+
* ```typescript
|
|
148
|
+
* const diagnostics = await validateURI('https://example.com/arazzo.yaml');
|
|
149
|
+
* ```
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* Validate with custom context
|
|
153
|
+
* ```typescript
|
|
154
|
+
* const diagnostics = await validateURI('/path/to/arazzo.yaml', {
|
|
155
|
+
* validationContext: { jsonSchemaValidation: true }
|
|
156
|
+
* });
|
|
157
|
+
* ```
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* Validate with custom resolve options
|
|
161
|
+
* ```typescript
|
|
162
|
+
* const diagnostics = await validateURI('/path/to/arazzo.yaml', {}, {
|
|
163
|
+
* resolverOpts: { timeout: 10000 }
|
|
164
|
+
* });
|
|
165
|
+
* ```
|
|
166
|
+
* @public
|
|
167
|
+
*/
|
|
168
|
+
export declare function validateURI(uri: string, context?: PartialDeep<LanguageServiceContext>, resolveOptions?: PartialDeep<ApiDOMReferenceResolveOptions>): Promise<Diagnostic[]>;
|
|
169
|
+
|
|
170
|
+
export { }
|