Refactor union resolution to explicitly try reference members before non-reference members. This replaces the previous error-message-based fallback with a deterministic, structural approach. - Update `parseValueWithReferences` and `resolveNestedReferences` to partition members by reference presence. - Update documentation in `README.md`, `AGENTS.md`, and `syntax-rework-plan.md` to reflect this behavior.
3.3 KiB
3.3 KiB
AGENTS.md
Commands
- Build:
npm run build(tsup, CJS + ESM + d.ts for all entry points) - Test:
npm run test(vitest run) |npm run test:watch(vitest watch) - Type check:
npm run typecheck - Run a single test:
npx vitest run -t "test name pattern"
No linter or formatter is configured. No CI pipeline exists.
Architecture
Single-package TypeScript library with two runtime entry points:
-
typed-csv(src/index.ts) — core schema parser, value parser, and validatorsrc/parser.ts—parseSchema()turns schema strings into AST (Schematype)src/validator.ts—parseValue()andcreateValidator()operate on the ASTsrc/types.ts— union typeSchema = Primitive | Tuple | Array | Reference | StringLiteral | Union
-
typed-csv/csv-loader(src/csv-loader/loader.ts) — CSV loader with@tablereference resolutionloader.ts—parseCsv()(eager resolution) andcsvToModule()(accessor-based output with lazy resolution);resolveReferences: falsemode stores IDs instead of resolved objectswebpack.ts,rollup.ts,esbuild.ts— bundler plugin wrappers aroundcsvToModule
Build produces separate bundles per entry point (see tsup.config.ts). The csv-loader entries externalize csv-parse, @rspack/core, esbuild, and rollup.
Key conventions
- Schema syntax uses semicolons (
;) as separators, not commas - Unknown identifiers throw a
ParseError— only recognized keywords (string,number,int,float,boolean) and string literals ("on",'off') are valid types - Tuple and array values must be wrapped in brackets
[](e.g.[a; b]);[single]is a 1-tuple, not an array — useType[]for arrays @tablename/@tablename[]are reference schemas resolved at CSV load timecsvToModule()emits accessor functions (getData()) for tables with references, and static JSON for tables without; bundler loaders all usecsvToModuleparseCsv({ resolveReferences: false })stores reference IDs instead of resolved objects — used bycsvToModuleto emit import-based lazy resolution- References can appear nested inside tuples, arrays, and unions; the loader resolves them recursively
Gotchas
- Circular references between CSV tables are supported in
csvToModuleoutput via accessor-based lazy resolution.parseCsv()withresolveReferences: true(default) still detects and throws on circular references via an in-progress loading set. - Run
npm run typecheckbefore committing to catch type errors. - Union member ordering — In unions containing references, reference members are tried before non-reference members (regardless of author order), so
@users | stringresolves1to the user object and falls back to a plain string only when the reference doesn't match.parseValue(no references) still tries members in author order; the first that parses wins. - csv-parse quote handling — Double-quoted schema values like
"active" | "inactive"in CSV rows confuse the csv-parse library. Use single-quoted string literals ('on' | 'off') or unquoted identifiers in the schema row of CSV data when possible. - Module imports use
.jsextension — source files import from../index.jsetc. (ESM convention), not../index.ts.