@shipworthy/openapi-parser 0.0.0-stage → 0.0.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/LICENSE +21 -0
- package/README.md +361 -2
- package/dist/bundle.d.ts +973 -0
- package/dist/bundle.js +11 -0
- package/dist/codec.d.ts +2188 -0
- package/dist/codec.js +42 -0
- package/dist/document.d.ts +9 -0
- package/dist/document.js +28 -0
- package/dist/errors.d.ts +105 -0
- package/dist/errors.js +162 -0
- package/dist/hoist.d.ts +10 -0
- package/dist/hoist.js +444 -0
- package/dist/http.d.ts +2 -0
- package/dist/http.js +163 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -0
- package/dist/load.d.ts +17 -0
- package/dist/load.js +128 -0
- package/dist/loader.d.ts +11 -0
- package/dist/loader.js +89 -0
- package/dist/parsers.d.ts +5 -0
- package/dist/parsers.js +90 -0
- package/dist/pipeline.d.ts +3 -0
- package/dist/pipeline.js +446 -0
- package/dist/plugins.d.ts +95 -0
- package/dist/plugins.js +61 -0
- package/dist/pointer.d.ts +7 -0
- package/dist/pointer.js +80 -0
- package/dist/run.d.ts +17 -0
- package/dist/run.js +313 -0
- package/dist/schemas/3.1/callback.d.ts +205 -0
- package/dist/schemas/3.1/callback.js +4 -0
- package/dist/schemas/3.1/components.d.ts +801 -0
- package/dist/schemas/3.1/components.js +25 -0
- package/dist/schemas/3.1/contact.d.ts +7 -0
- package/dist/schemas/3.1/contact.js +7 -0
- package/dist/schemas/3.1/document.d.ts +1093 -0
- package/dist/schemas/3.1/document.js +25 -0
- package/dist/schemas/3.1/encoding.d.ts +14 -0
- package/dist/schemas/3.1/encoding.js +11 -0
- package/dist/schemas/3.1/example.d.ts +8 -0
- package/dist/schemas/3.1/example.js +10 -0
- package/dist/schemas/3.1/external-docs.d.ts +6 -0
- package/dist/schemas/3.1/external-docs.js +6 -0
- package/dist/schemas/3.1/header.d.ts +194 -0
- package/dist/schemas/3.1/header.js +29 -0
- package/dist/schemas/3.1/http-method.d.ts +4 -0
- package/dist/schemas/3.1/http-method.js +12 -0
- package/dist/schemas/3.1/index.d.ts +29 -0
- package/dist/schemas/3.1/index.js +29 -0
- package/dist/schemas/3.1/info.d.ts +19 -0
- package/dist/schemas/3.1/info.js +13 -0
- package/dist/schemas/3.1/license.d.ts +7 -0
- package/dist/schemas/3.1/license.js +9 -0
- package/dist/schemas/3.1/link.d.ts +18 -0
- package/dist/schemas/3.1/link.js +13 -0
- package/dist/schemas/3.1/media-type.d.ts +27 -0
- package/dist/schemas/3.1/media-type.js +14 -0
- package/dist/schemas/3.1/oauth-flow.d.ts +8 -0
- package/dist/schemas/3.1/oauth-flow.js +8 -0
- package/dist/schemas/3.1/oauth-flows.d.ts +28 -0
- package/dist/schemas/3.1/oauth-flows.js +13 -0
- package/dist/schemas/3.1/object.d.ts +5 -0
- package/dist/schemas/3.1/object.js +17 -0
- package/dist/schemas/3.1/operation.d.ts +1040 -0
- package/dist/schemas/3.1/operation.js +25 -0
- package/dist/schemas/3.1/parameter.d.ts +101 -0
- package/dist/schemas/3.1/parameter.js +33 -0
- package/dist/schemas/3.1/path-item.d.ts +127 -0
- package/dist/schemas/3.1/path-item.js +22 -0
- package/dist/schemas/3.1/paths.d.ts +126 -0
- package/dist/schemas/3.1/paths.js +4 -0
- package/dist/schemas/3.1/reference.d.ts +13 -0
- package/dist/schemas/3.1/reference.js +11 -0
- package/dist/schemas/3.1/request-body.d.ts +31 -0
- package/dist/schemas/3.1/request-body.js +8 -0
- package/dist/schemas/3.1/response.d.ts +149 -0
- package/dist/schemas/3.1/response.js +12 -0
- package/dist/schemas/3.1/responses.d.ts +152 -0
- package/dist/schemas/3.1/responses.js +7 -0
- package/dist/schemas/3.1/schema.d.ts +4 -0
- package/dist/schemas/3.1/schema.js +6 -0
- package/dist/schemas/3.1/security-requirement.d.ts +3 -0
- package/dist/schemas/3.1/security-requirement.js +2 -0
- package/dist/schemas/3.1/security-scheme.d.ts +49 -0
- package/dist/schemas/3.1/security-scheme.js +25 -0
- package/dist/schemas/3.1/server-variable.d.ts +7 -0
- package/dist/schemas/3.1/server-variable.js +7 -0
- package/dist/schemas/3.1/server.d.ts +11 -0
- package/dist/schemas/3.1/server.js +8 -0
- package/dist/schemas/3.1/tag.d.ts +10 -0
- package/dist/schemas/3.1/tag.js +8 -0
- package/dist/upgraders/3.0-to-3.1.d.ts +9 -0
- package/dist/upgraders/3.0-to-3.1.js +310 -0
- package/dist/url.d.ts +29 -0
- package/dist/url.js +255 -0
- package/dist/yaml.d.ts +6 -0
- package/dist/yaml.js +235 -0
- package/package.json +50 -4
package/dist/load.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
// oxlint-disable-next-line effecttsgo/node-builtin-import -- Detect the public Node Readable input before adapting it with NodeStream.
|
|
2
|
+
import { Readable } from "node:stream";
|
|
3
|
+
import * as NodeStream from "@effect/platform-node/NodeStream";
|
|
4
|
+
import { Effect, Path, Predicate, Schema, Stream } from "effect";
|
|
5
|
+
import { decodeDocument } from "./document.js";
|
|
6
|
+
import { EmptySource, InvalidSource, ParseError } from "./errors.js";
|
|
7
|
+
import { loadDocument as loadResolvedDocument, makeContext } from "./loader.js";
|
|
8
|
+
import { parseText } from "./parsers.js";
|
|
9
|
+
const loadOptions = Schema.Struct({
|
|
10
|
+
cwd: Schema.optional(Schema.Union([Schema.String, Schema.URL])),
|
|
11
|
+
});
|
|
12
|
+
const emptyPath = "Empty schema. Please specify a URL or file path";
|
|
13
|
+
const emptySchema = "Can’t parse empty schema";
|
|
14
|
+
export const loadDocument = Effect.fn("loadDocument")(function* (source, options) {
|
|
15
|
+
const decoded = yield* Schema.decodeEffect(loadOptions)(options ?? {}).pipe(Effect.mapError(parseFailure));
|
|
16
|
+
const path = yield* Path.Path;
|
|
17
|
+
const cwd = yield* resolveCwd(path, decoded.cwd);
|
|
18
|
+
if (source == null || source === "")
|
|
19
|
+
return yield* new EmptySource({ message: emptyPath });
|
|
20
|
+
const loaded = yield* parseSource(source, cwd);
|
|
21
|
+
const document = yield* Effect.fromResult(decodeDocument(loaded.document));
|
|
22
|
+
return { ...loaded, document };
|
|
23
|
+
});
|
|
24
|
+
const parseSource = Effect.fnUntraced(function* (source, absoluteRef) {
|
|
25
|
+
if (source == null || source === "")
|
|
26
|
+
return yield* new EmptySource({ message: emptySchema });
|
|
27
|
+
if (source instanceof URL) {
|
|
28
|
+
const ref = source.protocol === "file:" ? yield* filePath(source) : source.href;
|
|
29
|
+
const parsed = yield* loadResolvedDocument(source.href, makeContext(source.href, {}, "root")).pipe(Effect.mapError(parseFailure));
|
|
30
|
+
const document = yield* requireDocument(parsed);
|
|
31
|
+
return { document, absoluteRef: ref };
|
|
32
|
+
}
|
|
33
|
+
if (source instanceof Readable) {
|
|
34
|
+
const contents = yield* readReadable(source);
|
|
35
|
+
return yield* parseSource(contents, absoluteRef);
|
|
36
|
+
}
|
|
37
|
+
if (source instanceof Buffer)
|
|
38
|
+
return yield* parseSource(source.toString("utf8"), absoluteRef);
|
|
39
|
+
if (typeof source === "string") {
|
|
40
|
+
if (source.startsWith("http://") ||
|
|
41
|
+
source.startsWith("https://") ||
|
|
42
|
+
source.startsWith("file://")) {
|
|
43
|
+
const url = yield* Effect.try({
|
|
44
|
+
try: () => new URL(source),
|
|
45
|
+
catch: (cause) => new InvalidSource({
|
|
46
|
+
message: Predicate.isError(cause) ? cause.message : `Expected a valid URL`,
|
|
47
|
+
}),
|
|
48
|
+
});
|
|
49
|
+
return yield* parseSource(url, absoluteRef);
|
|
50
|
+
}
|
|
51
|
+
if (isFilePath(source, yield* Path.Path))
|
|
52
|
+
return yield* parseSource(yield* fileUrl(source, absoluteRef), absoluteRef);
|
|
53
|
+
const parsed = yield* parseText(source);
|
|
54
|
+
const document = yield* requireDocument(parsed);
|
|
55
|
+
return { document, absoluteRef };
|
|
56
|
+
}
|
|
57
|
+
const document = yield* Schema.decodeUnknownEffect(documentObject)(source).pipe(Effect.mapError(() => new InvalidSource({
|
|
58
|
+
message: `Expected string, object, or Buffer. Got ${valueKind(source)}`,
|
|
59
|
+
})));
|
|
60
|
+
return { document, absoluteRef };
|
|
61
|
+
});
|
|
62
|
+
/**
|
|
63
|
+
* A single-line string is a filesystem path when it is platform-absolute or starts with
|
|
64
|
+
* `./`, `../`, `.\`, or `..\`. Otherwise, it needs a `.json`, `.yaml`, or `.yml` extension,
|
|
65
|
+
* no `: `, and no leading `{` or `[`. No inline OpenAPI document
|
|
66
|
+
* matches: one-line YAML needs `key: value` or `{...}`, and JSON starts with `{`.
|
|
67
|
+
*/
|
|
68
|
+
function isFilePath(source, path) {
|
|
69
|
+
const value = source.trim();
|
|
70
|
+
if (value === "" || /[\r\n]/.test(value))
|
|
71
|
+
return false;
|
|
72
|
+
if (path.isAbsolute(value) ||
|
|
73
|
+
value.startsWith("./") ||
|
|
74
|
+
value.startsWith("../") ||
|
|
75
|
+
value.startsWith(".\\") ||
|
|
76
|
+
value.startsWith("..\\"))
|
|
77
|
+
return true;
|
|
78
|
+
return ([".json", ".yaml", ".yml"].includes(path.extname(value).toLowerCase()) &&
|
|
79
|
+
!value.includes(": ") &&
|
|
80
|
+
!value.startsWith("{") &&
|
|
81
|
+
!value.startsWith("["));
|
|
82
|
+
}
|
|
83
|
+
/** Resolve a path string against the `cwd` directory URL. */
|
|
84
|
+
const fileUrl = Effect.fnUntraced(function* (source, cwd) {
|
|
85
|
+
const path = yield* Path.Path;
|
|
86
|
+
const value = source.trim();
|
|
87
|
+
if (!path.isAbsolute(value) && !cwd.startsWith("file:")) {
|
|
88
|
+
return yield* Effect.try({ try: () => new URL(value, cwd), catch: parseFailure });
|
|
89
|
+
}
|
|
90
|
+
const directory = path.isAbsolute(value) ? "" : yield* filePath(new URL(cwd));
|
|
91
|
+
return yield* path.toFileUrl(path.resolve(directory, value)).pipe(Effect.mapError(parseFailure));
|
|
92
|
+
});
|
|
93
|
+
const resolveCwd = Effect.fnUntraced(function* (path, cwd) {
|
|
94
|
+
if (cwd instanceof URL) {
|
|
95
|
+
return cwd.href;
|
|
96
|
+
}
|
|
97
|
+
const directory = typeof cwd === "string" ? path.resolve(cwd) : path.resolve(".");
|
|
98
|
+
return yield* path.toFileUrl(directory).pipe(Effect.map((url) => (url.href.endsWith("/") ? url.href : `${url.href}/`)), Effect.mapError(parseFailure));
|
|
99
|
+
});
|
|
100
|
+
const filePath = Effect.fnUntraced(function* (url) {
|
|
101
|
+
const path = yield* Path.Path;
|
|
102
|
+
return yield* path.fromFileUrl(url).pipe(Effect.mapError(parseFailure));
|
|
103
|
+
});
|
|
104
|
+
const readReadable = Effect.fnUntraced(function* (source) {
|
|
105
|
+
return yield* NodeStream.fromReadable({
|
|
106
|
+
evaluate: () => source,
|
|
107
|
+
onError: parseFailure,
|
|
108
|
+
}).pipe(Stream.decodeText, Stream.mkString, Effect.map((text) => text.trim()));
|
|
109
|
+
});
|
|
110
|
+
const documentObject = Schema.Record(Schema.String, Schema.Unknown);
|
|
111
|
+
const requireDocument = Effect.fnUntraced(function* (value) {
|
|
112
|
+
return yield* Schema.decodeUnknownEffect(documentObject)(value).pipe(Effect.mapError(() => new InvalidSource({
|
|
113
|
+
message: `Expected an OpenAPI document object. Got ${valueKind(value)}`,
|
|
114
|
+
})));
|
|
115
|
+
});
|
|
116
|
+
function parseFailure(cause) {
|
|
117
|
+
return new ParseError({
|
|
118
|
+
message: Predicate.isError(cause) ? cause.message : String(cause),
|
|
119
|
+
cause,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
function valueKind(value) {
|
|
123
|
+
if (value === null)
|
|
124
|
+
return "null";
|
|
125
|
+
if (Array.isArray(value))
|
|
126
|
+
return "Array";
|
|
127
|
+
return typeof value;
|
|
128
|
+
}
|
package/dist/loader.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Effect, FileSystem } from "effect";
|
|
2
|
+
import type { HttpClient } from "effect/http";
|
|
3
|
+
import { type TaggedFailure } from "./errors.ts";
|
|
4
|
+
import type { EffectPlugin, Options } from "./plugins.ts";
|
|
5
|
+
export interface LoadContext {
|
|
6
|
+
policy: "root" | "reference";
|
|
7
|
+
resolvers: EffectPlugin<Uint8Array>[];
|
|
8
|
+
parsers: EffectPlugin<unknown>[];
|
|
9
|
+
}
|
|
10
|
+
export declare function makeContext(rootUrl: string, options: Options, policy?: LoadContext["policy"]): LoadContext;
|
|
11
|
+
export declare const loadDocument: (url: string, context: LoadContext) => Effect.Effect<unknown, TaggedFailure, FileSystem.FileSystem | HttpClient.HttpClient>;
|
package/dist/loader.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Effect, FileSystem } from "effect";
|
|
2
|
+
import { ParserFailure, ResolverFailure, UnmatchedParserFailure, UnmatchedResolverFailure, nodeErrorCode, } from "./errors.js";
|
|
3
|
+
import { httpResolver } from "./http.js";
|
|
4
|
+
import { parserPlugins, parseText } from "./parsers.js";
|
|
5
|
+
import { promisePlugin } from "./plugins.js";
|
|
6
|
+
import { extensionOf, isFileSystemPath, stripHash, toFileSystemPath } from "./url.js";
|
|
7
|
+
export function makeContext(rootUrl, options, policy = "reference") {
|
|
8
|
+
return {
|
|
9
|
+
policy,
|
|
10
|
+
resolvers: resolversFor(rootUrl, options, policy),
|
|
11
|
+
parsers: parserPlugins(options),
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export const loadDocument = Effect.fnUntraced(function* (url, context) {
|
|
15
|
+
const file = fileInfo(url);
|
|
16
|
+
const resolvers = context.resolvers.filter((plugin) => plugin.can(file));
|
|
17
|
+
if (resolvers.length === 0) {
|
|
18
|
+
return yield* new UnmatchedResolverFailure({
|
|
19
|
+
message: `Could not find resolver for "${url}"`,
|
|
20
|
+
source: url,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
const bytes = yield* Effect.firstSuccessOf(resolvers.map((plugin) => plugin.run(file)));
|
|
24
|
+
if (context.policy === "root") {
|
|
25
|
+
return yield* parseText(bytes).pipe(Effect.mapError((cause) => new ParserFailure({ message: cause.message, source: url, cause })));
|
|
26
|
+
}
|
|
27
|
+
const parsedFile = { ...file, data: bytes };
|
|
28
|
+
const parsers = context.parsers.filter((plugin) => plugin.can(parsedFile));
|
|
29
|
+
const selected = parsers.length > 0 ? parsers : context.parsers;
|
|
30
|
+
if (selected.length === 0) {
|
|
31
|
+
return yield* new UnmatchedParserFailure({
|
|
32
|
+
message: `Could not find parser for "${url}"`,
|
|
33
|
+
source: url,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
const parsed = yield* Effect.firstSuccessOf(selected.map((plugin) => plugin.run(parsedFile)));
|
|
37
|
+
return parsed;
|
|
38
|
+
});
|
|
39
|
+
function resolversFor(rootUrl, options, policy) {
|
|
40
|
+
const plugins = [];
|
|
41
|
+
if (options.resolve?.file !== false)
|
|
42
|
+
plugins.push(fileResolver());
|
|
43
|
+
const http = httpResolver(rootUrl, options, policy);
|
|
44
|
+
if (http)
|
|
45
|
+
plugins.push(http);
|
|
46
|
+
for (const [index, plugin] of (options.resolvers ?? []).entries())
|
|
47
|
+
plugins.push(customResolver(plugin, index));
|
|
48
|
+
return plugins.sort((left, right) => left.order - right.order);
|
|
49
|
+
}
|
|
50
|
+
const readResolvedFile = Effect.fnUntraced(function* (file) {
|
|
51
|
+
const fs = yield* FileSystem.FileSystem;
|
|
52
|
+
let filePath = toFileSystemPath(file.url);
|
|
53
|
+
if (filePath.endsWith("/") || filePath.endsWith("\\"))
|
|
54
|
+
filePath = filePath.slice(0, -1);
|
|
55
|
+
return yield* fs.readFile(filePath).pipe(Effect.mapError((error) => new ResolverFailure({
|
|
56
|
+
message: `Error opening file ${filePath}: ${error.message}`,
|
|
57
|
+
source: filePath,
|
|
58
|
+
cause: error,
|
|
59
|
+
...ioCode(error),
|
|
60
|
+
})));
|
|
61
|
+
});
|
|
62
|
+
function fileResolver() {
|
|
63
|
+
return {
|
|
64
|
+
order: 100,
|
|
65
|
+
can: (file) => isFileSystemPath(file.url),
|
|
66
|
+
run: readResolvedFile,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function customResolver(plugin, index) {
|
|
70
|
+
const wrapped = promisePlugin(plugin.order ?? 300 + index, (file) => plugin.canRead(file), (file) => plugin.read(file), (cause, file) => new ResolverFailure({
|
|
71
|
+
message: cause instanceof Error ? cause.message : `Error reading file "${file.url}"`,
|
|
72
|
+
source: file.url,
|
|
73
|
+
cause,
|
|
74
|
+
...ioCode(cause),
|
|
75
|
+
}));
|
|
76
|
+
return {
|
|
77
|
+
...wrapped,
|
|
78
|
+
run: (file) => wrapped
|
|
79
|
+
.run(file)
|
|
80
|
+
.pipe(Effect.map((data) => (typeof data === "string" ? new TextEncoder().encode(data) : data))),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function fileInfo(url) {
|
|
84
|
+
return { url: stripHash(url), extension: extensionOf(url) };
|
|
85
|
+
}
|
|
86
|
+
function ioCode(cause) {
|
|
87
|
+
const ioErrorCode = nodeErrorCode(cause);
|
|
88
|
+
return ioErrorCode ? { ioErrorCode } : undefined;
|
|
89
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { ParseError } from "./errors.ts";
|
|
3
|
+
import type { EffectPlugin, Options } from "./plugins.ts";
|
|
4
|
+
export declare const parseText: (source: string | Uint8Array<ArrayBufferLike>) => Effect.Effect<unknown, ParseError, never>;
|
|
5
|
+
export declare function parserPlugins(options: Options): EffectPlugin<unknown>[];
|
package/dist/parsers.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { Effect, Predicate } from "effect";
|
|
2
|
+
import { ParseError, ParserFailure } from "./errors.js";
|
|
3
|
+
import { promisePlugin } from "./plugins.js";
|
|
4
|
+
import { extensionOf } from "./url.js";
|
|
5
|
+
import { parseYamlDocument } from "./yaml.js";
|
|
6
|
+
function decodeData(data) {
|
|
7
|
+
if (data === undefined)
|
|
8
|
+
return "";
|
|
9
|
+
const text = typeof data === "string" ? data : new TextDecoder().decode(data);
|
|
10
|
+
return text.replace(/^\uFEFF/, "");
|
|
11
|
+
}
|
|
12
|
+
function parseJsonText(text) {
|
|
13
|
+
if (text.trim().length === 0)
|
|
14
|
+
return null;
|
|
15
|
+
return JSON.parse(text);
|
|
16
|
+
}
|
|
17
|
+
export const parseText = Effect.fnUntraced(function* (source) {
|
|
18
|
+
const text = decodeData(source);
|
|
19
|
+
const first = text.trimStart()[0];
|
|
20
|
+
const yaml = () => Effect.try({ try: () => parseYamlDocument(text), catch: parseFailure });
|
|
21
|
+
if (first === "{" || first === "[") {
|
|
22
|
+
return yield* Effect.try({ try: () => parseJsonText(text), catch: parseFailure }).pipe(Effect.catch(yaml));
|
|
23
|
+
}
|
|
24
|
+
return yield* yaml();
|
|
25
|
+
});
|
|
26
|
+
function parseFailure(cause) {
|
|
27
|
+
return new ParseError({
|
|
28
|
+
message: Predicate.isError(cause) ? cause.message : String(cause),
|
|
29
|
+
cause,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
export function parserPlugins(options) {
|
|
33
|
+
const plugins = [];
|
|
34
|
+
if (options.parse?.json !== false)
|
|
35
|
+
plugins.push(jsonParser());
|
|
36
|
+
if (options.parse?.yaml !== false)
|
|
37
|
+
plugins.push(yamlParser());
|
|
38
|
+
for (const [index, plugin] of (options.parsers ?? []).entries()) {
|
|
39
|
+
plugins.push(customParser(plugin, index));
|
|
40
|
+
}
|
|
41
|
+
return plugins;
|
|
42
|
+
}
|
|
43
|
+
function jsonParser() {
|
|
44
|
+
return {
|
|
45
|
+
order: 100,
|
|
46
|
+
can: (file) => extensionOf(file.url) === ".json" || extensionOf(file.url) === "",
|
|
47
|
+
run(file) {
|
|
48
|
+
return Effect.try({
|
|
49
|
+
try: () => parseJson(file),
|
|
50
|
+
catch: (cause) => new ParserFailure({
|
|
51
|
+
message: cause instanceof Error ? cause.message : "Parser Error",
|
|
52
|
+
source: file.url,
|
|
53
|
+
cause,
|
|
54
|
+
}),
|
|
55
|
+
});
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function parseJson(file) {
|
|
60
|
+
return parseJsonText(decodeData(file.data));
|
|
61
|
+
}
|
|
62
|
+
function yamlParser() {
|
|
63
|
+
return {
|
|
64
|
+
order: 200,
|
|
65
|
+
can: (file) => {
|
|
66
|
+
const extension = extensionOf(file.url);
|
|
67
|
+
return (extension === ".yaml" || extension === ".yml" || extension === ".json" || extension === "");
|
|
68
|
+
},
|
|
69
|
+
run(file) {
|
|
70
|
+
return Effect.try({
|
|
71
|
+
try: () => parseYaml(file),
|
|
72
|
+
catch: (cause) => new ParserFailure({
|
|
73
|
+
message: cause instanceof Error ? cause.message : "Parser Error",
|
|
74
|
+
source: file.url,
|
|
75
|
+
cause,
|
|
76
|
+
}),
|
|
77
|
+
});
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
function parseYaml(file) {
|
|
82
|
+
return parseYamlDocument(decodeData(file.data));
|
|
83
|
+
}
|
|
84
|
+
function customParser(plugin, index) {
|
|
85
|
+
return promisePlugin(plugin.order ?? 300 + index, (file) => plugin.canParse(file), (file) => plugin.parse(file), (cause, file) => new ParserFailure({
|
|
86
|
+
message: cause instanceof Error ? cause.message : "Parser Error",
|
|
87
|
+
source: file.url,
|
|
88
|
+
cause,
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { DereferenceHooks } from "./plugins.ts";
|
|
2
|
+
export declare function runSchemaPipeline(document: Record<string, unknown>, mode: "bundle" | "dereference", hooks: DereferenceHooks | undefined): void;
|
|
3
|
+
export declare function inlineRemaining(document: Record<string, unknown>, recursive: Set<string>, hooks: DereferenceHooks | undefined): void;
|