@reliverse/rempts-core 1.6.1 → 2.3.2
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 +398 -102
- package/dist/cli.d.ts +32 -0
- package/dist/cli.js +731 -0
- package/dist/config-loader.d.ts +42 -0
- package/dist/config-loader.js +20 -0
- package/dist/config.d.ts +99 -0
- package/dist/config.js +188 -0
- package/dist/file-loader.d.ts +43 -0
- package/dist/file-loader.js +199 -0
- package/dist/global-flags.d.ts +36 -0
- package/dist/global-flags.js +36 -0
- package/dist/mod.d.ts +13 -0
- package/dist/mod.js +19 -0
- package/dist/parser.d.ts +6 -0
- package/dist/parser.js +137 -0
- package/dist/plugin/context.d.ts +13 -0
- package/dist/plugin/context.js +53 -0
- package/dist/plugin/create.d.ts +92 -0
- package/dist/plugin/create.js +61 -0
- package/dist/plugin/loader.d.ts +12 -0
- package/dist/plugin/loader.js +65 -0
- package/dist/plugin/manager.d.ts +53 -0
- package/dist/plugin/manager.js +135 -0
- package/dist/plugin/mod.d.ts +10 -0
- package/dist/plugin/mod.js +27 -0
- package/dist/plugin/store.d.ts +45 -0
- package/dist/plugin/store.js +60 -0
- package/dist/plugin/testing.d.ts +38 -0
- package/dist/plugin/testing.js +175 -0
- package/dist/plugin/types.d.ts +146 -0
- package/dist/tui/registry.d.ts +8 -0
- package/dist/tui/registry.js +10 -0
- package/dist/tui/types.d.ts +58 -0
- package/dist/tui/types.js +10 -0
- package/dist/types.d.ts +178 -0
- package/dist/types.js +25 -0
- package/dist/utils/logger.d.ts +10 -0
- package/dist/utils/logger.js +27 -0
- package/dist/utils/merge.d.ts +13 -0
- package/dist/utils/merge.js +25 -0
- package/dist/utils/mod.d.ts +6 -0
- package/dist/utils/mod.js +2 -0
- package/dist/utils/type-helpers.d.ts +41 -0
- package/dist/utils/type-helpers.js +0 -0
- package/dist/validation.d.ts +30 -0
- package/dist/validation.js +121 -0
- package/package.json +47 -44
- package/src/cli.ts +1049 -0
- package/src/config-loader.ts +71 -0
- package/src/config.ts +270 -0
- package/src/file-loader.ts +346 -0
- package/src/global-flags.ts +50 -0
- package/src/mod.ts +74 -0
- package/src/parser.ts +212 -0
- package/src/plugin/context.ts +88 -0
- package/src/plugin/create.ts +174 -0
- package/src/plugin/loader.ts +111 -0
- package/src/plugin/manager.ts +244 -0
- package/src/plugin/mod.ts +51 -0
- package/src/plugin/store.ts +124 -0
- package/src/plugin/testing.ts +236 -0
- package/src/plugin/types.ts +206 -0
- package/src/tui/registry.ts +22 -0
- package/src/tui/types.ts +79 -0
- package/src/types.ts +285 -0
- package/src/utils/logger.ts +43 -0
- package/src/utils/merge.ts +54 -0
- package/src/utils/mod.ts +7 -0
- package/src/utils/type-helpers.ts +151 -0
- package/src/validation.ts +177 -0
- package/LICENSE +0 -21
- package/bin/core-impl/anykey/anykey-mod.d.ts +0 -12
- package/bin/core-impl/anykey/anykey-mod.js +0 -125
- package/bin/core-impl/date/date.d.ts +0 -2
- package/bin/core-impl/date/date.js +0 -236
- package/bin/core-impl/editor/editor-mod.d.ts +0 -25
- package/bin/core-impl/editor/editor-mod.js +0 -896
- package/bin/core-impl/figures/figures-mod.d.ts +0 -233
- package/bin/core-impl/figures/figures-mod.js +0 -286
- package/bin/core-impl/figures/figures.test.d.ts +0 -1
- package/bin/core-impl/figures/figures.test.js +0 -474
- package/bin/core-impl/input/confirm-prompt.d.ts +0 -5
- package/bin/core-impl/input/confirm-prompt.js +0 -173
- package/bin/core-impl/input/input-prompt.d.ts +0 -16
- package/bin/core-impl/input/input-prompt.js +0 -370
- package/bin/core-impl/launcher/_parser.d.ts +0 -2
- package/bin/core-impl/launcher/_parser.js +0 -122
- package/bin/core-impl/launcher/_utils.d.ts +0 -8
- package/bin/core-impl/launcher/_utils.js +0 -29
- package/bin/core-impl/launcher/args.d.ts +0 -3
- package/bin/core-impl/launcher/args.js +0 -89
- package/bin/core-impl/launcher/command.d.ts +0 -8
- package/bin/core-impl/launcher/command.js +0 -68
- package/bin/core-impl/launcher/launcher-mod.d.ts +0 -8
- package/bin/core-impl/launcher/launcher-mod.js +0 -34
- package/bin/core-impl/launcher/usage.d.ts +0 -3
- package/bin/core-impl/launcher/usage.js +0 -104
- package/bin/core-impl/msg-fmt/colors.d.ts +0 -30
- package/bin/core-impl/msg-fmt/colors.js +0 -42
- package/bin/core-impl/msg-fmt/logger.d.ts +0 -17
- package/bin/core-impl/msg-fmt/logger.js +0 -106
- package/bin/core-impl/msg-fmt/mapping.d.ts +0 -3
- package/bin/core-impl/msg-fmt/mapping.js +0 -49
- package/bin/core-impl/msg-fmt/messages.d.ts +0 -35
- package/bin/core-impl/msg-fmt/messages.js +0 -314
- package/bin/core-impl/msg-fmt/terminal.d.ts +0 -15
- package/bin/core-impl/msg-fmt/terminal.js +0 -59
- package/bin/core-impl/msg-fmt/variants.d.ts +0 -11
- package/bin/core-impl/msg-fmt/variants.js +0 -52
- package/bin/core-impl/next-steps/next-steps.d.ts +0 -14
- package/bin/core-impl/next-steps/next-steps.js +0 -24
- package/bin/core-impl/number/number-mod.d.ts +0 -28
- package/bin/core-impl/number/number-mod.js +0 -197
- package/bin/core-impl/results/results.d.ts +0 -7
- package/bin/core-impl/results/results.js +0 -27
- package/bin/core-impl/select/multiselect-prompt.d.ts +0 -2
- package/bin/core-impl/select/multiselect-prompt.js +0 -341
- package/bin/core-impl/select/nummultiselect-prompt.d.ts +0 -6
- package/bin/core-impl/select/nummultiselect-prompt.js +0 -105
- package/bin/core-impl/select/numselect-prompt.d.ts +0 -7
- package/bin/core-impl/select/numselect-prompt.js +0 -115
- package/bin/core-impl/select/select-prompt.d.ts +0 -33
- package/bin/core-impl/select/select-prompt.js +0 -302
- package/bin/core-impl/select/toggle-prompt.d.ts +0 -5
- package/bin/core-impl/select/toggle-prompt.js +0 -208
- package/bin/core-impl/st-end/end.d.ts +0 -2
- package/bin/core-impl/st-end/end.js +0 -42
- package/bin/core-impl/st-end/start.d.ts +0 -17
- package/bin/core-impl/st-end/start.js +0 -66
- package/bin/core-impl/task/progress.d.ts +0 -2
- package/bin/core-impl/task/progress.js +0 -57
- package/bin/core-impl/task/spinner.d.ts +0 -15
- package/bin/core-impl/task/spinner.js +0 -110
- package/bin/core-impl/utils/colorize.d.ts +0 -2
- package/bin/core-impl/utils/colorize.js +0 -134
- package/bin/core-impl/utils/errors.d.ts +0 -1
- package/bin/core-impl/utils/errors.js +0 -15
- package/bin/core-impl/utils/prevent.d.ts +0 -10
- package/bin/core-impl/utils/prevent.js +0 -69
- package/bin/core-impl/utils/prompt-end.d.ts +0 -8
- package/bin/core-impl/utils/prompt-end.js +0 -33
- package/bin/core-impl/utils/stream-text.d.ts +0 -18
- package/bin/core-impl/utils/stream-text.js +0 -136
- package/bin/core-impl/utils/system.d.ts +0 -6
- package/bin/core-impl/utils/system.js +0 -7
- package/bin/core-impl/utils/validate.d.ts +0 -22
- package/bin/core-impl/utils/validate.js +0 -17
- package/bin/core-impl/visual/animate/animate.d.ts +0 -14
- package/bin/core-impl/visual/animate/animate.js +0 -64
- package/bin/core-impl/visual/ascii-art/ascii-art.d.ts +0 -6
- package/bin/core-impl/visual/ascii-art/ascii-art.js +0 -12
- package/bin/core-types.d.ts +0 -434
- package/bin/main.d.ts +0 -41
- package/bin/main.js +0 -96
- /package/{bin/core-types.js → dist/plugin/types.js} +0 -0
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type utilities inspired by TanStack Router for advanced type manipulation
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// Union to intersection conversion
|
|
6
|
+
export type UnionToIntersection<T> = (T extends any ? (arg: T) => any : never) extends (
|
|
7
|
+
arg: infer T
|
|
8
|
+
) => any
|
|
9
|
+
? T
|
|
10
|
+
: never;
|
|
11
|
+
|
|
12
|
+
// Constrain types with fallback
|
|
13
|
+
export type Constrain<T, TConstraint, TDefault = TConstraint> =
|
|
14
|
+
| (T extends TConstraint ? T : never)
|
|
15
|
+
| TDefault;
|
|
16
|
+
|
|
17
|
+
// Pick required properties
|
|
18
|
+
export type PickRequired<T> = {
|
|
19
|
+
[K in keyof T as undefined extends T[K] ? never : K]: T[K];
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// Pick optional properties
|
|
23
|
+
export type PickOptional<T> = {
|
|
24
|
+
[K in keyof T as undefined extends T[K] ? K : never]: T[K];
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// Extract primitive types from union
|
|
28
|
+
export type ExtractPrimitives<TUnion> = TUnion extends MergeAllPrimitive
|
|
29
|
+
? TUnion
|
|
30
|
+
: TUnion extends object
|
|
31
|
+
? never
|
|
32
|
+
: TUnion;
|
|
33
|
+
|
|
34
|
+
// Merge all primitive types
|
|
35
|
+
export type MergeAllPrimitive =
|
|
36
|
+
| readonly any[]
|
|
37
|
+
| number
|
|
38
|
+
| string
|
|
39
|
+
| bigint
|
|
40
|
+
| boolean
|
|
41
|
+
| symbol
|
|
42
|
+
| undefined
|
|
43
|
+
| null;
|
|
44
|
+
|
|
45
|
+
// Extract objects from union
|
|
46
|
+
export type ExtractObjects<TUnion> = TUnion extends MergeAllPrimitive ? never : TUnion;
|
|
47
|
+
|
|
48
|
+
// Partial merge all objects
|
|
49
|
+
export type PartialMergeAllObject<TUnion> =
|
|
50
|
+
ExtractObjects<TUnion> extends infer TObj
|
|
51
|
+
? [TObj] extends [never]
|
|
52
|
+
? never
|
|
53
|
+
: {
|
|
54
|
+
[TKey in TObj extends any ? keyof TObj : never]?: TObj extends any
|
|
55
|
+
? TKey extends keyof TObj
|
|
56
|
+
? TObj[TKey]
|
|
57
|
+
: never
|
|
58
|
+
: never;
|
|
59
|
+
}
|
|
60
|
+
: never;
|
|
61
|
+
|
|
62
|
+
// Partial merge all
|
|
63
|
+
export type PartialMergeAll<TUnion> = ExtractPrimitives<TUnion> | PartialMergeAllObject<TUnion>;
|
|
64
|
+
|
|
65
|
+
// Merge all objects in union
|
|
66
|
+
export type MergeAllObjects<TUnion, TIntersected = UnionToIntersection<ExtractObjects<TUnion>>> = [
|
|
67
|
+
keyof TIntersected,
|
|
68
|
+
] extends [never]
|
|
69
|
+
? never
|
|
70
|
+
: {
|
|
71
|
+
[TKey in keyof TIntersected]: TUnion extends any ? TUnion[TKey & keyof TUnion] : never;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
// Merge all types in union
|
|
75
|
+
export type MergeAll<TUnion> = MergeAllObjects<TUnion> | ExtractPrimitives<TUnion>;
|
|
76
|
+
|
|
77
|
+
// No inference utility
|
|
78
|
+
export type NoInfer<T> = [T][T extends any ? 0 : never];
|
|
79
|
+
|
|
80
|
+
// Check if type is any
|
|
81
|
+
export type IsAny<TValue, TYesResult, TNoResult = TValue> = 1 extends 0 & TValue
|
|
82
|
+
? TYesResult
|
|
83
|
+
: TNoResult;
|
|
84
|
+
|
|
85
|
+
// Pick as required
|
|
86
|
+
export type PickAsRequired<TValue, TKey extends keyof TValue> = Omit<TValue, TKey> &
|
|
87
|
+
Required<Pick<TValue, TKey>>;
|
|
88
|
+
|
|
89
|
+
// Without empty objects
|
|
90
|
+
export type WithoutEmpty<T> = T extends any ? ({} extends T ? never : T) : never;
|
|
91
|
+
|
|
92
|
+
// Expand type for better IntelliSense
|
|
93
|
+
export type Expand<T> = T extends object
|
|
94
|
+
? T extends infer O
|
|
95
|
+
? O extends Function
|
|
96
|
+
? O
|
|
97
|
+
: { [K in keyof O]: O[K] }
|
|
98
|
+
: never
|
|
99
|
+
: T;
|
|
100
|
+
|
|
101
|
+
// Deep partial
|
|
102
|
+
export type DeepPartial<T> = T extends object
|
|
103
|
+
? {
|
|
104
|
+
[P in keyof T]?: DeepPartial<T[P]>;
|
|
105
|
+
}
|
|
106
|
+
: T;
|
|
107
|
+
|
|
108
|
+
// Make difference optional
|
|
109
|
+
export type MakeDifferenceOptional<TLeft, TRight> = keyof TLeft & keyof TRight extends never
|
|
110
|
+
? TRight
|
|
111
|
+
: Omit<TRight, keyof TLeft & keyof TRight> & {
|
|
112
|
+
[K in keyof TLeft & keyof TRight]?: TRight[K];
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
// Check if type is union
|
|
116
|
+
export type IsUnion<T, U extends T = T> = (
|
|
117
|
+
T extends any
|
|
118
|
+
? U extends T
|
|
119
|
+
? false
|
|
120
|
+
: true
|
|
121
|
+
: never
|
|
122
|
+
) extends false
|
|
123
|
+
? false
|
|
124
|
+
: true;
|
|
125
|
+
|
|
126
|
+
// Check if type is non-empty object
|
|
127
|
+
export type IsNonEmptyObject<T> = T extends object ? (keyof T extends never ? false : true) : false;
|
|
128
|
+
|
|
129
|
+
// Assign types
|
|
130
|
+
export type Assign<TLeft, TRight> = TLeft extends any
|
|
131
|
+
? TRight extends any
|
|
132
|
+
? IsNonEmptyObject<TLeft> extends false
|
|
133
|
+
? TRight
|
|
134
|
+
: IsNonEmptyObject<TRight> extends false
|
|
135
|
+
? TLeft
|
|
136
|
+
: keyof TLeft & keyof TRight extends never
|
|
137
|
+
? TLeft & TRight
|
|
138
|
+
: Omit<TLeft, keyof TRight> & TRight
|
|
139
|
+
: never
|
|
140
|
+
: never;
|
|
141
|
+
|
|
142
|
+
// Intersect assign
|
|
143
|
+
export type IntersectAssign<TLeft, TRight> = TLeft extends any
|
|
144
|
+
? TRight extends any
|
|
145
|
+
? IsNonEmptyObject<TLeft> extends false
|
|
146
|
+
? TRight
|
|
147
|
+
: IsNonEmptyObject<TRight> extends false
|
|
148
|
+
? TLeft
|
|
149
|
+
: TRight & TLeft
|
|
150
|
+
: never
|
|
151
|
+
: never;
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime validation utilities for Rempts
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
|
6
|
+
import { RemptsValidationError } from "./types";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Validate a value against a schema at runtime
|
|
10
|
+
*/
|
|
11
|
+
export async function validateValue(
|
|
12
|
+
value: unknown,
|
|
13
|
+
schema: StandardSchemaV1,
|
|
14
|
+
context: {
|
|
15
|
+
option: string;
|
|
16
|
+
command: string;
|
|
17
|
+
}
|
|
18
|
+
): Promise<unknown> {
|
|
19
|
+
try {
|
|
20
|
+
const result = await schema["~standard"].validate(value);
|
|
21
|
+
|
|
22
|
+
if (result.issues && result.issues.length > 0) {
|
|
23
|
+
const issue = result.issues[0];
|
|
24
|
+
if (!issue) {
|
|
25
|
+
return value;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const expectedType = extractSchemaType(schema);
|
|
29
|
+
const hint = generateHint(schema, value);
|
|
30
|
+
|
|
31
|
+
throw new RemptsValidationError(`Invalid option '${context.option}': ${issue.message}`, {
|
|
32
|
+
option: context.option,
|
|
33
|
+
value,
|
|
34
|
+
command: context.command,
|
|
35
|
+
expectedType,
|
|
36
|
+
hint,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return "value" in result ? result.value : value;
|
|
41
|
+
} catch (error) {
|
|
42
|
+
if (error instanceof RemptsValidationError) {
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Wrap other errors
|
|
47
|
+
throw new RemptsValidationError(`Validation failed for option '${context.option}': ${error}`, {
|
|
48
|
+
option: context.option,
|
|
49
|
+
value,
|
|
50
|
+
command: context.command,
|
|
51
|
+
expectedType: "unknown",
|
|
52
|
+
hint: "Check the value format and try again",
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Validate multiple values against their schemas
|
|
59
|
+
*/
|
|
60
|
+
export async function validateValues(
|
|
61
|
+
values: Record<string, unknown>,
|
|
62
|
+
schemas: Record<string, StandardSchemaV1>,
|
|
63
|
+
command: string
|
|
64
|
+
): Promise<Record<string, unknown>> {
|
|
65
|
+
const results: Record<string, unknown> = {};
|
|
66
|
+
const errors: string[] = [];
|
|
67
|
+
|
|
68
|
+
for (const [key, value] of Object.entries(values)) {
|
|
69
|
+
const schema = schemas[key];
|
|
70
|
+
if (!schema) {
|
|
71
|
+
results[key] = value;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
results[key] = await validateValue(value, schema, {
|
|
77
|
+
option: key,
|
|
78
|
+
command,
|
|
79
|
+
});
|
|
80
|
+
} catch (error) {
|
|
81
|
+
if (error instanceof RemptsValidationError) {
|
|
82
|
+
errors.push(error.toString());
|
|
83
|
+
} else {
|
|
84
|
+
errors.push(`Validation error for ${key}: ${error}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
if (errors.length > 0) {
|
|
90
|
+
throw new Error(`Validation failed:\n${errors.join("\n")}`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return results;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Check if a value matches a schema type
|
|
98
|
+
*/
|
|
99
|
+
export function isValueOfType(value: unknown, expectedType: string): boolean {
|
|
100
|
+
switch (expectedType) {
|
|
101
|
+
case "string":
|
|
102
|
+
return typeof value === "string";
|
|
103
|
+
case "number":
|
|
104
|
+
return typeof value === "number";
|
|
105
|
+
case "boolean":
|
|
106
|
+
return typeof value === "boolean";
|
|
107
|
+
case "array":
|
|
108
|
+
return Array.isArray(value);
|
|
109
|
+
case "object":
|
|
110
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
111
|
+
default:
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Extract a human-readable type description from a schema
|
|
118
|
+
*/
|
|
119
|
+
function extractSchemaType(schema: StandardSchemaV1): string {
|
|
120
|
+
if ("type" in schema && typeof schema.type === "string") {
|
|
121
|
+
return schema.type;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if ("enum" in schema) {
|
|
125
|
+
return "enum";
|
|
126
|
+
}
|
|
127
|
+
if ("items" in schema) {
|
|
128
|
+
return "array";
|
|
129
|
+
}
|
|
130
|
+
if ("properties" in schema) {
|
|
131
|
+
return "object";
|
|
132
|
+
}
|
|
133
|
+
if ("format" in schema) {
|
|
134
|
+
return "string";
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return "unknown";
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Generate a helpful hint based on the schema and value
|
|
142
|
+
*/
|
|
143
|
+
function generateHint(schema: StandardSchemaV1, value: unknown): string {
|
|
144
|
+
const type = extractSchemaType(schema);
|
|
145
|
+
|
|
146
|
+
if (type === "boolean" && typeof value === "string") {
|
|
147
|
+
return "Use --flag or --no-flag for boolean options";
|
|
148
|
+
}
|
|
149
|
+
if (type === "number" && typeof value === "string") {
|
|
150
|
+
return "Provide a numeric value";
|
|
151
|
+
}
|
|
152
|
+
if (type === "array" && !Array.isArray(value)) {
|
|
153
|
+
return "Provide a comma-separated list of values";
|
|
154
|
+
}
|
|
155
|
+
if (type === "enum" && typeof value === "string") {
|
|
156
|
+
return "Choose from the available options";
|
|
157
|
+
}
|
|
158
|
+
return "";
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Create a validator function from a schema
|
|
163
|
+
*/
|
|
164
|
+
export function createValidator(schema: StandardSchemaV1) {
|
|
165
|
+
return async (value: unknown, context: { option: string; command: string }) => {
|
|
166
|
+
return validateValue(value, schema, context);
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Batch validate multiple values
|
|
172
|
+
*/
|
|
173
|
+
export function createBatchValidator(schemas: Record<string, StandardSchemaV1>) {
|
|
174
|
+
return async (values: Record<string, unknown>, command: string) => {
|
|
175
|
+
return validateValues(values, schemas, command);
|
|
176
|
+
};
|
|
177
|
+
}
|
package/LICENSE
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 blefnk Nazar Kornienko
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { ColorName } from "../../core-types.js";
|
|
2
|
-
type Options = {
|
|
3
|
-
ctrlC?: number | false | "reject";
|
|
4
|
-
preserveLog?: boolean;
|
|
5
|
-
hideMessage?: boolean;
|
|
6
|
-
shouldStream?: boolean;
|
|
7
|
-
streamDelay?: number;
|
|
8
|
-
color?: ColorName;
|
|
9
|
-
placeholderColor?: ColorName;
|
|
10
|
-
};
|
|
11
|
-
export declare function anykeyPrompt(message?: string, options?: Options): Promise<void>;
|
|
12
|
-
export {};
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import logUpdate from "log-update";
|
|
2
|
-
import { cursor } from "sisteransi";
|
|
3
|
-
import { fmt } from "../msg-fmt/messages.js";
|
|
4
|
-
import { endPrompt } from "../st-end/end.js";
|
|
5
|
-
import { streamText } from "../utils/stream-text.js";
|
|
6
|
-
const DEFAULT_MESSAGE = "Press any key to continue...";
|
|
7
|
-
const CTRL_C_CODE = 3;
|
|
8
|
-
const terminal = {
|
|
9
|
-
/**
|
|
10
|
-
* Move cursor to start of line
|
|
11
|
-
*/
|
|
12
|
-
moveToStart: () => process.stdout.write("\r"),
|
|
13
|
-
/**
|
|
14
|
-
* Clear current line and move cursor up
|
|
15
|
-
*/
|
|
16
|
-
clearLineAndMoveUp: () => process.stdout.write("\x1B[1A\x1B[2K"),
|
|
17
|
-
/**
|
|
18
|
-
* Clear multiple lines above current position
|
|
19
|
-
*/
|
|
20
|
-
clearLines: (count) => {
|
|
21
|
-
terminal.moveToStart();
|
|
22
|
-
process.stdout.write("\x1B[2K");
|
|
23
|
-
for (let i = 0; i < count; i++) {
|
|
24
|
-
terminal.clearLineAndMoveUp();
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
export async function anykeyPrompt(message = DEFAULT_MESSAGE, options = {}) {
|
|
29
|
-
const {
|
|
30
|
-
ctrlC = 1,
|
|
31
|
-
preserveLog = false,
|
|
32
|
-
hideMessage = false,
|
|
33
|
-
shouldStream = false,
|
|
34
|
-
streamDelay = 20,
|
|
35
|
-
color = "dim",
|
|
36
|
-
placeholderColor = "gray"
|
|
37
|
-
} = options;
|
|
38
|
-
if (message) {
|
|
39
|
-
if (!shouldStream) {
|
|
40
|
-
const { text } = fmt({
|
|
41
|
-
hintPlaceholderColor: placeholderColor,
|
|
42
|
-
type: "M_GENERAL",
|
|
43
|
-
title: message,
|
|
44
|
-
titleColor: color,
|
|
45
|
-
dontRemoveBar: true
|
|
46
|
-
});
|
|
47
|
-
message = text;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
if (message && !hideMessage) {
|
|
51
|
-
if (shouldStream) {
|
|
52
|
-
await streamText({
|
|
53
|
-
text: `\u25C6 ${message}`,
|
|
54
|
-
delay: streamDelay,
|
|
55
|
-
newline: false,
|
|
56
|
-
clearLine: true,
|
|
57
|
-
color
|
|
58
|
-
});
|
|
59
|
-
const lineCount = message.split("\n").length;
|
|
60
|
-
terminal.clearLines(lineCount);
|
|
61
|
-
const { text } = fmt({
|
|
62
|
-
hintPlaceholderColor: placeholderColor,
|
|
63
|
-
type: "M_GENERAL",
|
|
64
|
-
title: message,
|
|
65
|
-
titleColor: color,
|
|
66
|
-
dontRemoveBar: true
|
|
67
|
-
});
|
|
68
|
-
terminal.moveToStart();
|
|
69
|
-
logUpdate(text);
|
|
70
|
-
} else {
|
|
71
|
-
logUpdate(message);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
return new Promise((resolve, reject) => {
|
|
75
|
-
const cleanup = () => {
|
|
76
|
-
process.stdin.removeListener("data", handler);
|
|
77
|
-
if (process.stdin.isTTY && typeof process.stdin.setRawMode === "function") {
|
|
78
|
-
process.stdin.setRawMode(false);
|
|
79
|
-
}
|
|
80
|
-
process.stdin.pause();
|
|
81
|
-
process.stdout.write(cursor.show);
|
|
82
|
-
};
|
|
83
|
-
const handleCtrlC = () => {
|
|
84
|
-
cleanup();
|
|
85
|
-
void endPrompt({
|
|
86
|
-
title: "\u270B User pressed Ctrl+C, exiting...",
|
|
87
|
-
titleAnimation: "pulse",
|
|
88
|
-
titleColor: "redBright",
|
|
89
|
-
titleTypography: "bold",
|
|
90
|
-
endTitleColor: "redBright",
|
|
91
|
-
titleAnimationDelay: 400
|
|
92
|
-
}).then(() => {
|
|
93
|
-
if (ctrlC === "reject") {
|
|
94
|
-
reject(new Error("User pressed CTRL+C"));
|
|
95
|
-
} else if (ctrlC === false) {
|
|
96
|
-
resolve();
|
|
97
|
-
} else if (typeof ctrlC === "number") {
|
|
98
|
-
process.exit(0);
|
|
99
|
-
} else {
|
|
100
|
-
throw new TypeError("Invalid ctrlC option");
|
|
101
|
-
}
|
|
102
|
-
}).catch(reject);
|
|
103
|
-
};
|
|
104
|
-
const handler = (buffer) => {
|
|
105
|
-
cleanup();
|
|
106
|
-
if (message && !preserveLog) {
|
|
107
|
-
logUpdate.clear();
|
|
108
|
-
} else {
|
|
109
|
-
logUpdate.done();
|
|
110
|
-
process.stdout.write("\n");
|
|
111
|
-
}
|
|
112
|
-
const [firstByte] = buffer;
|
|
113
|
-
if (firstByte === CTRL_C_CODE) {
|
|
114
|
-
handleCtrlC();
|
|
115
|
-
} else {
|
|
116
|
-
resolve();
|
|
117
|
-
}
|
|
118
|
-
};
|
|
119
|
-
process.stdin.resume();
|
|
120
|
-
if (process.stdin.isTTY && typeof process.stdin.setRawMode === "function") {
|
|
121
|
-
process.stdin.setRawMode(true);
|
|
122
|
-
}
|
|
123
|
-
process.stdin.once("data", handler);
|
|
124
|
-
});
|
|
125
|
-
}
|