@opsydyn/elysia-spectral 0.5.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/README.md +35 -0
- package/dist/core/index.d.mts +1 -1
- package/dist/core/index.mjs +1 -1
- package/dist/{core-DTKNy6TU.mjs → core-BIi33eA1.mjs} +15 -2
- package/dist/{index-11HnbLDN.d.mts → index--_yjTKg8.d.mts} +2 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.0.0](https://github.com/opsydyn/elysia-spectral/compare/v0.5.2...v1.0.0) (2026-04-15)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### ⚠ BREAKING CHANGES
|
|
7
|
+
|
|
8
|
+
* result.artifacts paths are now relative (e.g. "./artifacts/openapi-lint.json") rather than absolute. Callers that used the path directly to open the file should resolve it with path.resolve().
|
|
9
|
+
|
|
10
|
+
### Features
|
|
11
|
+
|
|
12
|
+
* add durationMs, failOn to LintRunResult; relativise artifact paths ([421a20f](https://github.com/opsydyn/elysia-spectral/commit/421a20f6bf655432bceff8369c63bf4762edbc24))
|
|
13
|
+
|
|
3
14
|
## [0.5.2](https://github.com/opsydyn/elysia-spectral/compare/v0.5.1...v0.5.2) (2026-04-15)
|
|
4
15
|
|
|
5
16
|
|
package/README.md
CHANGED
|
@@ -63,6 +63,35 @@ Current package scope:
|
|
|
63
63
|
- reusable runtime for CI and tests
|
|
64
64
|
- opt-in healthcheck endpoint for cached and fresh runs
|
|
65
65
|
|
|
66
|
+
## Data flow
|
|
67
|
+
|
|
68
|
+
```mermaid
|
|
69
|
+
flowchart TD
|
|
70
|
+
A["Elysia routes\n(TypeScript + t.Object schemas)"]
|
|
71
|
+
B["@elysiajs/openapi\ngenerates OpenAPI spec at runtime"]
|
|
72
|
+
C["PublicSpecProvider\nfetches /openapi/json"]
|
|
73
|
+
D["lintOpenApi\nSpectral rules engine"]
|
|
74
|
+
E["LintRunResult\n{ ok, source, summary, findings }"]
|
|
75
|
+
|
|
76
|
+
F["Console output"]
|
|
77
|
+
G["JSON report\nopenapi-lint.json"]
|
|
78
|
+
H["OpenAPI snapshot\n*.open-api.json"]
|
|
79
|
+
I["SARIF\nGitHub code scanning"]
|
|
80
|
+
J["JUnit\nCI test reporters"]
|
|
81
|
+
K["Bruno collection\n.yml / .json"]
|
|
82
|
+
|
|
83
|
+
A -->|"route schemas are\nthe source of truth"| B
|
|
84
|
+
B -->|"spec JSON"| C
|
|
85
|
+
C -->|"spec JSON"| D
|
|
86
|
+
D -->|"findings + summary"| E
|
|
87
|
+
E --> F
|
|
88
|
+
E --> G
|
|
89
|
+
E --> H
|
|
90
|
+
E --> I
|
|
91
|
+
E --> J
|
|
92
|
+
E --> K
|
|
93
|
+
```
|
|
94
|
+
|
|
66
95
|
## Tutorial
|
|
67
96
|
|
|
68
97
|
### Add OpenAPI linting to an Elysia app
|
|
@@ -153,6 +182,10 @@ bun run src/index.ts
|
|
|
153
182
|
- `./artifacts/openapi-lint.json` contains the full lint result
|
|
154
183
|
- `./<package-name>.open-api.json` contains the generated OpenAPI snapshot
|
|
155
184
|
|
|
185
|
+
A passing run:
|
|
186
|
+
|
|
187
|
+

|
|
188
|
+
|
|
156
189
|
If startup fails, the terminal output includes:
|
|
157
190
|
|
|
158
191
|
- the failing rule code
|
|
@@ -160,6 +193,8 @@ If startup fails, the terminal output includes:
|
|
|
160
193
|
- a fix hint when one is known
|
|
161
194
|
- a spec reference in `open-api.json#/json/pointer` form
|
|
162
195
|
|
|
196
|
+

|
|
197
|
+
|
|
163
198
|
### Choose a preset
|
|
164
199
|
|
|
165
200
|
Three first-party presets are available. Import them directly or set `preset` in the plugin options.
|
package/dist/core/index.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as createOpenApiLintRuntime, c as ResolvedRulesetCandidate, d as RulesetResolverContext, f as RulesetResolverInput, g as lintOpenApi, h as loadRuleset, i as OpenApiLintArtifactWriteError, l as RulesetLoadError, m as loadResolvedRuleset, n as enforceThreshold, o as LoadResolvedRulesetOptions, p as defaultRulesetResolvers, r as shouldFail, s as LoadedRuleset, t as OpenApiLintThresholdError, u as RulesetResolver } from "../index
|
|
1
|
+
import { a as createOpenApiLintRuntime, c as ResolvedRulesetCandidate, d as RulesetResolverContext, f as RulesetResolverInput, g as lintOpenApi, h as loadRuleset, i as OpenApiLintArtifactWriteError, l as RulesetLoadError, m as loadResolvedRuleset, n as enforceThreshold, o as LoadResolvedRulesetOptions, p as defaultRulesetResolvers, r as shouldFail, s as LoadedRuleset, t as OpenApiLintThresholdError, u as RulesetResolver } from "../index--_yjTKg8.mjs";
|
|
2
2
|
export { LoadResolvedRulesetOptions, LoadedRuleset, OpenApiLintArtifactWriteError, OpenApiLintThresholdError, ResolvedRulesetCandidate, RulesetLoadError, RulesetResolver, RulesetResolverContext, RulesetResolverInput, createOpenApiLintRuntime, defaultRulesetResolvers, enforceThreshold, lintOpenApi, loadResolvedRuleset, loadRuleset, shouldFail };
|
package/dist/core/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as enforceThreshold, d as RulesetLoadError, f as defaultRulesetResolvers, g as lintOpenApi, i as OpenApiLintThresholdError, m as loadRuleset, n as createOpenApiLintRuntime, o as shouldFail, p as loadResolvedRuleset, t as OpenApiLintArtifactWriteError } from "../core-
|
|
1
|
+
import { a as enforceThreshold, d as RulesetLoadError, f as defaultRulesetResolvers, g as lintOpenApi, i as OpenApiLintThresholdError, m as loadRuleset, n as createOpenApiLintRuntime, o as shouldFail, p as loadResolvedRuleset, t as OpenApiLintArtifactWriteError } from "../core-BIi33eA1.mjs";
|
|
2
2
|
export { OpenApiLintArtifactWriteError, OpenApiLintThresholdError, RulesetLoadError, createOpenApiLintRuntime, defaultRulesetResolvers, enforceThreshold, lintOpenApi, loadResolvedRuleset, loadRuleset, shouldFail };
|
|
@@ -55,6 +55,8 @@ const normalizeFindings = (diagnostics, spec) => {
|
|
|
55
55
|
ok: summary.error === 0,
|
|
56
56
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
57
57
|
source: "manual",
|
|
58
|
+
failOn: "error",
|
|
59
|
+
durationMs: null,
|
|
58
60
|
summary,
|
|
59
61
|
findings
|
|
60
62
|
};
|
|
@@ -1198,7 +1200,8 @@ const createOpenApiLintRuntime = (options = {}) => {
|
|
|
1198
1200
|
else if (loadedRuleset.source?.path) reporter.ruleset(`OpenAPI lint loaded ruleset ${loadedRuleset.source.path}.`);
|
|
1199
1201
|
const result = await lintOpenApi(spec, loadedRuleset.ruleset);
|
|
1200
1202
|
result.source = source;
|
|
1201
|
-
result.
|
|
1203
|
+
result.failOn = options.failOn ?? "error";
|
|
1204
|
+
result.ok = !shouldFail(result, result.failOn);
|
|
1202
1205
|
await writeOutputSinks(result, spec, options, artifactWriteFailureMode);
|
|
1203
1206
|
runtime.latest = result;
|
|
1204
1207
|
reporter.complete("OpenAPI lint completed.");
|
|
@@ -1206,6 +1209,7 @@ const createOpenApiLintRuntime = (options = {}) => {
|
|
|
1206
1209
|
runtime.status = "passed";
|
|
1207
1210
|
runtime.lastSuccess = result;
|
|
1208
1211
|
finalizeRuntimeRun(runtime, startedAt);
|
|
1212
|
+
result.durationMs = runtime.durationMs;
|
|
1209
1213
|
return result;
|
|
1210
1214
|
} catch (error) {
|
|
1211
1215
|
runtime.status = "failed";
|
|
@@ -1264,9 +1268,18 @@ const writeOutputSinks = async (result, spec, options, artifactWriteFailureMode)
|
|
|
1264
1268
|
throw error;
|
|
1265
1269
|
}
|
|
1266
1270
|
};
|
|
1271
|
+
const relativiseArtifacts = (artifacts) => {
|
|
1272
|
+
const cwd = process.cwd();
|
|
1273
|
+
const result = {};
|
|
1274
|
+
for (const [key, value] of Object.entries(artifacts)) if (typeof value === "string" && path.isAbsolute(value)) {
|
|
1275
|
+
const rel = path.relative(cwd, value);
|
|
1276
|
+
result[key] = rel.startsWith(".") ? rel : `./${rel}`;
|
|
1277
|
+
} else result[key] = value;
|
|
1278
|
+
return result;
|
|
1279
|
+
};
|
|
1267
1280
|
const mergeArtifacts = (current, next) => ({
|
|
1268
1281
|
...current,
|
|
1269
|
-
...next
|
|
1282
|
+
...relativiseArtifacts(next)
|
|
1270
1283
|
});
|
|
1271
1284
|
const resolveStartupMode = (options = {}) => {
|
|
1272
1285
|
if (options.startup?.mode) return options.startup.mode;
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as SpectralLogger, C as OpenApiLintRuntime, D as OpenApiLintSinkContext, E as OpenApiLintSink, M as StartupLintMode, O as PresetName, S as OpenApiLintArtifacts, T as OpenApiLintRuntimeStatus, _ as ArtifactWriteFailureMode, a as createOpenApiLintRuntime, b as LintRunSource, c as ResolvedRulesetCandidate, d as RulesetResolverContext, f as RulesetResolverInput, g as lintOpenApi, h as loadRuleset, i as OpenApiLintArtifactWriteError, j as SpectralPluginOptions, k as SeverityThreshold, l as RulesetLoadError, m as loadResolvedRuleset, n as enforceThreshold, o as LoadResolvedRulesetOptions, p as defaultRulesetResolvers, r as shouldFail, s as LoadedRuleset, t as OpenApiLintThresholdError, u as RulesetResolver, v as LintFinding, w as OpenApiLintRuntimeFailure, x as LintSeverity, y as LintRunResult } from "./index
|
|
1
|
+
import { A as SpectralLogger, C as OpenApiLintRuntime, D as OpenApiLintSinkContext, E as OpenApiLintSink, M as StartupLintMode, O as PresetName, S as OpenApiLintArtifacts, T as OpenApiLintRuntimeStatus, _ as ArtifactWriteFailureMode, a as createOpenApiLintRuntime, b as LintRunSource, c as ResolvedRulesetCandidate, d as RulesetResolverContext, f as RulesetResolverInput, g as lintOpenApi, h as loadRuleset, i as OpenApiLintArtifactWriteError, j as SpectralPluginOptions, k as SeverityThreshold, l as RulesetLoadError, m as loadResolvedRuleset, n as enforceThreshold, o as LoadResolvedRulesetOptions, p as defaultRulesetResolvers, r as shouldFail, s as LoadedRuleset, t as OpenApiLintThresholdError, u as RulesetResolver, v as LintFinding, w as OpenApiLintRuntimeFailure, x as LintSeverity, y as LintRunResult } from "./index--_yjTKg8.mjs";
|
|
2
2
|
import { RulesetDefinition } from "@stoplight/spectral-core";
|
|
3
3
|
import { Elysia } from "elysia";
|
|
4
4
|
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as enforceThreshold, c as strict, d as RulesetLoadError, f as defaultRulesetResolvers, g as lintOpenApi, h as recommended, i as OpenApiLintThresholdError, l as server, m as loadRuleset, n as createOpenApiLintRuntime, o as shouldFail, p as loadResolvedRuleset, r as resolveStartupMode, s as presets, t as OpenApiLintArtifactWriteError, u as resolveReporter } from "./core-
|
|
1
|
+
import { a as enforceThreshold, c as strict, d as RulesetLoadError, f as defaultRulesetResolvers, g as lintOpenApi, h as recommended, i as OpenApiLintThresholdError, l as server, m as loadRuleset, n as createOpenApiLintRuntime, o as shouldFail, p as loadResolvedRuleset, r as resolveStartupMode, s as presets, t as OpenApiLintArtifactWriteError, u as resolveReporter } from "./core-BIi33eA1.mjs";
|
|
2
2
|
import { Elysia } from "elysia";
|
|
3
3
|
//#region src/plugin.ts
|
|
4
4
|
const spectralPlugin = (options = {}) => {
|