@opsydyn/elysia-spectral 1.5.0 → 1.5.1
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 +7 -0
- package/README.md +42 -3
- package/dist/core/index.d.mts +1 -1
- package/dist/core/index.mjs +4 -1
- package/dist/{index-CyJXdIRT.d.mts → index-DzJWrqPA.d.mts} +7 -5
- package/dist/index.d.mts +8 -3
- package/dist/index.mjs +16 -2
- package/dist/lint-openapi-D76sC7S5.mjs +122 -0
- package/dist/load-ruleset-CiikrzWx.mjs +301 -0
- package/dist/presets-CCfU_diN.mjs +132 -0
- package/dist/recommended-DgrTqq-3.mjs +40 -0
- package/dist/rolldown-runtime-wcPFST8Q.mjs +13 -0
- package/dist/ruleset-load-error-CogUOC7W.mjs +10 -0
- package/dist/{core-BLJeXQ15.mjs → runtime-4LlfDIZv.mjs} +13 -570
- package/package.json +1 -1
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-wcPFST8Q.mjs";
|
|
2
|
+
import { t as recommended } from "./recommended-DgrTqq-3.mjs";
|
|
3
|
+
//#region src/presets/server.ts
|
|
4
|
+
const operationSelector$1 = "$.paths[*][get,put,post,delete,options,head,patch,trace]";
|
|
5
|
+
/**
|
|
6
|
+
* Production API quality preset. Suitable as a CI gate for teams shipping
|
|
7
|
+
* public or internal APIs where contract quality matters.
|
|
8
|
+
*
|
|
9
|
+
* Tightens recommended:
|
|
10
|
+
* - elysia-operation-summary and elysia-operation-tags escalated to error
|
|
11
|
+
* - operation-description, operation-operationId, operation-success-response at warn
|
|
12
|
+
* - oas3-api-servers at warn (servers should be declared in production specs)
|
|
13
|
+
*/
|
|
14
|
+
const server = {
|
|
15
|
+
extends: [["spectral:oas", "recommended"]],
|
|
16
|
+
rules: {
|
|
17
|
+
"oas3-api-servers": "warn",
|
|
18
|
+
"info-contact": "off",
|
|
19
|
+
"elysia-operation-summary": {
|
|
20
|
+
description: "Operations should define a summary for generated docs and clients.",
|
|
21
|
+
severity: "error",
|
|
22
|
+
given: operationSelector$1,
|
|
23
|
+
then: {
|
|
24
|
+
field: "summary",
|
|
25
|
+
function: "truthy"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"elysia-operation-tags": {
|
|
29
|
+
description: "Operations should declare at least one tag for grouping and downstream tooling.",
|
|
30
|
+
severity: "error",
|
|
31
|
+
given: operationSelector$1,
|
|
32
|
+
then: {
|
|
33
|
+
field: "tags",
|
|
34
|
+
function: "schema",
|
|
35
|
+
functionOptions: { schema: {
|
|
36
|
+
type: "array",
|
|
37
|
+
minItems: 1
|
|
38
|
+
} }
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"operation-description": "warn",
|
|
42
|
+
"operation-operationId": "warn",
|
|
43
|
+
"operation-success-response": "warn"
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
//#endregion
|
|
47
|
+
//#region src/presets/strict.ts
|
|
48
|
+
const operationSelector = "$.paths[*][get,put,post,delete,options,head,patch,trace]";
|
|
49
|
+
const isRecord = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
|
|
50
|
+
/**
|
|
51
|
+
* Checks that all 4xx/5xx responses declare application/problem+json as
|
|
52
|
+
* their content type, conforming to RFC 9457 Problem Details for HTTP APIs.
|
|
53
|
+
*/
|
|
54
|
+
const checkProblemDetails = (operation) => {
|
|
55
|
+
if (!isRecord(operation) || !isRecord(operation.responses)) return;
|
|
56
|
+
const results = [];
|
|
57
|
+
for (const [statusCode, response] of Object.entries(operation.responses)) {
|
|
58
|
+
const code = Number(statusCode);
|
|
59
|
+
if (!Number.isFinite(code) || code < 400) continue;
|
|
60
|
+
if (!isRecord(response)) continue;
|
|
61
|
+
const content = response.content;
|
|
62
|
+
if (!isRecord(content) || !("application/problem+json" in content)) results.push({
|
|
63
|
+
message: `${statusCode} error response should use "application/problem+json" content type (RFC 9457 Problem Details).`,
|
|
64
|
+
path: ["responses", statusCode]
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
return results.length > 0 ? results : void 0;
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Full API governance preset. Suitable for teams with formal API governance
|
|
71
|
+
* requirements, public API programs, or downstream client generation pipelines.
|
|
72
|
+
*
|
|
73
|
+
* Tightens server:
|
|
74
|
+
* - All elysia rules and operation metadata rules escalated to error
|
|
75
|
+
* - info-contact at warn (API ownership should be declared)
|
|
76
|
+
* - oas3-api-servers at error (server declaration is required)
|
|
77
|
+
* - rfc9457-problem-details at warn (error responses should use Problem Details)
|
|
78
|
+
*/
|
|
79
|
+
const strict = {
|
|
80
|
+
extends: [["spectral:oas", "recommended"]],
|
|
81
|
+
rules: {
|
|
82
|
+
"oas3-api-servers": "error",
|
|
83
|
+
"info-contact": "warn",
|
|
84
|
+
"elysia-operation-summary": {
|
|
85
|
+
description: "Operations should define a summary for generated docs and clients.",
|
|
86
|
+
severity: "error",
|
|
87
|
+
given: operationSelector,
|
|
88
|
+
then: {
|
|
89
|
+
field: "summary",
|
|
90
|
+
function: "truthy"
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
"elysia-operation-tags": {
|
|
94
|
+
description: "Operations should declare at least one tag for grouping and downstream tooling.",
|
|
95
|
+
severity: "error",
|
|
96
|
+
given: operationSelector,
|
|
97
|
+
then: {
|
|
98
|
+
field: "tags",
|
|
99
|
+
function: "schema",
|
|
100
|
+
functionOptions: { schema: {
|
|
101
|
+
type: "array",
|
|
102
|
+
minItems: 1
|
|
103
|
+
} }
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
"operation-description": "error",
|
|
107
|
+
"operation-operationId": "error",
|
|
108
|
+
"operation-success-response": "error",
|
|
109
|
+
"rfc9457-problem-details": {
|
|
110
|
+
description: "Error responses (4xx, 5xx) should use RFC 9457 Problem Details (application/problem+json).",
|
|
111
|
+
message: "{{error}}",
|
|
112
|
+
severity: "warn",
|
|
113
|
+
given: operationSelector,
|
|
114
|
+
then: { function: checkProblemDetails }
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
//#endregion
|
|
119
|
+
//#region src/presets/index.ts
|
|
120
|
+
var presets_exports = /* @__PURE__ */ __exportAll({
|
|
121
|
+
presets: () => presets,
|
|
122
|
+
recommended: () => recommended,
|
|
123
|
+
server: () => server,
|
|
124
|
+
strict: () => strict
|
|
125
|
+
});
|
|
126
|
+
const presets = {
|
|
127
|
+
recommended,
|
|
128
|
+
server,
|
|
129
|
+
strict
|
|
130
|
+
};
|
|
131
|
+
//#endregion
|
|
132
|
+
export { server as i, presets_exports as n, strict as r, presets as t };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
//#region src/presets/recommended.ts
|
|
2
|
+
const operationSelector = "$.paths[*][get,put,post,delete,options,head,patch,trace]";
|
|
3
|
+
/**
|
|
4
|
+
* Baseline quality preset. Equivalent to the package default ruleset.
|
|
5
|
+
*
|
|
6
|
+
* - Extends spectral:oas/recommended
|
|
7
|
+
* - elysia-operation-summary and elysia-operation-tags at warn
|
|
8
|
+
* - oas3-api-servers and info-contact disabled (local-dev friendly)
|
|
9
|
+
*/
|
|
10
|
+
const recommended = {
|
|
11
|
+
extends: [["spectral:oas", "recommended"]],
|
|
12
|
+
rules: {
|
|
13
|
+
"oas3-api-servers": "off",
|
|
14
|
+
"info-contact": "off",
|
|
15
|
+
"elysia-operation-summary": {
|
|
16
|
+
description: "Operations should define a summary for generated docs and clients.",
|
|
17
|
+
severity: "warn",
|
|
18
|
+
given: operationSelector,
|
|
19
|
+
then: {
|
|
20
|
+
field: "summary",
|
|
21
|
+
function: "truthy"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"elysia-operation-tags": {
|
|
25
|
+
description: "Operations should declare at least one tag for grouping and downstream tooling.",
|
|
26
|
+
severity: "warn",
|
|
27
|
+
given: operationSelector,
|
|
28
|
+
then: {
|
|
29
|
+
field: "tags",
|
|
30
|
+
function: "schema",
|
|
31
|
+
functionOptions: { schema: {
|
|
32
|
+
type: "array",
|
|
33
|
+
minItems: 1
|
|
34
|
+
} }
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
//#endregion
|
|
40
|
+
export { recommended as t };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __exportAll = (all, no_symbols) => {
|
|
4
|
+
let target = {};
|
|
5
|
+
for (var name in all) __defProp(target, name, {
|
|
6
|
+
get: all[name],
|
|
7
|
+
enumerable: true
|
|
8
|
+
});
|
|
9
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
10
|
+
return target;
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { __exportAll as t };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
//#region src/core/ruleset-load-error.ts
|
|
2
|
+
var RulesetLoadError = class extends Error {
|
|
3
|
+
constructor(message, options) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = "RulesetLoadError";
|
|
6
|
+
if (options?.cause !== void 0) this.cause = options.cause;
|
|
7
|
+
}
|
|
8
|
+
};
|
|
9
|
+
//#endregion
|
|
10
|
+
export { RulesetLoadError as t };
|