mirror of
https://github.com/Kaelio/ktx.git
synced 2026-06-22 08:38:08 +02:00
feat(cli): redesign database scope picker for searchable schema-first setup (#203)
* feat: add searchable setup prompt pickers * fix: make snowflake scope discovery single query * fix: make bigquery table discovery schema scoped * fix: honor mysql and clickhouse database scope * feat: wire schema scope discovery for all relational setup drivers * feat: add schema-first database scope picker * test: update setup prompt stubs for type-check * docs: document database scope picker fields * Fix database setup edit preservation --------- Co-authored-by: Andrey Avtomonov <7889985+andreybavt@users.noreply.github.com>
This commit is contained in:
parent
fd2ba62d92
commit
c87d14a554
30 changed files with 1530 additions and 331 deletions
|
|
@ -1,5 +1,7 @@
|
|||
import type { Writable } from 'node:stream';
|
||||
import {
|
||||
autocomplete,
|
||||
autocompleteMultiselect,
|
||||
cancel,
|
||||
confirm,
|
||||
intro,
|
||||
|
|
@ -38,6 +40,22 @@ interface KtxSetupMultiselectOptions<Value extends string = string> {
|
|||
cursorAt?: Value;
|
||||
}
|
||||
|
||||
interface KtxSetupAutocompleteOptions<Value extends string = string> {
|
||||
message: string;
|
||||
options: Array<KtxSetupPromptOption<Value>>;
|
||||
placeholder?: string;
|
||||
maxItems?: number;
|
||||
}
|
||||
|
||||
interface KtxSetupAutocompleteMultiselectOptions<Value extends string = string> {
|
||||
message: string;
|
||||
options: Array<KtxSetupPromptOption<Value>>;
|
||||
placeholder?: string;
|
||||
required?: boolean;
|
||||
maxItems?: number;
|
||||
initialValues?: Value[];
|
||||
}
|
||||
|
||||
interface KtxSetupTextOptions {
|
||||
message: string;
|
||||
placeholder?: string;
|
||||
|
|
@ -53,6 +71,8 @@ interface KtxSetupPasswordOptions {
|
|||
export interface KtxSetupPromptAdapter {
|
||||
select(options: KtxSetupSelectOptions): Promise<string>;
|
||||
multiselect(options: KtxSetupMultiselectOptions): Promise<string[]>;
|
||||
autocomplete(options: KtxSetupAutocompleteOptions): Promise<string>;
|
||||
autocompleteMultiselect(options: KtxSetupAutocompleteMultiselectOptions): Promise<string[]>;
|
||||
text(options: KtxSetupTextOptions): Promise<string | undefined>;
|
||||
password(options: KtxSetupPasswordOptions): Promise<string | undefined>;
|
||||
cancel(message: string): void;
|
||||
|
|
@ -117,6 +137,50 @@ export function createKtxSetupPromptAdapter(options: KtxSetupPromptAdapterOption
|
|||
return selected;
|
||||
}
|
||||
},
|
||||
async autocomplete(promptOptions) {
|
||||
const value = await withSetupInterruptConfirmation(() =>
|
||||
autocomplete(withMenuOptionsSpacing(promptOptions)),
|
||||
);
|
||||
if (isCancel(value)) {
|
||||
if (cancelOnSelectCancel) {
|
||||
cancel(cancelMessage);
|
||||
}
|
||||
return options.selectCancelValue;
|
||||
}
|
||||
return String(value);
|
||||
},
|
||||
async autocompleteMultiselect(promptOptions) {
|
||||
while (true) {
|
||||
const value = await withSetupInterruptConfirmation(() =>
|
||||
autocompleteMultiselect(withMenuOptionsSpacing(promptOptions)),
|
||||
);
|
||||
if (isCancel(value)) {
|
||||
if (cancelOnMultiselectCancel) {
|
||||
cancel(cancelMessage);
|
||||
}
|
||||
return [multiselectCancelValue];
|
||||
}
|
||||
const selected = [...value].map(String);
|
||||
if (
|
||||
selected.length === 0 &&
|
||||
!promptOptions.required &&
|
||||
options.confirmEmptyOptionalMultiselect === true
|
||||
) {
|
||||
const skipConfirmed = await confirm({
|
||||
message: 'Nothing selected. Skip this step?',
|
||||
initialValue: false,
|
||||
});
|
||||
if (isCancel(skipConfirmed)) {
|
||||
cancel(cancelMessage);
|
||||
return [multiselectCancelValue];
|
||||
}
|
||||
if (!skipConfirmed) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return selected;
|
||||
}
|
||||
},
|
||||
async text(promptOptions) {
|
||||
const value = await withSetupInterruptConfirmation(() =>
|
||||
text({ ...promptOptions, message: withTextInputNavigation(promptOptions.message) }),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue