diff --git a/turbo/generators/config.ts b/turbo/generators/config.ts new file mode 100644 index 00000000..a599d9a0 --- /dev/null +++ b/turbo/generators/config.ts @@ -0,0 +1,90 @@ +import { execSync } from "node:child_process"; +import type { PlopTypes } from "@turbo/gen"; + +interface PackageJson { + name: string; + scripts: Record; + dependencies: Record; + devDependencies: Record; +} + +export default function generator(plop: PlopTypes.NodePlopAPI): void { + plop.setGenerator("init", { + description: "Generate a new package for the Weather.io Monorepo", + prompts: [ + { + type: "input", + name: "name", + message: + "What is the name of the package? (You can skip the `@weatherio/` prefix)", + }, + { + type: "input", + name: "deps", + message: + "Enter a space separated list of dependencies you would like to install", + }, + ], + actions: [ + (answers) => { + if ("name" in answers && typeof answers.name === "string") { + if (answers.name.startsWith("@acme/")) { + answers.name = answers.name.replace("@acme/", ""); + } + } + return "Config sanitized"; + }, + { + type: "add", + path: "packages/{{ name }}/package.json", + templateFile: "templates/package.json.hbs", + }, + { + type: "add", + path: "packages/{{ name }}/tsconfig.json", + templateFile: "templates/tsconfig.json.hbs", + }, + { + type: "add", + path: "packages/{{ name }}/src/index.ts", + template: "export const name = '{{ name }}';", + }, + { + type: "modify", + path: "packages/{{ name }}/package.json", + async transform(content, answers) { + if ("deps" in answers && typeof answers.deps === "string") { + const pkg = JSON.parse(content) as PackageJson; + for (const dep of answers.deps.split(" ").filter(Boolean)) { + const version = await fetch( + `https://registry.npmjs.org/-/package/${dep}/dist-tags`, + ) + .then((res) => res.json()) + .then((json) => json.latest); + if (!pkg.dependencies) pkg.dependencies = {}; + pkg.dependencies[dep] = `^${version}`; + } + return JSON.stringify(pkg, null, 2); + } + return content; + }, + }, + async (answers) => { + /** + * Install deps and format everything + */ + if ("name" in answers && typeof answers.name === "string") { + // execSync("pnpm dlx sherif@latest --fix", { + // stdio: "inherit", + // }); + execSync("pnpm i", { stdio: "inherit" }); + execSync( + `pnpm prettier --write packages/${answers.name}/** --list-different`, + ); + return "Package scaffolded"; + } + return "Package not scaffolded"; + }, + ], + }); +} diff --git a/turbo/generators/templates/package.json.hbs b/turbo/generators/templates/package.json.hbs new file mode 100644 index 00000000..1748b3e7 --- /dev/null +++ b/turbo/generators/templates/package.json.hbs @@ -0,0 +1,30 @@ +{ + "name": "@weatherio/{{ name }}", + "private": true, + "version": "0.1.0", + "type": "module", + "exports": { + ".": "./src/index.ts" + }, + "license": "MIT", + "scripts": { + "clean": "rm -rf .turbo node_modules", + "format": "prettier --check . --ignore-path ../../.gitignore", + "lint": "eslint .", + "typecheck": "tsc --noEmit" + }, + "devDependencies": { + "@weatherio/eslint-config": "workspace:^0.2.0", + "@weatherio/prettier-config": "workspace:^0.1.0", + "@weatherio/tsconfig": "workspace:^0.1.0", + "eslint": "^8.56.0", + "prettier": "^3.1.1", + "typescript": "^5.3.3" + }, + "eslintConfig": { + "extends": [ + "@weatherio/eslint-config/base" + ] + }, + "prettier": "@weatherio/prettier-config" +} diff --git a/turbo/generators/templates/tsconfig.json.hbs b/turbo/generators/templates/tsconfig.json.hbs new file mode 100644 index 00000000..454bd360 --- /dev/null +++ b/turbo/generators/templates/tsconfig.json.hbs @@ -0,0 +1,8 @@ +{ + "extends": "@weatherio/tsconfig/base.json", + "compilerOptions": { + "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json" + }, + "include": ["*.ts", "src"], + "exclude": ["node_modules"] +}