@wocker/utils 1.0.11 → 2.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +73 -2
- package/lib/index.d.ts +3 -8
- package/lib/index.js +3 -8
- package/lib/messages.d.ts +15 -0
- package/lib/messages.js +18 -0
- package/lib/prompts/index.d.ts +3 -0
- package/lib/prompts/index.js +19 -0
- package/lib/prompts/promptConfirm.d.ts +4 -0
- package/lib/prompts/promptConfirm.js +75 -0
- package/lib/prompts/promptInput.d.ts +15 -0
- package/lib/prompts/promptInput.js +179 -0
- package/lib/prompts/promptSelect.d.ts +15 -0
- package/lib/prompts/promptSelect.js +162 -0
- package/lib/tools/index.d.ts +4 -0
- package/lib/tools/index.js +20 -0
- package/lib/{normalizeOptions.d.ts → tools/normalizeOptions.d.ts} +6 -8
- package/lib/tools/normalizeOptions.js +26 -0
- package/lib/{volumeFormat.js → tools/volumeFormat.js} +1 -1
- package/lib/types/KeypressEvent.d.ts +5 -0
- package/lib/types/KeypressEvent.js +2 -0
- package/lib/types/PromptConfig.d.ts +8 -0
- package/lib/types/PromptConfig.js +2 -0
- package/lib/types/PromptValidationConfig.d.ts +10 -0
- package/lib/types/PromptValidationConfig.js +2 -0
- package/lib/types/Theme.d.ts +6 -0
- package/lib/types/Theme.js +2 -0
- package/lib/types/Validation.d.ts +2 -0
- package/lib/types/Validation.js +2 -0
- package/lib/types/ValidationError.d.ts +4 -0
- package/lib/types/ValidationError.js +2 -0
- package/lib/types/ValidationResult.d.ts +1 -0
- package/lib/types/ValidationResult.js +2 -0
- package/lib/types/ValidationRule.d.ts +3 -0
- package/lib/types/ValidationRule.js +2 -0
- package/lib/types/ValidationValue.d.ts +1 -0
- package/lib/types/ValidationValue.js +2 -0
- package/lib/types/ValidationValueMessage.d.ts +5 -0
- package/lib/types/ValidationValueMessage.js +2 -0
- package/lib/validation/normalizeRule.d.ts +3 -0
- package/lib/validation/normalizeRule.js +16 -0
- package/lib/validation/validatePrompt.d.ts +3 -0
- package/lib/validation/validatePrompt.js +101 -0
- package/lib/validators/index.d.ts +1 -0
- package/lib/validators/index.js +17 -0
- package/lib/validators/validateVolume.d.ts +2 -0
- package/lib/validators/validateVolume.js +20 -0
- package/package.json +18 -7
- package/test/makes/CustomMuteStream.ts +116 -0
- package/test/makes/PromptSimulator.ts +55 -0
- package/test/tools/render.ts +32 -0
- package/lib/normalizeOptions.js +0 -23
- package/lib/promptConfig.d.ts +0 -14
- package/lib/promptConfig.js +0 -76
- package/lib/promptConfirm.d.ts +0 -6
- package/lib/promptConfirm.js +0 -27
- package/lib/promptGroup.d.ts +0 -14
- package/lib/promptGroup.js +0 -55
- package/lib/promptSelect.d.ts +0 -14
- package/lib/promptSelect.js +0 -58
- package/lib/promptText.d.ts +0 -11
- package/lib/promptText.js +0 -62
- /package/lib/{demuxOutput.d.ts → tools/demuxOutput.d.ts} +0 -0
- /package/lib/{demuxOutput.js → tools/demuxOutput.js} +0 -0
- /package/lib/{volumeFormat.d.ts → tools/volumeFormat.d.ts} +0 -0
- /package/lib/{volumeParse.d.ts → tools/volumeParse.d.ts} +0 -0
- /package/lib/{volumeParse.js → tools/volumeParse.js} +0 -0
package/README.md
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
# @wocker/utils
|
|
2
2
|
|
|
3
|
-
######
|
|
3
|
+
###### Utils for wocker packages
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@wocker/utils)
|
|
6
|
+
[](https://github.com/kearisp/wocker-utils/actions/workflows/publish-latest.yml)
|
|
7
|
+
[](https://github.com/kearisp/wocker-utils/blob/main/LICENSE)
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/@wocker/utils)
|
|
10
|
+
[](https://bundlephobia.com/package/@wocker/utils)
|
|
11
|
+
[](https://codecov.io/gh/kearisp/wocker-utils)
|
|
12
|
+
|
|
4
13
|
|
|
5
14
|
## Usage
|
|
6
15
|
|
|
@@ -8,4 +17,66 @@
|
|
|
8
17
|
|
|
9
18
|
```shell
|
|
10
19
|
npm i @wocker/utils
|
|
11
|
-
```
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
## Breaking Changes in Version 2.0.0
|
|
24
|
+
|
|
25
|
+
### Name Changes for Prompt Functions
|
|
26
|
+
|
|
27
|
+
In version 2.0.0, we've renamed some core prompt functions to improve clarity and consistency across the API. These changes will require updates to your code if you're migrating from v1.x.
|
|
28
|
+
|
|
29
|
+
#### Function Renaming
|
|
30
|
+
|
|
31
|
+
| Old Name (v1.x) | New Name (v2.0.0) | Description |
|
|
32
|
+
|-----------------|-------------------|---------------------------------|
|
|
33
|
+
| `promptText` | `promptInput` | Prompts the user for text input |
|
|
34
|
+
| `promptConfig` | _Removed_ | Function has been removed |
|
|
35
|
+
| `promptGroup` | _Removed_ | Function has been removed |
|
|
36
|
+
|
|
37
|
+
#### Migration Guide
|
|
38
|
+
|
|
39
|
+
If you're upgrading from version 1.x to 2.0.0, you'll need to update your imports and function calls for `promptText`:
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
// Old usage (v1.x)
|
|
43
|
+
import {promptText} from "@wocker/utils";
|
|
44
|
+
|
|
45
|
+
const name = await promptText({
|
|
46
|
+
message: "Enter your name"
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
// New usage (v2.0.0)
|
|
52
|
+
import {promptInput} from "@wocker/utils";
|
|
53
|
+
|
|
54
|
+
const name = await promptInput({
|
|
55
|
+
message: "Enter your name"
|
|
56
|
+
});
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
### Why This Change?
|
|
61
|
+
|
|
62
|
+
We decided to rename the `promptText` function to `promptInput` to:
|
|
63
|
+
|
|
64
|
+
1. Provide a more descriptive name that better reflects its purpose
|
|
65
|
+
2. Create a more consistent naming convention across the API
|
|
66
|
+
3. Improve developer experience with more intuitive function names
|
|
67
|
+
|
|
68
|
+
The `promptConfig` and `promptGroup` functions have been removed as they are no longer supported in the new version.
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
### Migration
|
|
72
|
+
|
|
73
|
+
If you're using a large codebase with many occurrences of the old function name, you can use the following search and replace operation:
|
|
74
|
+
|
|
75
|
+
- Replace all occurrences of `promptText` with `promptInput`
|
|
76
|
+
- Remove any usage of `promptConfig` and `promptGroup` as these functions are no longer available
|
|
77
|
+
|
|
78
|
+
### Additional Information
|
|
79
|
+
|
|
80
|
+
The function signatures and return types remain the same, only the name of `promptText` has changed. All other functionality works exactly as before.
|
|
81
|
+
|
|
82
|
+
For any issues or questions regarding this migration, please open an issue on our GitHub repository.
|
package/lib/index.d.ts
CHANGED
|
@@ -1,8 +1,3 @@
|
|
|
1
|
-
export * from "./
|
|
2
|
-
export * from "./
|
|
3
|
-
export * from "./
|
|
4
|
-
export * from "./promptGroup";
|
|
5
|
-
export * from "./promptSelect";
|
|
6
|
-
export * from "./promptText";
|
|
7
|
-
export * from "./volumeFormat";
|
|
8
|
-
export * from "./volumeParse";
|
|
1
|
+
export * from "./prompts";
|
|
2
|
+
export * from "./tools";
|
|
3
|
+
export * from "./validators";
|
package/lib/index.js
CHANGED
|
@@ -14,11 +14,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./
|
|
18
|
-
__exportStar(require("./
|
|
19
|
-
__exportStar(require("./
|
|
20
|
-
__exportStar(require("./promptGroup"), exports);
|
|
21
|
-
__exportStar(require("./promptSelect"), exports);
|
|
22
|
-
__exportStar(require("./promptText"), exports);
|
|
23
|
-
__exportStar(require("./volumeFormat"), exports);
|
|
24
|
-
__exportStar(require("./volumeParse"), exports);
|
|
17
|
+
__exportStar(require("./prompts"), exports);
|
|
18
|
+
__exportStar(require("./tools"), exports);
|
|
19
|
+
__exportStar(require("./validators"), exports);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare const messages: {
|
|
2
|
+
required: string;
|
|
3
|
+
min: (min: number) => string;
|
|
4
|
+
max: (max: number) => string;
|
|
5
|
+
minLength: (min: number) => string;
|
|
6
|
+
maxLength: (max: number) => string;
|
|
7
|
+
minArrayLength: (min: number) => string;
|
|
8
|
+
maxArrayLength: (max: number) => string;
|
|
9
|
+
custom: string;
|
|
10
|
+
volume: {
|
|
11
|
+
notAString: string;
|
|
12
|
+
tooLong: string;
|
|
13
|
+
invalidCharacters: string;
|
|
14
|
+
};
|
|
15
|
+
};
|
package/lib/messages.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.messages = void 0;
|
|
4
|
+
exports.messages = {
|
|
5
|
+
required: "Mandatory value",
|
|
6
|
+
min: (min) => `The value must be greater that ${min}`,
|
|
7
|
+
max: (max) => `The value must be less than ${max}`,
|
|
8
|
+
minLength: (min) => `The value must have at least ${min} characters.`,
|
|
9
|
+
maxLength: (max) => `The value must not exceed ${max} characters.`,
|
|
10
|
+
minArrayLength: (min) => `The value must have at least ${min} items.`,
|
|
11
|
+
maxArrayLength: (max) => `The value must not exceed ${max} items.`,
|
|
12
|
+
custom: "Invalid value",
|
|
13
|
+
volume: {
|
|
14
|
+
notAString: "Volume name should be string.",
|
|
15
|
+
tooLong: "Volume name must not exceed 255 characters.",
|
|
16
|
+
invalidCharacters: "Invalid volume name. Only alphanumeric characters, single hyphens (-), and underscores (_) are allowed. The name must not start or end with a hyphen or underscore."
|
|
17
|
+
}
|
|
18
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./promptConfirm"), exports);
|
|
18
|
+
__exportStar(require("./promptInput"), exports);
|
|
19
|
+
__exportStar(require("./promptSelect"), exports);
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { PromptConfig } from "../types/PromptConfig";
|
|
2
|
+
type Config = Omit<PromptConfig<boolean>, "min" | "max" | "minLength" | "maxLength">;
|
|
3
|
+
export declare const promptConfirm: import("@inquirer/type").Prompt<boolean, Config>;
|
|
4
|
+
export type { Config as PromptConfirmConfig };
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.promptConfirm = void 0;
|
|
13
|
+
const core_1 = require("@inquirer/core");
|
|
14
|
+
const validatePrompt_1 = require("../validation/validatePrompt");
|
|
15
|
+
exports.promptConfirm = (0, core_1.createPrompt)((config, done) => {
|
|
16
|
+
const { message = "Confirm", default: defaultValue = false } = config;
|
|
17
|
+
const [status, setStatus] = (0, core_1.useState)("idle"), [inputValue, setInputValue] = (0, core_1.useState)(""), [error, setError] = (0, core_1.useState)(""), icon = (0, core_1.usePrefix)({ status });
|
|
18
|
+
const result = (0, core_1.useMemo)(() => {
|
|
19
|
+
if (inputValue) {
|
|
20
|
+
if (/^y(es?)?$/i.test(inputValue)) {
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
else if (/^(n|no)$/i.test(inputValue)) {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
return defaultValue;
|
|
29
|
+
}, [inputValue, defaultValue]);
|
|
30
|
+
const theme = (0, core_1.makeTheme)({}, config.theme);
|
|
31
|
+
(0, core_1.useKeypress)((key, readline) => __awaiter(void 0, void 0, void 0, function* () {
|
|
32
|
+
setStatus("idle");
|
|
33
|
+
setError("");
|
|
34
|
+
switch (key.name) {
|
|
35
|
+
case "return":
|
|
36
|
+
setInputValue("");
|
|
37
|
+
if (typeof result === "undefined") {
|
|
38
|
+
setStatus("error");
|
|
39
|
+
setError("Invalid value");
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
const error = yield (0, validatePrompt_1.validatePrompt)(result, config);
|
|
43
|
+
if (error) {
|
|
44
|
+
setStatus("error");
|
|
45
|
+
setError(error.message);
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
setStatus("done");
|
|
49
|
+
done(result);
|
|
50
|
+
break;
|
|
51
|
+
case "tab":
|
|
52
|
+
const inputValue = result ? "Yes" : "No";
|
|
53
|
+
readline.clearLine(0);
|
|
54
|
+
readline.write(inputValue);
|
|
55
|
+
setInputValue(inputValue);
|
|
56
|
+
break;
|
|
57
|
+
default:
|
|
58
|
+
setInputValue(readline.line);
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
}));
|
|
62
|
+
return [
|
|
63
|
+
[
|
|
64
|
+
`${icon} `,
|
|
65
|
+
theme.style.message(message, status),
|
|
66
|
+
" ",
|
|
67
|
+
theme.style.defaultAnswer(config.default ? "Y/n" : "y/N"),
|
|
68
|
+
" ",
|
|
69
|
+
inputValue
|
|
70
|
+
].join(""),
|
|
71
|
+
error
|
|
72
|
+
? theme.style.error(error)
|
|
73
|
+
: ""
|
|
74
|
+
];
|
|
75
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Context } from "@inquirer/type";
|
|
2
|
+
import { PromptConfig } from "../types/PromptConfig";
|
|
3
|
+
type InputValue = string | number;
|
|
4
|
+
type ValueType<T extends Config["type"] = "text"> = T extends "string" | "text" | "password" ? string : T extends "int" | "number" ? number : string;
|
|
5
|
+
type PromptFn = <V extends ValueType<C["type"]>, C extends Config<V> = Config<V>>(config: C, context?: Context) => Promise<V> & {
|
|
6
|
+
cancel: () => void;
|
|
7
|
+
};
|
|
8
|
+
type Config<V extends InputValue = InputValue> = PromptConfig<V, {
|
|
9
|
+
type?: "text" | "password" | "number";
|
|
10
|
+
step?: number;
|
|
11
|
+
prefix?: string;
|
|
12
|
+
suffix?: string;
|
|
13
|
+
}>;
|
|
14
|
+
export declare const promptInput: PromptFn;
|
|
15
|
+
export { Config as PromptInputConfig };
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.promptInput = void 0;
|
|
16
|
+
const core_1 = require("@inquirer/core");
|
|
17
|
+
const yoctocolors_cjs_1 = __importDefault(require("yoctocolors-cjs"));
|
|
18
|
+
const validatePrompt_1 = require("../validation/validatePrompt");
|
|
19
|
+
exports.promptInput = (0, core_1.createPrompt)((config, done) => {
|
|
20
|
+
const { message = "Input", type = "text", step = 1, prefix = "", suffix = "", default: defaultValue } = config;
|
|
21
|
+
const theme = (0, core_1.makeTheme)({
|
|
22
|
+
style: {
|
|
23
|
+
message: (message) => `${theme.style.highlight(message + ": ")}`,
|
|
24
|
+
value: (value, status) => {
|
|
25
|
+
switch (status) {
|
|
26
|
+
case "error":
|
|
27
|
+
return yoctocolors_cjs_1.default.red(value);
|
|
28
|
+
default:
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}, config.theme);
|
|
34
|
+
const [inputValue = "", setInputValue] = (0, core_1.useState)(typeof defaultValue === "number" ? defaultValue.toString() : defaultValue), [status, setStatus] = (0, core_1.useState)("idle"), [error, setError] = (0, core_1.useState)("");
|
|
35
|
+
const value = (0, core_1.useMemo)(() => {
|
|
36
|
+
switch (config.type) {
|
|
37
|
+
case "number":
|
|
38
|
+
return parseFloat(inputValue);
|
|
39
|
+
default:
|
|
40
|
+
return inputValue;
|
|
41
|
+
}
|
|
42
|
+
}, [inputValue, type]);
|
|
43
|
+
const displayValue = (0, core_1.useMemo)(() => {
|
|
44
|
+
switch (type) {
|
|
45
|
+
case "password":
|
|
46
|
+
return "*".repeat(inputValue.length);
|
|
47
|
+
default:
|
|
48
|
+
return inputValue;
|
|
49
|
+
}
|
|
50
|
+
}, [inputValue, type]);
|
|
51
|
+
const decimalPlaces = (0, core_1.useMemo)(() => {
|
|
52
|
+
if (type !== "number") {
|
|
53
|
+
return 0;
|
|
54
|
+
}
|
|
55
|
+
const [, inputValueDecimal = ""] = inputValue.split("."), [, stepDecimal = ""] = step.toString().split(".");
|
|
56
|
+
return Math.max(inputValueDecimal.length, stepDecimal.length);
|
|
57
|
+
}, [type, step, inputValue]);
|
|
58
|
+
const icon = (0, core_1.usePrefix)({
|
|
59
|
+
theme,
|
|
60
|
+
status
|
|
61
|
+
});
|
|
62
|
+
const handleUp = (readline) => {
|
|
63
|
+
switch (type) {
|
|
64
|
+
case "number": {
|
|
65
|
+
if (typeof value !== "number" || isNaN(value)) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const inputValue = (value + step).toFixed(decimalPlaces);
|
|
69
|
+
readline.clearLine(-1);
|
|
70
|
+
readline.write(inputValue);
|
|
71
|
+
setInputValue(inputValue);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
const handleDown = (readline) => {
|
|
76
|
+
switch (type) {
|
|
77
|
+
case "number": {
|
|
78
|
+
if (typeof value !== "number" || isNaN(value)) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const inputValue = (value - step).toFixed(decimalPlaces);
|
|
82
|
+
readline.clearLine(-1);
|
|
83
|
+
readline.write(inputValue);
|
|
84
|
+
setInputValue(inputValue);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
const handleChange = (readline) => {
|
|
89
|
+
switch (type) {
|
|
90
|
+
case "number": {
|
|
91
|
+
let [, minus = "", firstPart = "", dot = "", secondPart = ""] = /^(-)?([^.]*)(?:([.,])(.*))?$/.exec(readline.line) || [];
|
|
92
|
+
firstPart = firstPart.replace(/[^0-9]/g, "");
|
|
93
|
+
secondPart = secondPart.replace(/[^0-9]/g, "");
|
|
94
|
+
const inputValue = minus + firstPart + (dot ? "." : "") + secondPart;
|
|
95
|
+
if (inputValue !== readline.line) {
|
|
96
|
+
readline.clearLine(-1);
|
|
97
|
+
readline.write(inputValue);
|
|
98
|
+
}
|
|
99
|
+
setInputValue(inputValue);
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
default:
|
|
103
|
+
setInputValue(readline.line);
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
setStatus("idle");
|
|
107
|
+
setError("");
|
|
108
|
+
};
|
|
109
|
+
const handleSubmit = (readline) => __awaiter(void 0, void 0, void 0, function* () {
|
|
110
|
+
setStatus("loading");
|
|
111
|
+
const error = yield (0, validatePrompt_1.validatePrompt)(value, config);
|
|
112
|
+
if (error) {
|
|
113
|
+
readline.write(inputValue);
|
|
114
|
+
setStatus("error");
|
|
115
|
+
setError(error.message);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
setStatus("done");
|
|
119
|
+
setError("");
|
|
120
|
+
done(value);
|
|
121
|
+
});
|
|
122
|
+
(0, core_1.useEffect)((readline) => {
|
|
123
|
+
if (!suffix) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const moveCursor = () => {
|
|
127
|
+
const { cols } = readline.getCursorPos();
|
|
128
|
+
readline.output.unmute();
|
|
129
|
+
readline.output.write(`\x1b[${cols + 1 - suffix.length}G`);
|
|
130
|
+
readline.output.mute();
|
|
131
|
+
};
|
|
132
|
+
const handleKeypress = (_, key) => {
|
|
133
|
+
const keys = [
|
|
134
|
+
"up",
|
|
135
|
+
"left",
|
|
136
|
+
"right",
|
|
137
|
+
"down",
|
|
138
|
+
"home",
|
|
139
|
+
"end",
|
|
140
|
+
"pageup",
|
|
141
|
+
"pagedown",
|
|
142
|
+
"return"
|
|
143
|
+
];
|
|
144
|
+
if (keys.includes(key.name)) {
|
|
145
|
+
moveCursor();
|
|
146
|
+
setTimeout(moveCursor, 0);
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
readline.input.on("keypress", handleKeypress);
|
|
150
|
+
moveCursor();
|
|
151
|
+
return () => {
|
|
152
|
+
readline.input.removeListener("keypress", handleKeypress);
|
|
153
|
+
};
|
|
154
|
+
}, [displayValue, icon, status, suffix]);
|
|
155
|
+
(0, core_1.useKeypress)((key, readline) => __awaiter(void 0, void 0, void 0, function* () {
|
|
156
|
+
if ((0, core_1.isEnterKey)(key)) {
|
|
157
|
+
return yield handleSubmit(readline);
|
|
158
|
+
}
|
|
159
|
+
if ((0, core_1.isUpKey)(key)) {
|
|
160
|
+
return handleUp(readline);
|
|
161
|
+
}
|
|
162
|
+
if ((0, core_1.isDownKey)(key)) {
|
|
163
|
+
return handleDown(readline);
|
|
164
|
+
}
|
|
165
|
+
handleChange(readline);
|
|
166
|
+
}));
|
|
167
|
+
return [
|
|
168
|
+
[
|
|
169
|
+
`${icon} `,
|
|
170
|
+
theme.style.message(message, status),
|
|
171
|
+
theme.style.help(prefix),
|
|
172
|
+
theme.style.value(displayValue, status),
|
|
173
|
+
theme.style.help(suffix)
|
|
174
|
+
].join(""),
|
|
175
|
+
[
|
|
176
|
+
error ? `${theme.style.error(error)}` : ""
|
|
177
|
+
].join("")
|
|
178
|
+
];
|
|
179
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Context } from "@inquirer/type";
|
|
2
|
+
import { PromptConfig } from "../types/PromptConfig";
|
|
3
|
+
import { RawOptions } from "../tools";
|
|
4
|
+
type PromptFn = <V extends C["multiple"] extends true ? string[] : string, C extends Config<V> = Config<V>>(config?: C, context?: Context) => Promise<V> & {
|
|
5
|
+
cancel: () => void;
|
|
6
|
+
};
|
|
7
|
+
type Config<V> = PromptConfig<V, {
|
|
8
|
+
options: RawOptions;
|
|
9
|
+
topHelp?: string;
|
|
10
|
+
multiple?: boolean;
|
|
11
|
+
pageSize?: number;
|
|
12
|
+
default?: V;
|
|
13
|
+
}>;
|
|
14
|
+
export declare const promptSelect: PromptFn;
|
|
15
|
+
export { Config as PromptSelectConfig };
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.promptSelect = void 0;
|
|
16
|
+
const core_1 = require("@inquirer/core");
|
|
17
|
+
const figures_1 = __importDefault(require("@inquirer/figures"));
|
|
18
|
+
const ansi_escapes_1 = __importDefault(require("ansi-escapes"));
|
|
19
|
+
const yoctocolors_cjs_1 = __importDefault(require("yoctocolors-cjs"));
|
|
20
|
+
const tools_1 = require("../tools");
|
|
21
|
+
const validatePrompt_1 = require("../validation/validatePrompt");
|
|
22
|
+
const selectView = (config, done) => {
|
|
23
|
+
const { message = "Select", multiple, pageSize = 5, options: rawOptions = [] } = config;
|
|
24
|
+
const theme = (0, core_1.makeTheme)({
|
|
25
|
+
style: {
|
|
26
|
+
message: (message) => yoctocolors_cjs_1.default.bold(`${message}: `),
|
|
27
|
+
value: (value, status) => {
|
|
28
|
+
switch (status) {
|
|
29
|
+
case "selected":
|
|
30
|
+
return yoctocolors_cjs_1.default.green(value);
|
|
31
|
+
case "active":
|
|
32
|
+
return yoctocolors_cjs_1.default.blue(value);
|
|
33
|
+
case "done":
|
|
34
|
+
return yoctocolors_cjs_1.default.cyan(value);
|
|
35
|
+
default:
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}, config.theme);
|
|
41
|
+
const options = (0, core_1.useMemo)(() => {
|
|
42
|
+
const options = (0, tools_1.normalizeOptions)(rawOptions);
|
|
43
|
+
if (options.length === 0) {
|
|
44
|
+
throw new Error("No selectable choices");
|
|
45
|
+
}
|
|
46
|
+
return options;
|
|
47
|
+
}, [rawOptions]);
|
|
48
|
+
const [status, setStatus] = (0, core_1.useState)("idle"), [showHint, setShowHint] = (0, core_1.useState)(true), [values, setValues] = (0, core_1.useState)(typeof config.default === "string" ? [config.default] : config.default || []), [active, setActive] = (0, core_1.useState)(values.length > 0 ? options.findIndex((o) => o.value === values[0]) : 0), [error, setError] = (0, core_1.useState)(""), icon = (0, core_1.usePrefix)({ theme, status });
|
|
49
|
+
const activeOption = (0, core_1.useMemo)(() => {
|
|
50
|
+
return options[active];
|
|
51
|
+
}, [options, active]);
|
|
52
|
+
const selectedOptions = (0, core_1.useMemo)(() => {
|
|
53
|
+
return options.filter((option) => {
|
|
54
|
+
return values.includes(option.value);
|
|
55
|
+
});
|
|
56
|
+
}, [options, values]);
|
|
57
|
+
const displayValue = (0, core_1.useMemo)(() => {
|
|
58
|
+
if (multiple) {
|
|
59
|
+
return selectedOptions
|
|
60
|
+
.map((option) => option.label)
|
|
61
|
+
.join(", ");
|
|
62
|
+
}
|
|
63
|
+
return activeOption.label;
|
|
64
|
+
}, [activeOption, selectedOptions]);
|
|
65
|
+
// noinspection JSUnusedGlobalSymbols
|
|
66
|
+
const page = (0, core_1.usePagination)({
|
|
67
|
+
items: options,
|
|
68
|
+
active,
|
|
69
|
+
pageSize,
|
|
70
|
+
renderItem: ({ item, isActive }) => {
|
|
71
|
+
const selected = values.includes(item.value), status = selected || (isActive && !multiple) ? "selected" : "idle";
|
|
72
|
+
return [
|
|
73
|
+
isActive
|
|
74
|
+
? theme.style.value(figures_1.default.pointer, "active")
|
|
75
|
+
: " ",
|
|
76
|
+
" ",
|
|
77
|
+
multiple ?
|
|
78
|
+
(selected ? yoctocolors_cjs_1.default.green(figures_1.default.circleFilled) : figures_1.default.circleDotted) + " "
|
|
79
|
+
: "",
|
|
80
|
+
theme.style.value(item.label, status)
|
|
81
|
+
].join("");
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
(0, core_1.useKeypress)((key, readline) => __awaiter(void 0, void 0, void 0, function* () {
|
|
85
|
+
readline.clearLine(0);
|
|
86
|
+
setStatus("idle");
|
|
87
|
+
setShowHint(false);
|
|
88
|
+
setError("");
|
|
89
|
+
if (key.name === "a" && key.ctrl) {
|
|
90
|
+
if (!multiple) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
setValues(options.map(o => o.value));
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
switch (key.name) {
|
|
97
|
+
case "up":
|
|
98
|
+
case "down": {
|
|
99
|
+
const offset = key.name === "up" ? -1 : 1;
|
|
100
|
+
let next = active;
|
|
101
|
+
do {
|
|
102
|
+
next = (next + offset + options.length) % options.length;
|
|
103
|
+
} while (!options[next]);
|
|
104
|
+
setActive(next);
|
|
105
|
+
if (!multiple) {
|
|
106
|
+
setValues([
|
|
107
|
+
options[next].value
|
|
108
|
+
]);
|
|
109
|
+
}
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
case "space":
|
|
113
|
+
if (!multiple) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (values.includes(activeOption.value)) {
|
|
117
|
+
setValues([
|
|
118
|
+
...values.slice(0, values.indexOf(activeOption.value)),
|
|
119
|
+
...values.slice(values.indexOf(activeOption.value) + 1)
|
|
120
|
+
]);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
setValues([
|
|
124
|
+
...values,
|
|
125
|
+
activeOption.value
|
|
126
|
+
]);
|
|
127
|
+
}
|
|
128
|
+
break;
|
|
129
|
+
case "return":
|
|
130
|
+
const result = config.multiple
|
|
131
|
+
? values
|
|
132
|
+
: activeOption.value;
|
|
133
|
+
setStatus("loading");
|
|
134
|
+
const error = yield (0, validatePrompt_1.validatePrompt)(result, config);
|
|
135
|
+
if (error) {
|
|
136
|
+
setStatus("error");
|
|
137
|
+
setError(error.message);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
setStatus("done");
|
|
141
|
+
done(result);
|
|
142
|
+
break;
|
|
143
|
+
}
|
|
144
|
+
}));
|
|
145
|
+
return [
|
|
146
|
+
[
|
|
147
|
+
`${icon} `,
|
|
148
|
+
theme.style.message(message, status),
|
|
149
|
+
showHint
|
|
150
|
+
? theme.style.help("(Use arrow keys)") + " "
|
|
151
|
+
: "",
|
|
152
|
+
status !== "done"
|
|
153
|
+
? `\n${page}`
|
|
154
|
+
: theme.style.value(displayValue, status),
|
|
155
|
+
ansi_escapes_1.default.cursorHide
|
|
156
|
+
].join(""),
|
|
157
|
+
[
|
|
158
|
+
error ? theme.style.error(error) : ""
|
|
159
|
+
].join("")
|
|
160
|
+
];
|
|
161
|
+
};
|
|
162
|
+
exports.promptSelect = (0, core_1.createPrompt)(selectView);
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./demuxOutput"), exports);
|
|
18
|
+
__exportStar(require("./normalizeOptions"), exports);
|
|
19
|
+
__exportStar(require("./volumeFormat"), exports);
|
|
20
|
+
__exportStar(require("./volumeParse"), exports);
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
export type
|
|
2
|
-
[value: string]: string;
|
|
3
|
-
} | {
|
|
4
|
-
label?: string;
|
|
5
|
-
value: string;
|
|
6
|
-
}[];
|
|
7
|
-
export declare const normalizeOptions: (rawOptions: RawOptions) => {
|
|
1
|
+
export type Option = {
|
|
8
2
|
label: string;
|
|
9
3
|
value: string;
|
|
10
|
-
}
|
|
4
|
+
};
|
|
5
|
+
export type RawOptions = {
|
|
6
|
+
[value: string]: string;
|
|
7
|
+
} | (string | Partial<Option>)[];
|
|
8
|
+
export declare const normalizeOptions: (rawOptions: RawOptions) => Option[];
|