Skip to content
Source
Sign inSign up
Open History to see the last commit

schemaYaml.ts

59 lines1.9 KB

1import * as Effect from "effect/Effect";
2import * as Schema from "effect/Schema";
3import * as SchemaGetter from "effect/SchemaGetter";
4import * as SchemaIssue from "effect/SchemaIssue";
5import * as SchemaTransformation from "effect/SchemaTransformation";
6import {
7 YAMLParseError,
8 parse as parseYamlString,
9 stringify as stringifyYamlValue,
10 type CreateNodeOptions,
11 type DocumentOptions,
12 type ParseOptions,
13 type SchemaOptions,
14 type ToJSOptions,
15 type ToStringOptions,
16} from "yaml";
17​
18export type YamlParseOptions = ParseOptions & DocumentOptions & SchemaOptions & ToJSOptions;
19export type YamlStringifyOptions = DocumentOptions &
20 SchemaOptions &
21 ParseOptions &
22 CreateNodeOptions &
23 ToStringOptions;
24​
25function formatYamlParseError(error: unknown): string {
26 if (!(error instanceof YAMLParseError)) {
27 return "Invalid YAML.";
28 }
29​
30 const position = error.linePos?.[0];
31 const location = position === undefined ? "" : `, line=${position.line}, column=${position.col}`;
32 return `Invalid YAML (code=${error.code}${location}).`;
34​
35function parseYaml<E extends string>(options?: YamlParseOptions): SchemaGetter.Getter<unknown, E> {
36 return SchemaGetter.transformEffect((input: E) =>
37 Effect.try({
38 try: () => parseYamlString(input, options) as unknown,
39 catch: (error) => new SchemaIssue.InvalidValue({ message: formatYamlParseError(error) }),
40 }),
41 );
43​
44function stringifyYaml(options?: YamlStringifyOptions): SchemaGetter.Getter<string, unknown> {
45 return SchemaGetter.transformEffect((input: unknown) =>
46 Effect.try({
47 try: () => stringifyYamlValue(input, options),
48 catch: () => new SchemaIssue.InvalidValue({ message: "Failed to stringify YAML." }),
49 }),
50 );
52​
53const fromYamlString = new SchemaTransformation.Transformation<unknown, string>(
54 parseYaml(),
55 stringifyYaml(),
56);
57​
58export const fromYaml = <S extends Schema.Top>(schema: S) =>
59 Schema.String.pipe(Schema.decodeTo(schema, fromYamlString));