Skip to content

Commit

Permalink
Start re-implementation of inquirer package control flow on top of th…
Browse files Browse the repository at this point in the history
…e new prompts
  • Loading branch information
SBoudrias committed Oct 24, 2022
1 parent f532af8 commit 70f71f2
Show file tree
Hide file tree
Showing 5 changed files with 198 additions and 0 deletions.
5 changes: 5 additions & 0 deletions packages/canary/.eslintrc.json
@@ -0,0 +1,5 @@
{
"rules": {
"no-await-in-loop": "off"
}
}
35 changes: 35 additions & 0 deletions packages/canary/demo.ts
@@ -0,0 +1,35 @@
import inquirer from './src/index.js';

const answers = await inquirer.prompt([
{
type: 'input',
name: 'first_name',
message: "What's your first name",
},
{
type: 'select',
name: 'ask_last_name',
message: 'Are you willing to share your last name',
choices: [
{ value: '1', name: 'Yes' },
{ value: '', name: 'No' },
],
},
{
type: 'input',
name: 'last_name',
when: (answers) => Boolean(answers['ask_last_name']),
message: "What's your last name",
},
{
type: 'input',
name: 'phone',
message: "What's your phone number?",
filter(answer: string): string {
// TODO: What's the multi match flag again?
return answer.replace(/[^\d]+/, '');
},
},
]);

console.log(answers);
74 changes: 74 additions & 0 deletions packages/canary/package.json
@@ -0,0 +1,74 @@
{
"name": "@inquirer/canary",
"type": "module",
"version": "0.0.27-alpha.0",
"description": "Inquirer input text prompt",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"files": [
"dist/"
],
"repository": "SBoudrias/Inquirer.js",
"keywords": [
"answer",
"answers",
"ask",
"base",
"cli",
"cli",
"command",
"command-line",
"confirm",
"enquirer",
"generate",
"generator",
"hyper",
"input",
"inquire",
"inquirer",
"interface",
"iterm",
"javascript",
"menu",
"node",
"nodejs",
"prompt",
"promptly",
"prompts",
"question",
"readline",
"scaffold",
"scaffolder",
"scaffolding",
"stdin",
"stdout",
"terminal",
"tty",
"ui",
"yeoman",
"yo",
"zsh"
],
"author": "Simon Boudrias <admin@simonboudrias.com>",
"license": "MIT",
"homepage": "https://github.com/SBoudrias/Inquirer.js",
"dependencies": {
"@inquirer/checkbox": "^0.0.30-alpha.0",
"@inquirer/confirm": "^0.0.28-alpha.0",
"@inquirer/core": "^0.0.30-alpha.0",
"@inquirer/editor": "^0.0.21-alpha.0",
"@inquirer/expand": "^0.0.28-alpha.0",
"@inquirer/input": "^0.0.28-alpha.0",
"@inquirer/password": "^0.0.28-alpha.0",
"@inquirer/rawlist": "^0.0.11-alpha.0",
"@inquirer/select": "^0.0.29-alpha.0",
"@inquirer/type": "^0.0.4-alpha.0",
"lodash": "^4.17.21"
},
"scripts": {
"tsc": "tsc"
},
"publishConfig": {
"access": "public"
}
}
77 changes: 77 additions & 0 deletions packages/canary/src/index.ts
@@ -0,0 +1,77 @@
import input from '@inquirer/input';
import select from '@inquirer/select';
import type { Prompt } from '@inquirer/core';
import type { Context } from '@inquirer/type';

type AsyncValue<Value> = Value | Promise<Value>;

function createPromptModule() {
const promptStore = {
input,
select,
};

type GetPrompt<U extends keyof typeof promptStore> = typeof promptStore[U];
type GetAnswerType<U extends keyof typeof promptStore> = GetPrompt<U> extends Prompt<
infer Answer,
any
>
? Answer
: never;
type GetPromptConfig<U extends keyof typeof promptStore> = GetPrompt<U> extends Prompt<
any,
infer Config
>
? Config
: never;

type Answers = Record<string, unknown>;
type ControlFlowConfig<U extends keyof typeof promptStore> = {
name: string;
when?: (answers: Answers) => boolean | Promise<boolean>;
filter?: (answer: GetAnswerType<U>, answers: Answers) => AsyncValue<GetAnswerType<U>>;
};
type PromptNameToFullConfig<U extends keyof typeof promptStore> = U extends any
? ControlFlowConfig<U> & GetPromptConfig<U> & { type: U }
: never;

async function prompt(
config:
| PromptNameToFullConfig<keyof typeof promptStore>
| PromptNameToFullConfig<keyof typeof promptStore>[],
context?: Context
) {
const answers: Answers = {};
const promptSeries = Array.isArray(config) ? config : [config];

for (const promptConfig of promptSeries) {
const { type, name, when, filter, ...configRest } = promptConfig;
const promptFn = promptStore[type];

if (when != null && !(await when(answers))) {
continue;
}

const answer = await promptFn(configRest as GetPromptConfig<typeof type>, context);
answers[name] = filter ? await filter(answer, answers) : answer;
}

return answers;
}

function registerPrompt(name: string, promptFn: Prompt<unknown, unknown>) {
// @ts-ignore: To fix later
promptStore[name] = promptFn;
}

return {
prompt,
registerPrompt,
createPromptModule,
};
}

const inquirer = createPromptModule();
export default inquirer;

export { createPromptModule, input, select };
7 changes: 7 additions & 0 deletions packages/canary/tsconfig.json
@@ -0,0 +1,7 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist"
},
"include": ["./src"]
}

0 comments on commit 70f71f2

Please sign in to comment.