@ontemper/edi 1.1.6 → 1.2.0-beta.1
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/README.md +33 -13
- package/dist/control-numbers.js +3 -3
- package/dist/index.d.ts +31 -3
- package/dist/index.js +100 -13
- package/examples/node-edi.ts +6 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# Temper EDI Client
|
|
2
2
|
|
|
3
|
-
A TypeScript EDI client with structured logging and distributed tracing capabilities, built for processing X12
|
|
3
|
+
A TypeScript EDI client with structured logging and distributed tracing capabilities, built for processing X12 (including HIPAA) and EDIFACT documents with comprehensive error handling and automatic span tracking.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **X12 EDI Processing**: Complete X12 document parsing, validation, and generation
|
|
7
|
+
- **X12 EDI Processing**: Complete X12 document parsing, validation, and generation — HIPAA guide models resolve automatically from the ST03 implementation reference
|
|
8
|
+
- **EDIFACT Processing**: `fromEdifact` / `toEdifact` / `validateEdifact` / `acknowledgeEdifact` with the same error handling, tracing, and automatic control-reference stamping (UNB-0020 from the central counter service, UNH-0062 local sequence)
|
|
8
9
|
- **Structured Logging**: Built-in integration with Temper Logger for comprehensive operation tracking
|
|
9
10
|
- **Distributed Tracing**: Automatic span creation for all EDI operations with detailed payload information
|
|
10
11
|
- **Type Safety**: Full TypeScript support with comprehensive type definitions
|
|
@@ -54,10 +55,15 @@ const x12Document = await edi.toX12({
|
|
|
54
55
|
input: x12Interchanges[0],
|
|
55
56
|
});
|
|
56
57
|
|
|
57
|
-
// Generate
|
|
58
|
-
const
|
|
58
|
+
// Generate and serialize acknowledgments
|
|
59
|
+
const acknowledgments = await edi.acknowledgeX12({
|
|
59
60
|
input: x12Interchanges[0],
|
|
60
61
|
});
|
|
62
|
+
|
|
63
|
+
for (const acknowledgment of acknowledgments) {
|
|
64
|
+
// Apply partner-specific outbound envelope IDs here when needed.
|
|
65
|
+
const acknowledgmentX12 = await edi.toX12({ input: acknowledgment });
|
|
66
|
+
}
|
|
61
67
|
```
|
|
62
68
|
|
|
63
69
|
## API Reference
|
|
@@ -104,7 +110,7 @@ const x12Document = await edi.toX12({
|
|
|
104
110
|
|
|
105
111
|
**Returns:** X12 document as string
|
|
106
112
|
|
|
107
|
-
**Control number auto-stamping:** Leave `InterchangeControlNumber_13`, `GroupControlNumber_6`, and `TransactionSetControlNumber_02` empty or omit them.
|
|
113
|
+
**Control number auto-stamping:** Leave `InterchangeControlNumber_13`, `GroupControlNumber_6`, and `TransactionSetControlNumber_02` empty or omit them. Empty and all-zero ISA13, GS06, or ST02 values are treated as unassigned. Valid non-zero values are preserved.
|
|
108
114
|
|
|
109
115
|
#### `validateX12(options: ValidateX12Options): Promise<OperationResult>`
|
|
110
116
|
|
|
@@ -122,21 +128,29 @@ const validationResult = await edi.validateX12({
|
|
|
122
128
|
|
|
123
129
|
**Returns:** Validation result with operation details
|
|
124
130
|
|
|
125
|
-
#### `acknowledgeX12(options: AcknolwedgeX12Options): Promise<
|
|
131
|
+
#### `acknowledgeX12(options: AcknolwedgeX12Options): Promise<X12Interchange[]>`
|
|
126
132
|
|
|
127
|
-
Generates acknowledgment
|
|
133
|
+
Generates acknowledgment interchange objects. Apply any partner-specific outbound envelope IDs, then serialize
|
|
134
|
+
each acknowledgment with `toX12()`. During serialization, `toX12()` assigns control numbers using the final
|
|
135
|
+
sender and receiver. The method always returns an array because one input can produce more than one
|
|
136
|
+
acknowledgment.
|
|
128
137
|
|
|
129
138
|
```typescript
|
|
130
|
-
const
|
|
139
|
+
const acknowledgments = await edi.acknowledgeX12({
|
|
131
140
|
input: x12InterchangeObject,
|
|
132
141
|
});
|
|
142
|
+
|
|
143
|
+
for (const acknowledgment of acknowledgments) {
|
|
144
|
+
// Apply partner-specific outbound envelope IDs here when needed.
|
|
145
|
+
const serialized = await edi.toX12({ input: acknowledgment });
|
|
146
|
+
}
|
|
133
147
|
```
|
|
134
148
|
|
|
135
149
|
**Parameters:**
|
|
136
150
|
|
|
137
151
|
- `options.input` - The X12 interchange object to acknowledge
|
|
138
152
|
|
|
139
|
-
**Returns:**
|
|
153
|
+
**Returns:** The generated acknowledgment interchanges
|
|
140
154
|
|
|
141
155
|
## Error Handling
|
|
142
156
|
|
|
@@ -320,9 +334,13 @@ IEA*1*000001000`;
|
|
|
320
334
|
const x12Output = await edi.toX12({ input: interchange });
|
|
321
335
|
logger.info({ x12Output }, 'Converted back to X12');
|
|
322
336
|
|
|
323
|
-
// Generate
|
|
324
|
-
|
|
325
|
-
|
|
337
|
+
// Generate and serialize acknowledgments. toX12 assigns control numbers
|
|
338
|
+
// after any partner-specific outbound envelope changes.
|
|
339
|
+
const acknowledgments = await edi.acknowledgeX12({ input: interchange });
|
|
340
|
+
for (const acknowledgment of acknowledgments) {
|
|
341
|
+
const acknowledgmentX12 = await edi.toX12({ input: acknowledgment });
|
|
342
|
+
logger.info({ acknowledgmentX12 }, 'Generated acknowledgment');
|
|
343
|
+
}
|
|
326
344
|
}
|
|
327
345
|
} catch (error) {
|
|
328
346
|
logger.error({ err: error }, 'EDI processing failed');
|
|
@@ -350,7 +368,9 @@ const current = await getCurrentControlNumber('ISA13', 'ZZ:SENDER', 'ZZ:RECEIVER
|
|
|
350
368
|
await setControlNumber('ISA13', 'ZZ:SENDER', 'ZZ:RECEIVER', 1000);
|
|
351
369
|
```
|
|
352
370
|
|
|
353
|
-
In most cases you don't need these directly — `toX12()`
|
|
371
|
+
In most cases you don't need these directly — `toX12()` automatically stamps any empty or all-zero
|
|
372
|
+
ISA13/GS06/ST02 fields. ISA13 and GS06 use `getNextControlNumber`; ST02 is assigned `"0001"`. This includes the
|
|
373
|
+
zero placeholders returned by acknowledgment generation.
|
|
354
374
|
Once a counter has incremented, the API rejects later `setControlNumber` calls to avoid resetting active sequences.
|
|
355
375
|
Retried `setControlNumber` calls with the same already-stored seed are treated as idempotent no-ops.
|
|
356
376
|
The SDK surfaces that as a `ControlNumberError` with `code: "counter_already_started"`:
|
package/dist/control-numbers.js
CHANGED
|
@@ -123,7 +123,7 @@ function unwrapControlNumberError(error) {
|
|
|
123
123
|
*/
|
|
124
124
|
/** @public */
|
|
125
125
|
async function getNextControlNumber(counterName, senderId, receiverId, maxDigits = 9) {
|
|
126
|
-
const { data } = await getApiClient().post('/api/internal/edi/control-numbers/increment', {
|
|
126
|
+
const { data } = await getApiClient().post('/api/v2/internal/edi/control-numbers/increment', {
|
|
127
127
|
tradingPartnerKey: `${senderId}:${receiverId}`,
|
|
128
128
|
counterName,
|
|
129
129
|
});
|
|
@@ -134,7 +134,7 @@ async function getNextControlNumber(counterName, senderId, receiverId, maxDigits
|
|
|
134
134
|
*/
|
|
135
135
|
/** @public */
|
|
136
136
|
async function getCurrentControlNumber(counterName, senderId, receiverId, maxDigits = 9) {
|
|
137
|
-
const { data } = await getApiClient().get('/api/internal/edi/control-numbers/count', {
|
|
137
|
+
const { data } = await getApiClient().get('/api/v2/internal/edi/control-numbers/count', {
|
|
138
138
|
params: {
|
|
139
139
|
tradingPartnerKey: `${senderId}:${receiverId}`,
|
|
140
140
|
counterName,
|
|
@@ -148,7 +148,7 @@ async function getCurrentControlNumber(counterName, senderId, receiverId, maxDig
|
|
|
148
148
|
/** @public */
|
|
149
149
|
async function setControlNumber(counterName, senderId, receiverId, value, maxDigits = 9) {
|
|
150
150
|
const { data } = await getApiClient()
|
|
151
|
-
.post('/api/internal/edi/control-numbers/set', {
|
|
151
|
+
.post('/api/v2/internal/edi/control-numbers/set', {
|
|
152
152
|
tradingPartnerKey: `${senderId}:${receiverId}`,
|
|
153
153
|
counterName,
|
|
154
154
|
value,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type X12Interchange } from './edination-client';
|
|
1
|
+
import { type EdifactInterchange, type X12Interchange } from './edination-client';
|
|
2
2
|
export type { ControlNumberErrorCode } from './control-numbers';
|
|
3
3
|
export { ControlNumberError, getCurrentControlNumber, getNextControlNumber, isControlNumberError, setControlNumber, } from './control-numbers';
|
|
4
4
|
export * from './edination-client/model';
|
|
@@ -35,20 +35,48 @@ export interface ValidateX12Options {
|
|
|
35
35
|
export interface AcknolwedgeX12Options {
|
|
36
36
|
input: X12Interchange;
|
|
37
37
|
}
|
|
38
|
+
export interface FromEdifactOptions {
|
|
39
|
+
input: unknown;
|
|
40
|
+
}
|
|
41
|
+
export interface ToEdifactOptions {
|
|
42
|
+
input: EdifactInterchange;
|
|
43
|
+
}
|
|
44
|
+
export interface ValidateEdifactOptions {
|
|
45
|
+
input: EdifactInterchange;
|
|
46
|
+
}
|
|
47
|
+
export interface AcknowledgeEdifactOptions {
|
|
48
|
+
input: EdifactInterchange;
|
|
49
|
+
}
|
|
38
50
|
export declare class TemperEdiClient {
|
|
39
51
|
private X12;
|
|
52
|
+
private Edifact;
|
|
40
53
|
constructor();
|
|
41
54
|
private unwrap;
|
|
42
55
|
private unwrapError;
|
|
43
56
|
fromX12({ input }: FromX12Options): Promise<X12Interchange[]>;
|
|
44
57
|
/**
|
|
45
|
-
* Stamp ISA13/GS06 control numbers on the interchange if not already set.
|
|
58
|
+
* Stamp ISA13/GS06/ST02 control numbers on the interchange if not already set.
|
|
46
59
|
* Uses the Restate-backed counter service for atomic, per-trading-partner sequencing.
|
|
47
60
|
* ST02 is always "0001" (one transaction per file per ticket).
|
|
48
|
-
*
|
|
61
|
+
* Zero-filled values from acknowledgment generation are placeholders, not manual overrides.
|
|
49
62
|
*/
|
|
50
63
|
private stampControlNumbers;
|
|
51
64
|
toX12({ input }: ToX12Options): Promise<unknown>;
|
|
52
65
|
validateX12({ input }: ValidateX12Options): Promise<import("./edination-client").OperationResult>;
|
|
53
66
|
acknowledgeX12({ input }: AcknolwedgeX12Options): Promise<X12Interchange[]>;
|
|
67
|
+
fromEdifact({ input }: FromEdifactOptions): Promise<EdifactInterchange[]>;
|
|
68
|
+
/**
|
|
69
|
+
* Stamp UNB-0020/UNH-0062 control references on the interchange if not already set.
|
|
70
|
+
*
|
|
71
|
+
* UNB-0020 (interchange control reference) comes from the same Restate-backed
|
|
72
|
+
* per-trading-partner counter service X12 uses, under the platform counter name
|
|
73
|
+
* `UNB0020` — unpadded, since EDIFACT 0020 is an..14 with no fixed width. The
|
|
74
|
+
* UNZ trailer echo is set to match. UNH-0062 (message reference number) only
|
|
75
|
+
* needs uniqueness within the interchange, so it is a local 1..n sequence with
|
|
76
|
+
* no service call, echoed into each UNT — the EDIFACT sibling of ST02="0001".
|
|
77
|
+
*/
|
|
78
|
+
private stampEdifactControlNumbers;
|
|
79
|
+
toEdifact({ input }: ToEdifactOptions): Promise<unknown>;
|
|
80
|
+
validateEdifact({ input }: ValidateEdifactOptions): Promise<import("./edination-client").OperationResult>;
|
|
81
|
+
acknowledgeEdifact({ input }: AcknowledgeEdifactOptions): Promise<EdifactInterchange[]>;
|
|
54
82
|
}
|
package/dist/index.js
CHANGED
|
@@ -79,10 +79,15 @@ exports.EdiInfrastructureError = EdiInfrastructureError;
|
|
|
79
79
|
const isEdiInfrastructureError = (error) => error instanceof EdiInfrastructureError;
|
|
80
80
|
exports.isEdiInfrastructureError = isEdiInfrastructureError;
|
|
81
81
|
const buildEdiPayload = (edi) => ({ type: 'edi', edi });
|
|
82
|
-
const
|
|
82
|
+
const buildEdiTransactionPayload = (operation, format, transaction) => buildEdiPayload({ operation, type: format, transaction });
|
|
83
|
+
const needsControlNumber = (value) => {
|
|
84
|
+
const normalized = value?.trim();
|
|
85
|
+
return !normalized || /^0+$/.test(normalized);
|
|
86
|
+
};
|
|
83
87
|
const ediAxios = (0, unnbound_logger_sdk_1.traceAxios)(axios_1.default.create(), { getPayload: internal_1.internal });
|
|
84
88
|
class TemperEdiClient {
|
|
85
89
|
X12;
|
|
90
|
+
Edifact;
|
|
86
91
|
constructor() {
|
|
87
92
|
const apiKey = process.env.UNNBOUND_EDI_API_KEY;
|
|
88
93
|
// When UNNBOUND_EDI_BASE_URL is set, use self-hosted EdiFabric InHouse API
|
|
@@ -95,6 +100,7 @@ class TemperEdiClient {
|
|
|
95
100
|
// but the OpenAPI client requires a non-empty value — use a placeholder.
|
|
96
101
|
const config = new edination_client_1.Configuration({ apiKey: apiKey ?? 'self-hosted', basePath });
|
|
97
102
|
this.X12 = new edination_client_1.X12Api(config, undefined, ediAxios);
|
|
103
|
+
this.Edifact = new edination_client_1.EdifactApi(config, undefined, ediAxios);
|
|
98
104
|
}
|
|
99
105
|
unwrap(response) {
|
|
100
106
|
return response.data;
|
|
@@ -141,13 +147,13 @@ class TemperEdiClient {
|
|
|
141
147
|
return this.X12.x12ReadPost({ body: input })
|
|
142
148
|
.then(this.unwrap.bind(this))
|
|
143
149
|
.catch((error) => this.unwrapError(error, 'edi_read_error'));
|
|
144
|
-
}, (o) =>
|
|
150
|
+
}, (o) => buildEdiTransactionPayload('fromX12', 'x12', { input, output: o?.result }));
|
|
145
151
|
}
|
|
146
152
|
/**
|
|
147
|
-
* Stamp ISA13/GS06 control numbers on the interchange if not already set.
|
|
153
|
+
* Stamp ISA13/GS06/ST02 control numbers on the interchange if not already set.
|
|
148
154
|
* Uses the Restate-backed counter service for atomic, per-trading-partner sequencing.
|
|
149
155
|
* ST02 is always "0001" (one transaction per file per ticket).
|
|
150
|
-
*
|
|
156
|
+
* Zero-filled values from acknowledgment generation are placeholders, not manual overrides.
|
|
151
157
|
*/
|
|
152
158
|
async stampControlNumbers(input) {
|
|
153
159
|
const { getNextControlNumber } = await import('./control-numbers.js');
|
|
@@ -160,12 +166,13 @@ class TemperEdiClient {
|
|
|
160
166
|
const receiverKey = `${receiverQual}:${receiverId}`;
|
|
161
167
|
// Phase 1: Fetch all needed control numbers (no mutations yet).
|
|
162
168
|
// If any fetch fails, no fields are mutated — avoids partial stamping.
|
|
163
|
-
const isa13 =
|
|
169
|
+
const isa13 = needsControlNumber(isa.InterchangeControlNumber_13)
|
|
164
170
|
? await getNextControlNumber('ISA13', senderKey, receiverKey, 9)
|
|
165
171
|
: null;
|
|
166
172
|
const gs06Values = [];
|
|
167
|
-
|
|
168
|
-
|
|
173
|
+
const groups = input.Groups ?? [];
|
|
174
|
+
for (let i = 0; i < groups.length; i++) {
|
|
175
|
+
if (needsControlNumber(groups[i].GS.GroupControlNumber_6)) {
|
|
169
176
|
const value = await getNextControlNumber('GS06', senderKey, receiverKey, 9);
|
|
170
177
|
gs06Values.push({ index: i, value });
|
|
171
178
|
}
|
|
@@ -178,16 +185,16 @@ class TemperEdiClient {
|
|
|
178
185
|
}
|
|
179
186
|
}
|
|
180
187
|
for (const { index, value } of gs06Values) {
|
|
181
|
-
const group =
|
|
188
|
+
const group = groups[index];
|
|
182
189
|
group.GS.GroupControlNumber_6 = value;
|
|
183
190
|
if (group.GETrailers?.length) {
|
|
184
191
|
group.GETrailers[0].GroupControlNumber_2 = value;
|
|
185
192
|
}
|
|
186
193
|
}
|
|
187
194
|
// ST02 — always "0001" (pure assignment, no external calls)
|
|
188
|
-
for (const group of
|
|
195
|
+
for (const group of groups) {
|
|
189
196
|
for (const tx of group.Transactions) {
|
|
190
|
-
if (
|
|
197
|
+
if (needsControlNumber(tx?.ST?.TransactionSetControlNumber_02)) {
|
|
191
198
|
if (tx?.ST)
|
|
192
199
|
tx.ST.TransactionSetControlNumber_02 = '0001';
|
|
193
200
|
if (tx?.SE)
|
|
@@ -210,7 +217,7 @@ class TemperEdiClient {
|
|
|
210
217
|
return this.X12.x12WritePost({ x12Interchange: input })
|
|
211
218
|
.then(this.unwrap.bind(this))
|
|
212
219
|
.catch((error) => this.unwrapError(error, 'edi_write_error'));
|
|
213
|
-
}, (o) =>
|
|
220
|
+
}, (o) => buildEdiTransactionPayload('toX12', 'x12', { input, output: o?.result }));
|
|
214
221
|
}
|
|
215
222
|
validateX12({ input }) {
|
|
216
223
|
return (0, unnbound_logger_sdk_1.startSpan)('Validate X12', () => {
|
|
@@ -218,7 +225,7 @@ class TemperEdiClient {
|
|
|
218
225
|
.then(this.unwrap.bind(this))
|
|
219
226
|
.catch((error) => this.unwrapError(error, 'edi_validate_error'));
|
|
220
227
|
}, (o) => ({
|
|
221
|
-
...
|
|
228
|
+
...buildEdiTransactionPayload('validateX12', 'x12', { input, output: o?.result }),
|
|
222
229
|
...(o?.result?.Status === 'error' && { level: 'warn' }),
|
|
223
230
|
}));
|
|
224
231
|
}
|
|
@@ -227,7 +234,87 @@ class TemperEdiClient {
|
|
|
227
234
|
return this.X12.x12AckPost({ x12Interchange: input })
|
|
228
235
|
.then(this.unwrap.bind(this))
|
|
229
236
|
.catch((error) => this.unwrapError(error, 'edi_acknowledge_error'));
|
|
230
|
-
}, (o) =>
|
|
237
|
+
}, (o) => buildEdiTransactionPayload('acknowledgeX12', 'x12', { input, output: o?.result }));
|
|
238
|
+
}
|
|
239
|
+
fromEdifact({ input }) {
|
|
240
|
+
return (0, unnbound_logger_sdk_1.startSpan)('EDIFACT to JSON', () => {
|
|
241
|
+
return this.Edifact.edifactReadPost({ body: input })
|
|
242
|
+
.then(this.unwrap.bind(this))
|
|
243
|
+
.catch((error) => this.unwrapError(error, 'edi_read_error'));
|
|
244
|
+
}, (o) => buildEdiTransactionPayload('fromEdifact', 'edifact', { input, output: o?.result }));
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Stamp UNB-0020/UNH-0062 control references on the interchange if not already set.
|
|
248
|
+
*
|
|
249
|
+
* UNB-0020 (interchange control reference) comes from the same Restate-backed
|
|
250
|
+
* per-trading-partner counter service X12 uses, under the platform counter name
|
|
251
|
+
* `UNB0020` — unpadded, since EDIFACT 0020 is an..14 with no fixed width. The
|
|
252
|
+
* UNZ trailer echo is set to match. UNH-0062 (message reference number) only
|
|
253
|
+
* needs uniqueness within the interchange, so it is a local 1..n sequence with
|
|
254
|
+
* no service call, echoed into each UNT — the EDIFACT sibling of ST02="0001".
|
|
255
|
+
*/
|
|
256
|
+
async stampEdifactControlNumbers(input) {
|
|
257
|
+
const { getNextControlNumber } = await import('./control-numbers.js');
|
|
258
|
+
const sender = input.UNB?.INTERCHANGESENDER_2;
|
|
259
|
+
const recipient = input.UNB?.INTERCHANGERECIPIENT_3;
|
|
260
|
+
const senderKey = `${(sender?.IdentificationCodeQualifier_2 || '').trim()}:${(sender?.InterchangeSenderIdentification_1 || '').trim()}`;
|
|
261
|
+
const receiverKey = `${(recipient?.IdentificationCodeQualifier_2 || '').trim()}:${(recipient?.InterchangeRecipientIdentification_1 || '').trim()}`;
|
|
262
|
+
// Fetch before mutating — if the fetch fails, no fields change.
|
|
263
|
+
const unb0020 = needsControlNumber(input.UNB?.InterchangeControlReference_5)
|
|
264
|
+
? await getNextControlNumber('UNB0020', senderKey, receiverKey, 0)
|
|
265
|
+
: null;
|
|
266
|
+
if (unb0020) {
|
|
267
|
+
input.UNB.InterchangeControlReference_5 = unb0020;
|
|
268
|
+
if (input.UNZTrailers?.length) {
|
|
269
|
+
input.UNZTrailers[0].InterchangeControlReference_2 = unb0020;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
// UNH-0062 — local sequence across the interchange's messages (no external calls)
|
|
273
|
+
let messageReference = 0;
|
|
274
|
+
for (const group of input.Groups ?? []) {
|
|
275
|
+
for (const message of group.Transactions ?? []) {
|
|
276
|
+
messageReference += 1;
|
|
277
|
+
if (needsControlNumber(message?.UNH?.MessageReferenceNumber_01)) {
|
|
278
|
+
if (message?.UNH)
|
|
279
|
+
message.UNH.MessageReferenceNumber_01 = String(messageReference);
|
|
280
|
+
if (message?.UNT)
|
|
281
|
+
message.UNT.MessageReferenceNumber_02 = String(messageReference);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
async toEdifact({ input }) {
|
|
287
|
+
// Auto-stamp control references before writing EDIFACT
|
|
288
|
+
try {
|
|
289
|
+
await this.stampEdifactControlNumbers(input);
|
|
290
|
+
}
|
|
291
|
+
catch (error) {
|
|
292
|
+
// Log but don't fail — workflows can still set control references manually
|
|
293
|
+
const { logger } = await import('unnbound-logger-sdk');
|
|
294
|
+
logger.warn({ err: error }, '[EDI SDK] Failed to auto-stamp control references, proceeding without');
|
|
295
|
+
}
|
|
296
|
+
return (0, unnbound_logger_sdk_1.startSpan)('JSON to EDIFACT', () => {
|
|
297
|
+
return this.Edifact.edifactWritePost({ edifactInterchange: input })
|
|
298
|
+
.then(this.unwrap.bind(this))
|
|
299
|
+
.catch((error) => this.unwrapError(error, 'edi_write_error'));
|
|
300
|
+
}, (o) => buildEdiTransactionPayload('toEdifact', 'edifact', { input, output: o?.result }));
|
|
301
|
+
}
|
|
302
|
+
validateEdifact({ input }) {
|
|
303
|
+
return (0, unnbound_logger_sdk_1.startSpan)('Validate EDIFACT', () => {
|
|
304
|
+
return this.Edifact.edifactValidatePost({ edifactInterchange: input })
|
|
305
|
+
.then(this.unwrap.bind(this))
|
|
306
|
+
.catch((error) => this.unwrapError(error, 'edi_validate_error'));
|
|
307
|
+
}, (o) => ({
|
|
308
|
+
...buildEdiTransactionPayload('validateEdifact', 'edifact', { input, output: o?.result }),
|
|
309
|
+
...(o?.result?.Status === 'error' && { level: 'warn' }),
|
|
310
|
+
}));
|
|
311
|
+
}
|
|
312
|
+
acknowledgeEdifact({ input }) {
|
|
313
|
+
return (0, unnbound_logger_sdk_1.startSpan)('Acknowledge EDIFACT', () => {
|
|
314
|
+
return this.Edifact.edifactAckPost({ edifactInterchange: input })
|
|
315
|
+
.then(this.unwrap.bind(this))
|
|
316
|
+
.catch((error) => this.unwrapError(error, 'edi_acknowledge_error'));
|
|
317
|
+
}, (o) => buildEdiTransactionPayload('acknowledgeEdifact', 'edifact', { input, output: o?.result }));
|
|
231
318
|
}
|
|
232
319
|
}
|
|
233
320
|
exports.TemperEdiClient = TemperEdiClient;
|
package/examples/node-edi.ts
CHANGED
|
@@ -46,9 +46,13 @@ IEA*1*000001000`;
|
|
|
46
46
|
|
|
47
47
|
logger.info({ validated }, 'X12 validated.');
|
|
48
48
|
|
|
49
|
-
const
|
|
49
|
+
const acknowledgments = await edi.acknowledgeX12({ input: x12Interchange });
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
for (const acknowledgment of acknowledgments) {
|
|
52
|
+
// Apply partner-specific outbound envelope IDs before serialization when needed.
|
|
53
|
+
const acknowledgmentX12 = await edi.toX12({ input: acknowledgment });
|
|
54
|
+
logger.info({ acknowledgmentX12 }, 'X12 acknowledgment generated.');
|
|
55
|
+
}
|
|
52
56
|
}),
|
|
53
57
|
);
|
|
54
58
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ontemper/edi",
|
|
3
3
|
"description": "An EDI client with structured logging.",
|
|
4
|
-
"version": "1.1
|
|
4
|
+
"version": "1.2.0-beta.1",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"author": "Unnbound Team",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"axios": "1.16.0",
|
|
19
|
-
"unnbound-logger-sdk": "3.0.
|
|
19
|
+
"unnbound-logger-sdk": "3.2.0-beta.1"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@types/jest": "^29.5.12",
|