diff --git a/templates/basic/package.json b/templates/basic/package.json index d908d04..8256b6f 100644 --- a/templates/basic/package.json +++ b/templates/basic/package.json @@ -3,6 +3,10 @@ "version": "0.0.0", "type": "module", "packageManager": "pnpm@9.10.0", + "publishConfig": { + "access": "public", + "directory": "dist" + }, "scripts": { "codegen": "build-utils prepare-v2", "build": "pnpm build-esm && pnpm build-annotate && pnpm build-cjs && build-utils pack-v2", @@ -10,6 +14,8 @@ "build-cjs": "babel build/esm --plugins @babel/transform-export-namespace-from --plugins @babel/transform-modules-commonjs --out-dir build/cjs --source-maps", "build-annotate": "babel build/esm --plugins annotate-pure-calls --out-dir build/esm --source-maps", "check": "tsc -b tsconfig.json", + "lint": "eslint \"**/{src,test,examples,scripts,dtslint}/**/*.{ts,mjs}\"", + "lint-fix": "pnpm lint --fix", "test": "vitest", "coverage": "vitest --coverage", "changeset-version": "changeset version && node scripts/version.mjs", @@ -28,6 +34,9 @@ "detective-typescript": "^11.1.0", "@types/node": "^22.5.4" }, + "dependencies": { + "effect": "latest" + }, "devDependencies": { "@babel/cli": "^7.24.8", "@babel/core": "^7.25.2", @@ -45,8 +54,8 @@ "@eslint/eslintrc": "3.1.0", "@eslint/js": "9.10.0", "@types/node": "^22.5.2", - "@typescript-eslint/eslint-plugin": "^8.3.0", - "@typescript-eslint/parser": "^8.3.0", + "@typescript-eslint/eslint-plugin": "^8.4.0", + "@typescript-eslint/parser": "^8.4.0", "@vitest/browser": "^2.0.5", "@vitest/coverage-v8": "^2.0.5", "@vitest/expect": "^2.0.5", @@ -66,7 +75,7 @@ "rimraf": "^6.0.1", "tsx": "^4.17.0", "typescript": "^5.6.2", - "vite": "^5.4.0", + "vite": "^5.4.3", "vitest": "^2.0.5" }, "effect": { diff --git a/templates/cli/.github/actions/setup/action.yml b/templates/cli/.github/actions/setup/action.yml new file mode 100644 index 0000000..50cd2ca --- /dev/null +++ b/templates/cli/.github/actions/setup/action.yml @@ -0,0 +1,21 @@ +name: Setup +description: Perform standard setup and install dependencies using pnpm. +inputs: + node-version: + description: The version of Node.js to install + required: true + default: 20.16.0 + +runs: + using: composite + steps: + - name: Install pnpm + uses: pnpm/action-setup@v3 + - name: Install node + uses: actions/setup-node@v4 + with: + cache: pnpm + node-version: ${{ inputs.node-version }} + - name: Install dependencies + shell: bash + run: pnpm install diff --git a/templates/cli/.github/actions/workflows/check.yml b/templates/cli/.github/actions/workflows/check.yml new file mode 100644 index 0000000..0a3430d --- /dev/null +++ b/templates/cli/.github/actions/workflows/check.yml @@ -0,0 +1,54 @@ +name: Check + +on: + workflow_dispatch: + pull_request: + branches: [main] + push: + branches: [main] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +permissions: {} + +jobs: + build: + name: Build + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - name: Install dependencies + uses: ./.github/actions/setup + + types: + name: Types + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - name: Install dependencies + uses: ./.github/actions/setup + - run: pnpm check + + lint: + name: Lint + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - name: Install dependencies + uses: ./.github/actions/setup + - run: pnpm lint + + test: + name: Test + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - name: Install dependencies + uses: ./.github/actions/setup + - run: pnpm test diff --git a/templates/cli/.github/actions/workflows/release.yml b/templates/cli/.github/actions/workflows/release.yml new file mode 100644 index 0000000..e69de29 diff --git a/templates/cli/.github/actions/workflows/snapshot.yml b/templates/cli/.github/actions/workflows/snapshot.yml new file mode 100644 index 0000000..ca2dfc7 --- /dev/null +++ b/templates/cli/.github/actions/workflows/snapshot.yml @@ -0,0 +1,24 @@ +name: Snapshot + +on: + pull_request: + branches: [main, next-minor, next-major] + workflow_dispatch: + +permissions: {} + +jobs: + snapshot: + name: Snapshot + if: github.repository_owner == 'Effect-Ts' + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + - name: Install dependencies + uses: ./.github/actions/setup + - name: Build package + run: pnpm build + - name: Create snapshot + id: snapshot + run: pnpx pkg-pr-new@0.0.24 publish --pnpm --comment=off diff --git a/templates/cli/.prettierignore b/templates/cli/.prettierignore new file mode 100644 index 0000000..e727c7d --- /dev/null +++ b/templates/cli/.prettierignore @@ -0,0 +1,3 @@ +*.js +*.ts +*.cjs diff --git a/templates/cli/.prettierrc.json b/templates/cli/.prettierrc.json new file mode 100644 index 0000000..27b720e --- /dev/null +++ b/templates/cli/.prettierrc.json @@ -0,0 +1,4 @@ +{ + "semi": false, + "trailingComma": "none" +} diff --git a/templates/cli/flake.lock b/templates/cli/flake.lock index 591b4c8..be7021c 100644 --- a/templates/cli/flake.lock +++ b/templates/cli/flake.lock @@ -2,11 +2,11 @@ "nodes": { "nixpkgs": { "locked": { - "lastModified": 1720955038, - "narHash": "sha256-GaliJqfFwyYxReFywxAa8orCO+EnDq2NK2F+5aSc8vo=", + "lastModified": 1725910328, + "narHash": "sha256-n9pCtzGZ0httmTwMuEbi5E78UQ4ZbQMr1pzi5N0LAG8=", "owner": "nixos", "repo": "nixpkgs", - "rev": "aa247c0c90ecf4ae7a032c54fdc21b91ca274062", + "rev": "5775c2583f1801df7b790bf7f7d710a19bac66f4", "type": "github" }, "original": { diff --git a/templates/cli/flake.nix b/templates/cli/flake.nix index 9e171b1..687a417 100644 --- a/templates/cli/flake.nix +++ b/templates/cli/flake.nix @@ -15,6 +15,7 @@ corepack deno nodejs + python3 ]; }; }); diff --git a/templates/cli/package.json b/templates/cli/package.json index a9d06f5..f63f436 100644 --- a/templates/cli/package.json +++ b/templates/cli/package.json @@ -1,37 +1,44 @@ { "name": "@template/cli", "version": "0.0.0", - "bin": "./dist/bin.cjs", + "type": "module", + "packageManager": "pnpm@9.10.0", "publishConfig": { "access": "public", "directory": "dist" }, - "packageManager": "pnpm@9.9.0", "scripts": { "build": "tsup && pnpm copy-package-json", "build:ts": "tsup", "clean": "rimraf dist/*", "check": "tsc -b tsconfig.json", - "lint": "eslint .", - "lint:fix": "pnpm lint --fix", - "coverage": "vitest run --coverage", + "lint": "eslint \"**/{src,test,examples,scripts,dtslint}/**/*.{ts,mjs}\"", + "lint-fix": "pnpm lint --fix", "test": "vitest run", - "copy-package-json": "tsx scripts/copy-package-json.ts" + "coverage": "vitest run --coverage", + "copy-package-json": "tsx scripts/copy-package-json.ts", + "changeset-version": "changeset version && node scripts/version.mjs", + "changeset-publish": "pnpm build && TEST_DIST= pnpm vitest && changeset publish" }, "devDependencies": { - "@effect/cli": "0.42.2", + "@changesets/changelog-github": "^0.5.0", + "@changesets/cli": "2.27.7", + "@effect/cli": "latest", "@effect/eslint-plugin": "^0.2.0", "@effect/language-service": "^0.1.0", - "@effect/platform": "^0.63.2", - "@effect/platform-node": "^0.58.2", - "@eslint/compat": "^1.1.1", - "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "^9.9.1", - "@types/node": "^22.5.4", + "@effect/platform": "latest", + "@effect/platform-node": "latest", + "@eslint/compat": "1.1.1", + "@eslint/eslintrc": "3.1.0", + "@eslint/js": "9.10.0", + "@types/node": "^22.5.2", "@typescript-eslint/eslint-plugin": "^8.4.0", "@typescript-eslint/parser": "^8.4.0", + "@vitest/browser": "^2.0.5", "@vitest/coverage-v8": "^2.0.5", - "effect": "3.7.2", + "@vitest/expect": "^2.0.5", + "@vitest/web-worker": "^2.0.5", + "effect": "latest", "eslint": "^9.9.1", "eslint-import-resolver-typescript": "^3.6.3", "eslint-plugin-codegen": "0.28.0", @@ -39,17 +46,23 @@ "eslint-plugin-import": "^2.30.0", "eslint-plugin-simple-import-sort": "^12.1.1", "eslint-plugin-sort-destructure-keys": "^2.0.0", + "fast-check": "^3.21.0", "glob": "^11.0.0", + "playwright": "^1.46.0", "prettier": "^3.3.3", "rimraf": "^6.0.1", "tsup": "^8.2.4", - "typescript": "^5.5.4", + "typescript": "^5.6.2", "vite": "^5.4.3", "vitest": "^2.0.5" }, "pnpm": { "overrides": { "vitest": "^2.0.5" + }, + "patchedDependencies": { + "@changesets/get-github-info@0.6.0": "patches/@changesets__get-github-info@0.6.0.patch", + "@changesets/assemble-release-plan@6.0.3": "patches/@changesets__assemble-release-plan@6.0.3.patch" } } } diff --git a/templates/cli/scripts/copy-package-json.ts b/templates/cli/scripts/copy-package-json.ts index 91cc0ce..e9d9710 100644 --- a/templates/cli/scripts/copy-package-json.ts +++ b/templates/cli/scripts/copy-package-json.ts @@ -1,44 +1,32 @@ -import * as NodeFileSystem from "@effect/platform-node/NodeFileSystem" -import * as FileSystem from "@effect/platform/FileSystem" -import { Effect, pipe } from "effect" -import * as path from "node:path" +import { FileSystem, Path } from "@effect/platform" +import { NodeContext } from "@effect/platform-node" +import { Effect } from "effect" -const read = pipe( - FileSystem.FileSystem, - Effect.flatMap((fileSystem) => fileSystem.readFileString("package.json")), - Effect.map((_) => JSON.parse(_)), - Effect.map((json) => ({ +const program = Effect.gen(function*() { + const fs = yield* FileSystem.FileSystem + const path = yield* Path.Path + yield* Effect.log("[Build] Copying package.json ...") + const json: any = yield* fs.readFileString("package.json").pipe(Effect.map(JSON.parse)) + const pkg = { name: json.name, version: json.version, + type: json.type, description: json.description, - bin: { - "effect-codemod": "main.js" - }, + main: "bin.cjs", + bin: "bin.cjs", engines: json.engines, + dependencies: json.dependencies, + peerDependencies: json.peerDependencies, repository: json.repository, author: json.author, license: json.license, bugs: json.bugs, homepage: json.homepage, tags: json.tags, - keywords: json.keywords, - dependencies: json.dependencies - })) -) + keywords: json.keywords + } + yield* fs.writeFileString(path.join("dist", "package.json"), JSON.stringify(pkg, null, 2)) + yield* Effect.log("[Build] Build completed.") +}).pipe(Effect.provide(NodeContext.layer)) -const pathTo = path.join("dist", "package.json") - -const write = (pkg: object) => - pipe( - FileSystem.FileSystem, - Effect.flatMap((fileSystem) => fileSystem.writeFileString(pathTo, JSON.stringify(pkg, null, 2))) - ) - -const program = pipe( - Effect.sync(() => console.log(`copying package.json to ${pathTo}...`)), - Effect.flatMap(() => read), - Effect.flatMap(write), - Effect.provide(NodeFileSystem.layer) -) - -Effect.runPromise(program) +Effect.runPromise(program).catch(console.error) diff --git a/templates/cli/tsconfig.base.json b/templates/cli/tsconfig.base.json new file mode 100644 index 0000000..11b73ca --- /dev/null +++ b/templates/cli/tsconfig.base.json @@ -0,0 +1,45 @@ +{ + "include": [], + "compilerOptions": { + "strict": true, + "moduleDetection": "force", + "composite": true, + "downlevelIteration": true, + "resolveJsonModule": true, + "esModuleInterop": false, + "declaration": true, + "skipLibCheck": true, + "exactOptionalPropertyTypes": true, + "emitDecoratorMetadata": false, + "experimentalDecorators": true, + "moduleResolution": "NodeNext", + "lib": ["ES2022", "DOM"], + "isolatedModules": true, + "sourceMap": true, + "declarationMap": true, + "noImplicitReturns": false, + "noUnusedLocals": true, + "noUnusedParameters": false, + "noFallthroughCasesInSwitch": true, + "noEmitOnError": false, + "noErrorTruncation": false, + "allowJs": false, + "checkJs": false, + "forceConsistentCasingInFileNames": true, + "stripInternal": true, + "noImplicitAny": true, + "noImplicitThis": true, + "noUncheckedIndexedAccess": false, + "strictNullChecks": true, + "baseUrl": ".", + "target": "ES2022", + "module": "NodeNext", + "incremental": true, + "removeComments": false, + "plugins": [{ "name": "@effect/language-service" }], + "paths": { + "@template/cli": ["./src/index.js"], + "@template/cli/*": ["./src/*.js"] + } + } +} diff --git a/templates/cli/tsconfig.eslint.json b/templates/cli/tsconfig.eslint.json deleted file mode 100644 index 4740a1d..0000000 --- a/templates/cli/tsconfig.eslint.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "compilerOptions": { - "exactOptionalPropertyTypes": true, - "noEmit": true, - "allowJs": true, - "baseUrl": "." - }, - "include": [ - "./.eslintrc.cjs", - "./src/**/*.ts", - "./test/**/*.ts", - "./public/**/*.ts", - "./vitest.config.ts", - "./tsup.config.ts", - "./scripts/**/*.ts" - ] -} diff --git a/templates/cli/tsconfig.json b/templates/cli/tsconfig.json index afa6494..fa6d058 100644 --- a/templates/cli/tsconfig.json +++ b/templates/cli/tsconfig.json @@ -1,23 +1,8 @@ { - "compilerOptions": { - "esModuleInterop": true, - "exactOptionalPropertyTypes": true, - "target": "ES2021", - "noEmit": true, - "module": "commonjs", - "moduleResolution": "node", - "lib": ["es6"], - "sourceMap": false, - "strict": true, - "noImplicitReturns": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noFallthroughCasesInSwitch": true, - "forceConsistentCasingInFileNames": true, - "stripInternal": true, - "skipLibCheck": true, - "types": ["vitest/globals"], - "plugins": [{ "name": "@effect/language-service" }] - }, - "include": ["./src", "./public", "./test"] + "extends": "./tsconfig.base.json", + "references": [ + { "path": "tsconfig.src.json" }, + { "path": "tsconfig.test.json" }, + { "path": "tsconfig.scripts.json" } + ] } diff --git a/templates/cli/tsconfig.scripts.json b/templates/cli/tsconfig.scripts.json new file mode 100644 index 0000000..5fc1c35 --- /dev/null +++ b/templates/cli/tsconfig.scripts.json @@ -0,0 +1,11 @@ + +{ + "extends": "./tsconfig.base.json", + "include": ["scripts", "eslint.config.mjs", "tsup.config.ts", "vitest.config.ts"], + "compilerOptions": { + "types": ["node"], + "tsBuildInfoFile": ".tsbuildinfo/scripts.tsbuildinfo", + "rootDir": "scripts", + "noEmit": true + } +} diff --git a/templates/cli/tsconfig.src.json b/templates/cli/tsconfig.src.json new file mode 100644 index 0000000..07b33eb --- /dev/null +++ b/templates/cli/tsconfig.src.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.base.json", + "include": ["src"], + "compilerOptions": { + "types": ["node"], + "tsBuildInfoFile": ".tsbuildinfo/src.tsbuildinfo", + "rootDir": "src", + "noEmit": true + } +} diff --git a/templates/cli/tsconfig.test.json b/templates/cli/tsconfig.test.json new file mode 100644 index 0000000..52509c9 --- /dev/null +++ b/templates/cli/tsconfig.test.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.base.json", + "include": ["test"], + "compilerOptions": { + "types": ["node"], + "tsBuildInfoFile": ".tsbuildinfo/test.tsbuildinfo", + "rootDir": "test", + "noEmit": true + } +}