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 +4 -0
- package/browser/dist/compose/compose-doc.js +1 -0
- package/browser/dist/doc/Document.js +10 -6
- package/browser/dist/schema/tags.js +1 -1
- package/browser/dist/stringify/stringifyCollection.js +1 -1
- package/browser/dist/stringify/stringifyString.js +19 -5
- package/dist/compose/compose-doc.d.ts +2 -1
- package/dist/compose/compose-doc.js +1 -0
- package/dist/compose/composer.d.ts +5 -5
- package/dist/doc/Document.d.ts +9 -8
- package/dist/doc/Document.js +10 -6
- package/dist/doc/anchors.d.ts +2 -2
- package/dist/nodes/Node.d.ts +2 -2
- package/dist/nodes/toJS.d.ts +1 -1
- package/dist/public-api.d.ts +3 -3
- package/dist/stringify/stringifyCollection.js +1 -1
- package/dist/stringify/stringifyDocument.d.ts +2 -1
- package/dist/stringify/stringifyString.js +19 -5
- package/dist/util.d.ts +1 -1
- package/package.json +9 -3
- package/util.d.ts +0 -3
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
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
|
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)
|
|
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(
|
|
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 (
|
|
258
|
-
|
|
259
|
-
|
|
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<
|
|
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<
|
|
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<
|
|
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<
|
|
60
|
+
end(forceDoc?: boolean, endOffset?: number): Generator<Document.Parsed<Contents, Strict>, void, unknown>;
|
|
61
61
|
}
|
|
62
62
|
export {};
|
package/dist/doc/Document.d.ts
CHANGED
|
@@ -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
|
-
|
|
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<
|
|
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:
|
|
26
|
-
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<
|
|
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
|
*/
|
package/dist/doc/Document.js
CHANGED
|
@@ -51,11 +51,9 @@ class Document {
|
|
|
51
51
|
else
|
|
52
52
|
this.directives = new directives.Directives({ version });
|
|
53
53
|
this.setSchema(version, options);
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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)) {
|
package/dist/doc/anchors.d.ts
CHANGED
|
@@ -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
|
package/dist/nodes/Node.d.ts
CHANGED
|
@@ -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>;
|
package/dist/nodes/toJS.d.ts
CHANGED
package/dist/public-api.d.ts
CHANGED
|
@@ -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<
|
|
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<
|
|
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)
|
|
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
|
|
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(
|
|
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 (
|
|
260
|
-
|
|
261
|
-
|
|
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.
|
|
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