@effected/yaml 0.7.0 → 0.8.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.
Files changed (39) hide show
  1. package/README.md +78 -7
  2. package/Yaml.js +80 -32
  3. package/YamlDocument.js +22 -3
  4. package/YamlFormat.js +170 -19
  5. package/YamlLint.js +239 -0
  6. package/YamlLintRule.js +36 -0
  7. package/YamlNode.js +36 -2
  8. package/YamlToken.js +139 -0
  9. package/YamlVisitor.js +40 -5
  10. package/index.d.ts +439 -12
  11. package/index.js +4 -1
  12. package/internal/composer/anchors.js +2 -27
  13. package/internal/composer/block.js +246 -58
  14. package/internal/composer/comments.js +187 -0
  15. package/internal/composer/document.js +49 -12
  16. package/internal/composer/flow.js +82 -9
  17. package/internal/composer/scalars.js +48 -11
  18. package/internal/composer/state.js +16 -2
  19. package/internal/cst-parser.js +2 -1
  20. package/internal/diagnostics.js +12 -3
  21. package/internal/fold.js +22 -10
  22. package/internal/rules/catalog.js +39 -0
  23. package/internal/rules/colon-spacing.js +77 -0
  24. package/internal/rules/comments-spacing.js +68 -0
  25. package/internal/rules/document-end.js +65 -0
  26. package/internal/rules/document-start.js +64 -0
  27. package/internal/rules/empty-lines.js +70 -0
  28. package/internal/rules/eof-newline.js +33 -0
  29. package/internal/rules/hyphen-spacing.js +52 -0
  30. package/internal/rules/indentation.js +103 -0
  31. package/internal/rules/key-duplicates.js +49 -0
  32. package/internal/rules/line-length.js +36 -0
  33. package/internal/rules/parse-validity.js +33 -0
  34. package/internal/rules/quoted-strings.js +81 -0
  35. package/internal/rules/trailing-spaces.js +39 -0
  36. package/internal/rules/truthy.js +84 -0
  37. package/internal/rules/util.js +92 -0
  38. package/internal/stringifier.js +266 -54
  39. package/package.json +3 -2
package/index.d.ts CHANGED
@@ -54,7 +54,7 @@ type YamlStringifyErrorCode = typeof YamlStringifyErrorCode.Type;
54
54
  *
55
55
  * @public
56
56
  */
57
- declare const YamlModifyErrorCode: Schema.Literals<readonly ["EmptyDocument", "PathNotFound", "InvalidIndex", "NotNavigable"]>;
57
+ declare const YamlModifyErrorCode: Schema.Literals<readonly ["EmptyDocument", "PathNotFound", "InvalidIndex", "NotNavigable", "MultiDocumentStream", "DirectiveCarryingDocument"]>;
58
58
  /**
59
59
  * The union of all modify-stage error code string literals.
60
60
  *
@@ -67,7 +67,7 @@ type YamlModifyErrorCode = typeof YamlModifyErrorCode.Type;
67
67
  *
68
68
  * @public
69
69
  */
70
- declare const YamlErrorCode: Schema.Union<readonly [Schema.Literals<readonly ["UnexpectedCharacter", "UnterminatedString", "InvalidEscapeSequence", "InvalidUnicode", "UnterminatedBlockScalar", "UnterminatedFlowCollection", "InvalidDirective", "InvalidTagHandle", "InvalidAnchorName", "UnexpectedByteOrderMark"]>, Schema.Literals<readonly ["InvalidIndentation", "DuplicateKey", "UnexpectedToken", "MissingValue", "MissingKey", "TabIndentation", "InvalidBlockStructure", "MalformedFlowCollection", "NestingDepthExceeded"]>, Schema.Literals<readonly ["UndefinedAlias", "DuplicateAnchor", "CircularAlias", "UnresolvedTag", "InvalidTagValue", "AliasCountExceeded", "InvalidDirective"]>, Schema.Literals<readonly ["CircularReference"]>, Schema.Literals<readonly ["EmptyDocument", "PathNotFound", "InvalidIndex", "NotNavigable"]>]>;
70
+ declare const YamlErrorCode: Schema.Union<readonly [Schema.Literals<readonly ["UnexpectedCharacter", "UnterminatedString", "InvalidEscapeSequence", "InvalidUnicode", "UnterminatedBlockScalar", "UnterminatedFlowCollection", "InvalidDirective", "InvalidTagHandle", "InvalidAnchorName", "UnexpectedByteOrderMark"]>, Schema.Literals<readonly ["InvalidIndentation", "DuplicateKey", "UnexpectedToken", "MissingValue", "MissingKey", "TabIndentation", "InvalidBlockStructure", "MalformedFlowCollection", "NestingDepthExceeded"]>, Schema.Literals<readonly ["UndefinedAlias", "DuplicateAnchor", "CircularAlias", "UnresolvedTag", "InvalidTagValue", "AliasCountExceeded", "InvalidDirective"]>, Schema.Literals<readonly ["CircularReference"]>, Schema.Literals<readonly ["EmptyDocument", "PathNotFound", "InvalidIndex", "NotNavigable", "MultiDocumentStream", "DirectiveCarryingDocument"]>]>;
71
71
  /**
72
72
  * The union of all YAML error code string literals.
73
73
  *
@@ -75,7 +75,7 @@ declare const YamlErrorCode: Schema.Union<readonly [Schema.Literals<readonly ["U
75
75
  */
76
76
  type YamlErrorCode = typeof YamlErrorCode.Type;
77
77
  declare const YamlDiagnostic_base: Schema.Class<YamlDiagnostic, Schema.Struct<{
78
- readonly code: Schema.Union<readonly [Schema.Literals<readonly ["UnexpectedCharacter", "UnterminatedString", "InvalidEscapeSequence", "InvalidUnicode", "UnterminatedBlockScalar", "UnterminatedFlowCollection", "InvalidDirective", "InvalidTagHandle", "InvalidAnchorName", "UnexpectedByteOrderMark"]>, Schema.Literals<readonly ["InvalidIndentation", "DuplicateKey", "UnexpectedToken", "MissingValue", "MissingKey", "TabIndentation", "InvalidBlockStructure", "MalformedFlowCollection", "NestingDepthExceeded"]>, Schema.Literals<readonly ["UndefinedAlias", "DuplicateAnchor", "CircularAlias", "UnresolvedTag", "InvalidTagValue", "AliasCountExceeded", "InvalidDirective"]>, Schema.Literals<readonly ["CircularReference"]>, Schema.Literals<readonly ["EmptyDocument", "PathNotFound", "InvalidIndex", "NotNavigable"]>]>;
78
+ readonly code: Schema.Union<readonly [Schema.Literals<readonly ["UnexpectedCharacter", "UnterminatedString", "InvalidEscapeSequence", "InvalidUnicode", "UnterminatedBlockScalar", "UnterminatedFlowCollection", "InvalidDirective", "InvalidTagHandle", "InvalidAnchorName", "UnexpectedByteOrderMark"]>, Schema.Literals<readonly ["InvalidIndentation", "DuplicateKey", "UnexpectedToken", "MissingValue", "MissingKey", "TabIndentation", "InvalidBlockStructure", "MalformedFlowCollection", "NestingDepthExceeded"]>, Schema.Literals<readonly ["UndefinedAlias", "DuplicateAnchor", "CircularAlias", "UnresolvedTag", "InvalidTagValue", "AliasCountExceeded", "InvalidDirective"]>, Schema.Literals<readonly ["CircularReference"]>, Schema.Literals<readonly ["EmptyDocument", "PathNotFound", "InvalidIndex", "NotNavigable", "MultiDocumentStream", "DirectiveCarryingDocument"]>]>;
79
79
  readonly message: Schema.String;
80
80
  readonly offset: Schema.Number;
81
81
  readonly length: Schema.Number;
@@ -238,7 +238,9 @@ declare const YamlParseError_base: Schema.Class<YamlParseError, Schema.TaggedStr
238
238
  * Error-recovery parse failure: aggregates every fatal {@link YamlDiagnostic}
239
239
  * encountered, so a single failure reports the whole batch. Raised by
240
240
  * {@link Yaml.parse}, {@link Yaml.parseAll}, `YamlDocument.parse`/`parseAll`
241
- * and the decode direction of the schema factories.
241
+ * and the decode direction of the schema factories. The error itself has no
242
+ * `code` field: read the code from the diagnostics —
243
+ * `error.diagnostics[0].code` is the primary failure.
242
244
  *
243
245
  * @public
244
246
  */
@@ -253,7 +255,8 @@ declare const YamlStringifyError_base: Schema.Class<YamlStringifyError, Schema.T
253
255
  * Stringification failure (the circular-reference guard), carrying structured
254
256
  * {@link YamlDiagnostic} entries and the offending value. Raised by
255
257
  * {@link Yaml.stringify}, `YamlDocument#stringify` and the encode direction of
256
- * the schema factories.
258
+ * the schema factories. The error itself has no `code` field: read the code
259
+ * from the diagnostics — `error.diagnostics[0].code` is the primary failure.
257
260
  *
258
261
  * @public
259
262
  */
@@ -326,6 +329,9 @@ declare class Yaml {
326
329
  * A "billion laughs" alias-expansion blow-up in any document also fails
327
330
  * through {@link YamlParseError} with an `AliasCountExceeded` diagnostic,
328
331
  * never as an unhandled defect.
332
+ *
333
+ * Defined in terms of {@link Yaml.parseAllResult} — synchronous callers
334
+ * can use that variant directly.
329
335
  */
330
336
  static readonly parseAll: (text: string, options?: YamlParseOptions | undefined) => Effect.Effect<readonly unknown[], YamlParseError, never>;
331
337
  /**
@@ -378,6 +384,46 @@ declare class Yaml {
378
384
  * @public
379
385
  */
380
386
  static parseResult(text: string, options?: YamlParseOptions): Result.Result<unknown, YamlParseError>;
387
+ /**
388
+ * Synchronous multi-document parse, returning a `Result` instead of an
389
+ * `Effect` — the {@link Yaml.parseResult} counterpart to
390
+ * {@link Yaml.parseAll}. Empty input succeeds with `[null]` (the engine
391
+ * reads `""` as one empty document, exactly as {@link Yaml.parse} yields
392
+ * `null` for it); a single-document stream succeeds with a one-element
393
+ * array whose value is exactly what {@link Yaml.parseResult} yields.
394
+ *
395
+ * @remarks
396
+ * This is the package's single multi-document parse path.
397
+ * {@link Yaml.parseAll} is defined in terms of it (`Effect.fromResult`
398
+ * behind the named span), so the two variants cannot diverge. Anchors are
399
+ * document-scoped: each document's aliases resolve against its own anchor
400
+ * map, never a neighbor's.
401
+ *
402
+ * Fails with the aggregate {@link YamlParseError} when **any** document in
403
+ * the stream carries a fatal diagnostic (or a stream-level
404
+ * directive-placement error), which makes it a whole-stream validity
405
+ * check: a `Success` means every document parsed clean. Preserves the
406
+ * package contract — malformed and adversarial input (including a
407
+ * "billion laughs" alias bomb in any document) fails typed, never as a
408
+ * defect; the method never throws.
409
+ *
410
+ * @example
411
+ * ```ts
412
+ * import { Yaml } from "@effected/yaml";
413
+ * import { Result } from "effect";
414
+ *
415
+ * // Whole-stream validity check: fails if ANY document is invalid.
416
+ * const result = Yaml.parseAllResult("a: 1\n---\nb: 2\n");
417
+ * if (Result.isSuccess(result)) {
418
+ * result.success; // [{ a: 1 }, { b: 2 }]
419
+ * } else {
420
+ * result.failure; // YamlParseError aggregating every fatal diagnostic
421
+ * }
422
+ * ```
423
+ *
424
+ * @public
425
+ */
426
+ static parseAllResult(text: string, options?: YamlParseOptions): Result.Result<ReadonlyArray<unknown>, YamlParseError>;
381
427
  /**
382
428
  * Synchronous stringify, returning a `Result` instead of an `Effect`.
383
429
  * The pure counterpart to {@link Yaml.stringify} for config-time callers
@@ -613,8 +659,11 @@ declare const YamlScalar_base: Schema.Class<YamlScalar, Schema.TaggedStruct<"Yam
613
659
  readonly tag: Schema.optionalKey<Schema.String>;
614
660
  readonly style: Schema.Literals<readonly ["plain", "single-quoted", "double-quoted", "block-literal", "block-folded"]>;
615
661
  readonly anchor: Schema.optionalKey<Schema.String>;
662
+ readonly commentBefore: Schema.optionalKey<Schema.String>;
616
663
  readonly comment: Schema.optionalKey<Schema.String>;
664
+ readonly spaceBefore: Schema.optionalKey<Schema.Boolean>;
617
665
  readonly chomp: Schema.optionalKey<Schema.Literals<readonly ["strip", "clip", "keep"]>>;
666
+ readonly blockIndent: Schema.optionalKey<Schema.Number>;
618
667
  readonly raw: Schema.optionalKey<Schema.String>;
619
668
  readonly sourceMultiline: Schema.optionalKey<Schema.Boolean>;
620
669
  readonly offset: Schema.Number;
@@ -629,9 +678,17 @@ declare const YamlScalar_base: Schema.Class<YamlScalar, Schema.TaggedStruct<"Yam
629
678
  * - `style` — the scalar presentation style in the source document.
630
679
  * - `tag` — optional explicit YAML tag (e.g. `!!str`, `!!int`).
631
680
  * - `anchor` — optional anchor name for aliasing.
632
- * - `comment` — optional trailing or leading comment text.
681
+ * - `commentBefore` — own-line comment text directly above the node
682
+ * (multiple consecutive comment lines join with `\n`).
683
+ * - `comment` — trailing comment text on the node's line (strictly trailing;
684
+ * own-line comments live on `commentBefore`).
685
+ * - `spaceBefore` — `true` when a blank line precedes the node (and its
686
+ * `commentBefore` block, when present) in the source.
633
687
  * - `chomp` — block-scalar chomping indicator, when the scalar is a block
634
688
  * scalar.
689
+ * - `blockIndent` — the EXPLICIT indentation-indicator digit from a block
690
+ * scalar's header (`|2`, `>1+`), when the source spelled one; absent when
691
+ * the header let the reader auto-detect the indent.
635
692
  * - `raw` — the raw source text, preserved when it differs from the resolved
636
693
  * value in a way stringification needs to know about.
637
694
  * - `sourceMultiline` — `true` when the source span covers two or more lines;
@@ -740,12 +797,20 @@ type YamlNode = YamlScalar | YamlMap | YamlSeq | YamlAlias;
740
797
  declare const YamlPair_base: Schema.Class<YamlPair, Schema.TaggedStruct<"YamlPair", {
741
798
  readonly key: Schema.suspend<Schema.Codec<YamlAlias | YamlMap | YamlScalar | YamlSeq, YamlAliasEncoded | YamlMapEncoded | YamlScalarEncoded | YamlSeqEncoded, never, never>>;
742
799
  readonly value: Schema.NullOr<Schema.suspend<Schema.Codec<YamlAlias | YamlMap | YamlScalar | YamlSeq, YamlAliasEncoded | YamlMapEncoded | YamlScalarEncoded | YamlSeqEncoded, never, never>>>;
800
+ readonly commentBefore: Schema.optionalKey<Schema.String>;
743
801
  readonly comment: Schema.optionalKey<Schema.String>;
802
+ readonly spaceBefore: Schema.optionalKey<Schema.Boolean>;
744
803
  }>, {}>;
745
804
  /**
746
805
  * A YAML key-value pair AST node, representing one entry within a mapping.
747
806
  * `value` is `null` when absent (e.g. `key:` with no value).
748
807
  *
808
+ * - `commentBefore` — own-line comment text directly above the pair's key
809
+ * (multiple consecutive comment lines join with `\n`).
810
+ * - `comment` — trailing comment text on the pair's line (strictly trailing).
811
+ * - `spaceBefore` — `true` when a blank line precedes the pair (and its
812
+ * `commentBefore` block, when present) in the source.
813
+ *
749
814
  * @public
750
815
  */
751
816
  declare class YamlPair extends YamlPair_base {}
@@ -754,7 +819,9 @@ declare const YamlMap_base: Schema.Class<YamlMap, Schema.TaggedStruct<"YamlMap",
754
819
  readonly tag: Schema.optionalKey<Schema.String>;
755
820
  readonly anchor: Schema.optionalKey<Schema.String>;
756
821
  readonly style: Schema.Literals<readonly ["block", "flow"]>;
822
+ readonly commentBefore: Schema.optionalKey<Schema.String>;
757
823
  readonly comment: Schema.optionalKey<Schema.String>;
824
+ readonly spaceBefore: Schema.optionalKey<Schema.Boolean>;
758
825
  readonly sourceMultiline: Schema.optionalKey<Schema.Boolean>;
759
826
  readonly offset: Schema.Number;
760
827
  readonly length: Schema.Number;
@@ -764,6 +831,11 @@ declare const YamlMap_base: Schema.Class<YamlMap, Schema.TaggedStruct<"YamlMap",
764
831
  * entries.
765
832
  *
766
833
  * - `style` — the presentation style: `"block"` or `"flow"`.
834
+ * - `commentBefore` — own-line comment text directly above the mapping.
835
+ * - `comment` — trailing comment text: own-line comment lines after the
836
+ * mapping's last entry (still at the mapping's item indent), or a same-line
837
+ * trailing comment for a flow mapping.
838
+ * - `spaceBefore` — `true` when a blank line precedes the mapping.
767
839
  * - `sourceMultiline` — `true` when the source span covers two or more lines;
768
840
  * used by the canonical stringifier. Absent on synthetic nodes.
769
841
  *
@@ -784,7 +856,9 @@ declare const YamlSeq_base: Schema.Class<YamlSeq, Schema.TaggedStruct<"YamlSeq",
784
856
  readonly tag: Schema.optionalKey<Schema.String>;
785
857
  readonly anchor: Schema.optionalKey<Schema.String>;
786
858
  readonly style: Schema.Literals<readonly ["block", "flow"]>;
859
+ readonly commentBefore: Schema.optionalKey<Schema.String>;
787
860
  readonly comment: Schema.optionalKey<Schema.String>;
861
+ readonly spaceBefore: Schema.optionalKey<Schema.Boolean>;
788
862
  readonly sourceMultiline: Schema.optionalKey<Schema.Boolean>;
789
863
  readonly offset: Schema.Number;
790
864
  readonly length: Schema.Number;
@@ -793,6 +867,12 @@ declare const YamlSeq_base: Schema.Class<YamlSeq, Schema.TaggedStruct<"YamlSeq",
793
867
  * A YAML sequence AST node, representing an ordered list of
794
868
  * {@link (YamlNode:type)} values.
795
869
  *
870
+ * - `commentBefore` — own-line comment text directly above the sequence.
871
+ * - `comment` — trailing comment text: own-line comment lines after the
872
+ * sequence's last item (still at the sequence's item indent), or a
873
+ * same-line trailing comment for a flow sequence.
874
+ * - `spaceBefore` — `true` when a blank line precedes the sequence.
875
+ *
796
876
  * @public
797
877
  */
798
878
  declare class YamlSeq extends YamlSeq_base {
@@ -826,6 +906,7 @@ declare const YamlDocument_base: Schema.Class<YamlDocument, Schema.Struct<{
826
906
  readonly warnings: Schema.$Array<typeof YamlDiagnostic>;
827
907
  readonly directives: Schema.$Array<typeof YamlDirective>;
828
908
  readonly comment: Schema.optionalKey<Schema.String>;
909
+ readonly commentAfter: Schema.optionalKey<Schema.String>;
829
910
  readonly hasDocumentStart: Schema.optionalKey<Schema.Boolean>;
830
911
  readonly hasDocumentEnd: Schema.optionalKey<Schema.Boolean>;
831
912
  readonly hasDocumentStartTab: Schema.optionalKey<Schema.Boolean>;
@@ -833,8 +914,12 @@ declare const YamlDocument_base: Schema.Class<YamlDocument, Schema.Struct<{
833
914
  /**
834
915
  * A parsed YAML document: the root {@link (YamlNode:type)} (or `null` when
835
916
  * empty), recovered `errors` and `warnings` as {@link YamlDiagnostic} data,
836
- * the {@link YamlDirective} list, an optional document-level comment, and the
837
- * `---`/`...` framing flags (absent flags read as `false`).
917
+ * the {@link YamlDirective} list, the optional document-level comments
918
+ * (`comment` is the LEADING header block, `commentAfter` the trailing block
919
+ * after the content or the `...` marker — the reference `yaml` package calls
920
+ * these `commentBefore`/`comment`; the naming here keeps the pre-existing
921
+ * `comment`-as-header field stable), and the `---`/`...` framing flags
922
+ * (absent flags read as `false`).
838
923
  *
839
924
  * Construct via `YamlDocument.parse` / `parseAll`; `YamlDocument.make` is for
840
925
  * synthetic documents.
@@ -950,9 +1035,16 @@ declare const YamlModificationError_base: Schema.Class<YamlModificationError, Sc
950
1035
  }>, import("effect/Cause").YieldableError>;
951
1036
  /**
952
1037
  * Raised when `YamlFormat.modify` cannot navigate the requested path against
953
- * the composed AST (a structural mismatch) or the source fails to parse.
1038
+ * the composed AST (a structural mismatch), the source fails to parse, the
1039
+ * source is a multi-document stream (`MultiDocumentStream` — a path names no
1040
+ * particular document of a stream, so modify refuses rather than guessing),
1041
+ * or the document carries `%YAML`/`%TAG` directives
1042
+ * (`DirectiveCarryingDocument` — modify does not re-emit directive lines, and
1043
+ * dropping a `%TAG` would orphan the shorthand tags that depend on it).
954
1044
  * Carries structured {@link YamlDiagnostic} entries — never a collapsed
955
- * `reason` string (the structure-preserving-errors house rule).
1045
+ * `reason` string (the structure-preserving-errors house rule). The error
1046
+ * itself has no `code` field: read the code from the diagnostics —
1047
+ * `error.diagnostics[0].code` is the primary failure.
956
1048
  *
957
1049
  * @public
958
1050
  */
@@ -971,6 +1063,24 @@ declare class YamlModificationError extends YamlModificationError_base {
971
1063
  * `diagnostics: ReadonlyArray<YamlDiagnostic>`, never a collapsed `reason`
972
1064
  * string.
973
1065
  *
1066
+ * `format`/`formatToString` handle multi-document streams whole — every
1067
+ * document is re-emitted in order with its own framing, never a silently
1068
+ * truncated stream. `modify`/`modifyToString` are **single-document**: a
1069
+ * {@link YamlPath} carries no document index, so which document of a stream
1070
+ * a path names is a rule the format does not define, and a multi-document
1071
+ * stream fails typed with a `MultiDocumentStream` diagnostic rather than
1072
+ * guessing. Parse a stream with {@link Yaml.parseAll} /
1073
+ * `Yaml.parseAllResult`.
1074
+ *
1075
+ * **Directive-carrying input is refused on every path.** The stringifier does
1076
+ * not re-emit `%YAML`/`%TAG` directive lines, and re-emitting a document
1077
+ * without its `%TAG` while keeping the shorthand tags that depend on it
1078
+ * (`!e!foo`) turns a valid file into one no parser can read. So
1079
+ * `format`/`formatToString` leave such input byte-identical (no edits), and
1080
+ * `modify`/`modifyToString` fail typed with a `DirectiveCarryingDocument`
1081
+ * diagnostic. Directive re-emission is unimplemented, not undesired — the
1082
+ * refusal is the floor that stops corruption until it lands.
1083
+ *
974
1084
  * @public
975
1085
  */
976
1086
  declare class YamlFormat {
@@ -981,6 +1091,24 @@ declare class YamlFormat {
981
1091
  * Pure and total: malformed input (a fatal parse error) yields `[]` rather
982
1092
  * than corrupting the document.
983
1093
  *
1094
+ * **Multi-document streams format whole.** Input containing more than one
1095
+ * document (a `---`-separated stream — a Kubernetes manifest, a pnpm 11
1096
+ * `pnpm-lock.yaml` with a config-dependency preamble) formats every
1097
+ * document in order, re-emitting each document's own framing (`---`,
1098
+ * `...`, comment blocks); no document is ever dropped. Document detection
1099
+ * is CST-level, so a `---` inside a block scalar or quoted string is
1100
+ * content, not a document boundary. Two multi-document shapes yield `[]`
1101
+ * (untouched) because they cannot be re-emitted faithfully: a stream with
1102
+ * a fatal diagnostic in any document (the same posture as single-document
1103
+ * input) and a stream carrying `%YAML`/`%TAG` directives.
1104
+ *
1105
+ * **Directive-carrying documents yield `[]` on the single-document path
1106
+ * too.** Directive lines are not re-emitted, and dropping a `%TAG` while
1107
+ * keeping the shorthand tags that depend on it would turn a valid document
1108
+ * into an unparseable one — so a document carrying `%YAML`/`%TAG`
1109
+ * directives is left untouched. Detection is directive-token-level: a
1110
+ * literal `%TAG` inside a scalar is content and formats normally.
1111
+ *
984
1112
  * @remarks
985
1113
  * The positional `range` argument takes precedence over
986
1114
  * `options?.range` when both are given; either accepts a plain
@@ -999,6 +1127,13 @@ declare class YamlFormat {
999
1127
  /**
1000
1128
  * Format `text` and apply the resulting edits in one step
1001
1129
  * (`YamlEdit.applyAll ∘ format`). Pure and total.
1130
+ *
1131
+ * Inherits the {@link YamlFormat.format} contract: a multi-document stream
1132
+ * is formatted whole — every document re-emitted in order — and input
1133
+ * that cannot be formatted faithfully (a fatal parse error, or any
1134
+ * document — single or in a stream — carrying `%YAML`/`%TAG` directives)
1135
+ * is returned byte-identical — never a truncated first document, never a
1136
+ * document re-emitted without the directive its tags depend on.
1002
1137
  */
1003
1138
  static formatToString(text: string, range?: YamlRangeLike, options?: YamlFormattingOptions): string;
1004
1139
  /**
@@ -1010,6 +1145,23 @@ declare class YamlFormat {
1010
1145
  * {@link YamlModificationError} on a fatal parse error or a structural
1011
1146
  * navigation mismatch.
1012
1147
  *
1148
+ * **Single-document contract.** A `path` carries no document index, so on
1149
+ * a multi-document stream there is no rule for which document it names —
1150
+ * `modify` fails with {@link YamlModificationError} carrying a
1151
+ * `MultiDocumentStream` diagnostic rather than guessing document 1 (and
1152
+ * unlike {@link YamlFormat.format}, which formats a stream whole because
1153
+ * formatting needs no target). Detection is CST-level: a `---` inside a
1154
+ * block scalar or quoted string is content, not a document boundary.
1155
+ *
1156
+ * **Directive-carrying documents are refused.** A document carrying
1157
+ * `%YAML`/`%TAG` directives fails with {@link YamlModificationError}
1158
+ * carrying a `DirectiveCarryingDocument` diagnostic: modify re-emits the
1159
+ * whole document and does not re-emit directive lines, so applying it
1160
+ * would drop the `%TAG` while keeping the shorthand tags that depend on
1161
+ * it — unparseable output. A typed refusal beats silent corruption;
1162
+ * directive re-emission is unimplemented, not undesired. A literal
1163
+ * `%TAG` inside a scalar is content and does not trigger the refusal.
1164
+ *
1013
1165
  * @remarks
1014
1166
  * `options` is a bare {@link YamlStringifyOptions} — it controls only the
1015
1167
  * internal re-stringify step, not a range (there is no range to restrict
@@ -1018,11 +1170,278 @@ declare class YamlFormat {
1018
1170
  static readonly modify: (text: string, path: YamlPath, value: unknown, options?: YamlStringifyOptions | undefined) => Effect.Effect<readonly YamlEdit[], YamlModificationError, never>;
1019
1171
  /**
1020
1172
  * Modify `text` and apply the resulting edits in one step
1021
- * (`YamlEdit.applyAll ∘ modify`).
1173
+ * (`YamlEdit.applyAll ∘ modify`). Inherits the {@link YamlFormat.modify}
1174
+ * error channel, including the single-document contract's
1175
+ * `MultiDocumentStream` refusal and the `DirectiveCarryingDocument`
1176
+ * refusal of `%YAML`/`%TAG`-carrying documents.
1022
1177
  */
1023
1178
  static readonly modifyToString: (text: string, path: YamlPath, value: unknown, options?: YamlStringifyOptions | undefined) => Effect.Effect<string, YamlModificationError, never>;
1024
1179
  }
1025
1180
  //#endregion
1181
+ //#region src/YamlToken.d.ts
1182
+ /**
1183
+ * The 22 lexical token kinds produced by the YAML tokenizer.
1184
+ *
1185
+ * @public
1186
+ */
1187
+ declare const YamlTokenKind: Schema.Literals<readonly ["document-start", "document-end", "directive", "tag", "anchor", "alias", "scalar", "block-map-start", "block-map-key", "block-map-value", "block-seq-start", "block-seq-entry", "flow-map-start", "flow-map-end", "flow-seq-start", "flow-seq-end", "flow-separator", "newline", "whitespace", "comment", "byte-order-mark", "error"]>;
1188
+ /**
1189
+ * The union of all lexical token kind string literals.
1190
+ *
1191
+ * @public
1192
+ */
1193
+ type YamlTokenKind = typeof YamlTokenKind.Type;
1194
+ declare const YamlToken_base: Schema.Class<YamlToken, Schema.Struct<{
1195
+ readonly kind: Schema.Literals<readonly ["document-start", "document-end", "directive", "tag", "anchor", "alias", "scalar", "block-map-start", "block-map-key", "block-map-value", "block-seq-start", "block-seq-entry", "flow-map-start", "flow-map-end", "flow-seq-start", "flow-seq-end", "flow-separator", "newline", "whitespace", "comment", "byte-order-mark", "error"]>;
1196
+ readonly text: Schema.String;
1197
+ readonly offset: Schema.Number;
1198
+ readonly length: Schema.Number;
1199
+ readonly line: Schema.Number;
1200
+ readonly character: Schema.Number;
1201
+ }>, {}>;
1202
+ /**
1203
+ * A single positioned YAML lexical token.
1204
+ *
1205
+ * - `kind` — the {@link (YamlTokenKind:type)}.
1206
+ * - `text` — the raw source slice the token covers; the position-fidelity
1207
+ * invariant is `source.slice(offset, offset + length) === text`.
1208
+ * - `offset` / `length` — the token's span in UTF-16 code units.
1209
+ * - `line` / `character` — the zero-based position of the token's start,
1210
+ * matching the `YamlDiagnostic` position vocabulary.
1211
+ *
1212
+ * @public
1213
+ */
1214
+ declare class YamlToken extends YamlToken_base {}
1215
+ /**
1216
+ * Tokenizer statics. Not instantiable.
1217
+ *
1218
+ * @public
1219
+ */
1220
+ declare class YamlTokens {
1221
+ private constructor();
1222
+ /**
1223
+ * Tokenize YAML text into the full positioned token array — the sync
1224
+ * `Result` primitive (tokenizing is a pure batch transform; the
1225
+ * {@link YamlTokens.stream} form is derived from this one, per the kit's
1226
+ * sync-primitive policy).
1227
+ *
1228
+ * @remarks
1229
+ * The failure channel is **reserved** (for future input-hardening guards)
1230
+ * and never fires today: the lexer is total, and lexical errors surface as
1231
+ * `"error"`-kind tokens **in the success array** so that linting can run
1232
+ * on malformed input — the `parse-validity` lint rule exists precisely for
1233
+ * documents that do not parse. Do not "fix" this method to fail on
1234
+ * `"error"` tokens; that would make malformed documents unlintable.
1235
+ *
1236
+ * @example
1237
+ * ```ts
1238
+ * import { YamlTokens } from "@effected/yaml";
1239
+ * import { Result } from "effect";
1240
+ *
1241
+ * const result = YamlTokens.tokenize("a: 1\n");
1242
+ * if (Result.isSuccess(result)) {
1243
+ * result.success.map((t) => t.kind); // ["scalar", "block-map-start", ...]
1244
+ * }
1245
+ * ```
1246
+ */
1247
+ static tokenize(text: string): Result.Result<ReadonlyArray<YamlToken>, YamlParseError>;
1248
+ /**
1249
+ * Tokenize YAML text as a lazy `Stream` of tokens — the derived form of
1250
+ * {@link YamlTokens.tokenize} for genuinely incremental (SAX-style)
1251
+ * consumers, parallel to `YamlVisitor.visit`.
1252
+ *
1253
+ * @remarks
1254
+ * Derived from the sync primitive, so it shares its contract: lexical
1255
+ * errors arrive as `"error"`-kind tokens in the stream, never as a stream
1256
+ * failure. (The primitive's reserved failure channel would surface as a
1257
+ * defect here; it never fires today.)
1258
+ */
1259
+ static stream(text: string): Stream.Stream<YamlToken>;
1260
+ }
1261
+ //#endregion
1262
+ //#region src/YamlLintRule.d.ts
1263
+ /**
1264
+ * Lint diagnostic severities. `"off"` is a config-level disable only and
1265
+ * never reaches a diagnostic — a rule set to `"off"` is not run.
1266
+ *
1267
+ * @public
1268
+ */
1269
+ declare const YamlLintSeverity: Schema.Literals<readonly ["error", "warning"]>;
1270
+ /**
1271
+ * The union of lint severity string literals.
1272
+ *
1273
+ * @public
1274
+ */
1275
+ type YamlLintSeverity = typeof YamlLintSeverity.Type;
1276
+ declare const YamlLintDiagnostic_base: Schema.Class<YamlLintDiagnostic, Schema.Struct<{
1277
+ readonly rule: Schema.String;
1278
+ readonly severity: Schema.Literals<readonly ["error", "warning"]>;
1279
+ readonly message: Schema.String;
1280
+ readonly offset: Schema.Number;
1281
+ readonly length: Schema.Number;
1282
+ readonly line: Schema.Number;
1283
+ readonly character: Schema.Number;
1284
+ readonly fix: Schema.optionalKey<typeof YamlEdit>;
1285
+ }>, {}>;
1286
+ /**
1287
+ * A single lint finding: the reporting rule, its severity, a positioned span
1288
+ * and optionally a surgical fix.
1289
+ *
1290
+ * Deliberately separate from the engine's `YamlDiagnostic`: that type is the
1291
+ * lexer/parser/composer/stringifier error-code union and the single source
1292
+ * of truth for engine fatality — it carries no severity and no fix, and
1293
+ * lint-layer concerns must not pollute it. The `parse-validity` rule bridges
1294
+ * the two by mapping engine diagnostics into this shape.
1295
+ *
1296
+ * @public
1297
+ */
1298
+ declare class YamlLintDiagnostic extends YamlLintDiagnostic_base {}
1299
+ /**
1300
+ * One source line of the linted document: its text (without the line
1301
+ * terminator — the `\n`, and for CRLF input the `\r\n` pair), the offset of
1302
+ * its first character, and its zero-based line number.
1303
+ *
1304
+ * @public
1305
+ */
1306
+ interface LintLine {
1307
+ readonly text: string;
1308
+ readonly offset: number;
1309
+ readonly number: number;
1310
+ }
1311
+ /**
1312
+ * The context handed to every rule. The engine tokenizes ONCE and every rule
1313
+ * shares the one materialized `tokens` array — linting is inherently
1314
+ * multi-pass and random-access (layout rules need lookahead and lookbehind),
1315
+ * so the context is eager by nature; the streaming token form exists for
1316
+ * other consumers.
1317
+ *
1318
+ * `text`, `lines` and `tokens` cover the FULL source; `document` is the
1319
+ * FIRST document of the stream (matching `Yaml.parse` — split the stream
1320
+ * `Yaml.parseAll`-style to lint every document). It is always present,
1321
+ * including for input that does not parse: it is built from the engine's
1322
+ * recovered compose, and its `errors`/`warnings` carry what went wrong (the
1323
+ * `parse-validity` rule reports them).
1324
+ *
1325
+ * @public
1326
+ */
1327
+ interface LintContext {
1328
+ readonly text: string;
1329
+ readonly lines: ReadonlyArray<LintLine>;
1330
+ readonly tokens: ReadonlyArray<YamlToken>;
1331
+ readonly document: YamlDocument;
1332
+ }
1333
+ /**
1334
+ * The public rule interface — built-ins and custom rules are the same
1335
+ * shape, and config references either by `id`; there is no privileged
1336
+ * built-in mechanism a custom rule cannot reach.
1337
+ *
1338
+ * `options` is the validated per-rule options object from the config entry
1339
+ * (or `undefined` when the entry was a bare severity literal); built-in
1340
+ * rules receive options already validated against their exported options
1341
+ * schema, custom rules validate their own.
1342
+ *
1343
+ * @public
1344
+ */
1345
+ interface YamlRule {
1346
+ readonly id: string;
1347
+ readonly check: (ctx: LintContext, options: unknown) => Iterable<YamlLintDiagnostic>;
1348
+ }
1349
+ //#endregion
1350
+ //#region src/YamlLint.d.ts
1351
+ /**
1352
+ * One entry of the config `rules` map: a bare severity literal (the common
1353
+ * case), `"off"` to disable, or a typed per-rule options object (the tuning
1354
+ * case; may carry its own `severity`).
1355
+ *
1356
+ * @public
1357
+ */
1358
+ declare const YamlLintRuleSetting: Schema.Union<readonly [Schema.Literals<readonly ["error", "warning", "off"]>, Schema.$Record<Schema.String, Schema.Unknown>]>;
1359
+ /**
1360
+ * The union type of one `rules`-map entry.
1361
+ *
1362
+ * @public
1363
+ */
1364
+ type YamlLintRuleSetting = typeof YamlLintRuleSetting.Type;
1365
+ declare const YamlLintConfig_base: Schema.Class<YamlLintConfig, Schema.Struct<{
1366
+ readonly rules: Schema.$Record<Schema.String, Schema.Union<readonly [Schema.Literals<readonly ["error", "warning", "off"]>, Schema.$Record<Schema.String, Schema.Unknown>]>>;
1367
+ }>, {}>;
1368
+ /**
1369
+ * The lint configuration: a `rules` map keying rule ids (built-in or custom)
1370
+ * to a severity literal or a typed per-rule options object.
1371
+ *
1372
+ * Validation is rule-aware for the built-in catalog — a mistyped option on a
1373
+ * built-in rule fails schema validation with a typed error naming the rule,
1374
+ * and any attempt to demote or disable the always-on `parse-validity` rule
1375
+ * is rejected. Custom rule ids are accepted with a bare severity or an
1376
+ * opaque options object the custom rule validates itself.
1377
+ *
1378
+ * Presets ship as the statics {@link YamlLintConfig.default} and
1379
+ * {@link YamlLintConfig.relaxed} — composing one is object spread over a
1380
+ * static, not an `extends` string resolution step (this package owns no
1381
+ * config-file loader).
1382
+ *
1383
+ * @public
1384
+ */
1385
+ declare class YamlLintConfig extends YamlLintConfig_base {
1386
+ /**
1387
+ * The default preset. Rule entries accrete as built-ins land; the
1388
+ * `quoted-strings` rule defaults to DOUBLE quotes here (the one taste
1389
+ * call the design pins).
1390
+ */
1391
+ static readonly default: YamlLintConfig;
1392
+ /** The relaxed preset: style rules demoted to warnings. */
1393
+ static readonly relaxed: YamlLintConfig;
1394
+ }
1395
+ /**
1396
+ * Linting statics. Not instantiable.
1397
+ *
1398
+ * @remarks
1399
+ * Pure and synchronous throughout — the lint engine is the pure half only:
1400
+ * strings in, diagnostics or a fixed string out. File discovery, config-file
1401
+ * loading and autofix-to-disk belong to a consumer's tier, not here.
1402
+ *
1403
+ * @public
1404
+ */
1405
+ declare class YamlLint {
1406
+ private constructor();
1407
+ /**
1408
+ * The built-in rule catalog. Custom usage is array concatenation:
1409
+ * `YamlLint.run(text, [...YamlLint.builtins, myRule], config)`.
1410
+ */
1411
+ static readonly builtins: ReadonlyArray<YamlRule>;
1412
+ /**
1413
+ * Run `rules` over `text` under `config`, returning every finding sorted
1414
+ * by position.
1415
+ *
1416
+ * Document-driven rules see the FIRST document of the stream (matching
1417
+ * `Yaml.parse`; split the stream `Yaml.parseAll`-style to lint every
1418
+ * document), while token- and line-driven rules cover the full source —
1419
+ * see {@link LintContext}.
1420
+ *
1421
+ * A rule runs when its config entry is a severity or an options object;
1422
+ * `"off"` and absent entries skip it — except `parse-validity`, which is
1423
+ * always-on. The resolved severity (explicit-in-options, else the bare
1424
+ * literal, else `"error"`) overrides what the rule emitted, again except
1425
+ * for `parse-validity`, whose bridged engine diagnostics keep the
1426
+ * engine's own grading.
1427
+ */
1428
+ static run(text: string, rules: ReadonlyArray<YamlRule>, config: YamlLintConfig): ReadonlyArray<YamlLintDiagnostic>;
1429
+ /**
1430
+ * Run `rules` and apply every non-overlapping surgical fix, returning the
1431
+ * fixed text. Fails with {@link YamlParseError} when the FIRST document
1432
+ * of the stream has a fatal parse error — a document the engine cannot
1433
+ * compose is not safely fixable. The gate matches `Yaml.parse`'s scope:
1434
+ * later documents of a multi-document stream are not composed (split the
1435
+ * stream `Yaml.parseAll`-style to lint every document), though token- and
1436
+ * line-driven fixes still cover the full source. Fixes route exclusively through `YamlEdit.applyAll` (never a
1437
+ * reformat), so applying them is comment-safe by construction; when two
1438
+ * fixes overlap — or start at the same offset — the earlier one in
1439
+ * {@link YamlLint.run} order (position, then rule id) wins and the later
1440
+ * is dropped (its diagnostic remains reported by {@link YamlLint.run}).
1441
+ */
1442
+ static fix(text: string, rules: ReadonlyArray<YamlRule>, config: YamlLintConfig): Result.Result<string, YamlParseError>;
1443
+ }
1444
+ //#endregion
1026
1445
  //#region src/YamlVisitor.d.ts
1027
1446
  /**
1028
1447
  * The discriminated union of YAML AST visitor events. Every variant carries
@@ -1091,6 +1510,8 @@ type YamlVisitorEvent = Data.TaggedEnum<{
1091
1510
  readonly path: YamlPath;
1092
1511
  readonly depth: number;
1093
1512
  readonly text: string;
1513
+ /** Where the comment sits relative to its construct: own-line above (`"leading"`) or same-line after (`"trailing"`). */
1514
+ readonly placement: "leading" | "trailing";
1094
1515
  };
1095
1516
  Directive: {
1096
1517
  readonly path: YamlPath;
@@ -1124,6 +1545,7 @@ declare const YamlVisitorEvent: {
1124
1545
  readonly path: YamlPath;
1125
1546
  readonly depth: number;
1126
1547
  readonly text: string;
1548
+ readonly placement: "leading" | "trailing";
1127
1549
  }, {
1128
1550
  readonly _tag: Tag;
1129
1551
  }> | Extract<{
@@ -1219,6 +1641,7 @@ declare const YamlVisitorEvent: {
1219
1641
  readonly path: YamlPath;
1220
1642
  readonly depth: number;
1221
1643
  readonly text: string;
1644
+ readonly placement: "leading" | "trailing";
1222
1645
  }) => any;
1223
1646
  readonly Directive: (args: {
1224
1647
  readonly _tag: "Directive";
@@ -1299,6 +1722,7 @@ declare const YamlVisitorEvent: {
1299
1722
  readonly path: YamlPath;
1300
1723
  readonly depth: number;
1301
1724
  readonly text: string;
1725
+ readonly placement: "leading" | "trailing";
1302
1726
  } | {
1303
1727
  readonly _tag: "Directive";
1304
1728
  readonly path: YamlPath;
@@ -1371,6 +1795,7 @@ declare const YamlVisitorEvent: {
1371
1795
  readonly path: YamlPath;
1372
1796
  readonly depth: number;
1373
1797
  readonly text: string;
1798
+ readonly placement: "leading" | "trailing";
1374
1799
  }) => any;
1375
1800
  readonly Directive: (args: {
1376
1801
  readonly _tag: "Directive";
@@ -1451,6 +1876,7 @@ declare const YamlVisitorEvent: {
1451
1876
  readonly path: YamlPath;
1452
1877
  readonly depth: number;
1453
1878
  readonly text: string;
1879
+ readonly placement: "leading" | "trailing";
1454
1880
  } | {
1455
1881
  readonly _tag: "Directive";
1456
1882
  readonly path: YamlPath;
@@ -1523,6 +1949,7 @@ declare const YamlVisitorEvent: {
1523
1949
  readonly path: YamlPath;
1524
1950
  readonly depth: number;
1525
1951
  readonly text: string;
1952
+ readonly placement: "leading" | "trailing";
1526
1953
  }, "_tag">;
1527
1954
  readonly Directive: Data.TaggedEnum.ConstructorFrom<{
1528
1955
  readonly _tag: "Directive";
@@ -1617,5 +2044,5 @@ declare class YamlVisitor {
1617
2044
  static visit(text: string, options?: YamlParseOptions): Stream.Stream<YamlVisitorEvent>;
1618
2045
  }
1619
2046
  //#endregion
1620
- export { CollectionStyle, QuoteStyle, ScalarChomp, ScalarStyle, Yaml, YamlAlias, type YamlAliasEncoded, type YamlBoundCodec, YamlComposerErrorCode, YamlDiagnostic, YamlDirective, YamlDocument, YamlEdit, YamlErrorCode, YamlFormat, YamlFormattingOptions, YamlLexErrorCode, YamlMap, type YamlMapEncoded, YamlModificationError, YamlModifyErrorCode, YamlNode, YamlPair, YamlParseError, YamlParseErrorCode, YamlParseOptions, type YamlPath, YamlRange, type YamlRangeLike, YamlScalar, type YamlScalarEncoded, type YamlSegment, YamlSeq, type YamlSeqEncoded, YamlStringifyError, YamlStringifyErrorCode, YamlStringifyOptions, YamlVisitor, YamlVisitorEvent };
2047
+ export { CollectionStyle, type LintContext, type LintLine, QuoteStyle, ScalarChomp, ScalarStyle, Yaml, YamlAlias, type YamlAliasEncoded, type YamlBoundCodec, YamlComposerErrorCode, YamlDiagnostic, YamlDirective, YamlDocument, YamlEdit, YamlErrorCode, YamlFormat, YamlFormattingOptions, YamlLexErrorCode, YamlLint, YamlLintConfig, YamlLintDiagnostic, YamlLintRuleSetting, YamlLintSeverity, YamlMap, type YamlMapEncoded, YamlModificationError, YamlModifyErrorCode, YamlNode, YamlPair, YamlParseError, YamlParseErrorCode, YamlParseOptions, type YamlPath, YamlRange, type YamlRangeLike, type YamlRule, YamlScalar, type YamlScalarEncoded, type YamlSegment, YamlSeq, type YamlSeqEncoded, YamlStringifyError, YamlStringifyErrorCode, YamlStringifyOptions, YamlToken, YamlTokenKind, YamlTokens, YamlVisitor, YamlVisitorEvent };
1621
2048
  //# sourceMappingURL=index.d.ts.map