@cosyte/x12 0.0.1 → 0.0.3
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/CHANGELOG.md +295 -145
- package/README.md +24 -14
- package/TRADEMARKS.md +31 -0
- package/dist/index.cjs +132 -132
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1291 -1291
- package/dist/index.d.ts +1291 -1291
- package/dist/index.mjs +132 -132
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -4
package/README.md
CHANGED
|
@@ -1,24 +1,29 @@
|
|
|
1
|
+
<picture>
|
|
2
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://cosyte.com/tile/cosyte-lockup-tile-on-dark-1200x300.png">
|
|
3
|
+
<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
|
+
</picture>
|
|
5
|
+
|
|
1
6
|
# @cosyte/x12
|
|
2
7
|
|
|
3
|
-
> Parse real-world, vendor-quirky ASC X12 healthcare EDI
|
|
8
|
+
> Parse real-world, vendor-quirky ASC X12 healthcare EDI (835 remits, 837 claims, 271 eligibility responses, 277/277CA status, 278, 820, 834, 999/TA1) and pull the fields you need without reading a TR3.
|
|
4
9
|
|
|
5
10
|
[](https://www.npmjs.com/package/@cosyte/x12)
|
|
6
11
|
[](https://github.com/cosyte/x12/actions/workflows/ci.yml)
|
|
7
12
|
[](./LICENSE)
|
|
8
13
|
[](https://nodejs.org)
|
|
9
14
|
|
|
10
|
-
A developer-focused ASC X12 EDI parser and utility library for Node.js and TypeScript
|
|
15
|
+
A developer-focused ASC X12 EDI parser and utility library for Node.js and TypeScript: the payer-side sibling of [`@cosyte/hl7`](https://github.com/cosyte/hl7). Zero runtime dependencies, dual ESM/CJS, strict types. Lenient on the way in (vendor deviations become warnings, not exceptions), spec-clean on the way out: every domain builder emits spec-clean X12 by construction, and the general serializer does so on request.
|
|
11
16
|
|
|
12
|
-
> **Status:** pre-alpha
|
|
17
|
+
> **Status:** pre-alpha, **published on npm** from a public repo, on the `0.0.x`-until-first-alpha ladder. `npm view @cosyte/x12 version` is the source of truth for the current version and this page does not restate it; the badge above is a convenience, not the record. Typed **read** and **emit** support is complete for 271, 277/277CA, 278 (request + response), 820, 834, 835, 837P/I/D, 999, and TA1: every one of those has both a per-transaction reader and a matching domain builder, on top of a general serializer and interchange builder. The **270** and **276** inquiry directions do not: they parse into segments and dot-paths like any other X12, but nothing decodes them into a typed model yet. Pre-alpha means the public API may still move before `0.1`. Pin an exact version.
|
|
13
18
|
|
|
14
19
|
## Quickstart
|
|
15
20
|
|
|
16
21
|
```bash
|
|
17
|
-
# pnpm (recommended)
|
|
22
|
+
# pnpm (recommended), also works with: npm install @cosyte/x12 | yarn add @cosyte/x12
|
|
18
23
|
pnpm add @cosyte/x12
|
|
19
24
|
```
|
|
20
25
|
|
|
21
|
-
Parse an 835 remittance advice and read the money
|
|
26
|
+
Parse an 835 remittance advice and read the money, three lines of useful output, no TR3 lookup:
|
|
22
27
|
|
|
23
28
|
```ts
|
|
24
29
|
import { parseX12, get835 } from "@cosyte/x12";
|
|
@@ -27,25 +32,30 @@ const ix = parseX12(rawEdi); // never throws except on 4 structural fatals
|
|
|
27
32
|
const tx = ix.groups[0]?.transactions.find((t) => t.st.elements[1] === "835");
|
|
28
33
|
const remit = tx ? get835(ix.delimiters, tx) : undefined;
|
|
29
34
|
|
|
30
|
-
remit?.payment.totalActualPayment.toString(); // "450.00"
|
|
31
|
-
remit?.claims[0]?.patientControlNumber; // "PT-ACCT-001"
|
|
32
|
-
remit?.claims[0]?.serviceLines[0]?.adjustments[0]?.reasonCode; // "1"
|
|
35
|
+
remit?.payment.totalActualPayment.toString(); // "450.00": BigInt-exact, never a float
|
|
36
|
+
remit?.claims[0]?.patientControlNumber; // "PT-ACCT-001": your account number, echoed back
|
|
37
|
+
remit?.claims[0]?.serviceLines[0]?.adjustments[0]?.reasonCode; // "1": CARC (why it was adjusted)
|
|
33
38
|
```
|
|
34
39
|
|
|
35
40
|
That's the pitch: no schema upload, no spec knowledge. The parser accepts vendor-quirky input by default and flags what it tolerated with stable warning codes; you reach for strict mode, dot-paths, profiles, or the emit builders when you want them.
|
|
36
41
|
|
|
37
42
|
## What's inside
|
|
38
43
|
|
|
39
|
-
- **
|
|
40
|
-
- **Postel's Law
|
|
41
|
-
- **Money is exact
|
|
42
|
-
- **Safety-critical fidelity
|
|
43
|
-
- **PHI-disciplined
|
|
44
|
+
- **Typed read + emit, per transaction**: 271, 277/277CA, 278, 820, 834, 835, 837P/I/D, plus 999/TA1 acknowledgments. Per-transaction helpers (`get835`, `get837Claims`, `get271Eligibility`, …) and a matching domain builder for each (`build835`, `build837P/I/D`, `build271`, …). The 270 and 276 inquiries parse as generic segments; they have no typed model yet.
|
|
45
|
+
- **Postel's Law**: a lenient parser (deviations → warnings with a stable code + positional context) and a conservative serializer. `serializeX12` is byte-faithful by default; `{ specClean: true }` reconciles the envelope, and `{ specClean: true, recomputeCounts: true }` also emits the corrected counts (`recomputeCounts` does nothing on its own). A mismatch is always warned, never silently corrected. Only **4 structural failures** are ever fatal.
|
|
46
|
+
- **Money is exact**: every monetary/percent/quantity field decodes as `X12Decimal` (string-backed, BigInt arithmetic). The library **never `parseFloat`s** an EDI amount.
|
|
47
|
+
- **Safety-critical fidelity**: TRN reassociation traces, 835 balance invariants, 837 HL hierarchy integrity, 834 maintenance types, and 278 certification actions are preserved **verbatim** and never inferred; ambiguity yields a warning or a typed refusal, never a confident wrong answer.
|
|
48
|
+
- **PHI-disciplined**: synthetic-only fixtures, a PHI commit-gate, warning messages that carry a code and a position but never patient data, and builder refusals that carry structural locators and numeric totals only. **The one deliberate exception:** `X12ParseError.snippet` is a bounded (≤ 64 character) copy of the offending input, so on real traffic it can carry PHI. The library does not redact it. Redact at your call site, or log `err.code` and `err.position` instead.
|
|
44
49
|
|
|
45
50
|
See the [**Cookbook**](./docs-content/cookbook.md) for task-oriented recipes (post an 835, route 277CA rejections, round-trip a 271, walk an 837, read a 999) and [**KNOWN-LIMITATIONS.md**](./KNOWN-LIMITATIONS.md) for the honest do-not-over-trust list.
|
|
46
51
|
|
|
52
|
+
## Trademarks
|
|
53
|
+
|
|
54
|
+
Availity and Blue Cross Blue Shield are trademarks of their respective owners. cosyte is not affiliated with, endorsed by, or
|
|
55
|
+
sponsored by any of them. The names identify the trading partners whose companion-guide deviations the built-in profiles accommodate. See [TRADEMARKS.md](./TRADEMARKS.md).
|
|
56
|
+
|
|
47
57
|
## License
|
|
48
58
|
|
|
49
|
-
MIT
|
|
59
|
+
MIT. See [LICENSE](./LICENSE).
|
|
50
60
|
|
|
51
61
|
Built by [Cosyte](https://cosyte.com).
|
package/TRADEMARKS.md
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Trademarks
|
|
2
|
+
|
|
3
|
+
`@cosyte/x12` is an independent open-source project. cosyte is **not affiliated with, endorsed by,
|
|
4
|
+
or sponsored by** any company named in this repository or its documentation.
|
|
5
|
+
|
|
6
|
+
## Why these names appear
|
|
7
|
+
|
|
8
|
+
Clearinghouses and payers publish companion guides that deviate from the base X12 implementation
|
|
9
|
+
guide. A profile records whose deviation it accommodates, which cannot be said without naming
|
|
10
|
+
them.
|
|
11
|
+
|
|
12
|
+
Every reference is **descriptive**: it identifies whose companion-guide deviation a profile accommodates, and nothing more. Naming a system is the only way to say
|
|
13
|
+
whether a library works with it.
|
|
14
|
+
|
|
15
|
+
## Where the profiles come from
|
|
16
|
+
|
|
17
|
+
The built-in profiles are authored through this package's own public `defineProfile()` API and are
|
|
18
|
+
grounded in **synthetic** fixtures written from scratch. No real payer or clearinghouse file was
|
|
19
|
+
used to produce them. They are descriptive only: selecting a profile never changes a correct
|
|
20
|
+
parse. They embed no privileged, confidential, or reverse-engineered material.
|
|
21
|
+
|
|
22
|
+
## Names referenced
|
|
23
|
+
|
|
24
|
+
| Name | Where it appears |
|
|
25
|
+
| ----------------------------- | --------------------------------------------------------------------------------------------- |
|
|
26
|
+
| Availity | `profiles.availity`: a built-in profile name |
|
|
27
|
+
| Blue Cross Blue Shield (BCBS) | `profiles.bcbsCommon`: a built-in profile name, and descriptive use in documentation examples |
|
|
28
|
+
|
|
29
|
+
All product names, logos, and brands are the property of their respective owners. Use of a name here
|
|
30
|
+
does not imply any affiliation with, or endorsement by, its owner. If you own one of these marks and
|
|
31
|
+
would like a reference changed, please open an issue.
|