@reliverse/rempts-core 1.6.1 → 2.3.1

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.
Files changed (155) hide show
  1. package/README.md +398 -102
  2. package/dist/cli.d.ts +32 -0
  3. package/dist/cli.js +731 -0
  4. package/dist/config-loader.d.ts +42 -0
  5. package/dist/config-loader.js +20 -0
  6. package/dist/config.d.ts +99 -0
  7. package/dist/config.js +188 -0
  8. package/dist/file-loader.d.ts +43 -0
  9. package/dist/file-loader.js +199 -0
  10. package/dist/global-flags.d.ts +36 -0
  11. package/dist/global-flags.js +36 -0
  12. package/dist/mod.d.ts +13 -0
  13. package/dist/mod.js +19 -0
  14. package/dist/parser.d.ts +6 -0
  15. package/dist/parser.js +137 -0
  16. package/dist/plugin/context.d.ts +13 -0
  17. package/dist/plugin/context.js +53 -0
  18. package/dist/plugin/create.d.ts +92 -0
  19. package/dist/plugin/create.js +61 -0
  20. package/dist/plugin/loader.d.ts +12 -0
  21. package/dist/plugin/loader.js +65 -0
  22. package/dist/plugin/manager.d.ts +53 -0
  23. package/dist/plugin/manager.js +135 -0
  24. package/dist/plugin/mod.d.ts +10 -0
  25. package/dist/plugin/mod.js +27 -0
  26. package/dist/plugin/store.d.ts +45 -0
  27. package/dist/plugin/store.js +60 -0
  28. package/dist/plugin/testing.d.ts +38 -0
  29. package/dist/plugin/testing.js +175 -0
  30. package/dist/plugin/types.d.ts +146 -0
  31. package/dist/tui/registry.d.ts +8 -0
  32. package/dist/tui/registry.js +10 -0
  33. package/dist/tui/types.d.ts +58 -0
  34. package/dist/tui/types.js +10 -0
  35. package/dist/types.d.ts +178 -0
  36. package/dist/types.js +25 -0
  37. package/dist/utils/logger.d.ts +10 -0
  38. package/dist/utils/logger.js +27 -0
  39. package/dist/utils/merge.d.ts +13 -0
  40. package/dist/utils/merge.js +25 -0
  41. package/dist/utils/mod.d.ts +6 -0
  42. package/dist/utils/mod.js +2 -0
  43. package/dist/utils/type-helpers.d.ts +41 -0
  44. package/dist/utils/type-helpers.js +0 -0
  45. package/dist/validation.d.ts +30 -0
  46. package/dist/validation.js +121 -0
  47. package/package.json +47 -44
  48. package/src/cli.ts +1049 -0
  49. package/src/config-loader.ts +71 -0
  50. package/src/config.ts +270 -0
  51. package/src/file-loader.ts +346 -0
  52. package/src/global-flags.ts +50 -0
  53. package/src/mod.ts +74 -0
  54. package/src/parser.ts +212 -0
  55. package/src/plugin/context.ts +88 -0
  56. package/src/plugin/create.ts +174 -0
  57. package/src/plugin/loader.ts +111 -0
  58. package/src/plugin/manager.ts +244 -0
  59. package/src/plugin/mod.ts +51 -0
  60. package/src/plugin/store.ts +124 -0
  61. package/src/plugin/testing.ts +236 -0
  62. package/src/plugin/types.ts +206 -0
  63. package/src/tui/registry.ts +22 -0
  64. package/src/tui/types.ts +79 -0
  65. package/src/types.ts +285 -0
  66. package/src/utils/logger.ts +43 -0
  67. package/src/utils/merge.ts +54 -0
  68. package/src/utils/mod.ts +7 -0
  69. package/src/utils/type-helpers.ts +151 -0
  70. package/src/validation.ts +177 -0
  71. package/LICENSE +0 -21
  72. package/bin/core-impl/anykey/anykey-mod.d.ts +0 -12
  73. package/bin/core-impl/anykey/anykey-mod.js +0 -125
  74. package/bin/core-impl/date/date.d.ts +0 -2
  75. package/bin/core-impl/date/date.js +0 -236
  76. package/bin/core-impl/editor/editor-mod.d.ts +0 -25
  77. package/bin/core-impl/editor/editor-mod.js +0 -896
  78. package/bin/core-impl/figures/figures-mod.d.ts +0 -233
  79. package/bin/core-impl/figures/figures-mod.js +0 -286
  80. package/bin/core-impl/figures/figures.test.d.ts +0 -1
  81. package/bin/core-impl/figures/figures.test.js +0 -474
  82. package/bin/core-impl/input/confirm-prompt.d.ts +0 -5
  83. package/bin/core-impl/input/confirm-prompt.js +0 -173
  84. package/bin/core-impl/input/input-prompt.d.ts +0 -16
  85. package/bin/core-impl/input/input-prompt.js +0 -370
  86. package/bin/core-impl/launcher/_parser.d.ts +0 -2
  87. package/bin/core-impl/launcher/_parser.js +0 -122
  88. package/bin/core-impl/launcher/_utils.d.ts +0 -8
  89. package/bin/core-impl/launcher/_utils.js +0 -29
  90. package/bin/core-impl/launcher/args.d.ts +0 -3
  91. package/bin/core-impl/launcher/args.js +0 -89
  92. package/bin/core-impl/launcher/command.d.ts +0 -8
  93. package/bin/core-impl/launcher/command.js +0 -68
  94. package/bin/core-impl/launcher/launcher-mod.d.ts +0 -8
  95. package/bin/core-impl/launcher/launcher-mod.js +0 -34
  96. package/bin/core-impl/launcher/usage.d.ts +0 -3
  97. package/bin/core-impl/launcher/usage.js +0 -104
  98. package/bin/core-impl/msg-fmt/colors.d.ts +0 -30
  99. package/bin/core-impl/msg-fmt/colors.js +0 -42
  100. package/bin/core-impl/msg-fmt/logger.d.ts +0 -17
  101. package/bin/core-impl/msg-fmt/logger.js +0 -106
  102. package/bin/core-impl/msg-fmt/mapping.d.ts +0 -3
  103. package/bin/core-impl/msg-fmt/mapping.js +0 -49
  104. package/bin/core-impl/msg-fmt/messages.d.ts +0 -35
  105. package/bin/core-impl/msg-fmt/messages.js +0 -314
  106. package/bin/core-impl/msg-fmt/terminal.d.ts +0 -15
  107. package/bin/core-impl/msg-fmt/terminal.js +0 -59
  108. package/bin/core-impl/msg-fmt/variants.d.ts +0 -11
  109. package/bin/core-impl/msg-fmt/variants.js +0 -52
  110. package/bin/core-impl/next-steps/next-steps.d.ts +0 -14
  111. package/bin/core-impl/next-steps/next-steps.js +0 -24
  112. package/bin/core-impl/number/number-mod.d.ts +0 -28
  113. package/bin/core-impl/number/number-mod.js +0 -197
  114. package/bin/core-impl/results/results.d.ts +0 -7
  115. package/bin/core-impl/results/results.js +0 -27
  116. package/bin/core-impl/select/multiselect-prompt.d.ts +0 -2
  117. package/bin/core-impl/select/multiselect-prompt.js +0 -341
  118. package/bin/core-impl/select/nummultiselect-prompt.d.ts +0 -6
  119. package/bin/core-impl/select/nummultiselect-prompt.js +0 -105
  120. package/bin/core-impl/select/numselect-prompt.d.ts +0 -7
  121. package/bin/core-impl/select/numselect-prompt.js +0 -115
  122. package/bin/core-impl/select/select-prompt.d.ts +0 -33
  123. package/bin/core-impl/select/select-prompt.js +0 -302
  124. package/bin/core-impl/select/toggle-prompt.d.ts +0 -5
  125. package/bin/core-impl/select/toggle-prompt.js +0 -208
  126. package/bin/core-impl/st-end/end.d.ts +0 -2
  127. package/bin/core-impl/st-end/end.js +0 -42
  128. package/bin/core-impl/st-end/start.d.ts +0 -17
  129. package/bin/core-impl/st-end/start.js +0 -66
  130. package/bin/core-impl/task/progress.d.ts +0 -2
  131. package/bin/core-impl/task/progress.js +0 -57
  132. package/bin/core-impl/task/spinner.d.ts +0 -15
  133. package/bin/core-impl/task/spinner.js +0 -110
  134. package/bin/core-impl/utils/colorize.d.ts +0 -2
  135. package/bin/core-impl/utils/colorize.js +0 -134
  136. package/bin/core-impl/utils/errors.d.ts +0 -1
  137. package/bin/core-impl/utils/errors.js +0 -15
  138. package/bin/core-impl/utils/prevent.d.ts +0 -10
  139. package/bin/core-impl/utils/prevent.js +0 -69
  140. package/bin/core-impl/utils/prompt-end.d.ts +0 -8
  141. package/bin/core-impl/utils/prompt-end.js +0 -33
  142. package/bin/core-impl/utils/stream-text.d.ts +0 -18
  143. package/bin/core-impl/utils/stream-text.js +0 -136
  144. package/bin/core-impl/utils/system.d.ts +0 -6
  145. package/bin/core-impl/utils/system.js +0 -7
  146. package/bin/core-impl/utils/validate.d.ts +0 -22
  147. package/bin/core-impl/utils/validate.js +0 -17
  148. package/bin/core-impl/visual/animate/animate.d.ts +0 -14
  149. package/bin/core-impl/visual/animate/animate.js +0 -64
  150. package/bin/core-impl/visual/ascii-art/ascii-art.d.ts +0 -6
  151. package/bin/core-impl/visual/ascii-art/ascii-art.js +0 -12
  152. package/bin/core-types.d.ts +0 -434
  153. package/bin/main.d.ts +0 -41
  154. package/bin/main.js +0 -96
  155. /package/{bin/core-types.js → dist/plugin/types.js} +0 -0
@@ -0,0 +1,178 @@
1
+ import type { StandardSchemaV1 } from "@standard-schema/spec";
2
+ import type { GLOBAL_FLAGS } from "./global-flags.js";
3
+ export type { StandardSchemaV1 } from "@standard-schema/spec";
4
+ export type RenderResult = unknown;
5
+ export interface TuiRenderOptions {
6
+ exitOnCtrlC?: boolean;
7
+ targetFps?: number;
8
+ enableMouseMovement?: boolean;
9
+ [key: string]: unknown;
10
+ }
11
+ export interface RenderArgs<TFlags = Record<string, unknown>, TStore = {}> extends HandlerArgs<TFlags, TStore> {
12
+ command: Command<any, TStore>;
13
+ rendererOptions?: TuiRenderOptions;
14
+ }
15
+ export type RenderFunction<TFlags = Record<string, unknown>, TStore = {}> = (args: RenderArgs<TFlags, TStore>) => RenderResult;
16
+ /**
17
+ * CLI instance with plugin type information
18
+ */
19
+ export interface CLI<TStore = {}> {
20
+ /**
21
+ * Initialize the CLI (load config, etc)
22
+ */
23
+ init(): Promise<void>;
24
+ /**
25
+ * Run the CLI with given arguments
26
+ */
27
+ run(argv?: string[]): Promise<void>;
28
+ /**
29
+ * Execute a command programmatically
30
+ */
31
+ execute(commandName: string, args?: string[]): Promise<void>;
32
+ execute<T extends keyof RegisteredCommands>(commandName: T, options: CommandOptions<T>): Promise<void>;
33
+ execute<T extends keyof RegisteredCommands>(commandName: T, args: string[], options: CommandOptions<T>): Promise<void>;
34
+ /**
35
+ * Add a global before hook that runs before command execution
36
+ * This provides a simple API for setup/initialization tasks
37
+ */
38
+ before(hook: BeforeHook<TStore>): void;
39
+ /**
40
+ * Add a global after hook that runs after command execution
41
+ */
42
+ after(hook: AfterHook<TStore>): void;
43
+ }
44
+ interface BaseCommand<TOptions extends Options = Options, TStore = {}, TName extends string = string> {
45
+ description: string;
46
+ options?: TOptions;
47
+ alias?: string | string[];
48
+ handler?: Handler<InferOptions<TOptions>, TStore, TName>;
49
+ render?: RenderFunction<InferOptions<TOptions>, TStore>;
50
+ }
51
+ export type Command<TOptions extends Options = Options, TStore = {}, TName extends string = string> = (BaseCommand<TOptions, TStore, TName> & {
52
+ handler: Handler<InferOptions<TOptions>, TStore, TName>;
53
+ }) | (BaseCommand<TOptions, TStore, TName> & {
54
+ render: RenderFunction<InferOptions<TOptions>, TStore>;
55
+ }) | (BaseCommand<TOptions, TStore, TName> & {
56
+ handler: Handler<InferOptions<TOptions>, TStore, TName>;
57
+ render: RenderFunction<InferOptions<TOptions>, TStore>;
58
+ }) | (BaseCommand<TOptions, TStore, TName> & {
59
+ handler?: never;
60
+ render?: never;
61
+ });
62
+ type InferSchema<T> = T extends StandardSchemaV1<any, infer Out> ? Out : never;
63
+ export type InferOptions<T extends Options> = {
64
+ [K in keyof T]: T[K] extends CLIOption<infer S> ? InferSchema<S> : never;
65
+ };
66
+ export type MergedOptions<TOptions extends Options> = typeof GLOBAL_FLAGS & TOptions;
67
+ export type InferMergedOptions<TOptions extends Options> = InferOptions<MergedOptions<TOptions>>;
68
+ export type Handler<TFlags = Record<string, unknown>, TStore = {}, TCommandName extends string = string> = (args: HandlerArgs<TFlags, TStore, TCommandName>) => void | Promise<void>;
69
+ export interface HandlerArgs<TFlags = Record<string, unknown>, TStore = {}, TCommandName extends string = string> {
70
+ flags: TFlags;
71
+ positional: string[];
72
+ shell: typeof Bun.$;
73
+ env: typeof process.env;
74
+ cwd: string;
75
+ prompt: typeof import("@reliverse/rempts-utils").prompt;
76
+ spinner: typeof import("@reliverse/rempts-utils").spinner;
77
+ colors: typeof import("@reliverse/relico").relico;
78
+ context?: import("./plugin/types.js.js").CommandContext<any>;
79
+ hooks?: Record<string, any>;
80
+ terminal: TerminalInfo;
81
+ runtime: RuntimeInfo;
82
+ }
83
+ export interface TerminalInfo {
84
+ width: number;
85
+ height: number;
86
+ isInteractive: boolean;
87
+ isCI: boolean;
88
+ supportsColor: boolean;
89
+ supportsMouse: boolean;
90
+ }
91
+ export interface RuntimeInfo {
92
+ startTime: number;
93
+ args: string[];
94
+ command: string;
95
+ }
96
+ export interface CLIOption<S extends StandardSchemaV1 = StandardSchemaV1> {
97
+ schema: S;
98
+ short?: string;
99
+ description?: string;
100
+ default?: unknown;
101
+ }
102
+ export type Options = Record<string, CLIOption<any>>;
103
+ export declare function defineCommand<TOptions extends Options = Options, TStore = {}>(command: Command<TOptions, TStore>): Command<TOptions, TStore>;
104
+ import type { RemptsConfig } from "./config.js";
105
+ export type { RemptsConfig } from "./config.js";
106
+ export { remptsConfigSchema } from "./config.js";
107
+ export type PluginConfig = import("./plugin/types.js.js").PluginConfig;
108
+ export type RegisteredCommands = Record<string, Command<any, any, any>>;
109
+ /**
110
+ * Get command options type from registered commands
111
+ * Uses Standard Schema's InferOutput to extract types from schemas
112
+ */
113
+ export type CommandOptions<T extends keyof RegisteredCommands> = RegisteredCommands[T] extends Command<infer TOptions, any, any> ? InferOptions<TOptions> : never;
114
+ export type CommandFlags<TCommand extends Command<any, any, any>> = TCommand extends Command<infer TOptions, any, any> ? InferOptions<TOptions> : never;
115
+ /**
116
+ * Get all registered command names
117
+ */
118
+ export type RegisteredCommandNames = keyof RegisteredCommands;
119
+ export type ResolvedConfig = Required<Omit<RemptsConfig, "build" | "dev" | "test" | "workspace" | "release">> & {
120
+ build: NonNullable<RemptsConfig["build"]>;
121
+ dev: NonNullable<RemptsConfig["dev"]>;
122
+ test: NonNullable<RemptsConfig["test"]>;
123
+ workspace: NonNullable<RemptsConfig["workspace"]>;
124
+ release: NonNullable<RemptsConfig["release"]>;
125
+ };
126
+ /**
127
+ * Hook context passed to before/after hooks
128
+ */
129
+ export interface HookContext<TStore = {}> {
130
+ /** Global flags parsed from command line */
131
+ flags: Record<string, unknown>;
132
+ /** Store from plugins (if any) */
133
+ store: TStore;
134
+ /** Environment variables */
135
+ env: typeof process.env;
136
+ /** Current working directory */
137
+ cwd: string;
138
+ /** Set data that will be available to command handlers */
139
+ set(key: string, value: any): void;
140
+ /** Get data that was set by hooks */
141
+ get(key: string): any;
142
+ }
143
+ /**
144
+ * Before hook function type
145
+ */
146
+ export type BeforeHook<TStore = {}> = (context: HookContext<TStore>) => void | Promise<void>;
147
+ /**
148
+ * After hook function type
149
+ */
150
+ export type AfterHook<TStore = {}> = (context: HookContext<TStore> & {
151
+ exitCode: number;
152
+ error?: Error;
153
+ }) => void | Promise<void>;
154
+ /**
155
+ * Rich validation error with context information
156
+ */
157
+ export declare class RemptsValidationError extends Error {
158
+ readonly context: {
159
+ option: string;
160
+ value: unknown;
161
+ command: string;
162
+ expectedType: string;
163
+ hint?: string;
164
+ };
165
+ constructor(message: string, context: {
166
+ option: string;
167
+ value: unknown;
168
+ command: string;
169
+ expectedType: string;
170
+ hint?: string;
171
+ });
172
+ toString(): string;
173
+ }
174
+ export declare function option<S extends StandardSchemaV1>(schema: S, metadata?: {
175
+ short?: string;
176
+ description?: string;
177
+ default?: unknown;
178
+ }): CLIOption<S>;
package/dist/types.js ADDED
@@ -0,0 +1,25 @@
1
+ export function defineCommand(command) {
2
+ return command;
3
+ }
4
+ export { remptsConfigSchema } from "./config.js";
5
+ export class RemptsValidationError extends Error {
6
+ constructor(message, context) {
7
+ super(message);
8
+ this.context = context;
9
+ this.name = "RemptsValidationError";
10
+ }
11
+ toString() {
12
+ return `${this.name}: Invalid option '${this.context.option}' for command '${this.context.command}'
13
+
14
+ Expected: ${this.context.expectedType}
15
+ Received: ${typeof this.context.value} (${JSON.stringify(this.context.value)})
16
+ ${this.context.hint ? `
17
+ Hint: ${this.context.hint}` : ""}`;
18
+ }
19
+ }
20
+ export function option(schema, metadata) {
21
+ return {
22
+ schema,
23
+ ...metadata
24
+ };
25
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Simple logger implementation
3
+ */
4
+ export interface Logger {
5
+ info(message: string, ...args: any[]): void;
6
+ warn(message: string, ...args: any[]): void;
7
+ error(message: string, ...args: any[]): void;
8
+ debug(message: string, ...args: any[]): void;
9
+ }
10
+ export declare function createLogger(namespace: string): Logger;
@@ -0,0 +1,27 @@
1
+ export function createLogger(namespace) {
2
+ const prefix = `[${namespace}]`;
3
+ const debugEnabled = process.env.dler_DEBUG === "true" || process.env.dler_DEBUG?.includes(namespace);
4
+ const silent = process.env.dler_SILENT === "true" || process.env.NODE_ENV === "test";
5
+ return {
6
+ info(message, ...args) {
7
+ if (!silent) {
8
+ console.log(prefix, message, ...args);
9
+ }
10
+ },
11
+ warn(message, ...args) {
12
+ if (!silent) {
13
+ console.warn(prefix, message, ...args);
14
+ }
15
+ },
16
+ error(message, ...args) {
17
+ if (!silent) {
18
+ console.error(prefix, message, ...args);
19
+ }
20
+ },
21
+ debug(message, ...args) {
22
+ if (debugEnabled && !silent) {
23
+ console.log(`${prefix} [DEBUG]`, message, ...args);
24
+ }
25
+ }
26
+ };
27
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Deep merge utility for configuration objects
3
+ */
4
+ /**
5
+ * Deep merge multiple objects
6
+ * Arrays are concatenated, objects are recursively merged
7
+ */
8
+ export declare function deepMerge<T = any>(...objects: Partial<T>[]): T;
9
+ /**
10
+ * Shallow merge multiple objects
11
+ * Last value wins for all properties
12
+ */
13
+ export declare function shallowMerge<T = any>(...objects: Partial<T>[]): T;
@@ -0,0 +1,25 @@
1
+ function isPlainObject(value) {
2
+ return value !== null && typeof value === "object" && value.constructor === Object && Object.prototype.toString.call(value) === "[object Object]";
3
+ }
4
+ export function deepMerge(...objects) {
5
+ const result = {};
6
+ for (const obj of objects) {
7
+ if (!obj) {
8
+ continue;
9
+ }
10
+ for (const [key, value] of Object.entries(obj)) {
11
+ const existing = result[key];
12
+ if (Array.isArray(value)) {
13
+ result[key] = Array.isArray(existing) ? [...existing, ...value] : [...value];
14
+ } else if (isPlainObject(value)) {
15
+ result[key] = isPlainObject(existing) ? deepMerge(existing, value) : { ...value };
16
+ } else {
17
+ result[key] = value;
18
+ }
19
+ }
20
+ }
21
+ return result;
22
+ }
23
+ export function shallowMerge(...objects) {
24
+ return Object.assign({}, ...objects);
25
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Utility exports
3
+ */
4
+ export type { Logger } from "./logger.js";
5
+ export { createLogger } from "./logger.js";
6
+ export { deepMerge, shallowMerge } from "./merge.js";
@@ -0,0 +1,2 @@
1
+ export { createLogger } from "./logger.js";
2
+ export { deepMerge, shallowMerge } from "./merge.js";
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Type utilities inspired by TanStack Router for advanced type manipulation
3
+ */
4
+ export type UnionToIntersection<T> = (T extends any ? (arg: T) => any : never) extends (arg: infer T) => any ? T : never;
5
+ export type Constrain<T, TConstraint, TDefault = TConstraint> = (T extends TConstraint ? T : never) | TDefault;
6
+ export type PickRequired<T> = {
7
+ [K in keyof T as undefined extends T[K] ? never : K]: T[K];
8
+ };
9
+ export type PickOptional<T> = {
10
+ [K in keyof T as undefined extends T[K] ? K : never]: T[K];
11
+ };
12
+ export type ExtractPrimitives<TUnion> = TUnion extends MergeAllPrimitive ? TUnion : TUnion extends object ? never : TUnion;
13
+ export type MergeAllPrimitive = readonly any[] | number | string | bigint | boolean | symbol | undefined | null;
14
+ export type ExtractObjects<TUnion> = TUnion extends MergeAllPrimitive ? never : TUnion;
15
+ export type PartialMergeAllObject<TUnion> = ExtractObjects<TUnion> extends infer TObj ? [TObj] extends [never] ? never : {
16
+ [TKey in TObj extends any ? keyof TObj : never]?: TObj extends any ? TKey extends keyof TObj ? TObj[TKey] : never : never;
17
+ } : never;
18
+ export type PartialMergeAll<TUnion> = ExtractPrimitives<TUnion> | PartialMergeAllObject<TUnion>;
19
+ export type MergeAllObjects<TUnion, TIntersected = UnionToIntersection<ExtractObjects<TUnion>>> = [
20
+ keyof TIntersected
21
+ ] extends [never] ? never : {
22
+ [TKey in keyof TIntersected]: TUnion extends any ? TUnion[TKey & keyof TUnion] : never;
23
+ };
24
+ export type MergeAll<TUnion> = MergeAllObjects<TUnion> | ExtractPrimitives<TUnion>;
25
+ export type NoInfer<T> = [T][T extends any ? 0 : never];
26
+ export type IsAny<TValue, TYesResult, TNoResult = TValue> = 1 extends 0 & TValue ? TYesResult : TNoResult;
27
+ export type PickAsRequired<TValue, TKey extends keyof TValue> = Omit<TValue, TKey> & Required<Pick<TValue, TKey>>;
28
+ export type WithoutEmpty<T> = T extends any ? ({} extends T ? never : T) : never;
29
+ export type Expand<T> = T extends object ? T extends infer O ? O extends Function ? O : {
30
+ [K in keyof O]: O[K];
31
+ } : never : T;
32
+ export type DeepPartial<T> = T extends object ? {
33
+ [P in keyof T]?: DeepPartial<T[P]>;
34
+ } : T;
35
+ export type MakeDifferenceOptional<TLeft, TRight> = keyof TLeft & keyof TRight extends never ? TRight : Omit<TRight, keyof TLeft & keyof TRight> & {
36
+ [K in keyof TLeft & keyof TRight]?: TRight[K];
37
+ };
38
+ export type IsUnion<T, U extends T = T> = (T extends any ? U extends T ? false : true : never) extends false ? false : true;
39
+ export type IsNonEmptyObject<T> = T extends object ? (keyof T extends never ? false : true) : false;
40
+ export type Assign<TLeft, TRight> = TLeft extends any ? TRight extends any ? IsNonEmptyObject<TLeft> extends false ? TRight : IsNonEmptyObject<TRight> extends false ? TLeft : keyof TLeft & keyof TRight extends never ? TLeft & TRight : Omit<TLeft, keyof TRight> & TRight : never : never;
41
+ export type IntersectAssign<TLeft, TRight> = TLeft extends any ? TRight extends any ? IsNonEmptyObject<TLeft> extends false ? TRight : IsNonEmptyObject<TRight> extends false ? TLeft : TRight & TLeft : never : never;
File without changes
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Runtime validation utilities for Rempts
3
+ */
4
+ import type { StandardSchemaV1 } from "@standard-schema/spec";
5
+ /**
6
+ * Validate a value against a schema at runtime
7
+ */
8
+ export declare function validateValue(value: unknown, schema: StandardSchemaV1, context: {
9
+ option: string;
10
+ command: string;
11
+ }): Promise<unknown>;
12
+ /**
13
+ * Validate multiple values against their schemas
14
+ */
15
+ export declare function validateValues(values: Record<string, unknown>, schemas: Record<string, StandardSchemaV1>, command: string): Promise<Record<string, unknown>>;
16
+ /**
17
+ * Check if a value matches a schema type
18
+ */
19
+ export declare function isValueOfType(value: unknown, expectedType: string): boolean;
20
+ /**
21
+ * Create a validator function from a schema
22
+ */
23
+ export declare function createValidator(schema: StandardSchemaV1): (value: unknown, context: {
24
+ option: string;
25
+ command: string;
26
+ }) => Promise<unknown>;
27
+ /**
28
+ * Batch validate multiple values
29
+ */
30
+ export declare function createBatchValidator(schemas: Record<string, StandardSchemaV1>): (values: Record<string, unknown>, command: string) => Promise<Record<string, unknown>>;
@@ -0,0 +1,121 @@
1
+ import { RemptsValidationError } from "./types.js";
2
+ export async function validateValue(value, schema, context) {
3
+ try {
4
+ const result = await schema["~standard"].validate(value);
5
+ if (result.issues && result.issues.length > 0) {
6
+ const issue = result.issues[0];
7
+ if (!issue) {
8
+ return value;
9
+ }
10
+ const expectedType = extractSchemaType(schema);
11
+ const hint = generateHint(schema, value);
12
+ throw new RemptsValidationError(`Invalid option '${context.option}': ${issue.message}`, {
13
+ option: context.option,
14
+ value,
15
+ command: context.command,
16
+ expectedType,
17
+ hint
18
+ });
19
+ }
20
+ return "value" in result ? result.value : value;
21
+ } catch (error) {
22
+ if (error instanceof RemptsValidationError) {
23
+ throw error;
24
+ }
25
+ throw new RemptsValidationError(`Validation failed for option '${context.option}': ${error}`, {
26
+ option: context.option,
27
+ value,
28
+ command: context.command,
29
+ expectedType: "unknown",
30
+ hint: "Check the value format and try again"
31
+ });
32
+ }
33
+ }
34
+ export async function validateValues(values, schemas, command) {
35
+ const results = {};
36
+ const errors = [];
37
+ for (const [key, value] of Object.entries(values)) {
38
+ const schema = schemas[key];
39
+ if (!schema) {
40
+ results[key] = value;
41
+ continue;
42
+ }
43
+ try {
44
+ results[key] = await validateValue(value, schema, {
45
+ option: key,
46
+ command
47
+ });
48
+ } catch (error) {
49
+ if (error instanceof RemptsValidationError) {
50
+ errors.push(error.toString());
51
+ } else {
52
+ errors.push(`Validation error for ${key}: ${error}`);
53
+ }
54
+ }
55
+ }
56
+ if (errors.length > 0) {
57
+ throw new Error(`Validation failed:
58
+ ${errors.join("\n")}`);
59
+ }
60
+ return results;
61
+ }
62
+ export function isValueOfType(value, expectedType) {
63
+ switch (expectedType) {
64
+ case "string":
65
+ return typeof value === "string";
66
+ case "number":
67
+ return typeof value === "number";
68
+ case "boolean":
69
+ return typeof value === "boolean";
70
+ case "array":
71
+ return Array.isArray(value);
72
+ case "object":
73
+ return typeof value === "object" && value !== null && !Array.isArray(value);
74
+ default:
75
+ return false;
76
+ }
77
+ }
78
+ function extractSchemaType(schema) {
79
+ if ("type" in schema && typeof schema.type === "string") {
80
+ return schema.type;
81
+ }
82
+ if ("enum" in schema) {
83
+ return "enum";
84
+ }
85
+ if ("items" in schema) {
86
+ return "array";
87
+ }
88
+ if ("properties" in schema) {
89
+ return "object";
90
+ }
91
+ if ("format" in schema) {
92
+ return "string";
93
+ }
94
+ return "unknown";
95
+ }
96
+ function generateHint(schema, value) {
97
+ const type = extractSchemaType(schema);
98
+ if (type === "boolean" && typeof value === "string") {
99
+ return "Use --flag or --no-flag for boolean options";
100
+ }
101
+ if (type === "number" && typeof value === "string") {
102
+ return "Provide a numeric value";
103
+ }
104
+ if (type === "array" && !Array.isArray(value)) {
105
+ return "Provide a comma-separated list of values";
106
+ }
107
+ if (type === "enum" && typeof value === "string") {
108
+ return "Choose from the available options";
109
+ }
110
+ return "";
111
+ }
112
+ export function createValidator(schema) {
113
+ return async (value, context) => {
114
+ return validateValue(value, schema, context);
115
+ };
116
+ }
117
+ export function createBatchValidator(schemas) {
118
+ return async (values, command) => {
119
+ return validateValues(values, schemas, command);
120
+ };
121
+ }
package/package.json CHANGED
@@ -1,58 +1,61 @@
1
1
  {
2
- "description": "@reliverse/prompts is your modern, type-safe toolkit for building delightful CLI experiences. It's fast, flexible, and built with developer joy in mind. Forget the clutter — this is how CLI should feel.",
3
- "license": "MIT",
4
2
  "name": "@reliverse/rempts-core",
5
- "type": "module",
6
- "version": "1.6.1",
7
- "author": "reliverse",
8
- "bugs": {
9
- "email": "blefnk@gmail.com",
10
- "url": "https://github.com/reliverse/prompts/issues"
11
- },
3
+ "version": "2.3.1",
4
+ "description": "Minimal, type-safe CLI framework for Bun",
12
5
  "keywords": [
13
- "reliverse",
14
- "prompts"
6
+ "bun",
7
+ "cli",
8
+ "command-line",
9
+ "framework",
10
+ "rempts",
11
+ "type-safe",
12
+ "typescript"
15
13
  ],
14
+ "homepage": "https://github.com/reliverse/dler#readme",
15
+ "bugs": {
16
+ "url": "https://github.com/reliverse/dler/issues"
17
+ },
18
+ "license": "MIT",
19
+ "author": "blefnk",
16
20
  "repository": {
17
21
  "type": "git",
18
- "url": "git+https://github.com/reliverse/prompts.git"
19
- },
20
- "dependencies": {
21
- "@figliolia/chalk-animation": "^1.0.4",
22
- "@reliverse/relico": "^1.1.0",
23
- "@reliverse/relinka": "^1.3.7",
24
- "@reliverse/runtime": "^1.0.3",
25
- "ansi-escapes": "^7.0.0",
26
- "c12": "^3.0.2",
27
- "cli-spinners": "^3.2.0",
28
- "detect-package-manager": "^3.0.2",
29
- "figlet": "^1.8.0",
30
- "fs-extra": "^11.3.0",
31
- "gradient-string": "^3.0.0",
32
- "log-update": "^6.1.0",
33
- "node-emoji": "^2.2.0",
34
- "ora": "^8.2.0",
35
- "pathe": "^2.0.3",
36
- "scule": "^1.3.0",
37
- "sisteransi": "^1.0.5",
38
- "terminal-kit": "^3.1.2",
39
- "terminal-size": "^4.0.0",
40
- "ts-regex-builder": "^1.8.2",
41
- "wrap-ansi": "^9.0.0"
42
- },
43
- "devDependencies": {},
44
- "exports": {
45
- ".": "./bin/main.js"
22
+ "url": "https://github.com/reliverse/dler.git",
23
+ "directory": "packages/core"
46
24
  },
47
25
  "files": [
48
- "bin",
49
- "package.json",
26
+ "dist",
50
27
  "README.md",
51
- "LICENSE"
28
+ "src"
52
29
  ],
53
- "main": "./bin/main.js",
54
- "module": "./bin/main.js",
30
+ "type": "module",
31
+ "module": "./src/mod.ts",
32
+ "types": "./src/mod.ts",
33
+ "exports": {
34
+ ".": {
35
+ "types": "./dist/mod.d.ts",
36
+ "import": "./dist/mod.js"
37
+ },
38
+ "./plugin": {
39
+ "types": "./dist/plugin/mod.d.ts",
40
+ "import": "./dist/plugin/mod.js"
41
+ },
42
+ "./utils": {
43
+ "types": "./dist/utils/mod.d.ts",
44
+ "import": "./dist/utils/mod.js"
45
+ }
46
+ },
55
47
  "publishConfig": {
56
48
  "access": "public"
49
+ },
50
+ "dependencies": {
51
+ "@reliverse/relico": "2.3.1",
52
+ "@reliverse/rempts-utils": "2.3.1",
53
+ "@standard-schema/spec": "^1.1.0",
54
+ "@standard-schema/utils": "^0.3.0",
55
+ "arktype": "^2.1.29",
56
+ "zustand": "^5.0.9"
57
+ },
58
+ "engines": {
59
+ "bun": ">=1.3.5"
57
60
  }
58
61
  }