From 6f916438b732b1203e30797007e1044b36cf8f9e Mon Sep 17 00:00:00 2001 From: Robert Field Date: Thu, 21 Sep 2023 17:43:42 +0100 Subject: [PATCH] feat: support tracking for all commands --- .../src/commands/config/config-command.tsx | 3 +- .../src/commands/feedback/feedback-command.ts | 5 ++- .../src/commands/generate/d2c/d2c-command.tsx | 32 ++++++++++--------- .../commands/generate/generate-command.tsx | 16 ++++------ .../commands/insights/insights-command.tsx | 5 ++- .../src/commands/login/login-command.ts | 13 +++----- .../src/commands/logout/logout-command.ts | 3 +- .../src/commands/store/store-command.tsx | 7 ++-- packages/composable-cli/src/composable.ts | 5 ++- packages/composable-cli/src/types/command.ts | 3 ++ packages/composable-cli/src/util/command.ts | 2 ++ .../src/util/track-command-handler.ts | 31 ++++++++++++++++++ 12 files changed, 86 insertions(+), 39 deletions(-) create mode 100644 packages/composable-cli/src/util/track-command-handler.ts diff --git a/packages/composable-cli/src/commands/config/config-command.tsx b/packages/composable-cli/src/commands/config/config-command.tsx index 9a0335a0..958d07c3 100644 --- a/packages/composable-cli/src/commands/config/config-command.tsx +++ b/packages/composable-cli/src/commands/config/config-command.tsx @@ -7,6 +7,7 @@ import { ConfigCommandData, ConfigCommandError, } from "./config.types" +import { trackCommandHandler } from "../../util/track-command-handler" export function configClearCommand(store: Conf): void { store.clear() @@ -36,7 +37,7 @@ export function createConfigCommand( }) .help() }, - handler: handleErrors(createConfigCommandHandler(ctx)), + handler: handleErrors(trackCommandHandler(ctx, createConfigCommandHandler)), } } diff --git a/packages/composable-cli/src/commands/feedback/feedback-command.ts b/packages/composable-cli/src/commands/feedback/feedback-command.ts index 74a416b5..2ad593b0 100644 --- a/packages/composable-cli/src/commands/feedback/feedback-command.ts +++ b/packages/composable-cli/src/commands/feedback/feedback-command.ts @@ -10,13 +10,16 @@ import { } from "./feedback.types" import open from "open" import { Feedback } from "../ui/feedback/feedback" +import { trackCommandHandler } from "../../util/track-command-handler" export function createFeedbackCommand( ctx: CommandContext ): yargs.CommandModule<{}, FeedbackCommandArguments> { return { command: "feedback", describe: "Feedback to the Composable CLI", - handler: handleErrors(createFeedbackCommandHandler(ctx)), + handler: handleErrors( + trackCommandHandler(ctx, createFeedbackCommandHandler) + ), } } diff --git a/packages/composable-cli/src/commands/generate/d2c/d2c-command.tsx b/packages/composable-cli/src/commands/generate/d2c/d2c-command.tsx index 6a007978..e9370358 100644 --- a/packages/composable-cli/src/commands/generate/d2c/d2c-command.tsx +++ b/packages/composable-cli/src/commands/generate/d2c/d2c-command.tsx @@ -1,6 +1,6 @@ import yargs from "yargs" import { logging, schema, tags } from "@angular-devkit/core" -import { createConsoleLogger, ProcessOutput } from "@angular-devkit/core/node" +import { createConsoleLogger } from "@angular-devkit/core/node" import * as ansiColors from "ansi-colors" import { NodeWorkflow } from "@angular-devkit/schematics/tools" @@ -27,11 +27,10 @@ import React from "react" import { D2CGenerated } from "../../ui/generate/d2c-generated" import { getStore } from "../../../lib/stores/get-store" import { selectStoreById } from "../../store/store-command" +import { trackCommandHandler } from "../../../util/track-command-handler" export function createD2CCommand( - ctx: CommandContext, - stdout: ProcessOutput, - stderr: ProcessOutput + ctx: CommandContext ): yargs.CommandModule<{}, D2CCommandArguments> { return { command: "d2c [name]", @@ -56,7 +55,7 @@ export function createD2CCommand( "strip-aliased": true, }) }, - handler: handleErrors(createD2CCommandHandler(ctx, stdout, stderr)), + handler: handleErrors(trackCommandHandler(ctx, createD2CCommandHandler)), } } @@ -68,9 +67,7 @@ function resolveD2CCollectionName(nodeEnv: string): string { } export function createD2CCommandHandler( - ctx: CommandContext, - stdout: ProcessOutput, - stderr: ProcessOutput + ctx: CommandContext ): CommandHandlerFunction< D2CCommandData, D2CCommandError, @@ -85,13 +82,18 @@ export function createD2CCommandHandler( parseArgs(args) /** Create the DevKit Logger used through the CLI. */ - const logger = createConsoleLogger(!!cliOptions.verbose, stdout, stderr, { - info: (s) => s, - debug: (s) => s, - warn: (s) => colors.bold.yellow(s), - error: (s) => colors.bold.red(s), - fatal: (s) => colors.bold.red(s), - }) + const logger = createConsoleLogger( + !!cliOptions.verbose, + ctx.stdout, + ctx.stderr, + { + info: (s) => s, + debug: (s) => s, + warn: (s) => colors.bold.yellow(s), + error: (s) => colors.bold.red(s), + fatal: (s) => colors.bold.red(s), + } + ) logger.debug(`Cli Options: ${JSON.stringify(cliOptions)}`) logger.debug(`Schematic Options: ${JSON.stringify(schematicOptions)}`) diff --git a/packages/composable-cli/src/commands/generate/generate-command.tsx b/packages/composable-cli/src/commands/generate/generate-command.tsx index 6353967f..2678273d 100644 --- a/packages/composable-cli/src/commands/generate/generate-command.tsx +++ b/packages/composable-cli/src/commands/generate/generate-command.tsx @@ -6,16 +6,14 @@ import { GenerateCommandData, GenerateCommandError, } from "./generate.types" -import { ProcessOutput } from "@angular-devkit/core/node" import { createD2CCommand } from "./d2c/d2c-command" import { hasActiveStore } from "../../util/active-store" import { createSetStoreCommandHandler } from "../store/store-command" import { isAuthenticated } from "../../util/check-authenticated" +import { trackCommandHandler } from "../../util/track-command-handler" export function createGenerateCommand( - ctx: CommandContext, - stdout: ProcessOutput, - stderr: ProcessOutput + ctx: CommandContext ): yargs.CommandModule<{}, GenerateCommandArguments> { return { command: "generate", @@ -25,7 +23,7 @@ export function createGenerateCommand( return yargs .middleware(createAuthenticationCheckerMiddleware(ctx)) .middleware(createActiveStoreMiddleware(ctx)) - .command(createD2CCommand(ctx, stdout, stderr)) + .command(createD2CCommand(ctx)) .option("name", { type: "string", default: null }) .option("interactive", { type: "boolean", default: true }) .option("debug", { type: "boolean", default: null }) @@ -45,7 +43,9 @@ export function createGenerateCommand( "strip-aliased": true, }) }, - handler: handleErrors(createGenerateCommandHandler(ctx, stdout, stderr)), + handler: handleErrors( + trackCommandHandler(ctx, createGenerateCommandHandler) + ), } } @@ -100,9 +100,7 @@ export function createActiveStoreMiddleware( } export function createGenerateCommandHandler( - _ctx: CommandContext, - _stdout: ProcessOutput, - _stderr: ProcessOutput + _ctx: CommandContext ): CommandHandlerFunction< GenerateCommandData, GenerateCommandError, diff --git a/packages/composable-cli/src/commands/insights/insights-command.tsx b/packages/composable-cli/src/commands/insights/insights-command.tsx index 9f5bc3dd..9c2f4efd 100644 --- a/packages/composable-cli/src/commands/insights/insights-command.tsx +++ b/packages/composable-cli/src/commands/insights/insights-command.tsx @@ -8,6 +8,7 @@ import { } from "./insights.types" import { promptOptInProductInsights } from "../../lib/insights/opt-in-product-insights-middleware" import { optInsights } from "../../util/has-opted-insights" +import { trackCommandHandler } from "../../util/track-command-handler" export function createInsightsCommand( ctx: CommandContext @@ -24,7 +25,9 @@ export function createInsightsCommand( }) .help() }, - handler: handleErrors(createInsightsCommandHandler(ctx)), + handler: handleErrors( + trackCommandHandler(ctx, createInsightsCommandHandler) + ), } } diff --git a/packages/composable-cli/src/commands/login/login-command.ts b/packages/composable-cli/src/commands/login/login-command.ts index 81b43ac3..fea67665 100644 --- a/packages/composable-cli/src/commands/login/login-command.ts +++ b/packages/composable-cli/src/commands/login/login-command.ts @@ -23,6 +23,7 @@ import { isAuthenticated } from "../../util/check-authenticated" import React from "react" import { WelcomeNote } from "../ui/login/welcome-note" import { render } from "ink" +import { trackCommandHandler } from "../../util/track-command-handler" /** * Region prompts @@ -75,7 +76,7 @@ export function createLoginCommand( "strip-aliased": true, }) }, - handler: handleErrors(createLoginCommandHandler(ctx)), + handler: handleErrors(trackCommandHandler(ctx, createLoginCommandHandler)), } } @@ -89,7 +90,9 @@ export function createAuthenticationMiddleware( return } - return handleErrors(createLoginCommandHandler(ctx))(argv) + return handleErrors(trackCommandHandler(ctx, createLoginCommandHandler))( + argv + ) } } @@ -119,12 +122,6 @@ export function createLoginCommandHandler( const spinner = ora("Authenticating").start() - if (ctx.posthog) { - ctx.posthog.postHogCapture({ - event: "composable cli login", - }) - } - const result = await authenticateUserPassword( store, apiHost, diff --git a/packages/composable-cli/src/commands/logout/logout-command.ts b/packages/composable-cli/src/commands/logout/logout-command.ts index da9844a1..4202c856 100644 --- a/packages/composable-cli/src/commands/logout/logout-command.ts +++ b/packages/composable-cli/src/commands/logout/logout-command.ts @@ -11,6 +11,7 @@ import { renderInk } from "../../lib/ink/render-ink" import React from "react" import { LogoutNote } from "../ui/logout/logout-note" import { handleClearCredentials } from "../../util/conf-store/store-credentials" +import { trackCommandHandler } from "../../util/track-command-handler" export function createLogoutCommand( ctx: CommandContext @@ -18,7 +19,7 @@ export function createLogoutCommand( return { command: "logout", describe: "Logout of the Composable CLI", - handler: handleErrors(createLogoutCommandHandler(ctx)), + handler: handleErrors(trackCommandHandler(ctx, createLogoutCommandHandler)), } } diff --git a/packages/composable-cli/src/commands/store/store-command.tsx b/packages/composable-cli/src/commands/store/store-command.tsx index 6f689a0a..3d259c34 100644 --- a/packages/composable-cli/src/commands/store/store-command.tsx +++ b/packages/composable-cli/src/commands/store/store-command.tsx @@ -25,6 +25,7 @@ import { checkIsErrorResponse, resolveEPCCErrorMessage, } from "../../util/epcc-error" +import { trackCommandHandler } from "../../util/track-command-handler" export function createStoreCommand( ctx: CommandContext @@ -38,7 +39,7 @@ export function createStoreCommand( .command(createSetStoreCommand(ctx)) .help("h") }, - handler: handleErrors(createStoreCommandHandler(ctx)), + handler: handleErrors(trackCommandHandler(ctx, createStoreCommandHandler)), } } @@ -56,7 +57,9 @@ export function createSetStoreCommand( }) .help() }, - handler: handleErrors(createSetStoreCommandHandler(ctx)), + handler: handleErrors( + trackCommandHandler(ctx, createSetStoreCommandHandler) + ), } } diff --git a/packages/composable-cli/src/composable.ts b/packages/composable-cli/src/composable.ts index 7f39aa34..3b0eb133 100644 --- a/packages/composable-cli/src/composable.ts +++ b/packages/composable-cli/src/composable.ts @@ -32,6 +32,9 @@ export async function main({ stderr = process.stderr, }: MainOptions): Promise<1 | 0> { try { + commandContext.stdout = stdout + commandContext.stderr = stderr + await yargs(hideBin(argv)) .middleware(createUUIDMiddleware(commandContext)) .middleware(createOptInProductInsightsMiddleware(commandContext)) @@ -41,7 +44,7 @@ export async function main({ .command(createFeedbackCommand(commandContext)) .command(createConfigCommand(commandContext)) .command(createStoreCommand(commandContext)) - .command(createGenerateCommand(commandContext, stdout, stderr)) + .command(createGenerateCommand(commandContext)) .command(createInsightsCommand(commandContext)) .option("verbose", { alias: "v", diff --git a/packages/composable-cli/src/types/command.ts b/packages/composable-cli/src/types/command.ts index 46dbbc92..99312d09 100644 --- a/packages/composable-cli/src/types/command.ts +++ b/packages/composable-cli/src/types/command.ts @@ -3,6 +3,7 @@ import fetch from "node-fetch" import yargs from "yargs" import type { PostHog } from "posthog-node" import { createPostHogCapture } from "../lib/insights/capture-posthog" +import { ProcessOutput } from "@angular-devkit/core/node" export type CommandResult = | { @@ -21,6 +22,8 @@ export type CommandContext = { client: PostHog postHogCapture: Awaited> } + stdout: ProcessOutput + stderr: ProcessOutput } export type CommandHandlerFunction< diff --git a/packages/composable-cli/src/util/command.ts b/packages/composable-cli/src/util/command.ts index 862e4172..b3776c9c 100644 --- a/packages/composable-cli/src/util/command.ts +++ b/packages/composable-cli/src/util/command.ts @@ -31,5 +31,7 @@ export function createCommandContext(): CommandContext { return { store, requester: fetch, + stdout: process.stdout, + stderr: process.stderr, } } diff --git a/packages/composable-cli/src/util/track-command-handler.ts b/packages/composable-cli/src/util/track-command-handler.ts new file mode 100644 index 00000000..ee4e6e22 --- /dev/null +++ b/packages/composable-cli/src/util/track-command-handler.ts @@ -0,0 +1,31 @@ +import { CommandContext, CommandHandlerFunction } from "../types/command" +import { ProcessOutput } from "@angular-devkit/core/node" + +export function trackCommandHandler< + TData, + TError, + TCommandArguments extends Record +>( + ctx: CommandContext, + handler: ( + ctx: CommandContext, + stdout?: ProcessOutput, + stderr?: ProcessOutput + ) => CommandHandlerFunction +): CommandHandlerFunction { + return (args) => { + console.log(args) + if (ctx.posthog) { + // Making sure to filter out any properties that might contain sensitive information + const { _, $0, password, username, ...rest } = args + ctx.posthog.postHogCapture({ + event: `composable cli command ${args._.join(" ")}`, + properties: { + ...rest, + }, + }) + } + + return handler(ctx)(args) + } +}