node_modules ignore

This commit is contained in:
2025-05-08 23:43:47 +02:00
parent e19d52f172
commit 4574544c9f
65041 changed files with 10593536 additions and 0 deletions

5021
server/node_modules/@rushstack/terminal/CHANGELOG.json generated vendored Normal file

File diff suppressed because it is too large Load Diff

1661
server/node_modules/@rushstack/terminal/CHANGELOG.md generated vendored Normal file

File diff suppressed because it is too large Load Diff

24
server/node_modules/@rushstack/terminal/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,24 @@
@rushstack/terminal
Copyright (c) Microsoft Corporation. All rights reserved.
MIT License
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

53
server/node_modules/@rushstack/terminal/README.md generated vendored Normal file
View File

@@ -0,0 +1,53 @@
# @rushstack/terminal
This library implements a system for processing human readable text that
will be output by console applications.
The design is based loosely on the `WritableStream` and `TransformStream` classes from
the system [Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Concepts),
except that instead of asynchronous byte streams, the `TerminalWritable` system synchronously transmits
human readable messages intended to be rendered on a text console or log file.
Consider a console application whose output may need to be processed in different ways
before finally being output. The conceptual block diagram might look like this:
```
[Terminal API]
|
V
[normalize newlines]
|
V
+----[splitter]-------+
| |
V V
[shell console] [remove ANSI colors]
|
V
[write to build.log]
```
The application uses the `Terminal` API to print `stdout` and `stderr` messages, for example with standardized
formatting for errors and warnings, and ANSI escapes to make nice colors. Maybe it also includes text
received from external processes, whose newlines may be inconsistent. Ultimately we want to write the
output to the shell console and a `build.log` file, but we don't want to put ANSI colors in the build log.
For the above example, `[shell console]` and `[write to build.log]` would be modeled as subclasses of
`TerminalWritable`. The `[normalize newlines]` and `[remove ANSI colors]` steps are modeled as subclasses
of `TerminalTransform`, because they output to a "destination" object. The `[splitter]` would be
implemented using `SplitterTransform`.
The stream of messages are {@link ITerminalChunk} objects, which can represent both `stdout` and `stderr`
channels. The pipeline operates synchronously on each chunk, but by processing one chunk at a time,
it avoids storing the entire output in memory. This means that operations like `[remove ANSI colors]`
cannot be simple regular expressions -- they must be implemented as state machines (`TextRewriter` subclasses)
capable of matching substrings that span multiple chunks.
## Links
- [CHANGELOG.md](
https://github.com/microsoft/rushstack/blob/main/libraries/terminal/CHANGELOG.md) - Find
out what's new in the latest version
- [API Reference](https://api.rushstack.io/pages/terminal/)
`@rushstack/terminal` is part of the [Rush Stack](https://rushstack.io/) family of projects.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
// This file is read by tools that parse documentation comments conforming to the TSDoc standard.
// It should be published with your NPM package. It should not be tracked by Git.
{
"tsdocVersion": "0.12",
"toolPackages": [
{
"packageName": "@microsoft/api-extractor",
"packageVersion": "7.52.1"
}
]
}

View File

@@ -0,0 +1,35 @@
/**
* Options for {@link AnsiEscape.formatForTests}.
* @public
*/
export interface IAnsiEscapeConvertForTestsOptions {
/**
* If true then `\n` will be replaced by `[n]`, and `\r` will be replaced by `[r]`.
*/
encodeNewlines?: boolean;
}
/**
* Operations for working with text strings that contain
* {@link https://en.wikipedia.org/wiki/ANSI_escape_code | ANSI escape codes}.
* The most commonly used escape codes set the foreground/background color for console output.
* @public
*/
export declare class AnsiEscape {
private static readonly _csiRegExp;
private static readonly _sgrRegExp;
private static readonly _backslashNRegExp;
private static readonly _backslashRRegExp;
static getEscapeSequenceForAnsiCode(code: number): string;
/**
* Returns the input text with all ANSI escape codes removed. For example, this is useful when saving
* colorized console output to a log file.
*/
static removeCodes(text: string): string;
/**
* Replaces ANSI escape codes with human-readable tokens. This is useful for unit tests
* that compare text strings in test assertions or snapshot files.
*/
static formatForTests(text: string, options?: IAnsiEscapeConvertForTestsOptions): string;
private static _tryGetSgrFriendlyName;
}
//# sourceMappingURL=AnsiEscape.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"AnsiEscape.d.ts","sourceRoot":"","sources":["../src/AnsiEscape.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,MAAM,WAAW,iCAAiC;IAChD;;OAEG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;GAKG;AACH,qBAAa,UAAU;IAGrB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAA2D;IAI7F,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAwB;IAE1D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAiB;IAC1D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAiB;WAE5C,4BAA4B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAIhE;;;OAGG;WACW,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAK/C;;;OAGG;WACW,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iCAAiC,GAAG,MAAM;IAiC/F,OAAO,CAAC,MAAM,CAAC,sBAAsB;CAsEtC"}

View File

@@ -0,0 +1,136 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.AnsiEscape = void 0;
const Colorize_1 = require("./Colorize");
/**
* Operations for working with text strings that contain
* {@link https://en.wikipedia.org/wiki/ANSI_escape_code | ANSI escape codes}.
* The most commonly used escape codes set the foreground/background color for console output.
* @public
*/
class AnsiEscape {
static getEscapeSequenceForAnsiCode(code) {
return `\u001b[${code}m`;
}
/**
* Returns the input text with all ANSI escape codes removed. For example, this is useful when saving
* colorized console output to a log file.
*/
static removeCodes(text) {
// eslint-disable-next-line no-control-regex
return text.replace(AnsiEscape._csiRegExp, '');
}
/**
* Replaces ANSI escape codes with human-readable tokens. This is useful for unit tests
* that compare text strings in test assertions or snapshot files.
*/
static formatForTests(text, options) {
if (!options) {
options = {};
}
let result = text.replace(AnsiEscape._csiRegExp, (capture, csiCode) => {
// If it is an SGR code, then try to show a friendly token
const match = csiCode.match(AnsiEscape._sgrRegExp);
if (match) {
const sgrParameter = parseInt(match[1], 10);
const sgrParameterName = AnsiEscape._tryGetSgrFriendlyName(sgrParameter);
if (sgrParameterName) {
// Example: "[black-bg]"
return `[${sgrParameterName}]`;
}
}
// Otherwise show the raw code, but without the "[" from the CSI prefix
// Example: "[31m]"
return `[${csiCode}]`;
});
if (options.encodeNewlines) {
result = result
.replace(AnsiEscape._backslashNRegExp, '[n]')
.replace(AnsiEscape._backslashRRegExp, `[r]`);
}
return result;
}
// Returns a human-readable token representing an SGR parameter, or undefined for parameter that is not well-known.
// The SGR parameter numbers are documented in this table:
// https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters
static _tryGetSgrFriendlyName(sgiParameter) {
switch (sgiParameter) {
case Colorize_1.SgrParameterAttribute.BlackForeground:
return 'black';
case Colorize_1.SgrParameterAttribute.RedForeground:
return 'red';
case Colorize_1.SgrParameterAttribute.GreenForeground:
return 'green';
case Colorize_1.SgrParameterAttribute.YellowForeground:
return 'yellow';
case Colorize_1.SgrParameterAttribute.BlueForeground:
return 'blue';
case Colorize_1.SgrParameterAttribute.MagentaForeground:
return 'magenta';
case Colorize_1.SgrParameterAttribute.CyanForeground:
return 'cyan';
case Colorize_1.SgrParameterAttribute.WhiteForeground:
return 'white';
case Colorize_1.SgrParameterAttribute.GrayForeground:
return 'gray';
case Colorize_1.SgrParameterAttribute.DefaultForeground:
return 'default';
case Colorize_1.SgrParameterAttribute.BlackBackground:
return 'black-bg';
case Colorize_1.SgrParameterAttribute.RedBackground:
return 'red-bg';
case Colorize_1.SgrParameterAttribute.GreenBackground:
return 'green-bg';
case Colorize_1.SgrParameterAttribute.YellowBackground:
return 'yellow-bg';
case Colorize_1.SgrParameterAttribute.BlueBackground:
return 'blue-bg';
case Colorize_1.SgrParameterAttribute.MagentaBackground:
return 'magenta-bg';
case Colorize_1.SgrParameterAttribute.CyanBackground:
return 'cyan-bg';
case Colorize_1.SgrParameterAttribute.WhiteBackground:
return 'white-bg';
case Colorize_1.SgrParameterAttribute.GrayBackground:
return 'gray-bg';
case Colorize_1.SgrParameterAttribute.DefaultBackground:
return 'default-bg';
case Colorize_1.SgrParameterAttribute.Bold:
return 'bold';
case Colorize_1.SgrParameterAttribute.Dim:
return 'dim';
case Colorize_1.SgrParameterAttribute.NormalColorOrIntensity:
return 'normal';
case Colorize_1.SgrParameterAttribute.Underline:
return 'underline';
case Colorize_1.SgrParameterAttribute.UnderlineOff:
return 'underline-off';
case Colorize_1.SgrParameterAttribute.Blink:
return 'blink';
case Colorize_1.SgrParameterAttribute.BlinkOff:
return 'blink-off';
case Colorize_1.SgrParameterAttribute.InvertColor:
return 'invert';
case Colorize_1.SgrParameterAttribute.InvertColorOff:
return 'invert-off';
case Colorize_1.SgrParameterAttribute.Hidden:
return 'hidden';
case Colorize_1.SgrParameterAttribute.HiddenOff:
return 'hidden-off';
default:
return undefined;
}
}
}
exports.AnsiEscape = AnsiEscape;
// For now, we only care about the Control Sequence Introducer (CSI) commands which always start with "[".
// eslint-disable-next-line no-control-regex
AnsiEscape._csiRegExp = /\x1b\[([\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e])/gu;
// Text coloring is performed using Select Graphic Rendition (SGR) codes, which come after the
// CSI introducer "ESC [". The SGR sequence is a number followed by "m".
AnsiEscape._sgrRegExp = /([0-9]+)m/u;
AnsiEscape._backslashNRegExp = /\n/g;
AnsiEscape._backslashRRegExp = /\r/g;
//# sourceMappingURL=AnsiEscape.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,29 @@
import { TerminalWritable } from './TerminalWritable';
import type { ITerminalChunk } from './ITerminalChunk';
/**
* Constructor options for {@link CallbackWritable}.
* @public
*/
export interface ICallbackWritableOptions {
onWriteChunk: (chunk: ITerminalChunk) => void;
}
/**
* This class enables very basic {@link TerminalWritable.onWriteChunk} operations to be implemented
* as a callback function, avoiding the need to define a subclass of `TerminalWritable`.
*
* @remarks
* `CallbackWritable` is provided as a convenience for very simple situations. For most cases,
* it is generally preferable to create a proper subclass.
*
* @privateRemarks
* We intentionally do not expose a callback for {@link TerminalWritable.onClose}; if special
* close behavior is required, it is better to create a subclass.
*
* @public
*/
export declare class CallbackWritable extends TerminalWritable {
private readonly _callback;
constructor(options: ICallbackWritableOptions);
protected onWriteChunk(chunk: ITerminalChunk): void;
}
//# sourceMappingURL=CallbackWritable.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"CallbackWritable.d.ts","sourceRoot":"","sources":["../src/CallbackWritable.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC,YAAY,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;CAC/C;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,gBAAiB,SAAQ,gBAAgB;IACpD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAkC;gBAEzC,OAAO,EAAE,wBAAwB;IAKpD,SAAS,CAAC,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;CAGpD"}

View File

@@ -0,0 +1,31 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.CallbackWritable = void 0;
const TerminalWritable_1 = require("./TerminalWritable");
/**
* This class enables very basic {@link TerminalWritable.onWriteChunk} operations to be implemented
* as a callback function, avoiding the need to define a subclass of `TerminalWritable`.
*
* @remarks
* `CallbackWritable` is provided as a convenience for very simple situations. For most cases,
* it is generally preferable to create a proper subclass.
*
* @privateRemarks
* We intentionally do not expose a callback for {@link TerminalWritable.onClose}; if special
* close behavior is required, it is better to create a subclass.
*
* @public
*/
class CallbackWritable extends TerminalWritable_1.TerminalWritable {
constructor(options) {
super();
this._callback = options.onWriteChunk;
}
onWriteChunk(chunk) {
this._callback(chunk);
}
}
exports.CallbackWritable = CallbackWritable;
//# sourceMappingURL=CallbackWritable.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"CallbackWritable.js","sourceRoot":"","sources":["../src/CallbackWritable.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,yDAAsD;AAWtD;;;;;;;;;;;;;GAaG;AACH,MAAa,gBAAiB,SAAQ,mCAAgB;IAGpD,YAAmB,OAAiC;QAClD,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC;IACxC,CAAC;IAES,YAAY,CAAC,KAAqB;QAC1C,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC;CACF;AAXD,4CAWC","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 } from './TerminalWritable';\nimport type { ITerminalChunk } from './ITerminalChunk';\n\n/**\n * Constructor options for {@link CallbackWritable}.\n * @public\n */\nexport interface ICallbackWritableOptions {\n onWriteChunk: (chunk: ITerminalChunk) => void;\n}\n\n/**\n * This class enables very basic {@link TerminalWritable.onWriteChunk} operations to be implemented\n * as a callback function, avoiding the need to define a subclass of `TerminalWritable`.\n *\n * @remarks\n * `CallbackWritable` is provided as a convenience for very simple situations. For most cases,\n * it is generally preferable to create a proper subclass.\n *\n * @privateRemarks\n * We intentionally do not expose a callback for {@link TerminalWritable.onClose}; if special\n * close behavior is required, it is better to create a subclass.\n *\n * @public\n */\nexport class CallbackWritable extends TerminalWritable {\n private readonly _callback: (chunk: ITerminalChunk) => void;\n\n public constructor(options: ICallbackWritableOptions) {\n super();\n this._callback = options.onWriteChunk;\n }\n\n protected onWriteChunk(chunk: ITerminalChunk): void {\n this._callback(chunk);\n }\n}\n"]}

View File

@@ -0,0 +1,81 @@
export declare enum SgrParameterAttribute {
BlackForeground = 30,
RedForeground = 31,
GreenForeground = 32,
YellowForeground = 33,
BlueForeground = 34,
MagentaForeground = 35,
CyanForeground = 36,
WhiteForeground = 37,
GrayForeground = 90,
DefaultForeground = 39,
BlackBackground = 40,
RedBackground = 41,
GreenBackground = 42,
YellowBackground = 43,
BlueBackground = 44,
MagentaBackground = 45,
CyanBackground = 46,
WhiteBackground = 47,
GrayBackground = 100,
DefaultBackground = 49,
Bold = 1,
Dim = 2,
NormalColorOrIntensity = 22,
Underline = 4,
UnderlineOff = 24,
Blink = 5,
BlinkOff = 25,
InvertColor = 7,
InvertColorOff = 27,
Hidden = 8,
HiddenOff = 28
}
/**
* The static functions on this class are used to produce colored text
* for use with a terminal that supports ANSI escape codes.
*
* Note that this API always generates color codes, regardless of whether
* the process's stdout is a TTY. The reason is that, in a complex program, the
* code that is generating strings often does not know were those strings will end
* up. In some cases, the same log message may get printed both to a shell
* that supports color AND to a log file that does not.
*
* @example
* ```ts
* console.log(Colorize.red('Red Text!'))
* terminal.writeLine(Colorize.green('Green Text!'), ' ', Colorize.blue('Blue Text!'));
*```
*
* @public
*/
export declare class Colorize {
static black(text: string): string;
static red(text: string): string;
static green(text: string): string;
static yellow(text: string): string;
static blue(text: string): string;
static magenta(text: string): string;
static cyan(text: string): string;
static white(text: string): string;
static gray(text: string): string;
static blackBackground(text: string): string;
static redBackground(text: string): string;
static greenBackground(text: string): string;
static yellowBackground(text: string): string;
static blueBackground(text: string): string;
static magentaBackground(text: string): string;
static cyanBackground(text: string): string;
static whiteBackground(text: string): string;
static grayBackground(text: string): string;
static bold(text: string): string;
static dim(text: string): string;
static underline(text: string): string;
static blink(text: string): string;
static invertColor(text: string): string;
static hidden(text: string): string;
static rainbow(text: string): string;
private static _applyColorSequence;
private static _wrapTextInAnsiEscapeCodes;
}
//# sourceMappingURL=Colorize.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"Colorize.d.ts","sourceRoot":"","sources":["../src/Colorize.ts"],"names":[],"mappings":"AAKA,oBAAY,qBAAqB;IAC/B,eAAe,KAAK;IACpB,aAAa,KAAK;IAClB,eAAe,KAAK;IACpB,gBAAgB,KAAK;IACrB,cAAc,KAAK;IACnB,iBAAiB,KAAK;IACtB,cAAc,KAAK;IACnB,eAAe,KAAK;IACpB,cAAc,KAAK;IACnB,iBAAiB,KAAK;IAEtB,eAAe,KAAK;IACpB,aAAa,KAAK;IAClB,eAAe,KAAK;IACpB,gBAAgB,KAAK;IACrB,cAAc,KAAK;IACnB,iBAAiB,KAAK;IACtB,cAAc,KAAK;IACnB,eAAe,KAAK;IACpB,cAAc,MAAM;IACpB,iBAAiB,KAAK;IAEtB,IAAI,IAAI;IAOR,GAAG,IAAI;IACP,sBAAsB,KAAK;IAC3B,SAAS,IAAI;IACb,YAAY,KAAK;IACjB,KAAK,IAAI;IACT,QAAQ,KAAK;IACb,WAAW,IAAI;IACf,cAAc,KAAK;IACnB,MAAM,IAAI;IACV,SAAS,KAAK;CACf;AAWD;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,QAAQ;WACL,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;WAQ3B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;WAQzB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;WAQ3B,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;WAQ5B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;WAQ1B,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;WAQ7B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;WAQ1B,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;WAQ3B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;WAQ1B,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;WAQrC,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;WAQnC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;WAQrC,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;WAQtC,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;WAQpC,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;WAQvC,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;WAQpC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;WAQrC,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;WAQpC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;WAQ1B,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;WAQzB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;WAQ/B,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;WAQ3B,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;WAQjC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;WAQ5B,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAI3C,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAUlC,OAAO,CAAC,MAAM,CAAC,0BAA0B;CAO1C"}

162
server/node_modules/@rushstack/terminal/lib/Colorize.js generated vendored Normal file
View File

@@ -0,0 +1,162 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.Colorize = exports.SgrParameterAttribute = void 0;
const AnsiEscape_1 = require("./AnsiEscape");
var SgrParameterAttribute;
(function (SgrParameterAttribute) {
SgrParameterAttribute[SgrParameterAttribute["BlackForeground"] = 30] = "BlackForeground";
SgrParameterAttribute[SgrParameterAttribute["RedForeground"] = 31] = "RedForeground";
SgrParameterAttribute[SgrParameterAttribute["GreenForeground"] = 32] = "GreenForeground";
SgrParameterAttribute[SgrParameterAttribute["YellowForeground"] = 33] = "YellowForeground";
SgrParameterAttribute[SgrParameterAttribute["BlueForeground"] = 34] = "BlueForeground";
SgrParameterAttribute[SgrParameterAttribute["MagentaForeground"] = 35] = "MagentaForeground";
SgrParameterAttribute[SgrParameterAttribute["CyanForeground"] = 36] = "CyanForeground";
SgrParameterAttribute[SgrParameterAttribute["WhiteForeground"] = 37] = "WhiteForeground";
SgrParameterAttribute[SgrParameterAttribute["GrayForeground"] = 90] = "GrayForeground";
SgrParameterAttribute[SgrParameterAttribute["DefaultForeground"] = 39] = "DefaultForeground";
SgrParameterAttribute[SgrParameterAttribute["BlackBackground"] = 40] = "BlackBackground";
SgrParameterAttribute[SgrParameterAttribute["RedBackground"] = 41] = "RedBackground";
SgrParameterAttribute[SgrParameterAttribute["GreenBackground"] = 42] = "GreenBackground";
SgrParameterAttribute[SgrParameterAttribute["YellowBackground"] = 43] = "YellowBackground";
SgrParameterAttribute[SgrParameterAttribute["BlueBackground"] = 44] = "BlueBackground";
SgrParameterAttribute[SgrParameterAttribute["MagentaBackground"] = 45] = "MagentaBackground";
SgrParameterAttribute[SgrParameterAttribute["CyanBackground"] = 46] = "CyanBackground";
SgrParameterAttribute[SgrParameterAttribute["WhiteBackground"] = 47] = "WhiteBackground";
SgrParameterAttribute[SgrParameterAttribute["GrayBackground"] = 100] = "GrayBackground";
SgrParameterAttribute[SgrParameterAttribute["DefaultBackground"] = 49] = "DefaultBackground";
SgrParameterAttribute[SgrParameterAttribute["Bold"] = 1] = "Bold";
// On Linux, the "BoldOff" code instead causes the text to be double-underlined:
// https://en.wikipedia.org/wiki/Talk:ANSI_escape_code#SGR_21%E2%80%94%60Bold_off%60_not_widely_supported
// Use "NormalColorOrIntensity" instead
// BoldOff = 21,
SgrParameterAttribute[SgrParameterAttribute["Dim"] = 2] = "Dim";
SgrParameterAttribute[SgrParameterAttribute["NormalColorOrIntensity"] = 22] = "NormalColorOrIntensity";
SgrParameterAttribute[SgrParameterAttribute["Underline"] = 4] = "Underline";
SgrParameterAttribute[SgrParameterAttribute["UnderlineOff"] = 24] = "UnderlineOff";
SgrParameterAttribute[SgrParameterAttribute["Blink"] = 5] = "Blink";
SgrParameterAttribute[SgrParameterAttribute["BlinkOff"] = 25] = "BlinkOff";
SgrParameterAttribute[SgrParameterAttribute["InvertColor"] = 7] = "InvertColor";
SgrParameterAttribute[SgrParameterAttribute["InvertColorOff"] = 27] = "InvertColorOff";
SgrParameterAttribute[SgrParameterAttribute["Hidden"] = 8] = "Hidden";
SgrParameterAttribute[SgrParameterAttribute["HiddenOff"] = 28] = "HiddenOff";
})(SgrParameterAttribute || (exports.SgrParameterAttribute = SgrParameterAttribute = {}));
const RAINBOW_SEQUENCE = [
SgrParameterAttribute.RedForeground,
SgrParameterAttribute.YellowForeground,
SgrParameterAttribute.GreenForeground,
SgrParameterAttribute.CyanForeground,
SgrParameterAttribute.BlueForeground,
SgrParameterAttribute.MagentaForeground
];
/**
* The static functions on this class are used to produce colored text
* for use with a terminal that supports ANSI escape codes.
*
* Note that this API always generates color codes, regardless of whether
* the process's stdout is a TTY. The reason is that, in a complex program, the
* code that is generating strings often does not know were those strings will end
* up. In some cases, the same log message may get printed both to a shell
* that supports color AND to a log file that does not.
*
* @example
* ```ts
* console.log(Colorize.red('Red Text!'))
* terminal.writeLine(Colorize.green('Green Text!'), ' ', Colorize.blue('Blue Text!'));
*```
*
* @public
*/
class Colorize {
static black(text) {
return Colorize._wrapTextInAnsiEscapeCodes(SgrParameterAttribute.BlackForeground, SgrParameterAttribute.DefaultForeground, text);
}
static red(text) {
return Colorize._wrapTextInAnsiEscapeCodes(SgrParameterAttribute.RedForeground, SgrParameterAttribute.DefaultForeground, text);
}
static green(text) {
return Colorize._wrapTextInAnsiEscapeCodes(SgrParameterAttribute.GreenForeground, SgrParameterAttribute.DefaultForeground, text);
}
static yellow(text) {
return Colorize._wrapTextInAnsiEscapeCodes(SgrParameterAttribute.YellowForeground, SgrParameterAttribute.DefaultForeground, text);
}
static blue(text) {
return Colorize._wrapTextInAnsiEscapeCodes(SgrParameterAttribute.BlueForeground, SgrParameterAttribute.DefaultForeground, text);
}
static magenta(text) {
return Colorize._wrapTextInAnsiEscapeCodes(SgrParameterAttribute.MagentaForeground, SgrParameterAttribute.DefaultForeground, text);
}
static cyan(text) {
return Colorize._wrapTextInAnsiEscapeCodes(SgrParameterAttribute.CyanForeground, SgrParameterAttribute.DefaultForeground, text);
}
static white(text) {
return Colorize._wrapTextInAnsiEscapeCodes(SgrParameterAttribute.WhiteForeground, SgrParameterAttribute.DefaultForeground, text);
}
static gray(text) {
return Colorize._wrapTextInAnsiEscapeCodes(SgrParameterAttribute.GrayForeground, SgrParameterAttribute.DefaultForeground, text);
}
static blackBackground(text) {
return Colorize._wrapTextInAnsiEscapeCodes(SgrParameterAttribute.BlackBackground, SgrParameterAttribute.DefaultBackground, text);
}
static redBackground(text) {
return Colorize._wrapTextInAnsiEscapeCodes(SgrParameterAttribute.RedBackground, SgrParameterAttribute.DefaultBackground, text);
}
static greenBackground(text) {
return Colorize._wrapTextInAnsiEscapeCodes(SgrParameterAttribute.GreenBackground, SgrParameterAttribute.DefaultBackground, text);
}
static yellowBackground(text) {
return Colorize._wrapTextInAnsiEscapeCodes(SgrParameterAttribute.YellowBackground, SgrParameterAttribute.DefaultBackground, text);
}
static blueBackground(text) {
return Colorize._wrapTextInAnsiEscapeCodes(SgrParameterAttribute.BlueBackground, SgrParameterAttribute.DefaultBackground, text);
}
static magentaBackground(text) {
return Colorize._wrapTextInAnsiEscapeCodes(SgrParameterAttribute.MagentaBackground, SgrParameterAttribute.DefaultBackground, text);
}
static cyanBackground(text) {
return Colorize._wrapTextInAnsiEscapeCodes(SgrParameterAttribute.CyanBackground, SgrParameterAttribute.DefaultBackground, text);
}
static whiteBackground(text) {
return Colorize._wrapTextInAnsiEscapeCodes(SgrParameterAttribute.WhiteBackground, SgrParameterAttribute.DefaultBackground, text);
}
static grayBackground(text) {
return Colorize._wrapTextInAnsiEscapeCodes(SgrParameterAttribute.GrayBackground, SgrParameterAttribute.DefaultBackground, text);
}
static bold(text) {
return Colorize._wrapTextInAnsiEscapeCodes(SgrParameterAttribute.Bold, SgrParameterAttribute.NormalColorOrIntensity, text);
}
static dim(text) {
return Colorize._wrapTextInAnsiEscapeCodes(SgrParameterAttribute.Dim, SgrParameterAttribute.NormalColorOrIntensity, text);
}
static underline(text) {
return Colorize._wrapTextInAnsiEscapeCodes(SgrParameterAttribute.Underline, SgrParameterAttribute.UnderlineOff, text);
}
static blink(text) {
return Colorize._wrapTextInAnsiEscapeCodes(SgrParameterAttribute.Blink, SgrParameterAttribute.BlinkOff, text);
}
static invertColor(text) {
return Colorize._wrapTextInAnsiEscapeCodes(SgrParameterAttribute.InvertColor, SgrParameterAttribute.InvertColorOff, text);
}
static hidden(text) {
return Colorize._wrapTextInAnsiEscapeCodes(SgrParameterAttribute.Hidden, SgrParameterAttribute.HiddenOff, text);
}
static rainbow(text) {
return Colorize._applyColorSequence(text, RAINBOW_SEQUENCE);
}
static _applyColorSequence(text, sequence) {
let result = '';
const sequenceLength = sequence.length;
for (let i = 0; i < text.length; i++) {
result += AnsiEscape_1.AnsiEscape.getEscapeSequenceForAnsiCode(sequence[i % sequenceLength]) + text[i];
}
return result + AnsiEscape_1.AnsiEscape.getEscapeSequenceForAnsiCode(SgrParameterAttribute.DefaultForeground);
}
static _wrapTextInAnsiEscapeCodes(startCode, endCode, text) {
return (AnsiEscape_1.AnsiEscape.getEscapeSequenceForAnsiCode(startCode) +
text +
AnsiEscape_1.AnsiEscape.getEscapeSequenceForAnsiCode(endCode));
}
}
exports.Colorize = Colorize;
//# sourceMappingURL=Colorize.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,49 @@
import { type ITerminalProvider, TerminalProviderSeverity } from './ITerminalProvider';
/**
* Options to be provided to a {@link ConsoleTerminalProvider}
*
* @beta
*/
export interface IConsoleTerminalProviderOptions {
/**
* If true, print verbose logging messages.
*/
verboseEnabled: boolean;
/**
* If true, print debug logging messages. Note that "verbose" and "debug" are considered
* separate message filters; if you want debug to imply verbose, it is up to your
* application code to enforce that.
*/
debugEnabled: boolean;
}
/**
* Terminal provider that prints to STDOUT (for log- and verbose-level messages) and
* STDERR (for warning- and error-level messages).
*
* @beta
*/
export declare class ConsoleTerminalProvider implements ITerminalProvider {
static readonly supportsColor: boolean;
/**
* If true, verbose-level messages should be written to the console.
*/
verboseEnabled: boolean;
/**
* If true, debug-level messages should be written to the console.
*/
debugEnabled: boolean;
/**
* {@inheritDoc ITerminalProvider.supportsColor}
*/
readonly supportsColor: boolean;
constructor(options?: Partial<IConsoleTerminalProviderOptions>);
/**
* {@inheritDoc ITerminalProvider.write}
*/
write(data: string, severity: TerminalProviderSeverity): void;
/**
* {@inheritDoc ITerminalProvider.eolCharacter}
*/
get eolCharacter(): string;
}
//# sourceMappingURL=ConsoleTerminalProvider.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ConsoleTerminalProvider.d.ts","sourceRoot":"","sources":["../src/ConsoleTerminalProvider.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,KAAK,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAEvF;;;;GAIG;AACH,MAAM,WAAW,+BAA+B;IAC9C;;OAEG;IACH,cAAc,EAAE,OAAO,CAAC;IAExB;;;;OAIG;IACH,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;;;;GAKG;AACH,qBAAa,uBAAwB,YAAW,iBAAiB;IAC/D,gBAAuB,aAAa,EAAE,OAAO,CAAoD;IAEjG;;OAEG;IACI,cAAc,EAAE,OAAO,CAAC;IAE/B;;OAEG;IACI,YAAY,EAAE,OAAO,CAAC;IAE7B;;OAEG;IACH,SAAgB,aAAa,EAAE,OAAO,CAAyC;gBAE5D,OAAO,GAAE,OAAO,CAAC,+BAA+B,CAAM;IAKzE;;OAEG;IACI,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,wBAAwB,GAAG,IAAI;IA8BpE;;OAEG;IACH,IAAW,YAAY,IAAI,MAAM,CAEhC;CACF"}

View File

@@ -0,0 +1,65 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConsoleTerminalProvider = void 0;
const os_1 = require("os");
const supports_color_1 = __importDefault(require("supports-color"));
const ITerminalProvider_1 = require("./ITerminalProvider");
/**
* Terminal provider that prints to STDOUT (for log- and verbose-level messages) and
* STDERR (for warning- and error-level messages).
*
* @beta
*/
class ConsoleTerminalProvider {
constructor(options = {}) {
/**
* {@inheritDoc ITerminalProvider.supportsColor}
*/
this.supportsColor = ConsoleTerminalProvider.supportsColor;
this.verboseEnabled = !!options.verboseEnabled;
this.debugEnabled = !!options.debugEnabled;
}
/**
* {@inheritDoc ITerminalProvider.write}
*/
write(data, severity) {
switch (severity) {
case ITerminalProvider_1.TerminalProviderSeverity.warning:
case ITerminalProvider_1.TerminalProviderSeverity.error: {
process.stderr.write(data);
break;
}
case ITerminalProvider_1.TerminalProviderSeverity.verbose: {
if (this.verboseEnabled) {
process.stdout.write(data);
}
break;
}
case ITerminalProvider_1.TerminalProviderSeverity.debug: {
if (this.debugEnabled) {
process.stdout.write(data);
}
break;
}
case ITerminalProvider_1.TerminalProviderSeverity.log:
default: {
process.stdout.write(data);
break;
}
}
}
/**
* {@inheritDoc ITerminalProvider.eolCharacter}
*/
get eolCharacter() {
return os_1.EOL;
}
}
exports.ConsoleTerminalProvider = ConsoleTerminalProvider;
ConsoleTerminalProvider.supportsColor = !!supports_color_1.default.stdout && !!supports_color_1.default.stderr;
//# sourceMappingURL=ConsoleTerminalProvider.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ConsoleTerminalProvider.js","sourceRoot":"","sources":["../src/ConsoleTerminalProvider.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;;;;AAE3D,2BAAyB;AACzB,oEAA2C;AAE3C,2DAAuF;AAqBvF;;;;;GAKG;AACH,MAAa,uBAAuB;IAkBlC,YAAmB,UAAoD,EAAE;QALzE;;WAEG;QACa,kBAAa,GAAY,uBAAuB,CAAC,aAAa,CAAC;QAG7E,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC;QAC/C,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC;IAC7C,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,IAAY,EAAE,QAAkC;QAC3D,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,4CAAwB,CAAC,OAAO,CAAC;YACtC,KAAK,4CAAwB,CAAC,KAAK,CAAC,CAAC,CAAC;gBACpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC3B,MAAM;YACR,CAAC;YAED,KAAK,4CAAwB,CAAC,OAAO,CAAC,CAAC,CAAC;gBACtC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;oBACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC7B,CAAC;gBACD,MAAM;YACR,CAAC;YAED,KAAK,4CAAwB,CAAC,KAAK,CAAC,CAAC,CAAC;gBACpC,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;oBACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC7B,CAAC;gBACD,MAAM;YACR,CAAC;YAED,KAAK,4CAAwB,CAAC,GAAG,CAAC;YAClC,OAAO,CAAC,CAAC,CAAC;gBACR,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC3B,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACH,IAAW,YAAY;QACrB,OAAO,QAAG,CAAC;IACb,CAAC;;AA7DH,0DA8DC;AA7DwB,qCAAa,GAAY,CAAC,CAAC,wBAAa,CAAC,MAAM,IAAI,CAAC,CAAC,wBAAa,CAAC,MAAM,AAA5D,CAA6D","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 { EOL } from 'os';\nimport supportsColor from 'supports-color';\n\nimport { type ITerminalProvider, TerminalProviderSeverity } from './ITerminalProvider';\n\n/**\n * Options to be provided to a {@link ConsoleTerminalProvider}\n *\n * @beta\n */\nexport interface IConsoleTerminalProviderOptions {\n /**\n * If true, print verbose logging messages.\n */\n verboseEnabled: boolean;\n\n /**\n * If true, print debug logging messages. Note that \"verbose\" and \"debug\" are considered\n * separate message filters; if you want debug to imply verbose, it is up to your\n * application code to enforce that.\n */\n debugEnabled: boolean;\n}\n\n/**\n * Terminal provider that prints to STDOUT (for log- and verbose-level messages) and\n * STDERR (for warning- and error-level messages).\n *\n * @beta\n */\nexport class ConsoleTerminalProvider implements ITerminalProvider {\n public static readonly supportsColor: boolean = !!supportsColor.stdout && !!supportsColor.stderr;\n\n /**\n * If true, verbose-level messages should be written to the console.\n */\n public verboseEnabled: boolean;\n\n /**\n * If true, debug-level messages should be written to the console.\n */\n public debugEnabled: boolean;\n\n /**\n * {@inheritDoc ITerminalProvider.supportsColor}\n */\n public readonly supportsColor: boolean = ConsoleTerminalProvider.supportsColor;\n\n public constructor(options: Partial<IConsoleTerminalProviderOptions> = {}) {\n this.verboseEnabled = !!options.verboseEnabled;\n this.debugEnabled = !!options.debugEnabled;\n }\n\n /**\n * {@inheritDoc ITerminalProvider.write}\n */\n public write(data: string, severity: TerminalProviderSeverity): void {\n switch (severity) {\n case TerminalProviderSeverity.warning:\n case TerminalProviderSeverity.error: {\n process.stderr.write(data);\n break;\n }\n\n case TerminalProviderSeverity.verbose: {\n if (this.verboseEnabled) {\n process.stdout.write(data);\n }\n break;\n }\n\n case TerminalProviderSeverity.debug: {\n if (this.debugEnabled) {\n process.stdout.write(data);\n }\n break;\n }\n\n case TerminalProviderSeverity.log:\n default: {\n process.stdout.write(data);\n break;\n }\n }\n }\n\n /**\n * {@inheritDoc ITerminalProvider.eolCharacter}\n */\n public get eolCharacter(): string {\n return EOL;\n }\n}\n"]}

View File

@@ -0,0 +1,55 @@
import { type ITerminalChunk } from './ITerminalChunk';
import { TerminalTransform, type ITerminalTransformOptions } from './TerminalTransform';
/**
* Constructor options for {@link DiscardStdoutTransform}
*
* @beta
*/
export interface IDiscardStdoutTransformOptions extends ITerminalTransformOptions {
}
/**
* `DiscardStdoutTransform` discards `stdout` chunks while fixing up malformed `stderr` lines.
*
* @remarks
* Suppose that a poorly behaved process produces output like this:
*
* ```ts
* process.stdout.write('Starting operation...\n');
* process.stderr.write('An error occurred');
* process.stdout.write('\nFinishing up\n');
* process.stderr.write('The process completed with errors\n');
* ```
*
* When `stdout` and `stderr` are combined on the console, the mistake in the output would not be noticeable:
* ```
* Starting operation...
* An error occurred
* Finishing up
* The process completed with errors
* ```
*
* However, if we discard `stdout`, then `stderr` is missing a newline:
* ```
* An error occurredThe process completed with errors
* ```
*
* Tooling scripts can introduce these sorts of problems via edge cases that are difficult to find and fix.
* `DiscardStdoutTransform` can discard the `stdout` stream and fix up `stderr`:
*
* ```
* An error occurred
* The process completed with errors
* ```
*
* @privateRemarks
* This class is experimental and marked as `@beta`. The algorithm may need some fine-tuning, or there may
* be better solutions to this problem.
*
* @beta
*/
export declare class DiscardStdoutTransform extends TerminalTransform {
private _state;
constructor(options: IDiscardStdoutTransformOptions);
protected onWriteChunk(chunk: ITerminalChunk): void;
}
//# sourceMappingURL=DiscardStdoutTransform.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"DiscardStdoutTransform.d.ts","sourceRoot":"","sources":["../src/DiscardStdoutTransform.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,cAAc,EAAqB,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,KAAK,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAExF;;;;GAIG;AACH,MAAM,WAAW,8BAA+B,SAAQ,yBAAyB;CAAG;AAQpF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,qBAAa,sBAAuB,SAAQ,iBAAiB;IAC3D,OAAO,CAAC,MAAM,CAAQ;gBAEH,OAAO,EAAE,8BAA8B;IAM1D,SAAS,CAAC,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;CAgCpD"}

View File

@@ -0,0 +1,94 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.DiscardStdoutTransform = void 0;
const ITerminalChunk_1 = require("./ITerminalChunk");
const TerminalTransform_1 = require("./TerminalTransform");
var State;
(function (State) {
State[State["Okay"] = 0] = "Okay";
State[State["StderrFragment"] = 1] = "StderrFragment";
State[State["InsertLinefeed"] = 2] = "InsertLinefeed";
})(State || (State = {}));
/**
* `DiscardStdoutTransform` discards `stdout` chunks while fixing up malformed `stderr` lines.
*
* @remarks
* Suppose that a poorly behaved process produces output like this:
*
* ```ts
* process.stdout.write('Starting operation...\n');
* process.stderr.write('An error occurred');
* process.stdout.write('\nFinishing up\n');
* process.stderr.write('The process completed with errors\n');
* ```
*
* When `stdout` and `stderr` are combined on the console, the mistake in the output would not be noticeable:
* ```
* Starting operation...
* An error occurred
* Finishing up
* The process completed with errors
* ```
*
* However, if we discard `stdout`, then `stderr` is missing a newline:
* ```
* An error occurredThe process completed with errors
* ```
*
* Tooling scripts can introduce these sorts of problems via edge cases that are difficult to find and fix.
* `DiscardStdoutTransform` can discard the `stdout` stream and fix up `stderr`:
*
* ```
* An error occurred
* The process completed with errors
* ```
*
* @privateRemarks
* This class is experimental and marked as `@beta`. The algorithm may need some fine-tuning, or there may
* be better solutions to this problem.
*
* @beta
*/
class DiscardStdoutTransform extends TerminalTransform_1.TerminalTransform {
constructor(options) {
super(options);
this._state = State.Okay;
}
onWriteChunk(chunk) {
if (chunk.text.indexOf('\r') >= 0) {
throw new Error('DiscardStdoutTransform expects chunks with normalized newlines');
}
if (chunk.kind === ITerminalChunk_1.TerminalChunkKind.Stdout) {
if (this._state === State.StderrFragment) {
if (chunk.text.indexOf('\n') >= 0) {
this._state = State.InsertLinefeed;
}
}
}
else if (chunk.kind === ITerminalChunk_1.TerminalChunkKind.Stderr) {
let correctedText;
if (this._state === State.InsertLinefeed) {
correctedText = '\n' + chunk.text;
}
else {
correctedText = chunk.text;
}
this.destination.writeChunk({ kind: ITerminalChunk_1.TerminalChunkKind.Stderr, text: correctedText });
if (correctedText.length > 0) {
if (correctedText[correctedText.length - 1] === '\n') {
this._state = State.Okay;
}
else {
this._state = State.StderrFragment;
}
}
}
else {
this.destination.writeChunk(chunk);
}
}
}
exports.DiscardStdoutTransform = DiscardStdoutTransform;
//# sourceMappingURL=DiscardStdoutTransform.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"DiscardStdoutTransform.js","sourceRoot":"","sources":["../src/DiscardStdoutTransform.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,qDAA0E;AAC1E,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,KAAK,kCAAiB,CAAC,MAAM,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,KAAK,kCAAiB,CAAC,MAAM,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,EAAE,kCAAiB,CAAC,MAAM,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"]}

View File

@@ -0,0 +1,81 @@
import type { ITerminalProvider } from './ITerminalProvider';
/**
* @beta
*/
export interface ITerminalWriteOptions {
/**
* If set to true, SGR parameters will not be replaced by the terminal
* standard (i.e. - red for errors, yellow for warnings).
*/
doNotOverrideSgrCodes?: boolean;
}
/**
* @beta
*/
export type TerminalWriteParameters = string[] | [...string[], ITerminalWriteOptions];
/**
* @beta
*/
export interface ITerminal {
/**
* Subscribe a new terminal provider.
*/
registerProvider(provider: ITerminalProvider): void;
/**
* Unsubscribe a terminal provider. If the provider isn't subscribed, this function does nothing.
*/
unregisterProvider(provider: ITerminalProvider): void;
/**
* Write a generic message to the terminal
*/
write(...messageParts: TerminalWriteParameters): void;
/**
* Write a generic message to the terminal, followed by a newline
*/
writeLine(...messageParts: TerminalWriteParameters): void;
/**
* Write a warning message to the console with yellow text.
*
* @remarks
* The yellow color takes precedence over any other foreground colors set.
*/
writeWarning(...messageParts: TerminalWriteParameters): void;
/**
* Write a warning message to the console with yellow text, followed by a newline.
*
* @remarks
* The yellow color takes precedence over any other foreground colors set.
*/
writeWarningLine(...messageParts: TerminalWriteParameters): void;
/**
* Write an error message to the console with red text.
*
* @remarks
* The red color takes precedence over any other foreground colors set.
*/
writeError(...messageParts: TerminalWriteParameters): void;
/**
* Write an error message to the console with red text, followed by a newline.
*
* @remarks
* The red color takes precedence over any other foreground colors set.
*/
writeErrorLine(...messageParts: TerminalWriteParameters): void;
/**
* Write a verbose-level message.
*/
writeVerbose(...messageParts: TerminalWriteParameters): void;
/**
* Write a verbose-level message followed by a newline.
*/
writeVerboseLine(...messageParts: TerminalWriteParameters): void;
/**
* Write a debug-level message.
*/
writeDebug(...messageParts: TerminalWriteParameters): void;
/**
* Write a debug-level message followed by a newline.
*/
writeDebugLine(...messageParts: TerminalWriteParameters): void;
}
//# sourceMappingURL=ITerminal.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ITerminal.d.ts","sourceRoot":"","sources":["../src/ITerminal.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,EAAE,EAAE,qBAAqB,CAAC,CAAC;AAEtF;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAEpD;;OAEG;IACH,kBAAkB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAEtD;;OAEG;IACH,KAAK,CAAC,GAAG,YAAY,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAEtD;;OAEG;IACH,SAAS,CAAC,GAAG,YAAY,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAE1D;;;;;OAKG;IACH,YAAY,CAAC,GAAG,YAAY,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAE7D;;;;;OAKG;IACH,gBAAgB,CAAC,GAAG,YAAY,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAEjE;;;;;OAKG;IACH,UAAU,CAAC,GAAG,YAAY,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAE3D;;;;;OAKG;IACH,cAAc,CAAC,GAAG,YAAY,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAE/D;;OAEG;IACH,YAAY,CAAC,GAAG,YAAY,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAE7D;;OAEG;IACH,gBAAgB,CAAC,GAAG,YAAY,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAEjE;;OAEG;IACH,UAAU,CAAC,GAAG,YAAY,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAE3D;;OAEG;IACH,cAAc,CAAC,GAAG,YAAY,EAAE,uBAAuB,GAAG,IAAI,CAAC;CAChE"}

View File

@@ -0,0 +1,5 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=ITerminal.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ITerminal.js","sourceRoot":"","sources":["../src/ITerminal.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D","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 { ITerminalProvider } from './ITerminalProvider';\n\n/**\n * @beta\n */\nexport interface ITerminalWriteOptions {\n /**\n * If set to true, SGR parameters will not be replaced by the terminal\n * standard (i.e. - red for errors, yellow for warnings).\n */\n doNotOverrideSgrCodes?: boolean;\n}\n\n/**\n * @beta\n */\nexport type TerminalWriteParameters = string[] | [...string[], ITerminalWriteOptions];\n\n/**\n * @beta\n */\nexport interface ITerminal {\n /**\n * Subscribe a new terminal provider.\n */\n registerProvider(provider: ITerminalProvider): void;\n\n /**\n * Unsubscribe a terminal provider. If the provider isn't subscribed, this function does nothing.\n */\n unregisterProvider(provider: ITerminalProvider): void;\n\n /**\n * Write a generic message to the terminal\n */\n write(...messageParts: TerminalWriteParameters): void;\n\n /**\n * Write a generic message to the terminal, followed by a newline\n */\n writeLine(...messageParts: TerminalWriteParameters): void;\n\n /**\n * Write a warning message to the console with yellow text.\n *\n * @remarks\n * The yellow color takes precedence over any other foreground colors set.\n */\n writeWarning(...messageParts: TerminalWriteParameters): void;\n\n /**\n * Write a warning message to the console with yellow text, followed by a newline.\n *\n * @remarks\n * The yellow color takes precedence over any other foreground colors set.\n */\n writeWarningLine(...messageParts: TerminalWriteParameters): void;\n\n /**\n * Write an error message to the console with red text.\n *\n * @remarks\n * The red color takes precedence over any other foreground colors set.\n */\n writeError(...messageParts: TerminalWriteParameters): void;\n\n /**\n * Write an error message to the console with red text, followed by a newline.\n *\n * @remarks\n * The red color takes precedence over any other foreground colors set.\n */\n writeErrorLine(...messageParts: TerminalWriteParameters): void;\n\n /**\n * Write a verbose-level message.\n */\n writeVerbose(...messageParts: TerminalWriteParameters): void;\n\n /**\n * Write a verbose-level message followed by a newline.\n */\n writeVerboseLine(...messageParts: TerminalWriteParameters): void;\n\n /**\n * Write a debug-level message.\n */\n writeDebug(...messageParts: TerminalWriteParameters): void;\n\n /**\n * Write a debug-level message followed by a newline.\n */\n writeDebugLine(...messageParts: TerminalWriteParameters): void;\n}\n"]}

View File

@@ -0,0 +1,45 @@
/**
* Specifies the kind of data represented by a {@link ITerminalChunk} object.
* @public
*/
export declare enum TerminalChunkKind {
/**
* Indicates a `ITerminalChunk` object representing `stdout` console output.
*/
Stdout = "O",
/**
* Indicates a `ITerminalChunk` object representing `stderr` console output.
*/
Stderr = "E"
}
/**
* Represents a chunk of output that will ultimately be written to a {@link TerminalWritable}.
*
* @remarks
* Today `ITerminalChunk` represents the `stdout` and `stderr` text streams. In the future,
* we plan to expand it to include other console UI elements such as instructions for displaying
* an interactive progress bar. We may also add other metadata, for example tracking whether
* the `text` string is known to contain color codes or not.
*
* The `ITerminalChunk` object should be considered to be immutable once it is created.
* For example, {@link SplitterTransform} may pass the same chunk to multiple destinations.
*
* @public
*/
export interface ITerminalChunk {
/**
* Indicates the kind of information stored in this chunk.
*
* @remarks
* More kinds will be introduced in the future. Implementors of
* {@link TerminalWritable.onWriteChunk} should ignore unrecognized `TerminalChunkKind`
* values. `TerminalTransform` implementors should pass along unrecognized chunks
* rather than discarding them.
*/
kind: TerminalChunkKind;
/**
* The next chunk of text from the `stderr` or `stdout` stream.
*/
text: string;
}
//# sourceMappingURL=ITerminalChunk.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ITerminalChunk.d.ts","sourceRoot":"","sources":["../src/ITerminalChunk.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,oBAAY,iBAAiB;IAC3B;;OAEG;IACH,MAAM,MAAM;IAEZ;;OAEG;IACH,MAAM,MAAM;CACb;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;;;OAQG;IACH,IAAI,EAAE,iBAAiB,CAAC;IAExB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;CACd"}

View File

@@ -0,0 +1,21 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.TerminalChunkKind = void 0;
/**
* Specifies the kind of data represented by a {@link ITerminalChunk} object.
* @public
*/
var TerminalChunkKind;
(function (TerminalChunkKind) {
/**
* Indicates a `ITerminalChunk` object representing `stdout` console output.
*/
TerminalChunkKind["Stdout"] = "O";
/**
* Indicates a `ITerminalChunk` object representing `stderr` console output.
*/
TerminalChunkKind["Stderr"] = "E";
})(TerminalChunkKind || (exports.TerminalChunkKind = TerminalChunkKind = {}));
//# sourceMappingURL=ITerminalChunk.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ITerminalChunk.js","sourceRoot":"","sources":["../src/ITerminalChunk.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D;;;GAGG;AACH,IAAY,iBAUX;AAVD,WAAY,iBAAiB;IAC3B;;OAEG;IACH,iCAAY,CAAA;IAEZ;;OAEG;IACH,iCAAY,CAAA;AACd,CAAC,EAVW,iBAAiB,iCAAjB,iBAAiB,QAU5B","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\n/**\n * Specifies the kind of data represented by a {@link ITerminalChunk} object.\n * @public\n */\nexport enum TerminalChunkKind {\n /**\n * Indicates a `ITerminalChunk` object representing `stdout` console output.\n */\n Stdout = 'O',\n\n /**\n * Indicates a `ITerminalChunk` object representing `stderr` console output.\n */\n Stderr = 'E'\n}\n\n/**\n * Represents a chunk of output that will ultimately be written to a {@link TerminalWritable}.\n *\n * @remarks\n * Today `ITerminalChunk` represents the `stdout` and `stderr` text streams. In the future,\n * we plan to expand it to include other console UI elements such as instructions for displaying\n * an interactive progress bar. We may also add other metadata, for example tracking whether\n * the `text` string is known to contain color codes or not.\n *\n * The `ITerminalChunk` object should be considered to be immutable once it is created.\n * For example, {@link SplitterTransform} may pass the same chunk to multiple destinations.\n *\n * @public\n */\nexport interface ITerminalChunk {\n /**\n * Indicates the kind of information stored in this chunk.\n *\n * @remarks\n * More kinds will be introduced in the future. Implementors of\n * {@link TerminalWritable.onWriteChunk} should ignore unrecognized `TerminalChunkKind`\n * values. `TerminalTransform` implementors should pass along unrecognized chunks\n * rather than discarding them.\n */\n kind: TerminalChunkKind;\n\n /**\n * The next chunk of text from the `stderr` or `stdout` stream.\n */\n text: string;\n}\n"]}

View File

@@ -0,0 +1,54 @@
/**
* Similar to many popular logging packages, terminal providers support a range of message
* severities. These severities have built-in formatting defaults in the Terminal object
* (warnings are yellow, errors are red, etc.).
*
* Terminal providers may choose to suppress certain messages based on their severity,
* or to route some messages to other providers or not based on severity.
*
* Severity | Purpose
* --------- | -------
* error | Build errors and fatal issues
* warning | Not necessarily fatal, but indicate a problem the user should fix
* log | Informational messages
* verbose | Additional information that may not always be necessary
* debug | Highest detail level, best used for troubleshooting information
*
* @beta
*/
export declare enum TerminalProviderSeverity {
log = 0,
warning = 1,
error = 2,
verbose = 3,
debug = 4
}
/**
* Implement the interface to create a terminal provider. Terminal providers
* can be registered to a {@link Terminal} instance to receive messages.
*
* @beta
*/
export interface ITerminalProvider {
/**
* This property should return true only if the terminal provider supports
* rendering console colors.
*/
supportsColor: boolean;
/**
* This property should return the newline character the terminal provider
* expects.
*/
eolCharacter: string;
/**
* This function gets called on every terminal provider upon every
* message function call on the terminal instance.
*
* @param data - The terminal message.
* @param severity - The message severity. Terminal providers can
* route different kinds of messages to different streams and may choose
* to ignore verbose or debug messages.
*/
write(data: string, severity: TerminalProviderSeverity): void;
}
//# sourceMappingURL=ITerminalProvider.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ITerminalProvider.d.ts","sourceRoot":"","sources":["../src/ITerminalProvider.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;GAiBG;AACH,oBAAY,wBAAwB;IAClC,GAAG,IAAA;IACH,OAAO,IAAA;IACP,KAAK,IAAA;IACL,OAAO,IAAA;IACP,KAAK,IAAA;CACN;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,aAAa,EAAE,OAAO,CAAC;IAEvB;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;;;;;;;OAQG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,wBAAwB,GAAG,IAAI,CAAC;CAC/D"}

View File

@@ -0,0 +1,32 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.TerminalProviderSeverity = void 0;
/**
* Similar to many popular logging packages, terminal providers support a range of message
* severities. These severities have built-in formatting defaults in the Terminal object
* (warnings are yellow, errors are red, etc.).
*
* Terminal providers may choose to suppress certain messages based on their severity,
* or to route some messages to other providers or not based on severity.
*
* Severity | Purpose
* --------- | -------
* error | Build errors and fatal issues
* warning | Not necessarily fatal, but indicate a problem the user should fix
* log | Informational messages
* verbose | Additional information that may not always be necessary
* debug | Highest detail level, best used for troubleshooting information
*
* @beta
*/
var TerminalProviderSeverity;
(function (TerminalProviderSeverity) {
TerminalProviderSeverity[TerminalProviderSeverity["log"] = 0] = "log";
TerminalProviderSeverity[TerminalProviderSeverity["warning"] = 1] = "warning";
TerminalProviderSeverity[TerminalProviderSeverity["error"] = 2] = "error";
TerminalProviderSeverity[TerminalProviderSeverity["verbose"] = 3] = "verbose";
TerminalProviderSeverity[TerminalProviderSeverity["debug"] = 4] = "debug";
})(TerminalProviderSeverity || (exports.TerminalProviderSeverity = TerminalProviderSeverity = {}));
//# sourceMappingURL=ITerminalProvider.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"ITerminalProvider.js","sourceRoot":"","sources":["../src/ITerminalProvider.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D;;;;;;;;;;;;;;;;;GAiBG;AACH,IAAY,wBAMX;AAND,WAAY,wBAAwB;IAClC,qEAAG,CAAA;IACH,6EAAO,CAAA;IACP,yEAAK,CAAA;IACL,6EAAO,CAAA;IACP,yEAAK,CAAA;AACP,CAAC,EANW,wBAAwB,wCAAxB,wBAAwB,QAMnC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\n/**\n * Similar to many popular logging packages, terminal providers support a range of message\n * severities. These severities have built-in formatting defaults in the Terminal object\n * (warnings are yellow, errors are red, etc.).\n *\n * Terminal providers may choose to suppress certain messages based on their severity,\n * or to route some messages to other providers or not based on severity.\n *\n * Severity | Purpose\n * --------- | -------\n * error | Build errors and fatal issues\n * warning | Not necessarily fatal, but indicate a problem the user should fix\n * log | Informational messages\n * verbose | Additional information that may not always be necessary\n * debug | Highest detail level, best used for troubleshooting information\n *\n * @beta\n */\nexport enum TerminalProviderSeverity {\n log,\n warning,\n error,\n verbose,\n debug\n}\n\n/**\n * Implement the interface to create a terminal provider. Terminal providers\n * can be registered to a {@link Terminal} instance to receive messages.\n *\n * @beta\n */\nexport interface ITerminalProvider {\n /**\n * This property should return true only if the terminal provider supports\n * rendering console colors.\n */\n supportsColor: boolean;\n\n /**\n * This property should return the newline character the terminal provider\n * expects.\n */\n eolCharacter: string;\n\n /**\n * This function gets called on every terminal provider upon every\n * message function call on the terminal instance.\n *\n * @param data - The terminal message.\n * @param severity - The message severity. Terminal providers can\n * route different kinds of messages to different streams and may choose\n * to ignore verbose or debug messages.\n */\n write(data: string, severity: TerminalProviderSeverity): void;\n}\n"]}

View File

@@ -0,0 +1,15 @@
import type { ITerminalChunk } from './ITerminalChunk';
import { TerminalWritable } from './TerminalWritable';
/**
* A {@link TerminalWritable} subclass for use by unit tests.
*
* @beta
*/
export declare class MockWritable extends TerminalWritable {
readonly chunks: ITerminalChunk[];
protected onWriteChunk(chunk: ITerminalChunk): void;
reset(): void;
getAllOutput(): string;
getFormattedChunks(): ITerminalChunk[];
}
//# sourceMappingURL=MockWritable.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"MockWritable.d.ts","sourceRoot":"","sources":["../src/MockWritable.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;;GAIG;AACH,qBAAa,YAAa,SAAQ,gBAAgB;IAChD,SAAgB,MAAM,EAAE,cAAc,EAAE,CAAM;IAE9C,SAAS,CAAC,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IAI5C,KAAK,IAAI,IAAI;IAIb,YAAY,IAAI,MAAM;IAItB,kBAAkB,IAAI,cAAc,EAAE;CAG9C"}

View File

@@ -0,0 +1,32 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.MockWritable = void 0;
const AnsiEscape_1 = require("./AnsiEscape");
const TerminalWritable_1 = require("./TerminalWritable");
/**
* A {@link TerminalWritable} subclass for use by unit tests.
*
* @beta
*/
class MockWritable extends TerminalWritable_1.TerminalWritable {
constructor() {
super(...arguments);
this.chunks = [];
}
onWriteChunk(chunk) {
this.chunks.push(chunk);
}
reset() {
this.chunks.length = 0;
}
getAllOutput() {
return AnsiEscape_1.AnsiEscape.formatForTests(this.chunks.map((x) => x.text).join(''));
}
getFormattedChunks() {
return this.chunks.map((x) => (Object.assign(Object.assign({}, x), { text: AnsiEscape_1.AnsiEscape.formatForTests(x.text) })));
}
}
exports.MockWritable = MockWritable;
//# sourceMappingURL=MockWritable.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"MockWritable.js","sourceRoot":"","sources":["../src/MockWritable.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,6CAA0C;AAE1C,yDAAsD;AAEtD;;;;GAIG;AACH,MAAa,YAAa,SAAQ,mCAAgB;IAAlD;;QACkB,WAAM,GAAqB,EAAE,CAAC;IAiBhD,CAAC;IAfW,YAAY,CAAC,KAAqB;QAC1C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;IAEM,KAAK;QACV,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IACzB,CAAC;IAEM,YAAY;QACjB,OAAO,uBAAU,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5E,CAAC;IAEM,kBAAkB;QACvB,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iCAAM,CAAC,KAAE,IAAI,EAAE,uBAAU,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,IAAqB,CAAC,CAAC;IACvG,CAAC;CACF;AAlBD,oCAkBC","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 './AnsiEscape';\nimport type { ITerminalChunk } from './ITerminalChunk';\nimport { TerminalWritable } from './TerminalWritable';\n\n/**\n * A {@link TerminalWritable} subclass for use by unit tests.\n *\n * @beta\n */\nexport class MockWritable extends TerminalWritable {\n public readonly chunks: ITerminalChunk[] = [];\n\n protected onWriteChunk(chunk: ITerminalChunk): void {\n this.chunks.push(chunk);\n }\n\n public reset(): void {\n this.chunks.length = 0;\n }\n\n public getAllOutput(): string {\n return AnsiEscape.formatForTests(this.chunks.map((x) => x.text).join(''));\n }\n\n public getFormattedChunks(): ITerminalChunk[] {\n return this.chunks.map((x) => ({ ...x, text: AnsiEscape.formatForTests(x.text) }) as ITerminalChunk);\n }\n}\n"]}

View File

@@ -0,0 +1,23 @@
import type { ITerminalProvider, TerminalProviderSeverity } from './ITerminalProvider';
/**
* Terminal provider that stores written data in buffers separated by severity.
* This terminal provider is designed to be used when code that prints to a terminal
* is being unit tested.
*
* @beta
*/
export declare class NoOpTerminalProvider implements ITerminalProvider {
/**
* {@inheritDoc ITerminalProvider.write}
*/
write(data: string, severity: TerminalProviderSeverity): void;
/**
* {@inheritDoc ITerminalProvider.eolCharacter}
*/
get eolCharacter(): string;
/**
* {@inheritDoc ITerminalProvider.supportsColor}
*/
get supportsColor(): boolean;
}
//# sourceMappingURL=NoOpTerminalProvider.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"NoOpTerminalProvider.d.ts","sourceRoot":"","sources":["../src/NoOpTerminalProvider.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAEvF;;;;;;GAMG;AACH,qBAAa,oBAAqB,YAAW,iBAAiB;IAC5D;;OAEG;IACI,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,wBAAwB,GAAG,IAAI;IAIpE;;OAEG;IACH,IAAW,YAAY,IAAI,MAAM,CAEhC;IAED;;OAEG;IACH,IAAW,aAAa,IAAI,OAAO,CAElC;CACF"}

View File

@@ -0,0 +1,34 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.NoOpTerminalProvider = void 0;
/**
* Terminal provider that stores written data in buffers separated by severity.
* This terminal provider is designed to be used when code that prints to a terminal
* is being unit tested.
*
* @beta
*/
class NoOpTerminalProvider {
/**
* {@inheritDoc ITerminalProvider.write}
*/
write(data, severity) {
// no-op
}
/**
* {@inheritDoc ITerminalProvider.eolCharacter}
*/
get eolCharacter() {
return '\n';
}
/**
* {@inheritDoc ITerminalProvider.supportsColor}
*/
get supportsColor() {
return false;
}
}
exports.NoOpTerminalProvider = NoOpTerminalProvider;
//# sourceMappingURL=NoOpTerminalProvider.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"NoOpTerminalProvider.js","sourceRoot":"","sources":["../src/NoOpTerminalProvider.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAI3D;;;;;;GAMG;AACH,MAAa,oBAAoB;IAC/B;;OAEG;IACI,KAAK,CAAC,IAAY,EAAE,QAAkC;QAC3D,QAAQ;IACV,CAAC;IAED;;OAEG;IACH,IAAW,YAAY;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,IAAW,aAAa;QACtB,OAAO,KAAK,CAAC;IACf,CAAC;CACF;AArBD,oDAqBC","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 { ITerminalProvider, TerminalProviderSeverity } from './ITerminalProvider';\n\n/**\n * Terminal provider that stores written data in buffers separated by severity.\n * This terminal provider is designed to be used when code that prints to a terminal\n * is being unit tested.\n *\n * @beta\n */\nexport class NoOpTerminalProvider implements ITerminalProvider {\n /**\n * {@inheritDoc ITerminalProvider.write}\n */\n public write(data: string, severity: TerminalProviderSeverity): void {\n // no-op\n }\n\n /**\n * {@inheritDoc ITerminalProvider.eolCharacter}\n */\n public get eolCharacter(): string {\n return '\\n';\n }\n\n /**\n * {@inheritDoc ITerminalProvider.supportsColor}\n */\n public get supportsColor(): boolean {\n return false;\n }\n}\n"]}

View File

@@ -0,0 +1,43 @@
import { type NewlineKind } from '@rushstack/node-core-library';
import { TextRewriter, type TextRewriterState } from './TextRewriter';
/**
* Constructor options for {@link NormalizeNewlinesTextRewriter}
*
* @public
*/
export interface INormalizeNewlinesTextRewriterOptions {
/**
* Specifies how newlines should be represented in the output stream.
*/
newlineKind: NewlineKind;
/**
* If `true`, then `NormalizeNewlinesTextRewriter.close()` will append a newline to
* the output if it ends with an incomplete line.
*
* @remarks
* If the output is an empty string, then a newline will NOT be appended,
* because writing an empty string does not produce an incomplete line.
*/
ensureNewlineAtEnd?: boolean;
}
/**
* For use with {@link TextRewriterTransform}, this rewriter converts all newlines to
* a standard format.
*
* @public
*/
export declare class NormalizeNewlinesTextRewriter extends TextRewriter {
/** {@inheritDoc INormalizeNewlinesTextRewriterOptions.newlineKind} */
readonly newlineKind: NewlineKind;
/**
* The specific character sequence that will be used when appending newlines.
*/
readonly newline: string;
/** {@inheritDoc INormalizeNewlinesTextRewriterOptions.ensureNewlineAtEnd} */
readonly ensureNewlineAtEnd: boolean;
constructor(options: INormalizeNewlinesTextRewriterOptions);
initialize(): TextRewriterState;
process(unknownState: TextRewriterState, text: string): string;
close(unknownState: TextRewriterState): string;
}
//# sourceMappingURL=NormalizeNewlinesTextRewriter.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"NormalizeNewlinesTextRewriter.d.ts","sourceRoot":"","sources":["../src/NormalizeNewlinesTextRewriter.ts"],"names":[],"mappings":"AAGA,OAAO,EAAQ,KAAK,WAAW,EAAE,MAAM,8BAA8B,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAOtE;;;;GAIG;AACH,MAAM,WAAW,qCAAqC;IACpD;;OAEG;IACH,WAAW,EAAE,WAAW,CAAC;IAEzB;;;;;;;OAOG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;;;;GAKG;AACH,qBAAa,6BAA8B,SAAQ,YAAY;IAC7D,sEAAsE;IACtE,SAAgB,WAAW,EAAE,WAAW,CAAC;IAEzC;;OAEG;IACH,SAAgB,OAAO,EAAE,MAAM,CAAC;IAEhC,6EAA6E;IAC7E,SAAgB,kBAAkB,EAAE,OAAO,CAAC;gBAEzB,OAAO,EAAE,qCAAqC;IAO1D,UAAU,IAAI,iBAAiB;IAO/B,OAAO,CAAC,YAAY,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;IAiC9D,KAAK,CAAC,YAAY,EAAE,iBAAiB,GAAG,MAAM;CAWtD"}

View File

@@ -0,0 +1,70 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.NormalizeNewlinesTextRewriter = void 0;
const node_core_library_1 = require("@rushstack/node-core-library");
const TextRewriter_1 = require("./TextRewriter");
/**
* For use with {@link TextRewriterTransform}, this rewriter converts all newlines to
* a standard format.
*
* @public
*/
class NormalizeNewlinesTextRewriter extends TextRewriter_1.TextRewriter {
constructor(options) {
super();
this.newlineKind = options.newlineKind;
this.newline = node_core_library_1.Text.getNewline(options.newlineKind);
this.ensureNewlineAtEnd = !!options.ensureNewlineAtEnd;
}
initialize() {
return {
characterToIgnore: '',
incompleteLine: false
};
}
process(unknownState, text) {
const state = unknownState;
let result = '';
if (text.length > 0) {
let i = 0;
do {
const c = text[i];
++i;
if (c === state.characterToIgnore) {
state.characterToIgnore = '';
}
else if (c === '\r') {
result += this.newline;
state.characterToIgnore = '\n';
state.incompleteLine = false;
}
else if (c === '\n') {
result += this.newline;
state.characterToIgnore = '\r';
state.incompleteLine = false;
}
else {
result += c;
state.characterToIgnore = '';
state.incompleteLine = true;
}
} while (i < text.length);
}
return result;
}
close(unknownState) {
const state = unknownState;
state.characterToIgnore = '';
if (state.incompleteLine) {
state.incompleteLine = false;
return this.newline;
}
else {
return '';
}
}
}
exports.NormalizeNewlinesTextRewriter = NormalizeNewlinesTextRewriter;
//# sourceMappingURL=NormalizeNewlinesTextRewriter.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,57 @@
import type { ITerminalProvider, TerminalProviderSeverity } from './ITerminalProvider';
/**
* @beta
*/
export interface IPrefixProxyTerminalProviderOptionsBase {
/**
* The {@link ITerminalProvider} that will be wrapped.
*/
terminalProvider: ITerminalProvider;
}
/**
* Options for {@link PrefixProxyTerminalProvider}, with a static prefix.
*
* @beta
*/
export interface IStaticPrefixProxyTerminalProviderOptions extends IPrefixProxyTerminalProviderOptionsBase {
/**
* The prefix that should be added to each line of output.
*/
prefix: string;
}
/**
* Options for {@link PrefixProxyTerminalProvider}.
*
* @beta
*/
export interface IDynamicPrefixProxyTerminalProviderOptions extends IPrefixProxyTerminalProviderOptionsBase {
/**
* A function that returns the prefix that should be added to each line of output. This is useful
* for prefixing each line with a timestamp.
*/
getPrefix: () => string;
}
/**
* @beta
*/
export type IPrefixProxyTerminalProviderOptions = IStaticPrefixProxyTerminalProviderOptions | IDynamicPrefixProxyTerminalProviderOptions;
/**
* Wraps an existing {@link ITerminalProvider} that prefixes each line of output with a specified
* prefix string.
*
* @beta
*/
export declare class PrefixProxyTerminalProvider implements ITerminalProvider {
private readonly _parentTerminalProvider;
private readonly _getPrefix;
private readonly _newlineRegex;
private _isOnNewline;
constructor(options: IPrefixProxyTerminalProviderOptions);
/** @override */
get supportsColor(): boolean;
/** @override */
get eolCharacter(): string;
/** @override */
write(data: string, severity: TerminalProviderSeverity): void;
}
//# sourceMappingURL=PrefixProxyTerminalProvider.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"PrefixProxyTerminalProvider.d.ts","sourceRoot":"","sources":["../src/PrefixProxyTerminalProvider.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAEvF;;GAEG;AACH,MAAM,WAAW,uCAAuC;IACtD;;OAEG;IACH,gBAAgB,EAAE,iBAAiB,CAAC;CACrC;AAED;;;;GAIG;AACH,MAAM,WAAW,yCAA0C,SAAQ,uCAAuC;IACxG;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;GAIG;AACH,MAAM,WAAW,0CAA2C,SAAQ,uCAAuC;IACzG;;;OAGG;IACH,SAAS,EAAE,MAAM,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,MAAM,mCAAmC,GAC3C,yCAAyC,GACzC,0CAA0C,CAAC;AAE/C;;;;;GAKG;AACH,qBAAa,2BAA4B,YAAW,iBAAiB;IACnE,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAoB;IAC5D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAe;IAC1C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,YAAY,CAAU;gBAEX,OAAO,EAAE,mCAAmC;IAmB/D,gBAAgB;IAChB,IAAW,aAAa,IAAI,OAAO,CAElC;IAED,gBAAgB;IAChB,IAAW,YAAY,IAAI,MAAM,CAEhC;IAED,gBAAgB;IACT,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,wBAAwB,GAAG,IAAI;CA0BrE"}

View File

@@ -0,0 +1,64 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.PrefixProxyTerminalProvider = void 0;
const node_core_library_1 = require("@rushstack/node-core-library");
/**
* Wraps an existing {@link ITerminalProvider} that prefixes each line of output with a specified
* prefix string.
*
* @beta
*/
class PrefixProxyTerminalProvider {
constructor(options) {
const { terminalProvider } = options;
this._parentTerminalProvider = terminalProvider;
if (options.prefix !== undefined) {
const { prefix } = options;
this._getPrefix = () => prefix;
}
else {
const { getPrefix } = options;
this._getPrefix = getPrefix;
}
this._isOnNewline = true;
// eslint-disable-next-line @rushstack/security/no-unsafe-regexp
this._newlineRegex = new RegExp(`${node_core_library_1.Text.escapeRegExp(terminalProvider.eolCharacter)}|\\n`, 'g');
}
/** @override */
get supportsColor() {
return this._parentTerminalProvider.supportsColor;
}
/** @override */
get eolCharacter() {
return this._parentTerminalProvider.eolCharacter;
}
/** @override */
write(data, severity) {
// We need to track newlines to ensure that the prefix is added to each line
let currentIndex = 0;
// eslint-disable-next-line @rushstack/no-new-null
let newlineMatch;
while ((newlineMatch = this._newlineRegex.exec(data))) {
// Extract the line, add the prefix, and write it out with the newline
const newlineIndex = newlineMatch.index;
const newIndex = newlineIndex + newlineMatch[0].length;
const prefix = this._isOnNewline ? this._getPrefix() : '';
const dataToWrite = `${prefix}${data.substring(currentIndex, newIndex)}`;
this._parentTerminalProvider.write(dataToWrite, severity);
// Update the currentIndex to start the search from the char after the newline
currentIndex = newIndex;
this._isOnNewline = true;
}
// The remaining data is not postfixed by a newline, so write out the data and set _isNewline to false
const remainingData = data.substring(currentIndex);
if (remainingData.length) {
const prefix = this._isOnNewline ? this._getPrefix() : '';
this._parentTerminalProvider.write(`${prefix}${remainingData}`, severity);
this._isOnNewline = false;
}
}
}
exports.PrefixProxyTerminalProvider = PrefixProxyTerminalProvider;
//# sourceMappingURL=PrefixProxyTerminalProvider.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,77 @@
import type { ITerminal } from './ITerminal';
/**
* A sensible fallback column width for consoles.
*
* @public
*/
export declare const DEFAULT_CONSOLE_WIDTH: number;
/**
* A collection of utilities for printing messages to the console.
*
* @public
*/
export declare class PrintUtilities {
/**
* Returns the width of the console, measured in columns
*/
static getConsoleWidth(): number | undefined;
/**
* Applies word wrapping.
*
* @param text - The text to wrap
* @param maxLineLength - The maximum length of a line, defaults to the console width
* @param indent - The number of spaces to indent the wrapped lines, defaults to 0
*/
static wrapWords(text: string, maxLineLength?: number, indent?: number): string;
/**
* Applies word wrapping.
*
* @param text - The text to wrap
* @param maxLineLength - The maximum length of a line, defaults to the console width
* @param linePrefix - The string to prefix each line with, defaults to ''
*/
static wrapWords(text: string, maxLineLength?: number, linePrefix?: string): string;
/**
* Applies word wrapping.
*
* @param text - The text to wrap
* @param maxLineLength - The maximum length of a line, defaults to the console width
* @param indentOrLinePrefix - The number of spaces to indent the wrapped lines or the string to prefix
* each line with, defaults to no prefix
*/
static wrapWords(text: string, maxLineLength?: number, indentOrLinePrefix?: number | string): string;
/**
* Applies word wrapping and returns an array of lines.
*
* @param text - The text to wrap
* @param maxLineLength - The maximum length of a line, defaults to the console width
* @param indent - The number of spaces to indent the wrapped lines, defaults to 0
*/
static wrapWordsToLines(text: string, maxLineLength?: number, indent?: number): string[];
/**
* Applies word wrapping and returns an array of lines.
*
* @param text - The text to wrap
* @param maxLineLength - The maximum length of a line, defaults to the console width
* @param linePrefix - The string to prefix each line with, defaults to ''
*/
static wrapWordsToLines(text: string, maxLineLength?: number, linePrefix?: string): string[];
/**
* Applies word wrapping and returns an array of lines.
*
* @param text - The text to wrap
* @param maxLineLength - The maximum length of a line, defaults to the console width
* @param indentOrLinePrefix - The number of spaces to indent the wrapped lines or the string to prefix
* each line with, defaults to no prefix
*/
static wrapWordsToLines(text: string, maxLineLength?: number, indentOrLinePrefix?: number | string): string[];
/**
* Displays a message in the console wrapped in a box UI.
*
* @param message - The message to display.
* @param terminal - The terminal to write the message to.
* @param boxWidth - The width of the box, defaults to half of the console width.
*/
static printMessageInBox(message: string, terminal: ITerminal, boxWidth?: number): void;
}
//# sourceMappingURL=PrintUtilities.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"PrintUtilities.d.ts","sourceRoot":"","sources":["../src/PrintUtilities.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAW,CAAC;AAEhD;;;;GAIG;AACH,qBAAa,cAAc;IACzB;;OAEG;WACW,eAAe,IAAI,MAAM,GAAG,SAAS;IAInD;;;;;;OAMG;WACW,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM;IACtF;;;;;;OAMG;WACW,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM;IAC1F;;;;;;;OAOG;WACW,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,kBAAkB,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM;IAc3G;;;;;;OAMG;WACW,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;IAC/F;;;;;;OAMG;WACW,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;IACnG;;;;;;;OAOG;WACW,gBAAgB,CAC5B,IAAI,EAAE,MAAM,EACZ,aAAa,CAAC,EAAE,MAAM,EACtB,kBAAkB,CAAC,EAAE,MAAM,GAAG,MAAM,GACnC,MAAM,EAAE;IA0FX;;;;;;OAMG;WACW,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;CA0C/F"}

View File

@@ -0,0 +1,150 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.PrintUtilities = exports.DEFAULT_CONSOLE_WIDTH = void 0;
const node_core_library_1 = require("@rushstack/node-core-library");
/**
* A sensible fallback column width for consoles.
*
* @public
*/
exports.DEFAULT_CONSOLE_WIDTH = 80;
/**
* A collection of utilities for printing messages to the console.
*
* @public
*/
class PrintUtilities {
/**
* Returns the width of the console, measured in columns
*/
static getConsoleWidth() {
var _a;
return (_a = process.stdout) === null || _a === void 0 ? void 0 : _a.columns;
}
static wrapWords(text, maxLineLength, indentOrLinePrefix) {
const wrappedLines = PrintUtilities.wrapWordsToLines(text, maxLineLength, indentOrLinePrefix // TS is confused by the overloads
);
return wrappedLines.join('\n');
}
static wrapWordsToLines(text, maxLineLength, indentOrLinePrefix) {
var _a;
let linePrefix;
switch (typeof indentOrLinePrefix) {
case 'number':
linePrefix = ' '.repeat(indentOrLinePrefix);
break;
case 'string':
linePrefix = indentOrLinePrefix;
break;
default:
linePrefix = '';
break;
}
const linePrefixLength = linePrefix.length;
if (!maxLineLength) {
maxLineLength = PrintUtilities.getConsoleWidth() || exports.DEFAULT_CONSOLE_WIDTH;
}
// Apply word wrapping and the provided line prefix, while also respecting existing newlines
// and prefix spaces that may exist in the text string already.
const lines = node_core_library_1.Text.splitByNewLines(text);
const wrappedLines = [];
for (const line of lines) {
if (line.length + linePrefixLength <= maxLineLength) {
wrappedLines.push(linePrefix + line);
}
else {
const lineAdditionalPrefix = ((_a = line.match(/^\s*/)) === null || _a === void 0 ? void 0 : _a[0]) || '';
const whitespaceRegexp = /\s+/g;
let currentWhitespaceMatch = null;
let previousWhitespaceMatch;
let currentLineStartIndex = lineAdditionalPrefix.length;
let previousBreakRanOver = false;
while ((currentWhitespaceMatch = whitespaceRegexp.exec(line)) !== null) {
if (currentWhitespaceMatch.index + linePrefixLength - currentLineStartIndex > maxLineLength) {
let whitespaceToSplitAt;
if (!previousWhitespaceMatch ||
// Handle the case where there are two words longer than the maxLineLength in a row
previousBreakRanOver) {
whitespaceToSplitAt = currentWhitespaceMatch;
}
else {
whitespaceToSplitAt = previousWhitespaceMatch;
}
wrappedLines.push(linePrefix +
lineAdditionalPrefix +
line.substring(currentLineStartIndex, whitespaceToSplitAt.index));
previousBreakRanOver = whitespaceToSplitAt.index - currentLineStartIndex > maxLineLength;
currentLineStartIndex = whitespaceToSplitAt.index + whitespaceToSplitAt[0].length;
}
else {
previousBreakRanOver = false;
}
previousWhitespaceMatch = currentWhitespaceMatch;
}
if (previousWhitespaceMatch &&
line.length + linePrefixLength - currentLineStartIndex > maxLineLength) {
const whitespaceToSplitAt = previousWhitespaceMatch;
wrappedLines.push(linePrefix +
lineAdditionalPrefix +
line.substring(currentLineStartIndex, whitespaceToSplitAt.index));
currentLineStartIndex = whitespaceToSplitAt.index + whitespaceToSplitAt[0].length;
}
if (currentLineStartIndex < line.length) {
wrappedLines.push(linePrefix + lineAdditionalPrefix + line.substring(currentLineStartIndex));
}
}
}
return wrappedLines;
}
/**
* Displays a message in the console wrapped in a box UI.
*
* @param message - The message to display.
* @param terminal - The terminal to write the message to.
* @param boxWidth - The width of the box, defaults to half of the console width.
*/
static printMessageInBox(message, terminal, boxWidth) {
if (!boxWidth) {
const consoleWidth = PrintUtilities.getConsoleWidth() || exports.DEFAULT_CONSOLE_WIDTH;
boxWidth = Math.floor(consoleWidth / 2);
}
const maxLineLength = boxWidth - 10;
const wrappedMessageLines = PrintUtilities.wrapWordsToLines(message, maxLineLength);
let longestLineLength = 0;
const trimmedLines = [];
for (const line of wrappedMessageLines) {
const trimmedLine = line.trim();
trimmedLines.push(trimmedLine);
longestLineLength = Math.max(longestLineLength, trimmedLine.length);
}
if (longestLineLength > boxWidth - 2) {
// If the longest line is longer than the box, print bars above and below the message
// ═════════════
// Message
// ═════════════
const headerAndFooter = ` ${'═'.repeat(boxWidth)}`;
terminal.writeLine(headerAndFooter);
for (const line of wrappedMessageLines) {
terminal.writeLine(` ${line}`);
}
terminal.writeLine(headerAndFooter);
}
else {
// ╔═══════════╗
// ║ Message ║
// ╚═══════════╝
terminal.writeLine(`${'═'.repeat(boxWidth - 2)}`);
for (const trimmedLine of trimmedLines) {
const padding = boxWidth - trimmedLine.length - 2;
const leftPadding = Math.floor(padding / 2);
const rightPadding = padding - leftPadding;
terminal.writeLine(`${' '.repeat(leftPadding)}${trimmedLine}${' '.repeat(rightPadding)}`);
}
terminal.writeLine(`${'═'.repeat(boxWidth - 2)}`);
}
}
}
exports.PrintUtilities = PrintUtilities;
//# sourceMappingURL=PrintUtilities.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,17 @@
import { TextRewriter, type TextRewriterState } from './TextRewriter';
/**
* For use with {@link TextRewriterTransform}, this rewriter removes ANSI escape codes
* including colored text.
*
* @remarks
* The implementation also removes other ANSI escape codes such as cursor positioning.
* The specific set of affected codes may be adjusted in the future.
*
* @public
*/
export declare class RemoveColorsTextRewriter extends TextRewriter {
initialize(): TextRewriterState;
process(unknownState: TextRewriterState, text: string): string;
close(unknownState: TextRewriterState): string;
}
//# sourceMappingURL=RemoveColorsTextRewriter.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"RemoveColorsTextRewriter.d.ts","sourceRoot":"","sources":["../src/RemoveColorsTextRewriter.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,KAAK,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAgBtE;;;;;;;;;GASG;AACH,qBAAa,wBAAyB,SAAQ,YAAY;IACjD,UAAU,IAAI,iBAAiB;IAI/B,OAAO,CAAC,YAAY,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;IAgE9D,KAAK,CAAC,YAAY,EAAE,iBAAiB,GAAG,MAAM;CAOtD"}

View File

@@ -0,0 +1,95 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.RemoveColorsTextRewriter = void 0;
const AnsiEscape_1 = require("./AnsiEscape");
const TextRewriter_1 = require("./TextRewriter");
var State;
(function (State) {
// Buffer is empty, and we're looking for the ESC character
State[State["Start"] = 0] = "Start";
// We're looking for the '[' character
State[State["AwaitingBracket"] = 1] = "AwaitingBracket";
// We're reading the codes after the '[' character
State[State["ReadingCodes"] = 2] = "ReadingCodes";
})(State || (State = {}));
/**
* For use with {@link TextRewriterTransform}, this rewriter removes ANSI escape codes
* including colored text.
*
* @remarks
* The implementation also removes other ANSI escape codes such as cursor positioning.
* The specific set of affected codes may be adjusted in the future.
*
* @public
*/
class RemoveColorsTextRewriter extends TextRewriter_1.TextRewriter {
initialize() {
return { buffer: '', parseState: State.Start };
}
process(unknownState, text) {
const state = unknownState;
// We will be matching AnsiEscape._csiRegExp:
//
// /\x1b\[([\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e])/gu
//
const ESC = '\x1b';
let result = '';
let index = 0;
while (index < text.length) {
if (state.parseState === State.Start) {
// The buffer is empty, which means we haven't found anything yet
const csiIndex = text.indexOf(ESC, index);
if (csiIndex < 0) {
// We reached the end of "text" without finding another CSI prefix
result += text.substring(index);
break;
}
// Append everything up to the CSI prefix
result += text.substring(index, csiIndex);
// Save the partial match in the buffer
state.buffer = ESC;
index = csiIndex + 1;
state.parseState = State.AwaitingBracket;
}
else {
// The buffer has characters, which means we started matching a partial sequence
// Read another character into the buffer
const c = text[index];
++index;
state.buffer += c;
if (state.parseState === State.AwaitingBracket) {
if (c === '[') {
state.parseState = State.ReadingCodes;
}
else {
// Failed to match, so append the buffer and start over
result += state.buffer;
state.buffer = '';
state.parseState = State.Start;
}
}
else {
// state.state === State.ReadingCodes
// Stop when we reach any character that is not [\x30-\x3f] or [\x20-\x2f]
const code = c.charCodeAt(0);
if (code < 0x20 || code > 0x3f) {
result += AnsiEscape_1.AnsiEscape.removeCodes(state.buffer);
state.buffer = '';
state.parseState = State.Start;
}
}
}
}
return result;
}
close(unknownState) {
const state = unknownState;
const result = state.buffer;
state.buffer = '';
return result;
}
}
exports.RemoveColorsTextRewriter = RemoveColorsTextRewriter;
//# sourceMappingURL=RemoveColorsTextRewriter.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,32 @@
import { TerminalWritable, type ITerminalWritableOptions } from './TerminalWritable';
import type { ITerminalChunk } from './ITerminalChunk';
/**
* Constructor options for {@link SplitterTransform}.
*
* @public
*/
export interface ISplitterTransformOptions extends ITerminalWritableOptions {
/**
* Each input chunk will be passed to each destination in the array.
*/
destinations: TerminalWritable[];
}
/**
* Use this instead of {@link TerminalTransform} if you need to output `ITerminalChunk`
* data to more than one destination.
*
* @remarks
*
* Splitting streams complicates the pipeline topology and can make debugging more difficult.
* For this reason, it is modeled as an explicit `SplitterTransform` node, rather than
* as a built-in feature of `TerminalTransform`.
*
* @public
*/
export declare class SplitterTransform extends TerminalWritable {
readonly destinations: ReadonlyArray<TerminalWritable>;
constructor(options: ISplitterTransformOptions);
protected onWriteChunk(chunk: ITerminalChunk): void;
protected onClose(): void;
}
//# sourceMappingURL=SplitterTransform.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"SplitterTransform.d.ts","sourceRoot":"","sources":["../src/SplitterTransform.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,KAAK,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AACrF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD;;;;GAIG;AACH,MAAM,WAAW,yBAA0B,SAAQ,wBAAwB;IACzE;;OAEG;IACH,YAAY,EAAE,gBAAgB,EAAE,CAAC;CAClC;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,iBAAkB,SAAQ,gBAAgB;IACrD,SAAgB,YAAY,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC;gBAE3C,OAAO,EAAE,yBAAyB;IAKrD,SAAS,CAAC,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IAMnD,SAAS,CAAC,OAAO,IAAI,IAAI;CAkB1B"}

View File

@@ -0,0 +1,48 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.SplitterTransform = void 0;
const TerminalWritable_1 = require("./TerminalWritable");
/**
* Use this instead of {@link TerminalTransform} if you need to output `ITerminalChunk`
* data to more than one destination.
*
* @remarks
*
* Splitting streams complicates the pipeline topology and can make debugging more difficult.
* For this reason, it is modeled as an explicit `SplitterTransform` node, rather than
* as a built-in feature of `TerminalTransform`.
*
* @public
*/
class SplitterTransform extends TerminalWritable_1.TerminalWritable {
constructor(options) {
super();
this.destinations = [...options.destinations];
}
onWriteChunk(chunk) {
for (const destination of this.destinations) {
destination.writeChunk(chunk);
}
}
onClose() {
const errors = [];
// If an exception is thrown, try to ensure that the other destinations get closed properly
for (const destination of this.destinations) {
if (!destination.preventAutoclose) {
try {
destination.close();
}
catch (error) {
errors.push(error);
}
}
}
if (errors.length > 0) {
throw errors[0];
}
}
}
exports.SplitterTransform = SplitterTransform;
//# sourceMappingURL=SplitterTransform.js.map

View File

@@ -0,0 +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"]}

View File

@@ -0,0 +1,72 @@
import { NewlineKind } from '@rushstack/node-core-library';
import { type ITerminalChunk } from './ITerminalChunk';
import { TerminalTransform, type ITerminalTransformOptions } from './TerminalTransform';
/**
* Constructor options for {@link StderrLineTransform}
* @beta
*/
export interface IStdioLineTransformOptions extends ITerminalTransformOptions {
/**
* Specifies the kind of newline for the output.
*/
newlineKind?: NewlineKind;
}
/**
* `StderrLineTransform` normalizes lines that mix characters from `stdout` and `stderr`,
* so that each output line is routed entirely to `stdout` or `stderr`.
*
* @remarks
* IMPORTANT: This transform assumes that its input has been normalized to use `"\n"` newlines.
*
* IMPORTANT: This transform does not produce realtime output, because lines are buffered
* until a newline character is encountered.
*
* Suppose that a poorly behaved process produces output like this:
*
* ```ts
* process.stderr.write('An error occurred, cleaning up');
* process.stdout.write('.'); // (delay)
* process.stdout.write('.'); // (delay)
* process.stdout.write('.');
* process.stdout.write('\n');
* process.stderr.write('The process completed with errors\n');
* ```
*
* When `stdout` and `stderr` are combined on the console, the mistake in the output would not be noticeable:
* ```
* An error occurred, cleaning up...
* The process completed with errors
* ```
*
* However, if we discard `stdout`, then `stderr` is malformed:
* ```
* An error occurred, cleaning upThe process completed with errors
* ```
*
* Tooling scripts can introduce these sorts of problems via edge cases that are difficult to find and fix.
*
* `StderrLineTransform` normalizes the output so that if a combined line contains any `stderr` characters,
* then the entire line is routed to `stderr`. Later, if we discard `stdout`, then the output will
* preserve the appropriate context:
*
* ```
* An error occurred, cleaning up...
* The process completed with errors
* ```
*
* @privateRemarks
* This class is experimental and marked as `@beta`. The algorithm may need some fine-tuning, or there may
* be better solutions to this problem.
*
* @beta
*/
export declare class StderrLineTransform extends TerminalTransform {
private _accumulatedLine;
private _accumulatedStderr;
readonly newline: string;
constructor(options: IStdioLineTransformOptions);
protected onWriteChunk(chunk: ITerminalChunk): void;
protected onClose(): void;
private _processAccumulatedLine;
}
//# sourceMappingURL=StdioLineTransform.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"StdioLineTransform.d.ts","sourceRoot":"","sources":["../src/StdioLineTransform.ts"],"names":[],"mappings":"AAGA,OAAO,EAAQ,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAEjE,OAAO,EAAE,KAAK,cAAc,EAAqB,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,KAAK,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAExF;;;GAGG;AACH,MAAM,WAAW,0BAA2B,SAAQ,yBAAyB;IAC3E;;OAEG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,qBAAa,mBAAoB,SAAQ,iBAAiB;IACxD,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,kBAAkB,CAAU;IAEpC,SAAgB,OAAO,EAAE,MAAM,CAAC;gBAEb,OAAO,EAAE,0BAA0B;IAStD,SAAS,CAAC,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IAgCnD,SAAS,CAAC,OAAO,IAAI,IAAI;IAOzB,OAAO,CAAC,uBAAuB;CAkBhC"}

View File

@@ -0,0 +1,115 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.StderrLineTransform = void 0;
const node_core_library_1 = require("@rushstack/node-core-library");
const ITerminalChunk_1 = require("./ITerminalChunk");
const TerminalTransform_1 = require("./TerminalTransform");
/**
* `StderrLineTransform` normalizes lines that mix characters from `stdout` and `stderr`,
* so that each output line is routed entirely to `stdout` or `stderr`.
*
* @remarks
* IMPORTANT: This transform assumes that its input has been normalized to use `"\n"` newlines.
*
* IMPORTANT: This transform does not produce realtime output, because lines are buffered
* until a newline character is encountered.
*
* Suppose that a poorly behaved process produces output like this:
*
* ```ts
* process.stderr.write('An error occurred, cleaning up');
* process.stdout.write('.'); // (delay)
* process.stdout.write('.'); // (delay)
* process.stdout.write('.');
* process.stdout.write('\n');
* process.stderr.write('The process completed with errors\n');
* ```
*
* When `stdout` and `stderr` are combined on the console, the mistake in the output would not be noticeable:
* ```
* An error occurred, cleaning up...
* The process completed with errors
* ```
*
* However, if we discard `stdout`, then `stderr` is malformed:
* ```
* An error occurred, cleaning upThe process completed with errors
* ```
*
* Tooling scripts can introduce these sorts of problems via edge cases that are difficult to find and fix.
*
* `StderrLineTransform` normalizes the output so that if a combined line contains any `stderr` characters,
* then the entire line is routed to `stderr`. Later, if we discard `stdout`, then the output will
* preserve the appropriate context:
*
* ```
* An error occurred, cleaning up...
* The process completed with errors
* ```
*
* @privateRemarks
* This class is experimental and marked as `@beta`. The algorithm may need some fine-tuning, or there may
* be better solutions to this problem.
*
* @beta
*/
class StderrLineTransform extends TerminalTransform_1.TerminalTransform {
constructor(options) {
super(options);
this._accumulatedLine = '';
this._accumulatedStderr = false;
this.newline = node_core_library_1.Text.getNewline(options.newlineKind || node_core_library_1.NewlineKind.Lf);
}
onWriteChunk(chunk) {
if (chunk.text.indexOf('\r') >= 0) {
throw new Error('StderrLineTransform expects chunks with normalized newlines');
}
// After _newlineNormalizerTransform was applied, we can now assume that all newlines
// use the "\n" string
const text = chunk.text;
let startIndex = 0;
while (startIndex < text.length) {
if (chunk.kind === ITerminalChunk_1.TerminalChunkKind.Stderr) {
this._accumulatedStderr = true;
}
const endIndex = text.indexOf('\n', startIndex);
if (endIndex < 0) {
// we did not find \n, so simply append
this._accumulatedLine += text.substring(startIndex);
break;
}
// append everything up to \n
this._accumulatedLine += text.substring(startIndex, endIndex);
this._processAccumulatedLine();
// skip the \n
startIndex = endIndex + 1;
}
}
onClose() {
if (this._accumulatedLine.length > 0) {
this._processAccumulatedLine();
}
this.autocloseDestination();
}
_processAccumulatedLine() {
this._accumulatedLine += this.newline;
if (this._accumulatedStderr) {
this.destination.writeChunk({
kind: ITerminalChunk_1.TerminalChunkKind.Stderr,
text: this._accumulatedLine
});
}
else {
this.destination.writeChunk({
kind: ITerminalChunk_1.TerminalChunkKind.Stdout,
text: this._accumulatedLine
});
}
this._accumulatedLine = '';
this._accumulatedStderr = false;
}
}
exports.StderrLineTransform = StderrLineTransform;
//# sourceMappingURL=StdioLineTransform.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,63 @@
import { type ITerminalChunk } from './ITerminalChunk';
import { type ITerminalWritableOptions, TerminalWritable } from './TerminalWritable';
/**
* Constructor options for {@link StdioSummarizer}.
* @beta
*/
export interface IStdioSummarizerOptions extends ITerminalWritableOptions {
/**
* Specifies the maximum number of leading lines to include in the summary.
* @defaultValue `10`
*/
leadingLines?: number;
/**
* Specifies the maximum number of trailing lines to include in the summary.
* @defaultValue `10`
*/
trailingLines?: number;
}
/**
* Summarizes the results of a failed build task by returning a subset of `stderr` output not to exceed
* a specified maximum number of lines.
*
* @remarks
* IMPORTANT: This transform assumes that its input was prepared by {@link StderrLineTransform}, so that each
* {@link ITerminalChunk.text} item is a single line terminated by a `"\n"` character.
*
* The {@link IStdioSummarizerOptions.leadingLines} and {@link IStdioSummarizerOptions.trailingLines}
* counts specify the maximum number of lines to be returned. Any additional lines will be omitted.
* For example, if `leadingLines` and `trailingLines` were set to `3`, then the summary of 16 `stderr` lines might
* look like this:
*
* ```
* Line 1
* Line 2
* Line 3
* ...10 lines omitted...
* Line 14
* Line 15
* Line 16
* ```
*
* If the `stderr` output is completely empty, then the `stdout` output will be summarized instead.
*
* @beta
*/
export declare class StdioSummarizer extends TerminalWritable {
private _leadingLines;
private _trailingLines;
private readonly _abridgedLeading;
private readonly _abridgedTrailing;
private _abridgedOmittedLines;
private _abridgedStderr;
constructor(options?: IStdioSummarizerOptions);
/**
* Returns the summary report.
*
* @remarks
* The `close()` method must be called before `getReport()` can be used.
*/
getReport(): string;
onWriteChunk(chunk: ITerminalChunk): void;
}
//# sourceMappingURL=StdioSummarizer.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"StdioSummarizer.d.ts","sourceRoot":"","sources":["../src/StdioSummarizer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,cAAc,EAAqB,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,KAAK,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAErF;;;GAGG;AACH,MAAM,WAAW,uBAAwB,SAAQ,wBAAwB;IACvE;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,qBAAa,eAAgB,SAAQ,gBAAgB;IAEnD,OAAO,CAAC,aAAa,CAAS;IAG9B,OAAO,CAAC,cAAc,CAAS;IAE/B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAW;IAC5C,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAW;IAC7C,OAAO,CAAC,qBAAqB,CAAa;IAC1C,OAAO,CAAC,eAAe,CAAU;gBAEd,OAAO,CAAC,EAAE,uBAAuB;IAepD;;;;;OAKG;IACI,SAAS,IAAI,MAAM;IAenB,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;CAkCjD"}

View File

@@ -0,0 +1,99 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.StdioSummarizer = void 0;
const ITerminalChunk_1 = require("./ITerminalChunk");
const TerminalWritable_1 = require("./TerminalWritable");
/**
* Summarizes the results of a failed build task by returning a subset of `stderr` output not to exceed
* a specified maximum number of lines.
*
* @remarks
* IMPORTANT: This transform assumes that its input was prepared by {@link StderrLineTransform}, so that each
* {@link ITerminalChunk.text} item is a single line terminated by a `"\n"` character.
*
* The {@link IStdioSummarizerOptions.leadingLines} and {@link IStdioSummarizerOptions.trailingLines}
* counts specify the maximum number of lines to be returned. Any additional lines will be omitted.
* For example, if `leadingLines` and `trailingLines` were set to `3`, then the summary of 16 `stderr` lines might
* look like this:
*
* ```
* Line 1
* Line 2
* Line 3
* ...10 lines omitted...
* Line 14
* Line 15
* Line 16
* ```
*
* If the `stderr` output is completely empty, then the `stdout` output will be summarized instead.
*
* @beta
*/
class StdioSummarizer extends TerminalWritable_1.TerminalWritable {
constructor(options) {
super(options);
this._abridgedOmittedLines = 0;
if (!options) {
options = {};
}
this._leadingLines = options.leadingLines !== undefined ? options.leadingLines : 10;
this._trailingLines = options.trailingLines !== undefined ? options.trailingLines : 10;
this._abridgedLeading = [];
this._abridgedTrailing = [];
this._abridgedStderr = false;
}
/**
* Returns the summary report.
*
* @remarks
* The `close()` method must be called before `getReport()` can be used.
*/
getReport() {
if (this.isOpen) {
throw new Error('The summary cannot be prepared until after close() is called.');
}
const report = [...this._abridgedLeading];
if (this._abridgedOmittedLines === 1) {
report.push(` ...${this._abridgedOmittedLines} line omitted...\n`);
}
if (this._abridgedOmittedLines > 1) {
report.push(` ...${this._abridgedOmittedLines} lines omitted...\n`);
}
report.push(...this._abridgedTrailing);
return report.join('');
}
onWriteChunk(chunk) {
if (chunk.text.length === 0 || chunk.text[chunk.text.length - 1] !== '\n') {
throw new Error('StdioSummarizer expects chunks that were separated parsed into lines by StderrLineTransform\n' +
' Invalid input: ' +
JSON.stringify(chunk.text));
}
if (chunk.kind === ITerminalChunk_1.TerminalChunkKind.Stderr && !this._abridgedStderr) {
// The first time we see stderr, switch to capturing stderr
this._abridgedStderr = true;
this._abridgedLeading.length = 0;
this._abridgedTrailing.length = 0;
this._abridgedOmittedLines = 0;
}
else if (this._abridgedStderr && chunk.kind !== ITerminalChunk_1.TerminalChunkKind.Stderr) {
// If we're capturing stderr, then ignore non-stderr input
return;
}
// Did we capture enough leading lines?
if (this._abridgedLeading.length < this._leadingLines) {
this._abridgedLeading.push(chunk.text);
return;
}
this._abridgedTrailing.push(chunk.text);
// If we captured to many trailing lines, omit the extras
while (this._abridgedTrailing.length > this._trailingLines) {
this._abridgedTrailing.shift();
++this._abridgedOmittedLines;
}
}
}
exports.StdioSummarizer = StdioSummarizer;
//# sourceMappingURL=StdioSummarizer.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,17 @@
import { type ITerminalChunk } from './ITerminalChunk';
import { TerminalWritable } from './TerminalWritable';
/**
* A {@link TerminalWritable} subclass that writes its output directly to the process `stdout` and `stderr`
* streams.
*
* @remarks
* This is the standard output target for a process. You normally do not need to construct
* this class; the {@link StdioWritable."instance"} singleton can be used instead.
*
* @public
*/
export declare class StdioWritable extends TerminalWritable {
static instance: StdioWritable;
protected onWriteChunk(chunk: ITerminalChunk): void;
}
//# sourceMappingURL=StdioWritable.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"StdioWritable.d.ts","sourceRoot":"","sources":["../src/StdioWritable.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,cAAc,EAAqB,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD;;;;;;;;;GASG;AACH,qBAAa,aAAc,SAAQ,gBAAgB;IACjD,OAAc,QAAQ,EAAE,aAAa,CAAuB;IAE5D,SAAS,CAAC,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;CAOpD"}

View File

@@ -0,0 +1,34 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.StdioWritable = void 0;
const process_1 = __importDefault(require("process"));
const ITerminalChunk_1 = require("./ITerminalChunk");
const TerminalWritable_1 = require("./TerminalWritable");
/**
* A {@link TerminalWritable} subclass that writes its output directly to the process `stdout` and `stderr`
* streams.
*
* @remarks
* This is the standard output target for a process. You normally do not need to construct
* this class; the {@link StdioWritable."instance"} singleton can be used instead.
*
* @public
*/
class StdioWritable extends TerminalWritable_1.TerminalWritable {
onWriteChunk(chunk) {
if (chunk.kind === ITerminalChunk_1.TerminalChunkKind.Stdout) {
process_1.default.stdout.write(chunk.text);
}
else if (chunk.kind === ITerminalChunk_1.TerminalChunkKind.Stderr) {
process_1.default.stderr.write(chunk.text);
}
}
}
exports.StdioWritable = StdioWritable;
StdioWritable.instance = new StdioWritable();
//# sourceMappingURL=StdioWritable.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"StdioWritable.js","sourceRoot":"","sources":["../src/StdioWritable.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;;;;AAE3D,sDAA8B;AAC9B,qDAA0E;AAC1E,yDAAsD;AAEtD;;;;;;;;;GASG;AACH,MAAa,aAAc,SAAQ,mCAAgB;IAGvC,YAAY,CAAC,KAAqB;QAC1C,IAAI,KAAK,CAAC,IAAI,KAAK,kCAAiB,CAAC,MAAM,EAAE,CAAC;YAC5C,iBAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,kCAAiB,CAAC,MAAM,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"]}

View File

@@ -0,0 +1,67 @@
import { type ITerminalProvider, TerminalProviderSeverity } from './ITerminalProvider';
/**
* @beta
*/
export interface IStringBufferOutputOptions {
/**
* If set to true, special characters like \\n, \\r, and the \\u001b character
* in color control tokens will get normalized to [-n-], [-r-], and [-x-] respectively
*
* This option defaults to `true`
*/
normalizeSpecialCharacters: boolean;
}
/**
* Terminal provider that stores written data in buffers separated by severity.
* This terminal provider is designed to be used when code that prints to a terminal
* is being unit tested.
*
* @beta
*/
export declare class StringBufferTerminalProvider implements ITerminalProvider {
private _standardBuffer;
private _verboseBuffer;
private _debugBuffer;
private _warningBuffer;
private _errorBuffer;
private _supportsColor;
constructor(supportsColor?: boolean);
/**
* {@inheritDoc ITerminalProvider.write}
*/
write(data: string, severity: TerminalProviderSeverity): void;
/**
* {@inheritDoc ITerminalProvider.eolCharacter}
*/
get eolCharacter(): string;
/**
* {@inheritDoc ITerminalProvider.supportsColor}
*/
get supportsColor(): boolean;
/**
* Get everything that has been written at log-level severity.
*/
getOutput(options?: IStringBufferOutputOptions): string;
/**
* @deprecated - use {@link StringBufferTerminalProvider.getVerboseOutput}
*/
getVerbose(options?: IStringBufferOutputOptions): string;
/**
* Get everything that has been written at verbose-level severity.
*/
getVerboseOutput(options?: IStringBufferOutputOptions): string;
/**
* Get everything that has been written at debug-level severity.
*/
getDebugOutput(options?: IStringBufferOutputOptions): string;
/**
* Get everything that has been written at error-level severity.
*/
getErrorOutput(options?: IStringBufferOutputOptions): string;
/**
* Get everything that has been written at warning-level severity.
*/
getWarningOutput(options?: IStringBufferOutputOptions): string;
private _normalizeOutput;
}
//# sourceMappingURL=StringBufferTerminalProvider.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"StringBufferTerminalProvider.d.ts","sourceRoot":"","sources":["../src/StringBufferTerminalProvider.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAGvF;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC;;;;;OAKG;IACH,0BAA0B,EAAE,OAAO,CAAC;CACrC;AAED;;;;;;GAMG;AACH,qBAAa,4BAA6B,YAAW,iBAAiB;IACpE,OAAO,CAAC,eAAe,CAAsC;IAC7D,OAAO,CAAC,cAAc,CAAsC;IAC5D,OAAO,CAAC,YAAY,CAAsC;IAC1D,OAAO,CAAC,cAAc,CAAsC;IAC5D,OAAO,CAAC,YAAY,CAAsC;IAE1D,OAAO,CAAC,cAAc,CAAU;gBAEb,aAAa,GAAE,OAAe;IAIjD;;OAEG;IACI,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,wBAAwB,GAAG,IAAI;IA8BpE;;OAEG;IACH,IAAW,YAAY,IAAI,MAAM,CAEhC;IAED;;OAEG;IACH,IAAW,aAAa,IAAI,OAAO,CAElC;IAED;;OAEG;IACI,SAAS,CAAC,OAAO,CAAC,EAAE,0BAA0B,GAAG,MAAM;IAI9D;;OAEG;IACI,UAAU,CAAC,OAAO,CAAC,EAAE,0BAA0B,GAAG,MAAM;IAI/D;;OAEG;IACI,gBAAgB,CAAC,OAAO,CAAC,EAAE,0BAA0B,GAAG,MAAM;IAIrE;;OAEG;IACI,cAAc,CAAC,OAAO,CAAC,EAAE,0BAA0B,GAAG,MAAM;IAInE;;OAEG;IACI,cAAc,CAAC,OAAO,CAAC,EAAE,0BAA0B,GAAG,MAAM;IAInE;;OAEG;IACI,gBAAgB,CAAC,OAAO,CAAC,EAAE,0BAA0B,GAAG,MAAM;IAIrE,OAAO,CAAC,gBAAgB;CAezB"}

View File

@@ -0,0 +1,113 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.StringBufferTerminalProvider = void 0;
const node_core_library_1 = require("@rushstack/node-core-library");
const ITerminalProvider_1 = require("./ITerminalProvider");
const AnsiEscape_1 = require("./AnsiEscape");
/**
* Terminal provider that stores written data in buffers separated by severity.
* This terminal provider is designed to be used when code that prints to a terminal
* is being unit tested.
*
* @beta
*/
class StringBufferTerminalProvider {
constructor(supportsColor = false) {
this._standardBuffer = new node_core_library_1.StringBuilder();
this._verboseBuffer = new node_core_library_1.StringBuilder();
this._debugBuffer = new node_core_library_1.StringBuilder();
this._warningBuffer = new node_core_library_1.StringBuilder();
this._errorBuffer = new node_core_library_1.StringBuilder();
this._supportsColor = supportsColor;
}
/**
* {@inheritDoc ITerminalProvider.write}
*/
write(data, severity) {
switch (severity) {
case ITerminalProvider_1.TerminalProviderSeverity.warning: {
this._warningBuffer.append(data);
break;
}
case ITerminalProvider_1.TerminalProviderSeverity.error: {
this._errorBuffer.append(data);
break;
}
case ITerminalProvider_1.TerminalProviderSeverity.verbose: {
this._verboseBuffer.append(data);
break;
}
case ITerminalProvider_1.TerminalProviderSeverity.debug: {
this._debugBuffer.append(data);
break;
}
case ITerminalProvider_1.TerminalProviderSeverity.log:
default: {
this._standardBuffer.append(data);
break;
}
}
}
/**
* {@inheritDoc ITerminalProvider.eolCharacter}
*/
get eolCharacter() {
return '\n';
}
/**
* {@inheritDoc ITerminalProvider.supportsColor}
*/
get supportsColor() {
return this._supportsColor;
}
/**
* Get everything that has been written at log-level severity.
*/
getOutput(options) {
return this._normalizeOutput(this._standardBuffer.toString(), options);
}
/**
* @deprecated - use {@link StringBufferTerminalProvider.getVerboseOutput}
*/
getVerbose(options) {
return this.getVerboseOutput(options);
}
/**
* Get everything that has been written at verbose-level severity.
*/
getVerboseOutput(options) {
return this._normalizeOutput(this._verboseBuffer.toString(), options);
}
/**
* Get everything that has been written at debug-level severity.
*/
getDebugOutput(options) {
return this._normalizeOutput(this._debugBuffer.toString(), options);
}
/**
* Get everything that has been written at error-level severity.
*/
getErrorOutput(options) {
return this._normalizeOutput(this._errorBuffer.toString(), options);
}
/**
* Get everything that has been written at warning-level severity.
*/
getWarningOutput(options) {
return this._normalizeOutput(this._warningBuffer.toString(), options);
}
_normalizeOutput(s, options) {
options = Object.assign({ normalizeSpecialCharacters: true }, (options || {}));
s = node_core_library_1.Text.convertToLf(s);
if (options.normalizeSpecialCharacters) {
return AnsiEscape_1.AnsiEscape.formatForTests(s, { encodeNewlines: true });
}
else {
return s;
}
}
}
exports.StringBufferTerminalProvider = StringBufferTerminalProvider;
//# sourceMappingURL=StringBufferTerminalProvider.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,63 @@
import { type ITerminalProvider } from './ITerminalProvider';
import type { ITerminal, TerminalWriteParameters } from './ITerminal';
/**
* This class facilitates writing to a console.
*
* @beta
*/
export declare class Terminal implements ITerminal {
private _providers;
constructor(provider: ITerminalProvider);
/**
* {@inheritdoc ITerminal.registerProvider}
*/
registerProvider(provider: ITerminalProvider): void;
/**
* {@inheritdoc ITerminal.unregisterProvider}
*/
unregisterProvider(provider: ITerminalProvider): void;
/**
* {@inheritdoc ITerminal.write}
*/
write(...messageParts: TerminalWriteParameters): void;
/**
* {@inheritdoc ITerminal.writeLine}
*/
writeLine(...messageParts: TerminalWriteParameters): void;
/**
* {@inheritdoc ITerminal.writeWarning}
*/
writeWarning(...messageParts: TerminalWriteParameters): void;
/**
* {@inheritdoc ITerminal.writeWarningLine}
*/
writeWarningLine(...messageParts: TerminalWriteParameters): void;
/**
* {@inheritdoc ITerminal.writeError}
*/
writeError(...messageParts: TerminalWriteParameters): void;
/**
* {@inheritdoc ITerminal.writeErrorLine}
*/
writeErrorLine(...messageParts: TerminalWriteParameters): void;
/**
* {@inheritdoc ITerminal.writeVerbose}
*/
writeVerbose(...messageParts: TerminalWriteParameters): void;
/**
* {@inheritdoc ITerminal.writeVerboseLine}
*/
writeVerboseLine(...messageParts: TerminalWriteParameters): void;
/**
* {@inheritdoc ITerminal.writeDebug}
*/
writeDebug(...messageParts: TerminalWriteParameters): void;
/**
* {@inheritdoc ITerminal.writeDebugLine}
*/
writeDebugLine(...messageParts: TerminalWriteParameters): void;
private _writeSegmentsToProviders;
private _serializeLegacyColorableSequence;
private _normalizeWriteParameters;
}
//# sourceMappingURL=Terminal.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"Terminal.d.ts","sourceRoot":"","sources":["../src/Terminal.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,iBAAiB,EAA4B,MAAM,qBAAqB,CAAC;AAEvF,OAAO,KAAK,EAAE,SAAS,EAAyB,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAsC7F;;;;GAIG;AACH,qBAAa,QAAS,YAAW,SAAS;IACxC,OAAO,CAAC,UAAU,CAAyB;gBAExB,QAAQ,EAAE,iBAAiB;IAK9C;;OAEG;IACI,gBAAgB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI;IAI1D;;OAEG;IACI,kBAAkB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,IAAI;IAM5D;;OAEG;IACI,KAAK,CAAC,GAAG,YAAY,EAAE,uBAAuB,GAAG,IAAI;IAK5D;;OAEG;IACI,SAAS,CAAC,GAAG,YAAY,EAAE,uBAAuB,GAAG,IAAI;IAKhE;;OAEG;IACI,YAAY,CAAC,GAAG,YAAY,EAAE,uBAAuB,GAAG,IAAI;IAcnE;;OAEG;IACI,gBAAgB,CAAC,GAAG,YAAY,EAAE,uBAAuB,GAAG,IAAI;IAcvE;;OAEG;IACI,UAAU,CAAC,GAAG,YAAY,EAAE,uBAAuB,GAAG,IAAI;IAYjE;;OAEG;IACI,cAAc,CAAC,GAAG,YAAY,EAAE,uBAAuB,GAAG,IAAI;IAYrE;;OAEG;IACI,YAAY,CAAC,GAAG,YAAY,EAAE,uBAAuB,GAAG,IAAI;IAKnE;;OAEG;IACI,gBAAgB,CAAC,GAAG,YAAY,EAAE,uBAAuB,GAAG,IAAI;IAKvE;;OAEG;IACI,UAAU,CAAC,GAAG,YAAY,EAAE,uBAAuB,GAAG,IAAI;IAKjE;;OAEG;IACI,cAAc,CAAC,GAAG,YAAY,EAAE,uBAAuB,GAAG,IAAI;IAKrE,OAAO,CAAC,yBAAyB;IA6DjC,OAAO,CAAC,iCAAiC;IA6KzC,OAAO,CAAC,yBAAyB;CAelC"}

348
server/node_modules/@rushstack/terminal/lib/Terminal.js generated vendored Normal file
View File

@@ -0,0 +1,348 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.Terminal = void 0;
const ITerminalProvider_1 = require("./ITerminalProvider");
const Colorize_1 = require("./Colorize");
const AnsiEscape_1 = require("./AnsiEscape");
/**
* Colors used with {@link ILegacyColorableSequence}.
*/
var ColorValue;
(function (ColorValue) {
ColorValue[ColorValue["Black"] = 0] = "Black";
ColorValue[ColorValue["Red"] = 1] = "Red";
ColorValue[ColorValue["Green"] = 2] = "Green";
ColorValue[ColorValue["Yellow"] = 3] = "Yellow";
ColorValue[ColorValue["Blue"] = 4] = "Blue";
ColorValue[ColorValue["Magenta"] = 5] = "Magenta";
ColorValue[ColorValue["Cyan"] = 6] = "Cyan";
ColorValue[ColorValue["White"] = 7] = "White";
ColorValue[ColorValue["Gray"] = 8] = "Gray";
})(ColorValue || (ColorValue = {}));
/**
* Text styles used with {@link ILegacyColorableSequence}.
*/
var TextAttribute;
(function (TextAttribute) {
TextAttribute[TextAttribute["Bold"] = 0] = "Bold";
TextAttribute[TextAttribute["Dim"] = 1] = "Dim";
TextAttribute[TextAttribute["Underline"] = 2] = "Underline";
TextAttribute[TextAttribute["Blink"] = 3] = "Blink";
TextAttribute[TextAttribute["InvertColor"] = 4] = "InvertColor";
TextAttribute[TextAttribute["Hidden"] = 5] = "Hidden";
})(TextAttribute || (TextAttribute = {}));
/**
* This class facilitates writing to a console.
*
* @beta
*/
class Terminal {
constructor(provider) {
this._providers = new Set();
this._providers.add(provider);
}
/**
* {@inheritdoc ITerminal.registerProvider}
*/
registerProvider(provider) {
this._providers.add(provider);
}
/**
* {@inheritdoc ITerminal.unregisterProvider}
*/
unregisterProvider(provider) {
if (this._providers.has(provider)) {
this._providers.delete(provider);
}
}
/**
* {@inheritdoc ITerminal.write}
*/
write(...messageParts) {
const { parts } = this._normalizeWriteParameters(messageParts);
this._writeSegmentsToProviders(parts, ITerminalProvider_1.TerminalProviderSeverity.log, false);
}
/**
* {@inheritdoc ITerminal.writeLine}
*/
writeLine(...messageParts) {
const { parts } = this._normalizeWriteParameters(messageParts);
this._writeSegmentsToProviders(parts, ITerminalProvider_1.TerminalProviderSeverity.log, true);
}
/**
* {@inheritdoc ITerminal.writeWarning}
*/
writeWarning(...messageParts) {
const { parts, options: { doNotOverrideSgrCodes } } = this._normalizeWriteParameters(messageParts);
this._writeSegmentsToProviders(doNotOverrideSgrCodes
? parts
: parts.map((part) => Colorize_1.Colorize.yellow(AnsiEscape_1.AnsiEscape.removeCodes(part))), ITerminalProvider_1.TerminalProviderSeverity.warning, false);
}
/**
* {@inheritdoc ITerminal.writeWarningLine}
*/
writeWarningLine(...messageParts) {
const { parts, options: { doNotOverrideSgrCodes } } = this._normalizeWriteParameters(messageParts);
this._writeSegmentsToProviders(doNotOverrideSgrCodes
? parts
: parts.map((part) => Colorize_1.Colorize.yellow(AnsiEscape_1.AnsiEscape.removeCodes(part))), ITerminalProvider_1.TerminalProviderSeverity.warning, true);
}
/**
* {@inheritdoc ITerminal.writeError}
*/
writeError(...messageParts) {
const { parts, options: { doNotOverrideSgrCodes } } = this._normalizeWriteParameters(messageParts);
this._writeSegmentsToProviders(doNotOverrideSgrCodes ? parts : parts.map((part) => Colorize_1.Colorize.red(AnsiEscape_1.AnsiEscape.removeCodes(part))), ITerminalProvider_1.TerminalProviderSeverity.error, false);
}
/**
* {@inheritdoc ITerminal.writeErrorLine}
*/
writeErrorLine(...messageParts) {
const { parts, options: { doNotOverrideSgrCodes } } = this._normalizeWriteParameters(messageParts);
this._writeSegmentsToProviders(doNotOverrideSgrCodes ? parts : parts.map((part) => Colorize_1.Colorize.red(AnsiEscape_1.AnsiEscape.removeCodes(part))), ITerminalProvider_1.TerminalProviderSeverity.error, true);
}
/**
* {@inheritdoc ITerminal.writeVerbose}
*/
writeVerbose(...messageParts) {
const { parts } = this._normalizeWriteParameters(messageParts);
this._writeSegmentsToProviders(parts, ITerminalProvider_1.TerminalProviderSeverity.verbose, false);
}
/**
* {@inheritdoc ITerminal.writeVerboseLine}
*/
writeVerboseLine(...messageParts) {
const { parts } = this._normalizeWriteParameters(messageParts);
this._writeSegmentsToProviders(parts, ITerminalProvider_1.TerminalProviderSeverity.verbose, true);
}
/**
* {@inheritdoc ITerminal.writeDebug}
*/
writeDebug(...messageParts) {
const { parts } = this._normalizeWriteParameters(messageParts);
this._writeSegmentsToProviders(parts, ITerminalProvider_1.TerminalProviderSeverity.debug, false);
}
/**
* {@inheritdoc ITerminal.writeDebugLine}
*/
writeDebugLine(...messageParts) {
const { parts } = this._normalizeWriteParameters(messageParts);
this._writeSegmentsToProviders(parts, ITerminalProvider_1.TerminalProviderSeverity.debug, true);
}
_writeSegmentsToProviders(segments, severity, followedByEol) {
const linesSegments = [[]];
let currentLineSegments = linesSegments[0];
for (const segment of segments) {
if (typeof segment === 'string') {
currentLineSegments.push(segment);
}
else {
if (segment.isEol) {
linesSegments.push([]);
currentLineSegments = linesSegments[linesSegments.length - 1];
}
else {
currentLineSegments.push(this._serializeLegacyColorableSequence(segment));
}
}
}
const lines = [];
for (const lineSegments of linesSegments) {
lines.push(lineSegments.join(''));
}
if (followedByEol) {
lines.push('');
}
let linesWithoutColor;
const concatenatedLinesWithColorByNewlineChar = new Map();
const concatenatedLinesWithoutColorByNewlineChar = new Map();
for (const provider of this._providers) {
let textToWrite;
const eol = provider.eolCharacter;
if (provider.supportsColor) {
textToWrite = concatenatedLinesWithColorByNewlineChar.get(eol);
if (!textToWrite) {
textToWrite = lines.join(eol);
concatenatedLinesWithColorByNewlineChar.set(eol, textToWrite);
}
}
else {
textToWrite = concatenatedLinesWithoutColorByNewlineChar.get(eol);
if (!textToWrite) {
if (!linesWithoutColor) {
linesWithoutColor = [];
for (const line of lines) {
linesWithoutColor.push(AnsiEscape_1.AnsiEscape.removeCodes(line));
}
}
textToWrite = linesWithoutColor.join(eol);
concatenatedLinesWithoutColorByNewlineChar.set(eol, textToWrite);
}
}
provider.write(textToWrite, severity);
}
}
_serializeLegacyColorableSequence(segment) {
const startColorCodes = [];
const endColorCodes = [];
switch (segment.foregroundColor) {
case ColorValue.Black: {
startColorCodes.push(Colorize_1.SgrParameterAttribute.BlackForeground);
endColorCodes.push(Colorize_1.SgrParameterAttribute.DefaultForeground);
break;
}
case ColorValue.Red: {
startColorCodes.push(Colorize_1.SgrParameterAttribute.RedForeground);
endColorCodes.push(Colorize_1.SgrParameterAttribute.DefaultForeground);
break;
}
case ColorValue.Green: {
startColorCodes.push(Colorize_1.SgrParameterAttribute.GreenForeground);
endColorCodes.push(Colorize_1.SgrParameterAttribute.DefaultForeground);
break;
}
case ColorValue.Yellow: {
startColorCodes.push(Colorize_1.SgrParameterAttribute.YellowForeground);
endColorCodes.push(Colorize_1.SgrParameterAttribute.DefaultForeground);
break;
}
case ColorValue.Blue: {
startColorCodes.push(Colorize_1.SgrParameterAttribute.BlueForeground);
endColorCodes.push(Colorize_1.SgrParameterAttribute.DefaultForeground);
break;
}
case ColorValue.Magenta: {
startColorCodes.push(Colorize_1.SgrParameterAttribute.MagentaForeground);
endColorCodes.push(Colorize_1.SgrParameterAttribute.DefaultForeground);
break;
}
case ColorValue.Cyan: {
startColorCodes.push(Colorize_1.SgrParameterAttribute.CyanForeground);
endColorCodes.push(Colorize_1.SgrParameterAttribute.DefaultForeground);
break;
}
case ColorValue.White: {
startColorCodes.push(Colorize_1.SgrParameterAttribute.WhiteForeground);
endColorCodes.push(Colorize_1.SgrParameterAttribute.DefaultForeground);
break;
}
case ColorValue.Gray: {
startColorCodes.push(Colorize_1.SgrParameterAttribute.GrayForeground);
endColorCodes.push(Colorize_1.SgrParameterAttribute.DefaultForeground);
break;
}
}
switch (segment.backgroundColor) {
case ColorValue.Black: {
startColorCodes.push(Colorize_1.SgrParameterAttribute.BlackBackground);
endColorCodes.push(Colorize_1.SgrParameterAttribute.DefaultBackground);
break;
}
case ColorValue.Red: {
startColorCodes.push(Colorize_1.SgrParameterAttribute.RedBackground);
endColorCodes.push(Colorize_1.SgrParameterAttribute.DefaultBackground);
break;
}
case ColorValue.Green: {
startColorCodes.push(Colorize_1.SgrParameterAttribute.GreenBackground);
endColorCodes.push(Colorize_1.SgrParameterAttribute.DefaultBackground);
break;
}
case ColorValue.Yellow: {
startColorCodes.push(Colorize_1.SgrParameterAttribute.YellowBackground);
endColorCodes.push(Colorize_1.SgrParameterAttribute.DefaultBackground);
break;
}
case ColorValue.Blue: {
startColorCodes.push(Colorize_1.SgrParameterAttribute.BlueBackground);
endColorCodes.push(Colorize_1.SgrParameterAttribute.DefaultBackground);
break;
}
case ColorValue.Magenta: {
startColorCodes.push(Colorize_1.SgrParameterAttribute.MagentaBackground);
endColorCodes.push(Colorize_1.SgrParameterAttribute.DefaultBackground);
break;
}
case ColorValue.Cyan: {
startColorCodes.push(Colorize_1.SgrParameterAttribute.CyanBackground);
endColorCodes.push(Colorize_1.SgrParameterAttribute.DefaultBackground);
break;
}
case ColorValue.White: {
startColorCodes.push(Colorize_1.SgrParameterAttribute.WhiteBackground);
endColorCodes.push(Colorize_1.SgrParameterAttribute.DefaultBackground);
break;
}
case ColorValue.Gray: {
startColorCodes.push(Colorize_1.SgrParameterAttribute.GrayBackground);
endColorCodes.push(49);
break;
}
}
if (segment.textAttributes) {
for (const textAttribute of segment.textAttributes) {
switch (textAttribute) {
case TextAttribute.Bold: {
startColorCodes.push(Colorize_1.SgrParameterAttribute.Bold);
endColorCodes.push(Colorize_1.SgrParameterAttribute.NormalColorOrIntensity);
break;
}
case TextAttribute.Dim: {
startColorCodes.push(Colorize_1.SgrParameterAttribute.Dim);
endColorCodes.push(Colorize_1.SgrParameterAttribute.NormalColorOrIntensity);
break;
}
case TextAttribute.Underline: {
startColorCodes.push(Colorize_1.SgrParameterAttribute.Underline);
endColorCodes.push(Colorize_1.SgrParameterAttribute.UnderlineOff);
break;
}
case TextAttribute.Blink: {
startColorCodes.push(Colorize_1.SgrParameterAttribute.Blink);
endColorCodes.push(Colorize_1.SgrParameterAttribute.BlinkOff);
break;
}
case TextAttribute.InvertColor: {
startColorCodes.push(Colorize_1.SgrParameterAttribute.InvertColor);
endColorCodes.push(Colorize_1.SgrParameterAttribute.InvertColorOff);
break;
}
case TextAttribute.Hidden: {
startColorCodes.push(Colorize_1.SgrParameterAttribute.Hidden);
endColorCodes.push(Colorize_1.SgrParameterAttribute.HiddenOff);
break;
}
}
}
}
const resultSegments = [];
for (let j = 0; j < startColorCodes.length; j++) {
const code = startColorCodes[j];
resultSegments.push(AnsiEscape_1.AnsiEscape.getEscapeSequenceForAnsiCode(code));
}
resultSegments.push(segment.text);
for (let j = endColorCodes.length - 1; j >= 0; j--) {
const code = endColorCodes[j];
resultSegments.push(AnsiEscape_1.AnsiEscape.getEscapeSequenceForAnsiCode(code));
}
return resultSegments.join('');
}
_normalizeWriteParameters(parameters) {
if (parameters.length === 0) {
return { parts: [], options: {} };
}
else {
const lastParameter = parameters[parameters.length - 1];
if (typeof lastParameter === 'string') {
return { parts: parameters, options: {} };
}
else {
return { parts: parameters.slice(0, -1), options: lastParameter };
}
}
}
}
exports.Terminal = Terminal;
//# sourceMappingURL=Terminal.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,33 @@
import { Writable, type WritableOptions } from 'stream';
import type { ITerminal } from './ITerminal';
import { TerminalProviderSeverity } from './ITerminalProvider';
/**
* Options for {@link TerminalStreamWritable}.
*
* @beta
*/
export interface ITerminalStreamWritableOptions {
/**
* The {@link ITerminal} that the Writable will write to.
*/
terminal: ITerminal;
/**
* The severity of the messages that will be written to the {@link ITerminal}.
*/
severity: TerminalProviderSeverity;
/**
* Options for the underlying Writable.
*/
writableOptions?: WritableOptions;
}
/**
* A adapter to allow writing to a provided terminal using Writable streams.
*
* @beta
*/
export declare class TerminalStreamWritable extends Writable {
private _writeMethod;
constructor(options: ITerminalStreamWritableOptions);
_write(chunk: string | Buffer | Uint8Array, encoding: string, callback: (error?: Error | null) => void): void;
}
//# sourceMappingURL=TerminalStreamWritable.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"TerminalStreamWritable.d.ts","sourceRoot":"","sources":["../src/TerminalStreamWritable.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,MAAM,QAAQ,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAE/D;;;;GAIG;AACH,MAAM,WAAW,8BAA8B;IAC7C;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,QAAQ,EAAE,wBAAwB,CAAC;IACnC;;OAEG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAED;;;;GAIG;AACH,qBAAa,sBAAuB,SAAQ,QAAQ;IAClD,OAAO,CAAC,YAAY,CAAyB;gBAE1B,OAAO,EAAE,8BAA8B;IA0BnD,MAAM,CACX,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,UAAU,EACnC,QAAQ,EAAE,MAAM,EAEhB,QAAQ,EAAE,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,GACvC,IAAI;CAUR"}

View File

@@ -0,0 +1,53 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.TerminalStreamWritable = void 0;
const stream_1 = require("stream");
const ITerminalProvider_1 = require("./ITerminalProvider");
/**
* A adapter to allow writing to a provided terminal using Writable streams.
*
* @beta
*/
class TerminalStreamWritable extends stream_1.Writable {
constructor(options) {
const { terminal, severity, writableOptions } = options;
super(writableOptions);
this._writev = undefined;
switch (severity) {
case ITerminalProvider_1.TerminalProviderSeverity.log:
this._writeMethod = terminal.write.bind(terminal);
break;
case ITerminalProvider_1.TerminalProviderSeverity.verbose:
this._writeMethod = terminal.writeVerbose.bind(terminal);
break;
case ITerminalProvider_1.TerminalProviderSeverity.debug:
this._writeMethod = terminal.writeDebug.bind(terminal);
break;
case ITerminalProvider_1.TerminalProviderSeverity.warning:
this._writeMethod = terminal.writeWarning.bind(terminal);
break;
case ITerminalProvider_1.TerminalProviderSeverity.error:
this._writeMethod = terminal.writeError.bind(terminal);
break;
default:
throw new Error(`Unknown severity: ${severity}`);
}
}
_write(chunk, encoding,
// eslint-disable-next-line @rushstack/no-new-null
callback) {
try {
const chunkData = typeof chunk === 'string' ? chunk : Buffer.from(chunk);
this._writeMethod(chunkData.toString());
}
catch (e) {
callback(e);
return;
}
callback();
}
}
exports.TerminalStreamWritable = TerminalStreamWritable;
//# sourceMappingURL=TerminalStreamWritable.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"TerminalStreamWritable.js","sourceRoot":"","sources":["../src/TerminalStreamWritable.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,mCAAwD;AAExD,2DAA+D;AAsB/D;;;;GAIG;AACH,MAAa,sBAAuB,SAAQ,iBAAQ;IAGlD,YAAmB,OAAuC;QACxD,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC;QACxD,KAAK,CAAC,eAAe,CAAC,CAAC;QAEvB,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;QACzB,QAAQ,QAAQ,EAAE,CAAC;YACjB,KAAK,4CAAwB,CAAC,GAAG;gBAC/B,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAClD,MAAM;YACR,KAAK,4CAAwB,CAAC,OAAO;gBACnC,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACzD,MAAM;YACR,KAAK,4CAAwB,CAAC,KAAK;gBACjC,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACvD,MAAM;YACR,KAAK,4CAAwB,CAAC,OAAO;gBACnC,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACzD,MAAM;YACR,KAAK,4CAAwB,CAAC,KAAK;gBACjC,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACvD,MAAM;YACR;gBACE,MAAM,IAAI,KAAK,CAAC,qBAAqB,QAAQ,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAEM,MAAM,CACX,KAAmC,EACnC,QAAgB;IAChB,kDAAkD;IAClD,QAAwC;QAExC,IAAI,CAAC;YACH,MAAM,SAAS,GAAoB,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1F,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,CAAU,EAAE,CAAC;YACpB,QAAQ,CAAC,CAAU,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,QAAQ,EAAE,CAAC;IACb,CAAC;CACF;AA5CD,wDA4CC","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 { Writable, type WritableOptions } from 'stream';\nimport type { ITerminal } from './ITerminal';\nimport { TerminalProviderSeverity } from './ITerminalProvider';\n\n/**\n * Options for {@link TerminalStreamWritable}.\n *\n * @beta\n */\nexport interface ITerminalStreamWritableOptions {\n /**\n * The {@link ITerminal} that the Writable will write to.\n */\n terminal: ITerminal;\n /**\n * The severity of the messages that will be written to the {@link ITerminal}.\n */\n severity: TerminalProviderSeverity;\n /**\n * Options for the underlying Writable.\n */\n writableOptions?: WritableOptions;\n}\n\n/**\n * A adapter to allow writing to a provided terminal using Writable streams.\n *\n * @beta\n */\nexport class TerminalStreamWritable extends Writable {\n private _writeMethod: (data: string) => void;\n\n public constructor(options: ITerminalStreamWritableOptions) {\n const { terminal, severity, writableOptions } = options;\n super(writableOptions);\n\n this._writev = undefined;\n switch (severity) {\n case TerminalProviderSeverity.log:\n this._writeMethod = terminal.write.bind(terminal);\n break;\n case TerminalProviderSeverity.verbose:\n this._writeMethod = terminal.writeVerbose.bind(terminal);\n break;\n case TerminalProviderSeverity.debug:\n this._writeMethod = terminal.writeDebug.bind(terminal);\n break;\n case TerminalProviderSeverity.warning:\n this._writeMethod = terminal.writeWarning.bind(terminal);\n break;\n case TerminalProviderSeverity.error:\n this._writeMethod = terminal.writeError.bind(terminal);\n break;\n default:\n throw new Error(`Unknown severity: ${severity}`);\n }\n }\n\n public _write(\n chunk: string | Buffer | Uint8Array,\n encoding: string,\n // eslint-disable-next-line @rushstack/no-new-null\n callback: (error?: Error | null) => void\n ): void {\n try {\n const chunkData: string | Buffer = typeof chunk === 'string' ? chunk : Buffer.from(chunk);\n this._writeMethod(chunkData.toString());\n } catch (e: unknown) {\n callback(e as Error);\n return;\n }\n callback();\n }\n}\n"]}

View File

@@ -0,0 +1,68 @@
import { TerminalWritable, type ITerminalWritableOptions } from './TerminalWritable';
/**
* Constructor options for {@link TerminalTransform}.
*
* @public
*/
export interface ITerminalTransformOptions extends ITerminalWritableOptions {
/**
* The target `TerminalWritable` that the `TerminalTransform` will write its
* output to.
*/
destination: TerminalWritable;
/**
* Prevents the {@link TerminalTransform.destination} object from being
* closed automatically when the transform is closed.
*
* @remarks
* When a transform is closed, normally it will automatically close its destination
* `TerminalWritable` object. There are two ways to prevent that: either by setting
* `preventDestinationAutoclose` to `true` for the transform, or by setting
* {@link TerminalWritable.preventAutoclose} to `true` for the `destination` object.
*/
preventDestinationAutoclose?: boolean;
}
/**
* The abstract base class for {@link TerminalWritable} objects that receive an input,
* transform it somehow, and then write the output to another `TerminalWritable`.
*
* @remarks
*
* The `TerminalTransform` and {@link SplitterTransform} base classes formalize the idea
* of modeling data flow as a directed acyclic graph of reusable transforms, whose
* final outputs are `TerminalWritable` objects.
*
* The design is based loosely on the `WritableStream` and `TransformStream` classes from
* the system {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Concepts
* | Streams API}, except that instead of asynchronous byte streams, the `TerminalWritable`
* system synchronously transmits human readable messages intended to be rendered on a
* text console or log file.
*
* The main feature of the `TerminalTransform` class is its {@link TerminalTransform.destination}
* property, which tracks the next link in the graph.
*
* @public
*/
export declare abstract class TerminalTransform extends TerminalWritable {
/** {@inheritDoc ITerminalTransformOptions.destination} */
readonly destination: TerminalWritable;
/** {@inheritDoc ITerminalTransformOptions.preventDestinationAutoclose} */
readonly preventDestinationAutoclose: boolean;
constructor(options: ITerminalTransformOptions);
/** @override */
protected onClose(): void;
/**
* The default implementation of {@link TerminalTransform.onClose} calls this
* method, which closes the {@link TerminalTransform.destination} if appropriate.
*
* @remarks
* The destination will not be closed if its {@link TerminalWritable.preventAutoclose}
* property is `true`. The destination will not be closed if
* {@link ITerminalTransformOptions.preventDestinationAutoclose}
* is `true`.
*
* @sealed
*/
protected autocloseDestination(): void;
}
//# sourceMappingURL=TerminalTransform.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"TerminalTransform.d.ts","sourceRoot":"","sources":["../src/TerminalTransform.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,KAAK,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAErF;;;;GAIG;AACH,MAAM,WAAW,yBAA0B,SAAQ,wBAAwB;IACzE;;;OAGG;IACH,WAAW,EAAE,gBAAgB,CAAC;IAE9B;;;;;;;;;OASG;IACH,2BAA2B,CAAC,EAAE,OAAO,CAAC;CACvC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,8BAAsB,iBAAkB,SAAQ,gBAAgB;IAC9D,0DAA0D;IAC1D,SAAgB,WAAW,EAAE,gBAAgB,CAAC;IAE9C,0EAA0E;IAC1E,SAAgB,2BAA2B,EAAE,OAAO,CAAC;gBAElC,OAAO,EAAE,yBAAyB;IAMrD,gBAAgB;IAChB,SAAS,CAAC,OAAO,IAAI,IAAI;IAIzB;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,oBAAoB,IAAI,IAAI;CAKvC"}

View File

@@ -0,0 +1,57 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.TerminalTransform = void 0;
const TerminalWritable_1 = require("./TerminalWritable");
/**
* The abstract base class for {@link TerminalWritable} objects that receive an input,
* transform it somehow, and then write the output to another `TerminalWritable`.
*
* @remarks
*
* The `TerminalTransform` and {@link SplitterTransform} base classes formalize the idea
* of modeling data flow as a directed acyclic graph of reusable transforms, whose
* final outputs are `TerminalWritable` objects.
*
* The design is based loosely on the `WritableStream` and `TransformStream` classes from
* the system {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Concepts
* | Streams API}, except that instead of asynchronous byte streams, the `TerminalWritable`
* system synchronously transmits human readable messages intended to be rendered on a
* text console or log file.
*
* The main feature of the `TerminalTransform` class is its {@link TerminalTransform.destination}
* property, which tracks the next link in the graph.
*
* @public
*/
class TerminalTransform extends TerminalWritable_1.TerminalWritable {
constructor(options) {
super();
this.destination = options.destination;
this.preventDestinationAutoclose = !!options.preventDestinationAutoclose;
}
/** @override */
onClose() {
this.autocloseDestination();
}
/**
* The default implementation of {@link TerminalTransform.onClose} calls this
* method, which closes the {@link TerminalTransform.destination} if appropriate.
*
* @remarks
* The destination will not be closed if its {@link TerminalWritable.preventAutoclose}
* property is `true`. The destination will not be closed if
* {@link ITerminalTransformOptions.preventDestinationAutoclose}
* is `true`.
*
* @sealed
*/
autocloseDestination() {
if (!this.preventDestinationAutoclose && !this.destination.preventAutoclose) {
this.destination.close();
}
}
}
exports.TerminalTransform = TerminalTransform;
//# sourceMappingURL=TerminalTransform.js.map

View File

@@ -0,0 +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"]}

View File

@@ -0,0 +1,125 @@
import type { ITerminalChunk } from './ITerminalChunk';
/**
* Constructor options for {@link TerminalWritable}
*
* @public
*/
export interface ITerminalWritableOptions {
/**
* When this object is the {@link TerminalTransform.destination} for a transform,
* the transform will automatically close this object. Set `preventAutoclose` to `true`
* to prevent that behavior.
*
* @remarks
* When a transform is closed, normally it will automatically close its destination
* `TerminalWritable` object. There are two ways to prevent that: either by setting
* `preventDestinationAutoclose` to `true` for the transform, or by setting
* {@link TerminalWritable.preventAutoclose} to `true` for the `destination` object.
*/
preventAutoclose?: boolean;
}
/**
* The abstract base class for objects that can present, route, or process text output for
* a console application. This output is typically prepared using
* the {@link Terminal} API.
*
* @remarks
*
* The design is based loosely on the `WritableStream` and `TransformStream` classes from
* the system {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Concepts
* | Streams API}, except that instead of asynchronous byte streams, the `TerminalWritable`
* system synchronously transmits human readable messages intended to be rendered on a text
* console or log file.
*
* Consider a console application whose output may need to be processed in different ways
* before finally being output. The conceptual block diagram might look like this:
*
* ```
* [Terminal API]
* |
* V
* [normalize newlines]
* |
* V
* +----[splitter]-------+
* | |
* V V
* [shell console] [remove ANSI colors]
* |
* V
* [write to build.log]
* ```
*
* The application uses the `Terminal` API to print `stdout` and `stderr` messages, for example with standardized
* formatting for errors and warnings, and ANSI escapes to make nice colors. Maybe it also includes text
* received from external processes, whose newlines may be inconsistent. Ultimately we want to write the
* output to the shell console and a `build.log` file, but we don't want to put ANSI colors in the build log.
*
* For the above example, `[shell console]` and `[write to build.log]` would be modeled as subclasses of
* `TerminalWritable`. The `[normalize newlines]` and `[remove ANSI colors]` steps are modeled as subclasses
* of {@link TerminalTransform}, because they output to a "destination" object. The `[splitter]` would be
* implemented using {@link SplitterTransform}.
*
* The stream of messages are {@link ITerminalChunk} objects, which can represent both `stdout` and `stderr`
* channels. The pipeline operates synchronously on each chunk, but by processing one chunk at a time,
* it avoids storing the entire output in memory. This means that operations like `[remove ANSI colors]`
* cannot be simple regular expressions -- they must be implemented as state machines ({@link TextRewriter}
* subclasses) capable of matching substrings that span multiple chunks.
*
* @public
*/
export declare abstract class TerminalWritable {
private _isOpen;
readonly preventAutoclose: boolean;
constructor(options?: ITerminalWritableOptions);
/**
* This property is initially `true` when the object is constructed, and becomes `false`
* when `close()` is called.
* @sealed
*/
get isOpen(): boolean;
/**
* Upstream objects call this method to provide inputs to this object.
*
* @remarks
* The subclass provides its implementation via the the {@link TerminalWritable.onWriteChunk}
* method, which is called by `writeChunk()`.
*
* The object that calls `writeChunk()` must call `close()` when it is finished;
* failing to do so may introduce a resource leak, or may prevent some buffered data from
* being written.
*
* @sealed
*/
writeChunk(chunk: ITerminalChunk): void;
/**
* Subclasses should implement this `abstract` method to process the chunk.
*/
protected abstract onWriteChunk(chunk: ITerminalChunk): void;
/**
* Calling this method flushes any remaining outputs and permanently transitions the
* `TerminalWritable` to a "closed" state, where no further chunks can be written.
*
* @remarks
* The subclass provides its implementation via the the {@link TerminalWritable.onClose}
* method, which is called by `close()`.
*
* If this method is called more than once, the additional calls are ignored;
* `TerminalWritable.onClose` will be called at most once.
*
* @sealed
*/
close(): void;
/**
* Subclasses can override this empty method to perform additional operations
* such as closing a file handle.
*
* @remarks
* It is guaranteed that this method will be called at most once during the lifetime
* of a `TerminalWritable` object.
*
* @virtual
*/
protected onClose(): void;
}
//# sourceMappingURL=TerminalWritable.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"TerminalWritable.d.ts","sourceRoot":"","sources":["../src/TerminalWritable.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,8BAAsB,gBAAgB;IACpC,OAAO,CAAC,OAAO,CAAU;IAEzB,SAAgB,gBAAgB,EAAE,OAAO,CAAC;gBAEvB,OAAO,CAAC,EAAE,wBAAwB;IAUrD;;;;OAIG;IACH,IAAW,MAAM,IAAI,OAAO,CAE3B;IAED;;;;;;;;;;;;OAYG;IACI,UAAU,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IAO9C;;OAEG;IACH,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IAE5D;;;;;;;;;;;;OAYG;IACI,KAAK,IAAI,IAAI;IAOpB;;;;;;;;;OASG;IACH,SAAS,CAAC,OAAO,IAAI,IAAI;CAC1B"}

View File

@@ -0,0 +1,123 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See LICENSE in the project root for license information.
Object.defineProperty(exports, "__esModule", { value: true });
exports.TerminalWritable = void 0;
/**
* The abstract base class for objects that can present, route, or process text output for
* a console application. This output is typically prepared using
* the {@link Terminal} API.
*
* @remarks
*
* The design is based loosely on the `WritableStream` and `TransformStream` classes from
* the system {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Concepts
* | Streams API}, except that instead of asynchronous byte streams, the `TerminalWritable`
* system synchronously transmits human readable messages intended to be rendered on a text
* console or log file.
*
* Consider a console application whose output may need to be processed in different ways
* before finally being output. The conceptual block diagram might look like this:
*
* ```
* [Terminal API]
* |
* V
* [normalize newlines]
* |
* V
* +----[splitter]-------+
* | |
* V V
* [shell console] [remove ANSI colors]
* |
* V
* [write to build.log]
* ```
*
* The application uses the `Terminal` API to print `stdout` and `stderr` messages, for example with standardized
* formatting for errors and warnings, and ANSI escapes to make nice colors. Maybe it also includes text
* received from external processes, whose newlines may be inconsistent. Ultimately we want to write the
* output to the shell console and a `build.log` file, but we don't want to put ANSI colors in the build log.
*
* For the above example, `[shell console]` and `[write to build.log]` would be modeled as subclasses of
* `TerminalWritable`. The `[normalize newlines]` and `[remove ANSI colors]` steps are modeled as subclasses
* of {@link TerminalTransform}, because they output to a "destination" object. The `[splitter]` would be
* implemented using {@link SplitterTransform}.
*
* The stream of messages are {@link ITerminalChunk} objects, which can represent both `stdout` and `stderr`
* channels. The pipeline operates synchronously on each chunk, but by processing one chunk at a time,
* it avoids storing the entire output in memory. This means that operations like `[remove ANSI colors]`
* cannot be simple regular expressions -- they must be implemented as state machines ({@link TextRewriter}
* subclasses) capable of matching substrings that span multiple chunks.
*
* @public
*/
class TerminalWritable {
constructor(options) {
this._isOpen = true;
if (!options) {
options = {};
}
this.preventAutoclose = !!options.preventAutoclose;
}
/**
* This property is initially `true` when the object is constructed, and becomes `false`
* when `close()` is called.
* @sealed
*/
get isOpen() {
return this._isOpen;
}
/**
* Upstream objects call this method to provide inputs to this object.
*
* @remarks
* The subclass provides its implementation via the the {@link TerminalWritable.onWriteChunk}
* method, which is called by `writeChunk()`.
*
* The object that calls `writeChunk()` must call `close()` when it is finished;
* failing to do so may introduce a resource leak, or may prevent some buffered data from
* being written.
*
* @sealed
*/
writeChunk(chunk) {
if (!this._isOpen) {
throw new Error('Writer was already closed');
}
this.onWriteChunk(chunk);
}
/**
* Calling this method flushes any remaining outputs and permanently transitions the
* `TerminalWritable` to a "closed" state, where no further chunks can be written.
*
* @remarks
* The subclass provides its implementation via the the {@link TerminalWritable.onClose}
* method, which is called by `close()`.
*
* If this method is called more than once, the additional calls are ignored;
* `TerminalWritable.onClose` will be called at most once.
*
* @sealed
*/
close() {
if (this._isOpen) {
this.onClose();
this._isOpen = false;
}
}
/**
* Subclasses can override this empty method to perform additional operations
* such as closing a file handle.
*
* @remarks
* It is guaranteed that this method will be called at most once during the lifetime
* of a `TerminalWritable` object.
*
* @virtual
*/
onClose() { }
}
exports.TerminalWritable = TerminalWritable;
//# sourceMappingURL=TerminalWritable.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,70 @@
import type { Brand } from '@rushstack/node-core-library';
/**
* Represents the internal state of a {@link TextRewriter} subclass.
*
* @remarks
* For example, suppose that {@link NormalizeNewlinesTextRewriter} will be used to rewrite
* the input `"line 1\r\nline 2\r\n"` to become `"line 1\nline 2\n"`. But suppose that the `"\r\n"`
* pair is split across two chunks:
*
* ```ts
* const rewriter: NormalizeNewlinesTextRewriter = new NormalizeNewlinesTextRewriter(NewlineKind.Lf);
* const state: TextRewriterState = rewriter.initialize();
* let output: string = rewriter.process(state, 'line 1\r');
* output += rewriter.process(state, '\nline 2\r\n');
* output += rewriter.close(state);
*
* // The final "output" value is: "line 1\nline 2\n"
* ```
*
* The `TextRewriterState` keeps track of this context, so that split `"\r"` and `"\n"` are
* interpreted as a single newline.
*
* @public
*/
export type TextRewriterState = Brand<unknown, 'TextRewriterState'>;
/**
* The abstract base class for operations that can be applied by {@link TextRewriterTransform}.
*
* @remarks
* The {@link TextRewriterTransform} applies one or more character rewriting operations to its
* chunk stream. Since these operations are applied separately to `stderr` and `stdout`, the
* state is stored in an opaque `TextRewriterState` object.
*
* Conceptually, a `TextRewriter` subclass is very similar to a regular expression, with the difference
* that `RegExp` operates on a text string, whereas `TextRewriter` operates on a stream of characters.
*
* The two most common subclasses are {@link NormalizeNewlinesTextRewriter} and {@link RemoveColorsTextRewriter}.
*
* A rewriting operation starts with `initialize()`, followed by any number of `process()` calls, and
* then finishes with `close()`. For example:
*
* ```ts
* const rewriter: NormalizeNewlinesTextRewriter = new NormalizeNewlinesTextRewriter(NewlineKind.Lf);
* const state: TextRewriterState = rewriter.initialize();
* let output: string = rewriter.process(state, 'line 1\r');
* output += rewriter.process(state, '\nline 2\r\n');
* output += rewriter.close(state);
*
* // The final "output" value is: "line 1\nline 2\n"
* ```
*
* After `close()` has been called, the `TextRewriterState` state should not be reused.
*
* @public
*/
export declare abstract class TextRewriter {
/**
* Create a new `TextRewriterState` object that can be used to process a stream of characters.
*/
abstract initialize(): TextRewriterState;
/**
* Rewrite the next sequence of characters from the input stream, returning the modified output.
*/
abstract process(state: TextRewriterState, input: string): string;
/**
* Close the `TextRewriterState` object and return any buffered output.
*/
abstract close(state: TextRewriterState): string;
}
//# sourceMappingURL=TextRewriter.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"TextRewriter.d.ts","sourceRoot":"","sources":["../src/TextRewriter.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,8BAA8B,CAAC;AAE1D;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,MAAM,iBAAiB,GAAG,KAAK,CAAC,OAAO,EAAE,mBAAmB,CAAC,CAAC;AAEpE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,8BAAsB,YAAY;IAChC;;OAEG;aACa,UAAU,IAAI,iBAAiB;IAE/C;;OAEG;aACa,OAAO,CAAC,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;IAExE;;OAEG;aACa,KAAK,CAAC,KAAK,EAAE,iBAAiB,GAAG,MAAM;CACxD"}

Some files were not shown because too many files have changed in this diff Show More