From fcd6a8bdff4fc0174594d3c3574329b63aa0d985 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Thu, 20 Oct 2022 19:00:51 +0200 Subject: [PATCH 1/2] init refactor CLI package --- packages/cli/src/commands/build.ts | 14 ++--- packages/cli/src/commands/codegen.ts | 14 ++--- packages/cli/src/commands/create.ts | 49 ++++++++++----- packages/cli/src/commands/deploy.ts | 6 +- packages/cli/src/commands/docgen.ts | 33 +++++----- packages/cli/src/commands/index.ts | 40 ++++++++++++- packages/cli/src/commands/infra.ts | 23 +++---- packages/cli/src/commands/manifest.ts | 28 +++++---- packages/cli/src/commands/run.ts | 14 ++--- packages/cli/src/commands/types.ts | 15 +++++ packages/cli/src/index.ts | 21 +------ packages/js/cli-api/src/commands.ts | 60 ++++++++++++++----- .../cli-api/src/{utils => }/declarations.d.ts | 0 packages/js/cli-api/src/utils/index.ts | 1 - .../js/cli-api/src/utils/internal-types.ts | 34 ----------- todo | 14 +++++ 16 files changed, 212 insertions(+), 154 deletions(-) rename packages/js/cli-api/src/{utils => }/declarations.d.ts (100%) delete mode 100644 packages/js/cli-api/src/utils/index.ts delete mode 100644 packages/js/cli-api/src/utils/internal-types.ts create mode 100644 todo diff --git a/packages/cli/src/commands/build.ts b/packages/cli/src/commands/build.ts index a9aa8994f4..6fa177217a 100644 --- a/packages/cli/src/commands/build.ts +++ b/packages/cli/src/commands/build.ts @@ -1,4 +1,4 @@ -import { Command, Program } from "./types"; +import { Command, Program, BaseCommandOptions } from "./types"; import { createLogger } from "./utils/createLogger"; import { Compiler, @@ -24,7 +24,7 @@ import { import path from "path"; import readline from "readline"; -import { PolywrapClient, PolywrapClientConfig } from "@polywrap/client-js"; +import { PolywrapClient } from "@polywrap/client-js"; import { PolywrapManifest } from "@polywrap/polywrap-manifest-types-js"; const defaultOutputDir = "./build"; @@ -33,15 +33,13 @@ const strategyStr = intlMsg.commands_build_options_s_strategy(); const defaultManifestStr = defaultPolywrapManifest.join(" | "); const pathStr = intlMsg.commands_build_options_o_path(); -export type BuildCommandOptions = { +export interface BuildCommandOptions extends BaseCommandOptions { manifestFile: string; outputDir: string; - clientConfig: Partial; + clientConfig: string; skipCodegen?: boolean; watch?: boolean; strategy: SupportedStrategies; - verbose?: boolean; - quiet?: boolean; }; export const build: Command = { @@ -82,7 +80,6 @@ export const build: Command = { options.manifestFile, defaultPolywrapManifest ), - clientConfig: await parseClientConfigOption(options.clientConfig), outputDir: parseDirOption(options.outputDir, defaultOutputDir), strategy: options.strategy, }); @@ -139,7 +136,8 @@ async function run(options: BuildCommandOptions) { const logger = createLogger({ verbose, quiet }); // Get Client - const client = new PolywrapClient(clientConfig); + const config = await parseClientConfigOption(clientConfig); + const client = new PolywrapClient(config); const project = new PolywrapProject({ rootDir: path.dirname(manifestFile), diff --git a/packages/cli/src/commands/codegen.ts b/packages/cli/src/commands/codegen.ts index ba9d2e6215..70d1947780 100644 --- a/packages/cli/src/commands/codegen.ts +++ b/packages/cli/src/commands/codegen.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import { Command, Program } from "./types"; +import { Command, Program, BaseCommandOptions } from "./types"; import { createLogger } from "./utils/createLogger"; import { CodeGenerator, @@ -17,7 +17,7 @@ import { } from "../lib"; import { ScriptCodegenerator } from "../lib/codegen/ScriptCodeGenerator"; -import { PolywrapClient, PolywrapClientConfig } from "@polywrap/client-js"; +import { PolywrapClient } from "@polywrap/client-js"; import path from "path"; import fs from "fs"; @@ -27,14 +27,12 @@ const defaultPublishDir = "./build"; const pathStr = intlMsg.commands_codegen_options_o_path(); const defaultManifestStr = defaultPolywrapManifest.join(" | "); -export type CodegenCommandOptions = { +export interface CodegenCommandOptions extends BaseCommandOptions { manifestFile: string; codegenDir: string; publishDir: string; script?: string; - clientConfig: Partial; - verbose?: boolean; - quiet?: boolean; + clientConfig: string; }; export const codegen: Command = { @@ -74,7 +72,6 @@ export const codegen: Command = { .action(async (options) => { await run({ ...options, - clientConfig: await parseClientConfigOption(options.clientConfig), codegenDir: parseDirOption(options.codegenDir, defaultCodegenDir), script: parseCodegenScriptOption(options.script), manifestFile: parseManifestFileOption( @@ -100,7 +97,8 @@ async function run(options: CodegenCommandOptions) { const logger = createLogger({ verbose, quiet }); // Get Client - const client = new PolywrapClient(clientConfig); + const config = await parseClientConfigOption(clientConfig); + const client = new PolywrapClient(config); const project = await getProjectFromManifest(manifestFile, logger); diff --git a/packages/cli/src/commands/create.ts b/packages/cli/src/commands/create.ts index b80d8adeeb..ed7e395162 100644 --- a/packages/cli/src/commands/create.ts +++ b/packages/cli/src/commands/create.ts @@ -1,4 +1,4 @@ -import { Command, Program } from "./types"; +import { Command, Program, BaseCommandOptions } from "./types"; import { createLogger } from "./utils/createLogger"; import { generateProjectTemplate, intlMsg } from "../lib"; @@ -31,12 +31,21 @@ type SupportedLangs = | SupportedAppLangs | SupportedPluginLangs; -export type CreateCommandOptions = { +export interface CreateCommandOptions< + TLangs extends SupportedLangs +> extends BaseCommandOptions { + language: TLangs; + name: string; outputDir?: string; - verbose?: boolean; - quiet?: boolean; }; +export type CreateAppCommandOptions = + CreateCommandOptions; +export type CreatePluginCommandOptions = + CreateCommandOptions; +export type CreateWasmCommandOptions = + CreateCommandOptions; + export const create: Command = { setup: (program: Program) => { const createCommand = program @@ -61,8 +70,12 @@ export const create: Command = { ) .option("-v, --verbose", intlMsg.commands_common_options_verbose()) .option("-q, --quiet", intlMsg.commands_common_options_quiet()) - .action(async (langStr, nameStr, options) => { - await run("wasm", langStr, nameStr, options); + .action(async (language, name, options) => { + await run("wasm", { + ...options, + language, + name, + }); }); createCommand @@ -82,8 +95,12 @@ export const create: Command = { ) .option("-v, --verbose", intlMsg.commands_common_options_verbose()) .option("-q, --quiet", intlMsg.commands_common_options_quiet()) - .action(async (langStr, nameStr, options) => { - await run("app", langStr, nameStr, options); + .action(async (language, name, options) => { + await run("app", { + ...options, + language, + name + }); }); createCommand @@ -103,19 +120,21 @@ export const create: Command = { ) .option("-v, --verbose", intlMsg.commands_common_options_verbose()) .option("-q, --quiet", intlMsg.commands_common_options_quiet()) - .action(async (langStr, nameStr, options) => { - await run("plugin", langStr, nameStr, options); + .action(async (language, name, options) => { + await run("plugin", { + ...options, + language, + name + }); }); }, }; async function run( command: ProjectType, - lang: SupportedLangs, - name: string, - options: CreateCommandOptions + options: CreateCommandOptions ) { - const { outputDir, verbose, quiet } = options; + const { language, name, outputDir, verbose, quiet } = options; const logger = createLogger({ verbose, quiet }); const projectDir = path.resolve(outputDir ? `${outputDir}/${name}` : name); @@ -143,7 +162,7 @@ async function run( } } - await generateProjectTemplate(command, lang, projectDir) + await generateProjectTemplate(command, language, projectDir) .then(() => { let readyMessage; if (command === "wasm") { diff --git a/packages/cli/src/commands/deploy.ts b/packages/cli/src/commands/deploy.ts index 853f733b85..26117401dc 100644 --- a/packages/cli/src/commands/deploy.ts +++ b/packages/cli/src/commands/deploy.ts @@ -1,5 +1,5 @@ /* eslint-disable prefer-const */ -import { Command, Program } from "./types"; +import { Command, Program, BaseCommandOptions } from "./types"; import { createLogger } from "./utils/createLogger"; import { defaultPolywrapManifest, @@ -20,11 +20,9 @@ import { validate } from "jsonschema"; const defaultManifestStr = defaultPolywrapManifest.join(" | "); const pathStr = intlMsg.commands_deploy_options_o_path(); -export type DeployCommandOptions = { +export interface DeployCommandOptions extends BaseCommandOptions { manifestFile: string; outputFile?: string; - verbose?: boolean; - quiet?: boolean; }; type ManifestJob = DeployManifest["jobs"][number]; diff --git a/packages/cli/src/commands/docgen.ts b/packages/cli/src/commands/docgen.ts index 06e517f14d..a5759c323f 100644 --- a/packages/cli/src/commands/docgen.ts +++ b/packages/cli/src/commands/docgen.ts @@ -9,14 +9,14 @@ import { defaultProjectManifestFiles, getProjectFromManifest, } from "../lib"; -import { Command, Program } from "./types"; +import { Command, Program, BaseCommandOptions } from "./types"; import { createLogger } from "./utils/createLogger"; import { scriptPath as docusaurusScriptPath } from "../lib/docgen/docusaurus"; import { scriptPath as jsdocScriptPath } from "../lib/docgen/jsdoc"; import { scriptPath as schemaScriptPath } from "../lib/docgen/schema"; import { ScriptCodegenerator } from "../lib/codegen/ScriptCodeGenerator"; -import { PolywrapClient, PolywrapClientConfig } from "@polywrap/client-js"; +import { PolywrapClient } from "@polywrap/client-js"; import chalk from "chalk"; import { Argument } from "commander"; @@ -29,21 +29,20 @@ const commandToPathMap: Record = { const defaultDocgenDir = "./docs"; const pathStr = intlMsg.commands_codegen_options_o_path(); -export type DocgenCommandOptions = { - manifestFile: string; - docgenDir: string; - clientConfig: Partial; - imports: boolean; - verbose?: boolean; - quiet?: boolean; -}; - export enum DocgenActions { SCHEMA = "schema", DOCUSAURUS = "docusaurus", JSDOC = "jsdoc", } +export interface DocgenCommandOptions extends BaseCommandOptions { + action: DocgenActions; + manifestFile: string; + docgenDir: string; + clientConfig: string; + imports: boolean; +}; + const argumentsDescription = ` ${chalk.bold( DocgenActions.SCHEMA @@ -94,21 +93,22 @@ export const docgen: Command = { .option("-v, --verbose", intlMsg.commands_common_options_verbose()) .option("-q, --quiet", intlMsg.commands_common_options_quiet()) .action(async (action, options) => { - await run(action, { + await run({ ...options, + action, manifestFile: parseManifestFileOption( options.manifestFile, defaultProjectManifestFiles ), docgenDir: parseDirOption(options.docgenDir, defaultDocgenDir), - clientConfig: await parseClientConfigOption(options.clientConfig), }); }); }, }; -async function run(command: DocgenActions, options: DocgenCommandOptions) { +async function run(options: DocgenCommandOptions) { const { + action, manifestFile, docgenDir, clientConfig, @@ -133,9 +133,10 @@ async function run(command: DocgenActions, options: DocgenCommandOptions) { await project.validate(); // Resolve custom script - const customScript = require.resolve(commandToPathMap[command]); + const customScript = require.resolve(commandToPathMap[action]); - const client = new PolywrapClient(clientConfig); + const config = await parseClientConfigOption(clientConfig); + const client = new PolywrapClient(config); const schemaComposer = new SchemaComposer({ project, diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index 679a6877ff..ab585087e7 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -2,7 +2,43 @@ export * from "./build"; export * from "./codegen"; export * from "./create"; export * from "./deploy"; -export * from "./infra"; -export * from "./run"; export * from "./docgen"; +export * from "./infra"; export * from "./manifest"; +export * from "./run"; +export * from "./types"; + +import { CommandOptionMappings } from "./types"; +import { BuildCommandOptions } from "./build"; +import { CodegenCommandOptions } from "./codegen"; +import { + CreateAppCommandOptions, + CreatePluginCommandOptions, + CreateWasmCommandOptions +} from "./create"; +import { DeployCommandOptions } from "./deploy"; +import { DocgenCommandOptions } from "./docgen"; +import { InfraCommandOptions } from "./infra"; +import { + ManifestSchemaCommandOptions, + ManifestMigrateCommandOptions +} from "./manifest"; +import { RunCommandOptions } from "./run"; + +export interface CommandOptions extends CommandOptionMappings { + "build": BuildCommandOptions; + "codegen": CodegenCommandOptions; + "create": { + "app": CreateAppCommandOptions; + "plugin": CreatePluginCommandOptions; + "wasm": CreateWasmCommandOptions; + }; + "deploy": DeployCommandOptions; + "docgen": DocgenCommandOptions; + "infra": InfraCommandOptions; + "manifest": { + "migrate": ManifestMigrateCommandOptions; + "schema": ManifestSchemaCommandOptions; + }; + "run": RunCommandOptions; +}; diff --git a/packages/cli/src/commands/infra.ts b/packages/cli/src/commands/infra.ts index 313347e63a..47fc94875e 100644 --- a/packages/cli/src/commands/infra.ts +++ b/packages/cli/src/commands/infra.ts @@ -6,7 +6,7 @@ import { resolvePathIfExists, } from "../lib"; import { createLogger } from "./utils/createLogger"; -import { Command, Program } from "./types"; +import { Command, Program, BaseCommandOptions } from "./types"; import { InfraManifest } from "@polywrap/polywrap-manifest-types-js"; import path from "path"; @@ -15,13 +15,6 @@ import chalk from "chalk"; import yaml from "yaml"; import { readdirSync } from "fs"; -export type InfraCommandOptions = { - manifestFile: string; - modules?: string[]; - verbose?: boolean; - quiet?: boolean; -}; - export enum InfraActions { UP = "up", DOWN = "down", @@ -29,6 +22,12 @@ export enum InfraActions { CONFIG = "config", } +export interface InfraCommandOptions extends BaseCommandOptions { + action: InfraActions; + manifestFile: string; + modules?: string[]; +}; + const DEFAULT_MODULES_PATH = path.join( __dirname, "..", @@ -80,7 +79,10 @@ export const infra: Command = { .option("-v, --verbose", intlMsg.commands_common_options_verbose()) .option("-q, --quiet", intlMsg.commands_common_options_quiet()) .action(async (action, options) => { - await run(action, options); + await run({ + ...options, + action + }); }); }, }; @@ -94,10 +96,9 @@ Default Modules: \n${readdirSync(DEFAULT_MODULES_PATH) Example: 'polywrap infra up --modules=eth-ens-ipfs'.`; async function run( - action: InfraActions, options: InfraCommandOptions ): Promise { - const { modules, verbose, quiet, manifestFile } = options; + const { action, modules, verbose, quiet, manifestFile } = options; const logger = createLogger({ verbose, quiet }); diff --git a/packages/cli/src/commands/manifest.ts b/packages/cli/src/commands/manifest.ts index 825ac83e7a..9781ec1d71 100644 --- a/packages/cli/src/commands/manifest.ts +++ b/packages/cli/src/commands/manifest.ts @@ -1,4 +1,4 @@ -import { Argument, Command, Program } from "./types"; +import { Argument, Command, Program, BaseCommandOptions } from "./types"; import { createLogger } from "./utils/createLogger"; import { defaultBuildManifest, @@ -76,18 +76,16 @@ const manifestTypes = [ ] as const; export type ManifestType = typeof manifestTypes[number]; -export type ManifestSchemaCommandOptions = { +export interface ManifestSchemaCommandOptions extends BaseCommandOptions { + type: ManifestType; raw: boolean; manifestFile: ManifestType; - verbose?: boolean; - quiet?: boolean; }; -export type ManifestMigrateCommandOptions = { +export interface ManifestMigrateCommandOptions extends BaseCommandOptions { + type: ManifestType; manifestFile: string; format: string; - verbose?: boolean; - quiet?: boolean; }; export const manifest: Command = { @@ -124,7 +122,10 @@ export const manifest: Command = { .option("-v, --verbose", intlMsg.commands_common_options_verbose()) .option("-q, --quiet", intlMsg.commands_common_options_quiet()) .action(async (type, options) => { - await runSchemaCommand(type, options); + await runSchemaCommand({ + ...options, + type + }); }); manifestCommand @@ -153,16 +154,18 @@ export const manifest: Command = { .option("-v, --verbose", intlMsg.commands_common_options_verbose()) .option("-q, --quiet", intlMsg.commands_common_options_quiet()) .action(async (type, options) => { - await runMigrateCommand(type, options); + await runMigrateCommand({ + ...options, + type + }); }); }, }; export const runSchemaCommand = async ( - type: ManifestType, options: ManifestSchemaCommandOptions ): Promise => { - const { verbose, quiet } = options; + const { type, verbose, quiet } = options; const logger = createLogger({ verbose, quiet }); let manifestfile = ""; @@ -367,10 +370,9 @@ export const runSchemaCommand = async ( }; const runMigrateCommand = async ( - type: ManifestType, options: ManifestMigrateCommandOptions ) => { - const { verbose, quiet } = options; + const { type, verbose, quiet } = options; const logger = createLogger({ verbose, quiet }); let manifestFile = ""; let manifestString: string; diff --git a/packages/cli/src/commands/run.ts b/packages/cli/src/commands/run.ts index 908d51ddab..062e65e9ca 100644 --- a/packages/cli/src/commands/run.ts +++ b/packages/cli/src/commands/run.ts @@ -1,4 +1,4 @@ -import { Command, Program } from "./types"; +import { Command, Program, BaseCommandOptions } from "./types"; import { intlMsg, JobResult, @@ -18,19 +18,17 @@ import { } from "../lib"; import { createLogger } from "./utils/createLogger"; -import { PolywrapClient, PolywrapClientConfig } from "@polywrap/client-js"; +import { PolywrapClient } from "@polywrap/client-js"; import path from "path"; import yaml from "yaml"; import fs from "fs"; -export type RunCommandOptions = { - clientConfig: Partial; +export interface RunCommandOptions extends BaseCommandOptions { + clientConfig: string; manifestFile: string; jobs?: string[]; validationScript?: string; outputFile?: string; - verbose?: boolean; - quiet?: boolean; }; const defaultManifestStr = defaultWorkflowManifest.join(" | "); @@ -69,7 +67,6 @@ export const run: Command = { options.manifestFile, defaultWorkflowManifest ), - clientConfig: await parseClientConfigOption(options.clientConfig), outputFile: options.outputFile ? parseWorkflowOutputFilePathOption(options.outputFile) : undefined, @@ -88,7 +85,8 @@ const _run = async (options: RunCommandOptions) => { jobs, } = options; const logger = createLogger({ verbose, quiet }); - const client = new PolywrapClient(clientConfig); + const config = await parseClientConfigOption(clientConfig) + const client = new PolywrapClient(config); const manifestPath = path.resolve(manifestFile); const workflow = await loadWorkflowManifest(manifestPath, logger); diff --git a/packages/cli/src/commands/types.ts b/packages/cli/src/commands/types.ts index 03c1f5d622..47b49613ef 100644 --- a/packages/cli/src/commands/types.ts +++ b/packages/cli/src/commands/types.ts @@ -6,3 +6,18 @@ export { Program, Argument }; export interface Command { setup: (program: Program) => MaybeAsync; } + +export interface BaseCommandOptions { + verbose?: boolean; + quiet?: boolean; +} + +export type CommandOptionsOrSubCommand< + TOptions extends BaseCommandOptions = BaseCommandOptions +> = + TOptions | + { [subCommand: string]: CommandOptionsOrSubCommand }; + +export interface CommandOptionMappings { + [name: string]: CommandOptionsOrSubCommand; +} diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index 4d960cea5f..f3218a25c7 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -1,19 +1,2 @@ -export { - BuildCommandOptions, - CodegenCommandOptions, - CreateCommandOptions, - DeployCommandOptions, - DocgenCommandOptions, - InfraCommandOptions, - ManifestMigrateCommandOptions, - ManifestSchemaCommandOptions, - RunCommandOptions, - ManifestType, - ProjectType, - SupportedWasmLangs, - SupportedPluginLangs, - SupportedAppLangs, - DocgenActions, - InfraActions, -} from "./commands"; -export { SupportedStrategies } from "./lib/build-strategies"; +export * from "./commands"; +export * from "./lib"; diff --git a/packages/js/cli-api/src/commands.ts b/packages/js/cli-api/src/commands.ts index 6aade89844..86e738d5b4 100644 --- a/packages/js/cli-api/src/commands.ts +++ b/packages/js/cli-api/src/commands.ts @@ -1,20 +1,53 @@ import { runCLI } from "./run-cli"; +import { CreateCommandOptions, ManifestCommandOptions } from "./types"; + import { - Commands, - CommandNames, + ManifestMigrateCommandOptions, + ManifestSchemaCommandOptions, CommandOptions, - ActionCommandNames, -} from "./utils"; -import { CreateCommandOptions, ManifestCommandOptions } from "./types"; + CommandOptionMappings, +} from "polywrap"; + +type CommandFn = ( + options?: TOptions, + cwd?: string, + cli?: string +) => ReturnType; + +type CommandFns< + TCommands extends CommandOptionMappings = CommandOptions +> = Required<{ + [Command in keyof TCommands]: + TCommands[Command] extends CommandOptions ? + CommandFn : + TCommands[Command] extends CommandOptionMappings ? + CommandFn : never; +}>; + +type RecurseCommands< + TFinalType, + TCommands extends CommandOptionMappings = CommandOptions, +> = Required<{ + [Command in keyof TCommands]: + TCommands[Command] extends CommandOptions ? + CommandFn : + TCommands[Command] extends CommandOptionMappings ? + CommandFn : never; +}>; -export const commands: Commands = { +// TODO: generic recusive template + +export const commands: CommandFns = { build: simpleCommandExecutorFactory("build"), codegen: simpleCommandExecutorFactory("codegen"), create: createCommandExecutor, deploy: simpleCommandExecutorFactory("deploy"), docgen: actionCommandExecutorFactory("docgen"), infra: actionCommandExecutorFactory("infra"), - manifest: manifestCommandExecutor, + manifest: { + migrate: manifestCommandExecutor, + schema: manifestCommandExecutor + }, run: simpleCommandExecutorFactory("run"), }; @@ -43,14 +76,11 @@ function parseOptions( return parsed; } -function simpleCommandExecutorFactory( - command: Command -) { - return async ( - options?: CommandOptions[Command], - cwd?: string, - cli?: string - ) => { +function simpleCommandExecutorFactory< + TCommand extends keyof CommandOptions, + TOptions = CommandOptions[TCommand] +>(command: TCommand) { + return async (options?: TOptions, cwd?: string, cli?: string) => { const args = [command, ...parseOptions(options)]; return await runCLI({ args, cwd, cli }); }; diff --git a/packages/js/cli-api/src/utils/declarations.d.ts b/packages/js/cli-api/src/declarations.d.ts similarity index 100% rename from packages/js/cli-api/src/utils/declarations.d.ts rename to packages/js/cli-api/src/declarations.d.ts diff --git a/packages/js/cli-api/src/utils/index.ts b/packages/js/cli-api/src/utils/index.ts deleted file mode 100644 index 316a1aa00e..0000000000 --- a/packages/js/cli-api/src/utils/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./internal-types"; diff --git a/packages/js/cli-api/src/utils/internal-types.ts b/packages/js/cli-api/src/utils/internal-types.ts deleted file mode 100644 index ef6ed2479f..0000000000 --- a/packages/js/cli-api/src/utils/internal-types.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { runCLI } from "../run-cli"; -import { - BuildCommandOptions, - CodegenCommandOptions, - CreateCommandOptions, - DeployCommandOptions, - DocgenCommandOptions, - InfraCommandOptions, - ManifestCommandOptions, - RunCommandOptions, -} from "../types"; - -export type CommandNames = keyof CommandOptions; - -export type ActionCommandNames = "docgen" | "infra"; - -export type CommandOptions = { - build: BuildCommandOptions; - codegen: CodegenCommandOptions; - create: CreateCommandOptions; - deploy: DeployCommandOptions; - docgen: DocgenCommandOptions; - infra: InfraCommandOptions; - manifest: ManifestCommandOptions; - run: RunCommandOptions; -}; - -export type Commands = { - [Command in CommandNames]: ( - options?: CommandOptions[Command], - cwd?: string, - cli?: string - ) => ReturnType; -}; diff --git a/todo b/todo new file mode 100644 index 0000000000..6161e6f0ed --- /dev/null +++ b/todo @@ -0,0 +1,14 @@ +build: + x clientConfig => move to string + x strategy => BuildStrategy +codegen: + x clientConfig +create: + x wasm|plugin|app => { language + name } +docgen: + x clientConfig + x action => DocgenAction +infra: + x action => InfraAction +run: + x clientConfig From 321a1be401b033ae75acfdd1749fed70b76aa410 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Thu, 20 Oct 2022 22:40:33 +0200 Subject: [PATCH 2/2] finish typings --- packages/cli/src/commands/create.ts | 12 +- packages/cli/src/commands/index.ts | 5 +- packages/cli/src/commands/types.ts | 10 +- packages/cli/src/lib/index.ts | 10 +- .../js/cli-api/src/__tests__/cli-js.test.ts | 7 +- packages/js/cli-api/src/commands.ts | 120 +++++------------- packages/js/cli-api/src/index.ts | 1 - packages/js/cli-api/src/types.ts | 120 ------------------ todo | 18 +-- 9 files changed, 59 insertions(+), 244 deletions(-) delete mode 100644 packages/js/cli-api/src/types.ts diff --git a/packages/cli/src/commands/create.ts b/packages/cli/src/commands/create.ts index ed7e395162..85d17898e3 100644 --- a/packages/cli/src/commands/create.ts +++ b/packages/cli/src/commands/create.ts @@ -39,12 +39,12 @@ export interface CreateCommandOptions< outputDir?: string; }; -export type CreateAppCommandOptions = - CreateCommandOptions; -export type CreatePluginCommandOptions = - CreateCommandOptions; -export type CreateWasmCommandOptions = - CreateCommandOptions; +export interface CreateAppCommandOptions + extends CreateCommandOptions { } +export interface CreatePluginCommandOptions + extends CreateCommandOptions { } +export interface CreateWasmCommandOptions + extends CreateCommandOptions { } export const create: Command = { setup: (program: Program) => { diff --git a/packages/cli/src/commands/index.ts b/packages/cli/src/commands/index.ts index ab585087e7..76ccae5092 100644 --- a/packages/cli/src/commands/index.ts +++ b/packages/cli/src/commands/index.ts @@ -8,7 +8,6 @@ export * from "./manifest"; export * from "./run"; export * from "./types"; -import { CommandOptionMappings } from "./types"; import { BuildCommandOptions } from "./build"; import { CodegenCommandOptions } from "./codegen"; import { @@ -25,7 +24,7 @@ import { } from "./manifest"; import { RunCommandOptions } from "./run"; -export interface CommandOptions extends CommandOptionMappings { +export interface CommandOptions { "build": BuildCommandOptions; "codegen": CodegenCommandOptions; "create": { @@ -41,4 +40,4 @@ export interface CommandOptions extends CommandOptionMappings { "schema": ManifestSchemaCommandOptions; }; "run": RunCommandOptions; -}; +} diff --git a/packages/cli/src/commands/types.ts b/packages/cli/src/commands/types.ts index 47b49613ef..e74c4f62dc 100644 --- a/packages/cli/src/commands/types.ts +++ b/packages/cli/src/commands/types.ts @@ -12,12 +12,6 @@ export interface BaseCommandOptions { quiet?: boolean; } -export type CommandOptionsOrSubCommand< - TOptions extends BaseCommandOptions = BaseCommandOptions -> = - TOptions | - { [subCommand: string]: CommandOptionsOrSubCommand }; - -export interface CommandOptionMappings { - [name: string]: CommandOptionsOrSubCommand; +export type CommandOptionMapping = { + [name: string]: BaseCommandOptions | CommandOptionMapping; } diff --git a/packages/cli/src/lib/index.ts b/packages/cli/src/lib/index.ts index 9be4c276bf..c68110b2cf 100644 --- a/packages/cli/src/lib/index.ts +++ b/packages/cli/src/lib/index.ts @@ -1,15 +1,17 @@ +export * from "./build-strategies"; +export * from "./codegen"; export * from "./deploy"; export * from "./helpers"; export * from "./infra"; export * from "./intl"; -export * from "./option-parsers"; +export * from "./logging"; +export * from "./manifest"; export * from "./option-defaults"; +export * from "./option-parsers"; export * from "./project"; export * from "./system"; export * from "./test-env"; +export * from "./workflow"; export * from "./CacheDirectory"; export * from "./Compiler"; -export * from "./codegen"; export * from "./SchemaComposer"; -export * from "./workflow"; -export * from "./logging"; diff --git a/packages/js/cli-api/src/__tests__/cli-js.test.ts b/packages/js/cli-api/src/__tests__/cli-js.test.ts index 89fd92bcc6..f3ced7a569 100644 --- a/packages/js/cli-api/src/__tests__/cli-js.test.ts +++ b/packages/js/cli-api/src/__tests__/cli-js.test.ts @@ -1,4 +1,5 @@ -import { awaitResponse, Commands, InfraActions, runCLI } from "../../"; +import { awaitResponse, Commands, runCLI } from "../../"; +import { SupportedStrategies } from "polywrap"; import path from "path"; import fs from "fs"; @@ -26,7 +27,9 @@ describe("cli-js tests", () => { expect(fs.existsSync(buildDir)).toBeFalsy(); // build - await Commands.build({ strategy: "image" }, wrapperPath); + await Commands.build({ + strategy: SupportedStrategies.IMAGE + }, wrapperPath); // check for build dir and artifacts const wasmPath = path.join(buildDir, "wrap.wasm"); diff --git a/packages/js/cli-api/src/commands.ts b/packages/js/cli-api/src/commands.ts index 86e738d5b4..13a5d206b7 100644 --- a/packages/js/cli-api/src/commands.ts +++ b/packages/js/cli-api/src/commands.ts @@ -1,54 +1,54 @@ import { runCLI } from "./run-cli"; -import { CreateCommandOptions, ManifestCommandOptions } from "./types"; import { - ManifestMigrateCommandOptions, - ManifestSchemaCommandOptions, + CommandOptionMapping, + BaseCommandOptions, CommandOptions, - CommandOptionMappings, } from "polywrap"; -type CommandFn = ( +type CommandFn< + TOptions extends BaseCommandOptions +> = ( options?: TOptions, cwd?: string, cli?: string ) => ReturnType; type CommandFns< - TCommands extends CommandOptionMappings = CommandOptions + TCommands > = Required<{ [Command in keyof TCommands]: - TCommands[Command] extends CommandOptions ? - CommandFn : - TCommands[Command] extends CommandOptionMappings ? - CommandFn : never; + TCommands[Command] extends BaseCommandOptions ? + CommandFn : + TCommands[Command] extends CommandOptionMapping ? + CommandFns : never; }>; -type RecurseCommands< - TFinalType, - TCommands extends CommandOptionMappings = CommandOptions, -> = Required<{ - [Command in keyof TCommands]: - TCommands[Command] extends CommandOptions ? - CommandFn : - TCommands[Command] extends CommandOptionMappings ? - CommandFn : never; -}>; - -// TODO: generic recusive template +function execCommandFn< + TOptions extends BaseCommandOptions, +>(command: string): CommandFn { + return async (options?: TOptions, cwd?: string, cli?: string) => { + const args = [command, ...parseOptions(options)]; + return await runCLI({ args, cwd, cli }); + }; +} -export const commands: CommandFns = { - build: simpleCommandExecutorFactory("build"), - codegen: simpleCommandExecutorFactory("codegen"), - create: createCommandExecutor, - deploy: simpleCommandExecutorFactory("deploy"), - docgen: actionCommandExecutorFactory("docgen"), - infra: actionCommandExecutorFactory("infra"), +export const commands: CommandFns = { + build: execCommandFn("build"), + codegen: execCommandFn("codegen"), + create: { + app: execCommandFn("create app"), + plugin: execCommandFn("create plugin"), + wasm: execCommandFn("create wasm") + }, + deploy: execCommandFn("deploy"), + docgen: execCommandFn("docgen"), + infra: execCommandFn("infra"), manifest: { - migrate: manifestCommandExecutor, - schema: manifestCommandExecutor + migrate: execCommandFn("manifest migrate"), + schema: execCommandFn("manifest schema") }, - run: simpleCommandExecutorFactory("run"), + run: execCommandFn("run"), }; function toKebabCase(camelCase: string): string { @@ -62,8 +62,8 @@ function parseValue(value: string | string[] | boolean): string { return value.toString(); } -function parseOptions( - options?: CommandOptions[Command] +function parseOptions( + options?: TOptions ): string[] { const parsed: string[] = []; if (options) { @@ -75,55 +75,3 @@ function parseOptions( } return parsed; } - -function simpleCommandExecutorFactory< - TCommand extends keyof CommandOptions, - TOptions = CommandOptions[TCommand] ->(command: TCommand) { - return async (options?: TOptions, cwd?: string, cli?: string) => { - const args = [command, ...parseOptions(options)]; - return await runCLI({ args, cwd, cli }); - }; -} - -function actionCommandExecutorFactory( - command: Command -) { - return async ( - options: CommandOptions[Command], - cwd?: string, - cli?: string - ) => { - const { action, ...cmdOptions } = options; - const args = [command, action, ...parseOptions(cmdOptions)]; - return await runCLI({ args, cwd, cli }); - }; -} - -async function createCommandExecutor( - options: CreateCommandOptions, - cwd?: string, - cli?: string -): Promise<{ - exitCode: number; - stdout: string; - stderr: string; -}> { - const { command, language, name, ...createOpts } = options; - const args = ["create", command, language, name, ...parseOptions(createOpts)]; - return await runCLI({ args, cwd, cli }); -} - -async function manifestCommandExecutor( - options: ManifestCommandOptions, - cwd?: string, - cli?: string -): Promise<{ - exitCode: number; - stdout: string; - stderr: string; -}> { - const { command, type, ...manifestOptions } = options; - const args = ["manifest", command, type, ...parseOptions(manifestOptions)]; - return await runCLI({ args, cwd, cli }); -} diff --git a/packages/js/cli-api/src/index.ts b/packages/js/cli-api/src/index.ts index 73f992f8d8..4c8ca3b047 100644 --- a/packages/js/cli-api/src/index.ts +++ b/packages/js/cli-api/src/index.ts @@ -1,4 +1,3 @@ -export * from "./types"; export { runCLI } from "./run-cli"; export { commands as Commands } from "./commands"; export * from "./awaitResponse"; diff --git a/packages/js/cli-api/src/types.ts b/packages/js/cli-api/src/types.ts deleted file mode 100644 index e44c9ec952..0000000000 --- a/packages/js/cli-api/src/types.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { - BuildCommandOptions as ParsedBuildCommandOptions, - CodegenCommandOptions as ParsedCodegenCommandOptions, - CreateCommandOptions as ParsedCreateCommandOptions, - DeployCommandOptions as ParsedDeployCommandOptions, - DocgenCommandOptions as ParsedDocgenCommandOptions, - InfraCommandOptions as ParsedInfraCommandOptions, - ManifestMigrateCommandOptions as ParsedManifestMigrateCommandOptions, - ManifestSchemaCommandOptions as ParsedManifestSchemaCommandOptions, - RunCommandOptions as ParsedRunCommandOptions, - SupportedWasmLangs, - SupportedPluginLangs, - SupportedAppLangs, - DocgenActions, - InfraActions, - SupportedStrategies, - ManifestType, -} from "polywrap"; - -export { - DocgenActions, - InfraActions, - SupportedStrategies as BuildStrategies, -} from "polywrap"; - -export type DocgenAction = `${DocgenActions}`; -export type InfraAction = `${InfraActions}`; -export type BuildStrategy = `${SupportedStrategies}`; - -export type DeployCommandOptions = Partial; - -export type BuildCommandOptions = Omit< - Partial, - "watch" | "clientConfig" | "strategy" -> & { - clientConfig?: string; - strategy?: BuildStrategy; -}; - -export type CodegenCommandOptions = Omit< - Partial, - "clientConfig" -> & { - clientConfig?: string; -}; - -export type RunCommandOptions = Omit< - Partial, - "clientConfig" -> & { - clientConfig?: string; -}; - -// create - -export type CreateWasmCommandArgs = { - command: "wasm"; - language: SupportedWasmLangs; - name: string; -}; - -export type CreatePluginCommandArgs = { - command: "plugin"; - language: SupportedPluginLangs; - name: string; -}; - -export type CreateAppCommandArgs = { - command: "app"; - language: SupportedAppLangs; - name: string; -}; - -export type CreateCommandArgs = - | CreateWasmCommandArgs - | CreatePluginCommandArgs - | CreateAppCommandArgs; - -export type CreateCommandOptions = CreateCommandArgs & - Partial; - -// docgen - -export type DocgenCommandArgs = { - action: DocgenAction; -}; - -export type DocgenCommandOptions = DocgenCommandArgs & - Omit, "clientConfig"> & { - clientConfig?: string; - }; - -// infra - -export type InfraCommandArgs = { - action: InfraAction; -}; - -export type InfraCommandOptions = InfraCommandArgs & - Partial; - -// manifest - -export type ManifestSchemaCommandArgs = { - command: "schema"; - type: ManifestType; -}; - -export type ManifestMigrateCommandArgs = { - command: "migrate"; - type: ManifestType; -}; - -export type ManifestSchemaCommandOptions = Partial; - -export type ManifestMigrateCommandOptions = Partial; - -export type ManifestCommandOptions = - | (ManifestSchemaCommandArgs & ManifestSchemaCommandOptions) - | (ManifestMigrateCommandArgs & ManifestMigrateCommandOptions); diff --git a/todo b/todo index 6161e6f0ed..13174671e6 100644 --- a/todo +++ b/todo @@ -1,14 +1,4 @@ -build: - x clientConfig => move to string - x strategy => BuildStrategy -codegen: - x clientConfig -create: - x wasm|plugin|app => { language + name } -docgen: - x clientConfig - x action => DocgenAction -infra: - x action => InfraAction -run: - x clientConfig +- For all command option interfaces, make optional arguments undefine-able (i.e. `prop?: Type`), this way the cli-js library doesn't have to pass them in if they have defaults. Inside of the command's `run(...)` method, we should require all options to be defined (i.e. `run(options: Require)`). +- Make sure all CLI command options are serializable (string, number, array, etc) +- Usage of enums is awkward, and requires the user to import the enum type (see `commands.build({ strategy: ... })`). Instead, we can just use TypeScript string unions (i.e. `type BuildStrategy = "vm" | "image" | ...`). I think this will make our life easier. +- Create an automated test suite in cli-js that ensures test input is defined for all possible commands. \ No newline at end of file