lalph 0.3.31 → 0.3.32

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/cli.mjs CHANGED
@@ -5241,6 +5241,37 @@ const getFailure$1 = getFailure$2;
5241
5241
  */
5242
5242
  const getOrElse$1 = /* @__PURE__ */ dual(2, (self, onNone) => isNone(self) ? onNone() : self.value);
5243
5243
  /**
5244
+ * Returns `Some` of the fallback value if `self` is `None`; otherwise returns
5245
+ * `self`.
5246
+ *
5247
+ * **When to use**
5248
+ *
5249
+ * - Providing a default plain value (not an `Option`) as fallback
5250
+ *
5251
+ * **Behavior**
5252
+ *
5253
+ * - `Some` → returns `self` unchanged
5254
+ * - `None` → calls `onNone()`, wraps result in `Some`, and returns it
5255
+ *
5256
+ * **Example** (Providing a fallback value)
5257
+ *
5258
+ * ```ts
5259
+ * import { Option } from "effect"
5260
+ *
5261
+ * console.log(Option.none().pipe(Option.orElseSome(() => "b")))
5262
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'b' }
5263
+ *
5264
+ * console.log(Option.some("a").pipe(Option.orElseSome(() => "b")))
5265
+ * // Output: { _id: 'Option', _tag: 'Some', value: 'a' }
5266
+ * ```
5267
+ *
5268
+ * @see {@link orElse} when the fallback is itself an `Option`
5269
+ *
5270
+ * @category Error handling
5271
+ * @since 2.0.0
5272
+ */
5273
+ const orElseSome = /* @__PURE__ */ dual(2, (self, onNone) => isNone(self) ? some$2(onNone()) : self);
5274
+ /**
5244
5275
  * Converts a nullable value (`null` or `undefined`) into an `Option`.
5245
5276
  *
5246
5277
  * **When to use**
@@ -25876,6 +25907,69 @@ function passthrough$1() {
25876
25907
  return passthrough_$1;
25877
25908
  }
25878
25909
  /**
25910
+ * Creates a getter that handles the case when the input is absent (`Option.None`).
25911
+ *
25912
+ * Use this when:
25913
+ * - You need to provide a fallback or computed value for missing struct keys.
25914
+ * - Building custom "default value" logic more complex than {@link withDefault}.
25915
+ *
25916
+ * Behavior:
25917
+ * - When input is `None`, calls `f` to produce the result.
25918
+ * - When input is `Some`, passes it through unchanged.
25919
+ * - `f` receives the parse options and may return `None` to keep the value absent.
25920
+ *
25921
+ * **Example** (Default timestamp for missing field)
25922
+ *
25923
+ * ```ts
25924
+ * import { SchemaGetter, Effect, Option } from "effect"
25925
+ *
25926
+ * const withTimestamp = SchemaGetter.onNone<number>(() =>
25927
+ * Effect.succeed(Option.some(Date.now()))
25928
+ * )
25929
+ * ```
25930
+ *
25931
+ * See also:
25932
+ * - {@link required} — fails if input is absent
25933
+ * - {@link withDefault} — simpler default value for undefined inputs
25934
+ * - {@link onSome} — handle only present values
25935
+ *
25936
+ * @category Constructors
25937
+ * @since 4.0.0
25938
+ */
25939
+ function onNone(f) {
25940
+ return new Getter((ot, options) => isNone(ot) ? f(options) : succeed$1(ot));
25941
+ }
25942
+ /**
25943
+ * Creates a getter that fails with `MissingKey` if the input is absent (`Option.None`).
25944
+ *
25945
+ * Use this when:
25946
+ * - A struct field must be present in the encoded input.
25947
+ * - You want schema validation to report a missing key error.
25948
+ *
25949
+ * Behavior:
25950
+ * - When input is `None`, fails with `Issue.MissingKey`.
25951
+ * - When input is `Some`, passes it through unchanged.
25952
+ * - Optional `annotations` customize the error message for the missing key.
25953
+ *
25954
+ * **Example** (Required struct field)
25955
+ *
25956
+ * ```ts
25957
+ * import { SchemaGetter } from "effect"
25958
+ *
25959
+ * const mustExist = SchemaGetter.required<string>()
25960
+ * ```
25961
+ *
25962
+ * See also:
25963
+ * - {@link onNone} — provide a fallback instead of failing
25964
+ * - {@link withDefault} — substitute a default for undefined values
25965
+ *
25966
+ * @category Constructors
25967
+ * @since 4.0.0
25968
+ */
25969
+ function required(annotations) {
25970
+ return onNone(() => fail$4(new MissingKey(annotations)));
25971
+ }
25972
+ /**
25879
25973
  * Creates a getter that handles present values (`Option.Some`), passing `None` through.
25880
25974
  *
25881
25975
  * Use this when:
@@ -26016,6 +26110,36 @@ function transformOptional(f) {
26016
26110
  return new Getter((oe) => succeed$1(f(oe)));
26017
26111
  }
26018
26112
  /**
26113
+ * Creates a getter that replaces `undefined` values with a default.
26114
+ *
26115
+ * Use this when:
26116
+ * - A field may be `undefined` in the encoded input and should have a fallback.
26117
+ *
26118
+ * Behavior:
26119
+ * - If the input is `Some(undefined)` or `None`, produces `Some(defaultValue())`.
26120
+ * - If the input is `Some(value)` where value is not `undefined`, passes it through.
26121
+ * - `defaultValue` is called lazily each time a default is needed.
26122
+ *
26123
+ * **Example** (Default value for optional field)
26124
+ *
26125
+ * ```ts
26126
+ * import { SchemaGetter } from "effect"
26127
+ *
26128
+ * const withZero = SchemaGetter.withDefault(() => 0)
26129
+ * // Getter<number, number | undefined>
26130
+ * ```
26131
+ *
26132
+ * See also:
26133
+ * - {@link onNone} — handle only absent keys (not `undefined` values)
26134
+ * - {@link required} — fail instead of providing a default
26135
+ *
26136
+ * @category Constructors
26137
+ * @since 4.0.0
26138
+ */
26139
+ function withDefault$4(defaultValue) {
26140
+ return transformOptional((o) => o.pipe(filter$9(isNotUndefined), orElseSome(defaultValue)));
26141
+ }
26142
+ /**
26019
26143
  * Coerces any value to a `string` using the global `String()` constructor.
26020
26144
  *
26021
26145
  * Use this when:
@@ -28103,7 +28227,7 @@ const isNumberStringRegExp = /* @__PURE__ */ new globalThis.RegExp(`(?:${FINITE_
28103
28227
  * @internal
28104
28228
  */
28105
28229
  function getIndexSignatureKeys(input, parameter) {
28106
- const encoded = toEncoded(parameter);
28230
+ const encoded = toEncoded$1(parameter);
28107
28231
  switch (encoded._tag) {
28108
28232
  case "String": return Object.keys(input);
28109
28233
  case "TemplateLiteral": {
@@ -28464,7 +28588,7 @@ function getIndex(types) {
28464
28588
  if (idx) return idx;
28465
28589
  idx = {};
28466
28590
  for (const a of types) {
28467
- const encoded = toEncoded(a);
28591
+ const encoded = toEncoded$1(a);
28468
28592
  if (isNever(encoded)) continue;
28469
28593
  const types = getCandidateTypes(encoded);
28470
28594
  const sentinels = collectSentinels(encoded);
@@ -28489,7 +28613,7 @@ function getIndex(types) {
28489
28613
  }
28490
28614
  function filterLiterals(input) {
28491
28615
  return (ast) => {
28492
- const encoded = toEncoded(ast);
28616
+ const encoded = toEncoded$1(ast);
28493
28617
  return encoded._tag === "Literal" ? encoded.literal === input : encoded._tag === "UniqueSymbol" ? encoded.symbol === input : true;
28494
28618
  };
28495
28619
  }
@@ -28601,7 +28725,7 @@ var Union$1 = class Union$1 extends Base {
28601
28725
  if (typeof expected === "string") return expected;
28602
28726
  if (this.types.length === 0) return "never";
28603
28727
  const types = this.types.map((type) => {
28604
- const encoded = toEncoded(type);
28728
+ const encoded = toEncoded$1(type);
28605
28729
  switch (encoded._tag) {
28606
28730
  case "Arrays": {
28607
28731
  const literals = encoded.elements.filter(isLiteral);
@@ -29017,10 +29141,10 @@ function isMutable(ast) {
29017
29141
  *
29018
29142
  * @since 4.0.0
29019
29143
  */
29020
- const toType = /* @__PURE__ */ memoize((ast) => {
29021
- if (ast.encoding) return toType(replaceEncoding(ast, void 0));
29144
+ const toType$1 = /* @__PURE__ */ memoize((ast) => {
29145
+ if (ast.encoding) return toType$1(replaceEncoding(ast, void 0));
29022
29146
  const out = ast;
29023
- return out.recur?.(toType) ?? out;
29147
+ return out.recur?.(toType$1) ?? out;
29024
29148
  });
29025
29149
  /**
29026
29150
  * Returns the encoded (wire-format) AST by flipping and then stripping
@@ -29047,8 +29171,8 @@ const toType = /* @__PURE__ */ memoize((ast) => {
29047
29171
  *
29048
29172
  * @since 4.0.0
29049
29173
  */
29050
- const toEncoded = /* @__PURE__ */ memoize((ast) => {
29051
- return toType(flip(ast));
29174
+ const toEncoded$1 = /* @__PURE__ */ memoize((ast) => {
29175
+ return toType$1(flip(ast));
29052
29176
  });
29053
29177
  function flipEncoding(ast, encoding) {
29054
29178
  const links = encoding;
@@ -38014,7 +38138,7 @@ const recurDefaults = /* @__PURE__ */ memoize((ast) => {
38014
38138
  * @since 4.0.0
38015
38139
  */
38016
38140
  function makeEffect$1(schema) {
38017
- const parser = run$6(recurDefaults(toType(schema.ast)));
38141
+ const parser = run$6(recurDefaults(toType$1(schema.ast)));
38018
38142
  return (input, options) => {
38019
38143
  return parser(input, options?.parseOptions);
38020
38144
  };
@@ -38038,7 +38162,7 @@ function is$1(schema) {
38038
38162
  }
38039
38163
  /** @internal */
38040
38164
  function _is(ast) {
38041
- const parser = asExit(run$6(toType(ast)));
38165
+ const parser = asExit(run$6(toType$1(ast)));
38042
38166
  return (input) => {
38043
38167
  return isSuccess$3(parser(input, defaultParseOptions));
38044
38168
  };
@@ -38048,7 +38172,7 @@ function _is(ast) {
38048
38172
  * @since 4.0.0
38049
38173
  */
38050
38174
  function asserts$1(schema) {
38051
- const parser = asExit(run$6(toType(schema.ast)));
38175
+ const parser = asExit(run$6(toType$1(schema.ast)));
38052
38176
  return (input) => {
38053
38177
  const exit = parser(input, defaultParseOptions);
38054
38178
  if (isFailure$2(exit)) {
@@ -38359,7 +38483,7 @@ function toCodecJsonBase(ast) {
38359
38483
  case "Declaration": {
38360
38484
  const getLink = ast.annotations?.toCodecJson ?? ast.annotations?.toCodec;
38361
38485
  if (isFunction(getLink)) {
38362
- const link = getLink(isDeclaration(ast) ? ast.typeParameters.map((tp) => make$38(toEncoded(tp))) : []);
38486
+ const link = getLink(isDeclaration(ast) ? ast.typeParameters.map((tp) => make$38(toEncoded$1(tp))) : []);
38363
38487
  const to = toCodecJson$1(link.to);
38364
38488
  return replaceEncoding(ast, to === link.to ? [link] : [new Link(to, link.transformation)]);
38365
38489
  }
@@ -38399,10 +38523,10 @@ function getJsonPriority(ast) {
38399
38523
  function makeReorder(getPriority) {
38400
38524
  return (types) => {
38401
38525
  const indexMap = /* @__PURE__ */ new Map();
38402
- for (let i = 0; i < types.length; i++) indexMap.set(toEncoded(types[i]), i);
38526
+ for (let i = 0; i < types.length; i++) indexMap.set(toEncoded$1(types[i]), i);
38403
38527
  const sortedTypes = [...types].sort((a, b) => {
38404
- a = toEncoded(a);
38405
- b = toEncoded(b);
38528
+ a = toEncoded$1(a);
38529
+ b = toEncoded$1(b);
38406
38530
  const pa = getPriority(a);
38407
38531
  const pb = getPriority(b);
38408
38532
  if (pa !== pb) return pa - pb;
@@ -38537,7 +38661,7 @@ function fromASTs(asts) {
38537
38661
  function getEncodedSchema(last) {
38538
38662
  const getLink = last.annotations?.toCodecJson ?? last.annotations?.toCodec;
38539
38663
  if (isFunction(getLink)) {
38540
- const link = getLink(last.typeParameters.map((tp) => make$38(toEncoded(tp))));
38664
+ const link = getLink(last.typeParameters.map((tp) => make$38(toEncoded$1(tp))));
38541
38665
  return replaceEncoding(last, [link]);
38542
38666
  }
38543
38667
  return null_;
@@ -39329,6 +39453,14 @@ const optionalKey = /* @__PURE__ */ lambda((schema) => make$37(optionalKey$1(sch
39329
39453
  */
39330
39454
  const optional$2 = /* @__PURE__ */ lambda((self) => optionalKey(UndefinedOr(self)));
39331
39455
  /**
39456
+ * @since 4.0.0
39457
+ */
39458
+ const toType = /* @__PURE__ */ lambda((schema) => make$37(toType$1(schema.ast), { schema }));
39459
+ /**
39460
+ * @since 4.0.0
39461
+ */
39462
+ const toEncoded = /* @__PURE__ */ lambda((schema) => make$37(toEncoded$1(schema.ast), { schema }));
39463
+ /**
39332
39464
  * @see {@link Literals} for a schema that represents a union of literals.
39333
39465
  * @see {@link tag} for a schema that represents a literal value that can be
39334
39466
  * used as a discriminator field in tagged unions and has a constructor default.
@@ -40946,7 +41078,7 @@ function fromJsonString(schema) {
40946
41078
  return String$1.annotate({
40947
41079
  expected: "a string that will be decoded as JSON",
40948
41080
  contentMediaType: "application/json",
40949
- contentSchema: toEncoded(schema.ast)
41081
+ contentSchema: toEncoded$1(schema.ast)
40950
41082
  }).pipe(decodeTo(schema, fromJsonString$1));
40951
41083
  }
40952
41084
  /**
@@ -41440,7 +41572,7 @@ function serializerTree(ast, recur, onMissingAnnotation) {
41440
41572
  case "Declaration": {
41441
41573
  const getLink = ast.annotations?.toCodecJson ?? ast.annotations?.toCodec;
41442
41574
  if (isFunction(getLink)) {
41443
- const link = getLink(isDeclaration(ast) ? ast.typeParameters.map((tp) => make$37(recur(toEncoded(tp)))) : []);
41575
+ const link = getLink(isDeclaration(ast) ? ast.typeParameters.map((tp) => make$37(recur(toEncoded$1(tp)))) : []);
41444
41576
  const to = recur(link.to);
41445
41577
  return replaceEncoding(ast, to === link.to ? [link] : [new Link(to, link.transformation)]);
41446
41578
  }
@@ -41833,7 +41965,7 @@ const recur = /* @__PURE__ */ fnUntraced(function* (ast, provider, path) {
41833
41965
  function schema(codec, path) {
41834
41966
  const toCodecStringTree$2 = toCodecStringTree(codec);
41835
41967
  const decodeUnknownEffect = decodeUnknownEffect$1(toCodecStringTree$2);
41836
- const toCodecStringTreeEncoded = toEncoded(toCodecStringTree$2.ast);
41968
+ const toCodecStringTreeEncoded = toEncoded$1(toCodecStringTree$2.ast);
41837
41969
  const defaultPath = typeof path === "string" ? [path] : path ?? [];
41838
41970
  return make$36((provider) => {
41839
41971
  const path = provider.prefix ? [...provider.prefix, ...defaultPath] : defaultPath;
@@ -73807,33 +73939,46 @@ var ProjectSetting = class {
73807
73939
  };
73808
73940
  const selectedCliAgentId = new Setting("selectedCliAgentId", Literals(allCliAgents.map((a) => a.id)));
73809
73941
 
73942
+ //#endregion
73943
+ //#region src/shared/schema.ts
73944
+ const withEncodeDefault = (defaultValue) => (schema) => optionalKey(schema).pipe(decodeTo(toType(schema), {
73945
+ decode: withDefault$4(defaultValue),
73946
+ encode: required()
73947
+ }));
73948
+
73810
73949
  //#endregion
73811
73950
  //#region src/domain/PrdIssue.ts
73812
73951
  var PrdIssue = class PrdIssue extends Class$1("PrdIssue")({
73813
- id: NullOr(String$1).annotate({ description: "The unique identifier of the issue. If null, it is considered a new issue." }),
73952
+ id: NullOr(String$1).annotate({ description: "The unique identifier of the issue. If null, it is considered a new issue." }).pipe(withEncodeDefault(() => null)),
73814
73953
  title: String$1.annotate({ description: "The title of the issue" }),
73815
- description: String$1.annotate({ description: "The description of the issue in markdown format." }),
73816
- priority: Finite.annotate({ description: "The priority of the issue. 0 = No priority, 1 = Urgent, 2 = High, 3 = Normal, 4 = Low." }),
73817
- estimate: NullOr(Finite).annotate({ description: "The estimate of the issue in points. Null if no estimate is set. Roughly 1 point = 1 hour of work." }),
73954
+ description: String$1.annotate({ description: "The description of the issue in markdown format." }).pipe(withEncodeDefault(() => "")),
73955
+ priority: Finite.annotate({ description: "The priority of the issue. 0 = No priority, 1 = Urgent, 2 = High, 3 = Normal, 4 = Low." }).pipe(withEncodeDefault(() => 3)),
73956
+ estimate: NullOr(Finite).annotate({ description: "The estimate of the issue in points. Null if no estimate is set. Roughly 1 point = 1 hour of work." }).pipe(withEncodeDefault(() => null)),
73818
73957
  state: Literals([
73819
73958
  "backlog",
73820
73959
  "todo",
73821
73960
  "in-progress",
73822
73961
  "in-review",
73823
73962
  "done"
73824
- ]).annotate({ description: "The state of the issue." }),
73825
- blockedBy: Array$1(String$1).annotate({ description: "An array of issue IDs that block this issue. These issues must be completed before this issue can be worked on." }),
73826
- autoMerge: Boolean$2.annotate({ description: "Whether the issue should be auto-merged when complete. Read-only field" })
73963
+ ]).annotate({ description: "The state of the issue." }).pipe(withEncodeDefault(() => "todo")),
73964
+ blockedBy: Array$1(String$1).annotate({ description: "An array of issue IDs that block this issue. These issues must be completed before this issue can be worked on." }).pipe(withEncodeDefault(() => [])),
73965
+ autoMerge: Boolean$2.annotate({ description: "Whether the issue should be auto-merged when complete. Read-only field" }).pipe(withEncodeDefault(() => false))
73827
73966
  }) {
73967
+ static FromInput = Union([String$1, toEncoded(PrdIssue)]).pipe(decodeTo(PrdIssue, {
73968
+ decode: transform$3((s) => typeof s === "string" ? { title: s } : s),
73969
+ encode: passthrough$1()
73970
+ }));
73828
73971
  static Array = Array$1(this);
73972
+ static ArrayFromInput = Array$1(this.FromInput);
73829
73973
  static ArrayFromJson = toCodecJson(this.Array);
73974
+ static ArrayFromJsonInput = toCodecJson(this.ArrayFromInput);
73830
73975
  static arrayToYaml(issues) {
73831
73976
  const json = encodeSync(this.ArrayFromJson)(issues);
73832
73977
  return import_dist.stringify(json, { blockQuote: "literal" });
73833
73978
  }
73834
73979
  static arrayFromYaml(yaml) {
73835
73980
  const json = import_dist.parse(yaml);
73836
- return decodeSync(PrdIssue.ArrayFromJson)(json);
73981
+ return decodeSync(PrdIssue.ArrayFromJsonInput)(json);
73837
73982
  }
73838
73983
  static jsonSchemaDoc = toJsonSchemaDocument(this);
73839
73984
  static jsonSchema = {
@@ -159542,7 +159687,7 @@ const commandSource = make$34("source").pipe(withDescription("Select the issue s
159542
159687
 
159543
159688
  //#endregion
159544
159689
  //#region package.json
159545
- var version = "0.3.31";
159690
+ var version = "0.3.32";
159546
159691
 
159547
159692
  //#endregion
159548
159693
  //#region src/commands/projects/ls.ts
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "lalph",
3
3
  "type": "module",
4
- "version": "0.3.31",
4
+ "version": "0.3.32",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -1,52 +1,75 @@
1
- import { Schema, Array, Equal } from "effect"
1
+ import { Schema, Array, Equal, SchemaGetter } from "effect"
2
2
  import * as Yaml from "yaml"
3
+ import { withEncodeDefault } from "../shared/schema.ts"
3
4
 
4
5
  export class PrdIssue extends Schema.Class<PrdIssue>("PrdIssue")({
5
- id: Schema.NullOr(Schema.String).annotate({
6
- description:
7
- "The unique identifier of the issue. If null, it is considered a new issue.",
8
- }),
6
+ id: Schema.NullOr(Schema.String)
7
+ .annotate({
8
+ description:
9
+ "The unique identifier of the issue. If null, it is considered a new issue.",
10
+ })
11
+ .pipe(withEncodeDefault(() => null)),
9
12
  title: Schema.String.annotate({
10
13
  description: "The title of the issue",
11
14
  }),
12
15
  description: Schema.String.annotate({
13
16
  description: "The description of the issue in markdown format.",
14
- }),
17
+ }).pipe(withEncodeDefault(() => "")),
15
18
  priority: Schema.Finite.annotate({
16
19
  description:
17
20
  "The priority of the issue. 0 = No priority, 1 = Urgent, 2 = High, 3 = Normal, 4 = Low.",
18
- }),
19
- estimate: Schema.NullOr(Schema.Finite).annotate({
20
- description:
21
- "The estimate of the issue in points. Null if no estimate is set. Roughly 1 point = 1 hour of work.",
22
- }),
21
+ }).pipe(withEncodeDefault(() => 3)),
22
+ estimate: Schema.NullOr(Schema.Finite)
23
+ .annotate({
24
+ description:
25
+ "The estimate of the issue in points. Null if no estimate is set. Roughly 1 point = 1 hour of work.",
26
+ })
27
+ .pipe(withEncodeDefault(() => null)),
23
28
  state: Schema.Literals([
24
29
  "backlog",
25
30
  "todo",
26
31
  "in-progress",
27
32
  "in-review",
28
33
  "done",
29
- ]).annotate({
30
- description: "The state of the issue.",
31
- }),
32
- blockedBy: Schema.Array(Schema.String).annotate({
33
- description:
34
- "An array of issue IDs that block this issue. These issues must be completed before this issue can be worked on.",
35
- }),
34
+ ])
35
+ .annotate({
36
+ description: "The state of the issue.",
37
+ })
38
+ .pipe(withEncodeDefault(() => "todo")),
39
+ blockedBy: Schema.Array(Schema.String)
40
+ .annotate({
41
+ description:
42
+ "An array of issue IDs that block this issue. These issues must be completed before this issue can be worked on.",
43
+ })
44
+ .pipe(withEncodeDefault(() => [])),
36
45
  autoMerge: Schema.Boolean.annotate({
37
46
  description:
38
47
  "Whether the issue should be auto-merged when complete. Read-only field",
39
- }),
48
+ }).pipe(withEncodeDefault(() => false)),
40
49
  }) {
50
+ static FromInput = Schema.Union([
51
+ Schema.String,
52
+ Schema.toEncoded(PrdIssue),
53
+ ]).pipe(
54
+ Schema.decodeTo(PrdIssue, {
55
+ decode: SchemaGetter.transform((s) =>
56
+ typeof s === "string" ? { title: s } : s,
57
+ ),
58
+ encode: SchemaGetter.passthrough(),
59
+ }),
60
+ )
61
+
41
62
  static Array = Schema.Array(this)
63
+ static ArrayFromInput = Schema.Array(this.FromInput)
42
64
  static ArrayFromJson = Schema.toCodecJson(this.Array)
65
+ static ArrayFromJsonInput = Schema.toCodecJson(this.ArrayFromInput)
43
66
  static arrayToYaml(issues: ReadonlyArray<PrdIssue>): string {
44
67
  const json = Schema.encodeSync(this.ArrayFromJson)(issues)
45
68
  return Yaml.stringify(json, { blockQuote: "literal" })
46
69
  }
47
70
  static arrayFromYaml(yaml: string): ReadonlyArray<PrdIssue> {
48
71
  const json = Yaml.parse(yaml)
49
- const issues = Schema.decodeSync(PrdIssue.ArrayFromJson)(json)
72
+ const issues = Schema.decodeSync(PrdIssue.ArrayFromJsonInput)(json)
50
73
  return issues
51
74
  }
52
75
 
@@ -0,0 +1,11 @@
1
+ import { Schema, SchemaGetter } from "effect"
2
+
3
+ export const withEncodeDefault =
4
+ <S extends Schema.Top>(defaultValue: () => S["Type"]) =>
5
+ (schema: S) =>
6
+ Schema.optionalKey(schema).pipe(
7
+ Schema.decodeTo(Schema.toType(schema), {
8
+ decode: SchemaGetter.withDefault(defaultValue),
9
+ encode: SchemaGetter.required(),
10
+ }),
11
+ )