@unispechq/unispec-core 0.3.2 → 0.3.3
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/dist/cjs/src/cache/cache-factory.js +1 -1
- package/dist/cjs/src/cache/cache-manager.js +2 -2
- package/dist/cjs/src/cache/hash-utils.js +1 -1
- package/dist/cjs/src/cache/hashing.js +1 -1
- package/dist/cjs/src/cache/index.js +5 -5
- package/dist/cjs/src/cache/lru-cache.js +1 -1
- package/dist/cjs/src/diff/core.js +2 -2
- package/dist/cjs/src/diff/enhanced-diff.js +5 -5
- package/dist/cjs/src/diff/index.js +8 -8
- package/dist/cjs/src/errors/config-error.js +1 -1
- package/dist/cjs/src/errors/error-factory.js +7 -7
- package/dist/cjs/src/errors/index.js +8 -8
- package/dist/cjs/src/errors/loader-error.js +1 -1
- package/dist/cjs/src/errors/reference-error.js +1 -1
- package/dist/cjs/src/errors/schema-error.js +1 -1
- package/dist/cjs/src/errors/security-error.js +1 -1
- package/dist/cjs/src/errors/semantic-error.js +1 -1
- package/dist/cjs/src/index.js +13 -13
- package/dist/cjs/src/loader/index.js +4 -4
- package/dist/cjs/src/loader/security-validator.js +1 -1
- package/dist/cjs/src/loader/unispec-loader.js +3 -3
- package/dist/cjs/src/loader/yaml-loader.js +1 -1
- package/dist/cjs/src/normalizer/core.js +4 -4
- package/dist/cjs/src/normalizer/index.js +1 -1
- package/dist/cjs/src/optimizer/core.js +2 -2
- package/dist/cjs/src/optimizer/index.js +3 -3
- package/dist/cjs/src/optimizer/optimization-functions.js +2 -2
- package/dist/cjs/src/schemas/dedupe.js +1 -1
- package/dist/cjs/src/schemas/index.js +3 -3
- package/dist/cjs/src/schemas/resolver.js +1 -1
- package/dist/cjs/src/validator/ajv-validator.js +1 -1
- package/dist/cjs/src/validator/config-validator-main.js +4 -4
- package/dist/cjs/src/validator/config-validator.js +1 -1
- package/dist/cjs/src/validator/index.js +7 -7
- package/dist/cjs/src/validator/reference-validator.js +1 -1
- package/dist/cjs/src/validator/tests-validator.js +2 -2
- package/dist/cjs/src/validator/unispec-validator.js +5 -5
- package/dist/cjs/src/validator/validator-factory.js +1 -1
- package/dist/cjs/tests/cache/cache.test.js +4 -4
- package/dist/cjs/tests/cache/utils.js +1 -1
- package/dist/cjs/tests/diff/diff-annotators.test.js +2 -2
- package/dist/cjs/tests/diff/diff-comprehensive.test.js +2 -2
- package/dist/cjs/tests/diff/diff-extended.test.js +2 -2
- package/dist/cjs/tests/diff/diff.test.js +2 -2
- package/dist/cjs/tests/diff/utils.js +1 -1
- package/dist/cjs/tests/errors/errors-integration.test.js +3 -3
- package/dist/cjs/tests/errors/errors.test.js +2 -2
- package/dist/cjs/tests/errors/utils.js +1 -1
- package/dist/cjs/tests/loader/integration.test.js +2 -2
- package/dist/cjs/tests/loader/loader.test.js +2 -2
- package/dist/cjs/tests/normalizer/normalizer-comprehensive.test.js +2 -2
- package/dist/cjs/tests/normalizer/normalizer-invalid.test.js +2 -2
- package/dist/cjs/tests/normalizer/normalizer-valid.test.js +2 -2
- package/dist/cjs/tests/normalizer/utils.js +1 -1
- package/dist/cjs/tests/optimizer/compress-references.test.js +2 -2
- package/dist/cjs/tests/optimizer/deduplication.test.js +2 -2
- package/dist/cjs/tests/optimizer/integration.test.js +3 -3
- package/dist/cjs/tests/optimizer/optimization-report.test.js +2 -2
- package/dist/cjs/tests/optimizer/optimize-document.test.js +2 -2
- package/dist/cjs/tests/optimizer/orphaned-schemas.test.js +2 -2
- package/dist/cjs/tests/optimizer/sort-schemas.test.js +2 -2
- package/dist/cjs/tests/optimizer/utils.js +1 -1
- package/dist/cjs/tests/schemas/schemas-edge-cases.test.js +3 -3
- package/dist/cjs/tests/schemas/schemas.test.js +3 -3
- package/dist/cjs/tests/schemas/utils.js +1 -1
- package/dist/cjs/tests/validator/config-validator.test.js +2 -2
- package/dist/cjs/tests/validator/unispec-validator.test.js +2 -2
- package/dist/cjs/tests/validator/utils.js +1 -1
- package/package.json +1 -1
- package/dist/cache/cache-factory.d.ts +0 -31
- package/dist/cache/cache-factory.js +0 -65
- package/dist/cache/cache-manager.d.ts +0 -62
- package/dist/cache/cache-manager.js +0 -122
- package/dist/cache/constants.d.ts +0 -21
- package/dist/cache/constants.js +0 -22
- package/dist/cache/hash-utils.d.ts +0 -21
- package/dist/cache/hash-utils.js +0 -35
- package/dist/cache/hashing.d.ts +0 -19
- package/dist/cache/hashing.js +0 -197
- package/dist/cache/index.d.ts +0 -6
- package/dist/cache/index.js +0 -10
- package/dist/cache/lru-cache.d.ts +0 -56
- package/dist/cache/lru-cache.js +0 -161
- package/dist/cache/types.d.ts +0 -24
- package/dist/cache/types.js +0 -4
- package/dist/cjs/cache/cache-factory.js +0 -72
- package/dist/cjs/cache/cache-manager.js +0 -126
- package/dist/cjs/cache/constants.js +0 -25
- package/dist/cjs/cache/hash-utils.js +0 -41
- package/dist/cjs/cache/hashing.js +0 -236
- package/dist/cjs/cache/index.js +0 -26
- package/dist/cjs/cache/lru-cache.js +0 -165
- package/dist/cjs/cache/types.js +0 -5
- package/dist/cjs/diff/annotators.js +0 -159
- package/dist/cjs/diff/change-reports.js +0 -369
- package/dist/cjs/diff/core.js +0 -158
- package/dist/cjs/diff/enhanced-diff.js +0 -79
- package/dist/cjs/diff/impact-strategies-refactored.js +0 -230
- package/dist/cjs/diff/impact-strategies.js +0 -219
- package/dist/cjs/diff/index.js +0 -27
- package/dist/cjs/diff/metrics-calculator.js +0 -69
- package/dist/cjs/diff/risk-calculator.js +0 -58
- package/dist/cjs/diff/suggestion-generator.js +0 -78
- package/dist/cjs/diff/types.js +0 -11
- package/dist/cjs/errors/base-error.js +0 -33
- package/dist/cjs/errors/config-error.js +0 -11
- package/dist/cjs/errors/error-factory.js +0 -48
- package/dist/cjs/errors/index.js +0 -19
- package/dist/cjs/errors/loader-error.js +0 -11
- package/dist/cjs/errors/reference-error.js +0 -11
- package/dist/cjs/errors/schema-error.js +0 -11
- package/dist/cjs/errors/security-error.js +0 -11
- package/dist/cjs/errors/semantic-error.js +0 -11
- package/dist/cjs/generated-schemas.js +0 -2100
- package/dist/cjs/index.js +0 -59
- package/dist/cjs/loader/index.js +0 -13
- package/dist/cjs/loader/security-validator.js +0 -53
- package/dist/cjs/loader/types.js +0 -11
- package/dist/cjs/loader/unispec-loader.js +0 -84
- package/dist/cjs/loader/yaml-loader.js +0 -76
- package/dist/cjs/normalizer/core.js +0 -32
- package/dist/cjs/normalizer/graphql-normalizer.js +0 -67
- package/dist/cjs/normalizer/index.js +0 -7
- package/dist/cjs/normalizer/rest-normalizer.js +0 -51
- package/dist/cjs/normalizer/types.js +0 -2
- package/dist/cjs/normalizer/utils.js +0 -33
- package/dist/cjs/normalizer/websocket-normalizer.js +0 -81
- package/dist/cjs/optimizer/core.js +0 -115
- package/dist/cjs/optimizer/index.js +0 -17
- package/dist/cjs/optimizer/optimization-functions.js +0 -185
- package/dist/cjs/optimizer/types.js +0 -2
- package/dist/cjs/optimizer/utils.js +0 -32
- package/dist/cjs/schemas/dedupe.js +0 -100
- package/dist/cjs/schemas/index.js +0 -14
- package/dist/cjs/schemas/resolver.js +0 -41
- package/dist/cjs/schemas/utils.js +0 -53
- package/dist/cjs/types/index.js +0 -2
- package/dist/cjs/validator/ajv-validator.js +0 -82
- package/dist/cjs/validator/config-validator-main.js +0 -34
- package/dist/cjs/validator/config-validator.js +0 -17
- package/dist/cjs/validator/index.js +0 -23
- package/dist/cjs/validator/object-traversal.js +0 -112
- package/dist/cjs/validator/reference-validator.js +0 -233
- package/dist/cjs/validator/schema-references.js +0 -116
- package/dist/cjs/validator/semantic-validator.js +0 -328
- package/dist/cjs/validator/tests-validator.js +0 -16
- package/dist/cjs/validator/types.js +0 -2
- package/dist/cjs/validator/unispec-validator.js +0 -84
- package/dist/cjs/validator/validator-factory.js +0 -77
- package/dist/cjs/versions.js +0 -147
- package/dist/diff/annotators.d.ts +0 -4
- package/dist/diff/annotators.js +0 -154
- package/dist/diff/change-reports.d.ts +0 -37
- package/dist/diff/change-reports.js +0 -366
- package/dist/diff/core.d.ts +0 -26
- package/dist/diff/core.js +0 -155
- package/dist/diff/enhanced-diff.d.ts +0 -51
- package/dist/diff/enhanced-diff.js +0 -76
- package/dist/diff/impact-strategies-refactored.d.ts +0 -69
- package/dist/diff/impact-strategies-refactored.js +0 -223
- package/dist/diff/impact-strategies.d.ts +0 -41
- package/dist/diff/impact-strategies.js +0 -212
- package/dist/diff/index.d.ts +0 -8
- package/dist/diff/index.js +0 -11
- package/dist/diff/metrics-calculator.d.ts +0 -23
- package/dist/diff/metrics-calculator.js +0 -65
- package/dist/diff/risk-calculator.d.ts +0 -23
- package/dist/diff/risk-calculator.js +0 -55
- package/dist/diff/suggestion-generator.d.ts +0 -18
- package/dist/diff/suggestion-generator.js +0 -74
- package/dist/diff/types.d.ts +0 -24
- package/dist/diff/types.js +0 -8
- package/dist/errors/base-error.d.ts +0 -20
- package/dist/errors/base-error.js +0 -29
- package/dist/errors/config-error.d.ts +0 -4
- package/dist/errors/config-error.js +0 -7
- package/dist/errors/error-factory.d.ts +0 -22
- package/dist/errors/error-factory.js +0 -45
- package/dist/errors/index.d.ts +0 -8
- package/dist/errors/index.js +0 -8
- package/dist/errors/loader-error.d.ts +0 -4
- package/dist/errors/loader-error.js +0 -7
- package/dist/errors/reference-error.d.ts +0 -4
- package/dist/errors/reference-error.js +0 -7
- package/dist/errors/schema-error.d.ts +0 -4
- package/dist/errors/schema-error.js +0 -7
- package/dist/errors/security-error.d.ts +0 -4
- package/dist/errors/security-error.js +0 -7
- package/dist/errors/semantic-error.d.ts +0 -4
- package/dist/errors/semantic-error.js +0 -7
- package/dist/generated-schemas.d.ts +0 -2073
- package/dist/generated-schemas.js +0 -2097
- package/dist/index.cjs +0 -59
- package/dist/index.d.ts +0 -13
- package/dist/index.js +0 -43
- package/dist/loader/index.d.ts +0 -5
- package/dist/loader/index.js +0 -5
- package/dist/loader/security-validator.d.ts +0 -5
- package/dist/loader/security-validator.js +0 -50
- package/dist/loader/types.d.ts +0 -30
- package/dist/loader/types.js +0 -8
- package/dist/loader/unispec-loader.d.ts +0 -10
- package/dist/loader/unispec-loader.js +0 -81
- package/dist/loader/yaml-loader.d.ts +0 -10
- package/dist/loader/yaml-loader.js +0 -39
- package/dist/normalizer/core.d.ts +0 -24
- package/dist/normalizer/core.js +0 -29
- package/dist/normalizer/graphql-normalizer.d.ts +0 -8
- package/dist/normalizer/graphql-normalizer.js +0 -64
- package/dist/normalizer/index.d.ts +0 -2
- package/dist/normalizer/index.js +0 -3
- package/dist/normalizer/rest-normalizer.d.ts +0 -8
- package/dist/normalizer/rest-normalizer.js +0 -48
- package/dist/normalizer/types.d.ts +0 -7
- package/dist/normalizer/types.js +0 -1
- package/dist/normalizer/utils.d.ts +0 -14
- package/dist/normalizer/utils.js +0 -29
- package/dist/normalizer/websocket-normalizer.d.ts +0 -8
- package/dist/normalizer/websocket-normalizer.js +0 -78
- package/dist/optimizer/core.d.ts +0 -17
- package/dist/optimizer/core.js +0 -111
- package/dist/optimizer/index.d.ts +0 -4
- package/dist/optimizer/index.js +0 -7
- package/dist/optimizer/optimization-functions.d.ts +0 -32
- package/dist/optimizer/optimization-functions.js +0 -179
- package/dist/optimizer/types.d.ts +0 -28
- package/dist/optimizer/types.js +0 -1
- package/dist/optimizer/utils.d.ts +0 -7
- package/dist/optimizer/utils.js +0 -29
- package/dist/schemas/dedupe.d.ts +0 -9
- package/dist/schemas/dedupe.js +0 -97
- package/dist/schemas/index.d.ts +0 -3
- package/dist/schemas/index.js +0 -6
- package/dist/schemas/resolver.d.ts +0 -19
- package/dist/schemas/resolver.js +0 -37
- package/dist/schemas/utils.d.ts +0 -20
- package/dist/schemas/utils.js +0 -49
- package/dist/types/index.d.ts +0 -433
- package/dist/types/index.js +0 -1
- package/dist/validator/ajv-validator.d.ts +0 -15
- package/dist/validator/ajv-validator.js +0 -75
- package/dist/validator/config-validator-main.d.ts +0 -10
- package/dist/validator/config-validator-main.js +0 -31
- package/dist/validator/config-validator.d.ts +0 -5
- package/dist/validator/config-validator.js +0 -14
- package/dist/validator/index.d.ts +0 -10
- package/dist/validator/index.js +0 -11
- package/dist/validator/object-traversal.d.ts +0 -52
- package/dist/validator/object-traversal.js +0 -104
- package/dist/validator/reference-validator.d.ts +0 -31
- package/dist/validator/reference-validator.js +0 -230
- package/dist/validator/schema-references.d.ts +0 -23
- package/dist/validator/schema-references.js +0 -111
- package/dist/validator/semantic-validator.d.ts +0 -26
- package/dist/validator/semantic-validator.js +0 -325
- package/dist/validator/tests-validator.d.ts +0 -9
- package/dist/validator/tests-validator.js +0 -13
- package/dist/validator/types.d.ts +0 -29
- package/dist/validator/types.js +0 -1
- package/dist/validator/unispec-validator.d.ts +0 -15
- package/dist/validator/unispec-validator.js +0 -81
- package/dist/validator/validator-factory.d.ts +0 -10
- package/dist/validator/validator-factory.js +0 -73
- package/dist/versions.d.ts +0 -10
- package/dist/versions.js +0 -143
|
@@ -1,325 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Validate naming conventions across the UniSpec document.
|
|
3
|
-
*/
|
|
4
|
-
function validateNamingConventions(doc, options) {
|
|
5
|
-
const errors = [];
|
|
6
|
-
if (!options.strictNaming)
|
|
7
|
-
return errors;
|
|
8
|
-
// Validate service name
|
|
9
|
-
if (doc.service.name) {
|
|
10
|
-
if (!/^[a-z][a-z0-9-]*$/.test(doc.service.name)) {
|
|
11
|
-
errors.push({
|
|
12
|
-
message: "Service name should use kebab-case starting with lowercase letter",
|
|
13
|
-
path: "/service/name",
|
|
14
|
-
code: "naming_convention",
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
// Validate REST route names
|
|
19
|
-
const restRoutes = doc.service?.protocols?.rest?.routes || [];
|
|
20
|
-
for (const route of restRoutes) {
|
|
21
|
-
if (route.name && !/^[a-z][a-zA-Z0-9]*$/.test(route.name)) {
|
|
22
|
-
errors.push({
|
|
23
|
-
message: "REST route name should use camelCase starting with lowercase letter",
|
|
24
|
-
path: `/service/protocols/rest/routes/${route.name}/name`,
|
|
25
|
-
code: "naming_convention",
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
// Validate path parameters naming
|
|
29
|
-
if (route.pathParams) {
|
|
30
|
-
for (const param of route.pathParams) {
|
|
31
|
-
if (param.name && !/^[a-z][a-zA-Z0-9]*$/.test(param.name)) {
|
|
32
|
-
errors.push({
|
|
33
|
-
message: "Path parameter name should use camelCase starting with lowercase letter",
|
|
34
|
-
path: `/service/protocols/rest/routes/${route.name}/pathParams/${param.name}/name`,
|
|
35
|
-
code: "naming_convention",
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
// Validate GraphQL operation names
|
|
42
|
-
const graphql = doc.service?.protocols?.graphql;
|
|
43
|
-
if (graphql) {
|
|
44
|
-
const operations = [
|
|
45
|
-
...(graphql.queries || []),
|
|
46
|
-
...(graphql.mutations || []),
|
|
47
|
-
...(graphql.subscriptions || []),
|
|
48
|
-
];
|
|
49
|
-
for (const op of operations) {
|
|
50
|
-
if (op.name && !/^[A-Z][a-zA-Z]*$/.test(op.name)) {
|
|
51
|
-
errors.push({
|
|
52
|
-
message: "GraphQL operation name should use PascalCase starting with uppercase letter",
|
|
53
|
-
path: `/service/protocols/graphql/${op.name}/name`,
|
|
54
|
-
code: "naming_convention",
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
// Validate WebSocket channel and message names
|
|
60
|
-
const websocket = doc.service?.protocols?.websocket;
|
|
61
|
-
if (websocket?.channels) {
|
|
62
|
-
for (const channel of websocket.channels) {
|
|
63
|
-
if (channel.name && !/^[a-z][a-zA-Z0-9]*$/.test(channel.name)) {
|
|
64
|
-
errors.push({
|
|
65
|
-
message: "WebSocket channel name should use camelCase starting with lowercase letter",
|
|
66
|
-
path: `/service/protocols/websocket/channels/${channel.name}/name`,
|
|
67
|
-
code: "naming_convention",
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
if (channel.messages) {
|
|
71
|
-
for (const message of channel.messages) {
|
|
72
|
-
if (message.name && !/^[a-z][a-zA-Z0-9]*$/.test(message.name)) {
|
|
73
|
-
errors.push({
|
|
74
|
-
message: "WebSocket message name should use camelCase starting with lowercase letter",
|
|
75
|
-
path: `/service/protocols/websocket/channels/${channel.name}/messages/${message.name}/name`,
|
|
76
|
-
code: "naming_convention",
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return errors;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Validate URL patterns and formats.
|
|
87
|
-
*/
|
|
88
|
-
function validateUrlPatterns(doc, options) {
|
|
89
|
-
const errors = [];
|
|
90
|
-
if (!options.checkUrlPatterns)
|
|
91
|
-
return errors;
|
|
92
|
-
// Validate baseUrl
|
|
93
|
-
if (doc.service.baseUrl) {
|
|
94
|
-
try {
|
|
95
|
-
new URL(doc.service.baseUrl);
|
|
96
|
-
if (!doc.service.baseUrl.startsWith("http") &&
|
|
97
|
-
!doc.service.baseUrl.startsWith("https")) {
|
|
98
|
-
errors.push({
|
|
99
|
-
message: "baseUrl should start with http:// or https://",
|
|
100
|
-
path: "/service/baseUrl",
|
|
101
|
-
code: "invalid_url",
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
catch {
|
|
106
|
-
errors.push({
|
|
107
|
-
message: "baseUrl is not a valid URL",
|
|
108
|
-
path: "/service/baseUrl",
|
|
109
|
-
code: "invalid_url",
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
// Validate REST route paths
|
|
114
|
-
const restRoutes = doc.service?.protocols?.rest?.routes || [];
|
|
115
|
-
for (const route of restRoutes) {
|
|
116
|
-
if (route.path) {
|
|
117
|
-
// Path should start with /
|
|
118
|
-
if (!route.path.startsWith("/")) {
|
|
119
|
-
errors.push({
|
|
120
|
-
message: "REST route path should start with '/'",
|
|
121
|
-
path: `/service/protocols/rest/routes/${route.name}/path`,
|
|
122
|
-
code: "invalid_path",
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
// Check for path parameter consistency
|
|
126
|
-
const pathParamMatches = route.path.match(/:\w+/g) || [];
|
|
127
|
-
const declaredParams = route.pathParams?.map((p) => p.name) || [];
|
|
128
|
-
for (const param of pathParamMatches) {
|
|
129
|
-
const paramName = param.slice(1); // Remove ':'
|
|
130
|
-
if (!declaredParams.includes(paramName)) {
|
|
131
|
-
errors.push({
|
|
132
|
-
message: `Path parameter '${paramName}' is used in path but not declared in pathParams`,
|
|
133
|
-
path: `/service/protocols/rest/routes/${route.name}/path`,
|
|
134
|
-
code: "undeclared_parameter",
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
// Check for declared parameters not used in path
|
|
139
|
-
for (const declaredParam of declaredParams) {
|
|
140
|
-
if (!pathParamMatches.some((match) => match.slice(1) === declaredParam)) {
|
|
141
|
-
errors.push({
|
|
142
|
-
message: `Path parameter '${declaredParam}' is declared but not used in path`,
|
|
143
|
-
path: `/service/protocols/rest/routes/${route.name}/pathParams/${declaredParam}`,
|
|
144
|
-
code: "unused_parameter",
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
return errors;
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Check for name conflicts across different components.
|
|
154
|
-
*/
|
|
155
|
-
function validateNameConflicts(doc, options) {
|
|
156
|
-
const errors = [];
|
|
157
|
-
if (!options.checkNameConflicts)
|
|
158
|
-
return errors;
|
|
159
|
-
const allNames = new Map();
|
|
160
|
-
// Collect REST route names
|
|
161
|
-
const restRoutes = doc.service?.protocols?.rest?.routes || [];
|
|
162
|
-
for (const route of restRoutes) {
|
|
163
|
-
if (route.name) {
|
|
164
|
-
const existing = allNames.get(route.name) || [];
|
|
165
|
-
existing.push(`REST route: ${route.path} ${route.method}`);
|
|
166
|
-
allNames.set(route.name, existing);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
// Collect GraphQL operation names
|
|
170
|
-
const graphql = doc.service?.protocols?.graphql;
|
|
171
|
-
if (graphql) {
|
|
172
|
-
const operations = [
|
|
173
|
-
...(graphql.queries || []),
|
|
174
|
-
...(graphql.mutations || []),
|
|
175
|
-
...(graphql.subscriptions || []),
|
|
176
|
-
];
|
|
177
|
-
for (const op of operations) {
|
|
178
|
-
if (op.name) {
|
|
179
|
-
const existing = allNames.get(op.name) || [];
|
|
180
|
-
existing.push(`GraphQL operation`);
|
|
181
|
-
allNames.set(op.name, existing);
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
// Collect WebSocket channel names
|
|
186
|
-
const websocket = doc.service?.protocols?.websocket;
|
|
187
|
-
if (websocket?.channels) {
|
|
188
|
-
for (const channel of websocket.channels) {
|
|
189
|
-
if (channel.name) {
|
|
190
|
-
const existing = allNames.get(channel.name) || [];
|
|
191
|
-
existing.push(`WebSocket channel`);
|
|
192
|
-
allNames.set(channel.name, existing);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
// Check for conflicts
|
|
197
|
-
for (const [name, locations] of allNames.entries()) {
|
|
198
|
-
if (locations.length > 1) {
|
|
199
|
-
errors.push({
|
|
200
|
-
message: `Name '${name}' is used in multiple locations: ${locations.join(", ")}`,
|
|
201
|
-
path: "",
|
|
202
|
-
code: "name_conflict",
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
return errors;
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* Check for circular dependencies in schemas.
|
|
210
|
-
*/
|
|
211
|
-
function validateCircularDependencies(doc, options) {
|
|
212
|
-
const errors = [];
|
|
213
|
-
if (!options.checkCircularDependencies)
|
|
214
|
-
return errors;
|
|
215
|
-
const schemas = doc.service?.schemas;
|
|
216
|
-
if (!schemas)
|
|
217
|
-
return errors;
|
|
218
|
-
// Build dependency graph
|
|
219
|
-
const dependencies = new Map();
|
|
220
|
-
for (const [schemaName, schema] of Object.entries(schemas)) {
|
|
221
|
-
const deps = new Set();
|
|
222
|
-
findSchemaReferences(schema.jsonSchema, deps);
|
|
223
|
-
dependencies.set(schemaName, deps);
|
|
224
|
-
}
|
|
225
|
-
// Check for circular dependencies
|
|
226
|
-
const visited = new Set();
|
|
227
|
-
const recursionStack = new Set();
|
|
228
|
-
function hasCycle(schemaName, path) {
|
|
229
|
-
if (recursionStack.has(schemaName)) {
|
|
230
|
-
const cycle = [...path.slice(path.indexOf(schemaName)), schemaName].join(" -> ");
|
|
231
|
-
errors.push({
|
|
232
|
-
message: `Circular dependency detected in schemas: ${cycle}`,
|
|
233
|
-
path: `/service/schemas/${schemaName}`,
|
|
234
|
-
code: "circular_dependency",
|
|
235
|
-
});
|
|
236
|
-
return true;
|
|
237
|
-
}
|
|
238
|
-
if (visited.has(schemaName))
|
|
239
|
-
return false;
|
|
240
|
-
visited.add(schemaName);
|
|
241
|
-
recursionStack.add(schemaName);
|
|
242
|
-
const deps = dependencies.get(schemaName) || new Set();
|
|
243
|
-
for (const dep of deps) {
|
|
244
|
-
if (hasCycle(dep, [...path, schemaName])) {
|
|
245
|
-
return true;
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
recursionStack.delete(schemaName);
|
|
249
|
-
return false;
|
|
250
|
-
}
|
|
251
|
-
for (const schemaName of Object.keys(schemas)) {
|
|
252
|
-
if (!visited.has(schemaName)) {
|
|
253
|
-
hasCycle(schemaName, []);
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
return errors;
|
|
257
|
-
}
|
|
258
|
-
/**
|
|
259
|
-
* Find all schema references in a JSON Schema object.
|
|
260
|
-
*/
|
|
261
|
-
function findSchemaReferences(schema, dependencies) {
|
|
262
|
-
if (!schema || typeof schema !== "object")
|
|
263
|
-
return;
|
|
264
|
-
const schemaRecord = schema;
|
|
265
|
-
// Check for $ref
|
|
266
|
-
if (schemaRecord.$ref && typeof schemaRecord.$ref === "string") {
|
|
267
|
-
const ref = schemaRecord.$ref;
|
|
268
|
-
if (ref.startsWith("#/service/schemas/")) {
|
|
269
|
-
const schemaName = ref.split("/").pop();
|
|
270
|
-
if (schemaName) {
|
|
271
|
-
dependencies.add(schemaName);
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
// Check for schemaRef
|
|
276
|
-
if (schemaRecord.schemaRef && typeof schemaRecord.schemaRef === "string") {
|
|
277
|
-
dependencies.add(schemaRecord.schemaRef);
|
|
278
|
-
}
|
|
279
|
-
// Recursively check all properties
|
|
280
|
-
for (const [_key, value] of Object.entries(schemaRecord)) {
|
|
281
|
-
if (Array.isArray(value)) {
|
|
282
|
-
for (const item of value) {
|
|
283
|
-
findSchemaReferences(item, dependencies);
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
else if (typeof value === "object" && value !== null) {
|
|
287
|
-
findSchemaReferences(value, dependencies);
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
/**
|
|
292
|
-
* Perform semantic validation on a UniSpec document.
|
|
293
|
-
*
|
|
294
|
-
* This function goes beyond JSON Schema validation to check:
|
|
295
|
-
* - Naming conventions
|
|
296
|
-
* - URL patterns
|
|
297
|
-
* - Name conflicts
|
|
298
|
-
* - Circular dependencies
|
|
299
|
-
*
|
|
300
|
-
* @param doc - The UniSpec document to validate
|
|
301
|
-
* @param options - Validation options
|
|
302
|
-
* @returns Semantic validation result
|
|
303
|
-
*/
|
|
304
|
-
export function validateSemantic(doc, options = {}) {
|
|
305
|
-
const errors = [];
|
|
306
|
-
const warnings = [];
|
|
307
|
-
// Default options
|
|
308
|
-
const opts = {
|
|
309
|
-
strictNaming: true,
|
|
310
|
-
checkUrlPatterns: true,
|
|
311
|
-
checkNameConflicts: true,
|
|
312
|
-
checkCircularDependencies: true,
|
|
313
|
-
...options,
|
|
314
|
-
};
|
|
315
|
-
// Run all semantic validations
|
|
316
|
-
errors.push(...validateNamingConventions(doc, opts));
|
|
317
|
-
errors.push(...validateUrlPatterns(doc, opts));
|
|
318
|
-
errors.push(...validateNameConflicts(doc, opts));
|
|
319
|
-
errors.push(...validateCircularDependencies(doc, opts));
|
|
320
|
-
return {
|
|
321
|
-
valid: errors.length === 0,
|
|
322
|
-
errors,
|
|
323
|
-
warnings,
|
|
324
|
-
};
|
|
325
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { ValidateOptions } from "./types.js";
|
|
2
|
-
/**
|
|
3
|
-
* Validate a UniSpec Tests document against the UniSpec Tests JSON Schema.
|
|
4
|
-
*
|
|
5
|
-
* @param doc - The UniSpec Tests document to validate
|
|
6
|
-
* @param options - Validation options including custom schemas
|
|
7
|
-
* @returns Validation result with success status and error details
|
|
8
|
-
*/
|
|
9
|
-
export declare const validateUniSpecTests: (doc: unknown, options?: ValidateOptions) => Promise<import("../index.js").ValidationResult>;
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { getValidator } from "./ajv-validator.js";
|
|
2
|
-
import { createValidator } from "./validator-factory.js";
|
|
3
|
-
/**
|
|
4
|
-
* Validate a UniSpec Tests document against the UniSpec Tests JSON Schema.
|
|
5
|
-
*
|
|
6
|
-
* @param doc - The UniSpec Tests document to validate
|
|
7
|
-
* @param options - Validation options including custom schemas
|
|
8
|
-
* @returns Validation result with success status and error details
|
|
9
|
-
*/
|
|
10
|
-
export const validateUniSpecTests = createValidator("unispecTests", async (options) => {
|
|
11
|
-
const { validateUniSpecTestsFn } = await getValidator(options);
|
|
12
|
-
return validateUniSpecTestsFn;
|
|
13
|
-
});
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type { ValidationResult } from "../types/index.js";
|
|
2
|
-
import type { ReferenceValidationOptions, ReferenceValidationResult } from "./reference-validator.js";
|
|
3
|
-
import type { SemanticValidationOptions, SemanticValidationResult } from "./semantic-validator.js";
|
|
4
|
-
export interface SchemaProvider {
|
|
5
|
-
getSchema: (schemaPath: string) => Promise<object>;
|
|
6
|
-
}
|
|
7
|
-
export interface ValidatorSchemas {
|
|
8
|
-
unispec: object;
|
|
9
|
-
unispecTests?: object;
|
|
10
|
-
unispecConfig?: object;
|
|
11
|
-
subschemas?: object[];
|
|
12
|
-
}
|
|
13
|
-
export interface ValidateOptions {
|
|
14
|
-
schemas?: ValidatorSchemas;
|
|
15
|
-
schemaProvider?: SchemaProvider;
|
|
16
|
-
ajvOptions?: ConstructorParameters<typeof Ajv2020>[0];
|
|
17
|
-
semanticValidation?: SemanticValidationOptions;
|
|
18
|
-
referenceValidation?: ReferenceValidationOptions;
|
|
19
|
-
enableExtendedValidation?: boolean;
|
|
20
|
-
}
|
|
21
|
-
export interface ExtendedValidationResult extends ValidationResult {
|
|
22
|
-
semantic?: SemanticValidationResult;
|
|
23
|
-
references?: ReferenceValidationResult;
|
|
24
|
-
}
|
|
25
|
-
import type Ajv2020 from "ajv/dist/2020.js";
|
|
26
|
-
export type { Ajv2020 };
|
|
27
|
-
export type AjvValidateFn = ((data: unknown) => boolean) & {
|
|
28
|
-
errors?: import("ajv/dist/2020.js").ErrorObject[] | null | undefined;
|
|
29
|
-
};
|
package/dist/validator/types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { UniSpecDocument, ValidationResult } from "../types/index.js";
|
|
2
|
-
import type { ExtendedValidationResult, ValidateOptions } from "./types.js";
|
|
3
|
-
/**
|
|
4
|
-
* Validate a UniSpec document with optional extended validation.
|
|
5
|
-
*
|
|
6
|
-
* This function performs:
|
|
7
|
-
* - JSON Schema validation (always)
|
|
8
|
-
* - Semantic validation (optional, when enableExtendedValidation is true)
|
|
9
|
-
* - Reference validation (optional, when enableExtendedValidation is true)
|
|
10
|
-
*
|
|
11
|
-
* @param doc - The UniSpec document to validate
|
|
12
|
-
* @param options - Validation options
|
|
13
|
-
* @returns Validation result with optional extended results
|
|
14
|
-
*/
|
|
15
|
-
export declare function validateUniSpec(doc: UniSpecDocument, options?: ValidateOptions): Promise<ValidationResult | ExtendedValidationResult>;
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import { ErrorFactory } from "../errors/index.js";
|
|
2
|
-
import { getValidator } from "./ajv-validator.js";
|
|
3
|
-
import { validateReferences } from "./reference-validator.js";
|
|
4
|
-
import { validateSemantic } from "./semantic-validator.js";
|
|
5
|
-
import { mapAjvErrors } from "./validator-factory.js";
|
|
6
|
-
/**
|
|
7
|
-
* Validate a UniSpec document with optional extended validation.
|
|
8
|
-
*
|
|
9
|
-
* This function performs:
|
|
10
|
-
* - JSON Schema validation (always)
|
|
11
|
-
* - Semantic validation (optional, when enableExtendedValidation is true)
|
|
12
|
-
* - Reference validation (optional, when enableExtendedValidation is true)
|
|
13
|
-
*
|
|
14
|
-
* @param doc - The UniSpec document to validate
|
|
15
|
-
* @param options - Validation options
|
|
16
|
-
* @returns Validation result with optional extended results
|
|
17
|
-
*/
|
|
18
|
-
export async function validateUniSpec(doc, options = {}) {
|
|
19
|
-
// Always perform basic JSON Schema validation
|
|
20
|
-
const basicResult = await validateUniSpecBase(doc, options);
|
|
21
|
-
// If extended validation is disabled, return basic result
|
|
22
|
-
if (!options.enableExtendedValidation) {
|
|
23
|
-
return basicResult;
|
|
24
|
-
}
|
|
25
|
-
// Perform extended validation
|
|
26
|
-
const result = {
|
|
27
|
-
valid: basicResult.valid,
|
|
28
|
-
errors: [...basicResult.errors],
|
|
29
|
-
};
|
|
30
|
-
// Perform semantic validation
|
|
31
|
-
if (options.semanticValidation) {
|
|
32
|
-
const semanticResult = validateSemantic(doc, options.semanticValidation);
|
|
33
|
-
result.semantic = semanticResult;
|
|
34
|
-
if (!semanticResult.valid) {
|
|
35
|
-
result.valid = false;
|
|
36
|
-
result.errors.push(...semanticResult.errors);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
// Perform reference validation
|
|
40
|
-
if (options.referenceValidation) {
|
|
41
|
-
const referenceResult = validateReferences(doc, options.referenceValidation);
|
|
42
|
-
result.references = referenceResult;
|
|
43
|
-
if (!referenceResult.valid) {
|
|
44
|
-
result.valid = false;
|
|
45
|
-
result.errors.push(...referenceResult.errors);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
return result;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Internal function for basic JSON Schema validation.
|
|
52
|
-
*/
|
|
53
|
-
async function validateUniSpecBase(doc, options = {}) {
|
|
54
|
-
try {
|
|
55
|
-
const { validateUniSpecFn } = await getValidator(options);
|
|
56
|
-
// Ensure the document has required fields for validation
|
|
57
|
-
const docForValidation = {
|
|
58
|
-
unispecVersion: doc.unispecVersion || "1.0.0",
|
|
59
|
-
service: doc.service,
|
|
60
|
-
};
|
|
61
|
-
const valid = validateUniSpecFn(docForValidation);
|
|
62
|
-
const schemaErrors = mapAjvErrors(validateUniSpecFn.errors);
|
|
63
|
-
if (valid) {
|
|
64
|
-
return {
|
|
65
|
-
valid: true,
|
|
66
|
-
errors: [],
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
return {
|
|
70
|
-
valid: false,
|
|
71
|
-
errors: schemaErrors,
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
catch (error) {
|
|
75
|
-
const validationError = ErrorFactory.fromError(error, "validation_error");
|
|
76
|
-
return {
|
|
77
|
-
valid: false,
|
|
78
|
-
errors: [validationError.toJSON()],
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { ValidationError } from "../types/index.js";
|
|
2
|
-
import type { AjvValidateFn, ValidateOptions } from "./types.js";
|
|
3
|
-
/**
|
|
4
|
-
* Generic validator factory to reduce code duplication.
|
|
5
|
-
*/
|
|
6
|
-
export declare function createValidator<T>(documentType: "unispec" | "unispecTests" | "unispecConfig", getValidatorFn: (options: ValidateOptions) => Promise<AjvValidateFn | undefined>, customValidation?: (doc: T) => ValidationError[]): (doc: T, options?: ValidateOptions) => Promise<import("../types/index.js").ValidationResult>;
|
|
7
|
-
/**
|
|
8
|
-
* Map AJV errors to specific UniSpec validation errors.
|
|
9
|
-
*/
|
|
10
|
-
export declare function mapAjvErrors(errors: import("ajv/dist/2020.js").ErrorObject[] | null | undefined): ValidationError[];
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import { ErrorFactory } from "../errors/index.js";
|
|
2
|
-
/**
|
|
3
|
-
* Generic validator factory to reduce code duplication.
|
|
4
|
-
*/
|
|
5
|
-
export function createValidator(documentType, getValidatorFn, customValidation) {
|
|
6
|
-
return async function validate(doc, options = {}) {
|
|
7
|
-
try {
|
|
8
|
-
const validateFn = await getValidatorFn(options);
|
|
9
|
-
if (!validateFn) {
|
|
10
|
-
return {
|
|
11
|
-
valid: false,
|
|
12
|
-
errors: [
|
|
13
|
-
{
|
|
14
|
-
message: `${documentType} validation schema is not available. Provide appropriate schema in ValidateOptions.`,
|
|
15
|
-
path: "",
|
|
16
|
-
code: "schema_missing",
|
|
17
|
-
},
|
|
18
|
-
],
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
const valid = validateFn(doc);
|
|
22
|
-
// Run custom validation if provided
|
|
23
|
-
const customErrors = customValidation ? customValidation(doc) : [];
|
|
24
|
-
const schemaErrors = valid ? [] : mapAjvErrors(validateFn.errors);
|
|
25
|
-
const allErrors = [...schemaErrors, ...customErrors];
|
|
26
|
-
if (valid && customErrors.length === 0) {
|
|
27
|
-
return {
|
|
28
|
-
valid: true,
|
|
29
|
-
errors: [],
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
return {
|
|
33
|
-
valid: false,
|
|
34
|
-
errors: allErrors,
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
catch (error) {
|
|
38
|
-
const validationError = ErrorFactory.fromError(error, `${documentType}_validation_error`);
|
|
39
|
-
return {
|
|
40
|
-
valid: false,
|
|
41
|
-
errors: [validationError.toJSON()],
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Map AJV errors to specific UniSpec validation errors.
|
|
48
|
-
*/
|
|
49
|
-
export function mapAjvErrors(errors) {
|
|
50
|
-
if (!errors)
|
|
51
|
-
return [];
|
|
52
|
-
return errors.map((error) => {
|
|
53
|
-
const message = error.message || "UniSpec validation error";
|
|
54
|
-
const path = error.instancePath || error.schemaPath;
|
|
55
|
-
const _code = error.keyword;
|
|
56
|
-
// Create specific error types based on keyword
|
|
57
|
-
switch (error.keyword) {
|
|
58
|
-
case "required":
|
|
59
|
-
return ErrorFactory.createSchemaError(`Missing required property: ${message}`, path, { keyword: error.keyword, params: error.params });
|
|
60
|
-
case "type":
|
|
61
|
-
return ErrorFactory.createSchemaError(`Invalid type: ${message}`, path, { keyword: error.keyword, params: error.params });
|
|
62
|
-
case "format":
|
|
63
|
-
return ErrorFactory.createSchemaError(`Invalid format: ${message}`, path, { keyword: error.keyword, params: error.params });
|
|
64
|
-
case "additionalProperties":
|
|
65
|
-
return ErrorFactory.createSchemaError(`Additional property not allowed: ${message}`, path, { keyword: error.keyword, params: error.params });
|
|
66
|
-
default:
|
|
67
|
-
return ErrorFactory.createSchemaError(message, path, {
|
|
68
|
-
keyword: error.keyword,
|
|
69
|
-
params: error.params,
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
}
|
package/dist/versions.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Get the latest supported UniSpec version from @unispechq/unispec-schema package
|
|
3
|
-
* The version is derived from the package.json version (major.minor.0 format)
|
|
4
|
-
* @returns The latest UniSpec format version (SemVer)
|
|
5
|
-
*/
|
|
6
|
-
export declare function getLatestUniSpecVersion(): string;
|
|
7
|
-
/**
|
|
8
|
-
* Clear the version cache (useful for testing or dynamic updates)
|
|
9
|
-
*/
|
|
10
|
-
export declare function clearVersionCache(): void;
|