@rushstack/terminal 0.7.16 → 0.7.17

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.
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.39.0"
8
+ "packageVersion": "7.39.1"
9
9
  }
10
10
  ]
11
11
  }
@@ -1 +1 @@
1
- {"version":3,"file":"DiscardStdoutTransform.js","sourceRoot":"","sources":["../src/DiscardStdoutTransform.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAG3D,2DAAwF;AASxF,IAAK,KAIJ;AAJD,WAAK,KAAK;IACR,iCAAI,CAAA;IACJ,qDAAc,CAAA;IACd,qDAAc,CAAA;AAChB,CAAC,EAJI,KAAK,KAAL,KAAK,QAIT;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAa,sBAAuB,SAAQ,qCAAiB;IAG3D,YAAmB,OAAuC;QACxD,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC;IAC3B,CAAC;IAES,YAAY,CAAC,KAAqB;QAC1C,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACjC,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;SACnF;QAED,IAAI,KAAK,CAAC,IAAI,uCAA6B,EAAE;YAC3C,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,cAAc,EAAE;gBACxC,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;oBACjC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,cAAc,CAAC;iBACpC;aACF;SACF;aAAM,IAAI,KAAK,CAAC,IAAI,uCAA6B,EAAE;YAClD,IAAI,aAAqB,CAAC;YAC1B,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,cAAc,EAAE;gBACxC,aAAa,GAAG,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;aACnC;iBAAM;gBACL,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC;aAC5B;YAED,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,IAAI,oCAA0B,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;YAErF,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE;gBAC5B,IAAI,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE;oBACpD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC;iBAC1B;qBAAM;oBACL,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,cAAc,CAAC;iBACpC;aACF;SACF;aAAM;YACL,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;SACpC;IACH,CAAC;CACF;AAzCD,wDAyCC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { type ITerminalChunk, TerminalChunkKind } from './ITerminalChunk';\nimport { TerminalTransform, type ITerminalTransformOptions } from './TerminalTransform';\n\n/**\n * Constructor options for {@link DiscardStdoutTransform}\n *\n * @beta\n */\nexport interface IDiscardStdoutTransformOptions extends ITerminalTransformOptions {}\n\nenum State {\n Okay,\n StderrFragment,\n InsertLinefeed\n}\n\n/**\n * `DiscardStdoutTransform` discards `stdout` chunks while fixing up malformed `stderr` lines.\n *\n * @remarks\n * Suppose that a poorly behaved process produces output like this:\n *\n * ```ts\n * process.stdout.write('Starting operation...\\n');\n * process.stderr.write('An error occurred');\n * process.stdout.write('\\nFinishing up\\n');\n * process.stderr.write('The process completed with errors\\n');\n * ```\n *\n * When `stdout` and `stderr` are combined on the console, the mistake in the output would not be noticeable:\n * ```\n * Starting operation...\n * An error occurred\n * Finishing up\n * The process completed with errors\n * ```\n *\n * However, if we discard `stdout`, then `stderr` is missing a newline:\n * ```\n * An error occurredThe process completed with errors\n * ```\n *\n * Tooling scripts can introduce these sorts of problems via edge cases that are difficult to find and fix.\n * `DiscardStdoutTransform` can discard the `stdout` stream and fix up `stderr`:\n *\n * ```\n * An error occurred\n * The process completed with errors\n * ```\n *\n * @privateRemarks\n * This class is experimental and marked as `@beta`. The algorithm may need some fine-tuning, or there may\n * be better solutions to this problem.\n *\n * @beta\n */\nexport class DiscardStdoutTransform extends TerminalTransform {\n private _state: State;\n\n public constructor(options: IDiscardStdoutTransformOptions) {\n super(options);\n\n this._state = State.Okay;\n }\n\n protected onWriteChunk(chunk: ITerminalChunk): void {\n if (chunk.text.indexOf('\\r') >= 0) {\n throw new Error('DiscardStdoutTransform expects chunks with normalized newlines');\n }\n\n if (chunk.kind === TerminalChunkKind.Stdout) {\n if (this._state === State.StderrFragment) {\n if (chunk.text.indexOf('\\n') >= 0) {\n this._state = State.InsertLinefeed;\n }\n }\n } else if (chunk.kind === TerminalChunkKind.Stderr) {\n let correctedText: string;\n if (this._state === State.InsertLinefeed) {\n correctedText = '\\n' + chunk.text;\n } else {\n correctedText = chunk.text;\n }\n\n this.destination.writeChunk({ kind: TerminalChunkKind.Stderr, text: correctedText });\n\n if (correctedText.length > 0) {\n if (correctedText[correctedText.length - 1] === '\\n') {\n this._state = State.Okay;\n } else {\n this._state = State.StderrFragment;\n }\n }\n } else {\n this.destination.writeChunk(chunk);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"DiscardStdoutTransform.js","sourceRoot":"","sources":["../src/DiscardStdoutTransform.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAG3D,2DAAwF;AASxF,IAAK,KAIJ;AAJD,WAAK,KAAK;IACR,iCAAI,CAAA;IACJ,qDAAc,CAAA;IACd,qDAAc,CAAA;AAChB,CAAC,EAJI,KAAK,KAAL,KAAK,QAIT;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAa,sBAAuB,SAAQ,qCAAiB;IAG3D,YAAmB,OAAuC;QACxD,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC;IAC3B,CAAC;IAES,YAAY,CAAC,KAAqB;QAC1C,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;QACpF,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,uCAA6B,EAAE,CAAC;YAC5C,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,cAAc,EAAE,CAAC;gBACzC,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;oBAClC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,cAAc,CAAC;gBACrC,CAAC;YACH,CAAC;QACH,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,uCAA6B,EAAE,CAAC;YACnD,IAAI,aAAqB,CAAC;YAC1B,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,cAAc,EAAE,CAAC;gBACzC,aAAa,GAAG,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACN,aAAa,GAAG,KAAK,CAAC,IAAI,CAAC;YAC7B,CAAC;YAED,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,EAAE,IAAI,oCAA0B,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;YAErF,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7B,IAAI,aAAa,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;oBACrD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC;gBAC3B,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,cAAc,CAAC;gBACrC,CAAC;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;CACF;AAzCD,wDAyCC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { type ITerminalChunk, TerminalChunkKind } from './ITerminalChunk';\nimport { TerminalTransform, type ITerminalTransformOptions } from './TerminalTransform';\n\n/**\n * Constructor options for {@link DiscardStdoutTransform}\n *\n * @beta\n */\nexport interface IDiscardStdoutTransformOptions extends ITerminalTransformOptions {}\n\nenum State {\n Okay,\n StderrFragment,\n InsertLinefeed\n}\n\n/**\n * `DiscardStdoutTransform` discards `stdout` chunks while fixing up malformed `stderr` lines.\n *\n * @remarks\n * Suppose that a poorly behaved process produces output like this:\n *\n * ```ts\n * process.stdout.write('Starting operation...\\n');\n * process.stderr.write('An error occurred');\n * process.stdout.write('\\nFinishing up\\n');\n * process.stderr.write('The process completed with errors\\n');\n * ```\n *\n * When `stdout` and `stderr` are combined on the console, the mistake in the output would not be noticeable:\n * ```\n * Starting operation...\n * An error occurred\n * Finishing up\n * The process completed with errors\n * ```\n *\n * However, if we discard `stdout`, then `stderr` is missing a newline:\n * ```\n * An error occurredThe process completed with errors\n * ```\n *\n * Tooling scripts can introduce these sorts of problems via edge cases that are difficult to find and fix.\n * `DiscardStdoutTransform` can discard the `stdout` stream and fix up `stderr`:\n *\n * ```\n * An error occurred\n * The process completed with errors\n * ```\n *\n * @privateRemarks\n * This class is experimental and marked as `@beta`. The algorithm may need some fine-tuning, or there may\n * be better solutions to this problem.\n *\n * @beta\n */\nexport class DiscardStdoutTransform extends TerminalTransform {\n private _state: State;\n\n public constructor(options: IDiscardStdoutTransformOptions) {\n super(options);\n\n this._state = State.Okay;\n }\n\n protected onWriteChunk(chunk: ITerminalChunk): void {\n if (chunk.text.indexOf('\\r') >= 0) {\n throw new Error('DiscardStdoutTransform expects chunks with normalized newlines');\n }\n\n if (chunk.kind === TerminalChunkKind.Stdout) {\n if (this._state === State.StderrFragment) {\n if (chunk.text.indexOf('\\n') >= 0) {\n this._state = State.InsertLinefeed;\n }\n }\n } else if (chunk.kind === TerminalChunkKind.Stderr) {\n let correctedText: string;\n if (this._state === State.InsertLinefeed) {\n correctedText = '\\n' + chunk.text;\n } else {\n correctedText = chunk.text;\n }\n\n this.destination.writeChunk({ kind: TerminalChunkKind.Stderr, text: correctedText });\n\n if (correctedText.length > 0) {\n if (correctedText[correctedText.length - 1] === '\\n') {\n this._state = State.Okay;\n } else {\n this._state = State.StderrFragment;\n }\n }\n } else {\n this.destination.writeChunk(chunk);\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"NormalizeNewlinesTextRewriter.js","sourceRoot":"","sources":["../src/NormalizeNewlinesTextRewriter.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,oEAAsE;AACtE,iDAAsE;AA6BtE;;;;;GAKG;AACH,MAAa,6BAA8B,SAAQ,2BAAY;IAY7D,YAAmB,OAA8C;QAC/D,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QACvC,IAAI,CAAC,OAAO,GAAG,wBAAI,CAAC,UAAU,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACpD,IAAI,CAAC,kBAAkB,GAAG,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC;IACzD,CAAC;IAEM,UAAU;QACf,OAAO;YACL,iBAAiB,EAAE,EAAE;YACrB,cAAc,EAAE,KAAK;SACiB,CAAC;IAC3C,CAAC;IAEM,OAAO,CAAC,YAA+B,EAAE,IAAY;QAC1D,MAAM,KAAK,GAAwC,YAAmD,CAAC;QAEvG,IAAI,MAAM,GAAW,EAAE,CAAC;QAExB,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE;YACnB,IAAI,CAAC,GAAW,CAAC,CAAC;YAElB,GAAG;gBACD,MAAM,CAAC,GAAW,IAAI,CAAC,CAAC,CAAC,CAAC;gBAC1B,EAAE,CAAC,CAAC;gBAEJ,IAAI,CAAC,KAAK,KAAK,CAAC,iBAAiB,EAAE;oBACjC,KAAK,CAAC,iBAAiB,GAAG,EAAE,CAAC;iBAC9B;qBAAM,IAAI,CAAC,KAAK,IAAI,EAAE;oBACrB,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC;oBACvB,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC;oBAC/B,KAAK,CAAC,cAAc,GAAG,KAAK,CAAC;iBAC9B;qBAAM,IAAI,CAAC,KAAK,IAAI,EAAE;oBACrB,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC;oBACvB,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC;oBAC/B,KAAK,CAAC,cAAc,GAAG,KAAK,CAAC;iBAC9B;qBAAM;oBACL,MAAM,IAAI,CAAC,CAAC;oBACZ,KAAK,CAAC,iBAAiB,GAAG,EAAE,CAAC;oBAC7B,KAAK,CAAC,cAAc,GAAG,IAAI,CAAC;iBAC7B;aACF,QAAQ,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE;SAC3B;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAEM,KAAK,CAAC,YAA+B;QAC1C,MAAM,KAAK,GAAwC,YAAmD,CAAC;QACvG,KAAK,CAAC,iBAAiB,GAAG,EAAE,CAAC;QAE7B,IAAI,KAAK,CAAC,cAAc,EAAE;YACxB,KAAK,CAAC,cAAc,GAAG,KAAK,CAAC;YAC7B,OAAO,IAAI,CAAC,OAAO,CAAC;SACrB;aAAM;YACL,OAAO,EAAE,CAAC;SACX;IACH,CAAC;CACF;AAtED,sEAsEC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { Text, type NewlineKind } from '@rushstack/node-core-library';\nimport { TextRewriter, type TextRewriterState } from './TextRewriter';\n\ninterface INormalizeNewlinesTextRewriterState extends TextRewriterState {\n characterToIgnore: string;\n incompleteLine: boolean;\n}\n\n/**\n * Constructor options for {@link NormalizeNewlinesTextRewriter}\n *\n * @public\n */\nexport interface INormalizeNewlinesTextRewriterOptions {\n /**\n * Specifies how newlines should be represented in the output stream.\n */\n newlineKind: NewlineKind;\n\n /**\n * If `true`, then `NormalizeNewlinesTextRewriter.close()` will append a newline to\n * the output if it ends with an incomplete line.\n *\n * @remarks\n * If the output is an empty string, then a newline will NOT be appended,\n * because writing an empty string does not produce an incomplete line.\n */\n ensureNewlineAtEnd?: boolean;\n}\n\n/**\n * For use with {@link TextRewriterTransform}, this rewriter converts all newlines to\n * a standard format.\n *\n * @public\n */\nexport class NormalizeNewlinesTextRewriter extends TextRewriter {\n /** {@inheritDoc INormalizeNewlinesTextRewriterOptions.newlineKind} */\n public readonly newlineKind: NewlineKind;\n\n /**\n * The specific character sequence that will be used when appending newlines.\n */\n public readonly newline: string;\n\n /** {@inheritDoc INormalizeNewlinesTextRewriterOptions.ensureNewlineAtEnd} */\n public readonly ensureNewlineAtEnd: boolean;\n\n public constructor(options: INormalizeNewlinesTextRewriterOptions) {\n super();\n this.newlineKind = options.newlineKind;\n this.newline = Text.getNewline(options.newlineKind);\n this.ensureNewlineAtEnd = !!options.ensureNewlineAtEnd;\n }\n\n public initialize(): TextRewriterState {\n return {\n characterToIgnore: '',\n incompleteLine: false\n } as INormalizeNewlinesTextRewriterState;\n }\n\n public process(unknownState: TextRewriterState, text: string): string {\n const state: INormalizeNewlinesTextRewriterState = unknownState as INormalizeNewlinesTextRewriterState;\n\n let result: string = '';\n\n if (text.length > 0) {\n let i: number = 0;\n\n do {\n const c: string = text[i];\n ++i;\n\n if (c === state.characterToIgnore) {\n state.characterToIgnore = '';\n } else if (c === '\\r') {\n result += this.newline;\n state.characterToIgnore = '\\n';\n state.incompleteLine = false;\n } else if (c === '\\n') {\n result += this.newline;\n state.characterToIgnore = '\\r';\n state.incompleteLine = false;\n } else {\n result += c;\n state.characterToIgnore = '';\n state.incompleteLine = true;\n }\n } while (i < text.length);\n }\n\n return result;\n }\n\n public close(unknownState: TextRewriterState): string {\n const state: INormalizeNewlinesTextRewriterState = unknownState as INormalizeNewlinesTextRewriterState;\n state.characterToIgnore = '';\n\n if (state.incompleteLine) {\n state.incompleteLine = false;\n return this.newline;\n } else {\n return '';\n }\n }\n}\n"]}
1
+ {"version":3,"file":"NormalizeNewlinesTextRewriter.js","sourceRoot":"","sources":["../src/NormalizeNewlinesTextRewriter.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,oEAAsE;AACtE,iDAAsE;AA6BtE;;;;;GAKG;AACH,MAAa,6BAA8B,SAAQ,2BAAY;IAY7D,YAAmB,OAA8C;QAC/D,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QACvC,IAAI,CAAC,OAAO,GAAG,wBAAI,CAAC,UAAU,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACpD,IAAI,CAAC,kBAAkB,GAAG,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC;IACzD,CAAC;IAEM,UAAU;QACf,OAAO;YACL,iBAAiB,EAAE,EAAE;YACrB,cAAc,EAAE,KAAK;SACiB,CAAC;IAC3C,CAAC;IAEM,OAAO,CAAC,YAA+B,EAAE,IAAY;QAC1D,MAAM,KAAK,GAAwC,YAAmD,CAAC;QAEvG,IAAI,MAAM,GAAW,EAAE,CAAC;QAExB,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,IAAI,CAAC,GAAW,CAAC,CAAC;YAElB,GAAG,CAAC;gBACF,MAAM,CAAC,GAAW,IAAI,CAAC,CAAC,CAAC,CAAC;gBAC1B,EAAE,CAAC,CAAC;gBAEJ,IAAI,CAAC,KAAK,KAAK,CAAC,iBAAiB,EAAE,CAAC;oBAClC,KAAK,CAAC,iBAAiB,GAAG,EAAE,CAAC;gBAC/B,CAAC;qBAAM,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;oBACtB,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC;oBACvB,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC;oBAC/B,KAAK,CAAC,cAAc,GAAG,KAAK,CAAC;gBAC/B,CAAC;qBAAM,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;oBACtB,MAAM,IAAI,IAAI,CAAC,OAAO,CAAC;oBACvB,KAAK,CAAC,iBAAiB,GAAG,IAAI,CAAC;oBAC/B,KAAK,CAAC,cAAc,GAAG,KAAK,CAAC;gBAC/B,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,CAAC,CAAC;oBACZ,KAAK,CAAC,iBAAiB,GAAG,EAAE,CAAC;oBAC7B,KAAK,CAAC,cAAc,GAAG,IAAI,CAAC;gBAC9B,CAAC;YACH,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE;QAC5B,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAEM,KAAK,CAAC,YAA+B;QAC1C,MAAM,KAAK,GAAwC,YAAmD,CAAC;QACvG,KAAK,CAAC,iBAAiB,GAAG,EAAE,CAAC;QAE7B,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;YACzB,KAAK,CAAC,cAAc,GAAG,KAAK,CAAC;YAC7B,OAAO,IAAI,CAAC,OAAO,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;CACF;AAtED,sEAsEC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { Text, type NewlineKind } from '@rushstack/node-core-library';\nimport { TextRewriter, type TextRewriterState } from './TextRewriter';\n\ninterface INormalizeNewlinesTextRewriterState extends TextRewriterState {\n characterToIgnore: string;\n incompleteLine: boolean;\n}\n\n/**\n * Constructor options for {@link NormalizeNewlinesTextRewriter}\n *\n * @public\n */\nexport interface INormalizeNewlinesTextRewriterOptions {\n /**\n * Specifies how newlines should be represented in the output stream.\n */\n newlineKind: NewlineKind;\n\n /**\n * If `true`, then `NormalizeNewlinesTextRewriter.close()` will append a newline to\n * the output if it ends with an incomplete line.\n *\n * @remarks\n * If the output is an empty string, then a newline will NOT be appended,\n * because writing an empty string does not produce an incomplete line.\n */\n ensureNewlineAtEnd?: boolean;\n}\n\n/**\n * For use with {@link TextRewriterTransform}, this rewriter converts all newlines to\n * a standard format.\n *\n * @public\n */\nexport class NormalizeNewlinesTextRewriter extends TextRewriter {\n /** {@inheritDoc INormalizeNewlinesTextRewriterOptions.newlineKind} */\n public readonly newlineKind: NewlineKind;\n\n /**\n * The specific character sequence that will be used when appending newlines.\n */\n public readonly newline: string;\n\n /** {@inheritDoc INormalizeNewlinesTextRewriterOptions.ensureNewlineAtEnd} */\n public readonly ensureNewlineAtEnd: boolean;\n\n public constructor(options: INormalizeNewlinesTextRewriterOptions) {\n super();\n this.newlineKind = options.newlineKind;\n this.newline = Text.getNewline(options.newlineKind);\n this.ensureNewlineAtEnd = !!options.ensureNewlineAtEnd;\n }\n\n public initialize(): TextRewriterState {\n return {\n characterToIgnore: '',\n incompleteLine: false\n } as INormalizeNewlinesTextRewriterState;\n }\n\n public process(unknownState: TextRewriterState, text: string): string {\n const state: INormalizeNewlinesTextRewriterState = unknownState as INormalizeNewlinesTextRewriterState;\n\n let result: string = '';\n\n if (text.length > 0) {\n let i: number = 0;\n\n do {\n const c: string = text[i];\n ++i;\n\n if (c === state.characterToIgnore) {\n state.characterToIgnore = '';\n } else if (c === '\\r') {\n result += this.newline;\n state.characterToIgnore = '\\n';\n state.incompleteLine = false;\n } else if (c === '\\n') {\n result += this.newline;\n state.characterToIgnore = '\\r';\n state.incompleteLine = false;\n } else {\n result += c;\n state.characterToIgnore = '';\n state.incompleteLine = true;\n }\n } while (i < text.length);\n }\n\n return result;\n }\n\n public close(unknownState: TextRewriterState): string {\n const state: INormalizeNewlinesTextRewriterState = unknownState as INormalizeNewlinesTextRewriterState;\n state.characterToIgnore = '';\n\n if (state.incompleteLine) {\n state.incompleteLine = false;\n return this.newline;\n } else {\n return '';\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"PrintUtilities.js","sourceRoot":"","sources":["../src/PrintUtilities.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type { ITerminal } from '@rushstack/node-core-library';\n\n/**\n * A sensible fallback column width for consoles.\n *\n * @public\n */\nexport const DEFAULT_CONSOLE_WIDTH: number = 80;\n\n/**\n * A collection of utilities for printing messages to the console.\n *\n * @public\n */\nexport class PrintUtilities {\n /**\n * Returns the width of the console, measured in columns\n */\n public static getConsoleWidth(): number | undefined {\n return process.stdout?.columns;\n }\n\n /**\n * Applies word wrapping.\n *\n * @param text - The text to wrap\n * @param maxLineLength - The maximum length of a line, defaults to the console width\n * @param indent - The number of spaces to indent the wrapped lines, defaults to 0\n */\n public static wrapWords(text: string, maxLineLength?: number, indent?: number): string;\n /**\n * Applies word wrapping.\n *\n * @param text - The text to wrap\n * @param maxLineLength - The maximum length of a line, defaults to the console width\n * @param linePrefix - The string to prefix each line with, defaults to ''\n */\n public static wrapWords(text: string, maxLineLength?: number, linePrefix?: string): string;\n /**\n * Applies word wrapping.\n *\n * @param text - The text to wrap\n * @param maxLineLength - The maximum length of a line, defaults to the console width\n * @param indentOrLinePrefix - The number of spaces to indent the wrapped lines or the string to prefix\n * each line with, defaults to no prefix\n */\n public static wrapWords(text: string, maxLineLength?: number, indentOrLinePrefix?: number | string): string;\n public static wrapWords(\n text: string,\n maxLineLength?: number,\n indentOrLinePrefix?: number | string\n ): string {\n const wrappedLines: string[] = PrintUtilities.wrapWordsToLines(\n text,\n maxLineLength,\n indentOrLinePrefix as string | undefined // TS is confused by the overloads\n );\n return wrappedLines.join('\\n');\n }\n\n /**\n * Applies word wrapping and returns an array of lines.\n *\n * @param text - The text to wrap\n * @param maxLineLength - The maximum length of a line, defaults to the console width\n * @param indent - The number of spaces to indent the wrapped lines, defaults to 0\n */\n public static wrapWordsToLines(text: string, maxLineLength?: number, indent?: number): string[];\n /**\n * Applies word wrapping and returns an array of lines.\n *\n * @param text - The text to wrap\n * @param maxLineLength - The maximum length of a line, defaults to the console width\n * @param linePrefix - The string to prefix each line with, defaults to ''\n */\n public static wrapWordsToLines(text: string, maxLineLength?: number, linePrefix?: string): string[];\n /**\n * Applies word wrapping and returns an array of lines.\n *\n * @param text - The text to wrap\n * @param maxLineLength - The maximum length of a line, defaults to the console width\n * @param indentOrLinePrefix - The number of spaces to indent the wrapped lines or the string to prefix\n * each line with, defaults to no prefix\n */\n public static wrapWordsToLines(\n text: string,\n maxLineLength?: number,\n indentOrLinePrefix?: number | string\n ): string[];\n public static wrapWordsToLines(\n text: string,\n maxLineLength?: number,\n indentOrLinePrefix?: number | string\n ): string[] {\n let linePrefix: string;\n switch (typeof indentOrLinePrefix) {\n case 'number':\n linePrefix = ' '.repeat(indentOrLinePrefix);\n break;\n case 'string':\n linePrefix = indentOrLinePrefix;\n break;\n default:\n linePrefix = '';\n break;\n }\n\n const linePrefixLength: number = linePrefix.length;\n\n if (!maxLineLength) {\n maxLineLength = PrintUtilities.getConsoleWidth() || DEFAULT_CONSOLE_WIDTH;\n }\n\n // Apply word wrapping and the provided line prefix, while also respecting existing newlines\n // and prefix spaces that may exist in the text string already.\n const lines: string[] = text.split(/\\r?\\n/);\n\n const wrappedLines: string[] = [];\n for (const line of lines) {\n if (line.length + linePrefixLength <= maxLineLength) {\n wrappedLines.push(linePrefix + line);\n } else {\n const lineAdditionalPrefix: string = line.match(/^\\s*/)?.[0] || '';\n const whitespaceRegexp: RegExp = /\\s+/g;\n let currentWhitespaceMatch: RegExpExecArray | null = null;\n let previousWhitespaceMatch: RegExpExecArray | undefined;\n let currentLineStartIndex: number = lineAdditionalPrefix.length;\n let previousBreakRanOver: boolean = false;\n while ((currentWhitespaceMatch = whitespaceRegexp.exec(line)) !== null) {\n if (currentWhitespaceMatch.index + linePrefixLength - currentLineStartIndex > maxLineLength) {\n let whitespaceToSplitAt: RegExpExecArray | undefined;\n if (\n !previousWhitespaceMatch ||\n // Handle the case where there are two words longer than the maxLineLength in a row\n previousBreakRanOver\n ) {\n whitespaceToSplitAt = currentWhitespaceMatch;\n } else {\n whitespaceToSplitAt = previousWhitespaceMatch;\n }\n\n wrappedLines.push(\n linePrefix +\n lineAdditionalPrefix +\n line.substring(currentLineStartIndex, whitespaceToSplitAt.index)\n );\n previousBreakRanOver = whitespaceToSplitAt.index - currentLineStartIndex > maxLineLength;\n currentLineStartIndex = whitespaceToSplitAt.index + whitespaceToSplitAt[0].length;\n } else {\n previousBreakRanOver = false;\n }\n\n previousWhitespaceMatch = currentWhitespaceMatch;\n }\n\n if (currentLineStartIndex < line.length) {\n wrappedLines.push(linePrefix + lineAdditionalPrefix + line.substring(currentLineStartIndex));\n }\n }\n }\n\n return wrappedLines;\n }\n\n /**\n * Displays a message in the console wrapped in a box UI.\n *\n * @param message - The message to display.\n * @param terminal - The terminal to write the message to.\n * @param boxWidth - The width of the box, defaults to half of the console width.\n */\n public static printMessageInBox(message: string, terminal: ITerminal, boxWidth?: number): void {\n if (!boxWidth) {\n const consoleWidth: number = PrintUtilities.getConsoleWidth() || DEFAULT_CONSOLE_WIDTH;\n boxWidth = Math.floor(consoleWidth / 2);\n }\n\n const maxLineLength: number = boxWidth - 10;\n const wrappedMessageLines: string[] = PrintUtilities.wrapWordsToLines(message, maxLineLength);\n let longestLineLength: number = 0;\n const trimmedLines: string[] = [];\n for (const line of wrappedMessageLines) {\n const trimmedLine: string = line.trim();\n trimmedLines.push(trimmedLine);\n longestLineLength = Math.max(longestLineLength, trimmedLine.length);\n }\n\n if (longestLineLength > boxWidth - 2) {\n // If the longest line is longer than the box, print bars above and below the message\n // ═════════════\n // Message\n // ═════════════\n const headerAndFooter: string = ` ${'═'.repeat(boxWidth)}`;\n terminal.writeLine(headerAndFooter);\n for (const line of wrappedMessageLines) {\n terminal.writeLine(` ${line}`);\n }\n\n terminal.writeLine(headerAndFooter);\n } else {\n // ╔═══════════╗\n // ║ Message ║\n // ╚═══════════╝\n terminal.writeLine(` ╔${'═'.repeat(boxWidth - 2)}╗`);\n for (const trimmedLine of trimmedLines) {\n const padding: number = boxWidth - trimmedLine.length - 2;\n const leftPadding: number = Math.floor(padding / 2);\n const rightPadding: number = padding - leftPadding;\n terminal.writeLine(` ║${' '.repeat(leftPadding)}${trimmedLine}${' '.repeat(rightPadding)}║`);\n }\n terminal.writeLine(` ╚${'═'.repeat(boxWidth - 2)}╝`);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"PrintUtilities.js","sourceRoot":"","sources":["../src/PrintUtilities.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type { ITerminal } from '@rushstack/node-core-library';\n\n/**\n * A sensible fallback column width for consoles.\n *\n * @public\n */\nexport const DEFAULT_CONSOLE_WIDTH: number = 80;\n\n/**\n * A collection of utilities for printing messages to the console.\n *\n * @public\n */\nexport class PrintUtilities {\n /**\n * Returns the width of the console, measured in columns\n */\n public static getConsoleWidth(): number | undefined {\n return process.stdout?.columns;\n }\n\n /**\n * Applies word wrapping.\n *\n * @param text - The text to wrap\n * @param maxLineLength - The maximum length of a line, defaults to the console width\n * @param indent - The number of spaces to indent the wrapped lines, defaults to 0\n */\n public static wrapWords(text: string, maxLineLength?: number, indent?: number): string;\n /**\n * Applies word wrapping.\n *\n * @param text - The text to wrap\n * @param maxLineLength - The maximum length of a line, defaults to the console width\n * @param linePrefix - The string to prefix each line with, defaults to ''\n */\n public static wrapWords(text: string, maxLineLength?: number, linePrefix?: string): string;\n /**\n * Applies word wrapping.\n *\n * @param text - The text to wrap\n * @param maxLineLength - The maximum length of a line, defaults to the console width\n * @param indentOrLinePrefix - The number of spaces to indent the wrapped lines or the string to prefix\n * each line with, defaults to no prefix\n */\n public static wrapWords(text: string, maxLineLength?: number, indentOrLinePrefix?: number | string): string;\n public static wrapWords(\n text: string,\n maxLineLength?: number,\n indentOrLinePrefix?: number | string\n ): string {\n const wrappedLines: string[] = PrintUtilities.wrapWordsToLines(\n text,\n maxLineLength,\n indentOrLinePrefix as string | undefined // TS is confused by the overloads\n );\n return wrappedLines.join('\\n');\n }\n\n /**\n * Applies word wrapping and returns an array of lines.\n *\n * @param text - The text to wrap\n * @param maxLineLength - The maximum length of a line, defaults to the console width\n * @param indent - The number of spaces to indent the wrapped lines, defaults to 0\n */\n public static wrapWordsToLines(text: string, maxLineLength?: number, indent?: number): string[];\n /**\n * Applies word wrapping and returns an array of lines.\n *\n * @param text - The text to wrap\n * @param maxLineLength - The maximum length of a line, defaults to the console width\n * @param linePrefix - The string to prefix each line with, defaults to ''\n */\n public static wrapWordsToLines(text: string, maxLineLength?: number, linePrefix?: string): string[];\n /**\n * Applies word wrapping and returns an array of lines.\n *\n * @param text - The text to wrap\n * @param maxLineLength - The maximum length of a line, defaults to the console width\n * @param indentOrLinePrefix - The number of spaces to indent the wrapped lines or the string to prefix\n * each line with, defaults to no prefix\n */\n public static wrapWordsToLines(\n text: string,\n maxLineLength?: number,\n indentOrLinePrefix?: number | string\n ): string[];\n public static wrapWordsToLines(\n text: string,\n maxLineLength?: number,\n indentOrLinePrefix?: number | string\n ): string[] {\n let linePrefix: string;\n switch (typeof indentOrLinePrefix) {\n case 'number':\n linePrefix = ' '.repeat(indentOrLinePrefix);\n break;\n case 'string':\n linePrefix = indentOrLinePrefix;\n break;\n default:\n linePrefix = '';\n break;\n }\n\n const linePrefixLength: number = linePrefix.length;\n\n if (!maxLineLength) {\n maxLineLength = PrintUtilities.getConsoleWidth() || DEFAULT_CONSOLE_WIDTH;\n }\n\n // Apply word wrapping and the provided line prefix, while also respecting existing newlines\n // and prefix spaces that may exist in the text string already.\n const lines: string[] = text.split(/\\r?\\n/);\n\n const wrappedLines: string[] = [];\n for (const line of lines) {\n if (line.length + linePrefixLength <= maxLineLength) {\n wrappedLines.push(linePrefix + line);\n } else {\n const lineAdditionalPrefix: string = line.match(/^\\s*/)?.[0] || '';\n const whitespaceRegexp: RegExp = /\\s+/g;\n let currentWhitespaceMatch: RegExpExecArray | null = null;\n let previousWhitespaceMatch: RegExpExecArray | undefined;\n let currentLineStartIndex: number = lineAdditionalPrefix.length;\n let previousBreakRanOver: boolean = false;\n while ((currentWhitespaceMatch = whitespaceRegexp.exec(line)) !== null) {\n if (currentWhitespaceMatch.index + linePrefixLength - currentLineStartIndex > maxLineLength) {\n let whitespaceToSplitAt: RegExpExecArray | undefined;\n if (\n !previousWhitespaceMatch ||\n // Handle the case where there are two words longer than the maxLineLength in a row\n previousBreakRanOver\n ) {\n whitespaceToSplitAt = currentWhitespaceMatch;\n } else {\n whitespaceToSplitAt = previousWhitespaceMatch;\n }\n\n wrappedLines.push(\n linePrefix +\n lineAdditionalPrefix +\n line.substring(currentLineStartIndex, whitespaceToSplitAt.index)\n );\n previousBreakRanOver = whitespaceToSplitAt.index - currentLineStartIndex > maxLineLength;\n currentLineStartIndex = whitespaceToSplitAt.index + whitespaceToSplitAt[0].length;\n } else {\n previousBreakRanOver = false;\n }\n\n previousWhitespaceMatch = currentWhitespaceMatch;\n }\n\n if (currentLineStartIndex < line.length) {\n wrappedLines.push(linePrefix + lineAdditionalPrefix + line.substring(currentLineStartIndex));\n }\n }\n }\n\n return wrappedLines;\n }\n\n /**\n * Displays a message in the console wrapped in a box UI.\n *\n * @param message - The message to display.\n * @param terminal - The terminal to write the message to.\n * @param boxWidth - The width of the box, defaults to half of the console width.\n */\n public static printMessageInBox(message: string, terminal: ITerminal, boxWidth?: number): void {\n if (!boxWidth) {\n const consoleWidth: number = PrintUtilities.getConsoleWidth() || DEFAULT_CONSOLE_WIDTH;\n boxWidth = Math.floor(consoleWidth / 2);\n }\n\n const maxLineLength: number = boxWidth - 10;\n const wrappedMessageLines: string[] = PrintUtilities.wrapWordsToLines(message, maxLineLength);\n let longestLineLength: number = 0;\n const trimmedLines: string[] = [];\n for (const line of wrappedMessageLines) {\n const trimmedLine: string = line.trim();\n trimmedLines.push(trimmedLine);\n longestLineLength = Math.max(longestLineLength, trimmedLine.length);\n }\n\n if (longestLineLength > boxWidth - 2) {\n // If the longest line is longer than the box, print bars above and below the message\n // ═════════════\n // Message\n // ═════════════\n const headerAndFooter: string = ` ${'═'.repeat(boxWidth)}`;\n terminal.writeLine(headerAndFooter);\n for (const line of wrappedMessageLines) {\n terminal.writeLine(` ${line}`);\n }\n\n terminal.writeLine(headerAndFooter);\n } else {\n // ╔═══════════╗\n // ║ Message ║\n // ╚═══════════╝\n terminal.writeLine(` ╔${'═'.repeat(boxWidth - 2)}╗`);\n for (const trimmedLine of trimmedLines) {\n const padding: number = boxWidth - trimmedLine.length - 2;\n const leftPadding: number = Math.floor(padding / 2);\n const rightPadding: number = padding - leftPadding;\n terminal.writeLine(` ║${' '.repeat(leftPadding)}${trimmedLine}${' '.repeat(rightPadding)}║`);\n }\n terminal.writeLine(` ╚${'═'.repeat(boxWidth - 2)}╝`);\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"RemoveColorsTextRewriter.js","sourceRoot":"","sources":["../src/RemoveColorsTextRewriter.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { AnsiEscape } from '@rushstack/node-core-library';\nimport { TextRewriter, type TextRewriterState } from './TextRewriter';\n\nenum State {\n // Buffer is empty, and we're looking for the ESC character\n Start,\n // We're looking for the '[' character\n AwaitingBracket,\n // We're reading the codes after the '[' character\n ReadingCodes\n}\n\ninterface IRemoveColorsTextRewriterState extends TextRewriterState {\n buffer: string;\n parseState: State;\n}\n\n/**\n * For use with {@link TextRewriterTransform}, this rewriter removes ANSI escape codes\n * including colored text.\n *\n * @remarks\n * The implementation also removes other ANSI escape codes such as cursor positioning.\n * The specific set of affected codes may be adjusted in the future.\n *\n * @public\n */\nexport class RemoveColorsTextRewriter extends TextRewriter {\n public initialize(): TextRewriterState {\n return { buffer: '', parseState: State.Start } as IRemoveColorsTextRewriterState;\n }\n\n public process(unknownState: TextRewriterState, text: string): string {\n const state: IRemoveColorsTextRewriterState = unknownState as IRemoveColorsTextRewriterState;\n\n // We will be matching AnsiEscape._csiRegExp:\n //\n // /\\x1b\\[([\\x30-\\x3f]*[\\x20-\\x2f]*[\\x40-\\x7e])/gu\n //\n const ESC: string = '\\x1b';\n\n let result: string = '';\n let index: number = 0;\n\n while (index < text.length) {\n if (state.parseState === State.Start) {\n // The buffer is empty, which means we haven't found anything yet\n\n const csiIndex: number = text.indexOf(ESC, index);\n if (csiIndex < 0) {\n // We reached the end of \"text\" without finding another CSI prefix\n result += text.substring(index);\n break;\n }\n\n // Append everything up to the CSI prefix\n result += text.substring(index, csiIndex);\n\n // Save the partial match in the buffer\n state.buffer = ESC;\n index = csiIndex + 1;\n state.parseState = State.AwaitingBracket;\n } else {\n // The buffer has characters, which means we started matching a partial sequence\n\n // Read another character into the buffer\n const c: string = text[index];\n ++index;\n state.buffer += c;\n\n if (state.parseState === State.AwaitingBracket) {\n if (c === '[') {\n state.parseState = State.ReadingCodes;\n } else {\n // Failed to match, so append the buffer and start over\n result += state.buffer;\n state.buffer = '';\n state.parseState = State.Start;\n }\n } else {\n // state.state === State.ReadingCodes\n\n // Stop when we reach any character that is not [\\x30-\\x3f] or [\\x20-\\x2f]\n const code: number = c.charCodeAt(0);\n if (code < 0x20 || code > 0x3f) {\n result += AnsiEscape.removeCodes(state.buffer);\n state.buffer = '';\n state.parseState = State.Start;\n }\n }\n }\n }\n\n return result;\n }\n\n public close(unknownState: TextRewriterState): string {\n const state: IRemoveColorsTextRewriterState = unknownState as IRemoveColorsTextRewriterState;\n\n const result: string = state.buffer;\n state.buffer = '';\n return result;\n }\n}\n"]}
1
+ {"version":3,"file":"RemoveColorsTextRewriter.js","sourceRoot":"","sources":["../src/RemoveColorsTextRewriter.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { AnsiEscape } from '@rushstack/node-core-library';\nimport { TextRewriter, type TextRewriterState } from './TextRewriter';\n\nenum State {\n // Buffer is empty, and we're looking for the ESC character\n Start,\n // We're looking for the '[' character\n AwaitingBracket,\n // We're reading the codes after the '[' character\n ReadingCodes\n}\n\ninterface IRemoveColorsTextRewriterState extends TextRewriterState {\n buffer: string;\n parseState: State;\n}\n\n/**\n * For use with {@link TextRewriterTransform}, this rewriter removes ANSI escape codes\n * including colored text.\n *\n * @remarks\n * The implementation also removes other ANSI escape codes such as cursor positioning.\n * The specific set of affected codes may be adjusted in the future.\n *\n * @public\n */\nexport class RemoveColorsTextRewriter extends TextRewriter {\n public initialize(): TextRewriterState {\n return { buffer: '', parseState: State.Start } as IRemoveColorsTextRewriterState;\n }\n\n public process(unknownState: TextRewriterState, text: string): string {\n const state: IRemoveColorsTextRewriterState = unknownState as IRemoveColorsTextRewriterState;\n\n // We will be matching AnsiEscape._csiRegExp:\n //\n // /\\x1b\\[([\\x30-\\x3f]*[\\x20-\\x2f]*[\\x40-\\x7e])/gu\n //\n const ESC: string = '\\x1b';\n\n let result: string = '';\n let index: number = 0;\n\n while (index < text.length) {\n if (state.parseState === State.Start) {\n // The buffer is empty, which means we haven't found anything yet\n\n const csiIndex: number = text.indexOf(ESC, index);\n if (csiIndex < 0) {\n // We reached the end of \"text\" without finding another CSI prefix\n result += text.substring(index);\n break;\n }\n\n // Append everything up to the CSI prefix\n result += text.substring(index, csiIndex);\n\n // Save the partial match in the buffer\n state.buffer = ESC;\n index = csiIndex + 1;\n state.parseState = State.AwaitingBracket;\n } else {\n // The buffer has characters, which means we started matching a partial sequence\n\n // Read another character into the buffer\n const c: string = text[index];\n ++index;\n state.buffer += c;\n\n if (state.parseState === State.AwaitingBracket) {\n if (c === '[') {\n state.parseState = State.ReadingCodes;\n } else {\n // Failed to match, so append the buffer and start over\n result += state.buffer;\n state.buffer = '';\n state.parseState = State.Start;\n }\n } else {\n // state.state === State.ReadingCodes\n\n // Stop when we reach any character that is not [\\x30-\\x3f] or [\\x20-\\x2f]\n const code: number = c.charCodeAt(0);\n if (code < 0x20 || code > 0x3f) {\n result += AnsiEscape.removeCodes(state.buffer);\n state.buffer = '';\n state.parseState = State.Start;\n }\n }\n }\n }\n\n return result;\n }\n\n public close(unknownState: TextRewriterState): string {\n const state: IRemoveColorsTextRewriterState = unknownState as IRemoveColorsTextRewriterState;\n\n const result: string = state.buffer;\n state.buffer = '';\n return result;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"SplitterTransform.js","sourceRoot":"","sources":["../src/SplitterTransform.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,yDAAqF;AAerF;;;;;;;;;;;GAWG;AACH,MAAa,iBAAkB,SAAQ,mCAAgB;IAGrD,YAAmB,OAAkC;QACnD,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,YAAY,GAAG,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAChD,CAAC;IAES,YAAY,CAAC,KAAqB;QAC1C,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,YAAY,EAAE;YAC3C,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;SAC/B;IACH,CAAC;IAES,OAAO;QACf,MAAM,MAAM,GAAY,EAAE,CAAC;QAE3B,2FAA2F;QAC3F,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,YAAY,EAAE;YAC3C,IAAI,CAAC,WAAW,CAAC,gBAAgB,EAAE;gBACjC,IAAI;oBACF,WAAW,CAAC,KAAK,EAAE,CAAC;iBACrB;gBAAC,OAAO,KAAK,EAAE;oBACd,MAAM,CAAC,IAAI,CAAC,KAAc,CAAC,CAAC;iBAC7B;aACF;SACF;QAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE;YACrB,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC;SACjB;IACH,CAAC;CACF;AAhCD,8CAgCC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { TerminalWritable, type ITerminalWritableOptions } from './TerminalWritable';\nimport type { ITerminalChunk } from './ITerminalChunk';\n\n/**\n * Constructor options for {@link SplitterTransform}.\n *\n * @public\n */\nexport interface ISplitterTransformOptions extends ITerminalWritableOptions {\n /**\n * Each input chunk will be passed to each destination in the array.\n */\n destinations: TerminalWritable[];\n}\n\n/**\n * Use this instead of {@link TerminalTransform} if you need to output `ITerminalChunk`\n * data to more than one destination.\n *\n * @remarks\n *\n * Splitting streams complicates the pipeline topology and can make debugging more difficult.\n * For this reason, it is modeled as an explicit `SplitterTransform` node, rather than\n * as a built-in feature of `TerminalTransform`.\n *\n * @public\n */\nexport class SplitterTransform extends TerminalWritable {\n public readonly destinations: ReadonlyArray<TerminalWritable>;\n\n public constructor(options: ISplitterTransformOptions) {\n super();\n this.destinations = [...options.destinations];\n }\n\n protected onWriteChunk(chunk: ITerminalChunk): void {\n for (const destination of this.destinations) {\n destination.writeChunk(chunk);\n }\n }\n\n protected onClose(): void {\n const errors: Error[] = [];\n\n // If an exception is thrown, try to ensure that the other destinations get closed properly\n for (const destination of this.destinations) {\n if (!destination.preventAutoclose) {\n try {\n destination.close();\n } catch (error) {\n errors.push(error as Error);\n }\n }\n }\n\n if (errors.length > 0) {\n throw errors[0];\n }\n }\n}\n"]}
1
+ {"version":3,"file":"SplitterTransform.js","sourceRoot":"","sources":["../src/SplitterTransform.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,yDAAqF;AAerF;;;;;;;;;;;GAWG;AACH,MAAa,iBAAkB,SAAQ,mCAAgB;IAGrD,YAAmB,OAAkC;QACnD,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,YAAY,GAAG,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAChD,CAAC;IAES,YAAY,CAAC,KAAqB;QAC1C,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YAC5C,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAES,OAAO;QACf,MAAM,MAAM,GAAY,EAAE,CAAC;QAE3B,2FAA2F;QAC3F,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YAC5C,IAAI,CAAC,WAAW,CAAC,gBAAgB,EAAE,CAAC;gBAClC,IAAI,CAAC;oBACH,WAAW,CAAC,KAAK,EAAE,CAAC;gBACtB,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,CAAC,IAAI,CAAC,KAAc,CAAC,CAAC;gBAC9B,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;CACF;AAhCD,8CAgCC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { TerminalWritable, type ITerminalWritableOptions } from './TerminalWritable';\nimport type { ITerminalChunk } from './ITerminalChunk';\n\n/**\n * Constructor options for {@link SplitterTransform}.\n *\n * @public\n */\nexport interface ISplitterTransformOptions extends ITerminalWritableOptions {\n /**\n * Each input chunk will be passed to each destination in the array.\n */\n destinations: TerminalWritable[];\n}\n\n/**\n * Use this instead of {@link TerminalTransform} if you need to output `ITerminalChunk`\n * data to more than one destination.\n *\n * @remarks\n *\n * Splitting streams complicates the pipeline topology and can make debugging more difficult.\n * For this reason, it is modeled as an explicit `SplitterTransform` node, rather than\n * as a built-in feature of `TerminalTransform`.\n *\n * @public\n */\nexport class SplitterTransform extends TerminalWritable {\n public readonly destinations: ReadonlyArray<TerminalWritable>;\n\n public constructor(options: ISplitterTransformOptions) {\n super();\n this.destinations = [...options.destinations];\n }\n\n protected onWriteChunk(chunk: ITerminalChunk): void {\n for (const destination of this.destinations) {\n destination.writeChunk(chunk);\n }\n }\n\n protected onClose(): void {\n const errors: Error[] = [];\n\n // If an exception is thrown, try to ensure that the other destinations get closed properly\n for (const destination of this.destinations) {\n if (!destination.preventAutoclose) {\n try {\n destination.close();\n } catch (error) {\n errors.push(error as Error);\n }\n }\n }\n\n if (errors.length > 0) {\n throw errors[0];\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"StdioLineTransform.js","sourceRoot":"","sources":["../src/StdioLineTransform.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,oEAAiE;AAGjE,2DAAwF;AAaxF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,MAAa,mBAAoB,SAAQ,qCAAiB;IAMxD,YAAmB,OAAmC;QACpD,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC;QAEhC,IAAI,CAAC,OAAO,GAAG,wBAAI,CAAC,UAAU,CAAC,OAAO,CAAC,WAAW,IAAI,+BAAW,CAAC,EAAE,CAAC,CAAC;IACxE,CAAC;IAES,YAAY,CAAC,KAAqB;QAC1C,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACjC,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;SAChF;QAED,qFAAqF;QACrF,sBAAsB;QACtB,MAAM,IAAI,GAAW,KAAK,CAAC,IAAI,CAAC;QAChC,IAAI,UAAU,GAAW,CAAC,CAAC;QAE3B,OAAO,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE;YAC/B,IAAI,KAAK,CAAC,IAAI,uCAA6B,EAAE;gBAC3C,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;aAChC;YAED,MAAM,QAAQ,GAAW,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;YACxD,IAAI,QAAQ,GAAG,CAAC,EAAE;gBAChB,uCAAuC;gBACvC,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;gBACpD,MAAM;aACP;YAED,6BAA6B;YAC7B,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YAE9D,IAAI,CAAC,uBAAuB,EAAE,CAAC;YAE/B,cAAc;YACd,UAAU,GAAG,QAAQ,GAAG,CAAC,CAAC;SAC3B;IACH,CAAC;IAES,OAAO;QACf,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE;YACpC,IAAI,CAAC,uBAAuB,EAAE,CAAC;SAChC;QACD,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAC9B,CAAC;IAEO,uBAAuB;QAC7B,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,OAAO,CAAC;QAEtC,IAAI,IAAI,CAAC,kBAAkB,EAAE;YAC3B,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC;gBAC1B,IAAI,oCAA0B;gBAC9B,IAAI,EAAE,IAAI,CAAC,gBAAgB;aAC5B,CAAC,CAAC;SACJ;aAAM;YACL,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC;gBAC1B,IAAI,oCAA0B;gBAC9B,IAAI,EAAE,IAAI,CAAC,gBAAgB;aAC5B,CAAC,CAAC;SACJ;QAED,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC;IAClC,CAAC;CACF;AAxED,kDAwEC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { Text, NewlineKind } from '@rushstack/node-core-library';\n\nimport { type ITerminalChunk, TerminalChunkKind } from './ITerminalChunk';\nimport { TerminalTransform, type ITerminalTransformOptions } from './TerminalTransform';\n\n/**\n * Constructor options for {@link StderrLineTransform}\n * @beta\n */\nexport interface IStdioLineTransformOptions extends ITerminalTransformOptions {\n /**\n * Specifies the kind of newline for the output.\n */\n newlineKind?: NewlineKind;\n}\n\n/**\n * `StderrLineTransform` normalizes lines that mix characters from `stdout` and `stderr`,\n * so that each output line is routed entirely to `stdout` or `stderr`.\n *\n * @remarks\n * IMPORTANT: This transform assumes that its input has been normalized to use `\"\\n\"` newlines.\n *\n * IMPORTANT: This transform does not produce realtime output, because lines are buffered\n * until a newline character is encountered.\n *\n * Suppose that a poorly behaved process produces output like this:\n *\n * ```ts\n * process.stderr.write('An error occurred, cleaning up');\n * process.stdout.write('.'); // (delay)\n * process.stdout.write('.'); // (delay)\n * process.stdout.write('.');\n * process.stdout.write('\\n');\n * process.stderr.write('The process completed with errors\\n');\n * ```\n *\n * When `stdout` and `stderr` are combined on the console, the mistake in the output would not be noticeable:\n * ```\n * An error occurred, cleaning up...\n * The process completed with errors\n * ```\n *\n * However, if we discard `stdout`, then `stderr` is malformed:\n * ```\n * An error occurred, cleaning upThe process completed with errors\n * ```\n *\n * Tooling scripts can introduce these sorts of problems via edge cases that are difficult to find and fix.\n *\n * `StderrLineTransform` normalizes the output so that if a combined line contains any `stderr` characters,\n * then the entire line is routed to `stderr`. Later, if we discard `stdout`, then the output will\n * preserve the appropriate context:\n *\n * ```\n * An error occurred, cleaning up...\n * The process completed with errors\n * ```\n *\n * @privateRemarks\n * This class is experimental and marked as `@beta`. The algorithm may need some fine-tuning, or there may\n * be better solutions to this problem.\n *\n * @beta\n */\nexport class StderrLineTransform extends TerminalTransform {\n private _accumulatedLine: string;\n private _accumulatedStderr: boolean;\n\n public readonly newline: string;\n\n public constructor(options: IStdioLineTransformOptions) {\n super(options);\n\n this._accumulatedLine = '';\n this._accumulatedStderr = false;\n\n this.newline = Text.getNewline(options.newlineKind || NewlineKind.Lf);\n }\n\n protected onWriteChunk(chunk: ITerminalChunk): void {\n if (chunk.text.indexOf('\\r') >= 0) {\n throw new Error('StderrLineTransform expects chunks with normalized newlines');\n }\n\n // After _newlineNormalizerTransform was applied, we can now assume that all newlines\n // use the \"\\n\" string\n const text: string = chunk.text;\n let startIndex: number = 0;\n\n while (startIndex < text.length) {\n if (chunk.kind === TerminalChunkKind.Stderr) {\n this._accumulatedStderr = true;\n }\n\n const endIndex: number = text.indexOf('\\n', startIndex);\n if (endIndex < 0) {\n // we did not find \\n, so simply append\n this._accumulatedLine += text.substring(startIndex);\n break;\n }\n\n // append everything up to \\n\n this._accumulatedLine += text.substring(startIndex, endIndex);\n\n this._processAccumulatedLine();\n\n // skip the \\n\n startIndex = endIndex + 1;\n }\n }\n\n protected onClose(): void {\n if (this._accumulatedLine.length > 0) {\n this._processAccumulatedLine();\n }\n this.autocloseDestination();\n }\n\n private _processAccumulatedLine(): void {\n this._accumulatedLine += this.newline;\n\n if (this._accumulatedStderr) {\n this.destination.writeChunk({\n kind: TerminalChunkKind.Stderr,\n text: this._accumulatedLine\n });\n } else {\n this.destination.writeChunk({\n kind: TerminalChunkKind.Stdout,\n text: this._accumulatedLine\n });\n }\n\n this._accumulatedLine = '';\n this._accumulatedStderr = false;\n }\n}\n"]}
1
+ {"version":3,"file":"StdioLineTransform.js","sourceRoot":"","sources":["../src/StdioLineTransform.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,oEAAiE;AAGjE,2DAAwF;AAaxF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,MAAa,mBAAoB,SAAQ,qCAAiB;IAMxD,YAAmB,OAAmC;QACpD,KAAK,CAAC,OAAO,CAAC,CAAC;QAEf,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC;QAEhC,IAAI,CAAC,OAAO,GAAG,wBAAI,CAAC,UAAU,CAAC,OAAO,CAAC,WAAW,IAAI,+BAAW,CAAC,EAAE,CAAC,CAAC;IACxE,CAAC;IAES,YAAY,CAAC,KAAqB;QAC1C,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;QACjF,CAAC;QAED,qFAAqF;QACrF,sBAAsB;QACtB,MAAM,IAAI,GAAW,KAAK,CAAC,IAAI,CAAC;QAChC,IAAI,UAAU,GAAW,CAAC,CAAC;QAE3B,OAAO,UAAU,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;YAChC,IAAI,KAAK,CAAC,IAAI,uCAA6B,EAAE,CAAC;gBAC5C,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;YACjC,CAAC;YAED,MAAM,QAAQ,GAAW,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;YACxD,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;gBACjB,uCAAuC;gBACvC,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;gBACpD,MAAM;YACR,CAAC;YAED,6BAA6B;YAC7B,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YAE9D,IAAI,CAAC,uBAAuB,EAAE,CAAC;YAE/B,cAAc;YACd,UAAU,GAAG,QAAQ,GAAG,CAAC,CAAC;QAC5B,CAAC;IACH,CAAC;IAES,OAAO;QACf,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrC,IAAI,CAAC,uBAAuB,EAAE,CAAC;QACjC,CAAC;QACD,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAC9B,CAAC;IAEO,uBAAuB;QAC7B,IAAI,CAAC,gBAAgB,IAAI,IAAI,CAAC,OAAO,CAAC;QAEtC,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC5B,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC;gBAC1B,IAAI,oCAA0B;gBAC9B,IAAI,EAAE,IAAI,CAAC,gBAAgB;aAC5B,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC;gBAC1B,IAAI,oCAA0B;gBAC9B,IAAI,EAAE,IAAI,CAAC,gBAAgB;aAC5B,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,kBAAkB,GAAG,KAAK,CAAC;IAClC,CAAC;CACF;AAxED,kDAwEC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { Text, NewlineKind } from '@rushstack/node-core-library';\n\nimport { type ITerminalChunk, TerminalChunkKind } from './ITerminalChunk';\nimport { TerminalTransform, type ITerminalTransformOptions } from './TerminalTransform';\n\n/**\n * Constructor options for {@link StderrLineTransform}\n * @beta\n */\nexport interface IStdioLineTransformOptions extends ITerminalTransformOptions {\n /**\n * Specifies the kind of newline for the output.\n */\n newlineKind?: NewlineKind;\n}\n\n/**\n * `StderrLineTransform` normalizes lines that mix characters from `stdout` and `stderr`,\n * so that each output line is routed entirely to `stdout` or `stderr`.\n *\n * @remarks\n * IMPORTANT: This transform assumes that its input has been normalized to use `\"\\n\"` newlines.\n *\n * IMPORTANT: This transform does not produce realtime output, because lines are buffered\n * until a newline character is encountered.\n *\n * Suppose that a poorly behaved process produces output like this:\n *\n * ```ts\n * process.stderr.write('An error occurred, cleaning up');\n * process.stdout.write('.'); // (delay)\n * process.stdout.write('.'); // (delay)\n * process.stdout.write('.');\n * process.stdout.write('\\n');\n * process.stderr.write('The process completed with errors\\n');\n * ```\n *\n * When `stdout` and `stderr` are combined on the console, the mistake in the output would not be noticeable:\n * ```\n * An error occurred, cleaning up...\n * The process completed with errors\n * ```\n *\n * However, if we discard `stdout`, then `stderr` is malformed:\n * ```\n * An error occurred, cleaning upThe process completed with errors\n * ```\n *\n * Tooling scripts can introduce these sorts of problems via edge cases that are difficult to find and fix.\n *\n * `StderrLineTransform` normalizes the output so that if a combined line contains any `stderr` characters,\n * then the entire line is routed to `stderr`. Later, if we discard `stdout`, then the output will\n * preserve the appropriate context:\n *\n * ```\n * An error occurred, cleaning up...\n * The process completed with errors\n * ```\n *\n * @privateRemarks\n * This class is experimental and marked as `@beta`. The algorithm may need some fine-tuning, or there may\n * be better solutions to this problem.\n *\n * @beta\n */\nexport class StderrLineTransform extends TerminalTransform {\n private _accumulatedLine: string;\n private _accumulatedStderr: boolean;\n\n public readonly newline: string;\n\n public constructor(options: IStdioLineTransformOptions) {\n super(options);\n\n this._accumulatedLine = '';\n this._accumulatedStderr = false;\n\n this.newline = Text.getNewline(options.newlineKind || NewlineKind.Lf);\n }\n\n protected onWriteChunk(chunk: ITerminalChunk): void {\n if (chunk.text.indexOf('\\r') >= 0) {\n throw new Error('StderrLineTransform expects chunks with normalized newlines');\n }\n\n // After _newlineNormalizerTransform was applied, we can now assume that all newlines\n // use the \"\\n\" string\n const text: string = chunk.text;\n let startIndex: number = 0;\n\n while (startIndex < text.length) {\n if (chunk.kind === TerminalChunkKind.Stderr) {\n this._accumulatedStderr = true;\n }\n\n const endIndex: number = text.indexOf('\\n', startIndex);\n if (endIndex < 0) {\n // we did not find \\n, so simply append\n this._accumulatedLine += text.substring(startIndex);\n break;\n }\n\n // append everything up to \\n\n this._accumulatedLine += text.substring(startIndex, endIndex);\n\n this._processAccumulatedLine();\n\n // skip the \\n\n startIndex = endIndex + 1;\n }\n }\n\n protected onClose(): void {\n if (this._accumulatedLine.length > 0) {\n this._processAccumulatedLine();\n }\n this.autocloseDestination();\n }\n\n private _processAccumulatedLine(): void {\n this._accumulatedLine += this.newline;\n\n if (this._accumulatedStderr) {\n this.destination.writeChunk({\n kind: TerminalChunkKind.Stderr,\n text: this._accumulatedLine\n });\n } else {\n this.destination.writeChunk({\n kind: TerminalChunkKind.Stdout,\n text: this._accumulatedLine\n });\n }\n\n this._accumulatedLine = '';\n this._accumulatedStderr = false;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"StdioSummarizer.js","sourceRoot":"","sources":["../src/StdioSummarizer.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { type ITerminalChunk, TerminalChunkKind } from './ITerminalChunk';\nimport { TerminalWritable } from './TerminalWritable';\n\n/**\n * Constructor options for {@link StdioSummarizer}.\n * @beta\n */\nexport interface IStdioSummarizerOptions {\n /**\n * Specifies the maximum number of leading lines to include in the summary.\n * @defaultValue `10`\n */\n leadingLines?: number;\n\n /**\n * Specifies the maximum number of trailing lines to include in the summary.\n * @defaultValue `10`\n */\n trailingLines?: number;\n}\n\n/**\n * Summarizes the results of a failed build task by returning a subset of `stderr` output not to exceed\n * a specified maximum number of lines.\n *\n * @remarks\n * IMPORTANT: This transform assumes that its input was prepared by {@link StderrLineTransform}, so that each\n * {@link ITerminalChunk.text} item is a single line terminated by a `\"\\n\"` character.\n *\n * The {@link IStdioSummarizerOptions.leadingLines} and {@link IStdioSummarizerOptions.trailingLines}\n * counts specify the maximum number of lines to be returned. Any additional lines will be omitted.\n * For example, if `leadingLines` and `trailingLines` were set to `3`, then the summary of 16 `stderr` lines might\n * look like this:\n *\n * ```\n * Line 1\n * Line 2\n * Line 3\n * ...10 lines omitted...\n * Line 14\n * Line 15\n * Line 16\n * ```\n *\n * If the `stderr` output is completely empty, then the `stdout` output will be summarized instead.\n *\n * @beta\n */\nexport class StdioSummarizer extends TerminalWritable {\n // Capture up to this many leading lines\n private _leadingLines: number;\n\n // Capture up to this many trailing lines\n private _trailingLines: number;\n\n private readonly _abridgedLeading: string[];\n private readonly _abridgedTrailing: string[];\n private _abridgedOmittedLines: number = 0;\n private _abridgedStderr: boolean;\n\n public constructor(options?: IStdioSummarizerOptions) {\n super();\n\n if (!options) {\n options = {};\n }\n\n this._leadingLines = options.leadingLines !== undefined ? options.leadingLines : 10;\n this._trailingLines = options.trailingLines !== undefined ? options.trailingLines : 10;\n\n this._abridgedLeading = [];\n this._abridgedTrailing = [];\n this._abridgedStderr = false;\n }\n\n /**\n * Returns the summary report.\n *\n * @remarks\n * The `close()` method must be called before `getReport()` can be used.\n */\n public getReport(): string {\n if (this.isOpen) {\n throw new Error('The summary cannot be prepared until after close() is called.');\n }\n const report: string[] = [...this._abridgedLeading];\n if (this._abridgedOmittedLines === 1) {\n report.push(` ...${this._abridgedOmittedLines} line omitted...\\n`);\n }\n if (this._abridgedOmittedLines > 1) {\n report.push(` ...${this._abridgedOmittedLines} lines omitted...\\n`);\n }\n report.push(...this._abridgedTrailing);\n return report.join('');\n }\n\n public onWriteChunk(chunk: ITerminalChunk): void {\n if (chunk.text.length === 0 || chunk.text[chunk.text.length - 1] !== '\\n') {\n throw new Error(\n 'StdioSummarizer expects chunks that were separated parsed into lines by StderrLineTransform\\n' +\n ' Invalid input: ' +\n JSON.stringify(chunk.text)\n );\n }\n\n if (chunk.kind === TerminalChunkKind.Stderr && !this._abridgedStderr) {\n // The first time we see stderr, switch to capturing stderr\n this._abridgedStderr = true;\n this._abridgedLeading.length = 0;\n this._abridgedTrailing.length = 0;\n this._abridgedOmittedLines = 0;\n } else if (this._abridgedStderr && chunk.kind !== TerminalChunkKind.Stderr) {\n // If we're capturing stderr, then ignore non-stderr input\n return;\n }\n\n // Did we capture enough leading lines?\n if (this._abridgedLeading.length < this._leadingLines) {\n this._abridgedLeading.push(chunk.text);\n return;\n }\n\n this._abridgedTrailing.push(chunk.text);\n\n // If we captured to many trailing lines, omit the extras\n while (this._abridgedTrailing.length > this._trailingLines) {\n this._abridgedTrailing.shift();\n ++this._abridgedOmittedLines;\n }\n }\n}\n"]}
1
+ {"version":3,"file":"StdioSummarizer.js","sourceRoot":"","sources":["../src/StdioSummarizer.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { type ITerminalChunk, TerminalChunkKind } from './ITerminalChunk';\nimport { TerminalWritable } from './TerminalWritable';\n\n/**\n * Constructor options for {@link StdioSummarizer}.\n * @beta\n */\nexport interface IStdioSummarizerOptions {\n /**\n * Specifies the maximum number of leading lines to include in the summary.\n * @defaultValue `10`\n */\n leadingLines?: number;\n\n /**\n * Specifies the maximum number of trailing lines to include in the summary.\n * @defaultValue `10`\n */\n trailingLines?: number;\n}\n\n/**\n * Summarizes the results of a failed build task by returning a subset of `stderr` output not to exceed\n * a specified maximum number of lines.\n *\n * @remarks\n * IMPORTANT: This transform assumes that its input was prepared by {@link StderrLineTransform}, so that each\n * {@link ITerminalChunk.text} item is a single line terminated by a `\"\\n\"` character.\n *\n * The {@link IStdioSummarizerOptions.leadingLines} and {@link IStdioSummarizerOptions.trailingLines}\n * counts specify the maximum number of lines to be returned. Any additional lines will be omitted.\n * For example, if `leadingLines` and `trailingLines` were set to `3`, then the summary of 16 `stderr` lines might\n * look like this:\n *\n * ```\n * Line 1\n * Line 2\n * Line 3\n * ...10 lines omitted...\n * Line 14\n * Line 15\n * Line 16\n * ```\n *\n * If the `stderr` output is completely empty, then the `stdout` output will be summarized instead.\n *\n * @beta\n */\nexport class StdioSummarizer extends TerminalWritable {\n // Capture up to this many leading lines\n private _leadingLines: number;\n\n // Capture up to this many trailing lines\n private _trailingLines: number;\n\n private readonly _abridgedLeading: string[];\n private readonly _abridgedTrailing: string[];\n private _abridgedOmittedLines: number = 0;\n private _abridgedStderr: boolean;\n\n public constructor(options?: IStdioSummarizerOptions) {\n super();\n\n if (!options) {\n options = {};\n }\n\n this._leadingLines = options.leadingLines !== undefined ? options.leadingLines : 10;\n this._trailingLines = options.trailingLines !== undefined ? options.trailingLines : 10;\n\n this._abridgedLeading = [];\n this._abridgedTrailing = [];\n this._abridgedStderr = false;\n }\n\n /**\n * Returns the summary report.\n *\n * @remarks\n * The `close()` method must be called before `getReport()` can be used.\n */\n public getReport(): string {\n if (this.isOpen) {\n throw new Error('The summary cannot be prepared until after close() is called.');\n }\n const report: string[] = [...this._abridgedLeading];\n if (this._abridgedOmittedLines === 1) {\n report.push(` ...${this._abridgedOmittedLines} line omitted...\\n`);\n }\n if (this._abridgedOmittedLines > 1) {\n report.push(` ...${this._abridgedOmittedLines} lines omitted...\\n`);\n }\n report.push(...this._abridgedTrailing);\n return report.join('');\n }\n\n public onWriteChunk(chunk: ITerminalChunk): void {\n if (chunk.text.length === 0 || chunk.text[chunk.text.length - 1] !== '\\n') {\n throw new Error(\n 'StdioSummarizer expects chunks that were separated parsed into lines by StderrLineTransform\\n' +\n ' Invalid input: ' +\n JSON.stringify(chunk.text)\n );\n }\n\n if (chunk.kind === TerminalChunkKind.Stderr && !this._abridgedStderr) {\n // The first time we see stderr, switch to capturing stderr\n this._abridgedStderr = true;\n this._abridgedLeading.length = 0;\n this._abridgedTrailing.length = 0;\n this._abridgedOmittedLines = 0;\n } else if (this._abridgedStderr && chunk.kind !== TerminalChunkKind.Stderr) {\n // If we're capturing stderr, then ignore non-stderr input\n return;\n }\n\n // Did we capture enough leading lines?\n if (this._abridgedLeading.length < this._leadingLines) {\n this._abridgedLeading.push(chunk.text);\n return;\n }\n\n this._abridgedTrailing.push(chunk.text);\n\n // If we captured to many trailing lines, omit the extras\n while (this._abridgedTrailing.length > this._trailingLines) {\n this._abridgedTrailing.shift();\n ++this._abridgedOmittedLines;\n }\n }\n}\n"]}
@@ -28,6 +28,6 @@ class StdioWritable extends TerminalWritable_1.TerminalWritable {
28
28
  }
29
29
  }
30
30
  }
31
- StdioWritable.instance = new StdioWritable();
32
31
  exports.StdioWritable = StdioWritable;
32
+ StdioWritable.instance = new StdioWritable();
33
33
  //# sourceMappingURL=StdioWritable.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"StdioWritable.js","sourceRoot":"","sources":["../src/StdioWritable.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;;;;AAE3D,sDAA8B;AAE9B,yDAAsD;AAEtD;;;;;;;;;GASG;AACH,MAAa,aAAc,SAAQ,mCAAgB;IAGvC,YAAY,CAAC,KAAqB;QAC1C,IAAI,KAAK,CAAC,IAAI,uCAA6B,EAAE;YAC3C,iBAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;SAClC;aAAM,IAAI,KAAK,CAAC,IAAI,uCAA6B,EAAE;YAClD,iBAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;SAClC;IACH,CAAC;;AARa,sBAAQ,GAAkB,IAAI,aAAa,EAAE,CAAC;AADjD,sCAAa","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport process from 'process';\nimport { type ITerminalChunk, TerminalChunkKind } from './ITerminalChunk';\nimport { TerminalWritable } from './TerminalWritable';\n\n/**\n * A {@link TerminalWritable} subclass that writes its output directly to the process `stdout` and `stderr`\n * streams.\n *\n * @remarks\n * This is the standard output target for a process. You normally do not need to construct\n * this class; the {@link StdioWritable.\"instance\"} singleton can be used instead.\n *\n * @public\n */\nexport class StdioWritable extends TerminalWritable {\n public static instance: StdioWritable = new StdioWritable();\n\n protected onWriteChunk(chunk: ITerminalChunk): void {\n if (chunk.kind === TerminalChunkKind.Stdout) {\n process.stdout.write(chunk.text);\n } else if (chunk.kind === TerminalChunkKind.Stderr) {\n process.stderr.write(chunk.text);\n }\n }\n}\n"]}
1
+ {"version":3,"file":"StdioWritable.js","sourceRoot":"","sources":["../src/StdioWritable.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;;;;AAE3D,sDAA8B;AAE9B,yDAAsD;AAEtD;;;;;;;;;GASG;AACH,MAAa,aAAc,SAAQ,mCAAgB;IAGvC,YAAY,CAAC,KAAqB;QAC1C,IAAI,KAAK,CAAC,IAAI,uCAA6B,EAAE,CAAC;YAC5C,iBAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,uCAA6B,EAAE,CAAC;YACnD,iBAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;IACH,CAAC;;AATH,sCAUC;AATe,sBAAQ,GAAkB,IAAI,aAAa,EAAE,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport process from 'process';\nimport { type ITerminalChunk, TerminalChunkKind } from './ITerminalChunk';\nimport { TerminalWritable } from './TerminalWritable';\n\n/**\n * A {@link TerminalWritable} subclass that writes its output directly to the process `stdout` and `stderr`\n * streams.\n *\n * @remarks\n * This is the standard output target for a process. You normally do not need to construct\n * this class; the {@link StdioWritable.\"instance\"} singleton can be used instead.\n *\n * @public\n */\nexport class StdioWritable extends TerminalWritable {\n public static instance: StdioWritable = new StdioWritable();\n\n protected onWriteChunk(chunk: ITerminalChunk): void {\n if (chunk.kind === TerminalChunkKind.Stdout) {\n process.stdout.write(chunk.text);\n } else if (chunk.kind === TerminalChunkKind.Stderr) {\n process.stderr.write(chunk.text);\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"TerminalTransform.js","sourceRoot":"","sources":["../src/TerminalTransform.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,yDAAqF;AA2BrF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAsB,iBAAkB,SAAQ,mCAAgB;IAO9D,YAAmB,OAAkC;QACnD,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QACvC,IAAI,CAAC,2BAA2B,GAAG,CAAC,CAAC,OAAO,CAAC,2BAA2B,CAAC;IAC3E,CAAC;IAED,gBAAgB;IACN,OAAO;QACf,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAC9B,CAAC;IAED;;;;;;;;;;;OAWG;IACO,oBAAoB;QAC5B,IAAI,CAAC,IAAI,CAAC,2BAA2B,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,gBAAgB,EAAE;YAC3E,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;SAC1B;IACH,CAAC;CACF;AAnCD,8CAmCC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { TerminalWritable, type ITerminalWritableOptions } from './TerminalWritable';\n\n/**\n * Constructor options for {@link TerminalTransform}.\n *\n * @public\n */\nexport interface ITerminalTransformOptions extends ITerminalWritableOptions {\n /**\n * The target `TerminalWritable` that the `TerminalTransform` will write its\n * output to.\n */\n destination: TerminalWritable;\n\n /**\n * Prevents the {@link TerminalTransform.destination} object from being\n * closed automatically when the transform is closed.\n *\n * @remarks\n * When a transform is closed, normally it will automatically close its destination\n * `TerminalWritable` object. There are two ways to prevent that: either by setting\n * `preventDestinationAutoclose` to `true` for the transform, or by setting\n * {@link TerminalWritable.preventAutoclose} to `true` for the `destination` object.\n */\n preventDestinationAutoclose?: boolean;\n}\n\n/**\n * The abstract base class for {@link TerminalWritable} objects that receive an input,\n * transform it somehow, and then write the output to another `TerminalWritable`.\n *\n * @remarks\n *\n * The `TerminalTransform` and {@link SplitterTransform} base classes formalize the idea\n * of modeling data flow as a directed acyclic graph of reusable transforms, whose\n * final outputs are `TerminalWritable` objects.\n *\n * The design is based loosely on the `WritableStream` and `TransformStream` classes from\n * the system {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Concepts\n * | Streams API}, except that instead of asynchronous byte streams, the `TerminalWritable`\n * system synchronously transmits human readable messages intended to be rendered on a\n * text console or log file.\n *\n * The main feature of the `TerminalTransform` class is its {@link TerminalTransform.destination}\n * property, which tracks the next link in the graph.\n *\n * @public\n */\nexport abstract class TerminalTransform extends TerminalWritable {\n /** {@inheritDoc ITerminalTransformOptions.destination} */\n public readonly destination: TerminalWritable;\n\n /** {@inheritDoc ITerminalTransformOptions.preventDestinationAutoclose} */\n public readonly preventDestinationAutoclose: boolean;\n\n public constructor(options: ITerminalTransformOptions) {\n super();\n this.destination = options.destination;\n this.preventDestinationAutoclose = !!options.preventDestinationAutoclose;\n }\n\n /** @override */\n protected onClose(): void {\n this.autocloseDestination();\n }\n\n /**\n * The default implementation of {@link TerminalTransform.onClose} calls this\n * method, which closes the {@link TerminalTransform.destination} if appropriate.\n *\n * @remarks\n * The destination will not be closed if its {@link TerminalWritable.preventAutoclose}\n * property is `true`. The destination will not be closed if\n * {@link ITerminalTransformOptions.preventDestinationAutoclose}\n * is `true`.\n *\n * @sealed\n */\n protected autocloseDestination(): void {\n if (!this.preventDestinationAutoclose && !this.destination.preventAutoclose) {\n this.destination.close();\n }\n }\n}\n"]}
1
+ {"version":3,"file":"TerminalTransform.js","sourceRoot":"","sources":["../src/TerminalTransform.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,yDAAqF;AA2BrF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAsB,iBAAkB,SAAQ,mCAAgB;IAO9D,YAAmB,OAAkC;QACnD,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QACvC,IAAI,CAAC,2BAA2B,GAAG,CAAC,CAAC,OAAO,CAAC,2BAA2B,CAAC;IAC3E,CAAC;IAED,gBAAgB;IACN,OAAO;QACf,IAAI,CAAC,oBAAoB,EAAE,CAAC;IAC9B,CAAC;IAED;;;;;;;;;;;OAWG;IACO,oBAAoB;QAC5B,IAAI,CAAC,IAAI,CAAC,2BAA2B,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,gBAAgB,EAAE,CAAC;YAC5E,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QAC3B,CAAC;IACH,CAAC;CACF;AAnCD,8CAmCC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport { TerminalWritable, type ITerminalWritableOptions } from './TerminalWritable';\n\n/**\n * Constructor options for {@link TerminalTransform}.\n *\n * @public\n */\nexport interface ITerminalTransformOptions extends ITerminalWritableOptions {\n /**\n * The target `TerminalWritable` that the `TerminalTransform` will write its\n * output to.\n */\n destination: TerminalWritable;\n\n /**\n * Prevents the {@link TerminalTransform.destination} object from being\n * closed automatically when the transform is closed.\n *\n * @remarks\n * When a transform is closed, normally it will automatically close its destination\n * `TerminalWritable` object. There are two ways to prevent that: either by setting\n * `preventDestinationAutoclose` to `true` for the transform, or by setting\n * {@link TerminalWritable.preventAutoclose} to `true` for the `destination` object.\n */\n preventDestinationAutoclose?: boolean;\n}\n\n/**\n * The abstract base class for {@link TerminalWritable} objects that receive an input,\n * transform it somehow, and then write the output to another `TerminalWritable`.\n *\n * @remarks\n *\n * The `TerminalTransform` and {@link SplitterTransform} base classes formalize the idea\n * of modeling data flow as a directed acyclic graph of reusable transforms, whose\n * final outputs are `TerminalWritable` objects.\n *\n * The design is based loosely on the `WritableStream` and `TransformStream` classes from\n * the system {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Concepts\n * | Streams API}, except that instead of asynchronous byte streams, the `TerminalWritable`\n * system synchronously transmits human readable messages intended to be rendered on a\n * text console or log file.\n *\n * The main feature of the `TerminalTransform` class is its {@link TerminalTransform.destination}\n * property, which tracks the next link in the graph.\n *\n * @public\n */\nexport abstract class TerminalTransform extends TerminalWritable {\n /** {@inheritDoc ITerminalTransformOptions.destination} */\n public readonly destination: TerminalWritable;\n\n /** {@inheritDoc ITerminalTransformOptions.preventDestinationAutoclose} */\n public readonly preventDestinationAutoclose: boolean;\n\n public constructor(options: ITerminalTransformOptions) {\n super();\n this.destination = options.destination;\n this.preventDestinationAutoclose = !!options.preventDestinationAutoclose;\n }\n\n /** @override */\n protected onClose(): void {\n this.autocloseDestination();\n }\n\n /**\n * The default implementation of {@link TerminalTransform.onClose} calls this\n * method, which closes the {@link TerminalTransform.destination} if appropriate.\n *\n * @remarks\n * The destination will not be closed if its {@link TerminalWritable.preventAutoclose}\n * property is `true`. The destination will not be closed if\n * {@link ITerminalTransformOptions.preventDestinationAutoclose}\n * is `true`.\n *\n * @sealed\n */\n protected autocloseDestination(): void {\n if (!this.preventDestinationAutoclose && !this.destination.preventAutoclose) {\n this.destination.close();\n }\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"TerminalWritable.js","sourceRoot":"","sources":["../src/TerminalWritable.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAwB3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,MAAsB,gBAAgB;IAKpC,YAAmB,OAAkC;QACnD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QAEpB,IAAI,CAAC,OAAO,EAAE;YACZ,OAAO,GAAG,EAAE,CAAC;SACd;QAED,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC;IACrD,CAAC;IAED;;;;OAIG;IACH,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;;;;;;;;;;;OAYG;IACI,UAAU,CAAC,KAAqB;QACrC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACjB,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;SAC9C;QACD,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAOD;;;;;;;;;;;;OAYG;IACI,KAAK;QACV,IAAI,IAAI,CAAC,OAAO,EAAE;YAChB,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;SACtB;IACH,CAAC;IAED;;;;;;;;;OASG;IACO,OAAO,KAAU,CAAC;CAC7B;AAhFD,4CAgFC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type { ITerminalChunk } from './ITerminalChunk';\n\n/**\n * Constructor options for {@link TerminalWritable}\n *\n * @public\n */\nexport interface ITerminalWritableOptions {\n /**\n * When this object is the {@link TerminalTransform.destination} for a transform,\n * the transform will automatically close this object. Set `preventAutoclose` to `true`\n * to prevent that behavior.\n *\n * @remarks\n * When a transform is closed, normally it will automatically close its destination\n * `TerminalWritable` object. There are two ways to prevent that: either by setting\n * `preventDestinationAutoclose` to `true` for the transform, or by setting\n * {@link TerminalWritable.preventAutoclose} to `true` for the `destination` object.\n */\n preventAutoclose?: boolean;\n}\n\n/**\n * The abstract base class for objects that can present, route, or process text output for\n * a console application. This output is typically prepared using\n * the {@link @rushstack/node-core-library#Terminal} API.\n *\n * @remarks\n *\n * The design is based loosely on the `WritableStream` and `TransformStream` classes from\n * the system {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Concepts\n * | Streams API}, except that instead of asynchronous byte streams, the `TerminalWritable`\n * system synchronously transmits human readable messages intended to be rendered on a text\n * console or log file.\n *\n * Consider a console application whose output may need to be processed in different ways\n * before finally being output. The conceptual block diagram might look like this:\n *\n * ```\n * [Terminal API]\n * |\n * V\n * [normalize newlines]\n * |\n * V\n * +----[splitter]-------+\n * | |\n * V V\n * [shell console] [remove ANSI colors]\n * |\n * V\n * [write to build.log]\n * ```\n *\n * The application uses the `Terminal` API to print `stdout` and `stderr` messages, for example with standardized\n * formatting for errors and warnings, and ANSI escapes to make nice colors. Maybe it also includes text\n * received from external processes, whose newlines may be inconsistent. Ultimately we want to write the\n * output to the shell console and a `build.log` file, but we don't want to put ANSI colors in the build log.\n *\n * For the above example, `[shell console]` and `[write to build.log]` would be modeled as subclasses of\n * `TerminalWritable`. The `[normalize newlines]` and `[remove ANSI colors]` steps are modeled as subclasses\n * of {@link TerminalTransform}, because they output to a \"destination\" object. The `[splitter]` would be\n * implemented using {@link SplitterTransform}.\n *\n * The stream of messages are {@link ITerminalChunk} objects, which can represent both `stdout` and `stderr`\n * channels. The pipeline operates synchronously on each chunk, but by processing one chunk at a time,\n * it avoids storing the entire output in memory. This means that operations like `[remove ANSI colors]`\n * cannot be simple regular expressions -- they must be implemented as state machines ({@link TextRewriter}\n * subclasses) capable of matching substrings that span multiple chunks.\n *\n * @public\n */\nexport abstract class TerminalWritable {\n private _isOpen: boolean;\n\n public readonly preventAutoclose: boolean;\n\n public constructor(options?: ITerminalWritableOptions) {\n this._isOpen = true;\n\n if (!options) {\n options = {};\n }\n\n this.preventAutoclose = !!options.preventAutoclose;\n }\n\n /**\n * This property is initially `true` when the object is constructed, and becomes `false`\n * when `close()` is called.\n * @sealed\n */\n public get isOpen(): boolean {\n return this._isOpen;\n }\n\n /**\n * Upstream objects call this method to provide inputs to this object.\n *\n * @remarks\n * The subclass provides its implementation via the the {@link TerminalWritable.onWriteChunk}\n * method, which is called by `writeChunk()`.\n *\n * The object that calls `writeChunk()` must call `close()` when it is finished;\n * failing to do so may introduce a resource leak, or may prevent some buffered data from\n * being written.\n *\n * @sealed\n */\n public writeChunk(chunk: ITerminalChunk): void {\n if (!this._isOpen) {\n throw new Error('Writer was already closed');\n }\n this.onWriteChunk(chunk);\n }\n\n /**\n * Subclasses should implement this `abstract` method to process the chunk.\n */\n protected abstract onWriteChunk(chunk: ITerminalChunk): void;\n\n /**\n * Calling this method flushes any remaining outputs and permanently transitions the\n * `TerminalWritable` to a \"closed\" state, where no further chunks can be written.\n *\n * @remarks\n * The subclass provides its implementation via the the {@link TerminalWritable.onClose}\n * method, which is called by `close()`.\n *\n * If this method is called more than once, the additional calls are ignored;\n * `TerminalWritable.onClose` will be called at most once.\n *\n * @sealed\n */\n public close(): void {\n if (this._isOpen) {\n this.onClose();\n this._isOpen = false;\n }\n }\n\n /**\n * Subclasses can override this empty method to perform additional operations\n * such as closing a file handle.\n *\n * @remarks\n * It is guaranteed that this method will be called at most once during the lifetime\n * of a `TerminalWritable` object.\n *\n * @virtual\n */\n protected onClose(): void {}\n}\n"]}
1
+ {"version":3,"file":"TerminalWritable.js","sourceRoot":"","sources":["../src/TerminalWritable.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAwB3D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,MAAsB,gBAAgB;IAKpC,YAAmB,OAAkC;QACnD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QAEpB,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,GAAG,EAAE,CAAC;QACf,CAAC;QAED,IAAI,CAAC,gBAAgB,GAAG,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC;IACrD,CAAC;IAED;;;;OAIG;IACH,IAAW,MAAM;QACf,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;;;;;;;;;;;OAYG;IACI,UAAU,CAAC,KAAqB;QACrC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;QAC/C,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAOD;;;;;;;;;;;;OAYG;IACI,KAAK;QACV,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACvB,CAAC;IACH,CAAC;IAED;;;;;;;;;OASG;IACO,OAAO,KAAU,CAAC;CAC7B;AAhFD,4CAgFC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type { ITerminalChunk } from './ITerminalChunk';\n\n/**\n * Constructor options for {@link TerminalWritable}\n *\n * @public\n */\nexport interface ITerminalWritableOptions {\n /**\n * When this object is the {@link TerminalTransform.destination} for a transform,\n * the transform will automatically close this object. Set `preventAutoclose` to `true`\n * to prevent that behavior.\n *\n * @remarks\n * When a transform is closed, normally it will automatically close its destination\n * `TerminalWritable` object. There are two ways to prevent that: either by setting\n * `preventDestinationAutoclose` to `true` for the transform, or by setting\n * {@link TerminalWritable.preventAutoclose} to `true` for the `destination` object.\n */\n preventAutoclose?: boolean;\n}\n\n/**\n * The abstract base class for objects that can present, route, or process text output for\n * a console application. This output is typically prepared using\n * the {@link @rushstack/node-core-library#Terminal} API.\n *\n * @remarks\n *\n * The design is based loosely on the `WritableStream` and `TransformStream` classes from\n * the system {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Concepts\n * | Streams API}, except that instead of asynchronous byte streams, the `TerminalWritable`\n * system synchronously transmits human readable messages intended to be rendered on a text\n * console or log file.\n *\n * Consider a console application whose output may need to be processed in different ways\n * before finally being output. The conceptual block diagram might look like this:\n *\n * ```\n * [Terminal API]\n * |\n * V\n * [normalize newlines]\n * |\n * V\n * +----[splitter]-------+\n * | |\n * V V\n * [shell console] [remove ANSI colors]\n * |\n * V\n * [write to build.log]\n * ```\n *\n * The application uses the `Terminal` API to print `stdout` and `stderr` messages, for example with standardized\n * formatting for errors and warnings, and ANSI escapes to make nice colors. Maybe it also includes text\n * received from external processes, whose newlines may be inconsistent. Ultimately we want to write the\n * output to the shell console and a `build.log` file, but we don't want to put ANSI colors in the build log.\n *\n * For the above example, `[shell console]` and `[write to build.log]` would be modeled as subclasses of\n * `TerminalWritable`. The `[normalize newlines]` and `[remove ANSI colors]` steps are modeled as subclasses\n * of {@link TerminalTransform}, because they output to a \"destination\" object. The `[splitter]` would be\n * implemented using {@link SplitterTransform}.\n *\n * The stream of messages are {@link ITerminalChunk} objects, which can represent both `stdout` and `stderr`\n * channels. The pipeline operates synchronously on each chunk, but by processing one chunk at a time,\n * it avoids storing the entire output in memory. This means that operations like `[remove ANSI colors]`\n * cannot be simple regular expressions -- they must be implemented as state machines ({@link TextRewriter}\n * subclasses) capable of matching substrings that span multiple chunks.\n *\n * @public\n */\nexport abstract class TerminalWritable {\n private _isOpen: boolean;\n\n public readonly preventAutoclose: boolean;\n\n public constructor(options?: ITerminalWritableOptions) {\n this._isOpen = true;\n\n if (!options) {\n options = {};\n }\n\n this.preventAutoclose = !!options.preventAutoclose;\n }\n\n /**\n * This property is initially `true` when the object is constructed, and becomes `false`\n * when `close()` is called.\n * @sealed\n */\n public get isOpen(): boolean {\n return this._isOpen;\n }\n\n /**\n * Upstream objects call this method to provide inputs to this object.\n *\n * @remarks\n * The subclass provides its implementation via the the {@link TerminalWritable.onWriteChunk}\n * method, which is called by `writeChunk()`.\n *\n * The object that calls `writeChunk()` must call `close()` when it is finished;\n * failing to do so may introduce a resource leak, or may prevent some buffered data from\n * being written.\n *\n * @sealed\n */\n public writeChunk(chunk: ITerminalChunk): void {\n if (!this._isOpen) {\n throw new Error('Writer was already closed');\n }\n this.onWriteChunk(chunk);\n }\n\n /**\n * Subclasses should implement this `abstract` method to process the chunk.\n */\n protected abstract onWriteChunk(chunk: ITerminalChunk): void;\n\n /**\n * Calling this method flushes any remaining outputs and permanently transitions the\n * `TerminalWritable` to a \"closed\" state, where no further chunks can be written.\n *\n * @remarks\n * The subclass provides its implementation via the the {@link TerminalWritable.onClose}\n * method, which is called by `close()`.\n *\n * If this method is called more than once, the additional calls are ignored;\n * `TerminalWritable.onClose` will be called at most once.\n *\n * @sealed\n */\n public close(): void {\n if (this._isOpen) {\n this.onClose();\n this._isOpen = false;\n }\n }\n\n /**\n * Subclasses can override this empty method to perform additional operations\n * such as closing a file handle.\n *\n * @remarks\n * It is guaranteed that this method will be called at most once during the lifetime\n * of a `TerminalWritable` object.\n *\n * @virtual\n */\n protected onClose(): void {}\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"TextRewriterTransform.js","sourceRoot":"","sources":["../src/TextRewriterTransform.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type { NewlineKind } from '@rushstack/node-core-library';\n\nimport { type ITerminalChunk, TerminalChunkKind } from './ITerminalChunk';\nimport { TerminalTransform, type ITerminalTransformOptions } from './TerminalTransform';\nimport type { TextRewriter, TextRewriterState } from './TextRewriter';\nimport { RemoveColorsTextRewriter } from './RemoveColorsTextRewriter';\nimport { NormalizeNewlinesTextRewriter } from './NormalizeNewlinesTextRewriter';\n\n/**\n * Constructor options for {@link TextRewriterTransform}.\n *\n * @public\n */\nexport interface ITextRewriterTransformOptions extends ITerminalTransformOptions {\n /**\n * A list of rewriters to be applied. More items may be appended to the list, for example\n * if {@link ITextRewriterTransformOptions.removeColors} is specified.\n *\n * @remarks\n * The final list must contain at least one item.\n */\n textRewriters?: TextRewriter[];\n\n /**\n * If specified, a {@link RemoveColorsTextRewriter} will be appended to the list of rewriters.\n */\n removeColors?: boolean;\n\n /**\n * If `normalizeNewlines` or `ensureNewlineAtEnd` is specified, a {@link NormalizeNewlinesTextRewriter}\n * will be appended to the list of rewriters with the specified settings.\n *\n * @remarks\n * See {@link INormalizeNewlinesTextRewriterOptions} for details.\n */\n normalizeNewlines?: NewlineKind;\n\n /**\n * If `normalizeNewlines` or `ensureNewlineAtEnd` is specified, a {@link NormalizeNewlinesTextRewriter}\n * will be appended to the list of rewriters with the specified settings.\n *\n * @remarks\n * See {@link INormalizeNewlinesTextRewriterOptions} for details.\n */\n ensureNewlineAtEnd?: boolean;\n}\n\n/**\n * A {@link TerminalTransform} subclass that performs one or more {@link TextRewriter} operations.\n * The most common operations are {@link NormalizeNewlinesTextRewriter} and {@link RemoveColorsTextRewriter}.\n *\n * @remarks\n * The `TextRewriter` operations are applied separately to the `stderr` and `stdout` streams.\n * If multiple {@link ITextRewriterTransformOptions.textRewriters} are configured, they are applied\n * in the order that they appear in the array.\n *\n * @public\n */\nexport class TextRewriterTransform extends TerminalTransform {\n private readonly _stderrStates: TextRewriterState[];\n private readonly _stdoutStates: TextRewriterState[];\n\n public readonly textRewriters: ReadonlyArray<TextRewriter>;\n\n public constructor(options: ITextRewriterTransformOptions) {\n super(options);\n\n const textRewriters: TextRewriter[] = options.textRewriters || [];\n\n if (options.removeColors) {\n textRewriters.push(new RemoveColorsTextRewriter());\n }\n if (options.normalizeNewlines) {\n textRewriters.push(\n new NormalizeNewlinesTextRewriter({\n newlineKind: options.normalizeNewlines,\n ensureNewlineAtEnd: options.ensureNewlineAtEnd\n })\n );\n }\n\n if (textRewriters.length === 0) {\n throw new Error('TextRewriterTransform requires at least one matcher');\n }\n\n this.textRewriters = textRewriters;\n\n this._stderrStates = this.textRewriters.map((x) => x.initialize());\n this._stdoutStates = this.textRewriters.map((x) => x.initialize());\n }\n\n protected onWriteChunk(chunk: ITerminalChunk): void {\n if (chunk.kind === TerminalChunkKind.Stderr) {\n this._processText(chunk, this._stderrStates);\n } else if (chunk.kind === TerminalChunkKind.Stdout) {\n this._processText(chunk, this._stdoutStates);\n } else {\n this.destination.writeChunk(chunk);\n }\n }\n\n private _processText(chunk: ITerminalChunk, states: TextRewriterState[]): void {\n let text: string = chunk.text;\n for (let i: number = 0; i < states.length; ++i) {\n if (text.length > 0) {\n text = this.textRewriters[i].process(states[i], text);\n }\n }\n if (text.length > 0) {\n // If possible, avoid allocating a new chunk\n if (text === chunk.text) {\n this.destination.writeChunk(chunk);\n } else {\n this.destination.writeChunk({\n text: text,\n kind: chunk.kind\n });\n }\n }\n }\n\n private _closeRewriters(states: TextRewriterState[], chunkKind: TerminalChunkKind): void {\n let text: string = '';\n for (let i: number = 0; i < states.length; ++i) {\n if (text.length > 0) {\n text = this.textRewriters[i].process(states[i], text);\n }\n text += this.textRewriters[i].close(states[i]);\n }\n if (text.length > 0) {\n this.destination.writeChunk({\n text: text,\n kind: chunkKind\n });\n }\n }\n\n protected onClose(): void {\n this._closeRewriters(this._stderrStates, TerminalChunkKind.Stderr);\n this._closeRewriters(this._stdoutStates, TerminalChunkKind.Stdout);\n\n this.autocloseDestination();\n }\n}\n"]}
1
+ {"version":3,"file":"TextRewriterTransform.js","sourceRoot":"","sources":["../src/TextRewriterTransform.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type { NewlineKind } from '@rushstack/node-core-library';\n\nimport { type ITerminalChunk, TerminalChunkKind } from './ITerminalChunk';\nimport { TerminalTransform, type ITerminalTransformOptions } from './TerminalTransform';\nimport type { TextRewriter, TextRewriterState } from './TextRewriter';\nimport { RemoveColorsTextRewriter } from './RemoveColorsTextRewriter';\nimport { NormalizeNewlinesTextRewriter } from './NormalizeNewlinesTextRewriter';\n\n/**\n * Constructor options for {@link TextRewriterTransform}.\n *\n * @public\n */\nexport interface ITextRewriterTransformOptions extends ITerminalTransformOptions {\n /**\n * A list of rewriters to be applied. More items may be appended to the list, for example\n * if {@link ITextRewriterTransformOptions.removeColors} is specified.\n *\n * @remarks\n * The final list must contain at least one item.\n */\n textRewriters?: TextRewriter[];\n\n /**\n * If specified, a {@link RemoveColorsTextRewriter} will be appended to the list of rewriters.\n */\n removeColors?: boolean;\n\n /**\n * If `normalizeNewlines` or `ensureNewlineAtEnd` is specified, a {@link NormalizeNewlinesTextRewriter}\n * will be appended to the list of rewriters with the specified settings.\n *\n * @remarks\n * See {@link INormalizeNewlinesTextRewriterOptions} for details.\n */\n normalizeNewlines?: NewlineKind;\n\n /**\n * If `normalizeNewlines` or `ensureNewlineAtEnd` is specified, a {@link NormalizeNewlinesTextRewriter}\n * will be appended to the list of rewriters with the specified settings.\n *\n * @remarks\n * See {@link INormalizeNewlinesTextRewriterOptions} for details.\n */\n ensureNewlineAtEnd?: boolean;\n}\n\n/**\n * A {@link TerminalTransform} subclass that performs one or more {@link TextRewriter} operations.\n * The most common operations are {@link NormalizeNewlinesTextRewriter} and {@link RemoveColorsTextRewriter}.\n *\n * @remarks\n * The `TextRewriter` operations are applied separately to the `stderr` and `stdout` streams.\n * If multiple {@link ITextRewriterTransformOptions.textRewriters} are configured, they are applied\n * in the order that they appear in the array.\n *\n * @public\n */\nexport class TextRewriterTransform extends TerminalTransform {\n private readonly _stderrStates: TextRewriterState[];\n private readonly _stdoutStates: TextRewriterState[];\n\n public readonly textRewriters: ReadonlyArray<TextRewriter>;\n\n public constructor(options: ITextRewriterTransformOptions) {\n super(options);\n\n const textRewriters: TextRewriter[] = options.textRewriters || [];\n\n if (options.removeColors) {\n textRewriters.push(new RemoveColorsTextRewriter());\n }\n if (options.normalizeNewlines) {\n textRewriters.push(\n new NormalizeNewlinesTextRewriter({\n newlineKind: options.normalizeNewlines,\n ensureNewlineAtEnd: options.ensureNewlineAtEnd\n })\n );\n }\n\n if (textRewriters.length === 0) {\n throw new Error('TextRewriterTransform requires at least one matcher');\n }\n\n this.textRewriters = textRewriters;\n\n this._stderrStates = this.textRewriters.map((x) => x.initialize());\n this._stdoutStates = this.textRewriters.map((x) => x.initialize());\n }\n\n protected onWriteChunk(chunk: ITerminalChunk): void {\n if (chunk.kind === TerminalChunkKind.Stderr) {\n this._processText(chunk, this._stderrStates);\n } else if (chunk.kind === TerminalChunkKind.Stdout) {\n this._processText(chunk, this._stdoutStates);\n } else {\n this.destination.writeChunk(chunk);\n }\n }\n\n private _processText(chunk: ITerminalChunk, states: TextRewriterState[]): void {\n let text: string = chunk.text;\n for (let i: number = 0; i < states.length; ++i) {\n if (text.length > 0) {\n text = this.textRewriters[i].process(states[i], text);\n }\n }\n if (text.length > 0) {\n // If possible, avoid allocating a new chunk\n if (text === chunk.text) {\n this.destination.writeChunk(chunk);\n } else {\n this.destination.writeChunk({\n text: text,\n kind: chunk.kind\n });\n }\n }\n }\n\n private _closeRewriters(states: TextRewriterState[], chunkKind: TerminalChunkKind): void {\n let text: string = '';\n for (let i: number = 0; i < states.length; ++i) {\n if (text.length > 0) {\n text = this.textRewriters[i].process(states[i], text);\n }\n text += this.textRewriters[i].close(states[i]);\n }\n if (text.length > 0) {\n this.destination.writeChunk({\n text: text,\n kind: chunkKind\n });\n }\n }\n\n protected onClose(): void {\n this._closeRewriters(this._stderrStates, TerminalChunkKind.Stderr);\n this._closeRewriters(this._stdoutStates, TerminalChunkKind.Stdout);\n\n this.autocloseDestination();\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rushstack/terminal",
3
- "version": "0.7.16",
3
+ "version": "0.7.17",
4
4
  "description": "User interface primitives for console applications",
5
5
  "main": "lib/index.js",
6
6
  "typings": "dist/terminal.d.ts",
@@ -16,7 +16,7 @@
16
16
  "devDependencies": {
17
17
  "colors": "~1.2.1",
18
18
  "local-node-rig": "1.0.0",
19
- "@rushstack/heft": "0.63.6"
19
+ "@rushstack/heft": "0.64.0"
20
20
  },
21
21
  "peerDependencies": {
22
22
  "@types/node": "*"