projen 0.53.10 → 0.53.13

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 (158) hide show
  1. package/.jsii +155 -104
  2. package/changelog.md +1 -6
  3. package/docs/api/API.md +18 -12
  4. package/lib/awscdk/auto-discover.js +4 -4
  5. package/lib/awscdk/awscdk-app-java.js +1 -1
  6. package/lib/awscdk/awscdk-app-py.js +1 -1
  7. package/lib/awscdk/awscdk-app-ts.js +1 -1
  8. package/lib/awscdk/awscdk-construct.js +2 -2
  9. package/lib/awscdk/awscdk-deps-java.js +1 -1
  10. package/lib/awscdk/awscdk-deps-js.js +1 -1
  11. package/lib/awscdk/awscdk-deps.js +1 -1
  12. package/lib/awscdk/cdk-config.js +1 -1
  13. package/lib/awscdk/cdk-tasks.js +1 -1
  14. package/lib/awscdk/integration-test.js +1 -1
  15. package/lib/awscdk/lambda-extension.js +1 -1
  16. package/lib/awscdk/lambda-function.js +2 -2
  17. package/lib/build/build-workflow.js +1 -1
  18. package/lib/cdk/auto-discover-base.js +2 -2
  19. package/lib/cdk/construct-lib.js +1 -1
  20. package/lib/cdk/integration-test-base.js +1 -1
  21. package/lib/cdk/jsii-docgen.js +1 -1
  22. package/lib/cdk/jsii-project.js +1 -1
  23. package/lib/cdk8s/auto-discover.js +2 -2
  24. package/lib/cdk8s/cdk8s-app-ts.js +1 -1
  25. package/lib/cdk8s/cdk8s-construct.js +1 -1
  26. package/lib/cdk8s/integration-test.js +1 -1
  27. package/lib/cdktf/cdktf-construct.js +1 -1
  28. package/lib/component.js +1 -1
  29. package/lib/dependencies.js +1 -1
  30. package/lib/dev-env.js +1 -1
  31. package/lib/docker-compose.js +2 -2
  32. package/lib/file.js +1 -1
  33. package/lib/gitattributes.js +1 -1
  34. package/lib/github/auto-approve.js +1 -1
  35. package/lib/github/auto-merge.js +1 -1
  36. package/lib/github/dependabot.js +1 -1
  37. package/lib/github/github-project.js +1 -1
  38. package/lib/github/github.js +1 -1
  39. package/lib/github/mergify.js +1 -1
  40. package/lib/github/pr-template.js +1 -1
  41. package/lib/github/pull-request-lint.js +1 -1
  42. package/lib/github/stale.js +1 -1
  43. package/lib/github/task-workflow.js +1 -1
  44. package/lib/github/workflows.js +1 -1
  45. package/lib/gitlab/configuration.js +1 -1
  46. package/lib/gitlab/gitlab-configuration.js +1 -1
  47. package/lib/gitlab/nested-configuration.js +1 -1
  48. package/lib/gitpod.js +1 -1
  49. package/lib/ignore-file.js +1 -1
  50. package/lib/ini.js +1 -1
  51. package/lib/java/java-project.js +1 -1
  52. package/lib/java/junit.js +1 -1
  53. package/lib/java/maven-compile.js +1 -1
  54. package/lib/java/maven-packaging.js +1 -1
  55. package/lib/java/maven-sample.js +1 -1
  56. package/lib/java/pom.js +1 -1
  57. package/lib/java/projenrc.js +1 -1
  58. package/lib/javascript/bundler.js +1 -1
  59. package/lib/javascript/eslint.js +1 -1
  60. package/lib/javascript/jest.js +1 -1
  61. package/lib/javascript/node-package.js +1 -1
  62. package/lib/javascript/node-project.js +1 -1
  63. package/lib/javascript/npm-config.js +1 -1
  64. package/lib/javascript/prettier.js +1 -1
  65. package/lib/javascript/projenrc.js +1 -1
  66. package/lib/javascript/typescript-config.js +1 -1
  67. package/lib/javascript/upgrade-dependencies.d.ts +5 -2
  68. package/lib/javascript/upgrade-dependencies.js +51 -41
  69. package/lib/json.js +1 -1
  70. package/lib/license.js +1 -1
  71. package/lib/logger.js +1 -1
  72. package/lib/makefile.js +1 -1
  73. package/lib/object-file.js +1 -1
  74. package/lib/project-build.js +1 -1
  75. package/lib/project.js +1 -1
  76. package/lib/projects.js +1 -1
  77. package/lib/projenrc-json.js +1 -1
  78. package/lib/python/pip.js +1 -1
  79. package/lib/python/poetry.js +2 -2
  80. package/lib/python/projenrc.js +1 -1
  81. package/lib/python/pytest-sample.js +1 -1
  82. package/lib/python/pytest.js +1 -1
  83. package/lib/python/python-project.js +1 -1
  84. package/lib/python/python-sample.js +1 -1
  85. package/lib/python/requirements-file.js +1 -1
  86. package/lib/python/setuppy.js +1 -1
  87. package/lib/python/setuptools.js +1 -1
  88. package/lib/python/venv.js +1 -1
  89. package/lib/readme.js +1 -1
  90. package/lib/release/publisher.js +1 -1
  91. package/lib/release/release-trigger.js +1 -1
  92. package/lib/release/release.d.ts +14 -0
  93. package/lib/release/release.js +26 -2
  94. package/lib/run-task.js +0 -1813
  95. package/lib/sample-file.js +2 -2
  96. package/lib/semver.js +1 -1
  97. package/lib/source-code.js +1 -1
  98. package/lib/task-runtime.js +1 -1
  99. package/lib/task.d.ts +4 -0
  100. package/lib/task.js +12 -4
  101. package/lib/tasks.js +1 -1
  102. package/lib/testing.js +1 -1
  103. package/lib/textfile.js +1 -1
  104. package/lib/toml.js +1 -1
  105. package/lib/typescript/projenrc.js +1 -1
  106. package/lib/typescript/typescript-typedoc.js +1 -1
  107. package/lib/typescript/typescript.js +3 -3
  108. package/lib/version.js +1 -1
  109. package/lib/vscode/devcontainer.js +1 -1
  110. package/lib/vscode/launch-config.js +1 -1
  111. package/lib/vscode/vscode.js +1 -1
  112. package/lib/web/next.js +3 -3
  113. package/lib/web/postcss.js +1 -1
  114. package/lib/web/react.js +4 -4
  115. package/lib/web/tailwind.js +1 -1
  116. package/lib/xmlfile.js +1 -1
  117. package/lib/yaml.js +1 -1
  118. package/node_modules/yaml/browser/dist/compose/compose-doc.js +1 -1
  119. package/node_modules/yaml/browser/dist/compose/compose-node.js +13 -4
  120. package/node_modules/yaml/browser/dist/compose/composer.js +5 -7
  121. package/node_modules/yaml/browser/dist/compose/resolve-block-scalar.js +9 -2
  122. package/node_modules/yaml/browser/dist/compose/resolve-props.js +2 -0
  123. package/node_modules/yaml/browser/dist/doc/Document.js +9 -2
  124. package/node_modules/yaml/browser/dist/doc/directives.js +7 -4
  125. package/node_modules/yaml/browser/dist/index.js +1 -2
  126. package/node_modules/yaml/browser/dist/parse/lexer.js +16 -7
  127. package/node_modules/yaml/browser/dist/parse/parser.js +64 -30
  128. package/node_modules/yaml/browser/dist/schema/common/null.js +3 -1
  129. package/node_modules/yaml/browser/dist/stringify/stringifyDocument.js +26 -8
  130. package/node_modules/yaml/browser/dist/stringify/stringifyPair.js +1 -1
  131. package/node_modules/yaml/browser/dist/visit.js +150 -62
  132. package/node_modules/yaml/dist/compose/compose-doc.js +1 -1
  133. package/node_modules/yaml/dist/compose/compose-node.js +13 -4
  134. package/node_modules/yaml/dist/compose/composer.d.ts +1 -1
  135. package/node_modules/yaml/dist/compose/composer.js +7 -9
  136. package/node_modules/yaml/dist/compose/resolve-block-scalar.js +9 -2
  137. package/node_modules/yaml/dist/compose/resolve-props.js +2 -0
  138. package/node_modules/yaml/dist/doc/Document.d.ts +1 -1
  139. package/node_modules/yaml/dist/doc/Document.js +16 -9
  140. package/node_modules/yaml/dist/doc/directives.d.ts +3 -1
  141. package/node_modules/yaml/dist/doc/directives.js +7 -4
  142. package/node_modules/yaml/dist/index.d.ts +2 -2
  143. package/node_modules/yaml/dist/index.js +1 -2
  144. package/node_modules/yaml/dist/options.d.ts +0 -8
  145. package/node_modules/yaml/dist/parse/lexer.js +16 -7
  146. package/node_modules/yaml/dist/parse/parser.js +64 -30
  147. package/node_modules/yaml/dist/schema/common/null.js +3 -1
  148. package/node_modules/yaml/dist/stringify/stringifyDocument.js +26 -8
  149. package/node_modules/yaml/dist/stringify/stringifyPair.js +1 -1
  150. package/node_modules/yaml/dist/test-events.js +8 -9
  151. package/node_modules/yaml/dist/visit.d.ts +49 -10
  152. package/node_modules/yaml/dist/visit.js +149 -60
  153. package/node_modules/yaml/package.json +3 -3
  154. package/package.json +3 -3
  155. package/releasetag.txt +1 -1
  156. package/version.txt +1 -1
  157. package/node_modules/yaml/browser/dist/options.js +0 -18
  158. package/node_modules/yaml/dist/options.js +0 -20
@@ -8,6 +8,7 @@ const CN = { composeNode, composeEmptyNode };
8
8
  function composeNode(ctx, token, props, onError) {
9
9
  const { spaceBefore, comment, anchor, tag } = props;
10
10
  let node;
11
+ let isSrcToken = true;
11
12
  switch (token.type) {
12
13
  case 'alias':
13
14
  node = composeAlias(ctx, token, onError);
@@ -29,9 +30,14 @@ function composeNode(ctx, token, props, onError) {
29
30
  if (anchor)
30
31
  node.anchor = anchor.source.substring(1);
31
32
  break;
32
- default:
33
- console.log(token);
34
- throw new Error(`Unsupporten token type: ${token.type}`);
33
+ default: {
34
+ const message = token.type === 'error'
35
+ ? token.message
36
+ : `Unsupported token (type: ${token.type})`;
37
+ onError(token, 'UNEXPECTED_TOKEN', message);
38
+ node = composeEmptyNode(ctx, token.offset, undefined, null, props, onError);
39
+ isSrcToken = false;
40
+ }
35
41
  }
36
42
  if (anchor && node.anchor === '')
37
43
  onError(anchor, 'BAD_ALIAS', 'Anchor cannot be an empty string');
@@ -43,7 +49,8 @@ function composeNode(ctx, token, props, onError) {
43
49
  else
44
50
  node.commentBefore = comment;
45
51
  }
46
- if (ctx.options.keepSourceTokens)
52
+ // @ts-expect-error Type checking misses meaning of isSrcToken
53
+ if (ctx.options.keepSourceTokens && isSrcToken)
47
54
  node.srcToken = token;
48
55
  return node;
49
56
  }
@@ -70,6 +77,8 @@ function composeAlias({ options }, { offset, source, end }, onError) {
70
77
  const alias = new Alias(source.substring(1));
71
78
  if (alias.source === '')
72
79
  onError(offset, 'BAD_ALIAS', 'Alias cannot be an empty string');
80
+ if (alias.source.endsWith(':'))
81
+ onError(offset + source.length - 1, 'BAD_ALIAS', 'Alias ending in : is ambiguous', true);
73
82
  const valueEnd = offset + source.length;
74
83
  const re = resolveEnd(end, valueEnd, options.strict, onError);
75
84
  alias.range = [offset, valueEnd, re.offset];
@@ -2,7 +2,6 @@ import { Directives } from '../doc/directives.js';
2
2
  import { Document } from '../doc/Document.js';
3
3
  import { YAMLWarning, YAMLParseError } from '../errors.js';
4
4
  import { isCollection, isPair } from '../nodes/Node.js';
5
- import { defaultOptions } from '../options.js';
6
5
  import { composeDoc } from './compose-doc.js';
7
6
  import { resolveEnd } from './resolve-end.js';
8
7
 
@@ -68,9 +67,7 @@ class Composer {
68
67
  else
69
68
  this.errors.push(new YAMLParseError(pos, code, message));
70
69
  };
71
- this.directives = new Directives({
72
- version: options.version || defaultOptions.version
73
- });
70
+ this.directives = new Directives({ version: options.version || '1.2' });
74
71
  this.options = options;
75
72
  }
76
73
  decorate(doc, afterDoc) {
@@ -81,7 +78,7 @@ class Composer {
81
78
  if (afterDoc) {
82
79
  doc.comment = doc.comment ? `${doc.comment}\n${comment}` : comment;
83
80
  }
84
- else if (afterEmptyLine || doc.directives.marker || !dc) {
81
+ else if (afterEmptyLine || doc.directives.docStart || !dc) {
85
82
  doc.commentBefore = comment;
86
83
  }
87
84
  else if (isCollection(dc) && !dc.flow && dc.items.length > 0) {
@@ -146,8 +143,8 @@ class Composer {
146
143
  break;
147
144
  case 'document': {
148
145
  const doc = composeDoc(this.options, this.directives, token, this.onError);
149
- if (this.atDirectives && !doc.directives.marker)
150
- this.onError(token, 'MISSING_CHAR', 'Missing directives-end indicator line');
146
+ if (this.atDirectives && !doc.directives.docStart)
147
+ this.onError(token, 'MISSING_CHAR', 'Missing directives-end/doc-start indicator line');
151
148
  this.decorate(doc, false);
152
149
  if (this.doc)
153
150
  yield this.doc;
@@ -179,6 +176,7 @@ class Composer {
179
176
  this.errors.push(new YAMLParseError(getErrorPos(token), 'UNEXPECTED_TOKEN', msg));
180
177
  break;
181
178
  }
179
+ this.doc.directives.docEnd = true;
182
180
  const end = resolveEnd(token.end, token.offset + token.source.length, this.doc.options.strict, this.onError);
183
181
  this.decorate(this.doc, true);
184
182
  if (end.comment) {
@@ -17,8 +17,10 @@ function resolveBlockScalar(scalar, strict, onError) {
17
17
  break;
18
18
  }
19
19
  // shortcut for empty contents
20
- if (!scalar.source || chompStart === 0) {
21
- const value = header.chomp === '+' ? '\n'.repeat(Math.max(0, lines.length - 1)) : '';
20
+ if (chompStart === 0) {
21
+ const value = header.chomp === '+' && lines.length > 0
22
+ ? '\n'.repeat(Math.max(1, lines.length - 1))
23
+ : '';
22
24
  let end = start + header.length;
23
25
  if (scalar.source)
24
26
  end += scalar.source.length;
@@ -46,6 +48,11 @@ function resolveBlockScalar(scalar, strict, onError) {
46
48
  }
47
49
  offset += indent.length + content.length + 1;
48
50
  }
51
+ // include trailing more-indented empty lines in content
52
+ for (let i = lines.length - 1; i >= chompStart; --i) {
53
+ if (lines[i][0].length > trimIndent)
54
+ chompStart = i + 1;
55
+ }
49
56
  let value = '';
50
57
  let sep = '';
51
58
  let prevMoreIndented = false;
@@ -59,6 +59,8 @@ function resolveProps(tokens, { flow, indicator, next, offset, onError, startOnN
59
59
  case 'anchor':
60
60
  if (anchor)
61
61
  onError(token, 'MULTIPLE_ANCHORS', 'A node can have at most one anchor');
62
+ if (token.source.endsWith(':'))
63
+ onError(token.offset + token.source.length - 1, 'BAD_ALIAS', 'Anchor ending in : is ambiguous', true);
62
64
  anchor = token;
63
65
  if (start === null)
64
66
  start = token.offset;
@@ -3,7 +3,6 @@ import { isEmptyPath, collectionFromPath } from '../nodes/Collection.js';
3
3
  import { NODE_TYPE, DOC, isNode, isCollection, isScalar } from '../nodes/Node.js';
4
4
  import { Pair } from '../nodes/Pair.js';
5
5
  import { toJS } from '../nodes/toJS.js';
6
- import { defaultOptions } from '../options.js';
7
6
  import { Schema } from '../schema/Schema.js';
8
7
  import { stringify } from '../stringify/stringify.js';
9
8
  import { stringifyDocument } from '../stringify/stringifyDocument.js';
@@ -31,7 +30,15 @@ class Document {
31
30
  options = replacer;
32
31
  replacer = undefined;
33
32
  }
34
- const opt = Object.assign({}, defaultOptions, options);
33
+ const opt = Object.assign({
34
+ intAsBigInt: false,
35
+ keepSourceTokens: false,
36
+ logLevel: 'warn',
37
+ prettyErrors: true,
38
+ strict: true,
39
+ uniqueKeys: true,
40
+ version: '1.2'
41
+ }, options);
35
42
  this.options = opt;
36
43
  let { version } = opt;
37
44
  if (options === null || options === void 0 ? void 0 : options.directives) {
@@ -16,13 +16,15 @@ class Directives {
16
16
  * The directives-end/doc-start marker `---`. If `null`, a marker may still be
17
17
  * included in the document's stringified representation.
18
18
  */
19
- this.marker = null;
19
+ this.docStart = null;
20
+ /** The doc-end marker `...`. */
21
+ this.docEnd = false;
20
22
  this.yaml = Object.assign({}, Directives.defaultYaml, yaml);
21
23
  this.tags = Object.assign({}, Directives.defaultTags, tags);
22
24
  }
23
25
  clone() {
24
26
  const copy = new Directives(this.yaml, this.tags);
25
- copy.marker = this.marker;
27
+ copy.docStart = this.docStart;
26
28
  return copy;
27
29
  }
28
30
  /**
@@ -71,7 +73,7 @@ class Directives {
71
73
  }
72
74
  case '%YAML': {
73
75
  this.yaml.explicit = true;
74
- if (parts.length < 1) {
76
+ if (parts.length !== 1) {
75
77
  onError(0, '%YAML directive should contain exactly one part');
76
78
  return false;
77
79
  }
@@ -81,7 +83,8 @@ class Directives {
81
83
  return true;
82
84
  }
83
85
  else {
84
- onError(6, `Unsupported YAML version ${version}`, true);
86
+ const isValid = /^\d+\.\d+$/.test(version);
87
+ onError(6, `Unsupported YAML version ${version}`, isValid);
85
88
  return false;
86
89
  }
87
90
  }
@@ -8,11 +8,10 @@ export { Pair } from './nodes/Pair.js';
8
8
  export { Scalar } from './nodes/Scalar.js';
9
9
  export { YAMLMap } from './nodes/YAMLMap.js';
10
10
  export { YAMLSeq } from './nodes/YAMLSeq.js';
11
- export { defaultOptions } from './options.js';
12
11
  import * as cst from './parse/cst.js';
13
12
  export { cst as CST };
14
13
  export { Lexer } from './parse/lexer.js';
15
14
  export { LineCounter } from './parse/line-counter.js';
16
15
  export { Parser } from './parse/parser.js';
17
16
  export { parse, parseAllDocuments, parseDocument, stringify } from './public-api.js';
18
- export { visit } from './visit.js';
17
+ export { visit, visitAsync } from './visit.js';
@@ -357,9 +357,14 @@ class Lexer {
357
357
  let indent = -1;
358
358
  do {
359
359
  nl = yield* this.pushNewline();
360
- sp = yield* this.pushSpaces(true);
361
- if (nl > 0)
360
+ if (nl > 0) {
361
+ sp = yield* this.pushSpaces(false);
362
362
  this.indentValue = indent = sp;
363
+ }
364
+ else {
365
+ sp = 0;
366
+ }
367
+ sp += yield* this.pushSpaces(true);
363
368
  } while (nl + sp > 0);
364
369
  const line = this.getLine();
365
370
  if (line === null)
@@ -533,9 +538,10 @@ class Lexer {
533
538
  let ch = this.buffer[i];
534
539
  if (ch === '\r')
535
540
  ch = this.buffer[--i];
541
+ const lastChar = i; // Drop the line if last char not more indented
536
542
  while (ch === ' ' || ch === '\t')
537
543
  ch = this.buffer[--i];
538
- if (ch === '\n' && i >= this.pos)
544
+ if (ch === '\n' && i >= this.pos && i + 1 + indent > lastChar)
539
545
  nl = i;
540
546
  else
541
547
  break;
@@ -618,11 +624,13 @@ class Lexer {
618
624
  return ((yield* this.pushUntil(isNotAnchorChar)) +
619
625
  (yield* this.pushSpaces(true)) +
620
626
  (yield* this.pushIndicators()));
621
- case ':':
622
- case '?': // this is an error outside flow collections
623
627
  case '-': // this is an error
624
- if (isEmpty(this.charAt(1))) {
625
- if (this.flowLevel === 0)
628
+ case '?': // this is an error outside flow collections
629
+ case ':': {
630
+ const inFlow = this.flowLevel > 0;
631
+ const ch1 = this.charAt(1);
632
+ if (isEmpty(ch1) || (inFlow && invalidFlowScalarChars.includes(ch1))) {
633
+ if (!inFlow)
626
634
  this.indentNext = this.indentValue + 1;
627
635
  else if (this.flowKey)
628
636
  this.flowKey = false;
@@ -630,6 +638,7 @@ class Lexer {
630
638
  (yield* this.pushSpaces(true)) +
631
639
  (yield* this.pushIndicators()));
632
640
  }
641
+ }
633
642
  }
634
643
  return 0;
635
644
  }
@@ -541,36 +541,70 @@ class Parser {
541
541
  this.onKeyLine = true;
542
542
  return;
543
543
  case 'map-value-ind':
544
- if (!it.sep)
545
- Object.assign(it, { key: null, sep: [this.sourceToken] });
546
- else if (it.value ||
547
- (atNextItem && !includesToken(it.start, 'explicit-key-ind')))
548
- map.items.push({ start: [], key: null, sep: [this.sourceToken] });
549
- else if (includesToken(it.sep, 'map-value-ind'))
550
- this.stack.push({
551
- type: 'block-map',
552
- offset: this.offset,
553
- indent: this.indent,
554
- items: [{ start: [], key: null, sep: [this.sourceToken] }]
555
- });
556
- else if (includesToken(it.start, 'explicit-key-ind') &&
557
- isFlowToken(it.key) &&
558
- !includesToken(it.sep, 'newline')) {
559
- const start = getFirstKeyStartProps(it.start);
560
- const key = it.key;
561
- const sep = it.sep;
562
- sep.push(this.sourceToken);
563
- // @ts-ignore type guard is wrong here
564
- delete it.key, delete it.sep;
565
- this.stack.push({
566
- type: 'block-map',
567
- offset: this.offset,
568
- indent: this.indent,
569
- items: [{ start, key, sep }]
570
- });
544
+ if (includesToken(it.start, 'explicit-key-ind')) {
545
+ if (!it.sep) {
546
+ if (includesToken(it.start, 'newline')) {
547
+ Object.assign(it, { key: null, sep: [this.sourceToken] });
548
+ }
549
+ else {
550
+ const start = getFirstKeyStartProps(it.start);
551
+ this.stack.push({
552
+ type: 'block-map',
553
+ offset: this.offset,
554
+ indent: this.indent,
555
+ items: [{ start, key: null, sep: [this.sourceToken] }]
556
+ });
557
+ }
558
+ }
559
+ else if (it.value) {
560
+ map.items.push({ start: [], key: null, sep: [this.sourceToken] });
561
+ }
562
+ else if (includesToken(it.sep, 'map-value-ind')) {
563
+ this.stack.push({
564
+ type: 'block-map',
565
+ offset: this.offset,
566
+ indent: this.indent,
567
+ items: [{ start: [], key: null, sep: [this.sourceToken] }]
568
+ });
569
+ }
570
+ else if (isFlowToken(it.key) &&
571
+ !includesToken(it.sep, 'newline')) {
572
+ const start = getFirstKeyStartProps(it.start);
573
+ const key = it.key;
574
+ const sep = it.sep;
575
+ sep.push(this.sourceToken);
576
+ // @ts-expect-error type guard is wrong here
577
+ delete it.key, delete it.sep;
578
+ this.stack.push({
579
+ type: 'block-map',
580
+ offset: this.offset,
581
+ indent: this.indent,
582
+ items: [{ start, key, sep }]
583
+ });
584
+ }
585
+ else {
586
+ it.sep.push(this.sourceToken);
587
+ }
588
+ }
589
+ else {
590
+ if (!it.sep) {
591
+ Object.assign(it, { key: null, sep: [this.sourceToken] });
592
+ }
593
+ else if (it.value || atNextItem) {
594
+ map.items.push({ start: [], key: null, sep: [this.sourceToken] });
595
+ }
596
+ else if (includesToken(it.sep, 'map-value-ind')) {
597
+ this.stack.push({
598
+ type: 'block-map',
599
+ offset: this.offset,
600
+ indent: this.indent,
601
+ items: [{ start: [], key: null, sep: [this.sourceToken] }]
602
+ });
603
+ }
604
+ else {
605
+ it.sep.push(this.sourceToken);
606
+ }
571
607
  }
572
- else
573
- it.sep.push(this.sourceToken);
574
608
  this.onKeyLine = true;
575
609
  return;
576
610
  case 'alias':
@@ -734,7 +768,7 @@ class Parser {
734
768
  else {
735
769
  const parent = this.peek(2);
736
770
  if (parent.type === 'block-map' &&
737
- (this.type === 'map-value-ind' ||
771
+ ((this.type === 'map-value-ind' && parent.indent === fc.indent) ||
738
772
  (this.type === 'newline' &&
739
773
  !parent.items[parent.items.length - 1].sep))) {
740
774
  yield* this.pop();
@@ -7,7 +7,9 @@ const nullTag = {
7
7
  tag: 'tag:yaml.org,2002:null',
8
8
  test: /^(?:~|[Nn]ull|NULL)?$/,
9
9
  resolve: () => new Scalar(null),
10
- stringify: ({ source }, ctx) => source && nullTag.test.test(source) ? source : ctx.options.nullStr
10
+ stringify: ({ source }, ctx) => typeof source === 'string' && nullTag.test.test(source)
11
+ ? source
12
+ : ctx.options.nullStr
11
13
  };
12
14
 
13
15
  export { nullTag };
@@ -3,6 +3,7 @@ import { createStringifyContext, stringify } from './stringify.js';
3
3
  import { indentComment, lineComment } from './stringifyComment.js';
4
4
 
5
5
  function stringifyDocument(doc, options) {
6
+ var _a;
6
7
  const lines = [];
7
8
  let hasDirectives = options.directives === true;
8
9
  if (options.directives !== false && doc.directives) {
@@ -11,7 +12,7 @@ function stringifyDocument(doc, options) {
11
12
  lines.push(dir);
12
13
  hasDirectives = true;
13
14
  }
14
- else if (doc.directives.marker)
15
+ else if (doc.directives.docStart)
15
16
  hasDirectives = true;
16
17
  }
17
18
  if (hasDirectives)
@@ -54,13 +55,30 @@ function stringifyDocument(doc, options) {
54
55
  else {
55
56
  lines.push(stringify(doc.contents, ctx));
56
57
  }
57
- let dc = doc.comment;
58
- if (dc && chompKeep)
59
- dc = dc.replace(/^\n+/, '');
60
- if (dc) {
61
- if ((!chompKeep || contentComment) && lines[lines.length - 1] !== '')
62
- lines.push('');
63
- lines.push(indentComment(commentString(dc), ''));
58
+ if ((_a = doc.directives) === null || _a === void 0 ? void 0 : _a.docEnd) {
59
+ if (doc.comment) {
60
+ const cs = commentString(doc.comment);
61
+ if (cs.includes('\n')) {
62
+ lines.push('...');
63
+ lines.push(indentComment(cs, ''));
64
+ }
65
+ else {
66
+ lines.push(`... ${cs}`);
67
+ }
68
+ }
69
+ else {
70
+ lines.push('...');
71
+ }
72
+ }
73
+ else {
74
+ let dc = doc.comment;
75
+ if (dc && chompKeep)
76
+ dc = dc.replace(/^\n+/, '');
77
+ if (dc) {
78
+ if ((!chompKeep || contentComment) && lines[lines.length - 1] !== '')
79
+ lines.push('');
80
+ lines.push(indentComment(commentString(dc), ''));
81
+ }
64
82
  }
65
83
  return lines.join('\n') + '\n';
66
84
  }
@@ -39,7 +39,7 @@ function stringifyPair({ key, value }, ctx, onComment, onChompKeep) {
39
39
  if (allNullValues || value == null) {
40
40
  if (keyCommentDone && onComment)
41
41
  onComment();
42
- return explicitKey ? `? ${str}` : str;
42
+ return str === '' ? '?' : explicitKey ? `? ${str}` : str;
43
43
  }
44
44
  }
45
45
  else if ((allNullValues && !simpleKeys) || (value == null && explicitKey)) {