yaml 2.2.0 → 2.3.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/README.md CHANGED
@@ -14,6 +14,10 @@ It has no external dependencies and runs on Node.js as well as modern browsers.
14
14
  For the purposes of versioning, any changes that break any of the documented endpoints or APIs will be considered semver-major breaking changes.
15
15
  Undocumented library internals may change between minor versions, and previous APIs may be deprecated (but not removed).
16
16
 
17
+ The minimum supported TypeScript version of the included typings is 3.9;
18
+ for use in earlier versions you may need to set `skipLibCheck: true` in your config.
19
+ This requirement may be updated between minor versions of the library.
20
+
17
21
  For more information, see the project's documentation site: [**eemeli.org/yaml**](https://eemeli.org/yaml/)
18
22
 
19
23
  To install:
@@ -26,6 +26,7 @@ function composeDoc(options, directives, { offset, start, value, end }, onError)
26
26
  !props.hasNewline)
27
27
  onError(props.end, 'MISSING_CHAR', 'Block collection cannot start on same line with directives-end marker');
28
28
  }
29
+ // @ts-expect-error If Contents is set, let's trust the user
29
30
  doc.contents = value
30
31
  ? composeNode(ctx, value, props, onError)
31
32
  : composeEmptyNode(ctx, props.end, start, null, props, onError);
@@ -49,11 +49,9 @@ class Document {
49
49
  else
50
50
  this.directives = new Directives({ version });
51
51
  this.setSchema(version, options);
52
- if (value === undefined)
53
- this.contents = null;
54
- else {
55
- this.contents = this.createNode(value, _replacer, options);
56
- }
52
+ // @ts-expect-error We can't really know that this matches Contents.
53
+ this.contents =
54
+ value === undefined ? null : this.createNode(value, _replacer, options);
57
55
  }
58
56
  /**
59
57
  * Create a deep copy of this Document and its contents.
@@ -72,6 +70,7 @@ class Document {
72
70
  if (this.directives)
73
71
  copy.directives = this.directives.clone();
74
72
  copy.schema = this.schema.clone();
73
+ // @ts-expect-error We can't really know that this matches Contents.
75
74
  copy.contents = isNode(this.contents)
76
75
  ? this.contents.clone(copy.schema)
77
76
  : this.contents;
@@ -167,6 +166,7 @@ class Document {
167
166
  if (isEmptyPath(path)) {
168
167
  if (this.contents == null)
169
168
  return false;
169
+ // @ts-expect-error Presumed impossible if Strict extends false
170
170
  this.contents = null;
171
171
  return true;
172
172
  }
@@ -218,6 +218,7 @@ class Document {
218
218
  */
219
219
  set(key, value) {
220
220
  if (this.contents == null) {
221
+ // @ts-expect-error We can't really know that this matches Contents.
221
222
  this.contents = collectionFromPath(this.schema, [key], value);
222
223
  }
223
224
  else if (assertCollection(this.contents)) {
@@ -229,9 +230,12 @@ class Document {
229
230
  * boolean to add/remove the item from the set.
230
231
  */
231
232
  setIn(path, value) {
232
- if (isEmptyPath(path))
233
+ if (isEmptyPath(path)) {
234
+ // @ts-expect-error We can't really know that this matches Contents.
233
235
  this.contents = value;
236
+ }
234
237
  else if (this.contents == null) {
238
+ // @ts-expect-error We can't really know that this matches Contents.
235
239
  this.contents = collectionFromPath(this.schema, Array.from(path), value);
236
240
  }
237
241
  else if (assertCollection(this.contents)) {
@@ -12,7 +12,7 @@ import { omap } from './yaml-1.1/omap.js';
12
12
  import { pairs } from './yaml-1.1/pairs.js';
13
13
  import { schema as schema$2 } from './yaml-1.1/schema.js';
14
14
  import { set } from './yaml-1.1/set.js';
15
- import { floatTime, intTime, timestamp } from './yaml-1.1/timestamp.js';
15
+ import { timestamp, floatTime, intTime } from './yaml-1.1/timestamp.js';
16
16
 
17
17
  const schemas = new Map([
18
18
  ['core', schema],
@@ -133,7 +133,7 @@ function stringifyFlowCollection({ comment, items }, ctx, { flowChars, itemInden
133
133
  }
134
134
  }
135
135
  if (comment) {
136
- str += lineComment(str, commentString(comment), indent);
136
+ str += lineComment(str, indent, commentString(comment));
137
137
  if (onComment)
138
138
  onComment();
139
139
  }
@@ -146,6 +146,15 @@ function quotedString(value, ctx) {
146
146
  }
147
147
  return qs(value, ctx);
148
148
  }
149
+ // The negative lookbehind avoids a polynomial search,
150
+ // but isn't supported yet on Safari: https://caniuse.com/js-regexp-lookbehind
151
+ let blockEndNewlines;
152
+ try {
153
+ blockEndNewlines = new RegExp('(^|(?<!\n))\n+(?!\n|$)', 'g');
154
+ }
155
+ catch {
156
+ blockEndNewlines = /\n+(?!\n|$)/g;
157
+ }
149
158
  function blockString({ comment, type, value }, ctx, onComment, onChompKeep) {
150
159
  const { blockQuote, commentString, lineWidth } = ctx.options;
151
160
  // 1. Block can't end in whitespace unless the last line is non-empty.
@@ -189,7 +198,7 @@ function blockString({ comment, type, value }, ctx, onComment, onChompKeep) {
189
198
  value = value.slice(0, -end.length);
190
199
  if (end[end.length - 1] === '\n')
191
200
  end = end.slice(0, -1);
192
- end = end.replace(/\n+(?!\n|$)/g, `$&${indent}`);
201
+ end = end.replace(blockEndNewlines, `$&${indent}`);
193
202
  }
194
203
  // determine indent indicator from whitespace at value start
195
204
  let startWithSpace = false;
@@ -230,7 +239,7 @@ function blockString({ comment, type, value }, ctx, onComment, onChompKeep) {
230
239
  }
231
240
  function plainString(item, ctx, onComment, onChompKeep) {
232
241
  const { type, value } = item;
233
- const { actualString, implicitKey, indent, inFlow } = ctx;
242
+ const { actualString, implicitKey, indent, indentStep, inFlow } = ctx;
234
243
  if ((implicitKey && /[\n[\]{},]/.test(value)) ||
235
244
  (inFlow && /[[\]{},]/.test(value))) {
236
245
  return quotedString(value, ctx);
@@ -254,9 +263,14 @@ function plainString(item, ctx, onComment, onChompKeep) {
254
263
  // Where allowed & type not set explicitly, prefer block style for multiline strings
255
264
  return blockString(item, ctx, onComment, onChompKeep);
256
265
  }
257
- if (indent === '' && containsDocumentMarker(value)) {
258
- ctx.forceBlockIndent = true;
259
- return blockString(item, ctx, onComment, onChompKeep);
266
+ if (containsDocumentMarker(value)) {
267
+ if (indent === '') {
268
+ ctx.forceBlockIndent = true;
269
+ return blockString(item, ctx, onComment, onChompKeep);
270
+ }
271
+ else if (implicitKey && indent === indentStep) {
272
+ return quotedString(value, ctx);
273
+ }
260
274
  }
261
275
  const str = value.replace(/\n+/g, `$&\n${indent}`);
262
276
  // Verify that output will be parsed as a string, as e.g. plain numbers and
@@ -1,6 +1,7 @@
1
1
  import type { Directives } from '../doc/directives.js';
2
2
  import { Document } from '../doc/Document.js';
3
+ import type { ParsedNode } from '../nodes/Node.js';
3
4
  import type { DocumentOptions, ParseOptions, SchemaOptions } from '../options.js';
4
5
  import type * as CST from '../parse/cst.js';
5
6
  import type { ComposeErrorHandler } from './composer.js';
6
- export declare function composeDoc(options: ParseOptions & DocumentOptions & SchemaOptions, directives: Directives, { offset, start, value, end }: CST.Document, onError: ComposeErrorHandler): Document.Parsed<import("../index.js").ParsedNode>;
7
+ export declare function composeDoc<Contents extends ParsedNode = ParsedNode, Strict extends boolean = true>(options: ParseOptions & DocumentOptions & SchemaOptions, directives: Directives, { offset, start, value, end }: CST.Document, onError: ComposeErrorHandler): Document.Parsed<Contents, Strict>;
@@ -28,6 +28,7 @@ function composeDoc(options, directives, { offset, start, value, end }, onError)
28
28
  !props.hasNewline)
29
29
  onError(props.end, 'MISSING_CHAR', 'Block collection cannot start on same line with directives-end marker');
30
30
  }
31
+ // @ts-expect-error If Contents is set, let's trust the user
31
32
  doc.contents = value
32
33
  ? composeNode.composeNode(ctx, value, props, onError)
33
34
  : composeNode.composeEmptyNode(ctx, props.end, start, null, props, onError);
@@ -1,7 +1,7 @@
1
1
  import { Directives } from '../doc/directives.js';
2
2
  import { Document } from '../doc/Document.js';
3
3
  import { ErrorCode, YAMLParseError, YAMLWarning } from '../errors.js';
4
- import { Range } from '../nodes/Node.js';
4
+ import { ParsedNode, Range } from '../nodes/Node.js';
5
5
  import type { DocumentOptions, ParseOptions, SchemaOptions } from '../options.js';
6
6
  import type { Token } from '../parse/cst.js';
7
7
  type ErrorSource = number | [number, number] | Range | {
@@ -20,7 +20,7 @@ export type ComposeErrorHandler = (source: ErrorSource, code: ErrorCode, message
20
20
  * const docs = new Composer().compose(tokens)
21
21
  * ```
22
22
  */
23
- export declare class Composer {
23
+ export declare class Composer<Contents extends ParsedNode = ParsedNode, Strict extends boolean = true> {
24
24
  private directives;
25
25
  private doc;
26
26
  private options;
@@ -48,15 +48,15 @@ export declare class Composer {
48
48
  * @param forceDoc - If the stream contains no document, still emit a final document including any comments and directives that would be applied to a subsequent document.
49
49
  * @param endOffset - Should be set if `forceDoc` is also set, to set the document range end and to indicate errors correctly.
50
50
  */
51
- compose(tokens: Iterable<Token>, forceDoc?: boolean, endOffset?: number): Generator<Document.Parsed<import("../nodes/Node.js").ParsedNode>, void, unknown>;
51
+ compose(tokens: Iterable<Token>, forceDoc?: boolean, endOffset?: number): Generator<Document.Parsed<Contents, Strict>, void, unknown>;
52
52
  /** Advance the composer by one CST token. */
53
- next(token: Token): Generator<Document.Parsed<import("../nodes/Node.js").ParsedNode>, void, unknown>;
53
+ next(token: Token): Generator<Document.Parsed<Contents, Strict>, void, unknown>;
54
54
  /**
55
55
  * Call at end of input to yield any remaining document.
56
56
  *
57
57
  * @param forceDoc - If the stream contains no document, still emit a final document including any comments and directives that would be applied to a subsequent document.
58
58
  * @param endOffset - Should be set if `forceDoc` is also set, to set the document range end and to indicate errors correctly.
59
59
  */
60
- end(forceDoc?: boolean, endOffset?: number): Generator<Document.Parsed<import("../nodes/Node.js").ParsedNode>, void, unknown>;
60
+ end(forceDoc?: boolean, endOffset?: number): Generator<Document.Parsed<Contents, Strict>, void, unknown>;
61
61
  }
62
62
  export {};
@@ -10,20 +10,21 @@ import { Schema } from '../schema/Schema.js';
10
10
  import { Directives } from './directives.js';
11
11
  export type Replacer = any[] | ((key: any, value: any) => unknown);
12
12
  export declare namespace Document {
13
- interface Parsed<T extends ParsedNode = ParsedNode> extends Document<T> {
13
+ /** @ts-ignore The typing of directives fails in TS <= 4.2 */
14
+ interface Parsed<Contents extends ParsedNode = ParsedNode, Strict extends boolean = true> extends Document<Contents, Strict> {
14
15
  directives: Directives;
15
16
  range: Range;
16
17
  }
17
18
  }
18
- export declare class Document<T extends Node = Node> {
19
+ export declare class Document<Contents extends Node = Node, Strict extends boolean = true> {
19
20
  readonly [NODE_TYPE]: symbol;
20
21
  /** A comment before this Document */
21
22
  commentBefore: string | null;
22
23
  /** A comment immediately after this Document */
23
24
  comment: string | null;
24
25
  /** The document contents. */
25
- contents: T | null;
26
- directives?: Directives;
26
+ contents: Strict extends true ? Contents | null : Contents;
27
+ directives: Strict extends true ? Directives | undefined : Directives;
27
28
  /** Errors encountered during parsing. */
28
29
  errors: YAMLError[];
29
30
  options: Required<Omit<ParseOptions & DocumentOptions, '_directives' | 'lineCounter' | 'version'>>;
@@ -49,7 +50,7 @@ export declare class Document<T extends Node = Node> {
49
50
  *
50
51
  * Custom Node values that inherit from `Object` still refer to their original instances.
51
52
  */
52
- clone(): Document<T>;
53
+ clone(): Document<Contents, Strict>;
53
54
  /** Adds a value to the document. */
54
55
  add(value: any): void;
55
56
  /** Adds a value to the document. */
@@ -63,7 +64,7 @@ export declare class Document<T extends Node = Node> {
63
64
  * `name` will be used as a prefix for a new unique anchor.
64
65
  * If `name` is undefined, the generated anchor will use 'a' as a prefix.
65
66
  */
66
- createAlias(node: Scalar | YAMLMap | YAMLSeq, name?: string): Alias;
67
+ createAlias(node: Strict extends true ? Scalar | YAMLMap | YAMLSeq : Node, name?: string): Alias;
67
68
  /**
68
69
  * Convert any value into a `Node` using the current schema, recursively
69
70
  * turning objects into collections.
@@ -90,13 +91,13 @@ export declare class Document<T extends Node = Node> {
90
91
  * scalar values from their surrounding node; to disable set `keepScalar` to
91
92
  * `true` (collections are always returned intact).
92
93
  */
93
- get(key: unknown, keepScalar?: boolean): unknown;
94
+ get(key: unknown, keepScalar?: boolean): Strict extends true ? unknown : any;
94
95
  /**
95
96
  * Returns item at `path`, or `undefined` if not found. By default unwraps
96
97
  * scalar values from their surrounding node; to disable set `keepScalar` to
97
98
  * `true` (collections are always returned intact).
98
99
  */
99
- getIn(path: Iterable<unknown> | null, keepScalar?: boolean): unknown;
100
+ getIn(path: Iterable<unknown> | null, keepScalar?: boolean): Strict extends true ? unknown : any;
100
101
  /**
101
102
  * Checks if the document includes a value with the key `key`.
102
103
  */
@@ -51,11 +51,9 @@ class Document {
51
51
  else
52
52
  this.directives = new directives.Directives({ version });
53
53
  this.setSchema(version, options);
54
- if (value === undefined)
55
- this.contents = null;
56
- else {
57
- this.contents = this.createNode(value, _replacer, options);
58
- }
54
+ // @ts-expect-error We can't really know that this matches Contents.
55
+ this.contents =
56
+ value === undefined ? null : this.createNode(value, _replacer, options);
59
57
  }
60
58
  /**
61
59
  * Create a deep copy of this Document and its contents.
@@ -74,6 +72,7 @@ class Document {
74
72
  if (this.directives)
75
73
  copy.directives = this.directives.clone();
76
74
  copy.schema = this.schema.clone();
75
+ // @ts-expect-error We can't really know that this matches Contents.
77
76
  copy.contents = Node.isNode(this.contents)
78
77
  ? this.contents.clone(copy.schema)
79
78
  : this.contents;
@@ -169,6 +168,7 @@ class Document {
169
168
  if (Collection.isEmptyPath(path)) {
170
169
  if (this.contents == null)
171
170
  return false;
171
+ // @ts-expect-error Presumed impossible if Strict extends false
172
172
  this.contents = null;
173
173
  return true;
174
174
  }
@@ -220,6 +220,7 @@ class Document {
220
220
  */
221
221
  set(key, value) {
222
222
  if (this.contents == null) {
223
+ // @ts-expect-error We can't really know that this matches Contents.
223
224
  this.contents = Collection.collectionFromPath(this.schema, [key], value);
224
225
  }
225
226
  else if (assertCollection(this.contents)) {
@@ -231,9 +232,12 @@ class Document {
231
232
  * boolean to add/remove the item from the set.
232
233
  */
233
234
  setIn(path, value) {
234
- if (Collection.isEmptyPath(path))
235
+ if (Collection.isEmptyPath(path)) {
236
+ // @ts-expect-error We can't really know that this matches Contents.
235
237
  this.contents = value;
238
+ }
236
239
  else if (this.contents == null) {
240
+ // @ts-expect-error We can't really know that this matches Contents.
237
241
  this.contents = Collection.collectionFromPath(this.schema, Array.from(path), value);
238
242
  }
239
243
  else if (assertCollection(this.contents)) {
@@ -6,10 +6,10 @@ import type { Document } from './Document.js';
6
6
  * Will throw on errors.
7
7
  */
8
8
  export declare function anchorIsValid(anchor: string): true;
9
- export declare function anchorNames(root: Document | Node): Set<string>;
9
+ export declare function anchorNames(root: Document<Node, boolean> | Node): Set<string>;
10
10
  /** Find a new anchor name with the given `prefix` and a one-indexed suffix. */
11
11
  export declare function findNewAnchor(prefix: string, exclude: Set<string>): string;
12
- export declare function createNodeAnchors(doc: Document, prefix: string): {
12
+ export declare function createNodeAnchors(doc: Document<Node, boolean>, prefix: string): {
13
13
  onAnchor: (source: unknown) => string;
14
14
  /**
15
15
  * With circular references, the source node is only resolved after all
@@ -8,7 +8,7 @@ import type { YAMLMap } from './YAMLMap.js';
8
8
  import type { YAMLSeq } from './YAMLSeq.js';
9
9
  export type Node<T = unknown> = Alias | Scalar<T> | YAMLMap<unknown, T> | YAMLSeq<T>;
10
10
  /** Utility type mapper */
11
- export type NodeType<T> = T extends string | number | bigint | boolean | null ? Scalar<T> : T extends Array<any> ? YAMLSeq<NodeType<T[number]>> : T extends {
11
+ export type NodeType<T> = T extends string | number | bigint | boolean | null | undefined ? Scalar<T> : T extends Date ? Scalar<string | Date> : T extends Array<any> ? YAMLSeq<NodeType<T[number]>> : T extends {
12
12
  [key: string]: any;
13
13
  } ? YAMLMap<NodeType<keyof T>, NodeType<T[keyof T]>> : T extends {
14
14
  [key: number]: any;
@@ -23,7 +23,7 @@ export declare const SCALAR: unique symbol;
23
23
  export declare const SEQ: unique symbol;
24
24
  export declare const NODE_TYPE: unique symbol;
25
25
  export declare const isAlias: (node: any) => node is Alias;
26
- export declare const isDocument: <T extends Node<unknown> = Node<unknown>>(node: any) => node is Document<T>;
26
+ export declare const isDocument: <T extends Node<unknown> = Node<unknown>>(node: any) => node is Document<T, true>;
27
27
  export declare const isMap: <K = unknown, V = unknown>(node: any) => node is YAMLMap<K, V>;
28
28
  export declare const isPair: <K = unknown, V = unknown>(node: any) => node is Pair<K, V>;
29
29
  export declare const isScalar: <T = unknown>(node: any) => node is Scalar<T>;
@@ -8,7 +8,7 @@ export interface AnchorData {
8
8
  }
9
9
  export interface ToJSContext {
10
10
  anchors: Map<Node, AnchorData>;
11
- doc: Document;
11
+ doc: Document<Node, boolean>;
12
12
  keep: boolean;
13
13
  mapAsMap: boolean;
14
14
  mapKeyWarned: boolean;
@@ -1,7 +1,7 @@
1
1
  import { Composer } from './compose/composer.js';
2
2
  import type { Reviver } from './doc/applyReviver.js';
3
3
  import { Document, Replacer } from './doc/Document.js';
4
- import type { ParsedNode } from './nodes/Node.js';
4
+ import type { Node, ParsedNode } from './nodes/Node.js';
5
5
  import type { CreateNodeOptions, DocumentOptions, ParseOptions, SchemaOptions, ToJSOptions, ToStringOptions } from './options.js';
6
6
  export interface EmptyStream extends Array<Document.Parsed>, ReturnType<Composer['streamInfo']> {
7
7
  empty: true;
@@ -15,9 +15,9 @@ export interface EmptyStream extends Array<Document.Parsed>, ReturnType<Composer
15
15
  * EmptyStream and contain additional stream information. In
16
16
  * TypeScript, you should use `'empty' in docs` as a type guard for it.
17
17
  */
18
- export declare function parseAllDocuments<T extends ParsedNode = ParsedNode>(source: string, options?: ParseOptions & DocumentOptions & SchemaOptions): Document.Parsed<T>[] | EmptyStream;
18
+ export declare function parseAllDocuments<Contents extends Node = ParsedNode, Strict extends boolean = true>(source: string, options?: ParseOptions & DocumentOptions & SchemaOptions): Array<Contents extends ParsedNode ? Document.Parsed<Contents, Strict> : Document<Contents, Strict>> | EmptyStream;
19
19
  /** Parse an input string into a single YAML.Document */
20
- export declare function parseDocument<T extends ParsedNode = ParsedNode>(source: string, options?: ParseOptions & DocumentOptions & SchemaOptions): Document.Parsed<T>;
20
+ export declare function parseDocument<Contents extends Node = ParsedNode, Strict extends boolean = true>(source: string, options?: ParseOptions & DocumentOptions & SchemaOptions): Contents extends ParsedNode ? Document.Parsed<Contents, Strict> : Document<Contents, Strict>;
21
21
  /**
22
22
  * Parse an input string into JavaScript.
23
23
  *
@@ -135,7 +135,7 @@ function stringifyFlowCollection({ comment, items }, ctx, { flowChars, itemInden
135
135
  }
136
136
  }
137
137
  if (comment) {
138
- str += stringifyComment.lineComment(str, commentString(comment), indent);
138
+ str += stringifyComment.lineComment(str, indent, commentString(comment));
139
139
  if (onComment)
140
140
  onComment();
141
141
  }
@@ -1,3 +1,4 @@
1
1
  import { Document } from '../doc/Document.js';
2
+ import { Node } from '../nodes/Node.js';
2
3
  import { ToStringOptions } from '../options.js';
3
- export declare function stringifyDocument(doc: Readonly<Document>, options: ToStringOptions): string;
4
+ export declare function stringifyDocument(doc: Readonly<Document<Node, boolean>>, options: ToStringOptions): string;
@@ -148,6 +148,15 @@ function quotedString(value, ctx) {
148
148
  }
149
149
  return qs(value, ctx);
150
150
  }
151
+ // The negative lookbehind avoids a polynomial search,
152
+ // but isn't supported yet on Safari: https://caniuse.com/js-regexp-lookbehind
153
+ let blockEndNewlines;
154
+ try {
155
+ blockEndNewlines = new RegExp('(^|(?<!\n))\n+(?!\n|$)', 'g');
156
+ }
157
+ catch {
158
+ blockEndNewlines = /\n+(?!\n|$)/g;
159
+ }
151
160
  function blockString({ comment, type, value }, ctx, onComment, onChompKeep) {
152
161
  const { blockQuote, commentString, lineWidth } = ctx.options;
153
162
  // 1. Block can't end in whitespace unless the last line is non-empty.
@@ -191,7 +200,7 @@ function blockString({ comment, type, value }, ctx, onComment, onChompKeep) {
191
200
  value = value.slice(0, -end.length);
192
201
  if (end[end.length - 1] === '\n')
193
202
  end = end.slice(0, -1);
194
- end = end.replace(/\n+(?!\n|$)/g, `$&${indent}`);
203
+ end = end.replace(blockEndNewlines, `$&${indent}`);
195
204
  }
196
205
  // determine indent indicator from whitespace at value start
197
206
  let startWithSpace = false;
@@ -232,7 +241,7 @@ function blockString({ comment, type, value }, ctx, onComment, onChompKeep) {
232
241
  }
233
242
  function plainString(item, ctx, onComment, onChompKeep) {
234
243
  const { type, value } = item;
235
- const { actualString, implicitKey, indent, inFlow } = ctx;
244
+ const { actualString, implicitKey, indent, indentStep, inFlow } = ctx;
236
245
  if ((implicitKey && /[\n[\]{},]/.test(value)) ||
237
246
  (inFlow && /[[\]{},]/.test(value))) {
238
247
  return quotedString(value, ctx);
@@ -256,9 +265,14 @@ function plainString(item, ctx, onComment, onChompKeep) {
256
265
  // Where allowed & type not set explicitly, prefer block style for multiline strings
257
266
  return blockString(item, ctx, onComment, onChompKeep);
258
267
  }
259
- if (indent === '' && containsDocumentMarker(value)) {
260
- ctx.forceBlockIndent = true;
261
- return blockString(item, ctx, onComment, onChompKeep);
268
+ if (containsDocumentMarker(value)) {
269
+ if (indent === '') {
270
+ ctx.forceBlockIndent = true;
271
+ return blockString(item, ctx, onComment, onChompKeep);
272
+ }
273
+ else if (implicitKey && indent === indentStep) {
274
+ return quotedString(value, ctx);
275
+ }
262
276
  }
263
277
  const str = value.replace(/\n+/g, `$&\n${indent}`);
264
278
  // Verify that output will be parsed as a string, as e.g. plain numbers and
package/dist/util.d.ts CHANGED
@@ -4,6 +4,6 @@ export { toJS, ToJSContext } from './nodes/toJS.js';
4
4
  export { map as mapTag } from './schema/common/map.js';
5
5
  export { seq as seqTag } from './schema/common/seq.js';
6
6
  export { string as stringTag } from './schema/common/string.js';
7
- export { foldFlowLines } from './stringify/foldFlowLines';
7
+ export { foldFlowLines, FoldOptions } from './stringify/foldFlowLines';
8
8
  export { stringifyNumber } from './stringify/stringifyNumber.js';
9
9
  export { stringifyString } from './stringify/stringifyString.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yaml",
3
- "version": "2.2.0",
3
+ "version": "2.3.0-0",
4
4
  "license": "ISC",
5
5
  "author": "Eemeli Aro <eemeli@gmail.com>",
6
6
  "repository": "github:eemeli/yaml",
@@ -14,7 +14,6 @@
14
14
  "files": [
15
15
  "browser/",
16
16
  "dist/",
17
- "util.d.ts",
18
17
  "util.js"
19
18
  ],
20
19
  "type": "commonjs",
@@ -35,6 +34,13 @@
35
34
  "default": "./browser/dist/util.js"
36
35
  }
37
36
  },
37
+ "typesVersions": {
38
+ "*": {
39
+ "*": [
40
+ "dist/*"
41
+ ]
42
+ }
43
+ },
38
44
  "scripts": {
39
45
  "build": "npm run build:node && npm run build:browser",
40
46
  "build:browser": "rollup -c config/rollup.browser-config.mjs",
@@ -49,7 +55,7 @@
49
55
  "test:browsers": "cd playground && npm test",
50
56
  "test:dist": "npm run build:node && jest --config config/jest.config.js",
51
57
  "test:dist:types": "tsc --allowJs --moduleResolution node --noEmit --target es5 dist/index.js",
52
- "test:types": "tsc --noEmit",
58
+ "test:types": "tsc --noEmit && tsc --noEmit -p tests/tsconfig.json",
53
59
  "docs:install": "cd docs-slate && bundle install",
54
60
  "docs:deploy": "cd docs-slate && ./deploy.sh",
55
61
  "docs": "cd docs-slate && bundle exec middleman server",
package/util.d.ts DELETED
@@ -1,3 +0,0 @@
1
- // Workaround for incomplete exports support in TypeScript
2
- // https://github.com/microsoft/TypeScript/issues/33079
3
- export * from './dist/util.js'