@ontemper/edi 1.2.0-beta.4 → 1.2.0-beta.5
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 +4 -4
- package/dist/control-numbers.js +24 -23
- package/dist/index.d.ts +1 -6
- package/dist/index.js +11 -25
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -362,9 +362,9 @@ sequence. Sandbox and staging allocations do not consume production control numb
|
|
|
362
362
|
|
|
363
363
|
### Automatic environment routing
|
|
364
364
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
causes a `ControlNumberError` with the `control_number_environment_missing` code before any HTTP request.
|
|
365
|
+
Current workflow deployments inject `UNNBOUND_ENVIRONMENT`. The SDK also accepts `TEMPER_ENVIRONMENT` as the
|
|
366
|
+
future canonical name and prefers it when present. The value must be `sandbox`, `staging`, or `production`. A missing
|
|
367
|
+
or invalid value causes a `ControlNumberError` with the `control_number_environment_missing` code before any HTTP request.
|
|
368
368
|
|
|
369
369
|
`getNextControlNumber()`, `getCurrentControlNumber()`, and `toX12()` use this environment. They do not accept an
|
|
370
370
|
environment override. ISA15 (`UsageIndicator_15`) does not select a counter, and `toX12()` does not change it.
|
|
@@ -397,7 +397,7 @@ These helpers require `UNNBOUND_API_URL`. Temper configures it in workflow envir
|
|
|
397
397
|
- TypeScript (for TypeScript projects)
|
|
398
398
|
- The EDI connection env — `UNNBOUND_EDI_BASE_URL`, plus `UNNBOUND_EDI_API_KEY` where the path needs a credential — is platform-injected per environment in Temper workflows; nothing to configure. Supply a key yourself only for the standalone legacy EDINation-cloud path.
|
|
399
399
|
- `UNNBOUND_API_URL` (for control number auto-stamping, pre-configured in workflow environments)
|
|
400
|
-
- `
|
|
400
|
+
- `UNNBOUND_ENVIRONMENT` for current counter routing; `TEMPER_ENVIRONMENT` is the preferred future name
|
|
401
401
|
|
|
402
402
|
## Dependencies
|
|
403
403
|
|
package/dist/control-numbers.js
CHANGED
|
@@ -127,19 +127,6 @@ function unwrapControlNumberError(error, environmentScoped = false) {
|
|
|
127
127
|
cause: error,
|
|
128
128
|
});
|
|
129
129
|
}
|
|
130
|
-
async function requestControlNumber(operation, input) {
|
|
131
|
-
const environment = requireEnvironment();
|
|
132
|
-
const path = `/api/v2/internal/edi/control-numbers/${environment}/${operation}`;
|
|
133
|
-
try {
|
|
134
|
-
const response = operation === 'count'
|
|
135
|
-
? await getApiClient().get(path, { params: input })
|
|
136
|
-
: await getApiClient().post(path, input);
|
|
137
|
-
return response.data;
|
|
138
|
-
}
|
|
139
|
-
catch (error) {
|
|
140
|
-
return unwrapControlNumberError(error, true);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
130
|
/**
|
|
144
131
|
* Get the next control number for an EDI counter.
|
|
145
132
|
*
|
|
@@ -153,22 +140,36 @@ async function requestControlNumber(operation, input) {
|
|
|
153
140
|
*/
|
|
154
141
|
/** @public */
|
|
155
142
|
async function getNextControlNumber(counterName, senderId, receiverId, maxDigits = 9) {
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
143
|
+
const environment = requireEnvironment();
|
|
144
|
+
try {
|
|
145
|
+
const { data } = await getApiClient().post(`/api/v2/internal/edi/control-numbers/${environment}/increment`, {
|
|
146
|
+
tradingPartnerKey: `${senderId}:${receiverId}`,
|
|
147
|
+
counterName,
|
|
148
|
+
});
|
|
149
|
+
return String(data.value).padStart(maxDigits, '0');
|
|
150
|
+
}
|
|
151
|
+
catch (error) {
|
|
152
|
+
return unwrapControlNumberError(error, true);
|
|
153
|
+
}
|
|
161
154
|
}
|
|
162
155
|
/**
|
|
163
156
|
* Get the current control number value without incrementing.
|
|
164
157
|
*/
|
|
165
158
|
/** @public */
|
|
166
159
|
async function getCurrentControlNumber(counterName, senderId, receiverId, maxDigits = 9) {
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
160
|
+
const environment = requireEnvironment();
|
|
161
|
+
try {
|
|
162
|
+
const { data } = await getApiClient().get(`/api/v2/internal/edi/control-numbers/${environment}/count`, {
|
|
163
|
+
params: {
|
|
164
|
+
tradingPartnerKey: `${senderId}:${receiverId}`,
|
|
165
|
+
counterName,
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
return String(data.value).padStart(maxDigits, '0');
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
return unwrapControlNumberError(error, true);
|
|
172
|
+
}
|
|
172
173
|
}
|
|
173
174
|
/**
|
|
174
175
|
* Set the last-used production control number through the legacy endpoint.
|
package/dist/index.d.ts
CHANGED
|
@@ -41,12 +41,7 @@ export declare class TemperEdiClient {
|
|
|
41
41
|
private unwrap;
|
|
42
42
|
private unwrapError;
|
|
43
43
|
fromX12({ input }: FromX12Options): Promise<X12Interchange[]>;
|
|
44
|
-
/**
|
|
45
|
-
* Stamp ISA13/GS06/ST02 control numbers on the interchange if not already set.
|
|
46
|
-
* Uses the centralized per-environment service for atomic partner sequencing.
|
|
47
|
-
* ST02 is always "0001" (one transaction per file per ticket).
|
|
48
|
-
* Zero-filled values from acknowledgment generation are placeholders, not manual overrides.
|
|
49
|
-
*/
|
|
44
|
+
/** Allocate every remote number before mutating the interchange. */
|
|
50
45
|
private stampControlNumbers;
|
|
51
46
|
toX12({ input }: ToX12Options): Promise<File>;
|
|
52
47
|
validateX12({ input }: ValidateX12Options): Promise<import("./edination-client").OperationResult>;
|
package/dist/index.js
CHANGED
|
@@ -150,30 +150,24 @@ class TemperEdiClient {
|
|
|
150
150
|
.catch((error) => this.unwrapError(error, 'edi_read_error'));
|
|
151
151
|
}, (o) => buildEdiX12Payload('fromX12', { input, output: o?.result }));
|
|
152
152
|
}
|
|
153
|
-
/**
|
|
154
|
-
* Stamp ISA13/GS06/ST02 control numbers on the interchange if not already set.
|
|
155
|
-
* Uses the centralized per-environment service for atomic partner sequencing.
|
|
156
|
-
* ST02 is always "0001" (one transaction per file per ticket).
|
|
157
|
-
* Zero-filled values from acknowledgment generation are placeholders, not manual overrides.
|
|
158
|
-
*/
|
|
153
|
+
/** Allocate every remote number before mutating the interchange. */
|
|
159
154
|
async stampControlNumbers(input) {
|
|
160
155
|
const isa = input.ISA;
|
|
161
|
-
const senderQual = (isa.SenderIDQualifier_5
|
|
162
|
-
const senderId = (isa.InterchangeSenderID_6
|
|
163
|
-
const receiverQual = (isa.ReceiverIDQualifier_7
|
|
164
|
-
const receiverId = (isa.InterchangeReceiverID_8
|
|
156
|
+
const senderQual = (isa.SenderIDQualifier_5 ?? '').trim();
|
|
157
|
+
const senderId = (isa.InterchangeSenderID_6 ?? '').trim();
|
|
158
|
+
const receiverQual = (isa.ReceiverIDQualifier_7 ?? '').trim();
|
|
159
|
+
const receiverId = (isa.InterchangeReceiverID_8 ?? '').trim();
|
|
165
160
|
const senderKey = `${senderQual}:${senderId}`;
|
|
166
161
|
const receiverKey = `${receiverQual}:${receiverId}`;
|
|
167
|
-
// Allocate before mutating so a failed request cannot leave partial stamps.
|
|
168
162
|
const isa13 = needsControlNumber(isa.InterchangeControlNumber_13)
|
|
169
163
|
? await (0, control_numbers_1.getNextControlNumber)('ISA13', senderKey, receiverKey, 9)
|
|
170
164
|
: null;
|
|
165
|
+
const groups = input.Groups;
|
|
171
166
|
const gs06Values = [];
|
|
172
|
-
const
|
|
173
|
-
|
|
174
|
-
if (needsControlNumber(groups[i].GS.GroupControlNumber_6)) {
|
|
167
|
+
for (const group of groups) {
|
|
168
|
+
if (needsControlNumber(group.GS.GroupControlNumber_6)) {
|
|
175
169
|
const value = await (0, control_numbers_1.getNextControlNumber)('GS06', senderKey, receiverKey, 9);
|
|
176
|
-
gs06Values.push({
|
|
170
|
+
gs06Values.push({ group, value });
|
|
177
171
|
}
|
|
178
172
|
}
|
|
179
173
|
if (isa13) {
|
|
@@ -182,8 +176,7 @@ class TemperEdiClient {
|
|
|
182
176
|
input.IEATrailers[0].InterchangeControlNumber_2 = isa13;
|
|
183
177
|
}
|
|
184
178
|
}
|
|
185
|
-
for (const {
|
|
186
|
-
const group = groups[index];
|
|
179
|
+
for (const { group, value } of gs06Values) {
|
|
187
180
|
group.GS.GroupControlNumber_6 = value;
|
|
188
181
|
if (group.GETrailers?.length) {
|
|
189
182
|
group.GETrailers[0].GroupControlNumber_2 = value;
|
|
@@ -201,14 +194,7 @@ class TemperEdiClient {
|
|
|
201
194
|
}
|
|
202
195
|
}
|
|
203
196
|
async toX12({ input }) {
|
|
204
|
-
|
|
205
|
-
try {
|
|
206
|
-
await this.stampControlNumbers(input);
|
|
207
|
-
}
|
|
208
|
-
catch (error) {
|
|
209
|
-
// Workflows can still serialize documents whose control numbers were set manually.
|
|
210
|
-
unnbound_logger_sdk_1.logger.warn({ err: error }, '[EDI SDK] Failed to auto-stamp control numbers, proceeding without');
|
|
211
|
-
}
|
|
197
|
+
await this.stampControlNumbers(input);
|
|
212
198
|
return (0, unnbound_logger_sdk_1.startSpan)('JSON to X12', () => {
|
|
213
199
|
return this.X12.x12WritePost({ x12Interchange: input })
|
|
214
200
|
.then(this.unwrap.bind(this))
|