From 8ec582b2ac839d3942ffecb2f17717c455a5052c Mon Sep 17 00:00:00 2001 From: Roderik van der Veer Date: Mon, 7 Oct 2024 10:03:22 +0200 Subject: [PATCH] feat: create a codegen command --- .github/workflows/build.yml | 2 +- bun.lockb | Bin 125020 -> 125860 bytes packages/cli/.gitignore | 3 +- packages/cli/package.json | 4 +- packages/cli/src/cli.ts | 2 + packages/cli/src/commands/codegen.ts | 36 ++++++ .../src/commands/codegen/gqltada.spinner.ts | 117 ++++++++++++++++++ packages/cli/src/commands/connect.ts | 46 ++++--- .../src/commands/connect/write-env.spinner.ts | 9 +- packages/hasura/package.json | 2 +- packages/js/package.json | 2 +- packages/portal/package.json | 2 +- packages/thegraph/package.json | 2 +- packages/utils/package.json | 1 + packages/utils/src/environment/load-env.ts | 14 ++- packages/utils/src/environment/write-env.ts | 7 +- packages/utils/src/terminal.ts | 1 + packages/utils/src/terminal/run.ts | 18 +++ 18 files changed, 225 insertions(+), 43 deletions(-) create mode 100644 packages/cli/src/commands/codegen.ts create mode 100644 packages/cli/src/commands/codegen/gqltada.spinner.ts create mode 100644 packages/utils/src/terminal/run.ts diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1b5f4714f..7b54ab025 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -214,5 +214,5 @@ jobs: with: commit_message: "chore: update package versions [skip ci]" branch: main - file_pattern: 'package.json **/package.json **/schema.graphql' + file_pattern: 'package.json **/schema.graphql' diff --git a/bun.lockb b/bun.lockb index fb78aaa12dfb0ce8381264278bffa9344379aaf0..e79551b74e6fc2ab5e0c56e54e4d7fbeb6fa52df 100755 GIT binary patch delta 19256 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 delta 18738 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", "The name of your environment, defaults to development", "development") + // Set the command description + .description("Generate GraphQL and REST types and queries") + // Define the action to be executed when the command is run + .action(async ({ environment }) => { + intro( + `Generating GraphQL types and queries for your dApp's ${italic(underline(bold(environment)))} environment`, + ); + + const env: DotEnv = await loadEnv(); + + await gqltadaSpinner(env); + + outro("Codegen complete"); + }) + ); +} diff --git a/packages/cli/src/commands/codegen/gqltada.spinner.ts b/packages/cli/src/commands/codegen/gqltada.spinner.ts new file mode 100644 index 000000000..63b0df5c3 --- /dev/null +++ b/packages/cli/src/commands/codegen/gqltada.spinner.ts @@ -0,0 +1,117 @@ +import { generateSchema } from "@gql.tada/cli-utils"; +import type { DotEnv } from "@settlemint/sdk-utils/validation"; + +/** + * Writes environment variables to .env files with a spinner for visual feedback. + * + * @param env - Partial environment variables to be written. + * @param environment - The name of the environment (e.g., "development", "production"). + * @returns A promise that resolves when the environment variables are written. + * @throws If there's an error writing the environment files. + * + * @example + * await writeEnvSpinner( + * { SETTLEMINT_INSTANCE: "https://example.com", SETTLEMINT_ACCESS_TOKEN: "token123" }, + * "development" + * ); + */ +export async function gqltadaSpinner(env: DotEnv) { + await gqltadaCodegen({ + type: "HASURA", + env, + }); + await gqltadaCodegen({ + type: "PORTAL", + env, + }); + await gqltadaCodegen({ + type: "THEGRAPH", + env, + allowToFail: true, + }); + await gqltadaCodegen({ + type: "THEGRAPH_FALLBACK", + env, + }); +} + +async function gqltadaCodegen(options: { + type: "HASURA" | "PORTAL" | "THEGRAPH" | "THEGRAPH_FALLBACK"; + env: DotEnv; + allowToFail?: boolean; +}) { + let gqlEndpoint: string | undefined = undefined; + let output: string; + let adminSecret: string | undefined = undefined; + const accessToken = options.env.SETTLEMINT_ACCESS_TOKEN; + + switch (options.type) { + case "HASURA": + gqlEndpoint = options.env.SETTLEMINT_HASURA_ENDPOINT; + output = "hasura.schema.graphql"; + adminSecret = options.env.SETTLEMINT_HASURA_ADMIN_SECRET; + break; + case "PORTAL": + gqlEndpoint = options.env.SETTLEMINT_PORTAL_GRAPHQL_ENDPOINT; + output = "portal.schema.graphql"; + break; + case "THEGRAPH": + gqlEndpoint = options.env.SETTLEMINT_THEGRAPH_SUBGRAPH_ENDPOINT; + output = "thegraph.schema.graphql"; + break; + case "THEGRAPH_FALLBACK": + gqlEndpoint = options.env.SETTLEMINT_THEGRAPH_SUBGRAPH_ENDPOINT_FALLBACK; + output = "thegraph-fallback.schema.graphql"; + } + + if (!gqlEndpoint) { + return; + } + + const headers = { + ...(adminSecret && { "x-hasura-admin-secret": adminSecret }), + "x-auth-token": accessToken, + "Content-Type": "application/json", + }; + + try { + // Test the endpoint with a simple introspection query + const response = await fetch(gqlEndpoint, { + method: "POST", + headers, + body: JSON.stringify({ + query: ` + query { + __schema { + queryType { + name + } + } + } + `, + }), + }); + + if (!response.ok) { + throw new Error(`Failed to fetch schema: ${response.statusText}`); + } + + const data = await response.json(); + if (data.errors) { + throw new Error(`GraphQL errors: ${JSON.stringify(data.errors)}`); + } + + await generateSchema({ + input: gqlEndpoint, + output, + tsconfig: undefined, + headers, + }); + } catch (error) { + if (options.allowToFail) { + // ignore + } else { + throw error; + } + } +} diff --git a/packages/cli/src/commands/connect.ts b/packages/cli/src/commands/connect.ts index 171fed423..f5088d9d3 100644 --- a/packages/cli/src/commands/connect.ts +++ b/packages/cli/src/commands/connect.ts @@ -68,30 +68,28 @@ export function connectCommand(): Command { const portal = await portalPrompt(env, middleware, autoAccept); const hdPrivateKey = await hdPrivateKeyPrompt(env, privateKey, autoAccept); - await writeEnvSpinner( - { - SETTLEMINT_ACCESS_TOKEN: accessToken, - SETTLEMINT_INSTANCE: instance, - SETTLEMINT_WORKSPACE: workspace.id, - SETTLEMINT_APPLICATION: application.id, - SETTLEMINT_HASURA: hasura?.id, - SETTLEMINT_HASURA_ENDPOINT: hasura?.endpoints.find((endpoint) => endpoint.id === "graphql")?.displayValue, - SETTLEMINT_HASURA_ADMIN_SECRET: hasura?.credentials.find((credential) => credential.id === "admin-secret") - ?.displayValue, - SETTLEMINT_THEGRAPH: thegraph?.id, - SETTLEMINT_THEGRAPH_SUBGRAPH_ENDPOINT: thegraph?.endpoints.find((endpoint) => endpoint.id === "graphql") - ?.displayValue, - SETTLEMINT_THEGRAPH_SUBGRAPH_ENDPOINT_FALLBACK: thegraph?.endpoints.find( - (endpoint) => endpoint.id === "default-subgraph-graphql", - )?.displayValue, - SETTLEMINT_PORTAL: portal?.id, - SETTLEMINT_PORTAL_GRAPHQL_ENDPOINT: portal?.endpoints.find((endpoint) => endpoint.id === "graphql") - ?.displayValue, - SETTLEMINT_PORTAL_REST_ENDPOINT: portal?.endpoints.find((endpoint) => endpoint.id === "rest")?.displayValue, - SETTLEMINT_HD_PRIVATE_KEY: hdPrivateKey?.uniqueName, - }, - environment, - ); + await writeEnvSpinner({ + SETTLEMINT_ENVIRONMENT: environment, + SETTLEMINT_ACCESS_TOKEN: accessToken, + SETTLEMINT_INSTANCE: instance, + SETTLEMINT_WORKSPACE: workspace.id, + SETTLEMINT_APPLICATION: application.id, + SETTLEMINT_HASURA: hasura?.id, + SETTLEMINT_HASURA_ENDPOINT: hasura?.endpoints.find((endpoint) => endpoint.id === "graphql")?.displayValue, + SETTLEMINT_HASURA_ADMIN_SECRET: hasura?.credentials.find((credential) => credential.id === "admin-secret") + ?.displayValue, + SETTLEMINT_THEGRAPH: thegraph?.id, + SETTLEMINT_THEGRAPH_SUBGRAPH_ENDPOINT: thegraph?.endpoints.find((endpoint) => endpoint.id === "graphql") + ?.displayValue, + SETTLEMINT_THEGRAPH_SUBGRAPH_ENDPOINT_FALLBACK: thegraph?.endpoints.find( + (endpoint) => endpoint.id === "default-subgraph-graphql", + )?.displayValue, + SETTLEMINT_PORTAL: portal?.id, + SETTLEMINT_PORTAL_GRAPHQL_ENDPOINT: portal?.endpoints.find((endpoint) => endpoint.id === "graphql") + ?.displayValue, + SETTLEMINT_PORTAL_REST_ENDPOINT: portal?.endpoints.find((endpoint) => endpoint.id === "rest")?.displayValue, + SETTLEMINT_HD_PRIVATE_KEY: hdPrivateKey?.uniqueName, + }); outro("Connected to SettleMint"); }) diff --git a/packages/cli/src/commands/connect/write-env.spinner.ts b/packages/cli/src/commands/connect/write-env.spinner.ts index 03f5ac155..5399ff78a 100644 --- a/packages/cli/src/commands/connect/write-env.spinner.ts +++ b/packages/cli/src/commands/connect/write-env.spinner.ts @@ -16,13 +16,14 @@ import type { DotEnv } from "@settlemint/sdk-utils/validation"; * "development" * ); */ -export async function writeEnvSpinner(env: Partial, environment: string) { +export async function writeEnvSpinner(env: Partial) { return spinner({ - startMessage: `Saving .env.${environment} and .env.${environment}.local files`, - stopMessage: `Written .env.${environment} and .env.${environment}.local file`, + startMessage: `Saving .env.${env.SETTLEMINT_ENVIRONMENT} and .env.${env.SETTLEMINT_ENVIRONMENT}.local files`, + stopMessage: `Written .env.${env.SETTLEMINT_ENVIRONMENT} and .env.${env.SETTLEMINT_ENVIRONMENT}.local file`, task: async () => { await writeEnv( { + SETTLEMINT_ENVIRONMENT: env.SETTLEMINT_ENVIRONMENT, SETTLEMINT_INSTANCE: env.SETTLEMINT_INSTANCE, SETTLEMINT_WORKSPACE: env.SETTLEMINT_WORKSPACE, SETTLEMINT_APPLICATION: env.SETTLEMINT_APPLICATION, @@ -36,7 +37,6 @@ export async function writeEnvSpinner(env: Partial, environment: string) SETTLEMINT_PORTAL_REST_ENDPOINT: env.SETTLEMINT_PORTAL_REST_ENDPOINT, SETTLEMINT_HD_PRIVATE_KEY: env.SETTLEMINT_HD_PRIVATE_KEY, }, - environment, false, ); @@ -45,7 +45,6 @@ export async function writeEnvSpinner(env: Partial, environment: string) SETTLEMINT_ACCESS_TOKEN: env.SETTLEMINT_ACCESS_TOKEN, SETTLEMINT_HASURA_ADMIN_SECRET: env.SETTLEMINT_HASURA_ADMIN_SECRET, }, - environment, true, ); }, diff --git a/packages/hasura/package.json b/packages/hasura/package.json index 7ecbad78e..56690daab 100644 --- a/packages/hasura/package.json +++ b/packages/hasura/package.json @@ -48,7 +48,7 @@ }, "devDependencies": {}, "dependencies": { - "@settlemint/sdk-utils": "0.5.0", + "@settlemint/sdk-utils": "workspace:*", "graphql-request": "^7", "zod": "^3" }, diff --git a/packages/js/package.json b/packages/js/package.json index 3241876e9..158294978 100644 --- a/packages/js/package.json +++ b/packages/js/package.json @@ -54,7 +54,7 @@ "gql.tada": "^1", "graphql-request": "^7", "zod": "^3", - "@settlemint/sdk-utils": "0.5.0" + "@settlemint/sdk-utils": "workspace:*" }, "peerDependencies": {}, "engines": { diff --git a/packages/portal/package.json b/packages/portal/package.json index a9111e686..bb9889317 100644 --- a/packages/portal/package.json +++ b/packages/portal/package.json @@ -48,7 +48,7 @@ }, "devDependencies": {}, "dependencies": { - "@settlemint/sdk-utils": "0.5.0", + "@settlemint/sdk-utils": "workspace:*", "graphql-request": "^7", "zod": "^3" }, diff --git a/packages/thegraph/package.json b/packages/thegraph/package.json index 350efe61a..fe42afc72 100644 --- a/packages/thegraph/package.json +++ b/packages/thegraph/package.json @@ -48,7 +48,7 @@ }, "devDependencies": {}, "dependencies": { - "@settlemint/sdk-utils": "0.5.0", + "@settlemint/sdk-utils": "workspace:*", "graphql-request": "^7", "zod": "^3" }, diff --git a/packages/utils/package.json b/packages/utils/package.json index e33017f9e..81e1bfe81 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -63,6 +63,7 @@ "deepmerge-ts": "^7", "environment": "^1", "find-up": "^7", + "nano-spawn": "^0.1.0", "yocto-spinner": "^0.1", "yoctocolors": "^2" }, diff --git a/packages/utils/src/environment/load-env.ts b/packages/utils/src/environment/load-env.ts index c0f0a62a1..2368b3b45 100644 --- a/packages/utils/src/environment/load-env.ts +++ b/packages/utils/src/environment/load-env.ts @@ -1,5 +1,6 @@ import { join } from "node:path"; import { projectRoot } from "@/filesystem.js"; +import { cancel } from "@/terminal.js"; import { type DotEnv, DotEnvSchema, validate } from "@/validation.js"; import { config } from "@dotenvx/dotenvx"; import type { DotenvParseOutput } from "dotenv"; @@ -32,6 +33,7 @@ export async function loadEnv( export async function loadEnvironmentEnv( validateEnv: T, environment?: string, + override?: boolean, ): Promise { const projectDir = await projectRoot(); @@ -43,20 +45,24 @@ export async function loadEnvironmentEnv( ".env", ].map((file) => join(projectDir, file)); - let { parsed } = config({ path: paths, logLevel: "error" }); + let { parsed } = config({ path: paths, logLevel: "error", override: !!override }); if (!parsed) { parsed = {}; } - const envToUse = environment || parsed.SETTLEMINT_ENVIRONMENT; + const envToUse = environment || parsed.SETTLEMINT_ENVIRONMENT || "development"; if (envToUse && envToUse !== environment) { - return loadEnvironmentEnv(validateEnv, envToUse); + return loadEnvironmentEnv(validateEnv, envToUse, true); } if (validateEnv) { - return validate(DotEnvSchema, parsed); + try { + return validate(DotEnvSchema, parsed); + } catch (error) { + cancel((error as Error).message); + } } return parsed as T extends true ? DotEnv : DotenvParseOutput; diff --git a/packages/utils/src/environment/write-env.ts b/packages/utils/src/environment/write-env.ts index 0eeaa59c3..72c28a768 100644 --- a/packages/utils/src/environment/write-env.ts +++ b/packages/utils/src/environment/write-env.ts @@ -5,9 +5,12 @@ import type { DotEnv } from "@/validation.js"; import { config } from "@dotenvx/dotenvx"; import { deepmerge } from "deepmerge-ts"; -export async function writeEnv(env: Partial, environment: string, secrets: boolean) { +export async function writeEnv(env: Partial, secrets: boolean) { const projectDir = await projectRoot(); - const envFile = join(projectDir, secrets ? `.env.${environment}.local` : `.env.${environment}`); + const envFile = join( + projectDir, + secrets ? `.env.${env.SETTLEMINT_ENVIRONMENT}.local` : `.env.${env.SETTLEMINT_ENVIRONMENT}`, + ); let { parsed: currentEnv } = config({ path: envFile, diff --git a/packages/utils/src/terminal.ts b/packages/utils/src/terminal.ts index 349f3412c..278c18f58 100644 --- a/packages/utils/src/terminal.ts +++ b/packages/utils/src/terminal.ts @@ -3,4 +3,5 @@ export { cancel } from "./terminal/cancel.js"; export { intro } from "./terminal/intro.js"; export { note } from "./terminal/note.js"; export { outro } from "./terminal/outro.js"; +export { run } from "./terminal/run.js"; export { spinner } from "./terminal/spinner.js"; diff --git a/packages/utils/src/terminal/run.ts b/packages/utils/src/terminal/run.ts new file mode 100644 index 000000000..7e4d8287e --- /dev/null +++ b/packages/utils/src/terminal/run.ts @@ -0,0 +1,18 @@ +import spawn, { type Options } from "nano-spawn"; + +export async function run({ + command, + args, + options, +}: { + command: string; + args: string[]; + options?: Options; +}) { + const result = await spawn(command, args, { + preferLocal: true, + ...options, + }); + + return result.output; +}