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

1
server/node_modules/plop/.gitattributes generated vendored Normal file
View File

@@ -0,0 +1 @@
* text=auto eol=lf

12
server/node_modules/plop/.nycrc generated vendored Normal file
View File

@@ -0,0 +1,12 @@
{
"all": true,
"reporter": [
"text",
"text-summary",
"lcov"
],
"include": [
"bin/**/*.js",
"src/**/*.js"
]
}

48
server/node_modules/plop/.turbo/turbo-test.log generated vendored Normal file
View File

@@ -0,0 +1,48 @@
> plop@4.0.0 test:instrument
> nyc instrument ./bin ./instrumented/bin && nyc instrument ./src ./instrumented/src && cp package.json ./instrumented
Browserslist: caniuse-lite is outdated. Please run:
npx browserslist@latest --update-db
Why you should do it regularly: https://github.com/browserslist/browserslist#browsers-data-updating
Browserslist: caniuse-lite is outdated. Please run:
npx browserslist@latest --update-db
Why you should do it regularly: https://github.com/browserslist/browserslist#browsers-data-updating
> plop@4.0.0 vitest
> vitest run
 RUN  v1.1.0 C:/Users/crutchcorn/git/Plop/plop/packages/plop
✓ tests/typescript.spec.js  (1 test) 2806ms
✓ tests/action-failure.spec.js  (1 test) 2932ms
✓ tests/actions.spec.js  (6 tests | 4 skipped) 6462ms
✓ tests/esm.spec.js  (4 tests) 11837ms
✓ tests/wrapper.spec.js  (5 tests) 14946ms
✓ tests/input-processing.spec.js  (16 tests | 1 skipped) 38264ms
 Test Files  6 passed (6)
 Tests  28 passed | 5 todo (33)
 Start at  14:27:42
 Duration  39.24s (transform 133ms, setup 652ms, collect 239ms, tests 77.25s, environment 4ms, prepare 1.43s)
----------------------|---------|----------|---------|---------|--------------------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------------------|---------|----------|---------|---------|--------------------------------
All files | 15.66 | 14.91 | 8.1 | 16.56 |
bin | 100 | 100 | 100 | 100 |
plop.js | 100 | 100 | 100 | 100 |
src | 13.58 | 13.39 | 5.55 | 14.37 |
bypass.js | 0 | 0 | 0 | 0 | 14-69
console-out.js | 14.28 | 0 | 0 | 15 | 9-110,122-123
input-processing.js | 26.08 | 37.14 | 14.28 | 27.9 | 17-55,68-69,74-80,88-89,98-101
plop.js | 10.29 | 5 | 8.33 | 10.6 | 51-171
----------------------|---------|----------|---------|---------|--------------------------------
=============================== Coverage summary ===============================
Statements : 15.66% ( 26/166 )
Branches : 14.91% ( 17/114 )
Functions : 8.1% ( 3/37 )
Lines : 16.56% ( 26/157 )
================================================================================

59
server/node_modules/plop/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,59 @@
# plop
## 4.0.1
### Patch Changes
- [#408](https://github.com/plopjs/plop/pull/408) [`49c0029`](https://github.com/plopjs/plop/commit/49c00296b478efa5a212458ae1781acc93a16fa8) Thanks [@rznzippy](https://github.com/rznzippy)! - Adds --no-progress flag that disables the progress bar
## 4.0.0
### Major Changes
- [#396](https://github.com/plopjs/plop/pull/396) [`a22e33f`](https://github.com/plopjs/plop/commit/a22e33f416340352e83a1e9c0d470baf2aff1c4b) Thanks [@crutchcorn](https://github.com/crutchcorn)! - Support TypeScript config files OOTB. Drop support for Node 12, 14, & 16. Update all deps.
### Patch Changes
- Updated dependencies [[`a22e33f`](https://github.com/plopjs/plop/commit/a22e33f416340352e83a1e9c0d470baf2aff1c4b)]:
- node-plop@0.32.0
## 3.1.2
### Patch Changes
- Append action should now allow handlebars for template path
* Fix addMany dotfile extension stripping
- Fix Inquirer TypeScript typings
* Fix empty checkboxes not bypassing properly
* Updated dependencies []:
- node-plop@0.31.1
## 3.1.1
### Patch Changes
- Export PlopGeneratorConfig TypeScript type
## 3.1.0
### Minor Changes
- [#333](https://github.com/plopjs/plop/pull/333) [`d6176cc`](https://github.com/plopjs/plop/commit/d6176cce4ee57dfc18ad1c86ec467444e966567e) Thanks [@RobinKnipe](https://github.com/RobinKnipe)! - Added shorthand to load all Plop assets at once #333
### Patch Changes
- Updated dependencies [[`d6176cc`](https://github.com/plopjs/plop/commit/d6176cce4ee57dfc18ad1c86ec467444e966567e)]:
- node-plop@0.31.0
## 3.0.6
### Patch Changes
- Moved to monorepo
- Updated dependencies []:
- node-plop@0.30.1

564
server/node_modules/plop/README.md generated vendored Normal file
View File

@@ -0,0 +1,564 @@
Plop
======
Micro-generator framework that makes it easy for an entire team to create files with a level of uniformity.
![plop demo](https://i.imgur.com/penUFkr.gif)
> [Documentation also available on plopjs.com](https://plopjs.com/documentation/)
# Getting Started
[![npm](https://img.shields.io/npm/dm/plop.svg)](https://www.npmjs.com/package/plop)
 
[![npm](https://img.shields.io/npm/v/plop.svg)](https://www.npmjs.com/package/plop)
 
[![plop on slack](https://img.shields.io/badge/slack-join%20workspace-green)](https://join.slack.com/t/plopjs/shared_invite/zt-ehh69el1-2_DjgZRuMbpC9RnEa4M8cA)
## What is Plop?
Plop is what I like to call a "micro-generator framework." Now, I call it that because it is a small tool that gives you a simple way to generate code or any other type of flat text files in a consistent way. You see, we all create structures and patterns in our code (routes, controllers, components, helpers, etc). These patterns change and improve over time so when you need to create a NEW *insert-name-of-pattern-here*, it's not always easy to locate the files in your codebase that represent the current "best practice." That's where plop saves you. With plop, you have your "best practice" method of creating any given pattern in CODE. Code that can easily be run from the terminal by typing `plop`. Not only does this save you from hunting around in your codebase for the right files to copy, but it also turns "the right way" into "the easiest way" to make new files.
If you boil plop down to its core, it is basically glue code between [inquirer](https://github.com/SBoudrias/Inquirer.js/blob/master/packages/inquirer/README.md) prompts and [handlebar](https://github.com/wycats/handlebars.js/) templates.
> This documentation is a work in progress. If you have great ideas, I'd love to hear them.
## Installation
### 1. Add plop to your project
```
$ npm install --save-dev plop
```
### 2. Install plop globally (optional, but recommended for easy access)
```
$ npm install -g plop
```
### 3. Create a plopfile.js at the root of your project
``` javascript
export default function (plop) {
// create your generators here
plop.setGenerator('basics', {
description: 'this is a skeleton plopfile',
prompts: [], // array of inquirer prompts
actions: [] // array of actions
});
};
```
> `export default` is only allowed in NodeJS inside "ESM" supported files.
> To use this syntax, your `plopfile` must be either:
> - An ESM .js file with type: "module" in package.json
> - An ESM .mjs file with any type declared in package.json
>
> Alternatively, you can have a `plopfile` with `module.exports = function (plop)` instead.
> For _this_ syntax, your `plopfile` must be either:
> - A CommonJS .js file with type: "commonjs" in package.json
> - A CommonJS .cjs file with any type declared in package.json
## Your First Plopfile
A plopfile starts its life as a node module that exports a function which accepts the `plop` object as its first parameter.
``` javascript
export default function (plop) {};
```
The `plop` object exposes the plop API object which contains the `setGenerator(name, config)` function. This is the function that you use to (wait for it) create a generator for this plopfile. When `plop` is run from the terminal in this directory (or any sub-directory), a list of these generators will be displayed.
Let's try setting up a basic generator to see how that looks.
``` javascript
export default function (plop) {
// controller generator
plop.setGenerator('controller', {
description: 'application controller logic',
prompts: [{
type: 'input',
name: 'name',
message: 'controller name please'
}],
actions: [{
type: 'add',
path: 'src/{{name}}.js',
templateFile: 'plop-templates/controller.hbs'
}]
});
};
```
The *controller* generator we created above will ask us 1 question, and create 1 file. This can be expanded to ask as many questions as needed, and create as many files as needed. There are also additional actions that can be used to alter our codebase in different ways.
## Using Prompts
Plop uses the [inquirer.js](https://github.com/SBoudrias/Inquirer.js) library to gather user data. A list of [prompt types](https://github.com/SBoudrias/Inquirer.js/blob/master/packages/inquirer/README.md#prompt-types) can be found on the inquirer official website.
## CLI Usage
Once plop is installed, and you have created a generator, you are ready to run plop from the terminal. Running `plop` with no parameters will present you with a list of generators to pick from. You can also run `plop [generatorName]` to trigger a generator directly. If you did not install plop globally, you will need to setup an npm script to run plop for you.
```javascript
// package.json
{
...,
"scripts": {
"plop": "plop"
},
...
}
```
### Bypassing Prompts
Once you get to know a project (and its generators) well, you may want to provide answers to the prompts when you run the generator. If I have (for instance) a `component` generator that has one prompt (name), I can run that generator using `plop component "some component name"` and it will immediately execute as though I had typed "some component name" into the prompt. If that same generator had a second prompt, the same input would have resulted in the user being prompted for the second value.
Prompts like `confirm` and `list` try to make sense of your input as best they can. For instance entering "y", "yes", "t", or "true" for a confirm prompt will result in a boolean `true` value. You can select items from a list using their value, index, key, or name. Checkbox prompts can accept a comma separated list of values in order to select multiples.
![plop bypass demo](https://media.giphy.com/media/3ov9jQ38ypmX4SuT60/giphy.gif)
> If you want to provide bypass input for the second prompt but not the first, you can use an underscore "\_" to skip the bypass (ie `plop component _ "input for second prompt"`).
Plop comes with bypass logic built-in for standard inquirer prompts, but there are also ways to provide custom logic for how to handle user input for a specific prompt.
If you have published a 3rd party inquirer prompt plugin and would like to support bypass functionality for plop users out of the box, that is covered in [another section of this documentation](#3rd-party-prompt-bypass).
### Bypassing Prompts (by Name)
You can also bypass prompts by name using `--` and then providing arguments for each prompt that you'd like to bypass. Examples [below](#bypass-examples).
#### Bypass Examples
```
## Bypassing both prompt 1 and 2
$ plop component "my component" react
$ plop component -- --name "my component" --type react
## Bypassing only prompt 2 (will be prompted for name)
$ plop component _ react
$ plop component -- --type react
```
### Running a Generator Forcefully
By default Plop actions keep your files safe by failing when things look fishy. The most obvious example of this is not allowing an [`add`](#add) action to overwrite a file that already exists. Plop actions individually support the `force` property but you can also use the `--force` flag when running Plop from the terminal. Using the `--force` flag will tell every action to run forcefully. With great power...🕷
## Why Generators?
Because when you create your boilerplate separate from your code, you naturally put more time and thought into it.
Because saving your team (or yourself) 5-15 minutes when creating every route, component, controller, helper, test, view, etc... [really adds up](https://xkcd.com/1205/).
Because [context switching is expensive](https://www.petrikainulainen.net/software-development/processes/the-cost-of-context-switching/) and saving time is not the only [benefit to automating workflows](https://kentcdodds.com/blog/automation)
# Plopfile API
The plopfile api is the collection of methods that are exposed by the `plop` object. Most of the work is done by [`setGenerator`](#setgenerator) but this section documents the other methods that you may also find useful in your plopfile.
## TypeScript Declarations
`plop` bundles TypeScript declarations. Whether or not you write your plopfile in TypeScript, many editors will offer code assistance via these declarations.
```javascript
// plopfile.ts
import {NodePlopAPI} from 'plop';
export default function (plop: NodePlopAPI) {
// plop generator code
};
```
```javascript
// plopfile.js
export default function (
/** @type {import('plop').NodePlopAPI} */
plop
) {
// plop generator code
};
```
## Main Methods
These are the methods you will commonly use when creating a plopfile. Other methods that are mostly for internal use are list in the [other methods](#other-methods) section.
Method | Parameters | Returns | Description
------ | ---------- | ------- | -----------
[**setGenerator**](#setgenerator) | *String, [GeneratorConfig](#interface-generatorconfig)* | *[PlopGenerator](#interface-plopgenerator)* | setup a generator
[**setHelper**](#sethelper) | *String, Function* | | setup handlebars helper
[**setPartial**](#setpartial) | *String, String* | | setup a handlebars partial
[**setActionType**](#setactiontype) | *String, [CustomAction](#functionsignature-custom-action)* | | register a custom action type
[**setPrompt**](#setprompt) | *String, InquirerPrompt* | | registers a custom prompt type with inquirer
[**load**](https://github.com/plopjs/plop/blob/main/plop-load.md) | *Array[String], Object, Object* | | loads generators, helpers and/or partials from another plopfile or npm module
## setHelper
`setHelper` directly corresponds to the handlebars method `registerHelper`. So if you are familiar with [handlebars helpers](https://handlebarsjs.com/guide/expressions.html#helpers), then you already know how this works.
``` javascript
export default function (plop) {
plop.setHelper('upperCase', function (text) {
return text.toUpperCase();
});
// or in es6/es2015
plop.setHelper('upperCase', (txt) => txt.toUpperCase());
};
```
## setPartial
`setPartial` directly corresponds to the handlebars method `registerPartial`. So if you are familiar with [handlebars partials](https://handlebarsjs.com/guide/partials.html), then you already know how this works.
``` javascript
export default function (plop) {
plop.setPartial('myTitlePartial', '<h1>{{titleCase name}}</h1>');
// used in template as {{> myTitlePartial }}
};
```
## setActionType
`setActionType` allows you to create your own actions (similar to `add` or `modify`) that can be used in your plopfiles. These are basically highly reusable [custom action function](#custom-action-function)s.
### *FunctionSignature* Custom Action
Parameters | Type | Description
---------- | ---- | -----------
**answers** | *Object* | Answers to the generator prompts
**config** | *[ActionConfig](#interface-actionconfig)* | The object in the "actions" array for the generator
**plop** | *[PlopfileApi](#plopfile-api)* | The plop api for the plopfile where this action is being run
``` javascript
export default function (plop) {
plop.setActionType('doTheThing', function (answers, config, plop) {
// do something
doSomething(config.configProp);
// if something went wrong
throw 'error message';
// otherwise
return 'success status message';
});
// or do async things inside of an action
plop.setActionType('doTheAsyncThing', function (answers, config, plop) {
// do something
return new Promise((resolve, reject) => {
if (success) {
resolve('success status message');
} else {
reject('error message');
}
});
});
// use the custom action
plop.setGenerator('test', {
prompts: [],
actions: [{
type: 'doTheThing',
configProp: 'available from the config param'
}, {
type: 'doTheAsyncThing',
speed: 'slow'
}]
});
};
```
## setPrompt
[Inquirer](https://github.com/SBoudrias/Inquirer.js/blob/master/packages/inquirer/README.md) provides many types of prompts out of the box, but it also allows developers to build prompt plugins. If you'd like to use a prompt plugin, you can register it with `setPrompt`. For more details see the [Inquirer documentation for registering prompts](https://github.com/SBoudrias/Inquirer.js/blob/master/packages/inquirer/README.md#inquirerregisterpromptname-prompt). Also check out the [plop community driven list of custom prompts](https://github.com/plopjs/awesome-plop#inquirer-prompts).
``` javascript
import autocompletePrompt from 'inquirer-autocomplete-prompt';
export default function (plop) {
plop.setPrompt('autocomplete', autocompletePrompt);
plop.setGenerator('test', {
prompts: [{
type: 'autocomplete',
...
}]
});
};
```
## setGenerator
The config object needs to include `prompts` and `actions` (`description` is optional). The prompts array is passed to [inquirer](https://github.com/SBoudrias/Inquirer.js/blob/master/packages/inquirer/README.md/#objects). The `actions` array is a list of actions to take (described in greater detail below)
### *Interface* `GeneratorConfig`
Property | Type | Default | Description
-------- | ---- | ------- | -----------
**description** | *[String]* | | short description of what this generator does
**prompts** | *Array[[InquirerQuestion](https://github.com/SBoudrias/Inquirer.js/blob/master/packages/inquirer/README.md/#question)]* | | questions to ask the user
**actions** | *Array[[ActionConfig](#interface-actionconfig)]* | | actions to perform
> If your list of actions needs to be dynamic, take a look at [using a dynamic actions array.](#using-a-dynamic-actions-array)
### *Interface* `PlopGenerator`
Property | Type | Default | Description
-------- | ---- | ------- | -----------
**runPrompts** | *Function* | | a function to run the prompts within a generator
**runActions** | *Function* | | a function to run the actions within a generator
> This interface also contains all properties from [GeneratorConfig](#interface-generatorconfig)
### *Interface* `ActionConfig`
The following properties are the standard properties that plop handles internally. Other properties will be required depending on the *type* of action. Also take a look at the [built-in actions](#built-in-actions).
Property | Type | Default | Description
-------- | ---- | ------- | -----------
**type** | *String* | | the type of action ([`add`](#add), [`modify`](#modify), [`addMany`](#addmany), [etc](#setactiontype))
**force** | *Boolean* | `false` | performs the action [forcefully](#running-a-generator-forcefully) (means different things depending on the action)
**data** | *Object / Function* | `{}` | specifies data that should be mixed with user prompt answers when running this action
**abortOnFail** | *Boolean* | `true` | if this action fails for any reason abort all future actions
**skip** | *Function* | | an optional function that specifies if the action should run
> The `data` property on any `ActionConfig` can also be a `Function` that returns an `Object` or a `Function` that returns a `Promise` that resolves with an `Object`.
> The `skip` function on any `ActionConfig` is optional and should return a string if the action should be skipped. The return value is the reason to skip the action.
> Instead of an Action Object, a [function can also be used](#custom-action-function)
## Other Methods
Method | Parameters | Returns | Description
------ | ---------- | ------- | -----------
**getHelper** | *String* | *Function* | get the helper function
**getHelperList** | | *Array[String]* | get a list of helper names
**getPartial** | *String* | *String* | get a handlebars partial by name
**getPartialList** | | *Array[String]* | get a list of partial names
**getActionType** | *String* | *[CustomAction](#functionsignature-custom-action)* | get an actionType by name
**getActionTypeList** | | *Array[String]* | get a list of actionType names
**setWelcomeMessage** | *String* | | Customizes the displayed message that asks you to choose a generator when you run `plop`.
**getGenerator** | *String* | *[GeneratorConfig](#interface-generatorconfig)* | get the [PlopGenerator](#interface-plopgenerator) by name
**getGeneratorList** | | *Array[Object]* | gets an array of generator names and descriptions
**setPlopfilePath** | *String* | | set the `plopfilePath` value which is used internally to locate resources like template files
**getPlopfilePath** | | *String* | returns the absolute path to the plopfile in use
**getDestBasePath** | | *String* | returns the base path that is used when creating files
**setDefaultInclude** | *Object* | *Object* | sets the default config that will be used for this plopfile if it is consumed by another plopfile using `plop.load()`
**getDefaultInclude** | *String* | *Object* | gets the default config that will be used for this plopfile if it is consumed by another plopfile using `plop.load()`
**renderString** | *String, Object* | *String* | Runs the first parameter (*String*) through the handlebars template renderer using the second parameter (*Object*) as the data. Returns the rendered template.
# Built-In Actions
There are several types of built-in actions you can use in your [GeneratorConfig](#interface-generatorconfig). You specify which `type` of action (all paths are based on the location of the plopfile), and a template to use.
> The `Add`, `AddMany` and `Modify` actions have an optional `transform` method that can be used to transform the template result before it is written to disk. The `transform` function receives the template result or file contents as a `string` and the action data as arguments. It must return a `string` or a `Promise` that resolves to a `string`.
## Add
The `add` action is used to (you guessed it) add a file to your project. The path property is a handlebars template that will be used to create the file by name. The file contents will be determined by the `template` or `templateFile` property.
Property | Type | Default | Description
-------- | ---- | ------- | -----------
**path** | *String* | | a handlebars template that (when rendered) is the path of the new file
**template** | *String* | | a handlebars template that should be used to build the new file
**templateFile** | *String* | | a path a file containing the `template`
**skipIfExists** | *Boolean* | `false` | skips a file if it already exists (instead of failing)
**transform** | *Function* | | [an optional function](#built-in-actions) that can be used to transform the template result before writing the file to disk
**skip** | *Function* | | *inherited from [ActionConfig](#interface-actionconfig)*
**force** | *Boolean* | `false` | *inherited from [ActionConfig](#interface-actionconfig)* (overwrites files if they exist)
**data** | *Object* | `{}` | *inherited from [ActionConfig](#interface-actionconfig)*
**abortOnFail** | *Boolean* | `true` | *inherited from [ActionConfig](#interface-actionconfig)*
## AddMany
The `addMany` action can be used to add multiple files to your project with a single action. The `destination` property is a handlebars template that will be used to identify the folder that the generated files should go into. The `base` property can be used to alter what section of the template paths should be omitted when creating files. The paths located by the `templateFiles` glob can use handlebars syntax in their file/folder names if you'd like the added file names to be unique (example: `{{ dashCase name }}.spec.js`).
Property | Type | Default | Description
-------- | ---- | ------- | -----------
**destination** | *String* | | a handlebars template that (when rendered) is the destination folder for the new files
**base** | *String* | | the section of the path that should be excluded when adding files to the `destination` folder
**templateFiles** | *[Glob](https://github.com/sindresorhus/globby#globbing-patterns)* | | glob pattern that matches multiple template files to be added
**stripExtensions** | *[String]* | `['hbs']` | file extensions that should be stripped from `templateFiles` files names while being added to the `destination`
**globOptions** | *[Object](https://github.com/sindresorhus/globby#options)* | | glob options that change how to match to the template files to be added
**verbose** | *Boolean* | `true` | print each successfully added file path
**transform** | *Function* | | [an optional function](#built-in-actions) that can be used to transform the template result before writing each file to disk
**skip** | *Function* | | *inherited from [ActionConfig](#interface-actionconfig)*
**skipIfExists** | *Boolean* | `false` | *inherited from [Add](#add)* (skips a file if it already exists)
**force** | *Boolean* | `false` | *inherited from [ActionConfig](#interface-actionconfig)* (overwrites files if they exist)
**data** | *Object* | `{}` | *inherited from [ActionConfig](#interface-actionconfig)*
**abortOnFail** | *Boolean* | `true` | *inherited from [ActionConfig](#interface-actionconfig)*
## Modify
The `modify` action can be used two ways. You can use a `pattern` property to find/replace text in the file located at the `path` specified, or you can use a `transform` function to transform the file contents. Both `pattern` and `transform` can be used at the same time (`transform` will happen last). More details on modify can be found in the example folder.
Property | Type | Default | Description
-------- | ---- | ------- | -----------
**path** | *String* | | handlebars template that (when rendered) is the path of the file to be modified
**pattern** | *RegExp* | _end&#x2011;of&#x2011;file_ | regular expression used to match text that should be replaced
**template** | *String* | | handlebars template that should replace what was matched by the `pattern`. capture groups are available as $1, $2, etc
**templateFile** | *String* | | path a file containing the `template`
**transform** | *Function* | | [an optional function](#built-in-actions) that can be used to transform the file before writing it to disk
**skip** | *Function* | | *inherited from [ActionConfig](#interface-actionconfig)*
**data** | *Object* | `{}` | *inherited from [ActionConfig](#interface-actionconfig)*
**abortOnFail** | *Boolean* | `true` | *inherited from [ActionConfig](#interface-actionconfig)*
## Append
The `append` action is a commonly used subset of `modify`. It is used to append data in a file at a particular location.
Property | Type | Default | Description
-------- | ---- | ------- | -----------
**path** | *String* | | handlebars template that (when rendered) is the path of the file to be modified
**pattern** | *RegExp, String* | | regular expression used to match text where the append should happen
**unique** | *Boolean* | `true` | whether identical entries should be removed
**separator** | *String* | `new line` | the value that separates entries
**template** | *String* | | handlebars template to be used for the entry
**templateFile** | *String* | | path a file containing the `template`
**data** | *Object* | `{}` | *inherited from [ActionConfig](#interface-actionconfig)*
**abortOnFail** | *Boolean* | `true` | *inherited from [ActionConfig](#interface-actionconfig)*
## Custom (Action Function)
The `Add` and `Modify` actions will take care of almost every case that plop is designed to handle. However, plop does offer custom action functions for the node/js guru. A custom action function is a function that is provided in the actions array.
- Custom action functions are executed by plop with the same [CustomAction](#functionsignature-custom-action) function signature.
- Plop will wait for the custom action to complete before executing the next action.
- The function must let plop known whats happening through the return value. If you return a `Promise`, we wont start other actions until the promise resolves. If you return a message (*String*), we know that the action is done and well report the message in the status of the action.
- A custom action fails if the promise is rejected, or the function throws an `Exception`
_See the [example plopfile](https://github.com/plopjs/plop/blob/main/packages/plop/tests/examples/javascript/plopfile.js) for a sample synchronous custom action._
## Comments
Comment lines can be added to the actions array by adding a string in place of an action config object. Comments are printed to the screen when plop comes to them and have no functionality of their own.
# Built-In Helpers
There are a few helpers that I have found useful enough to include with plop. They are mostly case modifiers, but here is the complete list.
## Case Modifiers
- **camelCase**: changeFormatToThis
- **snakeCase**: change_format_to_this
- **dashCase/kebabCase**: change-format-to-this
- **dotCase**: change.format.to.this
- **pathCase**: change/format/to/this
- **properCase/pascalCase**: ChangeFormatToThis
- **lowerCase**: change format to this
- **sentenceCase**: Change format to this,
- **constantCase**: CHANGE_FORMAT_TO_THIS
- **titleCase**: Change Format To This
## Other Helpers
- **pkg**: look up a property from a package.json file in the same folder as the plopfile.
# Taking it Further
There is not a lot needed to get up and running on some basic generators. However, if you want to take your plop-fu further, read on young padawan.
## Using a Dynamic Actions Array
Alternatively, the `actions` property of the [GeneratorConfig](#interface-generatorconfig) can itself be a function that takes the answers data as a parameter and returns the actions array.
This allows you to adapt the actions array based on provided answers:
``` javascript
export default function (plop) {
plop.setGenerator('test', {
prompts: [{
type: 'confirm',
name: 'wantTacos',
message: 'Do you want tacos?'
}],
actions: function(data) {
var actions = [];
if(data.wantTacos) {
actions.push({
type: 'add',
path: 'folder/{{dashCase name}}.txt',
templateFile: 'templates/tacos.txt'
});
} else {
actions.push({
type: 'add',
path: 'folder/{{dashCase name}}.txt',
templateFile: 'templates/burritos.txt'
});
}
return actions;
}
});
};
```
## 3rd Party Prompt Bypass
If you have written an inquirer prompt plugin and want to support plop's bypass functionality, the process is pretty simple. The plugin object that your prompt exports should have a `bypass` function. This `bypass` function will be run by plop with the user's input as the first parameter and the prompt config object as the second parameter. The value that this function returns will be added to the answer data object for that prompt.
``` javascript
// My confirmation inquirer plugin
export default MyConfirmPluginConstructor;
function MyConfirmPluginConstructor() {
// ...your main plugin code
this.bypass = (rawValue, promptConfig) => {
const lowerVal = rawValue.toString().toLowerCase();
const trueValues = ['t', 'true', 'y', 'yes'];
const falseValues = ['f', 'false', 'n', 'no'];
if (trueValues.includes(lowerVal)) return true;
if (falseValues.includes(lowerVal)) return false;
throw Error(`"${rawValue}" is not a valid ${promptConfig.type} value`);
};
return this;
}
```
> For the above example, the bypass function takes the user's text input and turns it into a `Boolean` value that will be used as the prompt answer data.
### Adding Bypass Support to Your Plopfile
If the 3rd party prompt plugin you are using does not support bypass by default, you can add the `bypass` function above to your prompt's config object and plop will use it for handling bypass data for that prompt.
## Wrapping Plop
Plop provides a lot of powerful functionality "for free". This utility is so powerful, in fact, that you can even wrap `plop`
into your own CLI project. To do so, you only need a `plopfile.js`, a `package.json`, and a template to reference.
Your `index.js` file should look like the following:
```javascript
#!/usr/bin/env node
import path from "node:path";
import minimist from "minimist";
import { Plop, run } from "plop";
const args = process.argv.slice(2);
const argv = minimist(args);
import { dirname } from "node:path";
import { fileURLToPath } from "node:url";
const __dirname = dirname(fileURLToPath(import.meta.url));
Plop.prepare({
cwd: argv.cwd,
configPath: path.join(__dirname, 'plopfile.js'),
preload: argv.preload || [],
completion: argv.completion
}, env => Plop.execute(env, run));
```
And your `package.json` should look like the following:
```json
{
"name": "create-your-name-app",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "plop",
},
"bin": {
"create-your-name-app": "./index.js"
},
"preferGlobal": true,
"dependencies": {
"plop": "^3.0.0"
}
}
```
### Setting the base destination path for the wrapper
When wrapping plop, you might want to have the destination path to be based on the cwd when running the wrapper. You can configure the `dest` base path like this:
```javascript
Plop.prepare({
// config like above
}, env =>
Plop.execute(env, (env) => {
const options = {
...env,
dest: process.cwd() // this will make the destination path to be based on the cwd when calling the wrapper
}
return run(options, undefined, true)
})
)
```
### Adding General CLI Actions
Many CLI utilities handle some actions for you, such as running `git init` or `npm install` once the template is generated.
While we'd like to provide these actions, we also want to keep the core actions limited in scope. As such, we maintain a collection of libraries built to add these actions to Plop in [our Awesome Plop list](https://github.com/plopjs/awesome-plop). There, you'll be able to find options for those actions, or even build your own and add it to the list!
### Further Customization
While `plop` provides a great level of customization for CLI utility wrappers, there may be usecases where you simply
want more control over the CLI experience while also utilizing the template generation code.
Luckily, [`node-plop`](https://github.com/plopjs/node-plop/) may be for you! It's what the `plop` CLI itself is built
upon and can be easily extended for other usage in the CLI. However, be warned, documentation is not quite as fleshed out
for integration with `node-plop`. That is to say `Thar be dragons`.
> We note lackluster documentation on `node-plop` integration not as a point of pride, but rather a word of warning.
> If you'd like to contribute documentation to the project, please do so! We always welcome and encourage contributions!

17
server/node_modules/plop/bin/plop.js generated vendored Executable file
View File

@@ -0,0 +1,17 @@
#!/usr/bin/env node
const args = process.argv.slice(2);
import { Plop, run } from "../src/plop.js";
import minimist from "minimist";
const argv = minimist(args);
Plop.prepare(
{
cwd: argv.cwd,
preload: argv.preload || [],
configPath: argv.plopfile,
completion: argv.completion,
},
function (env) {
Plop.execute(env, run);
},
);

1
server/node_modules/plop/node_modules/.bin/mkdirp generated vendored Symbolic link
View File

@@ -0,0 +1 @@
../mkdirp/dist/cjs/src/bin.js

1
server/node_modules/plop/node_modules/.bin/rimraf generated vendored Symbolic link
View File

@@ -0,0 +1 @@
../rimraf/bin.js

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) Microsoft Corporation.
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

View File

@@ -0,0 +1,15 @@
# Installation
> `npm install --save @types/inquirer`
# Summary
This package contains type definitions for inquirer (https://github.com/SBoudrias/Inquirer.js).
# Details
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/inquirer.
### Additional Details
* Last updated: Mon, 05 May 2025 19:02:21 GMT
* Dependencies: [@types/through](https://npmjs.com/package/@types/through), [rxjs](https://npmjs.com/package/rxjs)
# Credits
These definitions were written by [Qubo](https://github.com/tkQubo), [Parvez](https://github.com/ppathan), [Jouderian](https://github.com/jouderianjr), [Qibang](https://github.com/bang88), [Jason Dreyzehner](https://github.com/bitjson), [Synarque](https://github.com/synarque), [Justin Rockwood](https://github.com/jrockwood), [Keith Kelly](https://github.com/kwkelly), and [Richard Lea](https://github.com/chigix).

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,66 @@
import { Answers, CheckboxChoiceOptions, ExpandChoiceOptions, ListChoiceOptions } from "../../index.js";
/**
* Represents a choice for several question-types.
*
* @template T
* The type of the answers.
*/
declare class Choice<T extends Answers = Answers>
implements ListChoiceOptions<T>, CheckboxChoiceOptions<T>, ExpandChoiceOptions
{
/**
* @inheritdoc
*/
type?: "choice" | undefined;
/**
* @inheritdoc
*/
name: string;
/**
* @inheritdoc
*/
short: string;
/**
* @inheritdoc
*/
value: any;
/**
* @inheritdoc
*/
checked?: boolean | undefined;
/**
* @inheritdoc
*/
disabled: boolean;
/**
* The key to press for selecting the choice.
*
* @inheritdoc
*/
key?: string | undefined;
/**
* @inheritdoc
*/
extra?: any;
/**
* Initializes a new instance of the {@link Choice `Choice<T>`} class.
*
* @param value
* The value of the choice.
*
* @param answers
* An object which contains the answers to the questions.
*/
constructor(value: any, answers: T);
}
export default Choice;

View File

@@ -0,0 +1,206 @@
import { AllChoiceMap, Answers, KeyUnion, UnionToIntersection } from "../../index.js";
import Choice from "./choice.js";
import Separator from "./separator.js";
/**
* Represents a valid choice for the {@link Choices `Choices<T>`} class.
*
* @template T
* The type of the answers.
*/
type DistinctChoice<T extends Answers> = AllChoiceMap<T>[keyof AllChoiceMap<T>];
/**
* Represents a valid real choice for the {@link Choices `Choices<T>`} class.
*
* @template T
* The type of the answers.
*/
type RealChoice<T extends Answers> = Exclude<DistinctChoice<T>, { type: Separator["type"] }>;
/**
* Represents a property-name of any choice-type.
*
* @template T
* The type of the answers.
*/
type ChoiceProperty<T extends Answers> = KeyUnion<UnionToIntersection<RealChoice<T>>>;
/**
* A collection of multiple `Choice`-objects.
*
* @template T
* The type of the answers.
*/
declare class Choices<T extends Answers = Answers> {
/**
* The number of selectable choices.
*/
realLength: number;
/**
* The number of choices.
*/
length: number;
/**
* The unfiltered choices.
*/
choices: Array<DistinctChoice<T>>;
/**
* The selectable choices.
*/
realChoices: Array<RealChoice<T>>;
/**
* Initializes a new instance of the {@link Choices `Choices<T>`} class.
*
* @param choices
* The choices to add to the collection.
*
* @param answers
* The {@link Answers `Answers`}-object.
*/
constructor(choices: Array<DistinctChoice<T>>, answers: T);
/**
* Gets the choice at the specified index.
*
* @param index
* The index of the choice to get.
*
* @returns
* The choice at the specified index.
*/
getChoice(index: number): RealChoice<T>;
/**
* Gets the item at the specified index.
*
* @param index
* The index of the item to get.
*
* @returns
* The item at the specified index.
*/
get(index: number): DistinctChoice<T>;
/**
* Gets all choices which apply to the where-clause.
*
* @param whereClause
* The where-clause to apply.
*
* @returns
* The choices which apply to the where-clause.
*/
where(whereClause: object): Array<RealChoice<T>>;
/**
* Retrieves the specified {@link property `property`} from all choices.
*
* @template TProperty
* The name of the property to get.
*
* @param property
* The property to query.
*
* @returns
* The value of the property of each choice.
*/
pluck<TProperty extends ChoiceProperty<T>>(
property: TProperty | ChoiceProperty<T>,
): Array<(RealChoice<T> & { [key: string]: undefined })[TProperty]>;
/**
* Returns the index of the first occurrence of a value in an array.
*
* @param searchElement
* The value to locate in the array.
*
* @param fromIndex
* The array index at which to begin the search.
*
* If {@link fromIndex `fromIndex`} is omitted, the search starts at index 0.
*
* @returns
* The index of the specified {@link searchElement `searchElement`}.
*/
indexOf(searchElement: Choice<T> | Separator, fromIndex?: number): number;
/**
* Performs the specified action for each element in an array.
*
* @param callbackfn
* A function that accepts up to three arguments.
*
* {@link forEach `forEach`} calls the {@link callbackfn `callbackfn`} function one time for each element in the array.
*
* @param thisArg
* An object to which the `this` keyword can refer in the {@link callbackfn `callbackfn`} function.
*
* If {@link thisArg `thisArg`} is omitted, `undefined` is used as the `this` value.
*/
forEach(
callbackfn: (value: Choice<T> | Separator, index: number, array: Array<Choice<T> | Separator>) => void,
thisArg?: any,
): void;
/**
* Returns the elements of an array that meet the condition specified in a callback function.
*
* @param callbackfn
* A function that accepts up to three arguments.
*
* The filter method calls the {@link callbackfn `callbackfn`} function one time for each element in the array.
*
* @param thisArg
* An object to which the `this` keyword can refer in the {@link callbackfn `callbackfn`} function.
*
* If {@link thisArg `thisArg`} is omitted, undefined is used as the this value.
*
* @returns
* The elements in the collection which meet the conditions.
*/
filter<TElement extends Choice<T> | Separator>(
callbackfn: (
value: Choice<T> | Separator,
index: number,
array: Array<Choice<T> | Separator>,
) => value is TElement,
thisArg?: any,
): TElement[];
/**
* Returns the value of the first element in the array where predicate is `true`, and `undefined` otherwise.
*
* @param predicate
* {@link find `find`} calls {@link predicate `predicate`} once for each element of the array, in ascending order, until it finds one where predicate returns `true`.
*
* If such an element is found, {@link find `find`} immediately returns that element value.
* Otherwise, find returns `undefined`.
*
* @param thisArg
* If provided, it will be used as the `this` value for each invocation of {@link predicate `predicate`}.
*
* If it is not provided, `undefined` is used instead.
*/
find(
predicate: (value: Choice<T> | Separator, index: number, obj: Array<Choice<T> | Separator>) => boolean,
thisArg?: any,
): Choice<T> | Separator;
/**
* Appends new elements to the array, and returns the new length of the array.
*
* @param items
* The elements to add to the array.
*
* @returns
* The new length of the array.
*/
push(...items: Array<Choice<T> | Separator>): number;
}
export default Choices;

View File

@@ -0,0 +1,3 @@
import inquirer from "../../index.js";
export default inquirer.Separator;

View File

@@ -0,0 +1,95 @@
import { Interface as ReadLineInterface } from "readline";
import { Observable } from "rxjs";
import inquirer, { Answers, Question } from "../../index.js";
import ScreenManager from "../utils/screen-manager.js";
/**
* Represents a prompt.
*
* @template TQuestion
* The options for the question.
*/
declare class Prompt<TQuestion extends Question = Question> implements inquirer.prompts.PromptBase {
/**
* @inheritdoc
*/
status: inquirer.prompts.PromptState;
/**
* Gets or sets an object which contains the answers.
*/
protected answers: Answers;
/**
* Gets or sets the options of the prompt.
*/
protected opt: inquirer.prompts.PromptOptions<TQuestion>;
/**
* Gets or sets an object for performing read from and write to the console.
*/
protected rl: ReadLineInterface;
/**
* Gets or sets an object for managing the console-screen.
*/
protected screen: ScreenManager;
/**
* Initializes a new instance of the {@link Prompt `Prompt<TQuestion>`} class.
*
* @param question
* The question to prompt the user to answer.
*
* @param readLine
* An object for performing read from and write to the console.
*
* @param answers
* The {@link Answers `Answers`}-object.
*/
constructor(question: TQuestion, readLine: ReadLineInterface, answers: Answers);
/**
* @inheritdoc
*/
run(): Promise<any>;
/**
* Runs the prompt.
*
* @param callback
* The callback for resolving the result.
*/
protected _run(callback: (callback: any) => void): void;
/**
* Throws an error for a missing parameter.
*
* @param name
* The name of the missing parameter.
*/
protected throwParamError(name: string): void;
/**
* Releases all unmanaged resources.
*/
protected close(): void;
/**
* Handles the submit-event.
*
* @param observable
* The observable submit-event flow.
*/
protected handleSubmitEvents<T>(observable: Observable<T>): inquirer.prompts.PromptEventPipes<T>;
/**
* Generates the question-string.
*
* @returns
* The question-string.
*/
protected getQuestion(): string;
}
export default Prompt;

View File

@@ -0,0 +1,116 @@
import { Interface as ReadLineInterface } from "readline";
import inquirer, { Answers, CheckboxQuestionOptions } from "../../index.js";
import Paginator from "../utils/paginator.js";
import Prompt from "./base.js";
/**
* The question-options for the {@link CheckboxPrompt `CheckboxPrompt<TQuestion>`}.
*/
type Question = CheckboxQuestionOptions;
/**
* Represents a prompt which provides a set of choices to check.
*
* @template TQuestion
* The options for the question.
*/
declare class CheckboxPrompt<TQuestion extends Question = Question> extends Prompt<TQuestion> {
/**
* Gets or sets the index of the currently focused choice.
*/
protected pointer: number;
/**
* Gets or sets an object for paginating the content.
*/
protected paginator: Paginator;
/**
* Initializes a new instance of the {@link CheckboxPrompt `CheckboxPrompt<TQuestion>`} class.
*
* @param question
* The question to prompt the user to answer.
*
* @param readLine
* An object for performing read from and write to the console.
*
* @param answers
* The answer-object.
*/
constructor(question: TQuestion, readLine: ReadLineInterface, answers: Answers);
/**
* Renders the prompt.
*
* @param error
* An error message to render.
*/
protected render(error?: string): void;
/**
* Handles the `success`-event of the prompt.
*
* @param eventArgs
* An object which contains event-data.
*/
protected onEnd(eventArgs: inquirer.prompts.SuccessfulPromptStateData): void;
/**
* Handles the `error`-event of the prompt.
*
* @param eventArgs
* An object which contains event-data.
*/
protected onError(eventArgs: inquirer.prompts.FailedPromptStateData): void;
/**
* Gets the current value of the prompt.
*
* @returns
* The current value of the prompt.
*/
protected getCurrentValue(): any;
/**
* Handles the `UpdKey`-event of the prompt.
*/
protected onUpKey(): void;
/**
* Handles the `DownKey`-event of the prompt.
*/
protected onDownKey(): void;
/**
* Handles the `NumberKey`-event of the prompt.
*
* @param input
* The number which has been pressed.
*/
protected onNumberKey(input: number): void;
/**
* Handles the `SpaceKey`-event of the prompt.
*/
protected onSpaceKey(): void;
/**
* Handles the `AllKey`-event of the prompt.
*/
protected onAllKey(): void;
/**
* Handles the `InverseKey`-event of the prompt.
*/
protected onInverseKey(): void;
/**
* Toggles the state of a choice.
*
* @param index
* The index of the choice to toggle.
*/
protected toggleChoice(index: number): void;
}
export default CheckboxPrompt;

View File

@@ -0,0 +1,53 @@
import { Interface as ReadlineInterface } from "readline";
import { Answers, ConfirmQuestionOptions } from "../../index.js";
import Prompt from "./base.js";
/**
* The question-options for the {@link ConfirmPrompt `ConfirmPrompt<TQuestion>`}.
*/
type Question = ConfirmQuestionOptions;
/**
* Represents a prompt which provides a message to confirm.
*
* @template TQuestion
* The options for the question.
*/
declare class ConfirmPrompt<TQuestion extends Question = Question> extends Prompt<TQuestion> {
/**
* Initializes a new instance of the {@link ConfirmPrompt `ConfirmPrompt<TQuestion>`} class.
*
* @param question
* The question to prompt the user to answer.
*
* @param readLine
* An object for performing read from and write to the console.
*
* @param answers
* The answer-object.
*/
constructor(question: TQuestion, readLine: ReadlineInterface, answers: Answers);
/**
* Renders the prompt.
*
* @param answer
* The answer provided by the user.
*/
protected render(answer?: boolean): this;
/**
* Handles the `success`-event of the prompt.
*
* @param input
* The input provided by the user.
*/
protected onEnd(input: string): void;
/**
* Handles the `Keypress`-event of the prompt.
*/
protected onKeypress(): void;
}
export default ConfirmPrompt;

View File

@@ -0,0 +1,101 @@
import { Interface as ReadlineInterface } from "readline";
import { Subject, Subscription } from "rxjs";
import inquirer, { Answers, EditorQuestionOptions } from "../../index.js";
import Prompt from "./base.js";
/**
* The question-options for the {@link EditorPrompt `EditorPrompt<TQuestion>`}.
*/
type Question = EditorQuestionOptions;
/**
* Represents a prompt which provides a text-editor.
*
* @template TQuestion
* The options for the question.
*/
declare class EditorPrompt<TQuestion extends Question = Question> extends Prompt<TQuestion> {
/**
* Resolves the value of the prompt.
*/
protected done: (value: any) => void;
/**
* Gets or sets an object for subscribing to the editor-result.
*/
protected editorResult: Subject<string>;
/**
* Gets or sets a subscription to the `line`-event.
*/
protected lineSubscription: Subscription;
/**
* Gets or sets the initial text.
*/
protected currentText: string;
/**
* Initializes a new instance of the {@link EditorPrompt `EditorPrompt<TQuestion>`} class.
*
* @param question
* The question to prompt the user to answer.
*
* @param readLine
* An object for performing read from and write to the console.
*
* @param answers
* The answer-object.
*/
constructor(question: TQuestion, readLine: ReadlineInterface, answers: Answers);
/**
* Runs the prompt.
*
* @param callback
* The callback for resolving the result.
*/
protected _run(callback: (value: any) => void): this;
/**
* Renders the prompt.
*
* @param error
* The error to render.
*/
protected render(error?: string): void;
/**
* Launches the default text-editor of the system.
*/
protected startExternalEditor(): void;
/**
* Closes the external editor.
*
* @param error
* Either the error which occurred while executing the external editor or `null`.
*
* @param result
* The result of the editor.
*/
protected endExternalEditor(error: Error, result: string): void;
/**
* Handles the `success`-event of the prompt.
*
* @param eventArgs
* An object which contains event-data.
*/
protected onEnd(eventArgs: inquirer.prompts.SuccessfulPromptStateData): void;
/**
* Handles the `error`-event of the prompt.
*
* @param eventArgs
* An object which contains event-data.
*/
protected onError(eventArgs: inquirer.prompts.FailedPromptStateData): void;
}
export default EditorPrompt;

View File

@@ -0,0 +1,149 @@
import { Interface as ReadlineInterface } from "readline";
import inquirer, { Answers, ExpandQuestionOptions } from "../../index.js";
import Paginator from "../utils/paginator.js";
import Prompt from "./base.js";
/**
* The question-options for the {@link ExpandPrompt `ExpandPrompt<TQuestion>`}.
*/
type Question = ExpandQuestionOptions;
/**
* Represents a prompt which forces the user to make a choice by typing a specific key.
*
* @template TQuestion
* The options for the question.
*/
declare class ExpandPrompt<TQuestion extends Question = Question> extends Prompt<TQuestion> {
/**
* Resolves the value of the prompt.
*/
protected done: (value: any) => void;
/**
* Gets or sets the default key.
*/
protected rawDefault: string;
/**
* Gets or sets an object for paginating the content.
*/
protected paginator: Paginator;
/**
* Gets the promise of the keypress-eventhandler.
*/
protected keypressObs: Promise<void>;
/**
* Gets or sets the currently selected key.
*/
protected selectedKey: string;
/**
* Gets or sets the answer of the prompt.
*/
protected answer: string;
/**
* Initializes a new instance of the {@link ExpandPrompt `ExpandPrompt<TQuestion>`} class.
*
* @param question
* The question to prompt the user to answer.
*
* @param readLine
* An object for performing read from and write to the console.
*
* @param answers
* The answer-object.
*/
constructor(question: TQuestion, readLine: ReadlineInterface, answers: Answers);
/**
* Renders the prompt to the screen.
*
* @param error
* The error to render.
*
* @param hint
* The hint to render.
*/
protected render(error?: string, hint?: string): void;
/**
* Determines the current value of the prompt.
*
* @param input
* The input provided by the user.
*
* @returns
* The current value of the prompt.
*/
protected getCurrentValue(input: string): any;
/**
* Generates the string-representation of the choices.
*
* @deprecated
*
* @returns
* The string-representations of the choices.
*/
protected getChoices(): string;
/**
* Handles the `success`-event of the prompt.
*
* @param eventArgs
* An object which contains event-data.
*/
protected onSubmit(eventArgs: inquirer.prompts.SuccessfulPromptStateData): void;
/**
* Handles the `error`-event of the prompt.
*
* @param eventArgs
* An object which contains event-data.
*/
protected onError(eventArgs: inquirer.prompts.FailedPromptStateData): void;
/**
* Handles the `keypress`-event of the prompt.
*/
protected onKeypress(): void;
/**
* Validates the integrity of the choices.
*
* @param choices
* The choices to validate.
*/
protected validateChoices(choices: ExpandPrompt<TQuestion>["opt"]["choices"]): void;
/**
* Generates the string-representation of the choices.
*
* @param choices
* The choices to generate the string-representation for.
*
* @param defaultChoice
* The value of the default choice.
*
* @returns
* The string-representations of the choices.
*/
protected generateChoicesString(choices: ExpandPrompt<TQuestion>["opt"]["choices"], defaultChoice: any): string;
/**
* Renders the choices.
*
* @param choices
* The choices to render.
*
* @param pointer
* The value of the choice to select.
*/
protected renderChoices(choices: ExpandPrompt<TQuestion>["opt"]["choices"], pointer: string): string;
}
export default ExpandPrompt;

View File

@@ -0,0 +1,82 @@
import { Interface as ReadlineInterface } from "readline";
import inquirer, { Answers, InputQuestionOptions } from "../../index.js";
import Prompt from "./base.js";
/**
* The question-options for the {@link InputPrompt `InputPrompt<TQuestion>`}.
*/
type Question = InputQuestionOptions;
/**
* Represents a prompt which allows the user to type an answer.
*
* @template TQuestion
* The options for the question.
*/
declare class InputPrompt<TQuestion extends Question = Question> extends Prompt<TQuestion> {
/**
* Resolves the value of the prompt.
*/
protected done: (value: any) => void;
/**
* The answer to this prompt.
*/
protected answer: any;
/**
* Initializes a new instance of the {@link InputPrompt `InputPrompt<TQuestion>`} class.
*
* @param question
* The question to prompt the user to answer.
*
* @param readLine
* An object for performing read from and write to the console.
*
* @param answers
* The answer-object.
*/
constructor(question: TQuestion, readLine: ReadlineInterface, answers: Answers);
/**
* Renders the prompt.
*
* @param error
* The error to render.
*/
protected render(error?: string): void;
/**
* Filters the specified {@link input `input`}.
*
* @param input
* The input to filter.
*
* @returns
* The filtered input.
*/
protected filterInput(input: string): string;
/**
* Handles the `success`-event of the prompt.
*
* @param eventArgs
* An object which contains event-data.
*/
protected onEnd(eventArgs: inquirer.prompts.SuccessfulPromptStateData): void;
/**
* Handles the `error`-event of the prompt.
*
* @param eventArgs
* An object which contains event-data.
*/
protected onError(eventArgs: inquirer.prompts.FailedPromptStateData): void;
/**
* Handles the `keypress`-event of the prompt.
*/
protected onKeypress(): void;
}
export default InputPrompt;

View File

@@ -0,0 +1,89 @@
import { Interface as ReadlineInterface } from "readline";
import { Answers, ListQuestionOptions } from "../../index.js";
import Paginator from "../utils/paginator.js";
import Prompt from "./base.js";
/**
* The question-options for the {@link ListPrompt `ListPrompt<TQuestion>`}.
*/
type Question = ListQuestionOptions;
/**
* Represents a prompt which provides a list to choose an answer from.
*
* @template TQuestion
* The options for the question.
*/
declare class ListPrompt<TQuestion extends Question = Question> extends Prompt<TQuestion> {
/**
* Resolves the value of the prompt.
*/
protected done: (value: any) => void;
/**
* Gets or sets a value indicating whether the prompt has been rendered the first time.
*/
protected firstRender: boolean;
/**
* The index of the selected choice.
*/
protected selected: number;
/**
* Gets or sets an object for paginating the content.
*/
protected paginator: Paginator;
/**
* Initializes a new instance of the {@link ListPrompt `ListPrompt<TQuestion>`} class.
*
* @param question
* The question to prompt the user to answer.
*
* @param readLine
* An object for performing read from and write to the console.
*
* @param answers
* The answer-object.
*/
constructor(question: TQuestion, readLine: ReadlineInterface, answers: Answers);
/**
* Renders the prompt.
*/
protected render(): void;
/**
* Gets the current value of the prompt.
*/
protected getCurrentValue(): any;
/**
* Handles the `upKey`-event.
*/
protected onUpKey(): void;
/**
* Handles the `downKey`-event.
*/
protected onDownKey(): void;
/**
* Handles the `numberKey`-event.
*
* @param input
* The number that has been pressed.
*/
protected onNumberKey(input: number): void;
/**
* Handles the `success`-event of the prompt.
*
* @param value
* The value of the prompt.
*/
protected onSubmit(value: any): void;
}
export default ListPrompt;

View File

@@ -0,0 +1,32 @@
import { Interface as ReadlineInterface } from "readline";
import { Answers, NumberQuestionOptions } from "../../index.js";
import InputPrompt from "./input.js";
/**
* The question for the {@link NumberPrompt `NumberPrompt<TQuestion>`}.
*/
type Question = NumberQuestionOptions;
/**
* Provides a prompt which allows the user to type a number as answer.
*
* @template TQuestion
* The options for the question.
*/
declare class NumberPrompt<TQuestion extends Question = Question> extends InputPrompt<TQuestion> {
/**
* Initializes a new instance of the {@link NumberPrompt `NumberPrompt<TQuestion>`} class.
*
* @param question
* The question to prompt the user to answer.
*
* @param readLine
* An object for performing read from and write to the console.
*
* @param answers
* The answer-object.
*/
constructor(question: TQuestion, readLine: ReadlineInterface, answers: Answers);
}
export default NumberPrompt;

View File

@@ -0,0 +1,82 @@
import { Interface as ReadlineInterface } from "readline";
import inquirer, { Answers, PasswordQuestionOptions } from "../../index.js";
import Prompt from "./base.js";
/**
* The question for the {@link PasswordPrompt `PasswordPrompt<TQuestion>`}.
*/
type Question = PasswordQuestionOptions;
/**
* Represents a prompt which allows the user to type a password.
*
* @template TQuestion
* The options for the question.
*/
declare class PasswordPrompt<TQuestion extends Question = Question> extends Prompt<TQuestion> {
/**
* Resolves the value of the prompt.
*/
protected done: (value: any) => void;
/**
* The answer to this prompt.
*/
protected answer: any;
/**
* Initializes a new instance of the {@link PasswordPrompt `PasswordPrompt<TQuestion>`} class.
*
* @param question
* The question to prompt the user to answer.
*
* @param readLine
* An object for performing read from and write to the console.
*
* @param answers
* The answer-object.
*/
constructor(question: TQuestion, readLine: ReadlineInterface, answers: Answers);
/**
* Renders the prompt.
*
* @param error
* The error to render.
*/
protected render(error?: string): void;
/**
* Filters the specified {@link input `input`}.
*
* @param input
* The input to filter.
*
* @returns
* The filtered input.
*/
protected filterInput(input: string): string;
/**
* Handles the `keypress`-event of the prompt.
*/
protected onKeypress(): void;
/**
* Handles the `success`-event of the prompt.
*
* @param eventArgs
* An object which contains event-data.
*/
protected onEnd(eventArgs: inquirer.prompts.SuccessfulPromptStateData): void;
/**
* Handles the `error`-event of the prompt.
*
* @param eventArgs
* An object which contains event-data.
*/
protected onError(eventArgs: inquirer.prompts.FailedPromptStateData): void;
}
export default PasswordPrompt;

View File

@@ -0,0 +1,111 @@
import { Interface as ReadlineInterface } from "readline";
import inquirer, { Answers, RawListQuestionOptions } from "../../index.js";
import Paginator from "../utils/paginator.js";
import Prompt from "./base.js";
/**
* The question for the {@link RawListPrompt `RawListPrompt<TQuestion>`}.
*/
type Question = RawListQuestionOptions;
/**
* Represents a prompt which provides a list to choose an answer from.
*
* @template TQuestion
* The options for the question.
*/
declare class RawListPrompt<TQuestion extends Question = Question> extends Prompt<TQuestion> {
/**
* Resolves the value of the prompt.
*/
protected done: (value: any) => void;
/**
* The index of the selected choice.
*/
protected selected: number;
/**
* Gets or sets the default index.
*/
protected rawDefault: number;
/**
* Gets or sets an object for paginating the content.
*/
protected paginator: Paginator;
/**
* Initializes a new instance of the {@link RawListPrompt `RawListPrompt<TQuestion>`} class.
*
* @param question
* The question to prompt the user to answer.
*
* @param readLine
* An object for performing read from and write to the console.
*
* @param answers
* The answer-object.
*/
constructor(question: TQuestion, readLine: ReadlineInterface, answers: Answers);
/**
* Renders the prompt.
*
* @param error
* The error to render.
*/
protected render(error?: string): void;
/**
* Gets the value of the specified {@link index `index`}.
*
* @param index
* The index to get the value for.
*
* @returns
* The value of the specified {@link index `index`}.
*/
protected getCurrentValue(index: number): any;
/**
* Handles the `Keypress`-event of the prompt.
*/
protected onKeypress(): void;
/**
* Handles the `UpdKey`-event of the prompt.
*/
protected onUpKey(): void;
/**
* Handles the `DownKey`-event of the prompt.
*/
protected onDownKey(): void;
/**
* Handles the `ArrowKey`-event of the prompt.
*
* @param type
* A value indicating whether the up or the down-arrow is being pressed.
*/
protected onArrowKey(type: "up" | "down"): void;
/**
* Handles the `success`-event of the prompt.
*
* @param eventArgs
* An object which contains event-data.
*/
protected onEnd(eventArgs: inquirer.prompts.SuccessfulPromptStateData): void;
/**
* Handles the `error`-event of the prompt.
*
* @param eventArgs
* An object which contains event-data.
*/
protected onError(): void;
}
export default RawListPrompt;

View File

@@ -0,0 +1,37 @@
import { Interface as ReadlineInterface } from "readline";
import inquirer, { StreamOptions } from "../../index.js";
/**
* Represents a ui.
*/
declare class UI {
/**
* Gets or sets an object for performing read from and write to the console.
*/
protected rl: ReadlineInterface;
/**
* Gets or sets the currently active prompt.
*/
protected activePrompt: inquirer.prompts.PromptBase;
/**
* Initializes a new instance of the {@link UI `UI`} class.
*
* @param options
* The input- and output-stream of the ui.
*/
constructor(options?: StreamOptions);
/**
* Handles a forced exit of the application.
*/
protected onForceClose(): void;
/**
* Releases all unmanaged resources.
*/
protected close(): void;
}
export default UI;

View File

@@ -0,0 +1,3 @@
import inquirer from "../../index.js";
export default inquirer.ui.BottomBar;

View File

@@ -0,0 +1,3 @@
import inquirer from "../../index.js";
export default inquirer.ui.Prompt;

View File

@@ -0,0 +1,72 @@
import { Interface as ReadlineInterface, Key } from "readline";
import { Observable } from "rxjs";
/**
* Provides a description about a key.
*/
interface KeyDescriptor {
/**
* The value of the key.
*/
value: string;
/**
* The description of the key.
*/
key: Key;
}
/**
* A set of events.
*/
interface Events {
/**
* The event-flow of the `line`-event of the {@link ReadlineInterface `readline.Interface`}-object.
*/
line: Observable<string>;
/**
* The event-flow of the `keypress`-event of the {@link ReadlineInterface `readline.Interface`}-object.
*/
keypress: Observable<KeyDescriptor>;
/**
* The event-flow of the `normalizedUpKey`-event.
*/
normalizedUpKey: Observable<KeyDescriptor>;
/**
* The event-flow of the `normalizedDownKey`-event.
*/
normalizedDownKey: Observable<KeyDescriptor>;
/**
* The event-flow of the `numberKey`-event.
*/
numberKey: Observable<KeyDescriptor>;
/**
* The event-flow of the `spaceKey`-event.
*/
spaceKey: Observable<KeyDescriptor>;
/**
* The event-flow of the `aKey`-event.
*/
aKey: Observable<KeyDescriptor>;
/**
* The event-flow of the `iKey`-event.
*/
iKey: Observable<KeyDescriptor>;
}
/**
* Observes a {@link ReadlineInterface `readline.Interface`}-object.
*
* @param readline
* The readline-object to observe.
*/
export default function(readline: ReadlineInterface): Events;
export {};

View File

@@ -0,0 +1,23 @@
import Choices from "../objects/choices.js";
type Direction = "up" | "down";
interface Options {
choices: Choices;
loop?: boolean;
}
/**
* Find the index of the next answer to be selected.
*
* @param current
* Index of the answer currently selected.
* @param dir
* Whether to go up or down in the answers list.
* @param opt
* The option used for the question initialization.
* @return
* The index of the next answer to be selected.
*/
declare function incrementListIndex(current: number, dir: Direction, opt: Options): number;
export default incrementListIndex;

View File

@@ -0,0 +1,55 @@
import ScreenManager from "./screen-manager.js";
interface PaginatorOptions {
/**
* Whether or not to loop the content.
*/
isInfinite: boolean;
}
/**
* Provides the functionality to draw paginated content using a {@link ScreenManager `ScreenManager`}.
*/
declare class Paginator {
/**
* Gets or sets the index of the currently focused line.
*/
protected pointer: number;
/**
* Gets or sets the index of the last focused line.
*/
protected lastIndex: number;
/**
* Gets or sets an object for drawing the paginated content.
*/
protected screen: ScreenManager;
/**
* Initializes a new instance of the {@link Paginator `Paginator`} class.
*
* @param screenManager
* A screen-manager for drawing the paginated content.
*/
constructor(screenManager: ScreenManager, options?: PaginatorOptions);
/**
* Paginates the specified {@link content `content`}.
*
* @param content
* The content to paginate.
*
* @param selectedIndex
* The number of the selected line.
*
* @param pageSize
* The number of lines to display at a time.
*
* @returns
* The paginated content.
*/
paginate(content: string, selectedIndex: number, pageSize?: number): string;
}
export default Paginator;

View File

@@ -0,0 +1,56 @@
import { Interface as ReadlineInterface } from "readline";
/**
* Moves the cursor to the left.
*
* @param readLine
* The readline-object.
*
* @param count
* The number of columns to move the cursor.
*/
export function left(readLine: ReadlineInterface, count: number): void;
/**
* Moves the cursor to the right.
*
* @param readLine
* The readline-object.
*
* @param count
* The number of columns to move the cursor.
*/
export function right(readLine: ReadlineInterface, count: number): void;
/**
* Moves the cursor upwards.
*
* @param readLine
* The readline-object.
*
* @param count
* The number of lines to move the cursor.
*/
export function up(readLine: ReadlineInterface, count: number): void;
/**
* Moves the cursor downwards.
*
* @param readLine
* The readline-object.
*
* @param count
* The number of lines to move the cursor.
*/
export function down(readLine: ReadlineInterface, count: number): void;
/**
* Clears one or more lines.
*
* @param readLine
* The readline-object.
*
* @param count
* The number of lines to clear.
*/
export function clearLine(readLine: ReadlineInterface, count: number): void;

View File

@@ -0,0 +1,90 @@
import { Interface as ReadLineInterface } from "readline";
/**
* Provides the functionality to manage the content of a console-screen.
*/
declare class ScreenManager {
/**
* Gets or sets the height of the screen.
*/
height: number;
/**
* Gets or sets the number of extra-lines below the prompt.
*/
extraLinesUnderPrompt: number;
/**
* Gets or sets an object for reading from and writing to the console.
*/
rl: ReadLineInterface;
/**
* Initializes a new instance of the {@link ScreenManager `ScreenManager`} class.
*
* @param readLine
* An object for reading from and writing to the console.
*/
constructor(readLine: ReadLineInterface);
/**
* Renders content to the screen.
*
* @param content
* The content to render.
*
* @param bottomContent
* The content to render to the bottom of the screen.
*/
render(content: string, bottomContent: string): void;
/**
* Cleans all lines expect the first {@link extraLines `extraLines`}.
*
* @param extraLines
* The number of lines at the begin to skip.
*/
clean(extraLines: number): void;
/**
* Releases all unmanaged resources.
*/
done(): void;
/**
* Releases the cursor.
*/
releaseCursor(): void;
/**
* Identifies the width of the screen.
*
* @returns
* The width of the screen.
*/
protected normalizedCliWidth(): number;
/**
* Splits the {@link text `text`} into multiple lines with the specified maximum {@link width `width`}.
*
* @param text
* The text to process.
*
* @param width
* The max width of each line.
*/
protected breakLines(text: string, width: number): string[];
/**
* Adds line-breaks to the specified {@link text `text`} with the specified maximum {@link width `width`}.
*
* @param text
* The text to process.
*
* @param width
* The maximum width of each line.
*/
protected forceLineReturn(text: string, width: number): string;
}
export default ScreenManager;

View File

@@ -0,0 +1,30 @@
import { Observable } from "rxjs";
import { Answers, DistinctQuestion, KeyUnion, UnionToIntersection } from "../../index.js";
/**
* Represents a property-name of any question-type.
*/
type QuestionProperty = KeyUnion<UnionToIntersection<DistinctQuestion>>;
/**
* Fetches a property of the specified {@link question `question`}.
*
* @param question
* The question to fetch the property from.
*
* @param prop
* The name of the property to fetch.
*
* @param answers
* The answers provided by the user.
*
* @returns
* The processed question.
*/
export function fetchAsyncQuestionProperty(
question: DistinctQuestion,
prop: QuestionProperty,
answers: Answers,
): Observable<DistinctQuestion>;
export {};

View File

@@ -0,0 +1,70 @@
{
"name": "@types/inquirer",
"version": "9.0.8",
"description": "TypeScript definitions for inquirer",
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/inquirer",
"license": "MIT",
"contributors": [
{
"name": "Qubo",
"githubUsername": "tkQubo",
"url": "https://github.com/tkQubo"
},
{
"name": "Parvez",
"githubUsername": "ppathan",
"url": "https://github.com/ppathan"
},
{
"name": "Jouderian",
"githubUsername": "jouderianjr",
"url": "https://github.com/jouderianjr"
},
{
"name": "Qibang",
"githubUsername": "bang88",
"url": "https://github.com/bang88"
},
{
"name": "Jason Dreyzehner",
"githubUsername": "bitjson",
"url": "https://github.com/bitjson"
},
{
"name": "Synarque",
"githubUsername": "synarque",
"url": "https://github.com/synarque"
},
{
"name": "Justin Rockwood",
"githubUsername": "jrockwood",
"url": "https://github.com/jrockwood"
},
{
"name": "Keith Kelly",
"githubUsername": "kwkelly",
"url": "https://github.com/kwkelly"
},
{
"name": "Richard Lea",
"githubUsername": "chigix",
"url": "https://github.com/chigix"
}
],
"type": "module",
"main": "",
"types": "index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
"directory": "types/inquirer"
},
"scripts": {},
"dependencies": {
"@types/through": "*",
"rxjs": "^7.2.0"
},
"peerDependencies": {},
"typesPublisherContentHash": "021c75d431cee8172e2b4faf1198f27422ffa9602a76c77731dd14aaaaa8f212",
"typeScriptVersion": "5.1"
}

View File

@@ -0,0 +1,47 @@
/**
Create an error from multiple errors.
*/
export default class AggregateError<T extends Error = Error> extends Error {
readonly name: 'AggregateError';
readonly errors: readonly [T];
/**
@param errors - If a string, a new `Error` is created with the string as the error message. If a non-Error object, a new `Error` is created with all properties from the object copied over.
@example
```
import AggregateError from 'aggregate-error';
const error = new AggregateError([new Error('foo'), 'bar', {message: 'baz'}]);
throw error;
// AggregateError:
// Error: foo
// at Object.<anonymous> (/Users/sindresorhus/dev/aggregate-error/example.js:3:33)
// Error: bar
// at Object.<anonymous> (/Users/sindresorhus/dev/aggregate-error/example.js:3:13)
// Error: baz
// at Object.<anonymous> (/Users/sindresorhus/dev/aggregate-error/example.js:3:13)
// at AggregateError (/Users/sindresorhus/dev/aggregate-error/index.js:19:3)
// at Object.<anonymous> (/Users/sindresorhus/dev/aggregate-error/example.js:3:13)
// at Module._compile (module.js:556:32)
// at Object.Module._extensions..js (module.js:565:10)
// at Module.load (module.js:473:32)
// at tryModuleLoad (module.js:432:12)
// at Function.Module._load (module.js:424:3)
// at Module.runMain (module.js:590:10)
// at run (bootstrap_node.js:394:7)
// at startup (bootstrap_node.js:149:9)
for (const individualError of error.errors) {
console.log(individualError);
}
//=> [Error: foo]
//=> [Error: bar]
//=> [Error: baz]
```
*/
constructor(errors: ReadonlyArray<T | Record<string, any> | string>);
}

View File

@@ -0,0 +1,44 @@
import indentString from 'indent-string';
import cleanStack from 'clean-stack';
const cleanInternalStack = stack => stack.replace(/\s+at .*aggregate-error\/index.js:\d+:\d+\)?/g, '');
export default class AggregateError extends Error {
#errors;
name = 'AggregateError';
constructor(errors) {
if (!Array.isArray(errors)) {
throw new TypeError(`Expected input to be an Array, got ${typeof errors}`);
}
errors = errors.map(error => {
if (error instanceof Error) {
return error;
}
if (error !== null && typeof error === 'object') {
// Handle plain error objects with message property and/or possibly other metadata
return Object.assign(new Error(error.message), error);
}
return new Error(error);
});
let message = errors
.map(error => {
// The `stack` property is not standardized, so we can't assume it exists
return typeof error.stack === 'string' && error.stack.length > 0 ? cleanInternalStack(cleanStack(error.stack)) : String(error);
})
.join('\n');
message = '\n' + indentString(message, 4);
super(message);
this.#errors = errors;
}
get errors() {
return this.#errors.slice();
}
}

View File

@@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
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.

View File

@@ -0,0 +1,45 @@
{
"name": "aggregate-error",
"version": "4.0.1",
"description": "Create an error from multiple errors",
"license": "MIT",
"repository": "sindresorhus/aggregate-error",
"funding": "https://github.com/sponsors/sindresorhus",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "https://sindresorhus.com"
},
"type": "module",
"exports": "./index.js",
"engines": {
"node": ">=12"
},
"scripts": {
"//test": "xo && ava && tsd",
"test": "ava && tsd"
},
"files": [
"index.js",
"index.d.ts"
],
"keywords": [
"aggregate",
"error",
"combine",
"multiple",
"many",
"collection",
"iterable",
"iterator"
],
"dependencies": {
"clean-stack": "^4.0.0",
"indent-string": "^5.0.0"
},
"devDependencies": {
"ava": "^3.15.0",
"tsd": "^0.14.0",
"xo": "^0.38.2"
}
}

View File

@@ -0,0 +1,60 @@
# aggregate-error
> Create an error from multiple errors
*Note: With [Node.js 15](https://medium.com/@nodejs/node-js-v15-0-0-is-here-deb00750f278), there's now a built-in [`AggregateError`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError) type.*
## Install
```
$ npm install aggregate-error
```
## Usage
```js
import AggregateError from 'aggregate-error';
const error = new AggregateError([new Error('foo'), 'bar', {message: 'baz'}]);
throw error;
/*
AggregateError:
Error: foo
at Object.<anonymous> (/Users/sindresorhus/dev/aggregate-error/example.js:3:33)
Error: bar
at Object.<anonymous> (/Users/sindresorhus/dev/aggregate-error/example.js:3:13)
Error: baz
at Object.<anonymous> (/Users/sindresorhus/dev/aggregate-error/example.js:3:13)
at AggregateError (/Users/sindresorhus/dev/aggregate-error/index.js:19:3)
at Object.<anonymous> (/Users/sindresorhus/dev/aggregate-error/example.js:3:13)
at Module._compile (module.js:556:32)
at Object.Module._extensions..js (module.js:565:10)
at Module.load (module.js:473:32)
at tryModuleLoad (module.js:432:12)
at Function.Module._load (module.js:424:3)
at Module.runMain (module.js:590:10)
at run (bootstrap_node.js:394:7)
at startup (bootstrap_node.js:149:9)
*/
for (const individualError of error.errors) {
console.log(individualError);
}
//=> [Error: foo]
//=> [Error: bar]
//=> [Error: baz]
```
## API
### AggregateError(errors)
Returns an `Error`.
#### errors
Type: `Array<Error|object|string>`
If a string, a new `Error` is created with the string as the error message.\
If a non-Error object, a new `Error` is created with all properties from the object copied over.

View File

@@ -0,0 +1,33 @@
export type Options = {
/**
Match only the first ANSI escape.
@default false
*/
readonly onlyFirst: boolean;
};
/**
Regular expression for matching ANSI escape codes.
@example
```
import ansiRegex from 'ansi-regex';
ansiRegex().test('\u001B[4mcake\u001B[0m');
//=> true
ansiRegex().test('cake');
//=> false
'\u001B[4mcake\u001B[0m'.match(ansiRegex());
//=> ['\u001B[4m', '\u001B[0m']
'\u001B[4mcake\u001B[0m'.match(ansiRegex({onlyFirst: true}));
//=> ['\u001B[4m']
'\u001B]8;;https://github.com\u0007click\u001B]8;;\u0007'.match(ansiRegex());
//=> ['\u001B]8;;https://github.com\u0007', '\u001B]8;;\u0007']
```
*/
export default function ansiRegex(options?: Options): RegExp;

View File

@@ -0,0 +1,10 @@
export default function ansiRegex({onlyFirst = false} = {}) {
// Valid string terminator sequences are BEL, ESC\, and 0x9c
const ST = '(?:\\u0007|\\u001B\\u005C|\\u009C)';
const pattern = [
`[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?${ST})`,
'(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))',
].join('|');
return new RegExp(pattern, onlyFirst ? undefined : 'g');
}

View File

@@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
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.

View File

@@ -0,0 +1,61 @@
{
"name": "ansi-regex",
"version": "6.1.0",
"description": "Regular expression for matching ANSI escape codes",
"license": "MIT",
"repository": "chalk/ansi-regex",
"funding": "https://github.com/chalk/ansi-regex?sponsor=1",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "https://sindresorhus.com"
},
"type": "module",
"exports": "./index.js",
"types": "./index.d.ts",
"sideEffects": false,
"engines": {
"node": ">=12"
},
"scripts": {
"test": "xo && ava && tsd",
"view-supported": "node fixtures/view-codes.js"
},
"files": [
"index.js",
"index.d.ts"
],
"keywords": [
"ansi",
"styles",
"color",
"colour",
"colors",
"terminal",
"console",
"cli",
"string",
"tty",
"escape",
"formatting",
"rgb",
"256",
"shell",
"xterm",
"command-line",
"text",
"regex",
"regexp",
"re",
"match",
"test",
"find",
"pattern"
],
"devDependencies": {
"ansi-escapes": "^5.0.0",
"ava": "^3.15.0",
"tsd": "^0.21.0",
"xo": "^0.54.2"
}
}

View File

@@ -0,0 +1,60 @@
# ansi-regex
> Regular expression for matching [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code)
## Install
```sh
npm install ansi-regex
```
## Usage
```js
import ansiRegex from 'ansi-regex';
ansiRegex().test('\u001B[4mcake\u001B[0m');
//=> true
ansiRegex().test('cake');
//=> false
'\u001B[4mcake\u001B[0m'.match(ansiRegex());
//=> ['\u001B[4m', '\u001B[0m']
'\u001B[4mcake\u001B[0m'.match(ansiRegex({onlyFirst: true}));
//=> ['\u001B[4m']
'\u001B]8;;https://github.com\u0007click\u001B]8;;\u0007'.match(ansiRegex());
//=> ['\u001B]8;;https://github.com\u0007', '\u001B]8;;\u0007']
```
## API
### ansiRegex(options?)
Returns a regex for matching ANSI escape codes.
#### options
Type: `object`
##### onlyFirst
Type: `boolean`\
Default: `false` *(Matches any ANSI escape codes in a string)*
Match only the first ANSI escape.
## FAQ
### Why do you test for codes not in the ECMA 48 standard?
Some of the codes we run as a test are codes that we acquired finding various lists of non-standard or manufacturer specific codes. We test for both standard and non-standard codes, as most of them follow the same or similar format and can be safely matched in strings without the risk of removing actual string content. There are a few non-standard control codes that do not follow the traditional format (i.e. they end in numbers) thus forcing us to exclude them from the test because we cannot reliably match them.
On the historical side, those ECMA standards were established in the early 90's whereas the VT100, for example, was designed in the mid/late 70's. At that point in time, control codes were still pretty ungoverned and engineers used them for a multitude of things, namely to activate hardware ports that may have been proprietary. Somewhere else you see a similar 'anarchy' of codes is in the x86 architecture for processors; there are a ton of "interrupts" that can mean different things on certain brands of processors, most of which have been phased out.
## Maintainers
- [Sindre Sorhus](https://github.com/sindresorhus)
- [Josh Junon](https://github.com/qix-)

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>
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.

View File

@@ -0,0 +1,129 @@
# brace-expansion
[Brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html),
as known from sh/bash, in JavaScript.
[![build status](https://secure.travis-ci.org/juliangruber/brace-expansion.svg)](http://travis-ci.org/juliangruber/brace-expansion)
[![downloads](https://img.shields.io/npm/dm/brace-expansion.svg)](https://www.npmjs.org/package/brace-expansion)
[![Greenkeeper badge](https://badges.greenkeeper.io/juliangruber/brace-expansion.svg)](https://greenkeeper.io/)
[![testling badge](https://ci.testling.com/juliangruber/brace-expansion.png)](https://ci.testling.com/juliangruber/brace-expansion)
## Example
```js
var expand = require('brace-expansion');
expand('file-{a,b,c}.jpg')
// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg']
expand('-v{,,}')
// => ['-v', '-v', '-v']
expand('file{0..2}.jpg')
// => ['file0.jpg', 'file1.jpg', 'file2.jpg']
expand('file-{a..c}.jpg')
// => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg']
expand('file{2..0}.jpg')
// => ['file2.jpg', 'file1.jpg', 'file0.jpg']
expand('file{0..4..2}.jpg')
// => ['file0.jpg', 'file2.jpg', 'file4.jpg']
expand('file-{a..e..2}.jpg')
// => ['file-a.jpg', 'file-c.jpg', 'file-e.jpg']
expand('file{00..10..5}.jpg')
// => ['file00.jpg', 'file05.jpg', 'file10.jpg']
expand('{{A..C},{a..c}}')
// => ['A', 'B', 'C', 'a', 'b', 'c']
expand('ppp{,config,oe{,conf}}')
// => ['ppp', 'pppconfig', 'pppoe', 'pppoeconf']
```
## API
```js
var expand = require('brace-expansion');
```
### var expanded = expand(str)
Return an array of all possible and valid expansions of `str`. If none are
found, `[str]` is returned.
Valid expansions are:
```js
/^(.*,)+(.+)?$/
// {a,b,...}
```
A comma separated list of options, like `{a,b}` or `{a,{b,c}}` or `{,a,}`.
```js
/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/
// {x..y[..incr]}
```
A numeric sequence from `x` to `y` inclusive, with optional increment.
If `x` or `y` start with a leading `0`, all the numbers will be padded
to have equal length. Negative numbers and backwards iteration work too.
```js
/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/
// {x..y[..incr]}
```
An alphabetic sequence from `x` to `y` inclusive, with optional increment.
`x` and `y` must be exactly one character, and if given, `incr` must be a
number.
For compatibility reasons, the string `${` is not eligible for brace expansion.
## Installation
With [npm](https://npmjs.org) do:
```bash
npm install brace-expansion
```
## Contributors
- [Julian Gruber](https://github.com/juliangruber)
- [Isaac Z. Schlueter](https://github.com/isaacs)
## Sponsors
This module is proudly supported by my [Sponsors](https://github.com/juliangruber/sponsors)!
Do you want to support modules like this to improve their quality, stability and weigh in on new features? Then please consider donating to my [Patreon](https://www.patreon.com/juliangruber). Not sure how much of my modules you're using? Try [feross/thanks](https://github.com/feross/thanks)!
## License
(MIT)
Copyright (c) 2013 Julian Gruber &lt;julian@juliangruber.com&gt;
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.

View File

@@ -0,0 +1,201 @@
var concatMap = require('concat-map');
var balanced = require('balanced-match');
module.exports = expandTop;
var escSlash = '\0SLASH'+Math.random()+'\0';
var escOpen = '\0OPEN'+Math.random()+'\0';
var escClose = '\0CLOSE'+Math.random()+'\0';
var escComma = '\0COMMA'+Math.random()+'\0';
var escPeriod = '\0PERIOD'+Math.random()+'\0';
function numeric(str) {
return parseInt(str, 10) == str
? parseInt(str, 10)
: str.charCodeAt(0);
}
function escapeBraces(str) {
return str.split('\\\\').join(escSlash)
.split('\\{').join(escOpen)
.split('\\}').join(escClose)
.split('\\,').join(escComma)
.split('\\.').join(escPeriod);
}
function unescapeBraces(str) {
return str.split(escSlash).join('\\')
.split(escOpen).join('{')
.split(escClose).join('}')
.split(escComma).join(',')
.split(escPeriod).join('.');
}
// Basically just str.split(","), but handling cases
// where we have nested braced sections, which should be
// treated as individual members, like {a,{b,c},d}
function parseCommaParts(str) {
if (!str)
return [''];
var parts = [];
var m = balanced('{', '}', str);
if (!m)
return str.split(',');
var pre = m.pre;
var body = m.body;
var post = m.post;
var p = pre.split(',');
p[p.length-1] += '{' + body + '}';
var postParts = parseCommaParts(post);
if (post.length) {
p[p.length-1] += postParts.shift();
p.push.apply(p, postParts);
}
parts.push.apply(parts, p);
return parts;
}
function expandTop(str) {
if (!str)
return [];
// I don't know why Bash 4.3 does this, but it does.
// Anything starting with {} will have the first two bytes preserved
// but *only* at the top level, so {},a}b will not expand to anything,
// but a{},b}c will be expanded to [a}c,abc].
// One could argue that this is a bug in Bash, but since the goal of
// this module is to match Bash's rules, we escape a leading {}
if (str.substr(0, 2) === '{}') {
str = '\\{\\}' + str.substr(2);
}
return expand(escapeBraces(str), true).map(unescapeBraces);
}
function identity(e) {
return e;
}
function embrace(str) {
return '{' + str + '}';
}
function isPadded(el) {
return /^-?0\d/.test(el);
}
function lte(i, y) {
return i <= y;
}
function gte(i, y) {
return i >= y;
}
function expand(str, isTop) {
var expansions = [];
var m = balanced('{', '}', str);
if (!m || /\$$/.test(m.pre)) return [str];
var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
var isSequence = isNumericSequence || isAlphaSequence;
var isOptions = m.body.indexOf(',') >= 0;
if (!isSequence && !isOptions) {
// {a},b}
if (m.post.match(/,.*\}/)) {
str = m.pre + '{' + m.body + escClose + m.post;
return expand(str);
}
return [str];
}
var n;
if (isSequence) {
n = m.body.split(/\.\./);
} else {
n = parseCommaParts(m.body);
if (n.length === 1) {
// x{{a,b}}y ==> x{a}y x{b}y
n = expand(n[0], false).map(embrace);
if (n.length === 1) {
var post = m.post.length
? expand(m.post, false)
: [''];
return post.map(function(p) {
return m.pre + n[0] + p;
});
}
}
}
// at this point, n is the parts, and we know it's not a comma set
// with a single entry.
// no need to expand pre, since it is guaranteed to be free of brace-sets
var pre = m.pre;
var post = m.post.length
? expand(m.post, false)
: [''];
var N;
if (isSequence) {
var x = numeric(n[0]);
var y = numeric(n[1]);
var width = Math.max(n[0].length, n[1].length)
var incr = n.length == 3
? Math.abs(numeric(n[2]))
: 1;
var test = lte;
var reverse = y < x;
if (reverse) {
incr *= -1;
test = gte;
}
var pad = n.some(isPadded);
N = [];
for (var i = x; test(i, y); i += incr) {
var c;
if (isAlphaSequence) {
c = String.fromCharCode(i);
if (c === '\\')
c = '';
} else {
c = String(i);
if (pad) {
var need = width - c.length;
if (need > 0) {
var z = new Array(need + 1).join('0');
if (i < 0)
c = '-' + z + c.slice(1);
else
c = z + c;
}
}
}
N.push(c);
}
} else {
N = concatMap(n, function(el) { return expand(el, false) });
}
for (var j = 0; j < N.length; j++) {
for (var k = 0; k < post.length; k++) {
var expansion = pre + N[j] + post[k];
if (!isTop || isSequence || expansion)
expansions.push(expansion);
}
}
return expansions;
}

View File

@@ -0,0 +1,47 @@
{
"name": "brace-expansion",
"description": "Brace expansion as known from sh/bash",
"version": "1.1.11",
"repository": {
"type": "git",
"url": "git://github.com/juliangruber/brace-expansion.git"
},
"homepage": "https://github.com/juliangruber/brace-expansion",
"main": "index.js",
"scripts": {
"test": "tape test/*.js",
"gentest": "bash test/generate.sh",
"bench": "matcha test/perf/bench.js"
},
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
},
"devDependencies": {
"matcha": "^0.7.0",
"tape": "^4.6.0"
},
"keywords": [],
"author": {
"name": "Julian Gruber",
"email": "mail@juliangruber.com",
"url": "http://juliangruber.com"
},
"license": "MIT",
"testling": {
"files": "test/*.js",
"browsers": [
"ie/8..latest",
"firefox/20..latest",
"firefox/nightly",
"chrome/25..latest",
"chrome/canary",
"opera/12..latest",
"opera/next",
"safari/5.1..latest",
"ipad/6.0..latest",
"iphone/6.0..latest",
"android-browser/4.2..latest"
]
}
}

9
server/node_modules/plop/node_modules/chalk/license generated vendored Normal file
View File

@@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
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.

View File

@@ -0,0 +1,83 @@
{
"name": "chalk",
"version": "5.4.1",
"description": "Terminal string styling done right",
"license": "MIT",
"repository": "chalk/chalk",
"funding": "https://github.com/chalk/chalk?sponsor=1",
"type": "module",
"main": "./source/index.js",
"exports": "./source/index.js",
"imports": {
"#ansi-styles": "./source/vendor/ansi-styles/index.js",
"#supports-color": {
"node": "./source/vendor/supports-color/index.js",
"default": "./source/vendor/supports-color/browser.js"
}
},
"types": "./source/index.d.ts",
"sideEffects": false,
"engines": {
"node": "^12.17.0 || ^14.13 || >=16.0.0"
},
"scripts": {
"test": "xo && c8 ava && tsd",
"bench": "matcha benchmark.js"
},
"files": [
"source",
"!source/index.test-d.ts"
],
"keywords": [
"color",
"colour",
"colors",
"terminal",
"console",
"cli",
"string",
"ansi",
"style",
"styles",
"tty",
"formatting",
"rgb",
"256",
"shell",
"xterm",
"log",
"logging",
"command-line",
"text"
],
"devDependencies": {
"@types/node": "^16.11.10",
"ava": "^3.15.0",
"c8": "^7.10.0",
"color-convert": "^2.0.1",
"execa": "^6.0.0",
"log-update": "^5.0.0",
"matcha": "^0.7.0",
"tsd": "^0.19.0",
"xo": "^0.57.0",
"yoctodelay": "^2.0.0"
},
"xo": {
"rules": {
"unicorn/prefer-string-slice": "off",
"@typescript-eslint/consistent-type-imports": "off",
"@typescript-eslint/consistent-type-exports": "off",
"@typescript-eslint/consistent-type-definitions": "off",
"unicorn/expiring-todo-comments": "off"
}
},
"c8": {
"reporter": [
"text",
"lcov"
],
"exclude": [
"source/vendor"
]
}
}

297
server/node_modules/plop/node_modules/chalk/readme.md generated vendored Normal file
View File

@@ -0,0 +1,297 @@
<h1 align="center">
<br>
<br>
<img width="320" src="media/logo.svg" alt="Chalk">
<br>
<br>
<br>
</h1>
> Terminal string styling done right
[![Coverage Status](https://codecov.io/gh/chalk/chalk/branch/main/graph/badge.svg)](https://codecov.io/gh/chalk/chalk)
[![npm dependents](https://badgen.net/npm/dependents/chalk)](https://www.npmjs.com/package/chalk?activeTab=dependents)
[![Downloads](https://badgen.net/npm/dt/chalk)](https://www.npmjs.com/package/chalk)
![](media/screenshot.png)
## Info
- [Why not switch to a smaller coloring package?](https://github.com/chalk/chalk?tab=readme-ov-file#why-not-switch-to-a-smaller-coloring-package)
- See [yoctocolors](https://github.com/sindresorhus/yoctocolors) for a smaller alternative
## Highlights
- Expressive API
- Highly performant
- No dependencies
- Ability to nest styles
- [256/Truecolor color support](#256-and-truecolor-color-support)
- Auto-detects color support
- Doesn't extend `String.prototype`
- Clean and focused
- Actively maintained
- [Used by ~115,000 packages](https://www.npmjs.com/browse/depended/chalk) as of July 4, 2024
## Install
```sh
npm install chalk
```
**IMPORTANT:** Chalk 5 is ESM. If you want to use Chalk with TypeScript or a build tool, you will probably want to use Chalk 4 for now. [Read more.](https://github.com/chalk/chalk/releases/tag/v5.0.0)
## Usage
```js
import chalk from 'chalk';
console.log(chalk.blue('Hello world!'));
```
Chalk comes with an easy to use composable API where you just chain and nest the styles you want.
```js
import chalk from 'chalk';
const log = console.log;
// Combine styled and normal strings
log(chalk.blue('Hello') + ' World' + chalk.red('!'));
// Compose multiple styles using the chainable API
log(chalk.blue.bgRed.bold('Hello world!'));
// Pass in multiple arguments
log(chalk.blue('Hello', 'World!', 'Foo', 'bar', 'biz', 'baz'));
// Nest styles
log(chalk.red('Hello', chalk.underline.bgBlue('world') + '!'));
// Nest styles of the same type even (color, underline, background)
log(chalk.green(
'I am a green line ' +
chalk.blue.underline.bold('with a blue substring') +
' that becomes green again!'
));
// ES2015 template literal
log(`
CPU: ${chalk.red('90%')}
RAM: ${chalk.green('40%')}
DISK: ${chalk.yellow('70%')}
`);
// Use RGB colors in terminal emulators that support it.
log(chalk.rgb(123, 45, 67).underline('Underlined reddish color'));
log(chalk.hex('#DEADED').bold('Bold gray!'));
```
Easily define your own themes:
```js
import chalk from 'chalk';
const error = chalk.bold.red;
const warning = chalk.hex('#FFA500'); // Orange color
console.log(error('Error!'));
console.log(warning('Warning!'));
```
Take advantage of console.log [string substitution](https://nodejs.org/docs/latest/api/console.html#console_console_log_data_args):
```js
import chalk from 'chalk';
const name = 'Sindre';
console.log(chalk.green('Hello %s'), name);
//=> 'Hello Sindre'
```
## API
### chalk.`<style>[.<style>...](string, [string...])`
Example: `chalk.red.bold.underline('Hello', 'world');`
Chain [styles](#styles) and call the last one as a method with a string argument. Order doesn't matter, and later styles take precedent in case of a conflict. This simply means that `chalk.red.yellow.green` is equivalent to `chalk.green`.
Multiple arguments will be separated by space.
### chalk.level
Specifies the level of color support.
Color support is automatically detected, but you can override it by setting the `level` property. You should however only do this in your own code as it applies globally to all Chalk consumers.
If you need to change this in a reusable module, create a new instance:
```js
import {Chalk} from 'chalk';
const customChalk = new Chalk({level: 0});
```
| Level | Description |
| :---: | :--- |
| `0` | All colors disabled |
| `1` | Basic color support (16 colors) |
| `2` | 256 color support |
| `3` | Truecolor support (16 million colors) |
### supportsColor
Detect whether the terminal [supports color](https://github.com/chalk/supports-color). Used internally and handled for you, but exposed for convenience.
Can be overridden by the user with the flags `--color` and `--no-color`. For situations where using `--color` is not possible, use the environment variable `FORCE_COLOR=1` (level 1), `FORCE_COLOR=2` (level 2), or `FORCE_COLOR=3` (level 3) to forcefully enable color, or `FORCE_COLOR=0` to forcefully disable. The use of `FORCE_COLOR` overrides all other color support checks.
Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color=16m` flags, respectively.
### chalkStderr and supportsColorStderr
`chalkStderr` contains a separate instance configured with color support detected for `stderr` stream instead of `stdout`. Override rules from `supportsColor` apply to this too. `supportsColorStderr` is exposed for convenience.
### modifierNames, foregroundColorNames, backgroundColorNames, and colorNames
All supported style strings are exposed as an array of strings for convenience. `colorNames` is the combination of `foregroundColorNames` and `backgroundColorNames`.
This can be useful if you wrap Chalk and need to validate input:
```js
import {modifierNames, foregroundColorNames} from 'chalk';
console.log(modifierNames.includes('bold'));
//=> true
console.log(foregroundColorNames.includes('pink'));
//=> false
```
## Styles
### Modifiers
- `reset` - Reset the current style.
- `bold` - Make the text bold.
- `dim` - Make the text have lower opacity.
- `italic` - Make the text italic. *(Not widely supported)*
- `underline` - Put a horizontal line below the text. *(Not widely supported)*
- `overline` - Put a horizontal line above the text. *(Not widely supported)*
- `inverse`- Invert background and foreground colors.
- `hidden` - Print the text but make it invisible.
- `strikethrough` - Puts a horizontal line through the center of the text. *(Not widely supported)*
- `visible`- Print the text only when Chalk has a color level above zero. Can be useful for things that are purely cosmetic.
### Colors
- `black`
- `red`
- `green`
- `yellow`
- `blue`
- `magenta`
- `cyan`
- `white`
- `blackBright` (alias: `gray`, `grey`)
- `redBright`
- `greenBright`
- `yellowBright`
- `blueBright`
- `magentaBright`
- `cyanBright`
- `whiteBright`
### Background colors
- `bgBlack`
- `bgRed`
- `bgGreen`
- `bgYellow`
- `bgBlue`
- `bgMagenta`
- `bgCyan`
- `bgWhite`
- `bgBlackBright` (alias: `bgGray`, `bgGrey`)
- `bgRedBright`
- `bgGreenBright`
- `bgYellowBright`
- `bgBlueBright`
- `bgMagentaBright`
- `bgCyanBright`
- `bgWhiteBright`
## 256 and Truecolor color support
Chalk supports 256 colors and [Truecolor](https://github.com/termstandard/colors) (16 million colors) on supported terminal apps.
Colors are downsampled from 16 million RGB values to an ANSI color format that is supported by the terminal emulator (or by specifying `{level: n}` as a Chalk option). For example, Chalk configured to run at level 1 (basic color support) will downsample an RGB value of #FF0000 (red) to 31 (ANSI escape for red).
Examples:
- `chalk.hex('#DEADED').underline('Hello, world!')`
- `chalk.rgb(15, 100, 204).inverse('Hello!')`
Background versions of these models are prefixed with `bg` and the first level of the module capitalized (e.g. `hex` for foreground colors and `bgHex` for background colors).
- `chalk.bgHex('#DEADED').underline('Hello, world!')`
- `chalk.bgRgb(15, 100, 204).inverse('Hello!')`
The following color models can be used:
- [`rgb`](https://en.wikipedia.org/wiki/RGB_color_model) - Example: `chalk.rgb(255, 136, 0).bold('Orange!')`
- [`hex`](https://en.wikipedia.org/wiki/Web_colors#Hex_triplet) - Example: `chalk.hex('#FF8800').bold('Orange!')`
- [`ansi256`](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) - Example: `chalk.bgAnsi256(194)('Honeydew, more or less')`
## Browser support
Since Chrome 69, ANSI escape codes are natively supported in the developer console.
## Windows
If you're on Windows, do yourself a favor and use [Windows Terminal](https://github.com/microsoft/terminal) instead of `cmd.exe`.
## FAQ
### Why not switch to a smaller coloring package?
Chalk may be larger, but there is a reason for that. It offers a more user-friendly API, well-documented types, supports millions of colors, and covers edge cases that smaller alternatives miss. Chalk is mature, reliable, and built to last.
But beyond the technical aspects, there's something more critical: trust and long-term maintenance. I have been active in open source for over a decade, and I'm committed to keeping Chalk maintained. Smaller packages might seem appealing now, but there's no guarantee they will be around for the long term, or that they won't become malicious over time.
Chalk is also likely already in your dependency tree (since 100K+ packages depend on it), so switching wont save space—in fact, it might increase it. npm deduplicates dependencies, so multiple Chalk instances turn into one, but adding another package alongside it will increase your overall size.
If the goal is to clean up the ecosystem, switching away from Chalk wont even make a dent. The real problem lies with packages that have very deep dependency trees (for example, those including a lot of polyfills). Chalk has no dependencies. It's better to focus on impactful changes rather than minor optimizations.
If absolute package size is important to you, I also maintain [yoctocolors](https://github.com/sindresorhus/yoctocolors), one of the smallest color packages out there.
*\- [Sindre](https://github.com/sindresorhus)*
### But the smaller coloring package has benchmarks showing it is faster
[Micro-benchmarks are flawed](https://sindresorhus.com/blog/micro-benchmark-fallacy) because they measure performance in unrealistic, isolated scenarios, often giving a distorted view of real-world performance. Don't believe marketing fluff. All the coloring packages are more than fast enough.
## Related
- [chalk-template](https://github.com/chalk/chalk-template) - [Tagged template literals](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates) support for this module
- [chalk-cli](https://github.com/chalk/chalk-cli) - CLI for this module
- [ansi-styles](https://github.com/chalk/ansi-styles) - ANSI escape codes for styling strings in the terminal
- [supports-color](https://github.com/chalk/supports-color) - Detect whether a terminal supports color
- [strip-ansi](https://github.com/chalk/strip-ansi) - Strip ANSI escape codes
- [strip-ansi-stream](https://github.com/chalk/strip-ansi-stream) - Strip ANSI escape codes from a stream
- [has-ansi](https://github.com/chalk/has-ansi) - Check if a string has ANSI escape codes
- [ansi-regex](https://github.com/chalk/ansi-regex) - Regular expression for matching ANSI escape codes
- [wrap-ansi](https://github.com/chalk/wrap-ansi) - Wordwrap a string with ANSI escape codes
- [slice-ansi](https://github.com/chalk/slice-ansi) - Slice a string with ANSI escape codes
- [color-convert](https://github.com/qix-/color-convert) - Converts colors between different models
- [chalk-animation](https://github.com/bokub/chalk-animation) - Animate strings in the terminal
- [gradient-string](https://github.com/bokub/gradient-string) - Apply color gradients to strings
- [chalk-pipe](https://github.com/LitoMore/chalk-pipe) - Create chalk style schemes with simpler style strings
- [terminal-link](https://github.com/sindresorhus/terminal-link) - Create clickable links in the terminal
*(Not accepting additional entries)*
## Maintainers
- [Sindre Sorhus](https://github.com/sindresorhus)
- [Josh Junon](https://github.com/qix-)

View File

@@ -0,0 +1,325 @@
// TODO: Make it this when TS suports that.
// import {ModifierName, ForegroundColor, BackgroundColor, ColorName} from '#ansi-styles';
// import {ColorInfo, ColorSupportLevel} from '#supports-color';
import {
ModifierName,
ForegroundColorName,
BackgroundColorName,
ColorName,
} from './vendor/ansi-styles/index.js';
import {ColorInfo, ColorSupportLevel} from './vendor/supports-color/index.js';
export interface Options {
/**
Specify the color support for Chalk.
By default, color support is automatically detected based on the environment.
Levels:
- `0` - All colors disabled.
- `1` - Basic 16 colors support.
- `2` - ANSI 256 colors support.
- `3` - Truecolor 16 million colors support.
*/
readonly level?: ColorSupportLevel;
}
/**
Return a new Chalk instance.
*/
export const Chalk: new (options?: Options) => ChalkInstance; // eslint-disable-line @typescript-eslint/naming-convention
export interface ChalkInstance {
(...text: unknown[]): string;
/**
The color support for Chalk.
By default, color support is automatically detected based on the environment.
Levels:
- `0` - All colors disabled.
- `1` - Basic 16 colors support.
- `2` - ANSI 256 colors support.
- `3` - Truecolor 16 million colors support.
*/
level: ColorSupportLevel;
/**
Use RGB values to set text color.
@example
```
import chalk from 'chalk';
chalk.rgb(222, 173, 237);
```
*/
rgb: (red: number, green: number, blue: number) => this;
/**
Use HEX value to set text color.
@param color - Hexadecimal value representing the desired color.
@example
```
import chalk from 'chalk';
chalk.hex('#DEADED');
```
*/
hex: (color: string) => this;
/**
Use an [8-bit unsigned number](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) to set text color.
@example
```
import chalk from 'chalk';
chalk.ansi256(201);
```
*/
ansi256: (index: number) => this;
/**
Use RGB values to set background color.
@example
```
import chalk from 'chalk';
chalk.bgRgb(222, 173, 237);
```
*/
bgRgb: (red: number, green: number, blue: number) => this;
/**
Use HEX value to set background color.
@param color - Hexadecimal value representing the desired color.
@example
```
import chalk from 'chalk';
chalk.bgHex('#DEADED');
```
*/
bgHex: (color: string) => this;
/**
Use a [8-bit unsigned number](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) to set background color.
@example
```
import chalk from 'chalk';
chalk.bgAnsi256(201);
```
*/
bgAnsi256: (index: number) => this;
/**
Modifier: Reset the current style.
*/
readonly reset: this;
/**
Modifier: Make the text bold.
*/
readonly bold: this;
/**
Modifier: Make the text have lower opacity.
*/
readonly dim: this;
/**
Modifier: Make the text italic. *(Not widely supported)*
*/
readonly italic: this;
/**
Modifier: Put a horizontal line below the text. *(Not widely supported)*
*/
readonly underline: this;
/**
Modifier: Put a horizontal line above the text. *(Not widely supported)*
*/
readonly overline: this;
/**
Modifier: Invert background and foreground colors.
*/
readonly inverse: this;
/**
Modifier: Print the text but make it invisible.
*/
readonly hidden: this;
/**
Modifier: Puts a horizontal line through the center of the text. *(Not widely supported)*
*/
readonly strikethrough: this;
/**
Modifier: Print the text only when Chalk has a color level above zero.
Can be useful for things that are purely cosmetic.
*/
readonly visible: this;
readonly black: this;
readonly red: this;
readonly green: this;
readonly yellow: this;
readonly blue: this;
readonly magenta: this;
readonly cyan: this;
readonly white: this;
/*
Alias for `blackBright`.
*/
readonly gray: this;
/*
Alias for `blackBright`.
*/
readonly grey: this;
readonly blackBright: this;
readonly redBright: this;
readonly greenBright: this;
readonly yellowBright: this;
readonly blueBright: this;
readonly magentaBright: this;
readonly cyanBright: this;
readonly whiteBright: this;
readonly bgBlack: this;
readonly bgRed: this;
readonly bgGreen: this;
readonly bgYellow: this;
readonly bgBlue: this;
readonly bgMagenta: this;
readonly bgCyan: this;
readonly bgWhite: this;
/*
Alias for `bgBlackBright`.
*/
readonly bgGray: this;
/*
Alias for `bgBlackBright`.
*/
readonly bgGrey: this;
readonly bgBlackBright: this;
readonly bgRedBright: this;
readonly bgGreenBright: this;
readonly bgYellowBright: this;
readonly bgBlueBright: this;
readonly bgMagentaBright: this;
readonly bgCyanBright: this;
readonly bgWhiteBright: this;
}
/**
Main Chalk object that allows to chain styles together.
Call the last one as a method with a string argument.
Order doesn't matter, and later styles take precedent in case of a conflict.
This simply means that `chalk.red.yellow.green` is equivalent to `chalk.green`.
*/
declare const chalk: ChalkInstance;
export const supportsColor: ColorInfo;
export const chalkStderr: typeof chalk;
export const supportsColorStderr: typeof supportsColor;
export {
ModifierName, ForegroundColorName, BackgroundColorName, ColorName,
modifierNames, foregroundColorNames, backgroundColorNames, colorNames,
// } from '#ansi-styles';
} from './vendor/ansi-styles/index.js';
export {
ColorInfo,
ColorSupport,
ColorSupportLevel,
// } from '#supports-color';
} from './vendor/supports-color/index.js';
// TODO: Remove these aliases in the next major version
/**
@deprecated Use `ModifierName` instead.
Basic modifier names.
*/
export type Modifiers = ModifierName;
/**
@deprecated Use `ForegroundColorName` instead.
Basic foreground color names.
[More colors here.](https://github.com/chalk/chalk/blob/main/readme.md#256-and-truecolor-color-support)
*/
export type ForegroundColor = ForegroundColorName;
/**
@deprecated Use `BackgroundColorName` instead.
Basic background color names.
[More colors here.](https://github.com/chalk/chalk/blob/main/readme.md#256-and-truecolor-color-support)
*/
export type BackgroundColor = BackgroundColorName;
/**
@deprecated Use `ColorName` instead.
Basic color names. The combination of foreground and background color names.
[More colors here.](https://github.com/chalk/chalk/blob/main/readme.md#256-and-truecolor-color-support)
*/
export type Color = ColorName;
/**
@deprecated Use `modifierNames` instead.
Basic modifier names.
*/
export const modifiers: readonly Modifiers[];
/**
@deprecated Use `foregroundColorNames` instead.
Basic foreground color names.
*/
export const foregroundColors: readonly ForegroundColor[];
/**
@deprecated Use `backgroundColorNames` instead.
Basic background color names.
*/
export const backgroundColors: readonly BackgroundColor[];
/**
@deprecated Use `colorNames` instead.
Basic color names. The combination of foreground and background color names.
*/
export const colors: readonly Color[];
export default chalk;

View File

@@ -0,0 +1,225 @@
import ansiStyles from '#ansi-styles';
import supportsColor from '#supports-color';
import { // eslint-disable-line import/order
stringReplaceAll,
stringEncaseCRLFWithFirstIndex,
} from './utilities.js';
const {stdout: stdoutColor, stderr: stderrColor} = supportsColor;
const GENERATOR = Symbol('GENERATOR');
const STYLER = Symbol('STYLER');
const IS_EMPTY = Symbol('IS_EMPTY');
// `supportsColor.level` → `ansiStyles.color[name]` mapping
const levelMapping = [
'ansi',
'ansi',
'ansi256',
'ansi16m',
];
const styles = Object.create(null);
const applyOptions = (object, options = {}) => {
if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {
throw new Error('The `level` option should be an integer from 0 to 3');
}
// Detect level if not set manually
const colorLevel = stdoutColor ? stdoutColor.level : 0;
object.level = options.level === undefined ? colorLevel : options.level;
};
export class Chalk {
constructor(options) {
// eslint-disable-next-line no-constructor-return
return chalkFactory(options);
}
}
const chalkFactory = options => {
const chalk = (...strings) => strings.join(' ');
applyOptions(chalk, options);
Object.setPrototypeOf(chalk, createChalk.prototype);
return chalk;
};
function createChalk(options) {
return chalkFactory(options);
}
Object.setPrototypeOf(createChalk.prototype, Function.prototype);
for (const [styleName, style] of Object.entries(ansiStyles)) {
styles[styleName] = {
get() {
const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]);
Object.defineProperty(this, styleName, {value: builder});
return builder;
},
};
}
styles.visible = {
get() {
const builder = createBuilder(this, this[STYLER], true);
Object.defineProperty(this, 'visible', {value: builder});
return builder;
},
};
const getModelAnsi = (model, level, type, ...arguments_) => {
if (model === 'rgb') {
if (level === 'ansi16m') {
return ansiStyles[type].ansi16m(...arguments_);
}
if (level === 'ansi256') {
return ansiStyles[type].ansi256(ansiStyles.rgbToAnsi256(...arguments_));
}
return ansiStyles[type].ansi(ansiStyles.rgbToAnsi(...arguments_));
}
if (model === 'hex') {
return getModelAnsi('rgb', level, type, ...ansiStyles.hexToRgb(...arguments_));
}
return ansiStyles[type][model](...arguments_);
};
const usedModels = ['rgb', 'hex', 'ansi256'];
for (const model of usedModels) {
styles[model] = {
get() {
const {level} = this;
return function (...arguments_) {
const styler = createStyler(getModelAnsi(model, levelMapping[level], 'color', ...arguments_), ansiStyles.color.close, this[STYLER]);
return createBuilder(this, styler, this[IS_EMPTY]);
};
},
};
const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1);
styles[bgModel] = {
get() {
const {level} = this;
return function (...arguments_) {
const styler = createStyler(getModelAnsi(model, levelMapping[level], 'bgColor', ...arguments_), ansiStyles.bgColor.close, this[STYLER]);
return createBuilder(this, styler, this[IS_EMPTY]);
};
},
};
}
const proto = Object.defineProperties(() => {}, {
...styles,
level: {
enumerable: true,
get() {
return this[GENERATOR].level;
},
set(level) {
this[GENERATOR].level = level;
},
},
});
const createStyler = (open, close, parent) => {
let openAll;
let closeAll;
if (parent === undefined) {
openAll = open;
closeAll = close;
} else {
openAll = parent.openAll + open;
closeAll = close + parent.closeAll;
}
return {
open,
close,
openAll,
closeAll,
parent,
};
};
const createBuilder = (self, _styler, _isEmpty) => {
// Single argument is hot path, implicit coercion is faster than anything
// eslint-disable-next-line no-implicit-coercion
const builder = (...arguments_) => applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' '));
// We alter the prototype because we must return a function, but there is
// no way to create a function with a different prototype
Object.setPrototypeOf(builder, proto);
builder[GENERATOR] = self;
builder[STYLER] = _styler;
builder[IS_EMPTY] = _isEmpty;
return builder;
};
const applyStyle = (self, string) => {
if (self.level <= 0 || !string) {
return self[IS_EMPTY] ? '' : string;
}
let styler = self[STYLER];
if (styler === undefined) {
return string;
}
const {openAll, closeAll} = styler;
if (string.includes('\u001B')) {
while (styler !== undefined) {
// Replace any instances already present with a re-opening code
// otherwise only the part of the string until said closing code
// will be colored, and the rest will simply be 'plain'.
string = stringReplaceAll(string, styler.close, styler.open);
styler = styler.parent;
}
}
// We can move both next actions out of loop, because remaining actions in loop won't have
// any/visible effect on parts we add here. Close the styling before a linebreak and reopen
// after next line to fix a bleed issue on macOS: https://github.com/chalk/chalk/pull/92
const lfIndex = string.indexOf('\n');
if (lfIndex !== -1) {
string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
}
return openAll + string + closeAll;
};
Object.defineProperties(createChalk.prototype, styles);
const chalk = createChalk();
export const chalkStderr = createChalk({level: stderrColor ? stderrColor.level : 0});
export {
modifierNames,
foregroundColorNames,
backgroundColorNames,
colorNames,
// TODO: Remove these aliases in the next major version
modifierNames as modifiers,
foregroundColorNames as foregroundColors,
backgroundColorNames as backgroundColors,
colorNames as colors,
} from './vendor/ansi-styles/index.js';
export {
stdoutColor as supportsColor,
stderrColor as supportsColorStderr,
};
export default chalk;

View File

@@ -0,0 +1,33 @@
// TODO: When targeting Node.js 16, use `String.prototype.replaceAll`.
export function stringReplaceAll(string, substring, replacer) {
let index = string.indexOf(substring);
if (index === -1) {
return string;
}
const substringLength = substring.length;
let endIndex = 0;
let returnValue = '';
do {
returnValue += string.slice(endIndex, index) + substring + replacer;
endIndex = index + substringLength;
index = string.indexOf(substring, endIndex);
} while (index !== -1);
returnValue += string.slice(endIndex);
return returnValue;
}
export function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {
let endIndex = 0;
let returnValue = '';
do {
const gotCR = string[index - 1] === '\r';
returnValue += string.slice(endIndex, (gotCR ? index - 1 : index)) + prefix + (gotCR ? '\r\n' : '\n') + postfix;
endIndex = index + 1;
index = string.indexOf('\n', endIndex);
} while (index !== -1);
returnValue += string.slice(endIndex);
return returnValue;
}

View File

@@ -0,0 +1,236 @@
export interface CSPair { // eslint-disable-line @typescript-eslint/naming-convention
/**
The ANSI terminal control sequence for starting this style.
*/
readonly open: string;
/**
The ANSI terminal control sequence for ending this style.
*/
readonly close: string;
}
export interface ColorBase {
/**
The ANSI terminal control sequence for ending this color.
*/
readonly close: string;
ansi(code: number): string;
ansi256(code: number): string;
ansi16m(red: number, green: number, blue: number): string;
}
export interface Modifier {
/**
Resets the current color chain.
*/
readonly reset: CSPair;
/**
Make text bold.
*/
readonly bold: CSPair;
/**
Emitting only a small amount of light.
*/
readonly dim: CSPair;
/**
Make text italic. (Not widely supported)
*/
readonly italic: CSPair;
/**
Make text underline. (Not widely supported)
*/
readonly underline: CSPair;
/**
Make text overline.
Supported on VTE-based terminals, the GNOME terminal, mintty, and Git Bash.
*/
readonly overline: CSPair;
/**
Inverse background and foreground colors.
*/
readonly inverse: CSPair;
/**
Prints the text, but makes it invisible.
*/
readonly hidden: CSPair;
/**
Puts a horizontal line through the center of the text. (Not widely supported)
*/
readonly strikethrough: CSPair;
}
export interface ForegroundColor {
readonly black: CSPair;
readonly red: CSPair;
readonly green: CSPair;
readonly yellow: CSPair;
readonly blue: CSPair;
readonly cyan: CSPair;
readonly magenta: CSPair;
readonly white: CSPair;
/**
Alias for `blackBright`.
*/
readonly gray: CSPair;
/**
Alias for `blackBright`.
*/
readonly grey: CSPair;
readonly blackBright: CSPair;
readonly redBright: CSPair;
readonly greenBright: CSPair;
readonly yellowBright: CSPair;
readonly blueBright: CSPair;
readonly cyanBright: CSPair;
readonly magentaBright: CSPair;
readonly whiteBright: CSPair;
}
export interface BackgroundColor {
readonly bgBlack: CSPair;
readonly bgRed: CSPair;
readonly bgGreen: CSPair;
readonly bgYellow: CSPair;
readonly bgBlue: CSPair;
readonly bgCyan: CSPair;
readonly bgMagenta: CSPair;
readonly bgWhite: CSPair;
/**
Alias for `bgBlackBright`.
*/
readonly bgGray: CSPair;
/**
Alias for `bgBlackBright`.
*/
readonly bgGrey: CSPair;
readonly bgBlackBright: CSPair;
readonly bgRedBright: CSPair;
readonly bgGreenBright: CSPair;
readonly bgYellowBright: CSPair;
readonly bgBlueBright: CSPair;
readonly bgCyanBright: CSPair;
readonly bgMagentaBright: CSPair;
readonly bgWhiteBright: CSPair;
}
export interface ConvertColor {
/**
Convert from the RGB color space to the ANSI 256 color space.
@param red - (`0...255`)
@param green - (`0...255`)
@param blue - (`0...255`)
*/
rgbToAnsi256(red: number, green: number, blue: number): number;
/**
Convert from the RGB HEX color space to the RGB color space.
@param hex - A hexadecimal string containing RGB data.
*/
hexToRgb(hex: string): [red: number, green: number, blue: number];
/**
Convert from the RGB HEX color space to the ANSI 256 color space.
@param hex - A hexadecimal string containing RGB data.
*/
hexToAnsi256(hex: string): number;
/**
Convert from the ANSI 256 color space to the ANSI 16 color space.
@param code - A number representing the ANSI 256 color.
*/
ansi256ToAnsi(code: number): number;
/**
Convert from the RGB color space to the ANSI 16 color space.
@param red - (`0...255`)
@param green - (`0...255`)
@param blue - (`0...255`)
*/
rgbToAnsi(red: number, green: number, blue: number): number;
/**
Convert from the RGB HEX color space to the ANSI 16 color space.
@param hex - A hexadecimal string containing RGB data.
*/
hexToAnsi(hex: string): number;
}
/**
Basic modifier names.
*/
export type ModifierName = keyof Modifier;
/**
Basic foreground color names.
[More colors here.](https://github.com/chalk/chalk/blob/main/readme.md#256-and-truecolor-color-support)
*/
export type ForegroundColorName = keyof ForegroundColor;
/**
Basic background color names.
[More colors here.](https://github.com/chalk/chalk/blob/main/readme.md#256-and-truecolor-color-support)
*/
export type BackgroundColorName = keyof BackgroundColor;
/**
Basic color names. The combination of foreground and background color names.
[More colors here.](https://github.com/chalk/chalk/blob/main/readme.md#256-and-truecolor-color-support)
*/
export type ColorName = ForegroundColorName | BackgroundColorName;
/**
Basic modifier names.
*/
export const modifierNames: readonly ModifierName[];
/**
Basic foreground color names.
*/
export const foregroundColorNames: readonly ForegroundColorName[];
/**
Basic background color names.
*/
export const backgroundColorNames: readonly BackgroundColorName[];
/*
Basic color names. The combination of foreground and background color names.
*/
export const colorNames: readonly ColorName[];
declare const ansiStyles: {
readonly modifier: Modifier;
readonly color: ColorBase & ForegroundColor;
readonly bgColor: ColorBase & BackgroundColor;
readonly codes: ReadonlyMap<number, number>;
} & ForegroundColor & BackgroundColor & Modifier & ConvertColor;
export default ansiStyles;

View File

@@ -0,0 +1,223 @@
const ANSI_BACKGROUND_OFFSET = 10;
const wrapAnsi16 = (offset = 0) => code => `\u001B[${code + offset}m`;
const wrapAnsi256 = (offset = 0) => code => `\u001B[${38 + offset};5;${code}m`;
const wrapAnsi16m = (offset = 0) => (red, green, blue) => `\u001B[${38 + offset};2;${red};${green};${blue}m`;
const styles = {
modifier: {
reset: [0, 0],
// 21 isn't widely supported and 22 does the same thing
bold: [1, 22],
dim: [2, 22],
italic: [3, 23],
underline: [4, 24],
overline: [53, 55],
inverse: [7, 27],
hidden: [8, 28],
strikethrough: [9, 29],
},
color: {
black: [30, 39],
red: [31, 39],
green: [32, 39],
yellow: [33, 39],
blue: [34, 39],
magenta: [35, 39],
cyan: [36, 39],
white: [37, 39],
// Bright color
blackBright: [90, 39],
gray: [90, 39], // Alias of `blackBright`
grey: [90, 39], // Alias of `blackBright`
redBright: [91, 39],
greenBright: [92, 39],
yellowBright: [93, 39],
blueBright: [94, 39],
magentaBright: [95, 39],
cyanBright: [96, 39],
whiteBright: [97, 39],
},
bgColor: {
bgBlack: [40, 49],
bgRed: [41, 49],
bgGreen: [42, 49],
bgYellow: [43, 49],
bgBlue: [44, 49],
bgMagenta: [45, 49],
bgCyan: [46, 49],
bgWhite: [47, 49],
// Bright color
bgBlackBright: [100, 49],
bgGray: [100, 49], // Alias of `bgBlackBright`
bgGrey: [100, 49], // Alias of `bgBlackBright`
bgRedBright: [101, 49],
bgGreenBright: [102, 49],
bgYellowBright: [103, 49],
bgBlueBright: [104, 49],
bgMagentaBright: [105, 49],
bgCyanBright: [106, 49],
bgWhiteBright: [107, 49],
},
};
export const modifierNames = Object.keys(styles.modifier);
export const foregroundColorNames = Object.keys(styles.color);
export const backgroundColorNames = Object.keys(styles.bgColor);
export const colorNames = [...foregroundColorNames, ...backgroundColorNames];
function assembleStyles() {
const codes = new Map();
for (const [groupName, group] of Object.entries(styles)) {
for (const [styleName, style] of Object.entries(group)) {
styles[styleName] = {
open: `\u001B[${style[0]}m`,
close: `\u001B[${style[1]}m`,
};
group[styleName] = styles[styleName];
codes.set(style[0], style[1]);
}
Object.defineProperty(styles, groupName, {
value: group,
enumerable: false,
});
}
Object.defineProperty(styles, 'codes', {
value: codes,
enumerable: false,
});
styles.color.close = '\u001B[39m';
styles.bgColor.close = '\u001B[49m';
styles.color.ansi = wrapAnsi16();
styles.color.ansi256 = wrapAnsi256();
styles.color.ansi16m = wrapAnsi16m();
styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
// From https://github.com/Qix-/color-convert/blob/3f0e0d4e92e235796ccb17f6e85c72094a651f49/conversions.js
Object.defineProperties(styles, {
rgbToAnsi256: {
value(red, green, blue) {
// We use the extended greyscale palette here, with the exception of
// black and white. normal palette only has 4 greyscale shades.
if (red === green && green === blue) {
if (red < 8) {
return 16;
}
if (red > 248) {
return 231;
}
return Math.round(((red - 8) / 247) * 24) + 232;
}
return 16
+ (36 * Math.round(red / 255 * 5))
+ (6 * Math.round(green / 255 * 5))
+ Math.round(blue / 255 * 5);
},
enumerable: false,
},
hexToRgb: {
value(hex) {
const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
if (!matches) {
return [0, 0, 0];
}
let [colorString] = matches;
if (colorString.length === 3) {
colorString = [...colorString].map(character => character + character).join('');
}
const integer = Number.parseInt(colorString, 16);
return [
/* eslint-disable no-bitwise */
(integer >> 16) & 0xFF,
(integer >> 8) & 0xFF,
integer & 0xFF,
/* eslint-enable no-bitwise */
];
},
enumerable: false,
},
hexToAnsi256: {
value: hex => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
enumerable: false,
},
ansi256ToAnsi: {
value(code) {
if (code < 8) {
return 30 + code;
}
if (code < 16) {
return 90 + (code - 8);
}
let red;
let green;
let blue;
if (code >= 232) {
red = (((code - 232) * 10) + 8) / 255;
green = red;
blue = red;
} else {
code -= 16;
const remainder = code % 36;
red = Math.floor(code / 36) / 5;
green = Math.floor(remainder / 6) / 5;
blue = (remainder % 6) / 5;
}
const value = Math.max(red, green, blue) * 2;
if (value === 0) {
return 30;
}
// eslint-disable-next-line no-bitwise
let result = 30 + ((Math.round(blue) << 2) | (Math.round(green) << 1) | Math.round(red));
if (value === 2) {
result += 60;
}
return result;
},
enumerable: false,
},
rgbToAnsi: {
value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
enumerable: false,
},
hexToAnsi: {
value: hex => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
enumerable: false,
},
});
return styles;
}
const ansiStyles = assembleStyles();
export default ansiStyles;

View File

@@ -0,0 +1 @@
export {default} from './index.js';

View File

@@ -0,0 +1,34 @@
/* eslint-env browser */
const level = (() => {
if (!('navigator' in globalThis)) {
return 0;
}
if (globalThis.navigator.userAgentData) {
const brand = navigator.userAgentData.brands.find(({brand}) => brand === 'Chromium');
if (brand && brand.version > 93) {
return 3;
}
}
if (/\b(Chrome|Chromium)\//.test(globalThis.navigator.userAgent)) {
return 1;
}
return 0;
})();
const colorSupport = level !== 0 && {
level,
hasBasic: true,
has256: level >= 2,
has16m: level >= 3,
};
const supportsColor = {
stdout: colorSupport,
stderr: colorSupport,
};
export default supportsColor;

View File

@@ -0,0 +1,55 @@
import type {WriteStream} from 'node:tty';
export type Options = {
/**
Whether `process.argv` should be sniffed for `--color` and `--no-color` flags.
@default true
*/
readonly sniffFlags?: boolean;
};
/**
Levels:
- `0` - All colors disabled.
- `1` - Basic 16 colors support.
- `2` - ANSI 256 colors support.
- `3` - Truecolor 16 million colors support.
*/
export type ColorSupportLevel = 0 | 1 | 2 | 3;
/**
Detect whether the terminal supports color.
*/
export type ColorSupport = {
/**
The color level.
*/
level: ColorSupportLevel;
/**
Whether basic 16 colors are supported.
*/
hasBasic: boolean;
/**
Whether ANSI 256 colors are supported.
*/
has256: boolean;
/**
Whether Truecolor 16 million colors are supported.
*/
has16m: boolean;
};
export type ColorInfo = ColorSupport | false;
export function createSupportsColor(stream?: WriteStream, options?: Options): ColorInfo;
declare const supportsColor: {
stdout: ColorInfo;
stderr: ColorInfo;
};
export default supportsColor;

View File

@@ -0,0 +1,182 @@
import process from 'node:process';
import os from 'node:os';
import tty from 'node:tty';
// From: https://github.com/sindresorhus/has-flag/blob/main/index.js
/// function hasFlag(flag, argv = globalThis.Deno?.args ?? process.argv) {
function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process.argv) {
const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--');
const position = argv.indexOf(prefix + flag);
const terminatorPosition = argv.indexOf('--');
return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
}
const {env} = process;
let flagForceColor;
if (
hasFlag('no-color')
|| hasFlag('no-colors')
|| hasFlag('color=false')
|| hasFlag('color=never')
) {
flagForceColor = 0;
} else if (
hasFlag('color')
|| hasFlag('colors')
|| hasFlag('color=true')
|| hasFlag('color=always')
) {
flagForceColor = 1;
}
function envForceColor() {
if ('FORCE_COLOR' in env) {
if (env.FORCE_COLOR === 'true') {
return 1;
}
if (env.FORCE_COLOR === 'false') {
return 0;
}
return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
}
}
function translateLevel(level) {
if (level === 0) {
return false;
}
return {
level,
hasBasic: true,
has256: level >= 2,
has16m: level >= 3,
};
}
function _supportsColor(haveStream, {streamIsTTY, sniffFlags = true} = {}) {
const noFlagForceColor = envForceColor();
if (noFlagForceColor !== undefined) {
flagForceColor = noFlagForceColor;
}
const forceColor = sniffFlags ? flagForceColor : noFlagForceColor;
if (forceColor === 0) {
return 0;
}
if (sniffFlags) {
if (hasFlag('color=16m')
|| hasFlag('color=full')
|| hasFlag('color=truecolor')) {
return 3;
}
if (hasFlag('color=256')) {
return 2;
}
}
// Check for Azure DevOps pipelines.
// Has to be above the `!streamIsTTY` check.
if ('TF_BUILD' in env && 'AGENT_NAME' in env) {
return 1;
}
if (haveStream && !streamIsTTY && forceColor === undefined) {
return 0;
}
const min = forceColor || 0;
if (env.TERM === 'dumb') {
return min;
}
if (process.platform === 'win32') {
// Windows 10 build 10586 is the first Windows release that supports 256 colors.
// Windows 10 build 14931 is the first release that supports 16m/TrueColor.
const osRelease = os.release().split('.');
if (
Number(osRelease[0]) >= 10
&& Number(osRelease[2]) >= 10_586
) {
return Number(osRelease[2]) >= 14_931 ? 3 : 2;
}
return 1;
}
if ('CI' in env) {
if (['GITHUB_ACTIONS', 'GITEA_ACTIONS', 'CIRCLECI'].some(key => key in env)) {
return 3;
}
if (['TRAVIS', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') {
return 1;
}
return min;
}
if ('TEAMCITY_VERSION' in env) {
return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
}
if (env.COLORTERM === 'truecolor') {
return 3;
}
if (env.TERM === 'xterm-kitty') {
return 3;
}
if ('TERM_PROGRAM' in env) {
const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10);
switch (env.TERM_PROGRAM) {
case 'iTerm.app': {
return version >= 3 ? 3 : 2;
}
case 'Apple_Terminal': {
return 2;
}
// No default
}
}
if (/-256(color)?$/i.test(env.TERM)) {
return 2;
}
if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
return 1;
}
if ('COLORTERM' in env) {
return 1;
}
return min;
}
export function createSupportsColor(stream, options = {}) {
const level = _supportsColor(stream, {
streamIsTTY: stream && stream.isTTY,
...options,
});
return translateLevel(level);
}
const supportsColor = {
stdout: createSupportsColor({isTTY: tty.isatty(1)}),
stderr: createSupportsColor({isTTY: tty.isatty(2)}),
};
export default supportsColor;

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com)
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.

View File

@@ -0,0 +1,44 @@
# Change Case
[![NPM version][npm-image]][npm-url]
[![NPM downloads][downloads-image]][downloads-url]
[![Bundle size][bundlephobia-image]][bundlephobia-url]
> Transform a string between `camelCase`, `PascalCase`, `Capital Case`, `snake_case`, `param-case`, `CONSTANT_CASE` and others.
## Installation
```
npm install change-case --save
```
## Usage
```js
import {
camelCase,
capitalCase,
constantCase,
dotCase,
headerCase,
noCase,
paramCase,
pascalCase,
pathCase,
sentenceCase,
snakeCase,
} from "change-case";
```
Methods can also be installed [independently](https://github.com/blakeembrey/change-case). All functions also accept [`options`](https://github.com/blakeembrey/change-case#options) as the second argument.
## License
MIT
[npm-image]: https://img.shields.io/npm/v/change-case.svg?style=flat
[npm-url]: https://npmjs.org/package/change-case
[downloads-image]: https://img.shields.io/npm/dm/change-case.svg?style=flat
[downloads-url]: https://npmjs.org/package/change-case
[bundlephobia-image]: https://img.shields.io/bundlephobia/minzip/change-case.svg
[bundlephobia-url]: https://bundlephobia.com/result?p=change-case

View File

@@ -0,0 +1,11 @@
export * from "camel-case";
export * from "capital-case";
export * from "constant-case";
export * from "dot-case";
export * from "header-case";
export * from "no-case";
export * from "param-case";
export * from "pascal-case";
export * from "path-case";
export * from "sentence-case";
export * from "snake-case";

View File

@@ -0,0 +1,12 @@
export * from "camel-case";
export * from "capital-case";
export * from "constant-case";
export * from "dot-case";
export * from "header-case";
export * from "no-case";
export * from "param-case";
export * from "pascal-case";
export * from "path-case";
export * from "sentence-case";
export * from "snake-case";
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC;AAC9B,cAAc,YAAY,CAAC","sourcesContent":["export * from \"camel-case\";\nexport * from \"capital-case\";\nexport * from \"constant-case\";\nexport * from \"dot-case\";\nexport * from \"header-case\";\nexport * from \"no-case\";\nexport * from \"param-case\";\nexport * from \"pascal-case\";\nexport * from \"path-case\";\nexport * from \"sentence-case\";\nexport * from \"snake-case\";\n"]}

View File

@@ -0,0 +1 @@
export {};

View File

@@ -0,0 +1,7 @@
import * as changeCase from ".";
describe("change case", function () {
it("exports expected methods", function () {
expect(typeof changeCase).toEqual("object");
});
});
//# sourceMappingURL=index.spec.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.spec.js","sourceRoot":"","sources":["../src/index.spec.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,UAAU,MAAM,GAAG,CAAC;AAEhC,QAAQ,CAAC,aAAa,EAAE;IACtB,EAAE,CAAC,0BAA0B,EAAE;QAC7B,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import * as changeCase from \".\";\n\ndescribe(\"change case\", () => {\n it(\"exports expected methods\", () => {\n expect(typeof changeCase).toEqual(\"object\");\n });\n});\n"]}

View File

@@ -0,0 +1,11 @@
export * from "camel-case";
export * from "capital-case";
export * from "constant-case";
export * from "dot-case";
export * from "header-case";
export * from "no-case";
export * from "param-case";
export * from "pascal-case";
export * from "path-case";
export * from "sentence-case";
export * from "snake-case";

View File

@@ -0,0 +1,15 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
tslib_1.__exportStar(require("camel-case"), exports);
tslib_1.__exportStar(require("capital-case"), exports);
tslib_1.__exportStar(require("constant-case"), exports);
tslib_1.__exportStar(require("dot-case"), exports);
tslib_1.__exportStar(require("header-case"), exports);
tslib_1.__exportStar(require("no-case"), exports);
tslib_1.__exportStar(require("param-case"), exports);
tslib_1.__exportStar(require("pascal-case"), exports);
tslib_1.__exportStar(require("path-case"), exports);
tslib_1.__exportStar(require("sentence-case"), exports);
tslib_1.__exportStar(require("snake-case"), exports);
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,qDAA2B;AAC3B,uDAA6B;AAC7B,wDAA8B;AAC9B,mDAAyB;AACzB,sDAA4B;AAC5B,kDAAwB;AACxB,qDAA2B;AAC3B,sDAA4B;AAC5B,oDAA0B;AAC1B,wDAA8B;AAC9B,qDAA2B","sourcesContent":["export * from \"camel-case\";\nexport * from \"capital-case\";\nexport * from \"constant-case\";\nexport * from \"dot-case\";\nexport * from \"header-case\";\nexport * from \"no-case\";\nexport * from \"param-case\";\nexport * from \"pascal-case\";\nexport * from \"path-case\";\nexport * from \"sentence-case\";\nexport * from \"snake-case\";\n"]}

View File

@@ -0,0 +1 @@
export {};

View File

@@ -0,0 +1,9 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var changeCase = require(".");
describe("change case", function () {
it("exports expected methods", function () {
expect(typeof changeCase).toEqual("object");
});
});
//# sourceMappingURL=index.spec.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.spec.js","sourceRoot":"","sources":["../src/index.spec.ts"],"names":[],"mappings":";;AAAA,8BAAgC;AAEhC,QAAQ,CAAC,aAAa,EAAE;IACtB,EAAE,CAAC,0BAA0B,EAAE;QAC7B,MAAM,CAAC,OAAO,UAAU,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import * as changeCase from \".\";\n\ndescribe(\"change case\", () => {\n it(\"exports expected methods\", () => {\n expect(typeof changeCase).toEqual(\"object\");\n });\n});\n"]}

View File

@@ -0,0 +1,101 @@
{
"name": "change-case",
"version": "4.1.2",
"description": "Transform a string between `camelCase`, `PascalCase`, `Capital Case`, `snake_case`, `param-case`, `CONSTANT_CASE` and others",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"module": "dist.es2015/index.js",
"sideEffects": false,
"jsnext:main": "dist.es2015/index.js",
"files": [
"dist/",
"dist.es2015/",
"LICENSE"
],
"scripts": {
"lint": "tslint \"src/**/*\" --project tsconfig.json",
"build": "rimraf dist/ dist.es2015/ && tsc && tsc -P tsconfig.es2015.json",
"specs": "jest --coverage",
"test": "npm run build && npm run lint && npm run specs",
"size": "size-limit",
"prepare": "npm run build"
},
"repository": {
"type": "git",
"url": "git://github.com/blakeembrey/change-case.git"
},
"keywords": [
"change",
"case",
"convert",
"transform",
"camel-case",
"pascal-case",
"param-case",
"kebab-case",
"header-case"
],
"author": {
"name": "Blake Embrey",
"email": "hello@blakeembrey.com",
"url": "http://blakeembrey.me"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/blakeembrey/change-case/issues"
},
"homepage": "https://github.com/blakeembrey/change-case/tree/master/packages/camel-case#readme",
"size-limit": [
{
"path": "dist/index.js",
"limit": "750 B"
}
],
"jest": {
"roots": [
"<rootDir>/src/"
],
"transform": {
"\\.tsx?$": "ts-jest"
},
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(tsx?|jsx?)$",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"json",
"node"
]
},
"publishConfig": {
"access": "public"
},
"dependencies": {
"camel-case": "^4.1.2",
"capital-case": "^1.0.4",
"constant-case": "^3.0.4",
"dot-case": "^3.0.4",
"header-case": "^2.0.4",
"no-case": "^3.0.4",
"param-case": "^3.0.4",
"pascal-case": "^3.1.2",
"path-case": "^3.0.4",
"sentence-case": "^3.0.4",
"snake-case": "^3.0.4",
"tslib": "^2.0.3"
},
"devDependencies": {
"@size-limit/preset-small-lib": "^2.2.1",
"@types/jest": "^24.0.23",
"@types/node": "^12.12.14",
"jest": "^24.9.0",
"rimraf": "^3.0.0",
"ts-jest": "^24.2.0",
"tslint": "^5.20.1",
"tslint-config-prettier": "^1.18.0",
"tslint-config-standard": "^9.0.0",
"typescript": "^4.1.2"
},
"gitHead": "76a21a7f6f2a226521ef6abd345ff309cbd01fb0"
}

View File

@@ -0,0 +1,50 @@
export interface Options {
/**
Prettify the file paths in the stack:
`/Users/sindresorhus/dev/clean-stack/unicorn.js:2:15` → `~/dev/clean-stack/unicorn.js:2:15`
@default false
*/
readonly pretty?: boolean;
/**
Remove the given base path from stack trace file paths, effectively turning absolute paths into relative ones.
Example with `'/Users/sindresorhus/dev/clean-stack/'` as `basePath`:
`/Users/sindresorhus/dev/clean-stack/unicorn.js:2:15` → `unicorn.js:2:15`
*/
readonly basePath?: string;
}
/**
Clean up error stack traces. Removes the mostly unhelpful internal Node.js entries.
@param stack - The `stack` property of an `Error`.
@returns The cleaned stack or `undefined` if the given `stack` is `undefined`.
@example
```
import cleanStack from 'clean-stack';
const error = new Error('Missing unicorn');
console.log(error.stack);
// Error: Missing unicorn
// at Object.<anonymous> (/Users/sindresorhus/dev/clean-stack/unicorn.js:2:15)
// at Module._compile (module.js:409:26)
// at Object.Module._extensions..js (module.js:416:10)
// at Module.load (module.js:343:32)
// at Function.Module._load (module.js:300:12)
// at Function.Module.runMain (module.js:441:10)
// at startup (node.js:139:18)
console.log(cleanStack(error.stack));
// Error: Missing unicorn
// at Object.<anonymous> (/Users/sindresorhus/dev/clean-stack/unicorn.js:2:15)
```
*/
export default function cleanStack<T extends string | undefined>(stack: T, options?: Options): T;

View File

@@ -0,0 +1,50 @@
import os from 'os';
import escapeStringRegexp from 'escape-string-regexp';
const extractPathRegex = /\s+at.*[(\s](.*)\)?/;
const pathRegex = /^(?:(?:(?:node|node:[\w/]+|(?:(?:node:)?internal\/[\w/]*|.*node_modules\/(?:babel-polyfill|pirates)\/.*)?\w+)(?:\.js)?:\d+:\d+)|native)/;
const homeDir = typeof os.homedir === 'undefined' ? '' : os.homedir().replace(/\\/g, '/');
export default function cleanStack(stack, {pretty = false, basePath} = {}) {
const basePathRegex = basePath && new RegExp(`(at | \\()${escapeStringRegexp(basePath.replace(/\\/g, '/'))}`, 'g');
if (typeof stack !== 'string') {
return undefined;
}
return stack.replace(/\\/g, '/')
.split('\n')
.filter(line => {
const pathMatches = line.match(extractPathRegex);
if (pathMatches === null || !pathMatches[1]) {
return true;
}
const match = pathMatches[1];
// Electron
if (
match.includes('.app/Contents/Resources/electron.asar') ||
match.includes('.app/Contents/Resources/default_app.asar') ||
match.includes('node_modules/electron/dist/resources/electron.asar') ||
match.includes('node_modules/electron/dist/resources/default_app.asar')
) {
return false;
}
return !pathRegex.test(match);
})
.filter(line => line.trim() !== '')
.map(line => {
if (basePathRegex) {
line = line.replace(basePathRegex, '$1');
}
if (pretty) {
line = line.replace(extractPathRegex, (m, p1) => m.replace(p1, p1.replace(homeDir, '~')));
}
return line;
})
.join('\n');
}

View File

@@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
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.

View File

@@ -0,0 +1,44 @@
{
"name": "clean-stack",
"version": "4.2.0",
"description": "Clean up error stack traces",
"license": "MIT",
"repository": "sindresorhus/clean-stack",
"funding": "https://github.com/sponsors/sindresorhus",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "https://sindresorhus.com"
},
"type": "module",
"exports": "./index.js",
"engines": {
"node": ">=12"
},
"scripts": {
"test": "xo && ava && tsd"
},
"files": [
"index.js",
"index.d.ts"
],
"keywords": [
"clean",
"stack",
"trace",
"traces",
"error",
"electron"
],
"dependencies": {
"escape-string-regexp": "5.0.0"
},
"devDependencies": {
"ava": "^3.15.0",
"tsd": "^0.14.0",
"xo": "^0.38.2"
},
"browser": {
"os": false
}
}

View File

@@ -0,0 +1,79 @@
# clean-stack
> Clean up error stack traces
Removes the mostly unhelpful internal Node.js entries.
Also works in Electron.
## Install
```
$ npm install clean-stack
```
## Usage
```js
import cleanStack from 'clean-stack';
const error = new Error('Missing unicorn');
console.log(error.stack);
/*
Error: Missing unicorn
at Object.<anonymous> (/Users/sindresorhus/dev/clean-stack/unicorn.js:2:15)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Function.Module.runMain (module.js:441:10)
at startup (node.js:139:18)
*/
console.log(cleanStack(error.stack));
/*
Error: Missing unicorn
at Object.<anonymous> (/Users/sindresorhus/dev/clean-stack/unicorn.js:2:15)
*/
```
## API
### cleanStack(stack, options?)
Returns the cleaned stack or `undefined` if the given `stack` is `undefined`.
#### stack
Type: `string | undefined`
The `stack` property of an [`Error`](https://github.com/microsoft/TypeScript/blob/eac073894b172ec719ca7f28b0b94fc6e6e7d4cf/lib/lib.es5.d.ts#L972-L976).
#### options
Type: `object`
##### pretty
Type: `boolean`\
Default: `false`
Prettify the file paths in the stack:
`/Users/sindresorhus/dev/clean-stack/unicorn.js:2:15``~/dev/clean-stack/unicorn.js:2:15`
##### basePath
Type: `string?`
Remove the given base path from stack trace file paths, effectively turning absolute paths into relative ones.
Example with `'/Users/sindresorhus/dev/clean-stack/'` as `basePath`:
`/Users/sindresorhus/dev/clean-stack/unicorn.js:2:15``unicorn.js:2:15`
## Related
- [extract-stack](https://github.com/sindresorhus/extract-stack) - Extract the actual stack of an error
- [stack-utils](https://github.com/tapjs/stack-utils) - Captures and cleans stack traces

View File

@@ -0,0 +1,13 @@
Copyright (c) 2015, Ilya Radchenko <knownasilya@gmail.com>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

View File

@@ -0,0 +1,71 @@
# cli-width
Get stdout window width, with four fallbacks, `tty`, `output.columns`, a custom environment variable and then a default.
[![npm version](https://badge.fury.io/js/cli-width.svg)](http://badge.fury.io/js/cli-width)
[![Build Status](https://travis-ci.org/knownasilya/cli-width.svg)](https://travis-ci.org/knownasilya/cli-width)
[![Coverage Status](https://coveralls.io/repos/knownasilya/cli-width/badge.svg?branch=master&service=github)](https://coveralls.io/github/knownasilya/cli-width?branch=master)
Tested against Node v12 to v20.
Includes TypeScript types.
## Usage
```
npm install --save cli-width
```
```js
const cliWidth = require('cli-width');
cliWidth(); // maybe 204 :)
```
You can also set the `CLI_WIDTH` environment variable.
If none of the methods are supported, and the environment variable isn't set,
the default width value is going to be `0`, that can be changed using the configurable `options`.
## API
### cliWidth([options])
`cliWidth` can be configured using an `options` parameter, the possible properties are:
- **defaultWidth**\<number\> Defines a default value to be used if none of the methods are available, defaults to `0`
- **output**\<object\> A stream to be used to read width values from, defaults to `process.stdout`
- **tty**\<object\> TTY module to try to read width from as a fallback, defaults to `require('tty')`
### Examples
Defining both a default width value and a stream output to try to read from:
```js
const cliWidth = require('cli-width');
const ttys = require('ttys');
cliWidth({
defaultWidth: 80,
output: ttys.output,
});
```
Defines a different tty module to read width from:
```js
const cliWidth = require('cli-width');
const ttys = require('ttys');
cliWidth({
tty: ttys,
});
```
## Tests
```bash
npm install
npm test
```
Coverage can be generated with `npm run coverage`.

View File

@@ -0,0 +1,13 @@
// Type definitions for cli-width 4.0
/// <reference types="node" />
import { Stream } from 'stream';
import tty = require('tty');
declare function cliWidth(options?: {
defaultWidth?: number;
output?: Stream;
tty?: typeof tty;
}): number;
export = cliWidth;

View File

@@ -0,0 +1,49 @@
'use strict';
module.exports = cliWidth;
function normalizeOpts(options) {
const defaultOpts = {
defaultWidth: 0,
output: process.stdout,
tty: require('tty'),
};
if (!options) {
return defaultOpts;
}
Object.keys(defaultOpts).forEach(function (key) {
if (!options[key]) {
options[key] = defaultOpts[key];
}
});
return options;
}
function cliWidth(options) {
const opts = normalizeOpts(options);
if (opts.output.getWindowSize) {
return opts.output.getWindowSize()[0] || opts.defaultWidth;
}
if (opts.tty.getWindowSize) {
return opts.tty.getWindowSize()[1] || opts.defaultWidth;
}
if (opts.output.columns) {
return opts.output.columns;
}
if (process.env.CLI_WIDTH) {
const width = parseInt(process.env.CLI_WIDTH, 10);
if (!isNaN(width) && width !== 0) {
return width;
}
}
return opts.defaultWidth;
}

View File

@@ -0,0 +1,40 @@
{
"name": "cli-width",
"version": "4.1.0",
"description": "Get stdout window width, with two fallbacks, tty and then a default.",
"main": "index.js",
"scripts": {
"test": "node test | tspec",
"coverage": "nyc node test | tspec",
"coveralls": "npm run coverage -s && coveralls < coverage/lcov.info",
"release": "standard-version"
},
"repository": {
"type": "git",
"url": "git@github.com:knownasilya/cli-width.git"
},
"author": "Ilya Radchenko <knownasilya@gmail.com>",
"license": "ISC",
"bugs": {
"url": "https://github.com/knownasilya/cli-width/issues"
},
"homepage": "https://github.com/knownasilya/cli-width",
"engines": {
"node": ">= 12"
},
"devDependencies": {
"coveralls": "^3.1.1",
"nyc": "^15.1.0",
"standard-version": "^9.3.2",
"tap-spec": "^5.0.0",
"tape": "^5.5.2"
},
"volta": {
"node": "12.22.11",
"npm": "8.5.5"
},
"files": [
"index.js",
"index.d.ts"
]
}

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com)
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.

View File

@@ -0,0 +1,37 @@
# Constant Case
[![NPM version][npm-image]][npm-url]
[![NPM downloads][downloads-image]][downloads-url]
[![Bundle size][bundlephobia-image]][bundlephobia-url]
> Transform into upper case string with an underscore between words.
## Installation
```
npm install constant-case --save
```
## Usage
```js
import { constantCase } from "constant-case";
constantCase("string"); //=> "STRING"
constantCase("dot.case"); //=> "DOT_CASE"
constantCase("PascalCase"); //=> "PASCAL_CASE"
constantCase("version 1.2.10"); //=> "VERSION_1_2_10"
```
The function also accepts [`options`](https://github.com/blakeembrey/change-case#options).
## License
MIT
[npm-image]: https://img.shields.io/npm/v/constant-case.svg?style=flat
[npm-url]: https://npmjs.org/package/constant-case
[downloads-image]: https://img.shields.io/npm/dm/constant-case.svg?style=flat
[downloads-url]: https://npmjs.org/package/constant-case
[bundlephobia-image]: https://img.shields.io/bundlephobia/minzip/constant-case.svg
[bundlephobia-url]: https://bundlephobia.com/result?p=constant-case

View File

@@ -0,0 +1,3 @@
import { Options } from "no-case";
export { Options };
export declare function constantCase(input: string, options?: Options): string;

View File

@@ -0,0 +1,8 @@
import { __assign } from "tslib";
import { noCase } from "no-case";
import { upperCase } from "upper-case";
export function constantCase(input, options) {
if (options === void 0) { options = {}; }
return noCase(input, __assign({ delimiter: "_", transform: upperCase }, options));
}
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAW,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAIvC,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,OAAqB;IAArB,wBAAA,EAAA,YAAqB;IAC/D,OAAO,MAAM,CAAC,KAAK,aACjB,SAAS,EAAE,GAAG,EACd,SAAS,EAAE,SAAS,IACjB,OAAO,EACV,CAAC;AACL,CAAC","sourcesContent":["import { noCase, Options } from \"no-case\";\nimport { upperCase } from \"upper-case\";\n\nexport { Options };\n\nexport function constantCase(input: string, options: Options = {}) {\n return noCase(input, {\n delimiter: \"_\",\n transform: upperCase,\n ...options,\n });\n}\n"]}

View File

@@ -0,0 +1 @@
export {};

View File

@@ -0,0 +1,24 @@
import { constantCase } from ".";
var TEST_CASES = [
["", ""],
["test", "TEST"],
["test string", "TEST_STRING"],
["Test String", "TEST_STRING"],
["dot.case", "DOT_CASE"],
["path/case", "PATH_CASE"],
["TestV2", "TEST_V2"],
["version 1.2.10", "VERSION_1_2_10"],
["version 1.21.0", "VERSION_1_21_0"],
];
describe("constant case", function () {
var _loop_1 = function (input, result) {
it(input + " -> " + result, function () {
expect(constantCase(input)).toEqual(result);
});
};
for (var _i = 0, TEST_CASES_1 = TEST_CASES; _i < TEST_CASES_1.length; _i++) {
var _a = TEST_CASES_1[_i], input = _a[0], result = _a[1];
_loop_1(input, result);
}
});
//# sourceMappingURL=index.spec.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.spec.js","sourceRoot":"","sources":["../src/index.spec.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,GAAG,CAAC;AAEjC,IAAM,UAAU,GAAuB;IACrC,CAAC,EAAE,EAAE,EAAE,CAAC;IACR,CAAC,MAAM,EAAE,MAAM,CAAC;IAChB,CAAC,aAAa,EAAE,aAAa,CAAC;IAC9B,CAAC,aAAa,EAAE,aAAa,CAAC;IAC9B,CAAC,UAAU,EAAE,UAAU,CAAC;IACxB,CAAC,WAAW,EAAE,WAAW,CAAC;IAC1B,CAAC,QAAQ,EAAE,SAAS,CAAC;IACrB,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IACpC,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;CACrC,CAAC;AAEF,QAAQ,CAAC,eAAe,EAAE;4BACZ,KAAK,EAAE,MAAM;QACvB,EAAE,CAAI,KAAK,YAAO,MAAQ,EAAE;YAC1B,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;;IAHL,KAA8B,UAAU,EAAV,yBAAU,EAAV,wBAAU,EAAV,IAAU;QAA7B,IAAA,qBAAe,EAAd,KAAK,QAAA,EAAE,MAAM,QAAA;gBAAb,KAAK,EAAE,MAAM;KAIxB;AACH,CAAC,CAAC,CAAC","sourcesContent":["import { constantCase } from \".\";\n\nconst TEST_CASES: [string, string][] = [\n [\"\", \"\"],\n [\"test\", \"TEST\"],\n [\"test string\", \"TEST_STRING\"],\n [\"Test String\", \"TEST_STRING\"],\n [\"dot.case\", \"DOT_CASE\"],\n [\"path/case\", \"PATH_CASE\"],\n [\"TestV2\", \"TEST_V2\"],\n [\"version 1.2.10\", \"VERSION_1_2_10\"],\n [\"version 1.21.0\", \"VERSION_1_21_0\"],\n];\n\ndescribe(\"constant case\", () => {\n for (const [input, result] of TEST_CASES) {\n it(`${input} -> ${result}`, () => {\n expect(constantCase(input)).toEqual(result);\n });\n }\n});\n"]}

View File

@@ -0,0 +1,3 @@
import { Options } from "no-case";
export { Options };
export declare function constantCase(input: string, options?: Options): string;

View File

@@ -0,0 +1,12 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.constantCase = void 0;
var tslib_1 = require("tslib");
var no_case_1 = require("no-case");
var upper_case_1 = require("upper-case");
function constantCase(input, options) {
if (options === void 0) { options = {}; }
return no_case_1.noCase(input, tslib_1.__assign({ delimiter: "_", transform: upper_case_1.upperCase }, options));
}
exports.constantCase = constantCase;
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AAAA,mCAA0C;AAC1C,yCAAuC;AAIvC,SAAgB,YAAY,CAAC,KAAa,EAAE,OAAqB;IAArB,wBAAA,EAAA,YAAqB;IAC/D,OAAO,gBAAM,CAAC,KAAK,qBACjB,SAAS,EAAE,GAAG,EACd,SAAS,EAAE,sBAAS,IACjB,OAAO,EACV,CAAC;AACL,CAAC;AAND,oCAMC","sourcesContent":["import { noCase, Options } from \"no-case\";\nimport { upperCase } from \"upper-case\";\n\nexport { Options };\n\nexport function constantCase(input: string, options: Options = {}) {\n return noCase(input, {\n delimiter: \"_\",\n transform: upperCase,\n ...options,\n });\n}\n"]}

View File

@@ -0,0 +1 @@
export {};

View File

@@ -0,0 +1,26 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var _1 = require(".");
var TEST_CASES = [
["", ""],
["test", "TEST"],
["test string", "TEST_STRING"],
["Test String", "TEST_STRING"],
["dot.case", "DOT_CASE"],
["path/case", "PATH_CASE"],
["TestV2", "TEST_V2"],
["version 1.2.10", "VERSION_1_2_10"],
["version 1.21.0", "VERSION_1_21_0"],
];
describe("constant case", function () {
var _loop_1 = function (input, result) {
it(input + " -> " + result, function () {
expect(_1.constantCase(input)).toEqual(result);
});
};
for (var _i = 0, TEST_CASES_1 = TEST_CASES; _i < TEST_CASES_1.length; _i++) {
var _a = TEST_CASES_1[_i], input = _a[0], result = _a[1];
_loop_1(input, result);
}
});
//# sourceMappingURL=index.spec.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.spec.js","sourceRoot":"","sources":["../src/index.spec.ts"],"names":[],"mappings":";;AAAA,sBAAiC;AAEjC,IAAM,UAAU,GAAuB;IACrC,CAAC,EAAE,EAAE,EAAE,CAAC;IACR,CAAC,MAAM,EAAE,MAAM,CAAC;IAChB,CAAC,aAAa,EAAE,aAAa,CAAC;IAC9B,CAAC,aAAa,EAAE,aAAa,CAAC;IAC9B,CAAC,UAAU,EAAE,UAAU,CAAC;IACxB,CAAC,WAAW,EAAE,WAAW,CAAC;IAC1B,CAAC,QAAQ,EAAE,SAAS,CAAC;IACrB,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IACpC,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;CACrC,CAAC;AAEF,QAAQ,CAAC,eAAe,EAAE;4BACZ,KAAK,EAAE,MAAM;QACvB,EAAE,CAAI,KAAK,YAAO,MAAQ,EAAE;YAC1B,MAAM,CAAC,eAAY,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;;IAHL,KAA8B,UAAU,EAAV,yBAAU,EAAV,wBAAU,EAAV,IAAU;QAA7B,IAAA,qBAAe,EAAd,KAAK,QAAA,EAAE,MAAM,QAAA;gBAAb,KAAK,EAAE,MAAM;KAIxB;AACH,CAAC,CAAC,CAAC","sourcesContent":["import { constantCase } from \".\";\n\nconst TEST_CASES: [string, string][] = [\n [\"\", \"\"],\n [\"test\", \"TEST\"],\n [\"test string\", \"TEST_STRING\"],\n [\"Test String\", \"TEST_STRING\"],\n [\"dot.case\", \"DOT_CASE\"],\n [\"path/case\", \"PATH_CASE\"],\n [\"TestV2\", \"TEST_V2\"],\n [\"version 1.2.10\", \"VERSION_1_2_10\"],\n [\"version 1.21.0\", \"VERSION_1_21_0\"],\n];\n\ndescribe(\"constant case\", () => {\n for (const [input, result] of TEST_CASES) {\n it(`${input} -> ${result}`, () => {\n expect(constantCase(input)).toEqual(result);\n });\n }\n});\n"]}

View File

@@ -0,0 +1,90 @@
{
"name": "constant-case",
"version": "3.0.4",
"description": "Transform into upper case string with an underscore between words",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"module": "dist.es2015/index.js",
"sideEffects": false,
"jsnext:main": "dist.es2015/index.js",
"files": [
"dist/",
"dist.es2015/",
"LICENSE"
],
"scripts": {
"lint": "tslint \"src/**/*\" --project tsconfig.json",
"build": "rimraf dist/ dist.es2015/ && tsc && tsc -P tsconfig.es2015.json",
"specs": "jest --coverage",
"test": "npm run build && npm run lint && npm run specs",
"size": "size-limit",
"prepare": "npm run build"
},
"repository": {
"type": "git",
"url": "git://github.com/blakeembrey/change-case.git"
},
"keywords": [
"constant",
"case",
"upper",
"uppercase",
"underscore",
"convert",
"transform"
],
"author": {
"name": "Blake Embrey",
"email": "hello@blakeembrey.com",
"url": "http://blakeembrey.me"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/blakeembrey/change-case/issues"
},
"homepage": "https://github.com/blakeembrey/change-case/tree/master/packages/constant-case#readme",
"size-limit": [
{
"path": "dist/index.js",
"limit": "650 B"
}
],
"jest": {
"roots": [
"<rootDir>/src/"
],
"transform": {
"\\.tsx?$": "ts-jest"
},
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(tsx?|jsx?)$",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"json",
"node"
]
},
"publishConfig": {
"access": "public"
},
"dependencies": {
"no-case": "^3.0.4",
"tslib": "^2.0.3",
"upper-case": "^2.0.2"
},
"devDependencies": {
"@size-limit/preset-small-lib": "^2.2.1",
"@types/jest": "^24.0.23",
"@types/node": "^12.12.14",
"jest": "^24.9.0",
"rimraf": "^3.0.0",
"ts-jest": "^24.2.0",
"tslint": "^5.20.1",
"tslint-config-prettier": "^1.18.0",
"tslint-config-standard": "^9.0.0",
"typescript": "^4.1.2"
},
"gitHead": "76a21a7f6f2a226521ef6abd345ff309cbd01fb0"
}

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