diff --git a/.gitignore b/.gitignore index a3c807c..accc0fa 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,6 @@ build/ dist/ node_modules/ -*.tsbuildinfo +scratchpad/* +!scratchpad/tsconfig.json +*.tsbuildinfo \ No newline at end of file diff --git a/templates/basic/.envrc b/templates/basic/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/templates/basic/.envrc @@ -0,0 +1 @@ +use flake diff --git a/templates/basic/.gitignore b/templates/basic/.gitignore new file mode 100644 index 0000000..6e3593a --- /dev/null +++ b/templates/basic/.gitignore @@ -0,0 +1,12 @@ +coverage/ +*.tsbuildinfo +node_modules/ +.DS_Store +tmp/ +dist/ +build/ +docs/ +scratchpad/* +!scratchpad/tsconfig.json +.direnv/ +.idea/ diff --git a/templates/basic/.madgerc b/templates/basic/.madgerc new file mode 100644 index 0000000..b407c6b --- /dev/null +++ b/templates/basic/.madgerc @@ -0,0 +1,7 @@ +{ + "detectiveOptions": { + "ts": { + "skipTypeImports": true + } + } +} diff --git a/templates/basic/.prettierignore b/templates/basic/.prettierignore new file mode 100644 index 0000000..e727c7d --- /dev/null +++ b/templates/basic/.prettierignore @@ -0,0 +1,3 @@ +*.js +*.ts +*.cjs diff --git a/templates/basic/.prettierrc.json b/templates/basic/.prettierrc.json new file mode 100644 index 0000000..27b720e --- /dev/null +++ b/templates/basic/.prettierrc.json @@ -0,0 +1,4 @@ +{ + "semi": false, + "trailingComma": "none" +} diff --git a/templates/basic/.vscode/settings.json b/templates/basic/.vscode/settings.json new file mode 100644 index 0000000..59f05cb --- /dev/null +++ b/templates/basic/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "typescript.tsdk": "node_modules/typescript/lib", + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnSave": true, +} diff --git a/templates/basic/README.md b/templates/basic/README.md new file mode 100644 index 0000000..460e66b --- /dev/null +++ b/templates/basic/README.md @@ -0,0 +1 @@ +# Effect Basic Package Template \ No newline at end of file diff --git a/templates/basic/deno.json b/templates/basic/deno.json new file mode 100644 index 0000000..6134d86 --- /dev/null +++ b/templates/basic/deno.json @@ -0,0 +1,3 @@ +{ + "unstable": ["byonm"] +} diff --git a/templates/basic/eslint.config.mjs b/templates/basic/eslint.config.mjs new file mode 100644 index 0000000..90e2807 --- /dev/null +++ b/templates/basic/eslint.config.mjs @@ -0,0 +1,122 @@ +import { fixupPluginRules } from "@eslint/compat" +import { FlatCompat } from "@eslint/eslintrc" +import js from "@eslint/js" +import tsParser from "@typescript-eslint/parser" +import codegen from "eslint-plugin-codegen" +import deprecation from "eslint-plugin-deprecation" +import _import from "eslint-plugin-import" +import simpleImportSort from "eslint-plugin-simple-import-sort" +import sortDestructureKeys from "eslint-plugin-sort-destructure-keys" +import path from "node:path" +import { fileURLToPath } from "node:url" + +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) +const compat = new FlatCompat({ + baseDirectory: __dirname, + recommendedConfig: js.configs.recommended, + allConfig: js.configs.all +}) + +export default [ + { + ignores: ["**/dist", "**/build", "**/docs", "**/*.md"] + }, + ...compat.extends( + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", + "plugin:@effect/recommended" + ), + { + plugins: { + deprecation, + import: fixupPluginRules(_import), + "sort-destructure-keys": sortDestructureKeys, + "simple-import-sort": simpleImportSort, + codegen + }, + + languageOptions: { + parser: tsParser, + ecmaVersion: 2018, + sourceType: "module" + }, + + settings: { + "import/parsers": { + "@typescript-eslint/parser": [".ts", ".tsx"] + }, + + "import/resolver": { + typescript: { + alwaysTryTypes: true + } + } + }, + + rules: { + "codegen/codegen": "error", + "no-fallthrough": "off", + "no-irregular-whitespace": "off", + "object-shorthand": "error", + "prefer-destructuring": "off", + "sort-imports": "off", + + "no-restricted-syntax": ["error", { + selector: "CallExpression[callee.property.name='push'] > SpreadElement.arguments", + message: "Do not use spread arguments in Array.push" + }], + + "no-unused-vars": "off", + "prefer-rest-params": "off", + "prefer-spread": "off", + "import/first": "error", + "import/newline-after-import": "error", + "import/no-duplicates": "error", + "import/no-unresolved": "off", + "import/order": "off", + "simple-import-sort/imports": "off", + "sort-destructure-keys/sort-destructure-keys": "error", + "deprecation/deprecation": "off", + + "@typescript-eslint/array-type": ["warn", { + default: "generic", + readonly: "generic" + }], + + "@typescript-eslint/member-delimiter-style": 0, + "@typescript-eslint/no-non-null-assertion": "off", + "@typescript-eslint/ban-types": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-empty-interface": "off", + "@typescript-eslint/consistent-type-imports": "warn", + + "@typescript-eslint/no-unused-vars": ["error", { + argsIgnorePattern: "^_", + varsIgnorePattern: "^_" + }], + + "@typescript-eslint/ban-ts-comment": "off", + "@typescript-eslint/camelcase": "off", + "@typescript-eslint/explicit-function-return-type": "off", + "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/interface-name-prefix": "off", + "@typescript-eslint/no-array-constructor": "off", + "@typescript-eslint/no-use-before-define": "off", + "@typescript-eslint/no-namespace": "off", + + "@effect/dprint": ["error", { + config: { + indentWidth: 2, + lineWidth: 120, + semiColons: "asi", + quoteStyle: "alwaysDouble", + trailingCommas: "never", + operatorPosition: "maintain", + "arrowFunction.useParentheses": "force" + } + }] + } + } +] diff --git a/templates/basic/flake.lock b/templates/basic/flake.lock new file mode 100644 index 0000000..591b4c8 --- /dev/null +++ b/templates/basic/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1720955038, + "narHash": "sha256-GaliJqfFwyYxReFywxAa8orCO+EnDq2NK2F+5aSc8vo=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "aa247c0c90ecf4ae7a032c54fdc21b91ca274062", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/templates/basic/flake.nix b/templates/basic/flake.nix new file mode 100644 index 0000000..687a417 --- /dev/null +++ b/templates/basic/flake.nix @@ -0,0 +1,23 @@ +{ + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable"; + }; + outputs = {nixpkgs, ...}: let + forAllSystems = function: + nixpkgs.lib.genAttrs nixpkgs.lib.systems.flakeExposed + (system: function nixpkgs.legacyPackages.${system}); + in { + formatter = forAllSystems (pkgs: pkgs.alejandra); + devShells = forAllSystems (pkgs: { + default = pkgs.mkShell { + packages = with pkgs; [ + bun + corepack + deno + nodejs + python3 + ]; + }; + }); + }; +} diff --git a/templates/basic/package.json b/templates/basic/package.json new file mode 100644 index 0000000..b435a6d --- /dev/null +++ b/templates/basic/package.json @@ -0,0 +1,29 @@ +{ + "name": "@template/basic", + "version": "0.0.0", + "type": "module", + "private": true, + "scripts": { + "codegen": "build-utils prepare-v2", + "build": "pnpm build-esm && pnpm build-annotate && pnpm build-cjs && build-utils pack-v2", + "build-esm": "tsc -b tsconfig.build.json", + "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", + "test": "vitest", + "coverage": "vitest --coverage" + }, + "devDependencies": {}, + "effect": { + "generateExports": { + "include": [ + "**/*.ts" + ] + }, + "generateIndex": { + "include": [ + "**/*.ts" + ] + } + } +} diff --git a/templates/basic/patches/babel-plugin-annotate-pure-calls@0.4.0.patch b/templates/basic/patches/babel-plugin-annotate-pure-calls@0.4.0.patch new file mode 100644 index 0000000..6659c82 --- /dev/null +++ b/templates/basic/patches/babel-plugin-annotate-pure-calls@0.4.0.patch @@ -0,0 +1,13 @@ +diff --git a/lib/index.js b/lib/index.js +index 2182884e21874ebb37261e2375eec08ad956fc9a..ef5630199121c2830756e00c7cc48cf1078c8207 100644 +--- a/lib/index.js ++++ b/lib/index.js +@@ -78,7 +78,7 @@ const isInAssignmentContext = path => { + + parentPath = _ref.parentPath; + +- if (parentPath.isVariableDeclaration() || parentPath.isAssignmentExpression()) { ++ if (parentPath.isVariableDeclaration() || parentPath.isAssignmentExpression() || parentPath.isClassDeclaration()) { + return true; + } + } while (parentPath !== statement); diff --git a/templates/basic/scratchpad/tsconfig.json b/templates/basic/scratchpad/tsconfig.json new file mode 100644 index 0000000..4bcbc7c --- /dev/null +++ b/templates/basic/scratchpad/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "declaration": false, + "declarationMap": false, + "composite": false, + "incremental": false + } +} diff --git a/templates/basic/setupTests.ts b/templates/basic/setupTests.ts new file mode 100644 index 0000000..62c5d03 --- /dev/null +++ b/templates/basic/setupTests.ts @@ -0,0 +1,3 @@ +import * as it from "@effect/vitest" + +it.addEqualityTesters() diff --git a/templates/basic/src/Program.ts b/templates/basic/src/Program.ts new file mode 100644 index 0000000..2e3ea6f --- /dev/null +++ b/templates/basic/src/Program.ts @@ -0,0 +1,3 @@ +import * as Effect from "effect/Effect" + +Effect.runPromise(Effect.log("Hello, World!")) diff --git a/templates/basic/test/Dummy.test.ts b/templates/basic/test/Dummy.test.ts new file mode 100644 index 0000000..7736992 --- /dev/null +++ b/templates/basic/test/Dummy.test.ts @@ -0,0 +1,7 @@ +import { describe, expect, it } from "@effect/vitest" + +describe("Dummy", () => { + it("should pass", () => { + expect(true).toBe(true) + }) +}) diff --git a/templates/basic/tsconfig.base.json b/templates/basic/tsconfig.base.json new file mode 100644 index 0000000..fc7664c --- /dev/null +++ b/templates/basic/tsconfig.base.json @@ -0,0 +1,40 @@ +{ + "compilerOptions": { + "strict": true, + "exactOptionalPropertyTypes": true, + "moduleDetection": "force", + "composite": true, + "downlevelIteration": true, + "resolveJsonModule": true, + "esModuleInterop": false, + "declaration": true, + "skipLibCheck": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "moduleResolution": "NodeNext", + "lib": ["ES2022", "DOM", "DOM.Iterable"], + "types": [], + "isolatedModules": true, + "sourceMap": true, + "declarationMap": true, + "noImplicitReturns": false, + "noUnusedLocals": true, + "noUnusedParameters": false, + "noFallthroughCasesInSwitch": true, + "noEmitOnError": false, + "noErrorTruncation": false, + "allowJs": false, + "checkJs": false, + "forceConsistentCasingInFileNames": true, + "noImplicitAny": true, + "noImplicitThis": true, + "noUncheckedIndexedAccess": false, + "strictNullChecks": true, + "baseUrl": ".", + "target": "ES2022", + "module": "NodeNext", + "incremental": true, + "removeComments": false, + "plugins": [{ "name": "@effect/language-service" }] + } +} diff --git a/templates/basic/tsconfig.build.json b/templates/basic/tsconfig.build.json new file mode 100644 index 0000000..152f93d --- /dev/null +++ b/templates/basic/tsconfig.build.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.src.json", + "compilerOptions": { + "types": ["node"], + "tsBuildInfoFile": ".tsbuildinfo/build.tsbuildinfo", + "outDir": "build/esm", + "declarationDir": "build/dts", + "stripInternal": true + } +} diff --git a/templates/basic/tsconfig.json b/templates/basic/tsconfig.json new file mode 100644 index 0000000..2c291d2 --- /dev/null +++ b/templates/basic/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.base.json", + "include": [], + "references": [ + { "path": "tsconfig.src.json" }, + { "path": "tsconfig.test.json" } + ] +} diff --git a/templates/basic/tsconfig.src.json b/templates/basic/tsconfig.src.json new file mode 100644 index 0000000..375b1f0 --- /dev/null +++ b/templates/basic/tsconfig.src.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["src"], + "compilerOptions": { + "types": ["node"], + "outDir": "build/src", + "tsBuildInfoFile": ".tsbuildinfo/src.tsbuildinfo", + "rootDir": "src" + } +} diff --git a/templates/basic/tsconfig.test.json b/templates/basic/tsconfig.test.json new file mode 100644 index 0000000..2fbcc00 --- /dev/null +++ b/templates/basic/tsconfig.test.json @@ -0,0 +1,13 @@ +{ + "extends": "../../tsconfig.base.json", + "include": ["test"], + "references": [ + { "path": "tsconfig.src.json" } + ], + "compilerOptions": { + "types": ["node"], + "tsBuildInfoFile": ".tsbuildinfo/test.tsbuildinfo", + "rootDir": "test", + "noEmit": true + } +} diff --git a/templates/basic/vitest.config.ts b/templates/basic/vitest.config.ts new file mode 100644 index 0000000..d8c9907 --- /dev/null +++ b/templates/basic/vitest.config.ts @@ -0,0 +1,18 @@ +/// +import path from "path" +import { defineConfig } from "vite" + +export default defineConfig({ + plugins: [], + test: { + setupFiles: [path.join(__dirname, "setupTests.ts")], + include: ["./test/**/*.test.ts"], + globals: true + }, + resolve: { + alias: { + "@template/basic/test": path.join(__dirname, "test"), + "@template/basic": path.join(__dirname, "src") + } + } +}) diff --git a/templates/monorepo/.gitignore b/templates/monorepo/.gitignore index 17765fb..6e3593a 100644 --- a/templates/monorepo/.gitignore +++ b/templates/monorepo/.gitignore @@ -6,6 +6,7 @@ tmp/ dist/ build/ docs/ -scratchpad/ +scratchpad/* +!scratchpad/tsconfig.json .direnv/ .idea/ diff --git a/templates/monorepo/scratchpad/tsconfig.json b/templates/monorepo/scratchpad/tsconfig.json new file mode 100644 index 0000000..4bcbc7c --- /dev/null +++ b/templates/monorepo/scratchpad/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "noEmit": true, + "declaration": false, + "declarationMap": false, + "composite": false, + "incremental": false + } +}