yaml 2.1.3 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,13 +18,13 @@ function findPair(items, key) {
18
18
  return undefined;
19
19
  }
20
20
  class YAMLMap extends Collection {
21
+ static get tagName() {
22
+ return 'tag:yaml.org,2002:map';
23
+ }
21
24
  constructor(schema) {
22
25
  super(MAP, schema);
23
26
  this.items = [];
24
27
  }
25
- static get tagName() {
26
- return 'tag:yaml.org,2002:map';
27
- }
28
28
  /**
29
29
  * Adds a value to the collection.
30
30
  *
@@ -5,13 +5,13 @@ import { isScalarValue } from './Scalar.js';
5
5
  import { toJS } from './toJS.js';
6
6
 
7
7
  class YAMLSeq extends Collection {
8
+ static get tagName() {
9
+ return 'tag:yaml.org,2002:seq';
10
+ }
8
11
  constructor(schema) {
9
12
  super(SEQ, schema);
10
13
  this.items = [];
11
14
  }
12
- static get tagName() {
13
- return 'tag:yaml.org,2002:seq';
14
- }
15
15
  add(value) {
16
16
  this.items.push(value);
17
17
  }
@@ -13,6 +13,7 @@ function createStringifyContext(doc, options) {
13
13
  doubleQuotedAsJSON: false,
14
14
  doubleQuotedMinMultiLineLength: 40,
15
15
  falseStr: 'false',
16
+ flowCollectionPadding: true,
16
17
  indentSeq: true,
17
18
  lineWidth: 80,
18
19
  minContentWidth: 20,
@@ -36,6 +37,7 @@ function createStringifyContext(doc, options) {
36
37
  return {
37
38
  anchors: new Set(),
38
39
  doc,
40
+ flowCollectionPadding: opt.flowCollectionPadding ? ' ' : '',
39
41
  indent: '',
40
42
  indentStep: typeof opt.indent === 'number' ? ' '.repeat(opt.indent) : ' ',
41
43
  inFlow,
@@ -60,7 +60,7 @@ function stringifyBlockCollection({ comment, items }, ctx, { blockItemPrefix, fl
60
60
  return str;
61
61
  }
62
62
  function stringifyFlowCollection({ comment, items }, ctx, { flowChars, itemIndent, onComment }) {
63
- const { indent, indentStep, options: { commentString } } = ctx;
63
+ const { indent, indentStep, flowCollectionPadding: fcPadding, options: { commentString } } = ctx;
64
64
  itemIndent += indentStep;
65
65
  const itemCtx = Object.assign({}, ctx, {
66
66
  indent: itemIndent,
@@ -129,7 +129,7 @@ function stringifyFlowCollection({ comment, items }, ctx, { flowChars, itemInden
129
129
  str += `\n${indent}${end}`;
130
130
  }
131
131
  else {
132
- str = `${start} ${lines.join(' ')} ${end}`;
132
+ str = `${start}${fcPadding}${lines.join(' ')}${fcPadding}${end}`;
133
133
  }
134
134
  }
135
135
  if (comment) {
@@ -63,19 +63,18 @@ function stringifyPair({ key, value }, ctx, onComment, onChompKeep) {
63
63
  if (keyComment)
64
64
  str += lineComment(str, ctx.indent, commentString(keyComment));
65
65
  }
66
- let vcb = '';
67
- let valueComment = null;
66
+ let vsb, vcb, valueComment;
68
67
  if (isNode(value)) {
69
- if (value.spaceBefore)
70
- vcb = '\n';
71
- if (value.commentBefore) {
72
- const cs = commentString(value.commentBefore);
73
- vcb += `\n${indentComment(cs, ctx.indent)}`;
74
- }
68
+ vsb = !!value.spaceBefore;
69
+ vcb = value.commentBefore;
75
70
  valueComment = value.comment;
76
71
  }
77
- else if (value && typeof value === 'object') {
78
- value = doc.createNode(value);
72
+ else {
73
+ vsb = false;
74
+ vcb = null;
75
+ valueComment = null;
76
+ if (value && typeof value === 'object')
77
+ value = doc.createNode(value);
79
78
  }
80
79
  ctx.implicitKey = false;
81
80
  if (!explicitKey && !keyComment && isScalar(value))
@@ -90,24 +89,50 @@ function stringifyPair({ key, value }, ctx, onComment, onChompKeep) {
90
89
  !value.tag &&
91
90
  !value.anchor) {
92
91
  // If indentSeq === false, consider '- ' as part of indentation where possible
93
- ctx.indent = ctx.indent.substr(2);
92
+ ctx.indent = ctx.indent.substring(2);
94
93
  }
95
94
  let valueCommentDone = false;
96
95
  const valueStr = stringify(value, ctx, () => (valueCommentDone = true), () => (chompKeep = true));
97
96
  let ws = ' ';
98
- if (vcb || keyComment) {
99
- if (valueStr === '' && !ctx.inFlow)
100
- ws = vcb === '\n' ? '\n\n' : vcb;
101
- else
102
- ws = `${vcb}\n${ctx.indent}`;
97
+ if (keyComment || vsb || vcb) {
98
+ ws = vsb ? '\n' : '';
99
+ if (vcb) {
100
+ const cs = commentString(vcb);
101
+ ws += `\n${indentComment(cs, ctx.indent)}`;
102
+ }
103
+ if (valueStr === '' && !ctx.inFlow) {
104
+ if (ws === '\n')
105
+ ws = '\n\n';
106
+ }
107
+ else {
108
+ ws += `\n${ctx.indent}`;
109
+ }
103
110
  }
104
111
  else if (!explicitKey && isCollection(value)) {
105
- const flow = valueStr[0] === '[' || valueStr[0] === '{';
106
- if (!flow || valueStr.includes('\n'))
107
- ws = `\n${ctx.indent}`;
112
+ const vs0 = valueStr[0];
113
+ const nl0 = valueStr.indexOf('\n');
114
+ const hasNewline = nl0 !== -1;
115
+ const flow = ctx.inFlow ?? value.flow ?? value.items.length === 0;
116
+ if (hasNewline || !flow) {
117
+ let hasPropsLine = false;
118
+ if (hasNewline && (vs0 === '&' || vs0 === '!')) {
119
+ let sp0 = valueStr.indexOf(' ');
120
+ if (vs0 === '&' &&
121
+ sp0 !== -1 &&
122
+ sp0 < nl0 &&
123
+ valueStr[sp0 + 1] === '!') {
124
+ sp0 = valueStr.indexOf(' ', sp0 + 1);
125
+ }
126
+ if (sp0 === -1 || nl0 < sp0)
127
+ hasPropsLine = true;
128
+ }
129
+ if (!hasPropsLine)
130
+ ws = `\n${ctx.indent}`;
131
+ }
108
132
  }
109
- else if (valueStr === '' || valueStr[0] === '\n')
133
+ else if (valueStr === '' || valueStr[0] === '\n') {
110
134
  ws = '';
135
+ }
111
136
  str += ws + valueStr;
112
137
  if (ctx.inFlow) {
113
138
  if (valueCommentDone && onComment)
@@ -230,7 +230,7 @@ function blockString({ comment, type, value }, ctx, onComment, onChompKeep) {
230
230
  }
231
231
  function plainString(item, ctx, onComment, onChompKeep) {
232
232
  const { type, value } = item;
233
- const { actualString, implicitKey, indent, inFlow } = ctx;
233
+ const { actualString, implicitKey, indent, indentStep, inFlow } = ctx;
234
234
  if ((implicitKey && /[\n[\]{},]/.test(value)) ||
235
235
  (inFlow && /[[\]{},]/.test(value))) {
236
236
  return quotedString(value, ctx);
@@ -254,9 +254,14 @@ function plainString(item, ctx, onComment, onChompKeep) {
254
254
  // Where allowed & type not set explicitly, prefer block style for multiline strings
255
255
  return blockString(item, ctx, onComment, onChompKeep);
256
256
  }
257
- if (indent === '' && containsDocumentMarker(value)) {
258
- ctx.forceBlockIndent = true;
259
- return blockString(item, ctx, onComment, onChompKeep);
257
+ if (containsDocumentMarker(value)) {
258
+ if (indent === '') {
259
+ ctx.forceBlockIndent = true;
260
+ return blockString(item, ctx, onComment, onChompKeep);
261
+ }
262
+ else if (implicitKey && indent === indentStep) {
263
+ return quotedString(value, ctx);
264
+ }
260
265
  }
261
266
  const str = value.replace(/\n+/g, `$&\n${indent}`);
262
267
  // Verify that output will be parsed as a string, as e.g. plain numbers and
@@ -21,7 +21,7 @@ declare const CN: {
21
21
  composeNode: typeof composeNode;
22
22
  composeEmptyNode: typeof composeEmptyNode;
23
23
  };
24
- export declare type ComposeNode = typeof CN;
24
+ export type ComposeNode = typeof CN;
25
25
  export declare function composeNode(ctx: ComposeContext, token: Token, props: Props, onError: ComposeErrorHandler): ParsedNode;
26
26
  export declare function composeEmptyNode(ctx: ComposeContext, offset: number, before: Token[] | undefined, pos: number | null, { spaceBefore, comment, anchor, tag, end }: Props, onError: ComposeErrorHandler): import("../index.js").Scalar.Parsed;
27
27
  export {};
@@ -4,11 +4,11 @@ import { ErrorCode, YAMLParseError, YAMLWarning } from '../errors.js';
4
4
  import { 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
- declare type ErrorSource = number | [number, number] | Range | {
7
+ type ErrorSource = number | [number, number] | Range | {
8
8
  offset: number;
9
9
  source?: string;
10
10
  };
11
- export declare type ComposeErrorHandler = (source: ErrorSource, code: ErrorCode, message: string, warning?: boolean) => void;
11
+ export type ComposeErrorHandler = (source: ErrorSource, code: ErrorCode, message: string, warning?: boolean) => void;
12
12
  /**
13
13
  * Compose a stream of CST nodes into a stream of YAML Documents.
14
14
  *
@@ -8,7 +8,7 @@ import type { YAMLSeq } from '../nodes/YAMLSeq.js';
8
8
  import type { CreateNodeOptions, DocumentOptions, ParseOptions, SchemaOptions, ToJSOptions, ToStringOptions } from '../options.js';
9
9
  import { Schema } from '../schema/Schema.js';
10
10
  import { Directives } from './directives.js';
11
- export declare type Replacer = any[] | ((key: any, value: any) => unknown);
11
+ export type Replacer = any[] | ((key: any, value: any) => unknown);
12
12
  export declare namespace Document {
13
13
  interface Parsed<T extends ParsedNode = ParsedNode> extends Document<T> {
14
14
  directives: Directives;
@@ -1,4 +1,4 @@
1
- export declare type Reviver = (key: unknown, value: unknown) => unknown;
1
+ export type Reviver = (key: unknown, value: unknown) => unknown;
2
2
  /**
3
3
  * Applies the JSON.parse reviver algorithm as defined in the ECMA-262 spec,
4
4
  * in section 24.5.1.1 "Runtime Semantics: InternalizeJSONProperty" of the
package/dist/errors.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import type { LineCounter } from './parse/line-counter';
2
- export declare type ErrorCode = 'ALIAS_PROPS' | 'BAD_ALIAS' | 'BAD_DIRECTIVE' | 'BAD_DQ_ESCAPE' | 'BAD_INDENT' | 'BAD_PROP_ORDER' | 'BAD_SCALAR_START' | 'BLOCK_AS_IMPLICIT_KEY' | 'BLOCK_IN_FLOW' | 'DUPLICATE_KEY' | 'IMPOSSIBLE' | 'KEY_OVER_1024_CHARS' | 'MISSING_CHAR' | 'MULTILINE_IMPLICIT_KEY' | 'MULTIPLE_ANCHORS' | 'MULTIPLE_DOCS' | 'MULTIPLE_TAGS' | 'TAB_AS_INDENT' | 'TAG_RESOLVE_FAILED' | 'UNEXPECTED_TOKEN';
3
- export declare type LinePos = {
2
+ export type ErrorCode = 'ALIAS_PROPS' | 'BAD_ALIAS' | 'BAD_DIRECTIVE' | 'BAD_DQ_ESCAPE' | 'BAD_INDENT' | 'BAD_PROP_ORDER' | 'BAD_SCALAR_START' | 'BLOCK_AS_IMPLICIT_KEY' | 'BLOCK_IN_FLOW' | 'DUPLICATE_KEY' | 'IMPOSSIBLE' | 'KEY_OVER_1024_CHARS' | 'MISSING_CHAR' | 'MULTILINE_IMPLICIT_KEY' | 'MULTIPLE_ANCHORS' | 'MULTIPLE_DOCS' | 'MULTIPLE_TAGS' | 'TAB_AS_INDENT' | 'TAG_RESOLVE_FAILED' | 'UNEXPECTED_TOKEN';
3
+ export type LinePos = {
4
4
  line: number;
5
5
  col: number;
6
6
  };
package/dist/log.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export declare type LogLevelId = 'silent' | 'error' | 'warn' | 'debug';
1
+ export type LogLevelId = 'silent' | 'error' | 'warn' | 'debug';
2
2
  export declare function debug(logLevel: LogLevelId, ...messages: any[]): void;
3
3
  export declare function warn(logLevel: LogLevelId, warning: string | Error): void;
@@ -6,15 +6,15 @@ import type { Pair } from './Pair.js';
6
6
  import type { Scalar } from './Scalar.js';
7
7
  import type { YAMLMap } from './YAMLMap.js';
8
8
  import type { YAMLSeq } from './YAMLSeq.js';
9
- export declare type Node<T = unknown> = Alias | Scalar<T> | YAMLMap<unknown, T> | YAMLSeq<T>;
9
+ export type Node<T = unknown> = Alias | Scalar<T> | YAMLMap<unknown, T> | YAMLSeq<T>;
10
10
  /** Utility type mapper */
11
- export declare 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 ? Scalar<T> : 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;
15
15
  } ? YAMLMap<NodeType<keyof T>, NodeType<T[keyof T]>> : Node;
16
- export declare type ParsedNode = Alias.Parsed | Scalar.Parsed | YAMLMap.Parsed | YAMLSeq.Parsed;
17
- export declare type Range = [number, number, number];
16
+ export type ParsedNode = Alias.Parsed | Scalar.Parsed | YAMLMap.Parsed | YAMLSeq.Parsed;
17
+ export type Range = [number, number, number];
18
18
  export declare const ALIAS: unique symbol;
19
19
  export declare const DOC: unique symbol;
20
20
  export declare const MAP: unique symbol;
@@ -6,7 +6,7 @@ import { ParsedNode, Range } from './Node.js';
6
6
  import { Pair } from './Pair.js';
7
7
  import { Scalar } from './Scalar.js';
8
8
  import type { ToJSContext } from './toJS.js';
9
- export declare type MapLike = Map<unknown, unknown> | Set<unknown> | Record<string | number | symbol, unknown>;
9
+ export type MapLike = Map<unknown, unknown> | Set<unknown> | Record<string | number | symbol, unknown>;
10
10
  export declare function findPair<K = unknown, V = unknown>(items: Iterable<Pair<K, V>>, key: unknown): Pair<K, V> | undefined;
11
11
  export declare namespace YAMLMap {
12
12
  interface Parsed<K extends ParsedNode = ParsedNode, V extends ParsedNode | null = ParsedNode | null> extends YAMLMap<K, V> {
@@ -20,13 +20,13 @@ function findPair(items, key) {
20
20
  return undefined;
21
21
  }
22
22
  class YAMLMap extends Collection.Collection {
23
+ static get tagName() {
24
+ return 'tag:yaml.org,2002:map';
25
+ }
23
26
  constructor(schema) {
24
27
  super(Node.MAP, schema);
25
28
  this.items = [];
26
29
  }
27
- static get tagName() {
28
- return 'tag:yaml.org,2002:map';
29
- }
30
30
  /**
31
31
  * Adds a value to the collection.
32
32
  *
@@ -7,13 +7,13 @@ var Scalar = require('./Scalar.js');
7
7
  var toJS = require('./toJS.js');
8
8
 
9
9
  class YAMLSeq extends Collection.Collection {
10
+ static get tagName() {
11
+ return 'tag:yaml.org,2002:seq';
12
+ }
10
13
  constructor(schema) {
11
14
  super(Node.SEQ, schema);
12
15
  this.items = [];
13
16
  }
14
- static get tagName() {
15
- return 'tag:yaml.org,2002:seq';
16
- }
17
17
  add(value) {
18
18
  this.items.push(value);
19
19
  }
package/dist/options.d.ts CHANGED
@@ -8,7 +8,7 @@ import type { LineCounter } from './parse/line-counter.js';
8
8
  import type { Schema } from './schema/Schema.js';
9
9
  import type { Tags } from './schema/tags.js';
10
10
  import type { CollectionTag, ScalarTag } from './schema/types.js';
11
- export declare type ParseOptions = {
11
+ export type ParseOptions = {
12
12
  /**
13
13
  * Whether integers should be parsed into BigInt rather than number values.
14
14
  *
@@ -56,7 +56,7 @@ export declare type ParseOptions = {
56
56
  */
57
57
  uniqueKeys?: boolean | ((a: ParsedNode, b: ParsedNode) => boolean);
58
58
  };
59
- export declare type DocumentOptions = {
59
+ export type DocumentOptions = {
60
60
  /**
61
61
  * @internal
62
62
  * Used internally by Composer. If set and includes an explicit version,
@@ -76,7 +76,7 @@ export declare type DocumentOptions = {
76
76
  */
77
77
  version?: '1.1' | '1.2' | 'next';
78
78
  };
79
- export declare type SchemaOptions = {
79
+ export type SchemaOptions = {
80
80
  /**
81
81
  * When parsing, warn about compatibility issues with the given schema.
82
82
  * When stringifying, use scalar styles that are parsed correctly
@@ -133,7 +133,7 @@ export declare type SchemaOptions = {
133
133
  */
134
134
  toStringDefaults?: ToStringOptions;
135
135
  };
136
- export declare type CreateNodeOptions = {
136
+ export type CreateNodeOptions = {
137
137
  /**
138
138
  * During node construction, use anchors and aliases to keep strictly equal
139
139
  * non-null objects as equivalent in YAML.
@@ -163,7 +163,7 @@ export declare type CreateNodeOptions = {
163
163
  */
164
164
  tag?: string;
165
165
  };
166
- export declare type ToJSOptions = {
166
+ export type ToJSOptions = {
167
167
  /**
168
168
  * Use Map rather than Object to represent mappings.
169
169
  *
@@ -189,7 +189,7 @@ export declare type ToJSOptions = {
189
189
  */
190
190
  reviver?: Reviver;
191
191
  };
192
- export declare type ToStringOptions = {
192
+ export type ToStringOptions = {
193
193
  /**
194
194
  * Use block quote styles for scalar values where applicable.
195
195
  * Set to `false` to disable block quotes completely.
@@ -264,6 +264,13 @@ export declare type ToStringOptions = {
264
264
  * Default: `'false'`
265
265
  */
266
266
  falseStr?: string;
267
+ /**
268
+ * When true, a single space of padding will be added inside the delimiters
269
+ * of non-empty single-line flow collections.
270
+ *
271
+ * Default: `true`
272
+ */
273
+ flowCollectionPadding?: boolean;
267
274
  /**
268
275
  * The number of spaces to use when indenting code.
269
276
  *
@@ -1,6 +1,6 @@
1
1
  import type { CollectionItem, Document } from './cst.js';
2
- export declare type VisitPath = readonly ['key' | 'value', number][];
3
- export declare type Visitor = (item: CollectionItem, path: VisitPath) => number | symbol | Visitor | void;
2
+ export type VisitPath = readonly ['key' | 'value', number][];
3
+ export type Visitor = (item: CollectionItem, path: VisitPath) => number | symbol | Visitor | void;
4
4
  /**
5
5
  * Apply a visitor to a CST document or item.
6
6
  *
@@ -72,7 +72,7 @@ export interface BlockSequence {
72
72
  value?: Token;
73
73
  }>;
74
74
  }
75
- export declare type CollectionItem = {
75
+ export type CollectionItem = {
76
76
  start: SourceToken[];
77
77
  key?: Token | null;
78
78
  sep?: SourceToken[];
@@ -86,8 +86,8 @@ export interface FlowCollection {
86
86
  items: CollectionItem[];
87
87
  end: SourceToken[];
88
88
  }
89
- export declare type Token = SourceToken | ErrorToken | Directive | Document | DocumentEnd | FlowScalar | BlockScalar | BlockMap | BlockSequence | FlowCollection;
90
- export declare type TokenType = SourceToken['type'] | DocumentEnd['type'] | FlowScalar['type'];
89
+ export type Token = SourceToken | ErrorToken | Directive | Document | DocumentEnd | FlowScalar | BlockScalar | BlockMap | BlockSequence | FlowCollection;
90
+ export type TokenType = SourceToken['type'] | DocumentEnd['type'] | FlowScalar['type'];
91
91
  /** The byte order mark */
92
92
  export declare const BOM = "\uFEFF";
93
93
  /** Start of doc-mode */
@@ -1,5 +1,5 @@
1
- declare type JsonSchema = boolean | ArraySchema | ObjectSchema | NumberSchema | StringSchema;
2
- declare type JsonType = 'array' | 'object' | 'string' | 'number' | 'integer' | 'boolean' | 'null';
1
+ type JsonSchema = boolean | ArraySchema | ObjectSchema | NumberSchema | StringSchema;
2
+ type JsonType = 'array' | 'object' | 'string' | 'number' | 'integer' | 'boolean' | 'null';
3
3
  interface CommonSchema {
4
4
  type?: JsonType | JsonType[];
5
5
  const?: unknown;
@@ -25,8 +25,8 @@ declare const tagsByName: {
25
25
  test: RegExp;
26
26
  };
27
27
  };
28
- export declare type TagId = keyof typeof tagsByName;
29
- export declare type Tags = Array<ScalarTag | CollectionTag | TagId>;
28
+ export type TagId = keyof typeof tagsByName;
29
+ export type Tags = Array<ScalarTag | CollectionTag | TagId>;
30
30
  export declare const coreKnownTags: {
31
31
  'tag:yaml.org,2002:binary': ScalarTag;
32
32
  'tag:yaml.org,2002:omap': CollectionTag;
@@ -16,7 +16,7 @@ interface TagBase {
16
16
  * an explicit tag. For most cases, it's unlikely that you'll actually want to
17
17
  * use this, even if you first think you do.
18
18
  */
19
- default: boolean;
19
+ default?: boolean;
20
20
  /**
21
21
  * If a tag has multiple forms that should be parsed and/or stringified
22
22
  * differently, use `format` to identify them.
@@ -5,7 +5,7 @@ export declare const FOLD_QUOTED = "quoted";
5
5
  * `'block'` prevents more-indented lines from being folded;
6
6
  * `'quoted'` allows for `\` escapes, including escaped newlines
7
7
  */
8
- export declare type FoldMode = 'flow' | 'block' | 'quoted';
8
+ export type FoldMode = 'flow' | 'block' | 'quoted';
9
9
  export interface FoldOptions {
10
10
  /**
11
11
  * Accounts for leading contents on the first line, defaulting to
@@ -1,7 +1,7 @@
1
1
  import type { Document } from '../doc/Document.js';
2
2
  import type { Alias } from '../nodes/Alias.js';
3
3
  import type { ToStringOptions } from '../options.js';
4
- export declare type StringifyContext = {
4
+ export type StringifyContext = {
5
5
  actualString?: boolean;
6
6
  allNullValues?: boolean;
7
7
  anchors: Set<string>;
@@ -13,6 +13,7 @@ export declare type StringifyContext = {
13
13
  indentAtStart?: number;
14
14
  inFlow: boolean | null;
15
15
  inStringifyKey?: boolean;
16
+ flowCollectionPadding: string;
16
17
  options: Readonly<Required<Omit<ToStringOptions, 'collectionStyle' | 'indent'>>>;
17
18
  resolvedAliases?: Set<Alias>;
18
19
  };
@@ -15,6 +15,7 @@ function createStringifyContext(doc, options) {
15
15
  doubleQuotedAsJSON: false,
16
16
  doubleQuotedMinMultiLineLength: 40,
17
17
  falseStr: 'false',
18
+ flowCollectionPadding: true,
18
19
  indentSeq: true,
19
20
  lineWidth: 80,
20
21
  minContentWidth: 20,
@@ -38,6 +39,7 @@ function createStringifyContext(doc, options) {
38
39
  return {
39
40
  anchors: new Set(),
40
41
  doc,
42
+ flowCollectionPadding: opt.flowCollectionPadding ? ' ' : '',
41
43
  indent: '',
42
44
  indentStep: typeof opt.indent === 'number' ? ' '.repeat(opt.indent) : ' ',
43
45
  inFlow,
@@ -62,7 +62,7 @@ function stringifyBlockCollection({ comment, items }, ctx, { blockItemPrefix, fl
62
62
  return str;
63
63
  }
64
64
  function stringifyFlowCollection({ comment, items }, ctx, { flowChars, itemIndent, onComment }) {
65
- const { indent, indentStep, options: { commentString } } = ctx;
65
+ const { indent, indentStep, flowCollectionPadding: fcPadding, options: { commentString } } = ctx;
66
66
  itemIndent += indentStep;
67
67
  const itemCtx = Object.assign({}, ctx, {
68
68
  indent: itemIndent,
@@ -131,7 +131,7 @@ function stringifyFlowCollection({ comment, items }, ctx, { flowChars, itemInden
131
131
  str += `\n${indent}${end}`;
132
132
  }
133
133
  else {
134
- str = `${start} ${lines.join(' ')} ${end}`;
134
+ str = `${start}${fcPadding}${lines.join(' ')}${fcPadding}${end}`;
135
135
  }
136
136
  }
137
137
  if (comment) {
@@ -65,19 +65,18 @@ function stringifyPair({ key, value }, ctx, onComment, onChompKeep) {
65
65
  if (keyComment)
66
66
  str += stringifyComment.lineComment(str, ctx.indent, commentString(keyComment));
67
67
  }
68
- let vcb = '';
69
- let valueComment = null;
68
+ let vsb, vcb, valueComment;
70
69
  if (Node.isNode(value)) {
71
- if (value.spaceBefore)
72
- vcb = '\n';
73
- if (value.commentBefore) {
74
- const cs = commentString(value.commentBefore);
75
- vcb += `\n${stringifyComment.indentComment(cs, ctx.indent)}`;
76
- }
70
+ vsb = !!value.spaceBefore;
71
+ vcb = value.commentBefore;
77
72
  valueComment = value.comment;
78
73
  }
79
- else if (value && typeof value === 'object') {
80
- value = doc.createNode(value);
74
+ else {
75
+ vsb = false;
76
+ vcb = null;
77
+ valueComment = null;
78
+ if (value && typeof value === 'object')
79
+ value = doc.createNode(value);
81
80
  }
82
81
  ctx.implicitKey = false;
83
82
  if (!explicitKey && !keyComment && Node.isScalar(value))
@@ -92,24 +91,50 @@ function stringifyPair({ key, value }, ctx, onComment, onChompKeep) {
92
91
  !value.tag &&
93
92
  !value.anchor) {
94
93
  // If indentSeq === false, consider '- ' as part of indentation where possible
95
- ctx.indent = ctx.indent.substr(2);
94
+ ctx.indent = ctx.indent.substring(2);
96
95
  }
97
96
  let valueCommentDone = false;
98
97
  const valueStr = stringify.stringify(value, ctx, () => (valueCommentDone = true), () => (chompKeep = true));
99
98
  let ws = ' ';
100
- if (vcb || keyComment) {
101
- if (valueStr === '' && !ctx.inFlow)
102
- ws = vcb === '\n' ? '\n\n' : vcb;
103
- else
104
- ws = `${vcb}\n${ctx.indent}`;
99
+ if (keyComment || vsb || vcb) {
100
+ ws = vsb ? '\n' : '';
101
+ if (vcb) {
102
+ const cs = commentString(vcb);
103
+ ws += `\n${stringifyComment.indentComment(cs, ctx.indent)}`;
104
+ }
105
+ if (valueStr === '' && !ctx.inFlow) {
106
+ if (ws === '\n')
107
+ ws = '\n\n';
108
+ }
109
+ else {
110
+ ws += `\n${ctx.indent}`;
111
+ }
105
112
  }
106
113
  else if (!explicitKey && Node.isCollection(value)) {
107
- const flow = valueStr[0] === '[' || valueStr[0] === '{';
108
- if (!flow || valueStr.includes('\n'))
109
- ws = `\n${ctx.indent}`;
114
+ const vs0 = valueStr[0];
115
+ const nl0 = valueStr.indexOf('\n');
116
+ const hasNewline = nl0 !== -1;
117
+ const flow = ctx.inFlow ?? value.flow ?? value.items.length === 0;
118
+ if (hasNewline || !flow) {
119
+ let hasPropsLine = false;
120
+ if (hasNewline && (vs0 === '&' || vs0 === '!')) {
121
+ let sp0 = valueStr.indexOf(' ');
122
+ if (vs0 === '&' &&
123
+ sp0 !== -1 &&
124
+ sp0 < nl0 &&
125
+ valueStr[sp0 + 1] === '!') {
126
+ sp0 = valueStr.indexOf(' ', sp0 + 1);
127
+ }
128
+ if (sp0 === -1 || nl0 < sp0)
129
+ hasPropsLine = true;
130
+ }
131
+ if (!hasPropsLine)
132
+ ws = `\n${ctx.indent}`;
133
+ }
110
134
  }
111
- else if (valueStr === '' || valueStr[0] === '\n')
135
+ else if (valueStr === '' || valueStr[0] === '\n') {
112
136
  ws = '';
137
+ }
113
138
  str += ws + valueStr;
114
139
  if (ctx.inFlow) {
115
140
  if (valueCommentDone && onComment)
@@ -1,3 +1,9 @@
1
1
  import { Scalar } from '../nodes/Scalar.js';
2
2
  import type { StringifyContext } from './stringify.js';
3
- export declare function stringifyString(item: Scalar, ctx: StringifyContext, onComment?: () => void, onChompKeep?: () => void): string;
3
+ interface StringifyScalar {
4
+ value: string;
5
+ comment?: string | null;
6
+ type?: string;
7
+ }
8
+ export declare function stringifyString(item: Scalar | StringifyScalar, ctx: StringifyContext, onComment?: () => void, onChompKeep?: () => void): string;
9
+ export {};
@@ -232,7 +232,7 @@ function blockString({ comment, type, value }, ctx, onComment, onChompKeep) {
232
232
  }
233
233
  function plainString(item, ctx, onComment, onChompKeep) {
234
234
  const { type, value } = item;
235
- const { actualString, implicitKey, indent, inFlow } = ctx;
235
+ const { actualString, implicitKey, indent, indentStep, inFlow } = ctx;
236
236
  if ((implicitKey && /[\n[\]{},]/.test(value)) ||
237
237
  (inFlow && /[[\]{},]/.test(value))) {
238
238
  return quotedString(value, ctx);
@@ -256,9 +256,14 @@ function plainString(item, ctx, onComment, onChompKeep) {
256
256
  // Where allowed & type not set explicitly, prefer block style for multiline strings
257
257
  return blockString(item, ctx, onComment, onChompKeep);
258
258
  }
259
- if (indent === '' && containsDocumentMarker(value)) {
260
- ctx.forceBlockIndent = true;
261
- return blockString(item, ctx, onComment, onChompKeep);
259
+ if (containsDocumentMarker(value)) {
260
+ if (indent === '') {
261
+ ctx.forceBlockIndent = true;
262
+ return blockString(item, ctx, onComment, onChompKeep);
263
+ }
264
+ else if (implicitKey && indent === indentStep) {
265
+ return quotedString(value, ctx);
266
+ }
262
267
  }
263
268
  const str = value.replace(/\n+/g, `$&\n${indent}`);
264
269
  // Verify that output will be parsed as a string, as e.g. plain numbers and
package/dist/visit.d.ts CHANGED
@@ -5,8 +5,8 @@ import type { Pair } from './nodes/Pair.js';
5
5
  import type { Scalar } from './nodes/Scalar.js';
6
6
  import type { YAMLMap } from './nodes/YAMLMap.js';
7
7
  import type { YAMLSeq } from './nodes/YAMLSeq.js';
8
- export declare type visitorFn<T> = (key: number | 'key' | 'value' | null, node: T, path: readonly (Document | Node | Pair)[]) => void | symbol | number | Node | Pair;
9
- export declare type visitor = visitorFn<unknown> | {
8
+ export type visitorFn<T> = (key: number | 'key' | 'value' | null, node: T, path: readonly (Document | Node | Pair)[]) => void | symbol | number | Node | Pair;
9
+ export type visitor = visitorFn<unknown> | {
10
10
  Alias?: visitorFn<Alias>;
11
11
  Collection?: visitorFn<YAMLMap | YAMLSeq>;
12
12
  Map?: visitorFn<YAMLMap>;
@@ -16,8 +16,8 @@ export declare type visitor = visitorFn<unknown> | {
16
16
  Seq?: visitorFn<YAMLSeq>;
17
17
  Value?: visitorFn<Scalar | YAMLMap | YAMLSeq>;
18
18
  };
19
- export declare type asyncVisitorFn<T> = (key: number | 'key' | 'value' | null, node: T, path: readonly (Document | Node | Pair)[]) => void | symbol | number | Node | Pair | Promise<void | symbol | number | Node | Pair>;
20
- export declare type asyncVisitor = asyncVisitorFn<unknown> | {
19
+ export type asyncVisitorFn<T> = (key: number | 'key' | 'value' | null, node: T, path: readonly (Document | Node | Pair)[]) => void | symbol | number | Node | Pair | Promise<void | symbol | number | Node | Pair>;
20
+ export type asyncVisitor = asyncVisitorFn<unknown> | {
21
21
  Alias?: asyncVisitorFn<Alias>;
22
22
  Collection?: asyncVisitorFn<YAMLMap | YAMLSeq>;
23
23
  Map?: asyncVisitorFn<YAMLMap>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yaml",
3
- "version": "2.1.3",
3
+ "version": "2.2.1",
4
4
  "license": "ISC",
5
5
  "author": "Eemeli Aro <eemeli@gmail.com>",
6
6
  "repository": "github:eemeli/yaml",
@@ -37,8 +37,8 @@
37
37
  },
38
38
  "scripts": {
39
39
  "build": "npm run build:node && npm run build:browser",
40
- "build:browser": "rollup -c config/rollup.browser-config.js",
41
- "build:node": "rollup -c config/rollup.node-config.js",
40
+ "build:browser": "rollup -c config/rollup.browser-config.mjs",
41
+ "build:node": "rollup -c config/rollup.node-config.mjs",
42
42
  "clean": "git clean -fdxe node_modules",
43
43
  "lint": "eslint src/",
44
44
  "prettier": "prettier --write .",
@@ -69,11 +69,11 @@
69
69
  "@babel/plugin-proposal-nullish-coalescing-operator": "^7.12.1",
70
70
  "@babel/plugin-transform-typescript": "^7.12.17",
71
71
  "@babel/preset-env": "^7.12.11",
72
- "@rollup/plugin-babel": "^5.2.3",
73
- "@rollup/plugin-replace": "^4.0.0",
74
- "@rollup/plugin-typescript": "^8.1.1",
75
- "@types/jest": "^28.1.8",
76
- "@types/node": "^12.20.47",
72
+ "@rollup/plugin-babel": "^6.0.3",
73
+ "@rollup/plugin-replace": "^5.0.2",
74
+ "@rollup/plugin-typescript": "^10.0.1",
75
+ "@types/jest": "^29.2.4",
76
+ "@types/node": "^14.18.35",
77
77
  "@typescript-eslint/eslint-plugin": "^5.3.1",
78
78
  "@typescript-eslint/parser": "^5.3.1",
79
79
  "babel-jest": "^29.0.1",
@@ -84,7 +84,7 @@
84
84
  "jest": "^29.0.1",
85
85
  "jest-ts-webcompat-resolver": "^1.0.0",
86
86
  "prettier": "^2.2.1",
87
- "rollup": "^2.38.2",
87
+ "rollup": "^3.7.5",
88
88
  "tslib": "^2.1.0",
89
89
  "typescript": "^4.3.5"
90
90
  },