@ontemper/edi 1.1.7 → 1.2.0-beta.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/README.md +64 -24
- package/dist/control-numbers.d.ts +30 -4
- package/dist/control-numbers.js +70 -14
- package/dist/index.d.ts +3 -3
- package/dist/index.js +14 -17
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -350,43 +350,83 @@ IEA*1*000001000`;
|
|
|
350
350
|
run().catch(console.error);
|
|
351
351
|
```
|
|
352
352
|
|
|
353
|
-
## Control
|
|
353
|
+
## Control numbers
|
|
354
354
|
|
|
355
|
-
The SDK
|
|
355
|
+
The SDK manages ISA13 and GS06 control numbers for each sender and receiver pair. `toX12()` automatically stamps
|
|
356
|
+
empty or all-zero ISA13, GS06, and ST02 fields. It preserves valid non-zero values. ISA13 and GS06 use the
|
|
357
|
+
centralized counters. ST02 is assigned `"0001"`.
|
|
358
|
+
|
|
359
|
+
**By default, every environment draws from one shared sequence per trading partner. No setup is required.**
|
|
360
|
+
Separating test traffic onto its own sequence is an optional, per-partner opt-in for agreements that demand it.
|
|
361
|
+
|
|
362
|
+
### Separate test counters (optional)
|
|
363
|
+
|
|
364
|
+
Skip this section unless a trading-partner agreement requires test traffic on an independent sequence. To opt in,
|
|
365
|
+
configure the trading partner once, then seed and verify the lanes before sending test traffic. A seeded value is the
|
|
366
|
+
last-used number, so the next allocation returns the seed plus one. To make the next ISA13 value 4601, seed 4600:
|
|
356
367
|
|
|
357
368
|
```typescript
|
|
358
|
-
import {
|
|
369
|
+
import {
|
|
370
|
+
getControlNumberPolicy,
|
|
371
|
+
getCurrentControlNumber,
|
|
372
|
+
setControlNumber,
|
|
373
|
+
setControlNumberPolicy,
|
|
374
|
+
} from '@ontemper/edi';
|
|
359
375
|
|
|
360
|
-
|
|
361
|
-
const
|
|
376
|
+
const senderId = 'ZZ:SENDER';
|
|
377
|
+
const receiverId = 'ZZ:RECEIVER';
|
|
362
378
|
|
|
363
|
-
|
|
364
|
-
const current = await getCurrentControlNumber('ISA13', 'ZZ:SENDER', 'ZZ:RECEIVER');
|
|
379
|
+
await setControlNumberPolicy(senderId, receiverId, { separateCounters: true });
|
|
365
380
|
|
|
366
|
-
//
|
|
367
|
-
await setControlNumber('ISA13',
|
|
381
|
+
// Seed the production lane explicitly before it starts.
|
|
382
|
+
await setControlNumber('ISA13', senderId, receiverId, 4600, 9, { lane: 'production' });
|
|
383
|
+
|
|
384
|
+
const policy = await getControlNumberPolicy(senderId, receiverId);
|
|
385
|
+
const production = await getCurrentControlNumber('ISA13', senderId, receiverId, 9, { lane: 'production' });
|
|
386
|
+
const test = await getCurrentControlNumber('ISA13', senderId, receiverId, 9, { lane: 'test' });
|
|
368
387
|
```
|
|
369
388
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
389
|
+
`getControlNumberPolicy()` returns `configured` and `separateCounters`. After test traffic starts, you cannot turn
|
|
390
|
+
separate counters off. `setControlNumberPolicy()` reports this as a `ControlNumberError` with the
|
|
391
|
+
`counter_policy_locked` code.
|
|
392
|
+
|
|
393
|
+
### Automatic environment routing
|
|
394
|
+
|
|
395
|
+
The SDK reads `UNNBOUND_ENVIRONMENT` and sends it with counter operations only when its value is `sandbox`,
|
|
396
|
+
`staging`, or `production`. The service selects the lane:
|
|
397
|
+
|
|
398
|
+
| Policy | Production environment | Sandbox or staging |
|
|
399
|
+
| --- | --- | --- |
|
|
400
|
+
| No policy row | Production lane | Production lane |
|
|
401
|
+
| `separateCounters: false` | Production lane | Production lane |
|
|
402
|
+
| `separateCounters: true` | Production lane | Test lane |
|
|
403
|
+
|
|
404
|
+
Older SDK versions do not send the environment, so their operations use the production lane. This is the historical
|
|
405
|
+
sequence that all environments use when separation is off. ISA15
|
|
406
|
+
(`UsageIndicator_15`) never selects a counter. Set ISA15 independently to the value required by the interchange.
|
|
407
|
+
`toX12()` does not change it.
|
|
408
|
+
|
|
409
|
+
### Manage counters directly
|
|
376
410
|
|
|
377
411
|
```typescript
|
|
378
|
-
import {
|
|
412
|
+
import { getCurrentControlNumber, getNextControlNumber, setControlNumber } from '@ontemper/edi';
|
|
379
413
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
// Counter is already active; do not reset it.
|
|
385
|
-
}
|
|
386
|
-
}
|
|
414
|
+
const next = await getNextControlNumber('ISA13', 'ZZ:SENDER', 'ZZ:RECEIVER');
|
|
415
|
+
const current = await getCurrentControlNumber('ISA13', 'ZZ:SENDER', 'ZZ:RECEIVER');
|
|
416
|
+
// The seed is last-used. To allocate 4601 next, seed 4600.
|
|
417
|
+
await setControlNumber('ISA13', 'ZZ:SENDER', 'ZZ:RECEIVER', 4600, 9, { lane: 'production' });
|
|
387
418
|
```
|
|
388
419
|
|
|
389
|
-
|
|
420
|
+
Use the optional `{ lane: 'production' | 'test' }` argument on `getCurrentControlNumber()` and `setControlNumber()`
|
|
421
|
+
to inspect or seed a specific lane. `getNextControlNumber()` always uses automatic environment routing and does not
|
|
422
|
+
accept a lane.
|
|
423
|
+
|
|
424
|
+
The seeded value is the last-used number, and the next allocation returns the seed plus one. For example, if you
|
|
425
|
+
expect the next ISA13 value to be 4601, seed 4600. Set this value before the counter increments. The service treats a
|
|
426
|
+
repeated seed with the same stored value as an idempotent operation. It rejects other updates after the counter
|
|
427
|
+
starts with a `ControlNumberError` whose code is `counter_already_started`.
|
|
428
|
+
|
|
429
|
+
These helpers require `UNNBOUND_API_URL`, which is preconfigured in workflow environments.
|
|
390
430
|
|
|
391
431
|
## Requirements
|
|
392
432
|
|
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
/** @public */
|
|
2
|
-
export type
|
|
2
|
+
export type ControlNumberCounterName = 'ISA13' | 'GS06';
|
|
3
|
+
/** @public */
|
|
4
|
+
export type ControlNumberLane = 'production' | 'test';
|
|
5
|
+
/** @public */
|
|
6
|
+
export interface ControlNumberLaneOptions {
|
|
7
|
+
readonly lane?: ControlNumberLane;
|
|
8
|
+
}
|
|
9
|
+
/** @public */
|
|
10
|
+
export interface SetControlNumberPolicyOptions {
|
|
11
|
+
readonly separateCounters: boolean;
|
|
12
|
+
}
|
|
13
|
+
/** @public */
|
|
14
|
+
export interface SetControlNumberPolicyResponse {
|
|
15
|
+
readonly tradingPartnerKey: string;
|
|
16
|
+
readonly separateCounters: boolean;
|
|
17
|
+
}
|
|
18
|
+
/** @public */
|
|
19
|
+
export interface GetControlNumberPolicyResponse {
|
|
20
|
+
readonly configured: boolean;
|
|
21
|
+
readonly separateCounters: boolean;
|
|
22
|
+
}
|
|
23
|
+
/** @public */
|
|
24
|
+
export type ControlNumberErrorCode = 'counter_already_started' | 'counter_policy_locked' | 'control_number_bad_request' | 'control_number_unauthorized' | 'control_number_unknown_error';
|
|
3
25
|
interface ControlNumberErrorOptions extends ErrorOptions {
|
|
4
26
|
code: ControlNumberErrorCode;
|
|
5
27
|
message: string;
|
|
@@ -23,15 +45,19 @@ export declare const isControlNumberError: (error: unknown) => error is ControlN
|
|
|
23
45
|
* @param maxDigits - Zero-pad to this width (default: 9 for ISA13)
|
|
24
46
|
*/
|
|
25
47
|
/** @public */
|
|
26
|
-
export declare function getNextControlNumber(counterName:
|
|
48
|
+
export declare function getNextControlNumber(counterName: ControlNumberCounterName, senderId: string, receiverId: string, maxDigits?: number): Promise<string>;
|
|
27
49
|
/**
|
|
28
50
|
* Get the current control number value without incrementing.
|
|
29
51
|
*/
|
|
30
52
|
/** @public */
|
|
31
|
-
export declare function getCurrentControlNumber(counterName:
|
|
53
|
+
export declare function getCurrentControlNumber(counterName: ControlNumberCounterName, senderId: string, receiverId: string, maxDigits?: number, options?: ControlNumberLaneOptions): Promise<string>;
|
|
32
54
|
/**
|
|
33
55
|
* Set a control number to a specific value before the counter starts (for migration/seeding).
|
|
34
56
|
*/
|
|
35
57
|
/** @public */
|
|
36
|
-
export declare function setControlNumber(counterName:
|
|
58
|
+
export declare function setControlNumber(counterName: ControlNumberCounterName, senderId: string, receiverId: string, value: number, maxDigits?: number, options?: ControlNumberLaneOptions): Promise<string>;
|
|
59
|
+
/** @public */
|
|
60
|
+
export declare function setControlNumberPolicy(senderId: string, receiverId: string, { separateCounters }: SetControlNumberPolicyOptions): Promise<SetControlNumberPolicyResponse>;
|
|
61
|
+
/** @public */
|
|
62
|
+
export declare function getControlNumberPolicy(senderId: string, receiverId: string): Promise<GetControlNumberPolicyResponse>;
|
|
37
63
|
export {};
|
package/dist/control-numbers.js
CHANGED
|
@@ -37,6 +37,8 @@ exports.isControlNumberError = exports.ControlNumberError = void 0;
|
|
|
37
37
|
exports.getNextControlNumber = getNextControlNumber;
|
|
38
38
|
exports.getCurrentControlNumber = getCurrentControlNumber;
|
|
39
39
|
exports.setControlNumber = setControlNumber;
|
|
40
|
+
exports.setControlNumberPolicy = setControlNumberPolicy;
|
|
41
|
+
exports.getControlNumberPolicy = getControlNumberPolicy;
|
|
40
42
|
const axios_1 = __importStar(require("axios"));
|
|
41
43
|
let _client = null;
|
|
42
44
|
function getApiClient() {
|
|
@@ -78,10 +80,23 @@ exports.ControlNumberError = ControlNumberError;
|
|
|
78
80
|
/** @public */
|
|
79
81
|
const isControlNumberError = (error) => error instanceof ControlNumberError;
|
|
80
82
|
exports.isControlNumberError = isControlNumberError;
|
|
81
|
-
|
|
83
|
+
const getEnvironment = () => {
|
|
84
|
+
const environment = process.env.UNNBOUND_ENVIRONMENT;
|
|
85
|
+
return environment === 'sandbox' || environment === 'staging' || environment === 'production'
|
|
86
|
+
? environment
|
|
87
|
+
: undefined;
|
|
88
|
+
};
|
|
89
|
+
function unwrapControlNumberError(error, operation) {
|
|
82
90
|
if (error instanceof ControlNumberError)
|
|
83
91
|
throw error;
|
|
84
92
|
if ((0, axios_1.isAxiosError)(error)) {
|
|
93
|
+
if (error.response?.status === 409 && operation === 'policy') {
|
|
94
|
+
throw new ControlNumberError({
|
|
95
|
+
code: 'counter_policy_locked',
|
|
96
|
+
message: 'Separate counters cannot be disabled after test traffic has started. Keep separate counters enabled or contact Temper support.',
|
|
97
|
+
cause: error,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
85
100
|
if (error.response?.status === 409) {
|
|
86
101
|
throw new ControlNumberError({
|
|
87
102
|
code: 'counter_already_started',
|
|
@@ -92,7 +107,7 @@ function unwrapControlNumberError(error) {
|
|
|
92
107
|
if (error.response?.status === 400) {
|
|
93
108
|
throw new ControlNumberError({
|
|
94
109
|
code: 'control_number_bad_request',
|
|
95
|
-
message:
|
|
110
|
+
message: "Invalid EDI control number request. Use counter name 'ISA13' or 'GS06' with trading partner IDs and, for set, a value.",
|
|
96
111
|
cause: error,
|
|
97
112
|
});
|
|
98
113
|
}
|
|
@@ -110,6 +125,21 @@ function unwrapControlNumberError(error) {
|
|
|
110
125
|
cause: error,
|
|
111
126
|
});
|
|
112
127
|
}
|
|
128
|
+
async function requestControlNumber(operation, input) {
|
|
129
|
+
const environment = getEnvironment();
|
|
130
|
+
const request = { ...input, ...(environment ? { environment } : {}) };
|
|
131
|
+
try {
|
|
132
|
+
const response = operation === 'count'
|
|
133
|
+
? await getApiClient().get(`/api/v2/internal/edi/control-numbers/${operation}`, {
|
|
134
|
+
params: request,
|
|
135
|
+
})
|
|
136
|
+
: await getApiClient().post(`/api/v2/internal/edi/control-numbers/${operation}`, request);
|
|
137
|
+
return response.data;
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
return unwrapControlNumberError(error, operation);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
113
143
|
/**
|
|
114
144
|
* Get the next control number for an EDI counter.
|
|
115
145
|
*
|
|
@@ -123,7 +153,7 @@ function unwrapControlNumberError(error) {
|
|
|
123
153
|
*/
|
|
124
154
|
/** @public */
|
|
125
155
|
async function getNextControlNumber(counterName, senderId, receiverId, maxDigits = 9) {
|
|
126
|
-
const
|
|
156
|
+
const data = await requestControlNumber('increment', {
|
|
127
157
|
tradingPartnerKey: `${senderId}:${receiverId}`,
|
|
128
158
|
counterName,
|
|
129
159
|
});
|
|
@@ -133,12 +163,11 @@ async function getNextControlNumber(counterName, senderId, receiverId, maxDigits
|
|
|
133
163
|
* Get the current control number value without incrementing.
|
|
134
164
|
*/
|
|
135
165
|
/** @public */
|
|
136
|
-
async function getCurrentControlNumber(counterName, senderId, receiverId, maxDigits = 9) {
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
},
|
|
166
|
+
async function getCurrentControlNumber(counterName, senderId, receiverId, maxDigits = 9, options) {
|
|
167
|
+
const data = await requestControlNumber('count', {
|
|
168
|
+
tradingPartnerKey: `${senderId}:${receiverId}`,
|
|
169
|
+
counterName,
|
|
170
|
+
...(options?.lane ? { lane: options.lane } : {}),
|
|
142
171
|
});
|
|
143
172
|
return String(data.value).padStart(maxDigits, '0');
|
|
144
173
|
}
|
|
@@ -146,13 +175,40 @@ async function getCurrentControlNumber(counterName, senderId, receiverId, maxDig
|
|
|
146
175
|
* Set a control number to a specific value before the counter starts (for migration/seeding).
|
|
147
176
|
*/
|
|
148
177
|
/** @public */
|
|
149
|
-
async function setControlNumber(counterName, senderId, receiverId, value, maxDigits = 9) {
|
|
150
|
-
const
|
|
151
|
-
.post('/api/internal/edi/control-numbers/set', {
|
|
178
|
+
async function setControlNumber(counterName, senderId, receiverId, value, maxDigits = 9, options) {
|
|
179
|
+
const data = await requestControlNumber('set', {
|
|
152
180
|
tradingPartnerKey: `${senderId}:${receiverId}`,
|
|
153
181
|
counterName,
|
|
154
182
|
value,
|
|
155
|
-
|
|
156
|
-
|
|
183
|
+
...(options?.lane ? { lane: options.lane } : {}),
|
|
184
|
+
});
|
|
157
185
|
return String(data.value).padStart(maxDigits, '0');
|
|
158
186
|
}
|
|
187
|
+
/** @public */
|
|
188
|
+
async function setControlNumberPolicy(senderId, receiverId, { separateCounters }) {
|
|
189
|
+
try {
|
|
190
|
+
const response = await getApiClient().post('/api/v2/internal/edi/control-numbers/policy', {
|
|
191
|
+
tradingPartnerKey: `${senderId}:${receiverId}`,
|
|
192
|
+
separateCounters,
|
|
193
|
+
});
|
|
194
|
+
return response.data;
|
|
195
|
+
}
|
|
196
|
+
catch (error) {
|
|
197
|
+
return unwrapControlNumberError(error, 'policy');
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/** @public */
|
|
201
|
+
async function getControlNumberPolicy(senderId, receiverId) {
|
|
202
|
+
try {
|
|
203
|
+
const response = await getApiClient().get('/api/v2/internal/edi/control-numbers/policy', {
|
|
204
|
+
params: { tradingPartnerKey: `${senderId}:${receiverId}` },
|
|
205
|
+
});
|
|
206
|
+
return {
|
|
207
|
+
configured: response.data.configured,
|
|
208
|
+
separateCounters: response.data.separateCounters,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
catch (error) {
|
|
212
|
+
return unwrapControlNumberError(error, 'policy');
|
|
213
|
+
}
|
|
214
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export type { ControlNumberErrorCode } from './control-numbers';
|
|
3
|
-
export { ControlNumberError, getCurrentControlNumber, getNextControlNumber, isControlNumberError, setControlNumber, } from './control-numbers';
|
|
1
|
+
import type { X12Interchange } from './edination-client';
|
|
2
|
+
export type { ControlNumberCounterName, ControlNumberErrorCode, ControlNumberLane, ControlNumberLaneOptions, GetControlNumberPolicyResponse, SetControlNumberPolicyOptions, SetControlNumberPolicyResponse, } from './control-numbers';
|
|
3
|
+
export { ControlNumberError, getControlNumberPolicy, getCurrentControlNumber, getNextControlNumber, isControlNumberError, setControlNumber, setControlNumberPolicy, } from './control-numbers';
|
|
4
4
|
export * from './edination-client/model';
|
|
5
5
|
interface UnnboundErrorOptions<C extends string = string> extends ErrorOptions {
|
|
6
6
|
message: string;
|
package/dist/index.js
CHANGED
|
@@ -36,17 +36,20 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
36
36
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
37
37
|
};
|
|
38
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
-
exports.TemperEdiClient = exports.isEdiInfrastructureError = exports.EdiInfrastructureError = exports.isTemperEdiClientError = exports.TemperEdiClientError = exports.setControlNumber = exports.isControlNumberError = exports.getNextControlNumber = exports.getCurrentControlNumber = exports.ControlNumberError = void 0;
|
|
39
|
+
exports.TemperEdiClient = exports.isEdiInfrastructureError = exports.EdiInfrastructureError = exports.isTemperEdiClientError = exports.TemperEdiClientError = exports.setControlNumberPolicy = exports.setControlNumber = exports.isControlNumberError = exports.getNextControlNumber = exports.getCurrentControlNumber = exports.getControlNumberPolicy = exports.ControlNumberError = void 0;
|
|
40
40
|
const axios_1 = __importStar(require("axios"));
|
|
41
41
|
const unnbound_logger_sdk_1 = require("unnbound-logger-sdk");
|
|
42
42
|
const internal_1 = require("unnbound-logger-sdk/dist/internal");
|
|
43
|
+
const control_numbers_1 = require("./control-numbers");
|
|
43
44
|
const edination_client_1 = require("./edination-client");
|
|
44
|
-
var
|
|
45
|
-
Object.defineProperty(exports, "ControlNumberError", { enumerable: true, get: function () { return
|
|
46
|
-
Object.defineProperty(exports, "
|
|
47
|
-
Object.defineProperty(exports, "
|
|
48
|
-
Object.defineProperty(exports, "
|
|
49
|
-
Object.defineProperty(exports, "
|
|
45
|
+
var control_numbers_2 = require("./control-numbers");
|
|
46
|
+
Object.defineProperty(exports, "ControlNumberError", { enumerable: true, get: function () { return control_numbers_2.ControlNumberError; } });
|
|
47
|
+
Object.defineProperty(exports, "getControlNumberPolicy", { enumerable: true, get: function () { return control_numbers_2.getControlNumberPolicy; } });
|
|
48
|
+
Object.defineProperty(exports, "getCurrentControlNumber", { enumerable: true, get: function () { return control_numbers_2.getCurrentControlNumber; } });
|
|
49
|
+
Object.defineProperty(exports, "getNextControlNumber", { enumerable: true, get: function () { return control_numbers_2.getNextControlNumber; } });
|
|
50
|
+
Object.defineProperty(exports, "isControlNumberError", { enumerable: true, get: function () { return control_numbers_2.isControlNumberError; } });
|
|
51
|
+
Object.defineProperty(exports, "setControlNumber", { enumerable: true, get: function () { return control_numbers_2.setControlNumber; } });
|
|
52
|
+
Object.defineProperty(exports, "setControlNumberPolicy", { enumerable: true, get: function () { return control_numbers_2.setControlNumberPolicy; } });
|
|
50
53
|
__exportStar(require("./edination-client/model"), exports);
|
|
51
54
|
class UnnboundError extends Error {
|
|
52
55
|
code;
|
|
@@ -154,7 +157,6 @@ class TemperEdiClient {
|
|
|
154
157
|
* Zero-filled values from acknowledgment generation are placeholders, not manual overrides.
|
|
155
158
|
*/
|
|
156
159
|
async stampControlNumbers(input) {
|
|
157
|
-
const { getNextControlNumber } = await import('./control-numbers.js');
|
|
158
160
|
const isa = input.ISA;
|
|
159
161
|
const senderQual = (isa.SenderIDQualifier_5 || '').trim();
|
|
160
162
|
const senderId = (isa.InterchangeSenderID_6 || '').trim();
|
|
@@ -162,20 +164,18 @@ class TemperEdiClient {
|
|
|
162
164
|
const receiverId = (isa.InterchangeReceiverID_8 || '').trim();
|
|
163
165
|
const senderKey = `${senderQual}:${senderId}`;
|
|
164
166
|
const receiverKey = `${receiverQual}:${receiverId}`;
|
|
165
|
-
//
|
|
166
|
-
// If any fetch fails, no fields are mutated — avoids partial stamping.
|
|
167
|
+
// Allocate before mutating so a failed request cannot leave partial stamps.
|
|
167
168
|
const isa13 = needsControlNumber(isa.InterchangeControlNumber_13)
|
|
168
|
-
? await getNextControlNumber('ISA13', senderKey, receiverKey, 9)
|
|
169
|
+
? await (0, control_numbers_1.getNextControlNumber)('ISA13', senderKey, receiverKey, 9)
|
|
169
170
|
: null;
|
|
170
171
|
const gs06Values = [];
|
|
171
172
|
const groups = input.Groups ?? [];
|
|
172
173
|
for (let i = 0; i < groups.length; i++) {
|
|
173
174
|
if (needsControlNumber(groups[i].GS.GroupControlNumber_6)) {
|
|
174
|
-
const value = await getNextControlNumber('GS06', senderKey, receiverKey, 9);
|
|
175
|
+
const value = await (0, control_numbers_1.getNextControlNumber)('GS06', senderKey, receiverKey, 9);
|
|
175
176
|
gs06Values.push({ index: i, value });
|
|
176
177
|
}
|
|
177
178
|
}
|
|
178
|
-
// Phase 2: Apply all mutations (only reached if all fetches succeeded).
|
|
179
179
|
if (isa13) {
|
|
180
180
|
isa.InterchangeControlNumber_13 = isa13;
|
|
181
181
|
if (input.IEATrailers?.length) {
|
|
@@ -189,7 +189,6 @@ class TemperEdiClient {
|
|
|
189
189
|
group.GETrailers[0].GroupControlNumber_2 = value;
|
|
190
190
|
}
|
|
191
191
|
}
|
|
192
|
-
// ST02 — always "0001" (pure assignment, no external calls)
|
|
193
192
|
for (const group of groups) {
|
|
194
193
|
for (const tx of group.Transactions) {
|
|
195
194
|
if (needsControlNumber(tx?.ST?.TransactionSetControlNumber_02)) {
|
|
@@ -202,14 +201,12 @@ class TemperEdiClient {
|
|
|
202
201
|
}
|
|
203
202
|
}
|
|
204
203
|
async toX12({ input }) {
|
|
205
|
-
// Auto-stamp control numbers before writing X12
|
|
206
204
|
try {
|
|
207
205
|
await this.stampControlNumbers(input);
|
|
208
206
|
}
|
|
209
207
|
catch (error) {
|
|
210
208
|
// Log but don't fail — workflows can still set control numbers manually
|
|
211
|
-
|
|
212
|
-
logger.warn({ err: error }, '[EDI SDK] Failed to auto-stamp control numbers, proceeding without');
|
|
209
|
+
unnbound_logger_sdk_1.logger.warn({ err: error }, '[EDI SDK] Failed to auto-stamp control numbers, proceeding without');
|
|
213
210
|
}
|
|
214
211
|
return (0, unnbound_logger_sdk_1.startSpan)('JSON to X12', () => {
|
|
215
212
|
return this.X12.x12WritePost({ x12Interchange: input })
|
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.
|
|
4
|
+
"version": "1.2.0-beta.2",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"author": "Unnbound Team",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"url": "https://github.com/unnbounddev/unnbound-sdks/issues"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"axios": "1.
|
|
18
|
+
"axios": "1.18.0",
|
|
19
19
|
"unnbound-logger-sdk": "3.0.37"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|