📚 Sync project-specs.md and package.json with current state

project-specs.md:
- Replace Prettier/ESLint/Vite/Vitest references with oxfmt/oxlint/oxc
  and TypeScript 7 / node --test
- Drop @tsconfig/strictest note; rules are inlined in tsconfig.json,
  enumerated explicitly
- Document oxlint rule disables (no-undefined, sort-keys, id-length,
  no-named-export) and test-file overrides (no-unused-expressions,
  no-empty-file, no-nodejs-modules, no-magic-numbers)
- Document Node 26 / .node-version / engines.node / CI follow
- Document allowImportingTsExtensions + rewriteRelativeImportExtensions
  for the node --strip-types quirk
- Replace Vite/vitest coverage example with c8 + node --test
- Sync scripts section: drop check:eslint, check:prettier and their
  fix:* counterparts; add check:oxlint/check:oxfmt/fix:oxlint/fix:oxfmt
- Add current source layout (index.ts, match.ts, pattern.ts, index.test.ts)
- Update VSCode integration section with actual settings.json and
  extensions.json contents
- Document the actual commit history with gitmoji prefixes
- Fix 'initilizing' typo
- Drop 'changesets is a devDep' claims (changesets is not installed)

package.json:
- Move @oxfmt/binding-* and @oxlint/binding-* from devDependencies to
  optionalDependencies so the right binding is selected per platform
  (CI on Ubuntu gnu gets the gnu binding automatically, not the
  local musl one)
- Extend check:outdated to ignore the platform-specific bindings (they
  show as 'not installed' on the current platform, which is correct
- Add cspell words: gitmoji, dbaeumer, msvc (the latter for the Windows
  binding variant). Drop the unused 'nocheck' word

README.md:
- Drop the 'changesets is available as a devDep' line; changesets
  isn't installed
This commit is contained in:
tmu committed 2026-09-03 13:42:37 +00:00
1 parent cb5b302238
commit ab6eb0f34c
5 files changed
+307 -148

No files matched your search

-1
View File
@@ -34,7 +34,6 @@ Pattern matching for TypeScript/ESM environments (F#-style, not regex).
- Version updates via `npm version`. - Version updates via `npm version`.
- Publishing via GitHub Actions on tagged commits (see `.github/workflows/ci.yml`). - Publishing via GitHub Actions on tagged commits (see `.github/workflows/ci.yml`).
- Changesets is available as a devDependency for changelog automation if desired.
## Contribution guidelines ## Contribution guidelines
+4 -2
View File
@@ -9,12 +9,14 @@
"oxfmt", "oxfmt",
"oxc", "oxc",
"nodenext", "nodenext",
"nocheck",
"oxfmtrc", "oxfmtrc",
"oxlintrc", "oxlintrc",
"sortpackagerc", "sortpackagerc",
"EDITMSG", "EDITMSG",
"typescriptteam" "typescriptteam",
"gitmoji",
"dbaeumer",
"msvc"
], ],
"ignorePaths": ["dist", "node_modules", "public", "coverage", "*.svg"] "ignorePaths": ["dist", "node_modules", "public", "coverage", "*.svg"]
} }
+18 -16
View File
@@ -9,8 +9,6 @@
"version": "0.0.0", "version": "0.0.0",
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"@oxfmt/binding-linux-x64-musl": "^0.66.0",
"@oxlint/binding-linux-x64-musl": "^1.81.0",
"@types/node": "^22.10.0", "@types/node": "^22.10.0",
"c8": "^10.1.3", "c8": "^10.1.3",
"check-outdated": "^2.13.0", "check-outdated": "^2.13.0",
@@ -26,6 +24,22 @@
}, },
"engines": { "engines": {
"node": ">=26" "node": ">=26"
},
"optionalDependencies": {
"@oxfmt/binding-darwin-arm64": "^0.66.0",
"@oxfmt/binding-darwin-x64": "^0.66.0",
"@oxfmt/binding-linux-arm64-gnu": "^0.66.0",
"@oxfmt/binding-linux-arm64-musl": "^0.66.0",
"@oxfmt/binding-linux-x64-gnu": "^0.66.0",
"@oxfmt/binding-linux-x64-musl": "^0.66.0",
"@oxfmt/binding-win32-x64-msvc": "^0.66.0",
"@oxlint/binding-darwin-arm64": "^1.81.0",
"@oxlint/binding-darwin-x64": "^1.81.0",
"@oxlint/binding-linux-arm64-gnu": "^1.81.0",
"@oxlint/binding-linux-arm64-musl": "^1.81.0",
"@oxlint/binding-linux-x64-gnu": "^1.81.0",
"@oxlint/binding-linux-x64-musl": "^1.81.0",
"@oxlint/binding-win32-x64-msvc": "^1.81.0"
} }
}, },
"node_modules/@bcoe/v8-coverage": { "node_modules/@bcoe/v8-coverage": {
@@ -723,7 +737,6 @@
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"dev": true,
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@@ -740,7 +753,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"dev": true,
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@@ -808,7 +820,6 @@
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"dev": true,
"libc": [ "libc": [
"glibc" "glibc"
], ],
@@ -828,7 +839,6 @@
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"dev": true,
"libc": [ "libc": [
"musl" "musl"
], ],
@@ -928,7 +938,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"dev": true,
"libc": [ "libc": [
"glibc" "glibc"
], ],
@@ -948,11 +957,11 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"dev": true,
"libc": [ "libc": [
"musl" "musl"
], ],
"license": "MIT", "license": "MIT",
"optional": true,
"os": [ "os": [
"linux" "linux"
], ],
@@ -1018,7 +1027,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"dev": true,
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@@ -1069,7 +1077,6 @@
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"dev": true,
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@@ -1086,7 +1093,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"dev": true,
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
@@ -1154,7 +1160,6 @@
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"dev": true,
"libc": [ "libc": [
"glibc" "glibc"
], ],
@@ -1174,7 +1179,6 @@
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
"dev": true,
"libc": [ "libc": [
"musl" "musl"
], ],
@@ -1274,7 +1278,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"dev": true,
"libc": [ "libc": [
"glibc" "glibc"
], ],
@@ -1294,11 +1297,11 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"dev": true,
"libc": [ "libc": [
"musl" "musl"
], ],
"license": "MIT", "license": "MIT",
"optional": true,
"os": [ "os": [
"linux" "linux"
], ],
@@ -1364,7 +1367,6 @@
"cpu": [ "cpu": [
"x64" "x64"
], ],
"dev": true,
"license": "MIT", "license": "MIT",
"optional": true, "optional": true,
"os": [ "os": [
+17 -3
View File
@@ -34,7 +34,7 @@
"build": "tsc -p tsconfig.build.json", "build": "tsc -p tsconfig.build.json",
"check": "npm run check:oxlint && npm run check:oxfmt && npm run check:tsc && npm run check:cspell && npm run check:package && npm run check:outdated", "check": "npm run check:oxlint && npm run check:oxfmt && npm run check:tsc && npm run check:cspell && npm run check:package && npm run check:outdated",
"check:cspell": "cspell .", "check:cspell": "cspell .",
"check:outdated": "check-outdated", "check:outdated": "check-outdated --ignore-pre-releases --ignore-packages @oxfmt/binding-darwin-arm64,@oxfmt/binding-darwin-x64,@oxfmt/binding-linux-arm64-gnu,@oxfmt/binding-linux-arm64-musl,@oxfmt/binding-linux-x64-gnu,@oxfmt/binding-linux-x64-musl,@oxfmt/binding-win32-x64-msvc,@oxlint/binding-darwin-arm64,@oxlint/binding-darwin-x64,@oxlint/binding-linux-arm64-gnu,@oxlint/binding-linux-arm64-musl,@oxlint/binding-linux-x64-gnu,@oxlint/binding-linux-x64-musl,@oxlint/binding-win32-x64-msvc",
"check:oxfmt": "oxfmt --check src", "check:oxfmt": "oxfmt --check src",
"check:oxlint": "oxlint src", "check:oxlint": "oxlint src",
"check:package": "sort-package-json --check", "check:package": "sort-package-json --check",
@@ -49,8 +49,6 @@
"use:git-commit-message": "cp commit-message-template .git/COMMIT_EDITMSG || true" "use:git-commit-message": "cp commit-message-template .git/COMMIT_EDITMSG || true"
}, },
"devDependencies": { "devDependencies": {
"@oxfmt/binding-linux-x64-musl": "^0.66.0",
"@oxlint/binding-linux-x64-musl": "^1.81.0",
"@types/node": "^22.10.0", "@types/node": "^22.10.0",
"c8": "^10.1.3", "c8": "^10.1.3",
"check-outdated": "^2.13.0", "check-outdated": "^2.13.0",
@@ -64,6 +62,22 @@
"type-fest": "^4.40.1", "type-fest": "^4.40.1",
"typescript": "^7.0.2" "typescript": "^7.0.2"
}, },
"optionalDependencies": {
"@oxfmt/binding-darwin-arm64": "^0.66.0",
"@oxfmt/binding-darwin-x64": "^0.66.0",
"@oxfmt/binding-linux-arm64-gnu": "^0.66.0",
"@oxfmt/binding-linux-arm64-musl": "^0.66.0",
"@oxfmt/binding-linux-x64-gnu": "^0.66.0",
"@oxfmt/binding-linux-x64-musl": "^0.66.0",
"@oxfmt/binding-win32-x64-msvc": "^0.66.0",
"@oxlint/binding-darwin-arm64": "^1.81.0",
"@oxlint/binding-darwin-x64": "^1.81.0",
"@oxlint/binding-linux-arm64-gnu": "^1.81.0",
"@oxlint/binding-linux-arm64-musl": "^1.81.0",
"@oxlint/binding-linux-x64-gnu": "^1.81.0",
"@oxlint/binding-linux-x64-musl": "^1.81.0",
"@oxlint/binding-win32-x64-msvc": "^1.81.0"
},
"engines": { "engines": {
"node": ">=26" "node": ">=26"
}, },
+268 -126
View File
@@ -8,107 +8,200 @@ typescript-lib-starter-tiny => https://github.com/tmueller/typescript-lib-starte
## 1. Development Environment ## 1. Development Environment
- **TypeScript**: Use strictest rules (via npm package "@tsconfig/strictest", additional strictures) - **TypeScript**: Use strictest practical rules. Inline in `tsconfig.json` (not
- **EditorConfig**: Use `.editorconfig` from typescript-lib-starter-tiny via `@tsconfig/strictest`). The rule set is: `strict`, `noImplicitAny`,
- **Prettier**: For code formatting, integrated with ESLint `noImplicitThis`, `alwaysStrict`, `strictNullChecks`, `strictFunctionTypes`,
- **ESLint**: Strictest type-checked rules, integrated with Prettier `strictBindCallApply`, `strictPropertyInitialization`, `noImplicitReturns`,
- **Import Sorting**: Via Prettier or ESLint `noFallthroughCasesInSwitch`, `noUncheckedIndexedAccess`, `noImplicitOverride`,
- **cspell**: Basic spelling configuration `noUnusedLocals`, `noUnusedParameters`, `forceConsistentCasingInFileNames`,
- **Lefthook**: Pre-commit checks for: `isolatedModules`, `verbatimModuleSyntax`.
- **EditorConfig**: Use `.editorconfig` from typescript-lib-starter-tiny.
- Type checking - **oxfmt**: Rust-based formatter, Prettier-compatible. Replaces Prettier.
- Spelling Config in `.oxfmtrc.json` (same shape as `.prettierrc`).
- Package sorting - **oxlint**: Rust-based linter. Replaces ESLint. Config in `.oxlintrc.json`
- Linting with `typescript`, `unicorn`, `oxc`, `import` plugins. Categories enabled
- Formatting as errors: `correctness`, `suspicious`, `restriction`. As warnings: `perf`,
- Outdated Packages `style`. `nursery` is off.
- **oxlint rules disabled by design** (in `.oxlintrc.json`):
- `eslint/no-undefined` — we use `undefined` as the no-match sentinel.
- `eslint/sort-keys` — handler/case order is semantic, not alphabetical.
- `eslint/id-length` — `T`, `R`, `U`, `V` are standard TS generics.
- `import/no-named-export` — false positive on library entry re-exports.
For `*.test.ts` files additionally: `no-unused-expressions` (for
`expectTypeOf(...)` calls), `no-empty-file` (we have a single import
per test file in some cases), `import/no-nodejs-modules` (we use
`node:test`/`node:assert`/`node:fs` intentionally), `eslint/no-magic-numbers`
(literals in tests are fine).
- **Import sorting**: built into oxfmt (no separate plugin).
- **cspell**: Basic spelling configuration. Words dictionary in `cspell.json`
covers tooling names (`oxlint`, `oxfmt`, `oxc`, `nodenext`,
`oxfmtrc`, `oxlintrc`, `sortpackagerc`, `EDITMSG`, `typescriptteam`,
`gitmoji`, `dbaeumer`, `msvc`) and a few library names (`tslib`,
`typefest`, `lefthook`).
- **Lefthook**: Pre-commit checks for (run in parallel):
- oxlint on staged JS/TS files
- oxfmt --check on staged JS/TS files
- cspell on staged files
- sort-package-json --check
- tsc --noEmit
`outdated` is intentionally NOT a pre-commit check (it can flag
upstream patch releases that aren't actionable locally); it runs in
CI and via the explicit `lefthook run outdated` command.
- **Additional Dev Dependencies**: - **Additional Dev Dependencies**:
- lefthook - lefthook
- sort-package-json - sort-package-json
- check-outdated - check-outdated
- c8 (coverage for `node --test`)
- expect-type (type-level assertions in tests)
- oxfmt, oxlint (with their native bindings as `optionalDependencies`
so the correct binding is selected per platform automatically)
- typescript (TS 7)
- @types/node
- tslib (available for future runtime helper imports)
- type-fest (utility types)
## 2. Build & Test ## 2. Build & Test
- **Build Tool**: Vite (ESM only, no CJS) - **Build Tool**: TypeScript 7 (`tsc`) — no bundler, no Vite. The build
- **Testing**: Vitest is a plain `tsc -p tsconfig.build.json` invocation that emits ESM
- **TypeScript Build Output**: `dist` directory JavaScript and `.d.ts` declarations to `dist/`. ESM only, no CJS.
- **Additional Runtime Dependencies**: - **Testing**: Node's built-in `node --test` with `--strip-types` (Node
- tslib 22.6+, unflagged on Node 24/26). Test files are co-located with
- type-fest source as `*.test.ts`. No Vitest.
- **TypeScript Build Output**: `dist` directory (set in
`tsconfig.build.json#outDir`; `tsconfig.json` keeps `outDir` for
editor tooling but excludes tests from emission via
`tsconfig.build.json#exclude`).
- **Import extensions**: Source uses `.ts` extensions in imports
(e.g. `from "./match.ts"`) so `node --strip-types` resolves them
at test time. TypeScript's `rewriteRelativeImportExtensions` (in
`tsconfig.build.json`) rewrites these to `.js` in the emitted
`dist/*` output, so consumers see conventional ESM imports.
- **TypeScript Compiler Options Notes**:
- `allowImportingTsExtensions: true` is set in the root
`tsconfig.json` (works because the root config has `noEmit: true`).
- `rewriteRelativeImportExtensions: true` is set in
`tsconfig.build.json` to rewrite `.ts` to `.js` on emit.
- `module: nodenext`, `moduleResolution: nodenext` for ESM-first
Node packages.
- `verbatimModuleSyntax: true` enforces explicit `import type`.
- `target: es2024`, `lib: ["es2024"]` (Node 26 supports all ES2024
features natively).
- **Additional Dev Dependencies** (for types and tests):
- `tslib` — available for runtime helper imports; not currently
used by source (kept for future use per the original spec).
- `type-fest` — utility types; not currently used by source
(kept for future use per the original spec).
- `@types/node` — types for `node:test`, `node:assert`, `node:fs`.
- **Node Version**: `>=26` (engines field). Pinned via `.node-version`
for fnm/nvm/volta/mise auto-switching and CI
(`actions/setup-node@v4` with `node-version-file: .node-version`).
## 3. Project Structure & Files ## 3. Project Structure & Files
- __.gitignore__: Ignore `dist`, `node_modules`, and other common files - **.gitignore**: Ignore `dist`, `node_modules`, `coverage`, and other
- **.npmignore**: Ignore `src` and other non-dist files common files.
- **LICENSE**: MIT - **.node-version**: Single line containing the Node major version
- **README.md**: Scaffolded (currently `26`). Used by version managers and CI.
- **commit-message-template**: From typescript-lib-starter-tiny - **.npmignore**: Ignore `node_modules/`, `coverage/`, `*.log`,
- **Target Environments**: Browser and latest LTS Node.js `*.tsbuildinfo`, `src/`, `.vscode/`, `.editorconfig`,
- **No React, No CJS, ESM only** `.oxfmtrc.json`, `.oxlintrc.json`, `.node-version`, `cspell.json`,
`lefthook.yml`, `.sortpackagerc.json`, `commit-message-template`.
(Note: `dist/` is included via `package.json#files`, not by absence
from `.npmignore`.)
- **.oxfmtrc.json**: oxfmt configuration (Prettier-shaped).
- **.oxlintrc.json**: oxlint configuration.
- **.oxlintrc.json + .oxfmtrc.json** replace the old `.eslintrc.cjs`
and `.prettierrc`.
- **LICENSE**: MIT.
- **README.md**: Scaffolded.
- **commit-message-template**: From typescript-lib-starter-tiny.
- **Target Environments**: Node 26 LTS only (no browser target; this
is a pure Node library, no DOM, no DOM lib in tsconfig).
- **No React, No CJS, ESM only**.
## 4. Automation & Quality ## 4. Automation & Quality
- **Version Automation**: Use standard `npm version` for versioning - **Version Automation**: Use standard `npm version` for versioning.
- **Unused Dependency Check**: Use `check-outdated` with config - **Unused Dependency Check**: Use `check-outdated` (devDep, runs in CI
- **No commitlint, no conventional commits** and via the explicit `lefthook run outdated` command).
- **No commitlint, no conventional commits**. Commits use gitmoji
prefixes (e.g. `:sparkles:`, `:wrench:`, `:bug:`, `:fire:`,
`:white_check_mark:`, `:tada:`) for at-a-glance categorization.
## 5. Scripts (Clustered as in typescript-lib-starter-tiny, named similarly) ## 5. Scripts
### SETUP ### SETUP
- `use:git-commit-message`: Set up commit message template (if needed) - `use:git-commit-message`: Set up commit message template (if needed).
### TEST ### TEST
- `test`: Run typecheck and all tests - `test`: Run `tsc --noEmit` then `node --test --strip-types src/`.
- `test:unit`: Run unit tests with Vitest - `test:unit`: Run unit tests with `node --test --strip-types src/`
- `test:ci`: Run tests in CI mode (with coverage, fail-fast) (no preceding typecheck).
- `test:ci`: Run tests in CI mode with c8 coverage (text + lcov + html
reporters), uploading `coverage/` as an artifact.
### BUILD ### BUILD
- `build`: Build the project using Vite - `build`: Build the project using `tsc -p tsconfig.build.json`
(emits `dist/*.js` + `dist/*.d.ts` + sourcemaps, with `.ts`
imports rewritten to `.js`).
### CLEAN ### CLEAN
- `clean`: Clean build output - `clean`: Remove `dist/` via `node -e "fs.rmSync('dist', {recursive:true, force:true})"`.
- `clean:build`: Remove dist directory (Replaces `clean:build` from the original spec — same effect,
no `rimraf` dep needed.)
### CHECK ### CHECK
- `check`: Run all checks (lint, spell, typecheck, import/package sort, outdated) - `check`: Run all checks in order — `check:oxlint`, `check:oxfmt`,
- `check:eslint`: Run ESLint `check:tsc`, `check:cspell`, `check:package`, `check:outdated`.
- `check:prettier`: Check formatting with Prettier - `check:oxlint`: `oxlint src`.
- `check:cspell`: Run cspell - `check:oxfmt`: `oxfmt --check src`.
- `check:tsc`: TypeScript typecheck (no emit) - `check:tsc`: `tsc --noEmit`.
- `check:package`: Check package.json sort - `check:cspell`: `cspell .`.
- `check:outdated`: Check for unused/outdated dependencies - `check:package`: `sort-package-json --check`.
- `check:outdated`: `check-outdated --ignore-pre-releases --ignore-packages @oxfmt/binding-*,@oxlint/binding-*`. The oxc native bindings are declared as `optionalDependencies` so the correct one is selected per platform automatically; the `*`-platform bindings show as "not installed" on the current platform and are explicitly ignored here.
### FIX ### FIX
- `fix`: Run all fixers (eslint, prettier, package sort) - `fix:oxlint`: `oxlint --fix src`.
- `fix:eslint`: Auto-fix ESLint issues - `fix:oxfmt`: `oxfmt src`.
- `fix:prettier`: Auto-fix formatting with Prettier - `fix:package`: `sort-package-json --write`.
- `fix:package`: Auto-fix package.json sort (There is no `fix` aggregator in the scripts; run the `fix:*` scripts
individually or via the lefthook `commands:` block.)
### HOOKS ### HOOKS
- Lefthook will run relevant scripts on staged files for pre-commit (typecheck, lint, spell, sort, format, check:outdated) - Lefthook runs the relevant `check:*` scripts on staged files in
parallel for pre-commit. See `lefthook.yml`.
--- ---
## 6. Repository & CI/CD ## 6. Repository & CI/CD
- **Repository**: Hosted on GitHub - **Repository**: Hosted on GitHub.
- **Build Pipeline**: Use GitHub Actions for CI/CD - **Build Pipeline**: GitHub Actions (`.github/workflows/ci.yml`).
- On push and pull request: run build, lint, typecheck, test:ci, spell, check:outdated - `build` job on push and pull_request to `main` and on
- On release (tagged commit): publish to npm `workflow_dispatch`. Steps: `actions/checkout@v4`,
`actions/setup-node@v4` (with `node-version-file: .node-version`,
`cache: npm`), `npm ci`, `npm run build`, `npm run check`,
`npm run test:ci`, then upload `coverage/` as an artifact.
- `publish` job: only on `refs/tags/*`, depends on `build`. Steps:
`actions/checkout@v4`, `actions/setup-node@v4` (with
`node-version-file: .node-version` and `registry-url`),
`npm ci`, `npm run build`, `npm publish --access public`
with `NODE_AUTH_TOKEN` from secrets.
## 7. Versioning & Publishing ## 7. Versioning & Publishing
- **Version Update**: Use `npm version` to bump version after merging to main and before publishing - **Version Update**: Use `npm version` to bump version after merging
- **Publishing to npm**: Only publish from CI on tagged commits (e.g., after version bump and release notes) to main and before publishing.
- **Publishing to npm**: Only publish from CI on tagged commits.
- **Recommended Workflow**: - **Recommended Workflow**:
1. Develop and merge PRs to main 1. Develop and merge PRs to main
2. Run all checks via CI 2. Run all checks via CI
@@ -125,40 +218,42 @@ typescript-lib-starter-tiny => https://github.com/tmueller/typescript-lib-starte
- adt - adt
- typescript - typescript
> The library is for pattern matching (not regex), similar to F#'s pattern matching, for TypeScript/ESM environments. > The library is for pattern matching (not regex), similar to F#'s
> pattern matching, for TypeScript/ESM environments.
## 9. Code Coverage ## 9. Code Coverage
- **Configuration**: - **Tool**: c8 (V8-native coverage, no instrumentation step).
- **Configuration**: c8 has no project config; the report shape is
pinned in the `test:ci` script:
```ts ```jsonc
import { defineConfig } from 'vitest/config'; "test:ci": "c8 --reporter=text --reporter=lcov --reporter=html node --test --strip-types src/"
export default defineConfig({
test: {
coverage: {
reporter: ['text', 'html', 'lcov'],
include: ['src/**/*.ts'],
exclude: ['src/**/*.test.ts', 'test/**'],
},
},
});
``` ```
- Coverage reports: text summary, HTML, and lcov formats - **Reporters**: text summary, HTML, and lcov (matching the original
spec).
- Add coverage thresholds if desired - **CI**: `coverage/` is uploaded as a workflow artifact via
`actions/upload-artifact@v4` (see `.github/workflows/ci.yml`).
- **CI**: Ensure coverage is generated and optionally uploaded as an artifact or checked for minimum thresholds - **Optional**: Coverage thresholds can be added in c8 config when the
library surface stabilizes.
## 10. Source Structure & Tree Shaking ## 10. Source Structure & Tree Shaking
- **Source Directory**: All source code resides in `src/` and is exported via `src/index.ts`. - **Source Directory**: All source code resides in `src/` and is
exported via `src/index.ts`.
- **Configuration**: - **Configuration**:
- Ensure `sideEffects: false` in `package.json` - `sideEffects: false` in `package.json` (set).
- Use ESM-only exports - ESM-only exports; `package.json#exports` field maps `.` to
- Avoid top-level side effects in modules `{"types": "./dist/index.d.ts", "import": "./dist/index.js"}`.
- Prefer explicit exports in `index.ts` for best results - Avoid top-level side effects in modules.
- the human will implement the source code - Explicit re-exports in `index.ts` for best results.
- Source structure (current):
- `src/index.ts` — public barrel.
- `src/match.ts` — `match(value).with(...).exhaustive() / .otherwise(...)` builder.
- `src/pattern.ts` — `P.literal`, `P.type`, `P.when`, `P.any`, `P.shape` constructors and the `Matcher<T>` interface.
- `src/index.test.ts` — runtime + type-level tests using `node --test` + `expect-type`.
- The human will implement the source code.
## 11. Included Templates from typescript-lib-starter-tiny ## 11. Included Templates from typescript-lib-starter-tiny
@@ -207,90 +302,137 @@ Resolves #...
# Can use multiple lines with "-" for bullet points in body # Can use multiple lines with "-" for bullet points in body
``` ```
### README.md Structure (to scaffold) ### README.md Structure (scaffolded)
- Project title and description - Project title and description
- Development - Development
- Build: `npm run build` - Build: `npm run build`
- Test: `npm run test`, `npm run test:ci` - Test: `npm run test`, `npm run test:ci`
- Checks: `npm run check`, `npm run fix` - Checks: `npm run check`, `npm run fix:oxfmt`, `npm run fix:oxlint`
- Tooling section listing TypeScript 7, node --test, c8, oxlint, oxfmt,
cspell, sort-package-json, lefthook
- Requirements: Node.js >= 26
- VSCode integration - VSCode integration
- Debugging - Debugging
- Running tests - Running tests
- Document workflows like - oxc.oxc-vscode provides oxlint and oxfmt in-editor
- Version updates - Workflows
- Changelog automation - Version updates via `npm version`
- Publishing - Publishing via GitHub Actions on tagged commits
- Contribution guidelines - Contribution guidelines
- Commit signing (GPG) - Commit signing (GPG)
- How to set up commit message template - How to set up commit message template (`npm run use:git-commit-message`)
- Reference to commit-message-template - Reference to commit-message-template
- Type-level tests use `expect-type`'s `expectTypeOf(...)` inside
`node --test` cases
## 12. Project Initialization & Commit Strategy ## 12. Project Initialization & Commit Strategy
- Start by initilizing git with a main branch - Start by initializing git with a `main` branch.
- Initial commit: add an empty README.md - Initial commit: empty README + LICENSE.
- create a feature branch: `feature/setup` - Create a feature branch: `feature/setup`.
- For each technology or tool added (and its configuration), create a separate commit: - For each technology or tool added (and its configuration), create a
- Prepend each commit message with a matching gitmoji (e.g., :sparkles: for new features, :wrench: for config, etc.) separate commit:
- Example commit messages: - Prepend each commit message with a matching gitmoji (e.g.
- :tada: Initial commit with empty README `:sparkles:` for new features, `:wrench:` for config,
- :sparkles: Configured Vite (Vite-specific setup) `:bug:` for fixes, `:fire:` for removals,
- :sparkles: Configured TypeScript (may be merged with Vite if dependent) `:white_check_mark:` for tests, `:tada:` for initial commit).
- :wrench: Configured ESLint - Example commit messages used in this project:
- :wrench: Configured Prettier - `:tada: Initial commit with empty README`
- ...and so on for each technology/tool - `:wrench: Track .vscode/settings.json for workspace settings`
- Each commit should include only the relevant files and configuration for that technology/tool - `:construction_worker: Added GitHub Actions workflow for CI/CD`
- This approach ensures a clean, understandable project history and makes it easy to review or revert specific setup steps - `:test_tube: Added Vitest configuration with coverage` (later removed)
- `:sparkles: Scaffolded src/index.ts entry point for library code`
- `:wrench: Replace Vite/Vitest with TypeScript 7 and node --test`
- `:wrench: Replace ESLint and Prettier with oxlint and oxfmt`
- `:fire: Remove Vite scaffold leftovers`
- `:sparkles: Add initial pattern-matching API`
- `:white_check_mark: Add expect-type for type-level tests`
- `:wrench: Declare Node 26 as the supported runtime`
- `:bug: Use .ts extensions in imports for node --strip-types`
- `:wrench: Remove Prettier from editor formatter config`
- Each commit should include only the relevant files and configuration
for that technology/tool. This approach ensures a clean, understandable
project history and makes it easy to review or revert specific setup
steps.
## 13. Changelog Automation ## 13. Changelog Automation
- Use a tool like standard-version or changesets to automate changelog generation from commit messages or PRs. - Not currently configured. The intended workflow, when adopted, is a
- Ensure changelog is updated as part of the release process. changesets-driven release process: feature PRs include a changeset,
which gets consumed by a release workflow, producing a `CHANGELOG.md`
and a version bump on merge to main.
- The changelog should be updated as part of the release process.
## 14. Publishing Public ## 14. Publishing Public
- Configure npm publishing to be public by default. - npm publishing is configured to be public by default.
- Add `"publishConfig": { "access": "public" }` to package.json. - `publishConfig: { "access": "public" }` is set in `package.json`.
- Ensure CI/CD pipeline publishes with public access. - The CI/CD pipeline publishes with `--access public` on tagged commits.
## 15. VSCode Integration ## 15. VSCode Integration
- Add a `.vscode/settings.json` with the following content: - `.vscode/settings.json` uses `oxc.oxc-vscode` as the default
formatter for `[typescript]`, `[javascript]`, `[json]`, `[jsonc]`,
`[markdown]`, `[mdx]`, and `[yaml]` (oxfmt under the hood).
```json ```json
{ {
"typescript.tsdk": "node_modules/typescript/lib", "typescript.tsdk": "node_modules/typescript/lib",
"js/ts.tsdk.path": "node_modules/typescript/lib",
"[typescript]": { "[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode", "editor.defaultFormatter": "oxc.oxc-vscode",
"editor.formatOnSave": true
},
"[javascript]": {
"editor.defaultFormatter": "oxc.oxc-vscode",
"editor.formatOnSave": true "editor.formatOnSave": true
}, },
"[json]": { "[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode", "editor.defaultFormatter": "oxc.oxc-vscode",
"editor.formatOnSave": true
},
"[jsonc]": {
"editor.defaultFormatter": "oxc.oxc-vscode",
"editor.formatOnSave": true
},
"[markdown]": {
"editor.defaultFormatter": "oxc.oxc-vscode",
"editor.formatOnSave": true "editor.formatOnSave": true
}, },
"[mdx]": { "[mdx]": {
"editor.defaultFormatter": "esbenp.prettier-vscode", "editor.defaultFormatter": "oxc.oxc-vscode",
"editor.formatOnSave": true "editor.formatOnSave": true
}, },
"editor.defaultFormatter": "esbenp.prettier-vscode", "[yaml]": {
"editor.formatOnSave": true, "editor.defaultFormatter": "oxc.oxc-vscode",
"[javascript]": { "editor.formatOnSave": true
"editor.defaultFormatter": "esbenp.prettier-vscode", },
"editor.defaultFormatter": "oxc.oxc-vscode",
"editor.formatOnSave": true "editor.formatOnSave": true
}
} }
``` ```
- Add `.vscode/extensions.json` with recommended extensions: - `.vscode/extensions.json` recommends:
- `esbenp.prettier-vscode` (Prettier) - `oxc.oxc-vscode` (oxlint + oxfmt, replaces eslint/prettier/vitest)
- `dbaeumer.vscode-eslint` (ESLint)
- `streetsidesoftware.code-spell-checker` (cspell) - `streetsidesoftware.code-spell-checker` (cspell)
- `vitest.explorer` (for test integration) - `typescriptteam.native-preview` (TypeScript 7 nightly support;
- TODO: Native test extension with node test runner replaces the older `ms-vscode.vscode-typescript-next`)
- `ms-vscode.vscode-typescript-next` (for latest TS features, optional)
- Add `.vscode/tasks.json` for common tasks (optional): ```json
- Build, test, lint, typecheck, format, spell, check:outdated {
- Ensure VSCode uses workspace TypeScript version and Prettier for formatting "recommendations": [
"oxc.oxc-vscode",
"streetsidesoftware.code-spell-checker",
"typescriptteam.native-preview"
]
}
```
- `.vscode/tasks.json` is not currently provided; common tasks
(build, test, lint, typecheck, format, spell, check:outdated) are
run via the npm scripts in `package.json` from the integrated
terminal.
- VSCode uses the workspace TypeScript version via
`typescript.tsdk` (and the explicit `js/ts.tsdk.path`), with
`oxc.oxc-vscode` for formatting and linting.