Skip to content

Commit

Permalink
Add stderr support (#9)
Browse files Browse the repository at this point in the history
Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
  • Loading branch information
tom-sherman and sindresorhus committed Sep 1, 2019
1 parent d879caf commit 1d248b6
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 4 deletions.
30 changes: 29 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ declare namespace terminalLink {

declare const terminalLink: {
/**
Create a clickable link in the terminal.
Create a clickable link in the terminal's stdout.
[Supported terminals.](https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda)
For unsupported terminals, the link will be printed in parens after the text: `My website (https://sindresorhus.com)`.
Expand All @@ -36,6 +36,34 @@ declare const terminalLink: {
*/
readonly isSupported: boolean;

readonly stderr: {
/**
Create a clickable link in the terminal's stderr.
[Supported terminals.](https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda)
For unsupported terminals, the link will be printed in parens after the text: `My website (https://sindresorhus.com)`.
@param text - Text to linkify.
@param url - URL to link to.
@example
```
import terminalLink = require('terminal-link');
const link = terminalLink.stderr('My Website', 'https://sindresorhus.com');
console.error(link);
```
*/
(text: string, url: string, options?: terminalLink.Options): string;

/**
Check whether the terminal's stderr support links.
Prefer just using the default fallback or the `fallback` option whenever possible.
*/
readonly isSupported: boolean;
}

// TODO: Remove this for the next major release
default: typeof terminalLink;
};
Expand Down
9 changes: 7 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@
const ansiEscapes = require('ansi-escapes');
const supportsHyperlinks = require('supports-hyperlinks');

module.exports = (text, url, options = {}) => {
if (!supportsHyperlinks.stdout) {
const terminalLink = (text, url, {target = 'stdout', ...options} = {}) => {
if (!supportsHyperlinks[target]) {
return options.fallback ? options.fallback(text, url) : `${text} (\u200B${url}\u200B)`;
}

return ansiEscapes.link(text, url);
};

module.exports = (text, url, options = {}) => terminalLink(text, url, options);

module.exports.stderr = (text, url, options = {}) => terminalLink(text, url, {target: 'stderr', ...options});

// TODO: Remove this for the next major release
module.exports.default = module.exports;
module.exports.isSupported = supportsHyperlinks.stdout;
module.exports.stderr.isSupported = supportsHyperlinks.stderr;
12 changes: 12 additions & 0 deletions index.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,15 @@ expectType<string>(
);

expectType<boolean>(terminalLink.isSupported);

// stderr

expectType<string>(terminalLink.stderr('text', 'url'));

expectType<string>(
terminalLink.stderr('text', 'url', {
fallback: (text, url) => `[${text}](${url})`
})
);

expectType<boolean>(terminalLink.stderr.isSupported)
37 changes: 36 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ console.log(link);

### terminalLink(text, url, [options])

Create a link for use in stdout.

[Supported terminals.](https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda)

For unsupported terminals, the link will be printed in parens after the text: `My website (https://sindresorhus.com)`.
Expand Down Expand Up @@ -56,10 +58,43 @@ Override the default fallback. The function receives the `text` and `url` as par

Type: `boolean`

Check whether the terminal support links.
Check whether the terminal's stdout supports links.

Prefer just using the default fallback or the `fallback` option whenever possible.

### terminalLink.stderr(text, url, [options])

Create a link for use in stdout.

#### text

Type: `string`

Text to linkify.

#### url

Type: `string`

URL to link to.

#### options

Type: `Object`

##### fallback

Type: `Function`

Override the default fallback. The function receives the `text` and `url` as parameters and is expected to return a string.

### terminalLink.stderr.isSupported

Type: `boolean`

Check whether the terminal's stderr supports links.

Prefer just using the default fallback or the `fallback` option whenever possible.

## Related

Expand Down
34 changes: 34 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ test('main', t => {
t.is(actual, '\u001B]8;;https://sindresorhus.com\u0007My Website\u001B]8;;\u0007');
});

test('stderr', t => {
process.env.FORCE_HYPERLINK = 1;
const m = require('.');

const actual = m.stderr('My Website', 'https://sindresorhus.com');
console.log(actual);
t.is(actual, '\u001B]8;;https://sindresorhus.com\u0007My Website\u001B]8;;\u0007');
});

test('default fallback', t => {
process.env.FORCE_HYPERLINK = 0;
const m = require('.');
Expand All @@ -27,6 +36,15 @@ test('default fallback', t => {
t.is(actual, 'My Website (\u200Bhttps://sindresorhus.com\u200B)');
});

test('stderr default fallback', t => {
process.env.FORCE_HYPERLINK = 0;
const m = require('.');

const actual = m.stderr('My Website', 'https://sindresorhus.com');
console.log(actual);
t.is(actual, 'My Website (\u200Bhttps://sindresorhus.com\u200B)');
});

test('custom fallback', t => {
process.env.FORCE_HYPERLINK = 0;
const m = require('.');
Expand All @@ -38,7 +56,23 @@ test('custom fallback', t => {
t.is(actual, 'My Website: https://sindresorhus.com');
});

test('custom fallback stderr', t => {
process.env.FORCE_HYPERLINK = 0;
const m = require('.');

const actual = m.stderr('My Website', 'https://sindresorhus.com', {
fallback: (text, url) => `${text}: ${url}`
});
console.log(actual);
t.is(actual, 'My Website: https://sindresorhus.com');
});

test('isSupported', t => {
const m = require('.');
t.is(typeof m.isSupported, 'boolean');
});

test('isSupported stderr', t => {
const m = require('.');
t.is(typeof m.stderr.isSupported, 'boolean');
});

0 comments on commit 1d248b6

Please sign in to comment.