From a90908df6eafd8b520712dfbbb61db7613681306 Mon Sep 17 00:00:00 2001 From: Matt Aitken Date: Wed, 9 Aug 2023 10:37:10 +0100 Subject: [PATCH] CLI init fixes: don't ask for endpoint slug, fix for next.config and package manager artifact issue (#287) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * If an endpointId isn’t in the arguments or package, then use the project slug. Don’t ask for it. * Should await the package artifact detection * Catch error thrown if there’s no next.config file when detecting the type of Next project * Create long-carrots-camp.md --- .changeset/long-carrots-camp.md | 5 ++ packages/cli/src/commands/init.ts | 56 ++++++++++++--------- packages/cli/src/utils/getUserPkgManager.ts | 2 +- 3 files changed, 38 insertions(+), 25 deletions(-) create mode 100644 .changeset/long-carrots-camp.md diff --git a/.changeset/long-carrots-camp.md b/.changeset/long-carrots-camp.md new file mode 100644 index 000000000..396beb39e --- /dev/null +++ b/.changeset/long-carrots-camp.md @@ -0,0 +1,5 @@ +--- +"@trigger.dev/cli": patch +--- + +CLI init fixes: don't ask for endpoint slug, fix for next.config and package manager artifact issue diff --git a/packages/cli/src/commands/init.ts b/packages/cli/src/commands/init.ts index aba974d36..f363e35a5 100644 --- a/packages/cli/src/commands/init.ts +++ b/packages/cli/src/commands/init.ts @@ -67,24 +67,28 @@ export const initCommand = async (options: InitCommandOptions) => { const isTypescriptProject = await detectTypescriptProject(resolvedPath); telemetryClient.init.isTypescriptProject(isTypescriptProject, options); - const resolvedOptions = await resolveOptionsWithPrompts(options, resolvedPath, telemetryClient); - const apiKey = resolvedOptions.apiKey; + const optionsAfterPrompts = await resolveOptionsWithPrompts( + options, + resolvedPath, + telemetryClient + ); + const apiKey = optionsAfterPrompts.apiKey; if (!apiKey) { logger.error("You must provide an API key to continue."); - telemetryClient.init.failed("no_api_key", resolvedOptions); + telemetryClient.init.failed("no_api_key", optionsAfterPrompts); return; } - const apiClient = new TriggerApi(apiKey, resolvedOptions.apiUrl); + const apiClient = new TriggerApi(apiKey, optionsAfterPrompts.apiUrl); const authorizedKey = await apiClient.whoami(apiKey); if (!authorizedKey) { logger.error( - `🛑 The API key you provided is not authorized. Try visiting your dashboard at ${resolvedOptions.triggerUrl} to get a new API key.` + `🛑 The API key you provided is not authorized. Try visiting your dashboard at ${optionsAfterPrompts.triggerUrl} to get a new API key.` ); - telemetryClient.init.failed("invalid_api_key", resolvedOptions); + telemetryClient.init.failed("invalid_api_key", optionsAfterPrompts); return; } @@ -94,6 +98,9 @@ export const initCommand = async (options: InitCommandOptions) => { authorizedKey.userId ); + const endpointSlug = authorizedKey.project.slug; + const resolvedOptions: ResolvedOptions = { ...optionsAfterPrompts, endpointSlug }; + await addDependencies(resolvedPath, [ { name: "@trigger.dev/sdk", tag: "latest" }, { name: "@trigger.dev/nextjs", tag: "latest" }, @@ -174,11 +181,15 @@ async function addConfigurationToPackageJson(path: string, options: ResolvedOpti logger.success(`✅ Wrote trigger.dev config to package.json`); } +type OptionsAfterPrompts = Required> & { + endpointSlug: InitCommandOptions["endpointSlug"]; +}; + const resolveOptionsWithPrompts = async ( options: InitCommandOptions, path: string, telemetryClient: TelemetryClient -): Promise => { +): Promise => { const resolvedOptions: InitCommandOptions = { ...options }; try { @@ -205,11 +216,8 @@ const resolveOptionsWithPrompts = async ( if (packageJSON && packageJSON["trigger.dev"] && packageJSON["trigger.dev"].endpointId) { resolvedOptions.endpointSlug = packageJSON["trigger.dev"].endpointId; - } else { - resolvedOptions.endpointSlug = await promptEndpointSlug(path); + telemetryClient.init.resolvedEndpointSlug(resolvedOptions); } - - telemetryClient.init.resolvedEndpointSlug(resolvedOptions); } } catch (err) { // If the user is not calling the command from an interactive terminal, inquirer will throw an error with isTTYError = true @@ -239,7 +247,7 @@ const resolveOptionsWithPrompts = async ( } } - return resolvedOptions as ResolvedOptions; + return resolvedOptions as OptionsAfterPrompts; }; // Detects if there are any uncommitted git changes at path @@ -278,7 +286,7 @@ async function detectPagesOrAppDir( isTypescriptProject = false ): Promise<"pages" | "app"> { const nextConfigPath = pathModule.join(path, "next.config.js"); - const importedConfig = await import(pathToFileURL(nextConfigPath).toString()); + const importedConfig = await import(pathToFileURL(nextConfigPath).toString()).catch(() => ({})); if (importedConfig?.default?.experimental?.appDir) { return "app"; @@ -437,11 +445,11 @@ async function createTriggerAppRoute( const tsConfigPath = pathModule.join(projectPath, configFileName); const { tsconfig } = await parse(tsConfigPath); - const extension = isTypescriptProject ? ".ts" : ".js" - const triggerFileName = `trigger${extension}` - const examplesFileName = `examples${extension}` - const examplesIndexFileName = `index${extension}` - const routeFileName = `route${extension}` + const extension = isTypescriptProject ? ".ts" : ".js"; + const triggerFileName = `trigger${extension}`; + const examplesFileName = `examples${extension}`; + const examplesIndexFileName = `index${extension}`; + const routeFileName = `route${extension}`; const pathAlias = getPathAlias(tsconfig, usesSrcDir); const routePathPrefix = pathAlias ? pathAlias + "/" : "../../../"; @@ -495,7 +503,7 @@ client.defineJob({ // import all your job files here export * from "./examples" -` +`; const directories = pathModule.join(path, "app", "api", "trigger"); await fs.mkdir(directories, { recursive: true }); @@ -552,10 +560,10 @@ async function createTriggerPageRoute( const pathAlias = getPathAlias(tsconfig, usesSrcDir); const routePathPrefix = pathAlias ? pathAlias + "/" : "../.."; - const extension = isTypescriptProject ? ".ts" : ".js" - const triggerFileName = `trigger${extension}` - const examplesFileName = `examples${extension}` - const examplesIndexFileName = `index${extension}` + const extension = isTypescriptProject ? ".ts" : ".js"; + const triggerFileName = `trigger${extension}`; + const examplesFileName = `examples${extension}`; + const examplesIndexFileName = `index${extension}`; const routeContent = ` import { createPagesRoute } from "@trigger.dev/nextjs"; @@ -608,7 +616,7 @@ client.defineJob({ // import all your job files here export * from "./examples" - ` + `; const directories = pathModule.join(path, "pages", "api"); await fs.mkdir(directories, { recursive: true }); diff --git a/packages/cli/src/utils/getUserPkgManager.ts b/packages/cli/src/utils/getUserPkgManager.ts index 697f288ef..27b9a9031 100644 --- a/packages/cli/src/utils/getUserPkgManager.ts +++ b/packages/cli/src/utils/getUserPkgManager.ts @@ -5,7 +5,7 @@ export type PackageManager = "npm" | "pnpm" | "yarn"; export async function getUserPackageManager(path: string): Promise { try { - return detectPackageManagerFromArtifacts(path); + return await detectPackageManagerFromArtifacts(path); } catch (error) { return detectPackageManagerFromCurrentCommand(); }