@cosyte/fhir 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Cosyte
3
+ Copyright (c) 2026 Cosyte LLC
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  <a href="https://cosyte.com">
2
2
  <picture>
3
3
  <source media="(prefers-color-scheme: dark)" srcset="https://cosyte.com/tile/cosyte-lockup-tile-on-dark-1200x300.png">
4
- <img alt="Cosyte: a plus mark set in two overlapping rounded squares, one solid and one outlined, beside the Cosyte wordmark" src="https://cosyte.com/tile/cosyte-lockup-tile-on-light-1200x300.png">
4
+ <img alt="The Cosyte logo on its own white ground: the icon beside the word Cosyte." src="https://cosyte.com/tile/cosyte-lockup-tile-on-light-1200x300.png">
5
5
  </picture>
6
6
  </a>
7
7
 
@@ -12,7 +12,7 @@
12
12
 
13
13
  [![npm version](https://img.shields.io/npm/v/@cosyte/fhir.svg)](https://www.npmjs.com/package/@cosyte/fhir)
14
14
  [![CI](https://img.shields.io/github/actions/workflow/status/cosyte/fhir/ci.yml?branch=main&label=CI)](https://github.com/cosyte/fhir/actions/workflows/ci.yml)
15
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
15
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://github.com/cosyte/fhir/blob/main/LICENSE)
16
16
  [![Node](https://img.shields.io/badge/node-%3E%3D22-brightgreen.svg)](https://nodejs.org)
17
17
 
18
18
  FHIR R4 for Node.js and TypeScript: a resource model that keeps every value exactly as written, JSON and XML codecs, layered validation, and a safety readout for status and negation.
@@ -20,18 +20,18 @@ FHIR R4 for Node.js and TypeScript: a resource model that keeps every value exac
20
20
  ## Why this exists
21
21
 
22
22
  Reading FHIR correctly takes more than a JSON parse: a `decimal` written `0.010` has to stay
23
- `0.010`, an `integer64` has to keep every digit, and a status, a modifier or a negation must never be
23
+ `0.010`, an `integer64` has to keep every digit, and a status, a modifier, or a negation must never be
24
24
  skipped, because a missed `refuted` reads as its opposite. We built `@cosyte/fhir` for the engineer
25
25
  who reads FHIR R4 from a server or an EHR (the format ONC HTI-1 binds §170.315(g)(10) to, with US
26
26
  Core and SMART on FHIR) and has to get those values right without reading the specification first.
27
27
  Type definitions alone describe a resource's shape and check nothing at run time, and `JSON.parse`
28
- turns `0.010` into the number `0.01` and knows nothing about modifiers. This library reads, writes
28
+ turns `0.010` into the number `0.01` and knows nothing about modifiers. This library reads, writes,
29
29
  and validates FHIR R4 with zero runtime dependencies, and tells you with a coded reason what it could
30
30
  not read safely.
31
31
 
32
32
  ## Status
33
33
 
34
- **The 0.1 line.** From 0.1 the public API is settled: the exported names, options, result shapes and
34
+ **The 0.1 line.** From 0.1 the public API is settled: the exported names, options, result shapes, and
35
35
  issue codes are the surface we keep stable. While the package is below 1.0, a breaking change ships
36
36
  in a minor version and is called out in the
37
37
  [changelog](https://github.com/cosyte/fhir/blob/main/CHANGELOG.md). Upgrading from 0.0.10 changes
@@ -47,10 +47,10 @@ and DSTU2 documents can be read, since the model is schema-free, but they are no
47
47
  their own definitions.
48
48
 
49
49
  Not covered yet: typed per-resource models (the built-in structural schemas cover the base elements
50
- plus `Patient`), `type` and `profile` slicing discriminators and reslicing (reported
51
- `PROFILE_SLICE_UNCHECKED`), FHIRPath outside the supported subset (reported `INVARIANT_UNCHECKED`,
52
- never passed), bundled terminology or US Core content, spec-clean JSON written from a model read out
53
- of XML, unit conversion, and executing a transaction Bundle.
50
+ plus the eight modeled resource types), `type` and `profile` slicing discriminators and reslicing
51
+ (reported `PROFILE_SLICE_UNCHECKED`), FHIRPath outside the supported subset (reported
52
+ `INVARIANT_UNCHECKED`, never passed), bundled terminology or US Core content, spec-clean JSON written
53
+ from a model read out of XML, unit conversion, and executing a transaction Bundle.
54
54
 
55
55
  ## Install
56
56
 
@@ -59,9 +59,9 @@ of XML, unit conversion, and executing a transaction Bundle.
59
59
  pnpm add @cosyte/fhir
60
60
  ```
61
61
 
62
- Requires Node `>=22.0.0`. The package ships dual ESM and CommonJS builds with type declarations for
63
- both, so `import` and `require` both work and neither needs a compatibility shim. There are zero
64
- runtime dependencies, and it imports no Node built-in.
62
+ Requires Node.js 22 or later, tested on 22 and 24. The package ships dual ESM and CommonJS builds
63
+ with type declarations for both, so `import` and `require` both work and neither needs a
64
+ compatibility shim. There are zero runtime dependencies, and it imports no Node built-in.
65
65
 
66
66
  ## Usage
67
67
 
@@ -115,13 +115,13 @@ Everything ships from one entry point; there are no subpath imports.
115
115
  - **Validate.** `validateResource` returns `valid`, the issues, and `toOperationOutcome()` to render
116
116
  them as an `OperationOutcome`. Pass the `profiles` you load with `loadStructureDefinition` or
117
117
  author with `defineProfile`, and a `terminology` service of your own for code validity.
118
- - **Read status and negation.** `readSafety` surfaces status, modifiers and negations.
118
+ - **Read status and negation.** `readSafety` surfaces status, modifiers, and negations.
119
119
  `assertSafeToSummarize` throws `FhirSafetyError`, carrying locations only, when a resource holds
120
120
  something it cannot summarize honestly, such as a `modifierExtension` it does not understand.
121
121
  - **Read measured values.** `readObservationValue` branches on the `value[x]` type and keeps the
122
122
  UCUM `code`, and `readMedicationDoses` reads dose quantities. No unit is ever converted.
123
123
  - **Bundles and NDJSON.** `readBundle` tells a transaction (all or nothing) from a batch and
124
- executes neither, `resolveReference` resolves relative, absolute, logical and `#fragment`
124
+ executes neither, `resolveReference` resolves relative, absolute, logical, and `#fragment`
125
125
  references, and `streamNdjson` reads a Bulk Data export line by line, reporting a malformed line
126
126
  and carrying on.
127
127
 
@@ -130,16 +130,16 @@ Everything ships from one entry point; there are no subpath imports.
130
130
  FHIR resources carry protected health information, so treat every document you hand this library
131
131
  as PHI.
132
132
 
133
- - **It works in memory.** It reads, validates and writes in memory and nothing else. It opens no
134
- socket, writes nothing to disk and fetches nothing at run time; it has zero runtime dependencies,
133
+ - **It works in memory.** It reads, validates, and writes in memory and nothing else. It opens no
134
+ socket, writes nothing to disk, and fetches nothing at run time; it has zero runtime dependencies,
135
135
  imports no Node built-in, and calls no terminology service unless you pass one in.
136
136
  - **Diagnostics carry no values.** An issue is a code and a FHIRPath location, never the value it
137
137
  was raised over. A location can repeat an element name the document supplied when that name has
138
138
  the published form of a FHIR name, so treat a location as derived from the document.
139
139
  - **The XML reader accepts plain XML only.** Anything else is refused with a typed `FhirXmlError`
140
- that carries a code and a byte offset, never a slice of the document. The reader performs no I/O
141
- and resolves no URI. The troubleshooting pages on
142
- [docs.cosyte.com/fhir](https://docs.cosyte.com/fhir) list each refusal and its code.
140
+ that carries a code and an offset into the input string (in UTF-16 code units, not bytes), never a
141
+ slice of the document. The reader performs no I/O and resolves no URI. The troubleshooting pages
142
+ on [docs.cosyte.com/fhir](https://docs.cosyte.com/fhir) list each refusal and its code.
143
143
  - **Nesting is bounded.** Both readers stop at a fixed depth with a typed error, so a deeply nested
144
144
  document fails cleanly rather than exhausting the stack.
145
145
  - **A status or a negation is not skipped silently.** `assertSafeToSummarize` refuses a resource
@@ -151,7 +151,7 @@ as PHI.
151
151
  ## Documentation
152
152
 
153
153
  - [docs.cosyte.com/fhir](https://docs.cosyte.com/fhir): installation, the quickstart, core
154
- concepts, guides, current limits and troubleshooting.
154
+ concepts, guides, current limits, and troubleshooting.
155
155
  - [`documentation/capabilities.md`](https://github.com/cosyte/fhir/blob/main/documentation/capabilities.md):
156
156
  the full capability readout, layer by layer, with what each one checks and what it leaves open.
157
157
  - [`documentation/`](https://github.com/cosyte/fhir/tree/main/documentation) in the repository: the
@@ -162,7 +162,7 @@ as PHI.
162
162
 
163
163
  ## Contributing
164
164
 
165
- Questions, bug reports and FHIR quirks from the servers and EHRs you connect to all belong in
165
+ Questions, bug reports, and FHIR quirks from the servers and EHRs you connect to all belong in
166
166
  [GitHub issues](https://github.com/cosyte/fhir/issues). Pull requests are welcome; every fixture
167
167
  must be synthetic, never a real patient's data.
168
168
 
@@ -174,10 +174,12 @@ pnpm lint
174
174
  pnpm test
175
175
  ```
176
176
 
177
- Every meaningful change gets a Changeset (`pnpm changeset`: `minor` for new capability or a breaking
178
- change while the version is below 1.0, `patch` for a fix) and a `CHANGELOG.md` `[Unreleased]`
179
- entry. See [`CONTRIBUTING.md`](https://github.com/cosyte/fhir/blob/main/CONTRIBUTING.md).
177
+ Every meaningful change gets a changeset (`pnpm changeset`: `minor` for new capability or a breaking
178
+ change while the version is below 1.0, `patch` for a fix), and its summary becomes the change's
179
+ entry in `CHANGELOG.md`. See [`CONTRIBUTING.md`](https://github.com/cosyte/fhir/blob/main/CONTRIBUTING.md).
180
180
 
181
181
  ## License
182
182
 
183
- MIT, copyright Cosyte. See [LICENSE](./LICENSE).
183
+ MIT, copyright Cosyte LLC. See [LICENSE](https://github.com/cosyte/fhir/blob/main/LICENSE). The names of
184
+ the standards and code systems this package works with belong to their owners; see
185
+ [TRADEMARKS.md](https://github.com/cosyte/fhir/blob/main/TRADEMARKS.md).
package/dist/index.cjs CHANGED
@@ -555,7 +555,7 @@ var FATAL_CODES = {
555
555
  * JSON nested deeper than the reader's fixed bound. Well-formed but pathological input (a tower of
556
556
  * `[[[[…]]]]` / `{"a":{"a":…}}`) is refused as a **DoS guard**, turning what would otherwise be a
557
557
  * V8 stack overflow (`RangeError`, environment-dependent, untyped) into a typed, value-free fatal
558
- * carrying a byte `offset`. Mirrors the XML reader's `MAX_DEPTH_EXCEEDED` (fuzzing: deep
558
+ * carrying an `offset`. Mirrors the XML reader's `MAX_DEPTH_EXCEEDED` (fuzzing: deep
559
559
  * nesting must never crash/hang/OOM, always a typed error or a bounded rejection).
560
560
  */
561
561
  MAX_DEPTH_EXCEEDED: "MAX_DEPTH_EXCEEDED"
@@ -564,12 +564,16 @@ var FhirCodecError = class extends Error {
564
564
  code;
565
565
  /** FHIRPath location of the failure, when it has one (misalignment). */
566
566
  expression;
567
- /** Byte offset into the input, when it has one (malformed JSON). */
567
+ /**
568
+ * Where in the input the failure was detected, when it has one (malformed JSON), as an index into
569
+ * the input string in UTF-16 code units (JavaScript string indexing), not a byte offset: the two
570
+ * differ once a non-ASCII character precedes the failure.
571
+ */
568
572
  offset;
569
573
  /**
570
574
  * @param code - The fatal reason.
571
575
  * @param message - A PHI-safe description, must not embed any input value.
572
- * @param location - Either a FHIRPath `expression` or a byte `offset`.
576
+ * @param location - Either a FHIRPath `expression` or a string-index `offset`.
573
577
  * @internal
574
578
  */
575
579
  constructor(code, message, location = {}) {
@@ -6653,12 +6657,16 @@ var XML_FATAL_CODES = {
6653
6657
  };
6654
6658
  var FhirXmlError = class extends Error {
6655
6659
  code;
6656
- /** Byte offset into the input where the failure was detected. */
6660
+ /**
6661
+ * Where in the input the failure was detected, as an index into the input string in UTF-16 code
6662
+ * units (JavaScript string indexing), not a byte offset: the two differ once a non-ASCII character
6663
+ * precedes the failure.
6664
+ */
6657
6665
  offset;
6658
6666
  /**
6659
6667
  * @param code - The fatal reason.
6660
6668
  * @param message - A PHI-safe description, must not embed any input value.
6661
- * @param offset - The byte offset where the failure was detected.
6669
+ * @param offset - The string index (UTF-16 code units) where the failure was detected.
6662
6670
  * @internal
6663
6671
  */
6664
6672
  constructor(code, message, offset) {
@@ -7550,7 +7558,7 @@ async function* streamNdjson(source, options = {}) {
7550
7558
  }
7551
7559
 
7552
7560
  // src/index.ts
7553
- var VERSION = "0.1.0";
7561
+ var VERSION = "0.1.2";
7554
7562
 
7555
7563
  exports.ABSENCE_CODES = ABSENCE_CODES;
7556
7564
  exports.ALLERGY_CLINICAL_SYSTEM = ALLERGY_CLINICAL_SYSTEM;
package/dist/index.d.cts CHANGED
@@ -793,7 +793,7 @@ declare function parseReference(raw: string): ParsedReference;
793
793
  * **PHI discipline.** A FHIR resource is PHI by default, and diagnostics are the leak
794
794
  * vector. Every issue and every error here is **value-free by construction**: it carries a coded
795
795
  * `code`, a `severity`, and an `expression` (a FHIRPath *location* such as `Patient.name[0].given[1]`),
796
- * never the offending value. The `FhirCodecError` for malformed JSON carries a byte `offset`, not
796
+ * never the offending value. The `FhirCodecError` for malformed JSON carries an `offset`, not
797
797
  * the surrounding text.
798
798
  *
799
799
  * @packageDocumentation
@@ -1122,7 +1122,7 @@ declare const FATAL_CODES: {
1122
1122
  * JSON nested deeper than the reader's fixed bound. Well-formed but pathological input (a tower of
1123
1123
  * `[[[[…]]]]` / `{"a":{"a":…}}`) is refused as a **DoS guard**, turning what would otherwise be a
1124
1124
  * V8 stack overflow (`RangeError`, environment-dependent, untyped) into a typed, value-free fatal
1125
- * carrying a byte `offset`. Mirrors the XML reader's `MAX_DEPTH_EXCEEDED` (fuzzing: deep
1125
+ * carrying an `offset`. Mirrors the XML reader's `MAX_DEPTH_EXCEEDED` (fuzzing: deep
1126
1126
  * nesting must never crash/hang/OOM, always a typed error or a bounded rejection).
1127
1127
  */
1128
1128
  readonly MAX_DEPTH_EXCEEDED: "MAX_DEPTH_EXCEEDED";
@@ -1150,12 +1150,16 @@ declare class FhirCodecError extends Error {
1150
1150
  readonly code: FatalCode;
1151
1151
  /** FHIRPath location of the failure, when it has one (misalignment). */
1152
1152
  readonly expression: string | undefined;
1153
- /** Byte offset into the input, when it has one (malformed JSON). */
1153
+ /**
1154
+ * Where in the input the failure was detected, when it has one (malformed JSON), as an index into
1155
+ * the input string in UTF-16 code units (JavaScript string indexing), not a byte offset: the two
1156
+ * differ once a non-ASCII character precedes the failure.
1157
+ */
1154
1158
  readonly offset: number | undefined;
1155
1159
  /**
1156
1160
  * @param code - The fatal reason.
1157
1161
  * @param message - A PHI-safe description, must not embed any input value.
1158
- * @param location - Either a FHIRPath `expression` or a byte `offset`.
1162
+ * @param location - Either a FHIRPath `expression` or a string-index `offset`.
1159
1163
  * @internal
1160
1164
  */
1161
1165
  constructor(code: FatalCode, message: string, location?: {
@@ -1175,7 +1179,7 @@ declare class FhirCodecError extends Error {
1175
1179
  *
1176
1180
  * The output is a raw JSON tree ({@link RawJson}) that preserves member order (FHIR allows
1177
1181
  * `resourceType` in any position) and number literals verbatim. Malformed input throws a value-free
1178
- * {@link FhirCodecError} carrying a byte offset, never a snippet (the snippet could be PHI).
1182
+ * {@link FhirCodecError} carrying an offset, never a snippet (the snippet could be PHI).
1179
1183
  *
1180
1184
  * @packageDocumentation
1181
1185
  */
@@ -1219,7 +1223,7 @@ type RawJson = RawObject | RawArray | RawString | RawNumber | RawBool | RawNull;
1219
1223
  * Parse a JSON document into a {@link RawJson} tree that preserves number literals verbatim and
1220
1224
  * member order. Throws {@link FhirCodecError} (`MALFORMED_JSON`) on invalid input, or
1221
1225
  * (`MAX_DEPTH_EXCEEDED`) when nesting passes the reader's fixed depth bound, both value-free, with a
1222
- * byte `offset` and no snippet.
1226
+ * `offset` and no snippet.
1223
1227
  *
1224
1228
  * @param src - The JSON text.
1225
1229
  * @example
@@ -2264,7 +2268,7 @@ interface TerminologyService {
2264
2268
  *
2265
2269
  * This is deliberately *not* a FHIR `StructureDefinition` and not a snapshot generator, that engine
2266
2270
  * (loading StructureDefinitions, generating snapshots from differentials, slicing, US Core profiles)
2267
- * is separate ({@link ../profiles/index.js}). This layer needs only enough shape to run layers 1–3,
2271
+ * is separate ({@link ../profiles/index.js}). This layer needs only enough shape to run layers 1 to 3,
2268
2272
  * so it uses a hand-authored, hierarchy-free record; the schema type is the seam between the two.
2269
2273
  *
2270
2274
  * **What ships built-in here is a named, deliberately short list:** the base `Resource` /
@@ -2876,7 +2880,7 @@ declare function diagnosticFor(code: ValidationCode): string;
2876
2880
  declare function validationIssue(code: ValidationCode, severity: ValidationSeverity, expression: string, constraint?: string, codeSystemVersion?: CodeSystemVersionRecord): ValidationIssue;
2877
2881
 
2878
2882
  /**
2879
- * The layered structural / cardinality / value-domain validator (validation layers 1–3).
2883
+ * The layered structural / cardinality / value-domain validator (validation layers 1 to 3).
2880
2884
  *
2881
2885
  * Given a resource model (from `parseResource`) and a schema ({@link ./schema.js}), the validator
2882
2886
  * walks the resource once and produces value-free {@link ValidationIssue}s across three layers:
@@ -5499,8 +5503,8 @@ declare function matchesPattern(instance: FhirNode | undefined, pattern: FhirNod
5499
5503
  *
5500
5504
  * Profile validation and slicing discriminators are expressed as **element paths** relative to a
5501
5505
  * resource or a slice element (e.g. `clinicalStatus.coding.code`, `value[x]`, `$this`). This module
5502
- * resolves such a path to the set of model nodes it selects, flattening repeating elements and
5503
- * honoring `[x]` choice variants. It is a deliberately small, FHIRPath-*shaped* navigator, not the
5506
+ * resolves such a path to the set of model nodes it selects, flattening the repeating elements it
5507
+ * walks through and honoring `[x]` choice variants. It is a deliberately small, FHIRPath-*shaped* navigator, not the
5504
5508
  * FHIRPath engine: it walks dotted member access and choice suffixes,
5505
5509
  * which is exactly what StructureDefinition discriminator paths and fixed/pattern locations use, and
5506
5510
  * nothing more (no functions, no filters, no arithmetic).
@@ -5511,8 +5515,11 @@ declare function matchesPattern(instance: FhirNode | undefined, pattern: FhirNod
5511
5515
  /**
5512
5516
  * Resolve an element path against a node, returning every node it selects (empty when nothing
5513
5517
  * matches). `$this` (or the empty path) selects the node itself. A `[x]` segment matches any concrete
5514
- * choice variant (`value[x]` → `valueQuantity`, `valueString`, …). Repeating elements are flattened,
5515
- * so `coding.code` on a `CodeableConcept` with three codings yields three nodes.
5518
+ * choice variant (`value[x]` → `valueQuantity`, `valueString`, …). A repeating element the path
5519
+ * walks through is flattened, so `coding.code` on a `CodeableConcept` with three codings yields three
5520
+ * nodes. A repeating element in the last segment is not: it comes back as its list node
5521
+ * (`kind: "list"`, members on `items`), so `name` on a Patient with two names yields one node.
5522
+ * Flatten it with `isList(node) ? node.items : [node]`.
5516
5523
  *
5517
5524
  * @param node - The starting node (a resource, a slice element instance, …).
5518
5525
  * @param path - A dotted element path relative to `node` (`""` / `"$this"` selects `node`).
@@ -5692,7 +5699,9 @@ interface ProfileOptions {
5692
5699
  * ```ts
5693
5700
  * import { collectProfileIssues, loadStructureDefinition, parseResource } from "@cosyte/fhir";
5694
5701
  * const profile = loadStructureDefinition(parseResource(usCoreAllergyJson).resource);
5695
- * const issues = collectProfileIssues(parseResource(allergyJson).resource, profile);
5702
+ * if (profile !== undefined) {
5703
+ * const issues = collectProfileIssues(parseResource(allergyJson).resource, profile);
5704
+ * }
5696
5705
  * ```
5697
5706
  */
5698
5707
  declare function collectProfileIssues(resource: FhirComplex, profile: StructureDefinition, options?: ProfileOptions): ValidationIssue[];
@@ -5769,7 +5778,9 @@ interface InvariantOptions {
5769
5778
  * ```ts
5770
5779
  * import { collectInvariantIssues, loadStructureDefinition, parseResource } from "@cosyte/fhir";
5771
5780
  * const profile = loadStructureDefinition(parseResource(usCoreProfileJson).resource);
5772
- * const issues = collectInvariantIssues(parseResource(instanceJson).resource, profile);
5781
+ * if (profile !== undefined) {
5782
+ * const issues = collectInvariantIssues(parseResource(instanceJson).resource, profile);
5783
+ * }
5773
5784
  * ```
5774
5785
  */
5775
5786
  declare function collectInvariantIssues(resource: FhirComplex, profile: StructureDefinition, options?: InvariantOptions): ValidationIssue[];
@@ -6325,7 +6336,7 @@ type XmlNode = XmlElement | XmlText;
6325
6336
  * decoding the five predefined entities and numeric character references. **Refuses** any DTD
6326
6337
  * (`DTD_FORBIDDEN`) or non-predefined entity (`UNDEFINED_ENTITY`), and bounds nesting depth, so it
6327
6338
  * is XXE- and billion-laughs-safe and never crashes on adversarial input. Throws
6328
- * {@link FhirXmlError} on any refusal or well-formedness error, with a byte `offset` and no snippet.
6339
+ * {@link FhirXmlError} on any refusal or well-formedness error, with an `offset` and no snippet.
6329
6340
  *
6330
6341
  * @param src - The XML text.
6331
6342
  * @example
@@ -6363,7 +6374,7 @@ declare function readRawXml(src: string): XmlElement;
6363
6374
  * {@link XML_FATAL_CODES.MAX_DEPTH_EXCEEDED} so adversarial input yields a typed error, never a stack
6364
6375
  * overflow.
6365
6376
  *
6366
- * Every message is **value-free**: it carries a coded reason and a byte `offset`, never
6377
+ * Every message is **value-free**: it carries a coded reason and an `offset`, never
6367
6378
  * a slice of the offending document, because that slice could be PHI.
6368
6379
  *
6369
6380
  * @packageDocumentation
@@ -6394,7 +6405,7 @@ type XmlFatalCode = (typeof XML_FATAL_CODES)[keyof typeof XML_FATAL_CODES];
6394
6405
  /**
6395
6406
  * Thrown by the XML reader on an unrecoverable failure, a well-formedness error, a **refused** DTD
6396
6407
  * or entity (the safety refusals), or nesting past the depth bound. Carries the coded reason and a
6397
- * byte `offset`, and, by design, **no** slice of the offending input, because that slice could be
6408
+ * `offset` into the input, and, by design, **no** slice of the offending input, because that slice could be
6398
6409
  * PHI.
6399
6410
  *
6400
6411
  * @example
@@ -6411,12 +6422,16 @@ type XmlFatalCode = (typeof XML_FATAL_CODES)[keyof typeof XML_FATAL_CODES];
6411
6422
  */
6412
6423
  declare class FhirXmlError extends Error {
6413
6424
  readonly code: XmlFatalCode;
6414
- /** Byte offset into the input where the failure was detected. */
6425
+ /**
6426
+ * Where in the input the failure was detected, as an index into the input string in UTF-16 code
6427
+ * units (JavaScript string indexing), not a byte offset: the two differ once a non-ASCII character
6428
+ * precedes the failure.
6429
+ */
6415
6430
  readonly offset: number;
6416
6431
  /**
6417
6432
  * @param code - The fatal reason.
6418
6433
  * @param message - A PHI-safe description, must not embed any input value.
6419
- * @param offset - The byte offset where the failure was detected.
6434
+ * @param offset - The string index (UTF-16 code units) where the failure was detected.
6420
6435
  * @internal
6421
6436
  */
6422
6437
  constructor(code: XmlFatalCode, message: string, offset: number);
package/dist/index.d.ts CHANGED
@@ -793,7 +793,7 @@ declare function parseReference(raw: string): ParsedReference;
793
793
  * **PHI discipline.** A FHIR resource is PHI by default, and diagnostics are the leak
794
794
  * vector. Every issue and every error here is **value-free by construction**: it carries a coded
795
795
  * `code`, a `severity`, and an `expression` (a FHIRPath *location* such as `Patient.name[0].given[1]`),
796
- * never the offending value. The `FhirCodecError` for malformed JSON carries a byte `offset`, not
796
+ * never the offending value. The `FhirCodecError` for malformed JSON carries an `offset`, not
797
797
  * the surrounding text.
798
798
  *
799
799
  * @packageDocumentation
@@ -1122,7 +1122,7 @@ declare const FATAL_CODES: {
1122
1122
  * JSON nested deeper than the reader's fixed bound. Well-formed but pathological input (a tower of
1123
1123
  * `[[[[…]]]]` / `{"a":{"a":…}}`) is refused as a **DoS guard**, turning what would otherwise be a
1124
1124
  * V8 stack overflow (`RangeError`, environment-dependent, untyped) into a typed, value-free fatal
1125
- * carrying a byte `offset`. Mirrors the XML reader's `MAX_DEPTH_EXCEEDED` (fuzzing: deep
1125
+ * carrying an `offset`. Mirrors the XML reader's `MAX_DEPTH_EXCEEDED` (fuzzing: deep
1126
1126
  * nesting must never crash/hang/OOM, always a typed error or a bounded rejection).
1127
1127
  */
1128
1128
  readonly MAX_DEPTH_EXCEEDED: "MAX_DEPTH_EXCEEDED";
@@ -1150,12 +1150,16 @@ declare class FhirCodecError extends Error {
1150
1150
  readonly code: FatalCode;
1151
1151
  /** FHIRPath location of the failure, when it has one (misalignment). */
1152
1152
  readonly expression: string | undefined;
1153
- /** Byte offset into the input, when it has one (malformed JSON). */
1153
+ /**
1154
+ * Where in the input the failure was detected, when it has one (malformed JSON), as an index into
1155
+ * the input string in UTF-16 code units (JavaScript string indexing), not a byte offset: the two
1156
+ * differ once a non-ASCII character precedes the failure.
1157
+ */
1154
1158
  readonly offset: number | undefined;
1155
1159
  /**
1156
1160
  * @param code - The fatal reason.
1157
1161
  * @param message - A PHI-safe description, must not embed any input value.
1158
- * @param location - Either a FHIRPath `expression` or a byte `offset`.
1162
+ * @param location - Either a FHIRPath `expression` or a string-index `offset`.
1159
1163
  * @internal
1160
1164
  */
1161
1165
  constructor(code: FatalCode, message: string, location?: {
@@ -1175,7 +1179,7 @@ declare class FhirCodecError extends Error {
1175
1179
  *
1176
1180
  * The output is a raw JSON tree ({@link RawJson}) that preserves member order (FHIR allows
1177
1181
  * `resourceType` in any position) and number literals verbatim. Malformed input throws a value-free
1178
- * {@link FhirCodecError} carrying a byte offset, never a snippet (the snippet could be PHI).
1182
+ * {@link FhirCodecError} carrying an offset, never a snippet (the snippet could be PHI).
1179
1183
  *
1180
1184
  * @packageDocumentation
1181
1185
  */
@@ -1219,7 +1223,7 @@ type RawJson = RawObject | RawArray | RawString | RawNumber | RawBool | RawNull;
1219
1223
  * Parse a JSON document into a {@link RawJson} tree that preserves number literals verbatim and
1220
1224
  * member order. Throws {@link FhirCodecError} (`MALFORMED_JSON`) on invalid input, or
1221
1225
  * (`MAX_DEPTH_EXCEEDED`) when nesting passes the reader's fixed depth bound, both value-free, with a
1222
- * byte `offset` and no snippet.
1226
+ * `offset` and no snippet.
1223
1227
  *
1224
1228
  * @param src - The JSON text.
1225
1229
  * @example
@@ -2264,7 +2268,7 @@ interface TerminologyService {
2264
2268
  *
2265
2269
  * This is deliberately *not* a FHIR `StructureDefinition` and not a snapshot generator, that engine
2266
2270
  * (loading StructureDefinitions, generating snapshots from differentials, slicing, US Core profiles)
2267
- * is separate ({@link ../profiles/index.js}). This layer needs only enough shape to run layers 1–3,
2271
+ * is separate ({@link ../profiles/index.js}). This layer needs only enough shape to run layers 1 to 3,
2268
2272
  * so it uses a hand-authored, hierarchy-free record; the schema type is the seam between the two.
2269
2273
  *
2270
2274
  * **What ships built-in here is a named, deliberately short list:** the base `Resource` /
@@ -2876,7 +2880,7 @@ declare function diagnosticFor(code: ValidationCode): string;
2876
2880
  declare function validationIssue(code: ValidationCode, severity: ValidationSeverity, expression: string, constraint?: string, codeSystemVersion?: CodeSystemVersionRecord): ValidationIssue;
2877
2881
 
2878
2882
  /**
2879
- * The layered structural / cardinality / value-domain validator (validation layers 1–3).
2883
+ * The layered structural / cardinality / value-domain validator (validation layers 1 to 3).
2880
2884
  *
2881
2885
  * Given a resource model (from `parseResource`) and a schema ({@link ./schema.js}), the validator
2882
2886
  * walks the resource once and produces value-free {@link ValidationIssue}s across three layers:
@@ -5499,8 +5503,8 @@ declare function matchesPattern(instance: FhirNode | undefined, pattern: FhirNod
5499
5503
  *
5500
5504
  * Profile validation and slicing discriminators are expressed as **element paths** relative to a
5501
5505
  * resource or a slice element (e.g. `clinicalStatus.coding.code`, `value[x]`, `$this`). This module
5502
- * resolves such a path to the set of model nodes it selects, flattening repeating elements and
5503
- * honoring `[x]` choice variants. It is a deliberately small, FHIRPath-*shaped* navigator, not the
5506
+ * resolves such a path to the set of model nodes it selects, flattening the repeating elements it
5507
+ * walks through and honoring `[x]` choice variants. It is a deliberately small, FHIRPath-*shaped* navigator, not the
5504
5508
  * FHIRPath engine: it walks dotted member access and choice suffixes,
5505
5509
  * which is exactly what StructureDefinition discriminator paths and fixed/pattern locations use, and
5506
5510
  * nothing more (no functions, no filters, no arithmetic).
@@ -5511,8 +5515,11 @@ declare function matchesPattern(instance: FhirNode | undefined, pattern: FhirNod
5511
5515
  /**
5512
5516
  * Resolve an element path against a node, returning every node it selects (empty when nothing
5513
5517
  * matches). `$this` (or the empty path) selects the node itself. A `[x]` segment matches any concrete
5514
- * choice variant (`value[x]` → `valueQuantity`, `valueString`, …). Repeating elements are flattened,
5515
- * so `coding.code` on a `CodeableConcept` with three codings yields three nodes.
5518
+ * choice variant (`value[x]` → `valueQuantity`, `valueString`, …). A repeating element the path
5519
+ * walks through is flattened, so `coding.code` on a `CodeableConcept` with three codings yields three
5520
+ * nodes. A repeating element in the last segment is not: it comes back as its list node
5521
+ * (`kind: "list"`, members on `items`), so `name` on a Patient with two names yields one node.
5522
+ * Flatten it with `isList(node) ? node.items : [node]`.
5516
5523
  *
5517
5524
  * @param node - The starting node (a resource, a slice element instance, …).
5518
5525
  * @param path - A dotted element path relative to `node` (`""` / `"$this"` selects `node`).
@@ -5692,7 +5699,9 @@ interface ProfileOptions {
5692
5699
  * ```ts
5693
5700
  * import { collectProfileIssues, loadStructureDefinition, parseResource } from "@cosyte/fhir";
5694
5701
  * const profile = loadStructureDefinition(parseResource(usCoreAllergyJson).resource);
5695
- * const issues = collectProfileIssues(parseResource(allergyJson).resource, profile);
5702
+ * if (profile !== undefined) {
5703
+ * const issues = collectProfileIssues(parseResource(allergyJson).resource, profile);
5704
+ * }
5696
5705
  * ```
5697
5706
  */
5698
5707
  declare function collectProfileIssues(resource: FhirComplex, profile: StructureDefinition, options?: ProfileOptions): ValidationIssue[];
@@ -5769,7 +5778,9 @@ interface InvariantOptions {
5769
5778
  * ```ts
5770
5779
  * import { collectInvariantIssues, loadStructureDefinition, parseResource } from "@cosyte/fhir";
5771
5780
  * const profile = loadStructureDefinition(parseResource(usCoreProfileJson).resource);
5772
- * const issues = collectInvariantIssues(parseResource(instanceJson).resource, profile);
5781
+ * if (profile !== undefined) {
5782
+ * const issues = collectInvariantIssues(parseResource(instanceJson).resource, profile);
5783
+ * }
5773
5784
  * ```
5774
5785
  */
5775
5786
  declare function collectInvariantIssues(resource: FhirComplex, profile: StructureDefinition, options?: InvariantOptions): ValidationIssue[];
@@ -6325,7 +6336,7 @@ type XmlNode = XmlElement | XmlText;
6325
6336
  * decoding the five predefined entities and numeric character references. **Refuses** any DTD
6326
6337
  * (`DTD_FORBIDDEN`) or non-predefined entity (`UNDEFINED_ENTITY`), and bounds nesting depth, so it
6327
6338
  * is XXE- and billion-laughs-safe and never crashes on adversarial input. Throws
6328
- * {@link FhirXmlError} on any refusal or well-formedness error, with a byte `offset` and no snippet.
6339
+ * {@link FhirXmlError} on any refusal or well-formedness error, with an `offset` and no snippet.
6329
6340
  *
6330
6341
  * @param src - The XML text.
6331
6342
  * @example
@@ -6363,7 +6374,7 @@ declare function readRawXml(src: string): XmlElement;
6363
6374
  * {@link XML_FATAL_CODES.MAX_DEPTH_EXCEEDED} so adversarial input yields a typed error, never a stack
6364
6375
  * overflow.
6365
6376
  *
6366
- * Every message is **value-free**: it carries a coded reason and a byte `offset`, never
6377
+ * Every message is **value-free**: it carries a coded reason and an `offset`, never
6367
6378
  * a slice of the offending document, because that slice could be PHI.
6368
6379
  *
6369
6380
  * @packageDocumentation
@@ -6394,7 +6405,7 @@ type XmlFatalCode = (typeof XML_FATAL_CODES)[keyof typeof XML_FATAL_CODES];
6394
6405
  /**
6395
6406
  * Thrown by the XML reader on an unrecoverable failure, a well-formedness error, a **refused** DTD
6396
6407
  * or entity (the safety refusals), or nesting past the depth bound. Carries the coded reason and a
6397
- * byte `offset`, and, by design, **no** slice of the offending input, because that slice could be
6408
+ * `offset` into the input, and, by design, **no** slice of the offending input, because that slice could be
6398
6409
  * PHI.
6399
6410
  *
6400
6411
  * @example
@@ -6411,12 +6422,16 @@ type XmlFatalCode = (typeof XML_FATAL_CODES)[keyof typeof XML_FATAL_CODES];
6411
6422
  */
6412
6423
  declare class FhirXmlError extends Error {
6413
6424
  readonly code: XmlFatalCode;
6414
- /** Byte offset into the input where the failure was detected. */
6425
+ /**
6426
+ * Where in the input the failure was detected, as an index into the input string in UTF-16 code
6427
+ * units (JavaScript string indexing), not a byte offset: the two differ once a non-ASCII character
6428
+ * precedes the failure.
6429
+ */
6415
6430
  readonly offset: number;
6416
6431
  /**
6417
6432
  * @param code - The fatal reason.
6418
6433
  * @param message - A PHI-safe description, must not embed any input value.
6419
- * @param offset - The byte offset where the failure was detected.
6434
+ * @param offset - The string index (UTF-16 code units) where the failure was detected.
6420
6435
  * @internal
6421
6436
  */
6422
6437
  constructor(code: XmlFatalCode, message: string, offset: number);
package/dist/index.mjs CHANGED
@@ -553,7 +553,7 @@ var FATAL_CODES = {
553
553
  * JSON nested deeper than the reader's fixed bound. Well-formed but pathological input (a tower of
554
554
  * `[[[[…]]]]` / `{"a":{"a":…}}`) is refused as a **DoS guard**, turning what would otherwise be a
555
555
  * V8 stack overflow (`RangeError`, environment-dependent, untyped) into a typed, value-free fatal
556
- * carrying a byte `offset`. Mirrors the XML reader's `MAX_DEPTH_EXCEEDED` (fuzzing: deep
556
+ * carrying an `offset`. Mirrors the XML reader's `MAX_DEPTH_EXCEEDED` (fuzzing: deep
557
557
  * nesting must never crash/hang/OOM, always a typed error or a bounded rejection).
558
558
  */
559
559
  MAX_DEPTH_EXCEEDED: "MAX_DEPTH_EXCEEDED"
@@ -562,12 +562,16 @@ var FhirCodecError = class extends Error {
562
562
  code;
563
563
  /** FHIRPath location of the failure, when it has one (misalignment). */
564
564
  expression;
565
- /** Byte offset into the input, when it has one (malformed JSON). */
565
+ /**
566
+ * Where in the input the failure was detected, when it has one (malformed JSON), as an index into
567
+ * the input string in UTF-16 code units (JavaScript string indexing), not a byte offset: the two
568
+ * differ once a non-ASCII character precedes the failure.
569
+ */
566
570
  offset;
567
571
  /**
568
572
  * @param code - The fatal reason.
569
573
  * @param message - A PHI-safe description, must not embed any input value.
570
- * @param location - Either a FHIRPath `expression` or a byte `offset`.
574
+ * @param location - Either a FHIRPath `expression` or a string-index `offset`.
571
575
  * @internal
572
576
  */
573
577
  constructor(code, message, location = {}) {
@@ -6651,12 +6655,16 @@ var XML_FATAL_CODES = {
6651
6655
  };
6652
6656
  var FhirXmlError = class extends Error {
6653
6657
  code;
6654
- /** Byte offset into the input where the failure was detected. */
6658
+ /**
6659
+ * Where in the input the failure was detected, as an index into the input string in UTF-16 code
6660
+ * units (JavaScript string indexing), not a byte offset: the two differ once a non-ASCII character
6661
+ * precedes the failure.
6662
+ */
6655
6663
  offset;
6656
6664
  /**
6657
6665
  * @param code - The fatal reason.
6658
6666
  * @param message - A PHI-safe description, must not embed any input value.
6659
- * @param offset - The byte offset where the failure was detected.
6667
+ * @param offset - The string index (UTF-16 code units) where the failure was detected.
6660
6668
  * @internal
6661
6669
  */
6662
6670
  constructor(code, message, offset) {
@@ -7548,7 +7556,7 @@ async function* streamNdjson(source, options = {}) {
7548
7556
  }
7549
7557
 
7550
7558
  // src/index.ts
7551
- var VERSION = "0.1.0";
7559
+ var VERSION = "0.1.2";
7552
7560
 
7553
7561
  export { ABSENCE_CODES, ALLERGY_CLINICAL_SYSTEM, ALLERGY_SUBSTANCE_VALUESET, ALLERGY_VERIFICATION_SYSTEM, BINDING_STRENGTHS, BUNDLE_TYPES, CODE_SYSTEM_VERSION_RECORD_CODES, CODE_SYSTEM_VERSION_RECORD_SYSTEM, CONDITION_CATEGORY_SYSTEM, CONDITION_CLINICAL_SYSTEM, CONDITION_VERIFICATION_SYSTEM, CPT_SYSTEM, CVX_SYSTEM, DATA_ABSENT_REASON_URL, DISCRIMINATOR_TYPES, ENTERED_IN_ERROR, FATAL_CODES, FHIR_XML_NAMESPACE, FhirCodecError, FhirDecimal, FhirInteger64, FhirProfileError, FhirSafetyError, FhirSerializeError, FhirXmlError, ICD10CM_SYSTEM, ICD9CM_SYSTEM, ISSUE_CODES, ISSUE_SEVERITIES, ISSUE_TYPES, InvalidProfileError, KNOWN_MODIFIER_EXTENSION_URLS, KNOWN_SYSTEMS, LOINC_SYSTEM, MAX_REFERENCE_DEPTH, MEDICATION_VALUESET, MODIFIER_ELEMENT_ROOT_TYPES, NDC_SYSTEM, NDJSON_ERROR_CODES, NOT_DONE, NOT_TAKEN, NO_KNOWN_ALLERGY, OBSERVATION_CATEGORY_SYSTEM, OBSERVATION_VALUE_TYPES, PATIENT_IDENTIFIER_STARTER, PRIMITIVE_TYPES, REFUTED, RXNORM_SYSTEM, SAFETY_RESOURCE_TYPES, SERIALIZE_ERROR_CODES, SNOMED_SCT, STARTER_PROFILES, STARTER_PROFILE_BASE_URL, TERMINOLOGY_BINDINGS, UCUM_SYSTEM, UNBOUNDED, UnsupportedFhirPathError, VALIDATION_CODES, VERSION, VITAL_SIGNS_CATEGORY, VITAL_SIGNS_PROFILE, VITAL_SIGN_OBSERVATION_STARTER, VITAL_SIGN_UNITS, WITHHELD, XHTML_NAMESPACE, XML_FATAL_CODES, absenceMarkers, arrayWrappedScalars, assertSafeToSummarize, baseSchema, buildBindingRegistry, buildBundleIndex, buildRegistry, codeOf, codingsOf, collectBundleIssues, collectInvariantIssues, collectProfileIssues, collectProfileVersionIssues, collectQuantityIssues, collectSafetyIssues, collectTerminologyIssues, complex, conflictingAbsenceMarkers, containedIndex, convertToBoolean, decimal, decimalPrecisionAtRisk, defineProfile, diagnosticFor, droppedText, duplicateProperty, entryProcessing, evaluateInvariant, generateSnapshot, getAllProperties, getProperty, hasCodeAnySystem, hasCoding, hasContainedCycle, integer64, isAbsenceCode, isAtomicBundle, isChoice, isComplex, isDroppedText, isForeignRoot, isKnownSystem, isList, isNestedArray, isPrimitive, isPrimitiveType, isRetracted, isUndefinedNull, list, loadStructureDefinition, locateDoseQuantities, matchSlices, matchesFixed, matchesPattern, misplacedPrimitiveExtension, mixedXmlSpelling, modifierElements, nearMissNegationCodes, nestedArray, nestedArrayContent, nestedArrays, nodesEquivalent, parseFhirPath, parseNdjsonLine, parseReference, parseResource, parseResourceXml, pathExists, primitive, readBundle, readInterpretations, readMedicationDoses, readObservationValue, readQuantity, readRawJson, readRawXml, readReferenceRanges, readSafety, requiredVitalSignUnits, resolveElement, resolvePath, resolveReference, resolveSlices, resourceType, serializeResource, serializeResourceXml, shadowedProperties, snapshotElements, starterProfile, streamNdjson, toOperationOutcome, tokenize, undefinedJsonNull, unexpectedXmlContent, unhandledModifierExtensions, unknownProperty, unreadableAbsenceMarkers, unreadableBooleans, unreadableNegationCodes, validatePrimitiveValue, validateResource, validateUcumShape, validationIssue, wouldLosePrecisionAsDouble };
7554
7562
  //# sourceMappingURL=index.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosyte/fhir",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "FHIR R4 for Node.js and TypeScript: a resource model that keeps every value exactly as written, JSON and XML codecs, layered validation, and a safety readout for status and negation.",
5
5
  "keywords": [
6
6
  "fhir",
@@ -33,13 +33,6 @@
33
33
  "engines": {
34
34
  "node": ">=22.0.0"
35
35
  },
36
- "packageManager": "pnpm@10.0.0+sha512.b8fef5494bd3fe4cbd4edabd0745df2ee5be3e4b0b8b08fa643aa3e4c6702ccc0f00d68fa8a8c9858a735a0032485a44990ed2810526c875e416f001b17df12b",
37
- "pnpm": {
38
- "overrides": {
39
- "esbuild@>=0.27.3 <0.28.1": "0.28.1",
40
- "js-yaml@>=4.0.0 <4.3.0": "4.3.0"
41
- }
42
- },
43
36
  "main": "./dist/index.cjs",
44
37
  "module": "./dist/index.mjs",
45
38
  "types": "./dist/index.d.ts",
@@ -69,6 +62,30 @@
69
62
  "provenance": true
70
63
  },
71
64
  "prettier": "@cosyte/prettier-config",
65
+ "simple-git-hooks": {
66
+ "pre-commit": "pnpm phi-scan --staged"
67
+ },
68
+ "devDependencies": {
69
+ "@arethetypeswrong/cli": "0.18.4",
70
+ "@changesets/cli": "2.31.0",
71
+ "@cosyte/eslint-config": "^0.1.1",
72
+ "@cosyte/prettier-config": "^0.1.1",
73
+ "@cosyte/test-utils": "^0.1.1",
74
+ "@cosyte/tsconfig": "^0.1.1",
75
+ "@cosyte/tsup-config": "^0.1.1",
76
+ "@cosyte/vitest-config": "^0.1.1",
77
+ "@types/node": "^22.0.0",
78
+ "@vitest/coverage-v8": "4.1.4",
79
+ "eslint": "10.5.0",
80
+ "fast-check": "3.23.2",
81
+ "prettier": "3.8.3",
82
+ "simple-git-hooks": "2.13.0",
83
+ "tsup": "8.5.1",
84
+ "tsx": "4.21.0",
85
+ "typescript": "5.9.3",
86
+ "vite": "7.3.6",
87
+ "vitest": "4.1.4"
88
+ },
72
89
  "scripts": {
73
90
  "build": "tsup",
74
91
  "changeset": "changeset",
@@ -100,32 +117,6 @@
100
117
  "check:no-internal-refs": "bash scripts/check-no-internal-refs.sh",
101
118
  "check:docs-set": "tsx scripts/docs-set-check.ts",
102
119
  "version": "changeset version && node scripts/sync-version.mjs && prettier --write package.json src/index.ts",
103
- "release": "changeset publish",
104
- "prepublishOnly": "pnpm clean && pnpm typecheck && pnpm lint && pnpm test && pnpm build && pnpm attw",
105
- "prepare": "command -v simple-git-hooks >/dev/null 2>&1 && simple-git-hooks || true"
106
- },
107
- "simple-git-hooks": {
108
- "pre-commit": "pnpm phi-scan --staged"
109
- },
110
- "devDependencies": {
111
- "@arethetypeswrong/cli": "0.18.4",
112
- "@changesets/cli": "2.31.0",
113
- "@cosyte/eslint-config": "^0.0.3",
114
- "@cosyte/prettier-config": "^0.0.2",
115
- "@cosyte/test-utils": "^0.0.2",
116
- "@cosyte/tsconfig": "^0.0.2",
117
- "@cosyte/tsup-config": "^0.0.1",
118
- "@cosyte/vitest-config": "^0.0.2",
119
- "@types/node": "^22.0.0",
120
- "@vitest/coverage-v8": "4.1.4",
121
- "eslint": "10.5.0",
122
- "fast-check": "3.23.2",
123
- "prettier": "3.8.3",
124
- "simple-git-hooks": "2.13.0",
125
- "tsup": "8.5.1",
126
- "tsx": "4.21.0",
127
- "typescript": "5.9.3",
128
- "vite": "7.3.6",
129
- "vitest": "4.1.4"
120
+ "release": "changeset publish"
130
121
  }
131
- }
122
+ }