README named --experimental-strip-types, which was renamed to --strip-types. Document the current flag only. The extension recommendations list is unchanged, but the VSCode section undercounted it and now matches extensions.json. The per-language formatter blocks in .vscode/settings.json stay (they keep a user's local formatter settings from overriding the project's) and gain the JSX/TSX language ids to match what oxfmt and the lefthook glob cover.
68 lines
5.9 KiB
Markdown
68 lines
5.9 KiB
Markdown
# tiny-pattern-ts
|
|
|
|
Pattern matching for TypeScript/ESM environments (F#-style, not regex).
|
|
|
|
## Development
|
|
|
|
- **Build:** `npm run build`
|
|
- **Test:** `npm run test`, `npm run test:ci`
|
|
- **Watch:** `npm run watch`
|
|
- **Checks:** `npm run check`, `npm run fix`
|
|
- **Verify:** `npm run verify` — the definition of done
|
|
- **Maintenance:** `npm run maintain` — advisory only
|
|
- **Individual fixes:** `npm run fix:oxfmt`, `npm run fix:oxlint`
|
|
|
|
What each tier runs, when it fires and what it costs:
|
|
[CONTRIBUTING.md § Feedback tiers](./CONTRIBUTING.md#feedback-tiers). How the
|
|
`prefix:` in a script name is chosen:
|
|
[§ Script prefix convention](./CONTRIBUTING.md#script-prefix-convention).
|
|
|
|
### Tooling
|
|
|
|
- **TypeScript 7** — type checker and build (`tsc`).
|
|
- **node --test** + `--strip-types` — test runner.
|
|
- **c8** — code coverage for `test:ci`.
|
|
- **oxlint** — Rust-based linter, with type-aware rules powered by **oxlint-tsgolint** (typescript-go).
|
|
- **oxfmt** — Rust-based formatter (Prettier-compatible). Formats JS/TS, JSON/JSONC, YAML, Markdown, MDX, and more; built-in `package.json` key sorting replaces `sort-package-json`.
|
|
- **cspell** — spell checking.
|
|
- **knip** — finds unused dependencies, exports, and files.
|
|
- **check-outdated** — reports dependencies behind the registry; it exits non-zero whenever _any_ dependency is outdated.
|
|
- **publint** — validates `package.json` for ESM publishing correctness.
|
|
- **@arethetypeswrong/cli** (`attw`) — validates `.d.ts` declarations against multiple module-resolution scenarios.
|
|
- **lefthook** — git hooks.
|
|
- **@spences10/pi-lsp** — read-only LSP code intelligence for AI coding agents (project-local `.pi/settings.json`). Talks to this repo's TypeScript 7 via `tsc --lsp --stdio`.
|
|
|
|
Each tool's configuration trade-off is recorded in [Tooling decisions](#tooling-decisions); when it runs is in [CONTRIBUTING.md § Feedback tiers](./CONTRIBUTING.md#feedback-tiers).
|
|
|
|
### Tooling decisions
|
|
|
|
The choice and configuration of each tool above is the result of deliberate trade-offs, not defaults. The non-obvious ones:
|
|
|
|
- **`tsconfig.json` extends `@tsconfig/strictest` + `@tsconfig/node26`**; `tsconfig.build.json` extends it to add the emit-only options (`declaration`, `sourceMap`, `outDir`, `target: es2024`, `rewriteRelativeImportExtensions: true`) and to exclude test files. This separation lets the editor and CI type-check from one config while the build emits from the other.
|
|
- **Source imports use `.ts` extensions** so `node --strip-types` resolves them at test time. `rewriteRelativeImportExtensions: true` in `tsconfig.build.json` rewrites them to `.js` in the emitted `dist/*` output, so consumers see conventional ESM imports.
|
|
- **Type-aware oxlint is enabled declaratively** via `options.typeAware: true` in `.oxlintrc.json` (powered by `oxlint-tsgolint`). The script commands stay clean — no CLI flag — and type-aware mode is a property of the config, not the invocation.
|
|
- **Source-level `oxlint-disable` directives** are used for known type-aware false positives (see `src/pattern.ts`, `src/match.ts`, `src/index.test.ts`). The disable lives next to the code it silences, not in `.oxlintrc.json`, so the trade-off is visible to anyone reading the source.
|
|
- **`knip --include dependencies,exports,files`** intentionally omits the `types` category, which produces systematic false positives for libraries whose exported types are part of the public API. The targeted scope keeps the signal high without config-file boilerplate.
|
|
- **`attw --profile esm-only`** is semantically correct: this package is intentionally ESM-only (no CommonJS shim), so CJS resolution scenarios are out of scope by design, not a bug.
|
|
- **`check:tsc` runs first** in the `npm run check` chain so a type error short-circuits the rest (faster feedback than letting oxlint/oxfmt run and then failing on tsc at the end).
|
|
- **The pre-commit hook sets the `LEFTHOOK_FILES` env var** to the staged-files list, and the affected scripts use `${LEFTHOOK_FILES:-<default>}` to default to the whole project when invoked manually. This keeps `package.json#scripts` as the single source of truth for the underlying commands — `lefthook.yml` only describes _what to run on which files_.
|
|
- **`tslib` and `type-fest` are deliberately not used.** `tslib` is a runtime helper for old ES3/ES5 targets (the project targets ES2024); `type-fest` was never imported. knip caught both.
|
|
- **`@spences10/pi-lsp` is pinned to `0.0.46` and is read-only by design.** The package inspects `node_modules/typescript`, sees major ≥ 7 with no `lib/tsserver.js` (true of the `typescript-go` / `tsgo` port), and spawns the repo's own `tsc --lsp --stdio` binary — no `typescript-language-server` dependency is required. Earlier releases (`≤ 0.0.10`) hard-wire to `typescript-language-server --stdio` and are TS6-only. The tool is _intermediate_ agent feedback (hover, references, definition, symbols, diagnostics); it has no rename / code-action / apply-edit surface, and never a correctness gate — `npm run check` / `verify` remain that.
|
|
|
|
### Requirements
|
|
|
|
- Node.js >= 26 (engines field; pinned via `.node-version`).
|
|
|
|
## VSCode integration
|
|
|
|
- Recommended extensions: see `.vscode/extensions.json` (oxc, cspell, TypeScript native-preview, EditorConfig, todo-tasks).
|
|
- TypeScript 7 is used via the `typescriptteam.native-preview` extension.
|
|
- oxc extension provides oxlint squiggles and oxfmt format-on-save; `.vscode/settings.json` pins it per language so a user's local `[language]` formatter settings cannot override the project's choice.
|
|
|
|
## Contributing
|
|
|
|
For maintainer and contributor docs — the script prefix convention, the feedback-tier system, the rules the tools don't enforce, and the publishing workflow — see [CONTRIBUTING.md](./CONTRIBUTING.md). AI coding agents: your entry point is [AGENTS.md](./AGENTS.md), which points back to CONTRIBUTING.md.
|
|
|
|
- Commit signing (GPG).
|
|
- Type-only tests use `expect-type`'s `expectTypeOf(...)` inside `node --test` cases.
|