From fc2d1acf41ae5607806a0ac116350391edec1bbd Mon Sep 17 00:00:00 2001 From: Noah Schatz Date: Fri, 25 Sep 2026 22:10:32 +0000 Subject: [PATCH] Prepare the 0.1.0 release: the 0.1 changeset, metadata and current examples docs The operator directed every package to 0.1.x. The pending queue already resolves to 0.1.0; this adds what the release still lacked: - A minor changeset stating what 0.1 means to someone using the package: what is covered, what the version promises below 1.0 (a breaking change bumps the minor and is called out in the changelog) and what is not covered. Changesets writes it into CHANGELOG.md as the 0.1.0 entry. - release/0.1.0-readiness.md accounts for it: a classification row, the pending and minor counts (34 and 19), and a line in the break-candidate accounting. scripts/release-readiness.ts reports "OK: ready to release 0.1.0". - package.json: keywords, homepage https://docs.cosyte.com/hl7. description, repository and bugs were already right. - README: the two out-of-scope lines pointed at a future @cosyte/hl7-mllp and a future FHIR bridge; they now name @cosyte/mllp and @cosyte/transform, which exist. - examples/README.md and scripts/run-examples.ts: drop the internal plan and example labels and the note that `pnpm examples` would be wired later; it is wired, and the extras CI job runs it. The examples, the runner and the extras job were confirmed complete and current: `pnpm examples` passes all three against the built package. No change under src/. Claude-Session: https://claude.ai/code/session_01U24bnHKNxQWMxmfN7ny7w9 --- .changeset/first-minor-release.md | 32 +++++++++++++++++++++++++++++++ README.md | 4 ++-- examples/README.md | 15 ++++++++------- package.json | 10 +++++++--- release/0.1.0-readiness.md | 12 ++++++++---- scripts/run-examples.ts | 6 +++--- 6 files changed, 60 insertions(+), 19 deletions(-) create mode 100644 .changeset/first-minor-release.md diff --git a/.changeset/first-minor-release.md b/.changeset/first-minor-release.md new file mode 100644 index 0000000..62c582d --- /dev/null +++ b/.changeset/first-minor-release.md @@ -0,0 +1,32 @@ +--- +"@cosyte/hl7": minor +--- + +**This is 0.1.0, the first release of `@cosyte/hl7` whose public API we treat as settled.** + +What is covered, and what you can build against: + +- Parsing HL7 v2 in one line with `parseHL7`: lenient by default, so the deviations real feeds carry + come back as stable warning codes rather than exceptions, with MLLP framing stripped, and a strict + mode for when you want a refusal instead. Batch files and multi-gigabyte streams (`parseStream`) + parse too. +- Reading without the spec: named helpers (`msg.patient`, `msg.visit`, `msg.observations()`, + `msg.allergies()`, `msg.medications()`, `msg.immunizations()` and more), dot-paths, and structural + traversal, with every datetime kept at the precision and zone it arrived with. +- Writing: `setField` and the segment methods mutate explicitly, the typed builders assemble ADT, ORM, + ORU, SIU, MDM, DFT and VXU messages, and the serializer always emits spec-clean HL7. +- Checking: conformance profiles you define and validate against, the opt-in + `validateMessageStructure` against HL7's published message structures, typed overlays that narrow + a message to its type, and JSON Schema and Zod emission for `toJSON()` output. + +What the version promises. The exported functions, the message and helper surfaces, and the warning +and finding codes are the surface we keep stable: renaming a warning code is a breaking change. While +the package is below 1.0, a breaking change bumps the minor version (0.1 to 0.2) and is called out in +this changelog; a fix that changes no public value ships as a patch. Upgrading from 0.0.10 is itself +breaking in a few places, each named in the entries below: `buildAdt` now refuses a merge trigger +with no prior identity, and several types and profile rules narrow. + +What is not covered. There is no network transport: MLLP framing is stripped on read, and sending +or receiving over a socket belongs to `@cosyte/mllp`. The parser does not convert HL7 v2 to FHIR +(that is `@cosyte/transform`), it reads v2 only (not v3 or CDA), and it validates structure rather +than every coded value against every HL7 table. diff --git a/README.md b/README.md index 143cb2b..c5451b5 100644 --- a/README.md +++ b/README.md @@ -1295,9 +1295,9 @@ What lands next starts as a quirk sighting or a real-world edge case on the [iss ### Out of scope (permanently) -- **MLLP framing / network transport**: a future `@cosyte/hl7-mllp` package will cover network IO; this library is parser-only. +- **Network transport**: sending and receiving over MLLP is [`@cosyte/mllp`](https://github.com/cosyte/mllp)'s job; this library is parser-only and only strips MLLP framing on read. - **HL7 v3 and CDA**: different spec family entirely; not in our plans. -- **FHIR conversion**: a future companion package could bridge, but the conversion is non-trivial and deserves its own repo. +- **FHIR conversion**: [`@cosyte/transform`](https://github.com/cosyte/transform) converts a parsed message to FHIR R4; this library does not. - **Exhaustive coded-value validation**: we validate structure, not every HL7 table. Integrate a domain validator (e.g. your LIS's internal code registry) for that. --- diff --git a/examples/README.md b/examples/README.md index faeed49..f9108f0 100644 --- a/examples/README.md +++ b/examples/README.md @@ -4,18 +4,19 @@ Three runnable TypeScript scripts that demonstrate the one-line-extraction value prop of `@cosyte/hl7`. Each example reads a synthetic HL7 fixture from `examples/data/`, calls the library, and prints labeled human-readable output via `console.log`. Run them from the repo root with -`pnpm tsx examples/.ts`, or run all three at once via -`pnpm examples` (wired by Plan 08-05; invokes `scripts/run-examples.ts`). +`pnpm tsx examples/.ts`, or run all three at once with +`pnpm examples`, which runs `scripts/run-examples.ts` and fails if an +example exits non-zero or stops printing its expected output. All three fixtures use synthetic patient identifiers only, no PHI. ## Files -| Example | Demonstrates | Run | -| --------------------------------- | ------------------------------------------------------------------------- | --------------------------------------------- | -| `extract-patient-info.ts` (EX-01) | Named-helper access: `msg.patient` + `msg.meta` one-liners. | `pnpm tsx examples/extract-patient-info.ts` | -| `read-lab-results.ts` (EX-02) | Collection iteration: `msg.observations()` over an ORU^R01 with 3 OBXs. | `pnpm tsx examples/read-lab-results.ts` | -| `modify-and-resend.ts` (EX-03) | Mutation + round-trip: `msg.setField(...)` then `msg.toString()`. | `pnpm tsx examples/modify-and-resend.ts` | +| Example | Demonstrates | Run | +| ------------------------- | ----------------------------------------------------------------------- | ------------------------------------------- | +| `extract-patient-info.ts` | Named-helper access: `msg.patient` + `msg.meta` one-liners. | `pnpm tsx examples/extract-patient-info.ts` | +| `read-lab-results.ts` | Collection iteration: `msg.observations()` over an ORU^R01 with 3 OBXs. | `pnpm tsx examples/read-lab-results.ts` | +| `modify-and-resend.ts` | Mutation + round-trip: `msg.setField(...)` then `msg.toString()`. | `pnpm tsx examples/modify-and-resend.ts` | ## Fixtures (`examples/data/`) diff --git a/package.json b/package.json index d82a5f9..dc5fbae 100644 --- a/package.json +++ b/package.json @@ -5,15 +5,19 @@ "keywords": [ "hl7", "hl7v2", + "hl7-v2", "parser", + "builder", + "serializer", "healthcare", "interoperability", "typescript", - "builder", - "serializer", + "adt", + "oru", + "mllp", "toolkit" ], - "homepage": "https://github.com/cosyte/hl7#readme", + "homepage": "https://docs.cosyte.com/hl7", "bugs": { "url": "https://github.com/cosyte/hl7/issues" }, diff --git a/release/0.1.0-readiness.md b/release/0.1.0-readiness.md index b5b4541..4bd75fe 100644 --- a/release/0.1.0-readiness.md +++ b/release/0.1.0-readiness.md @@ -24,8 +24,9 @@ changeset in this queue was originally filed asking for `patch`, because the rep contributor guidance told every contributor to pick `patch` while that ladder held. A queue classified that way resolves to `0.0.11` no matter what is in it. -What is in it is not a `0.0.11`. Every declaration classified `minor` below adds behaviour a -consumer can call that did not exist before: five new typed message builders, conformance condition +What is in it is not a `0.0.11`. Every declaration classified `minor` below, except the release +statement `first-minor-release.md`, adds behaviour a consumer can call that did not exist before: +five new typed message builders, conformance condition predicates, coding-system bindings on a value set, a declared profile conformance level, component rules on a field rule, declared conditional usage with caller-supplied resolutions, a message-structure registry derived from HL7's published structures instead of hand-transcribed, @@ -57,8 +58,8 @@ queue is ready, not that the release may go out today.** ## Pending changesets -- pending: `33` -- minor: `18` +- pending: `34` +- minor: `19` Every `.md` in `.changeset/` except Changesets' own `README.md` is a pending declaration and is classified here, and every row here is a file in `.changeset/`; `config.json` is not a declaration. @@ -73,6 +74,7 @@ read. | `brave-comets-certify.md` | `patch` | Corrects release tooling only: it adds the readiness check and the public-export inventory, and it stops the contributor guidance instructing patch-only changesets. Nothing a consumer receives changes. | | `brave-otters-recount.md` | `patch` | Corrects release tooling and this record: the counts and the break-candidate attributions stated here are recounted from `.changeset/` and `release/public-api.json` instead of read as prose, the inventory becomes a third input the check refuses rather than skips, and the record itself is re-derived from the tree. No export, type, parse behaviour, warning code or serialized byte moves. | | `brave-turtles-describe.md` | `minor` | Adds schema emission for the serialized projection: `messageJsonSchema`, `messageZodSource`, `emitMessageSchema`, `isSchemaEmitTarget`, `SCHEMA_EMIT_TARGETS`, `SchemaTargetError`, `JSON_SCHEMA_DIALECT` and the `SchemaEmitTarget` / `JsonSchemaDocument` / `JsonSchemaNode` types. Both functions build a description and return it; nothing validates anything, the Zod artifact is source TEXT so no `zod` dependency is added at run time or in development, and the file states no existing export was removed, renamed or re-typed. | +| `first-minor-release.md` | `minor` | States what 0.1 means to someone using the package: what is covered and dependable, what the version promises below 1.0 (a breaking change bumps the minor and is called out in the changelog) and what is not covered. It adds no behaviour of its own; it carries `minor` as the class of the release it describes, which the other `minor` declarations already resolve to, so the target does not move. | | `first-use-examples-executed.md` | `patch` | Corrects the documentation's first examples: the README usage example and the quickstart's first example now parse a committed synthetic fixture byte for byte, and the test suite reads both out of their pages and executes them against the package, asserting their printed and claimed values; the hand-kept copy of the README example under `examples/` is removed. No export, type, parse behaviour, warning code or serialized byte moves. | | `great-moons-shave.md` | `patch` | Corrects the repository's own gate tooling only: the em-dash brand gate stops running this repository's copy of the scanner and runs the one shared implementation published in `@cosyte/script-utils`, the copy is deleted, and what the scan leaves out becomes a tracked declaration instead of two patterns inside the scanner. The package script keeps its name, its two modes and its exit codes, and the set of tracked files it reads was enumerated before and after and compared in both directions. The dependency is a devDependency, `dependencies` stays empty, and the published files, exports and types are untouched. | | `great-otters-author.md` | `minor` | Adds five typed builders mirroring the read helpers, `buildOrm`, `buildSiu`, `buildMdm`, `buildDft` and `buildVxu`, plus `SUPPORTED_BUILDER_MESSAGES`, `supportsBuilderMessage` and `TYPED_BUILDER_COVERAGE`, and optional prior-identity content on the ADT typed init. The support claim is derived from the same published structures the parser checks against rather than asserted. The file names two behaviour changes of its own, both listed under Break candidates below. | @@ -220,6 +222,8 @@ holds every name below to the pending queue. with no published surface. - `brave-turtles-describe.md` removes, renames and narrows nothing: emission is additive, and the file states no existing export was removed, renamed or re-typed. +- `first-minor-release.md` removes, renames and narrows nothing: it is the release statement, and + it changes no export, type, parse behaviour, warning code or serialized byte. - `first-use-examples-executed.md` removes, renames and narrows nothing: it changes the example message two documentation pages print and adds tests that execute them; no export, type, parse behaviour, warning code or serialized byte moves. diff --git a/scripts/run-examples.ts b/scripts/run-examples.ts index f1b1baa..9914e70 100644 --- a/scripts/run-examples.ts +++ b/scripts/run-examples.ts @@ -4,10 +4,10 @@ * For each example, asserts the process exits 0 and stdout contains a * known marker string. Exits non-zero if any example fails. * - * Run from repo root (will be invoked by `pnpm examples` once Plan 08-05 - * wires the script into `package.json`): + * Run from repo root, after `pnpm build` (the examples import the built + * package by name): * - * pnpm tsx scripts/run-examples.ts + * pnpm examples * * Security note (Phase 8 threat T-08-01): filenames are passed as argv * to spawnSync: they are NEVER concatenated into a shell template. Any