From 4adc0e5391eba8a0ff76779b6f3641ff61305742 Mon Sep 17 00:00:00 2001 From: Pontus Abrahamsson Date: Sat, 7 Sep 2024 12:49:26 +0200 Subject: [PATCH] cli wip --- .github/workflows/cli.yml | 19 +++++++++++ cli/bun.lockb | Bin 0 -> 65669 bytes cli/package.json | 53 ++++++++++++++++++++++++++++++ cli/src/commands/init.ts | 36 ++++++++++++++++++++ cli/src/index.ts | 27 +++++++++++++++ cli/src/utils/get-package-info.ts | 9 +++++ cli/tsconfig.json | 15 +++++++++ cli/tsup.config.ts | 12 +++++++ package.json | 2 +- services/cal/config.json | 2 +- services/dub/config.json | 2 +- services/openpanel/config.json | 2 +- services/resend/config.json | 2 +- services/sentry/config.json | 2 +- services/trigger/config.json | 2 +- services/upstash/config.json | 2 +- 16 files changed, 179 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/cli.yml create mode 100755 cli/bun.lockb create mode 100644 cli/package.json create mode 100644 cli/src/commands/init.ts create mode 100644 cli/src/index.ts create mode 100644 cli/src/utils/get-package-info.ts create mode 100644 cli/tsconfig.json create mode 100644 cli/tsup.config.ts diff --git a/.github/workflows/cli.yml b/.github/workflows/cli.yml new file mode 100644 index 00000000..5d3526ed --- /dev/null +++ b/.github/workflows/cli.yml @@ -0,0 +1,19 @@ +name: CLI +on: + push: + paths: + - 'cli/**' +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: oven-sh/setup-bun@v1 + with: + bun-version: latest + - name: Install dependencies + run: bun install + - name: 🔦 Run linter + run: bun run lint + - name: 🪐 Check TypeScript + run: bun run typecheck \ No newline at end of file diff --git a/cli/bun.lockb b/cli/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..45095b2c44c7b5826e065ee72d043bd34b99825c GIT binary patch literal 65669 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 literal 0 HcmV?d00001 diff --git a/cli/package.json b/cli/package.json new file mode 100644 index 00000000..378dd64e --- /dev/null +++ b/cli/package.json @@ -0,0 +1,53 @@ +{ + "name": "v1-run", + "version": "0.0.1", + "description": "A CLI for v1", + "publishConfig": { + "access": "public" + }, + "license": "MIT", + "author": { + "name": "pontusab", + "url": "https://twitter.com/pontusab" + }, + "repository": { + "type": "git", + "url": "https://github.com/midday-ai/v1.git", + "directory": "cli" + }, + "files": ["dist"], + "keywords": ["nextjs"], + "type": "module", + "exports": "./dist/index.js", + "bin": "./dist/index.js", + "scripts": { + "dev": "tsup --watch", + "build": "tsup", + "typecheck": "tsc --noEmit", + "clean": "rimraf dist && rimraf components", + "start:dev": "node dist/index.js", + "start": "node dist/index.js", + "release": "changeset version", + "pub:beta": "pnpm build && pnpm publish --no-git-checks --access public --tag beta", + "pub:next": "pnpm build && pnpm publish --no-git-checks --access public --tag next", + "pub:release": "pnpm build && pnpm publish --access public", + "test": "vitest run" + }, + "dependencies": { + "chalk": "5.2.0", + "commander": "^10.0.0", + "fast-glob": "^3.3.2", + "fs-extra": "^11.1.0", + "ora": "^6.1.2", + "prompts": "^2.4.2", + "zod": "^3.23.8" + }, + "devDependencies": { + "@types/fs-extra": "^11.0.1", + "@types/prompts": "^2.4.2", + "rimraf": "^4.1.3", + "tsup": "^6.6.3", + "type-fest": "^3.8.0", + "typescript": "^4.9.3" + } +} diff --git a/cli/src/commands/init.ts b/cli/src/commands/init.ts new file mode 100644 index 00000000..ab604bf5 --- /dev/null +++ b/cli/src/commands/init.ts @@ -0,0 +1,36 @@ +import { existsSync } from "node:fs"; +import path from "node:path"; +import { Command } from "commander"; +import { z } from "zod"; + +const initOptionsSchema = z.object({ + cwd: z.string(), + yes: z.boolean(), + defaults: z.boolean(), +}); + +export const init = new Command() + .name("init") + .description("initialize your project and install dependencies") + .option("-y, --yes", "skip confirmation prompt.", false) + .option("-d, --defaults,", "use default configuration.", false) + .option( + "-c, --cwd ", + "the working directory. defaults to the current directory.", + process.cwd(), + ) + .action(async (opts) => { + try { + const options = initOptionsSchema.parse(opts); + const cwd = path.resolve(options.cwd); + + // Ensure target directory exists. + if (!existsSync(cwd)) { + // logger.error(`The path ${cwd} does not exist. Please try again.`); + process.exit(1); + } + } catch (error) { + console.error(error); + process.exit(1); + } + }); diff --git a/cli/src/index.ts b/cli/src/index.ts new file mode 100644 index 00000000..ac494d56 --- /dev/null +++ b/cli/src/index.ts @@ -0,0 +1,27 @@ +#!/usr/bin/env node +import { init } from "@/src/commands/init"; +import { Command } from "commander"; +import { getPackageInfo } from "./utils/get-package-info"; + +process.on("SIGINT", () => process.exit(0)); +process.on("SIGTERM", () => process.exit(0)); + +async function main() { + const packageInfo = await getPackageInfo(); + + const program = new Command() + .name("v1-run") + .description("Blah") + .version( + packageInfo.version || "1.0.0", + "-v, --version", + "display the version number", + ); + + program.addCommand(init); + // .addCommand(add).addCommand(diff); + + program.parse(); +} + +main(); diff --git a/cli/src/utils/get-package-info.ts b/cli/src/utils/get-package-info.ts new file mode 100644 index 00000000..4081f01e --- /dev/null +++ b/cli/src/utils/get-package-info.ts @@ -0,0 +1,9 @@ +import path from "node:path"; +import fs from "fs-extra"; +import type { PackageJson } from "type-fest"; + +export function getPackageInfo() { + const packageJsonPath = path.join("package.json"); + + return fs.readJSONSync(packageJsonPath) as PackageJson; +} diff --git a/cli/tsconfig.json b/cli/tsconfig.json new file mode 100644 index 00000000..c84f91f6 --- /dev/null +++ b/cli/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "@v1/typescript/base.json", + "compilerOptions": { + "isolatedModules": false, + "module": "preserve", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "baseUrl": ".", + "paths": { + "@/*": ["./*"] + } + }, + "include": ["src/**/*.ts"], + "exclude": ["node_modules"] +} diff --git a/cli/tsup.config.ts b/cli/tsup.config.ts new file mode 100644 index 00000000..30e7a114 --- /dev/null +++ b/cli/tsup.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + clean: true, + dts: true, + entry: ["src/index.ts"], + format: ["esm"], + sourcemap: true, + minify: true, + target: "esnext", + outDir: "dist", +}); diff --git a/package.json b/package.json index ac45fa09..dce33dbc 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "v1", "private": true, - "workspaces": ["packages/*", "apps/*", "tooling/*", "services/*", "cli/*"], + "workspaces": ["packages/*", "apps/*", "tooling/*", "services/*"], "scripts": { "build": "turbo build", "clean": "git clean -xdf node_modules", diff --git a/services/cal/config.json b/services/cal/config.json index 2f3b3af5..1625036f 100644 --- a/services/cal/config.json +++ b/services/cal/config.json @@ -1,5 +1,5 @@ { - "name": "cal", + "name": "Cal.com", "generate": { "src/example/index.tsx": "apps/web/src/app/talk-to-us/page.tsx" } diff --git a/services/dub/config.json b/services/dub/config.json index dd3691c4..26059d28 100644 --- a/services/dub/config.json +++ b/services/dub/config.json @@ -1,5 +1,5 @@ { - "name": "dub", + "name": "Dub", "envs": { "DUB_API_KEY": { "description": "The API key to use for Dub", diff --git a/services/openpanel/config.json b/services/openpanel/config.json index 1186691f..444337b9 100644 --- a/services/openpanel/config.json +++ b/services/openpanel/config.json @@ -1,5 +1,5 @@ { - "name": "openpanel", + "name": "OpenPanel", "envs": { "OPENPANEL_API_KEY": { "description": "The API key to use for OpenPanel", diff --git a/services/resend/config.json b/services/resend/config.json index 2826708b..e5461673 100644 --- a/services/resend/config.json +++ b/services/resend/config.json @@ -1,5 +1,5 @@ { - "name": "resend", + "name": "Resend", "envs": { "RESEND_API_KEY": { "description": "The API key to use for Resend", diff --git a/services/sentry/config.json b/services/sentry/config.json index eb15b556..8aa7b606 100644 --- a/services/sentry/config.json +++ b/services/sentry/config.json @@ -1,5 +1,5 @@ { - "name": "sentry", + "name": "Sentry", "envs": { "SENTRY_AUTH_TOKEN": { "description": "The auth token to use for Sentry", diff --git a/services/trigger/config.json b/services/trigger/config.json index a97dd4c9..0e5d04e2 100644 --- a/services/trigger/config.json +++ b/services/trigger/config.json @@ -1,5 +1,5 @@ { - "name": "trigger", + "name": "Trigger.dev", "envs": { "TRIGGER_API_KEY": { "description": "The API key to use for Trigger", diff --git a/services/upstash/config.json b/services/upstash/config.json index 7fb34103..2063aa27 100644 --- a/services/upstash/config.json +++ b/services/upstash/config.json @@ -1,5 +1,5 @@ { - "name": "upstash", + "name": "Upstash", "envs": { "UPSTASH_REDIS_REST_URL": { "description": "The URL to use for Upstash",