@marteye/studiojs 1.1.40 → 1.1.42
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/dist/index.d.ts +132 -19
- package/dist/index.esm.js +247 -52
- package/dist/index.js +247 -51
- package/dist/resources/adjustments.d.ts +2 -2
- package/dist/resources/bidderApplications.d.ts +13 -0
- package/dist/resources/customers.d.ts +14 -2
- package/dist/resources/invoices.d.ts +2 -2
- package/dist/resources/ledger.d.ts +2 -1
- package/dist/resources/lots.d.ts +2 -2
- package/dist/resources/markets.d.ts +2 -2
- package/dist/resources/members.d.ts +34 -0
- package/dist/resources/productCodes.d.ts +2 -2
- package/dist/resources/sales.d.ts +2 -2
- package/dist/resources/settings.d.ts +2 -2
- package/dist/resources.d.ts +14 -8
- package/dist/studio.d.ts +14 -8
- package/dist/types.d.ts +20 -0
- package/dist/utils/cattlePassport.d.ts +49 -0
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -43,6 +43,9 @@ function SimpleHttpClient(baseUrl, apiKey, fetch, defaultTimeout, debug = false)
|
|
|
43
43
|
console.log(`[SimpleHttpClient] ${method} ${path} response: ${response.status}`);
|
|
44
44
|
}
|
|
45
45
|
if (response.ok) {
|
|
46
|
+
if (response.status === 204) {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
46
49
|
return response.json();
|
|
47
50
|
}
|
|
48
51
|
if (response.status === 404) {
|
|
@@ -70,7 +73,7 @@ function SimpleHttpClient(baseUrl, apiKey, fetch, defaultTimeout, debug = false)
|
|
|
70
73
|
}
|
|
71
74
|
|
|
72
75
|
// Path: studiojs/src/resources/markets.ts
|
|
73
|
-
function create$
|
|
76
|
+
function create$o(_) {
|
|
74
77
|
const actions = {
|
|
75
78
|
/***
|
|
76
79
|
* This is used to construct the action from the request body
|
|
@@ -100,7 +103,7 @@ function create$n(_) {
|
|
|
100
103
|
return actions;
|
|
101
104
|
}
|
|
102
105
|
|
|
103
|
-
function create$
|
|
106
|
+
function create$n(httpClient) {
|
|
104
107
|
let activity = {
|
|
105
108
|
/**
|
|
106
109
|
* List activity logs for a market with pagination and filtering
|
|
@@ -152,13 +155,13 @@ function create$m(httpClient) {
|
|
|
152
155
|
return activity;
|
|
153
156
|
}
|
|
154
157
|
|
|
155
|
-
function create$
|
|
158
|
+
function create$m(httpClient) {
|
|
156
159
|
return {
|
|
157
160
|
list: async (marketId) => {
|
|
158
161
|
return httpClient.get(`/${marketId}/adjustments`);
|
|
159
162
|
},
|
|
160
|
-
get: async (marketId, id) => {
|
|
161
|
-
return httpClient.get(`/${marketId}/adjustments/${id}
|
|
163
|
+
get: async (marketId, id, options) => {
|
|
164
|
+
return httpClient.get(`/${marketId}/adjustments/${id}`, (options === null || options === void 0 ? void 0 : options.at) ? { at: options.at } : undefined);
|
|
162
165
|
},
|
|
163
166
|
create: async (marketId, data) => {
|
|
164
167
|
return httpClient.post(`/${marketId}/adjustments`, data);
|
|
@@ -169,7 +172,7 @@ function create$l(httpClient) {
|
|
|
169
172
|
};
|
|
170
173
|
}
|
|
171
174
|
|
|
172
|
-
function create$
|
|
175
|
+
function create$l(httpClient) {
|
|
173
176
|
return {
|
|
174
177
|
/**
|
|
175
178
|
* Get the full cart for a customer including extras and uninvoiced lots
|
|
@@ -192,7 +195,7 @@ function create$k(httpClient) {
|
|
|
192
195
|
};
|
|
193
196
|
}
|
|
194
197
|
|
|
195
|
-
function create$
|
|
198
|
+
function create$k(httpClient) {
|
|
196
199
|
return {
|
|
197
200
|
list: async (marketId) => {
|
|
198
201
|
return httpClient.get(`/${marketId}/extras`);
|
|
@@ -212,7 +215,7 @@ function create$j(httpClient) {
|
|
|
212
215
|
/***
|
|
213
216
|
* Bidder applications
|
|
214
217
|
*/
|
|
215
|
-
function create$
|
|
218
|
+
function create$j(httpClient) {
|
|
216
219
|
let applications = {
|
|
217
220
|
/**
|
|
218
221
|
* List applications for a market with optional filtering
|
|
@@ -274,12 +277,29 @@ function create$i(httpClient) {
|
|
|
274
277
|
reject: async (marketId, applicationId, notes) => {
|
|
275
278
|
return httpClient.post(`/${marketId}/applications/${applicationId}/reject`, { notes });
|
|
276
279
|
},
|
|
280
|
+
/**
|
|
281
|
+
* Unlink an application from its customer/contact
|
|
282
|
+
* @param marketId - ID of the market
|
|
283
|
+
* @param applicationId - ID of the application to unlink
|
|
284
|
+
* @returns The unlinked application (reset to pending)
|
|
285
|
+
*/
|
|
286
|
+
unlink: async (marketId, applicationId) => {
|
|
287
|
+
return httpClient.post(`/${marketId}/applications/${applicationId}/unlink`, {});
|
|
288
|
+
},
|
|
289
|
+
/**
|
|
290
|
+
* Delete an application
|
|
291
|
+
* @param marketId - ID of the market
|
|
292
|
+
* @param applicationId - ID of the application to delete
|
|
293
|
+
*/
|
|
294
|
+
delete: async (marketId, applicationId) => {
|
|
295
|
+
return httpClient.delete(`/${marketId}/applications/${applicationId}`);
|
|
296
|
+
},
|
|
277
297
|
};
|
|
278
298
|
return applications;
|
|
279
299
|
}
|
|
280
300
|
|
|
281
301
|
// Path: studiojs/src/resources/markets.ts
|
|
282
|
-
function create$
|
|
302
|
+
function create$i(httpClient) {
|
|
283
303
|
let customers = {
|
|
284
304
|
list: async (marketId, lastId) => {
|
|
285
305
|
let params = {};
|
|
@@ -288,8 +308,8 @@ function create$h(httpClient) {
|
|
|
288
308
|
}
|
|
289
309
|
return httpClient.get(`/${marketId}/customers`, params);
|
|
290
310
|
},
|
|
291
|
-
get: async (marketId, customerId) => {
|
|
292
|
-
return httpClient.get(`/${marketId}/customers/${customerId}
|
|
311
|
+
get: async (marketId, customerId, options) => {
|
|
312
|
+
return httpClient.get(`/${marketId}/customers/${customerId}`, (options === null || options === void 0 ? void 0 : options.at) ? { at: options.at } : undefined);
|
|
293
313
|
},
|
|
294
314
|
avatar: async (marketId, customerId) => {
|
|
295
315
|
return httpClient.get(`/${marketId}/customers/${customerId}/avatar`);
|
|
@@ -5116,7 +5136,7 @@ const uploadSingleFile = async (input, token) => {
|
|
|
5116
5136
|
};
|
|
5117
5137
|
|
|
5118
5138
|
// Multipart Upload for Media to the MARTEYE Media Service
|
|
5119
|
-
function create$
|
|
5139
|
+
function create$h() {
|
|
5120
5140
|
const files = {
|
|
5121
5141
|
uploadSingleFile: async (input, token) => {
|
|
5122
5142
|
return await uploadSingleFile(input, token);
|
|
@@ -5131,7 +5151,7 @@ function create$g() {
|
|
|
5131
5151
|
return files;
|
|
5132
5152
|
}
|
|
5133
5153
|
|
|
5134
|
-
function create$
|
|
5154
|
+
function create$g(httpClient) {
|
|
5135
5155
|
const invoices = {
|
|
5136
5156
|
/**
|
|
5137
5157
|
* List all invoices for a market with pagination
|
|
@@ -5152,14 +5172,14 @@ function create$f(httpClient) {
|
|
|
5152
5172
|
* @param invoiceId - ID of the invoice to fetch
|
|
5153
5173
|
* @returns The invoice details
|
|
5154
5174
|
*/
|
|
5155
|
-
get: async (marketId, invoiceId) => {
|
|
5156
|
-
return httpClient.get(`/${marketId}/invoices/${invoiceId}
|
|
5175
|
+
get: async (marketId, invoiceId, options) => {
|
|
5176
|
+
return httpClient.get(`/${marketId}/invoices/${invoiceId}`, (options === null || options === void 0 ? void 0 : options.at) ? { at: options.at } : undefined);
|
|
5157
5177
|
},
|
|
5158
5178
|
};
|
|
5159
5179
|
return invoices;
|
|
5160
5180
|
}
|
|
5161
5181
|
|
|
5162
|
-
function create$
|
|
5182
|
+
function create$f(httpClient) {
|
|
5163
5183
|
return {
|
|
5164
5184
|
create: async (marketId, saleId, lotId, data) => {
|
|
5165
5185
|
return httpClient.post(`/${marketId}/sales/${saleId}/lots/${lotId}/items`, data);
|
|
@@ -5176,10 +5196,10 @@ function create$e(httpClient) {
|
|
|
5176
5196
|
/**
|
|
5177
5197
|
* Defines the possible status values for a lot in a sale
|
|
5178
5198
|
*/
|
|
5179
|
-
function create$
|
|
5199
|
+
function create$e(httpClient) {
|
|
5180
5200
|
return {
|
|
5181
|
-
get: async (marketId, saleId, lotId) => {
|
|
5182
|
-
return httpClient.get(`/${marketId}/sales/${saleId}/lots/${lotId}
|
|
5201
|
+
get: async (marketId, saleId, lotId, options) => {
|
|
5202
|
+
return httpClient.get(`/${marketId}/sales/${saleId}/lots/${lotId}`, (options === null || options === void 0 ? void 0 : options.at) ? { at: options.at } : undefined);
|
|
5183
5203
|
},
|
|
5184
5204
|
list: async (marketId, saleId, filters) => {
|
|
5185
5205
|
return httpClient.get(`/${marketId}/sales/${saleId}/lots`, filters);
|
|
@@ -5196,10 +5216,10 @@ function create$d(httpClient) {
|
|
|
5196
5216
|
};
|
|
5197
5217
|
}
|
|
5198
5218
|
|
|
5199
|
-
function create$
|
|
5219
|
+
function create$d(httpClient) {
|
|
5200
5220
|
const markets = {
|
|
5201
|
-
get: async (marketId) => {
|
|
5202
|
-
return httpClient.get(`/${marketId}
|
|
5221
|
+
get: async (marketId, options) => {
|
|
5222
|
+
return httpClient.get(`/${marketId}`, (options === null || options === void 0 ? void 0 : options.at) ? { at: options.at } : undefined);
|
|
5203
5223
|
},
|
|
5204
5224
|
// update: async (marketId: string, market: Partial<Market>) => {
|
|
5205
5225
|
// // return httpClient.put<Market>(`/${marketId}`, market);
|
|
@@ -5218,6 +5238,37 @@ function create$c(httpClient) {
|
|
|
5218
5238
|
return markets;
|
|
5219
5239
|
}
|
|
5220
5240
|
|
|
5241
|
+
function create$c(httpClient) {
|
|
5242
|
+
let members = {
|
|
5243
|
+
/**
|
|
5244
|
+
* List members (staff accounts) for a market with pagination
|
|
5245
|
+
* @param marketId - ID of the market
|
|
5246
|
+
* @param params - Optional pagination parameters
|
|
5247
|
+
* @returns Paginated list of members
|
|
5248
|
+
*/
|
|
5249
|
+
list: async (marketId, params) => {
|
|
5250
|
+
let queryParams = {};
|
|
5251
|
+
if ((params === null || params === void 0 ? void 0 : params.limit) !== undefined) {
|
|
5252
|
+
queryParams.limit = String(params.limit);
|
|
5253
|
+
}
|
|
5254
|
+
if (params === null || params === void 0 ? void 0 : params.lastId) {
|
|
5255
|
+
queryParams.lastId = params.lastId;
|
|
5256
|
+
}
|
|
5257
|
+
return httpClient.get(`/${marketId}/members`, queryParams);
|
|
5258
|
+
},
|
|
5259
|
+
/**
|
|
5260
|
+
* Get a specific member by ID
|
|
5261
|
+
* @param marketId - ID of the market
|
|
5262
|
+
* @param memberId - User ID of the member
|
|
5263
|
+
* @returns The member details
|
|
5264
|
+
*/
|
|
5265
|
+
get: async (marketId, memberId) => {
|
|
5266
|
+
return httpClient.get(`/${marketId}/members/${memberId}`);
|
|
5267
|
+
},
|
|
5268
|
+
};
|
|
5269
|
+
return members;
|
|
5270
|
+
}
|
|
5271
|
+
|
|
5221
5272
|
function create$b(httpClient) {
|
|
5222
5273
|
const payments = {
|
|
5223
5274
|
/**
|
|
@@ -5290,8 +5341,8 @@ function create$9(httpClient) {
|
|
|
5290
5341
|
list: async (marketId) => {
|
|
5291
5342
|
return httpClient.get(`/${marketId}/product-codes`);
|
|
5292
5343
|
},
|
|
5293
|
-
get: async (marketId, id) => {
|
|
5294
|
-
return httpClient.get(`/${marketId}/product-codes/${id}
|
|
5344
|
+
get: async (marketId, id, options) => {
|
|
5345
|
+
return httpClient.get(`/${marketId}/product-codes/${id}`, (options === null || options === void 0 ? void 0 : options.at) ? { at: options.at } : undefined);
|
|
5295
5346
|
},
|
|
5296
5347
|
create: async (marketId, data) => {
|
|
5297
5348
|
return httpClient.post(`/${marketId}/product-codes`, data);
|
|
@@ -5304,8 +5355,8 @@ function create$9(httpClient) {
|
|
|
5304
5355
|
|
|
5305
5356
|
function create$8(httpClient) {
|
|
5306
5357
|
return {
|
|
5307
|
-
get: async (marketId, saleId) => {
|
|
5308
|
-
return httpClient.get(`/${marketId}/sales/${saleId}
|
|
5358
|
+
get: async (marketId, saleId, options) => {
|
|
5359
|
+
return httpClient.get(`/${marketId}/sales/${saleId}`, (options === null || options === void 0 ? void 0 : options.at) ? { at: options.at } : undefined);
|
|
5309
5360
|
},
|
|
5310
5361
|
list: async (marketId, opts) => {
|
|
5311
5362
|
return httpClient.get(`/${marketId}/sales`, opts);
|
|
@@ -5356,8 +5407,8 @@ function create$6(httpClient) {
|
|
|
5356
5407
|
|
|
5357
5408
|
function create$5(httpClient) {
|
|
5358
5409
|
return {
|
|
5359
|
-
get: async (marketId) => {
|
|
5360
|
-
return httpClient.get(`/${marketId}/settings
|
|
5410
|
+
get: async (marketId, options) => {
|
|
5411
|
+
return httpClient.get(`/${marketId}/settings`, (options === null || options === void 0 ? void 0 : options.at) ? { at: options.at } : undefined);
|
|
5361
5412
|
},
|
|
5362
5413
|
};
|
|
5363
5414
|
}
|
|
@@ -5482,13 +5533,19 @@ function create(httpClient) {
|
|
|
5482
5533
|
* @returns List of transactions with pagination info
|
|
5483
5534
|
*/
|
|
5484
5535
|
listTransactions: async (marketId, params) => {
|
|
5485
|
-
let queryParams = {
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
|
|
5489
|
-
|
|
5490
|
-
|
|
5491
|
-
|
|
5536
|
+
let queryParams = {};
|
|
5537
|
+
if (params.account)
|
|
5538
|
+
queryParams.account = params.account;
|
|
5539
|
+
if (params.referenceGroupKey)
|
|
5540
|
+
queryParams.referenceGroupKey = params.referenceGroupKey;
|
|
5541
|
+
if (params.dateFrom)
|
|
5542
|
+
queryParams.dateFrom = params.dateFrom;
|
|
5543
|
+
if (params.dateTo)
|
|
5544
|
+
queryParams.dateTo = params.dateTo;
|
|
5545
|
+
if (params.limit)
|
|
5546
|
+
queryParams.limit = params.limit;
|
|
5547
|
+
if (params.cursor)
|
|
5548
|
+
queryParams.cursor = params.cursor;
|
|
5492
5549
|
return httpClient.get(`/${marketId}/ledger/transactions`, queryParams);
|
|
5493
5550
|
},
|
|
5494
5551
|
};
|
|
@@ -5497,28 +5554,29 @@ function create(httpClient) {
|
|
|
5497
5554
|
|
|
5498
5555
|
function resources(httpClient) {
|
|
5499
5556
|
return {
|
|
5500
|
-
activity: create$
|
|
5501
|
-
markets: create$
|
|
5557
|
+
activity: create$n(httpClient),
|
|
5558
|
+
markets: create$d(httpClient),
|
|
5559
|
+
members: create$c(httpClient),
|
|
5502
5560
|
sales: create$8(httpClient),
|
|
5503
|
-
lots: create$
|
|
5504
|
-
lotitems: create$
|
|
5505
|
-
carts: create$
|
|
5561
|
+
lots: create$e(httpClient),
|
|
5562
|
+
lotitems: create$f(httpClient),
|
|
5563
|
+
carts: create$l(httpClient),
|
|
5506
5564
|
cph: create$2(httpClient),
|
|
5507
5565
|
webhooks: create$3(),
|
|
5508
|
-
actions: create$
|
|
5509
|
-
bidderApplications: create$
|
|
5566
|
+
actions: create$o(),
|
|
5567
|
+
bidderApplications: create$j(httpClient),
|
|
5510
5568
|
settings: create$5(httpClient),
|
|
5511
|
-
adjustments: create$
|
|
5512
|
-
extras: create$
|
|
5569
|
+
adjustments: create$m(httpClient),
|
|
5570
|
+
extras: create$k(httpClient),
|
|
5513
5571
|
productCodes: create$9(httpClient),
|
|
5514
5572
|
saleTemplates: create$7(httpClient),
|
|
5515
5573
|
taxRates: create$4(httpClient),
|
|
5516
|
-
customers: create$
|
|
5517
|
-
invoices: create$
|
|
5574
|
+
customers: create$i(httpClient),
|
|
5575
|
+
invoices: create$g(httpClient),
|
|
5518
5576
|
payments: create$b(httpClient),
|
|
5519
5577
|
payouts: create$a(httpClient),
|
|
5520
5578
|
search: create$6(httpClient),
|
|
5521
|
-
files: create$
|
|
5579
|
+
files: create$h(),
|
|
5522
5580
|
contacts: create$1(httpClient),
|
|
5523
5581
|
ledger: create(httpClient),
|
|
5524
5582
|
};
|
|
@@ -5756,6 +5814,15 @@ class EarTag {
|
|
|
5756
5814
|
parsedCountryCode = match11[1];
|
|
5757
5815
|
parsedNationalIdentifier = `${match11[3]}${match11[4]}`;
|
|
5758
5816
|
}
|
|
5817
|
+
else {
|
|
5818
|
+
// 10-digit national ID (e.g. DE, FR imported tags)
|
|
5819
|
+
const regex10 = new RegExp(`^[0-9]{0,7}(${countryPattern})([0-9]{5})([0-9]{5})`);
|
|
5820
|
+
let match10 = regex10.exec(workingInput);
|
|
5821
|
+
if (match10) {
|
|
5822
|
+
parsedCountryCode = match10[1];
|
|
5823
|
+
parsedNationalIdentifier = `${match10[3]}${match10[4]}`;
|
|
5824
|
+
}
|
|
5825
|
+
}
|
|
5759
5826
|
}
|
|
5760
5827
|
// Part 2: If no country code parsed yet, try fallback
|
|
5761
5828
|
if (!parsedCountryCode && fallbackCountryCode) {
|
|
@@ -5763,7 +5830,7 @@ class EarTag {
|
|
|
5763
5830
|
if (numericFallback) {
|
|
5764
5831
|
// `workingInput` at this point is the original input (cleaned, no recognized country code)
|
|
5765
5832
|
// Assume `workingInput` is the national identifier part (must be 11 or 12 digits)
|
|
5766
|
-
if (workingInput.length
|
|
5833
|
+
if (workingInput.length >= 10 && workingInput.length <= 12) {
|
|
5767
5834
|
parsedCountryCode = numericFallback;
|
|
5768
5835
|
parsedNationalIdentifier = workingInput;
|
|
5769
5836
|
// Update _raw to reflect the tag as if it had the country code
|
|
@@ -5774,7 +5841,11 @@ class EarTag {
|
|
|
5774
5841
|
// Part 3: Finalize and set properties
|
|
5775
5842
|
if (parsedCountryCode && parsedNationalIdentifier) {
|
|
5776
5843
|
this._isoCountryCode = parsedCountryCode;
|
|
5777
|
-
if (parsedNationalIdentifier.length ===
|
|
5844
|
+
if (parsedNationalIdentifier.length === 10) {
|
|
5845
|
+
// 10-digit national ID (e.g. DE, FR imported tags) — store as-is
|
|
5846
|
+
this._nationalIdentifier = parsedNationalIdentifier;
|
|
5847
|
+
}
|
|
5848
|
+
else if (parsedNationalIdentifier.length === 11) {
|
|
5778
5849
|
// Pad 11-digit national ID to 12-digits by prepending "0"
|
|
5779
5850
|
this._nationalIdentifier = "0" + parsedNationalIdentifier;
|
|
5780
5851
|
}
|
|
@@ -5782,7 +5853,6 @@ class EarTag {
|
|
|
5782
5853
|
this._nationalIdentifier = parsedNationalIdentifier;
|
|
5783
5854
|
}
|
|
5784
5855
|
else {
|
|
5785
|
-
// This case should ideally not be reached if lengths are checked properly before.
|
|
5786
5856
|
this._isEartag = false;
|
|
5787
5857
|
return;
|
|
5788
5858
|
}
|
|
@@ -5806,7 +5876,14 @@ class EarTag {
|
|
|
5806
5876
|
if (!this._isEartag) {
|
|
5807
5877
|
return "Invalid EarTag";
|
|
5808
5878
|
}
|
|
5809
|
-
|
|
5879
|
+
let country = EarTag.countryCodesByNumber[this.isoCountryCode];
|
|
5880
|
+
let id = this.nationalIdentifier;
|
|
5881
|
+
// 10-digit national IDs (DE, FR imports) format as 5+5
|
|
5882
|
+
// 12-digit national IDs (UK, IE, etc.) format as 7+5
|
|
5883
|
+
if (id.length === 10) {
|
|
5884
|
+
return `${country} ${id.slice(0, 5)} ${id.slice(5)}`;
|
|
5885
|
+
}
|
|
5886
|
+
return `${country} ${id.slice(0, 7)} ${id.slice(7)}`;
|
|
5810
5887
|
}
|
|
5811
5888
|
isISO24631() {
|
|
5812
5889
|
return EarTag.regexISO24631.test(this._raw);
|
|
@@ -5831,6 +5908,124 @@ EarTag.countryCodes = {
|
|
|
5831
5908
|
BE: "056",
|
|
5832
5909
|
};
|
|
5833
5910
|
|
|
5911
|
+
/**
|
|
5912
|
+
* Parses the bottom barcode on a UK cattle passport.
|
|
5913
|
+
*
|
|
5914
|
+
* The barcode is a 30-character fixed-width positional format:
|
|
5915
|
+
* [0-13] Eartag — 2 alpha country code + 12 char national ID (space-padded for shorter foreign tags)
|
|
5916
|
+
* [14-21] Date of birth — ddMMyyyy
|
|
5917
|
+
* [22] Sex — F or M
|
|
5918
|
+
* [23-27] Breed code — left-justified, space-padded to 5 chars
|
|
5919
|
+
* [28-29] Passport version — 2 digits
|
|
5920
|
+
*
|
|
5921
|
+
* UK animals fill all 12 digits of the national ID. Imported animals (DE, FR, BE, etc.)
|
|
5922
|
+
* have shorter national IDs so the field is right-padded with spaces.
|
|
5923
|
+
*
|
|
5924
|
+
* Examples:
|
|
5925
|
+
* UK12345671004215032023MHER 01 ← UK tag, breed HER
|
|
5926
|
+
* UK98765430018722112022FLIMX 01 ← UK tag, breed LIMX
|
|
5927
|
+
* DE04821 9315614092018FHF 01 ← German import, 10-digit national ID
|
|
5928
|
+
* FR72341 6850203052020FHF 01 ← French import, 10-digit national ID
|
|
5929
|
+
*/
|
|
5930
|
+
class CattlePassport {
|
|
5931
|
+
constructor(raw, earTag, dateOfBirth, sex, breed, passportVersion) {
|
|
5932
|
+
this._raw = raw;
|
|
5933
|
+
this._earTag = earTag;
|
|
5934
|
+
this._dateOfBirth = dateOfBirth;
|
|
5935
|
+
this._sex = sex;
|
|
5936
|
+
this._breed = breed;
|
|
5937
|
+
this._passportVersion = passportVersion;
|
|
5938
|
+
}
|
|
5939
|
+
static parse(code) {
|
|
5940
|
+
let raw = code;
|
|
5941
|
+
let trimmed = code.trim();
|
|
5942
|
+
if (trimmed.length !== CattlePassport.BARCODE_LENGTH)
|
|
5943
|
+
return null;
|
|
5944
|
+
// Extract fixed-width fields
|
|
5945
|
+
let earTagField = trimmed.slice(0, 14);
|
|
5946
|
+
let dobField = trimmed.slice(14, 22);
|
|
5947
|
+
let sexChar = trimmed.charAt(22);
|
|
5948
|
+
let breedField = trimmed.slice(23, 28);
|
|
5949
|
+
let versionField = trimmed.slice(28, 30);
|
|
5950
|
+
// Country code: 2 alpha chars
|
|
5951
|
+
let countryCode = earTagField.slice(0, 2);
|
|
5952
|
+
if (!/^[A-Z]{2}$/.test(countryCode))
|
|
5953
|
+
return null;
|
|
5954
|
+
// National ID: strip spaces (padding for shorter foreign tags)
|
|
5955
|
+
let nationalId = earTagField.slice(2).replace(/\s/g, "");
|
|
5956
|
+
if (!/^\d+$/.test(nationalId) || nationalId.length === 0)
|
|
5957
|
+
return null;
|
|
5958
|
+
let earTag = countryCode + nationalId;
|
|
5959
|
+
// DOB: ddMMyyyy
|
|
5960
|
+
if (!/^\d{8}$/.test(dobField))
|
|
5961
|
+
return null;
|
|
5962
|
+
let day = dobField.slice(0, 2);
|
|
5963
|
+
let month = dobField.slice(2, 4);
|
|
5964
|
+
let year = dobField.slice(4, 8);
|
|
5965
|
+
let d = new Date(`${year}-${month}-${day}T00:00:00Z`);
|
|
5966
|
+
if (isNaN(d.getTime()))
|
|
5967
|
+
return null;
|
|
5968
|
+
// Sex
|
|
5969
|
+
if (sexChar !== "F" && sexChar !== "M")
|
|
5970
|
+
return null;
|
|
5971
|
+
let sex = sexChar === "M" ? "Male" : "Female";
|
|
5972
|
+
// Breed: trimmed, alpha only
|
|
5973
|
+
let breed = breedField.trim();
|
|
5974
|
+
if (!breed || !/^[A-Z]+$/.test(breed))
|
|
5975
|
+
return null;
|
|
5976
|
+
// Passport version
|
|
5977
|
+
if (!/^\d{2}$/.test(versionField))
|
|
5978
|
+
return null;
|
|
5979
|
+
let passportVersion = parseInt(versionField);
|
|
5980
|
+
return new CattlePassport(raw, earTag, d, sex, breed, passportVersion);
|
|
5981
|
+
}
|
|
5982
|
+
/** The original raw barcode string */
|
|
5983
|
+
get raw() {
|
|
5984
|
+
return this._raw;
|
|
5985
|
+
}
|
|
5986
|
+
/** The eartag extracted from the barcode, e.g. "UK705946601313" or "DE0359581730" */
|
|
5987
|
+
get earTag() {
|
|
5988
|
+
return this._earTag;
|
|
5989
|
+
}
|
|
5990
|
+
/** Date of birth (UTC) */
|
|
5991
|
+
get dateOfBirth() {
|
|
5992
|
+
return this._dateOfBirth;
|
|
5993
|
+
}
|
|
5994
|
+
/** Male or Female */
|
|
5995
|
+
get sex() {
|
|
5996
|
+
return this._sex;
|
|
5997
|
+
}
|
|
5998
|
+
/** Breed code, e.g. "AA", "HF", "LIMX" */
|
|
5999
|
+
get breed() {
|
|
6000
|
+
return this._breed;
|
|
6001
|
+
}
|
|
6002
|
+
/** Passport version number */
|
|
6003
|
+
get passportVersion() {
|
|
6004
|
+
return this._passportVersion;
|
|
6005
|
+
}
|
|
6006
|
+
/** 2-letter country code, e.g. "UK", "DE", "FR" */
|
|
6007
|
+
get countryCode() {
|
|
6008
|
+
return this._earTag.slice(0, 2);
|
|
6009
|
+
}
|
|
6010
|
+
/** Format the eartag via the EarTag class. Falls back to the raw tag string. */
|
|
6011
|
+
get formattedEarTag() {
|
|
6012
|
+
let formatted = EarTag.format(this._earTag);
|
|
6013
|
+
return formatted !== null && formatted !== void 0 ? formatted : this._earTag;
|
|
6014
|
+
}
|
|
6015
|
+
/** Date of birth as DD/MM/YYYY */
|
|
6016
|
+
get formattedDateOfBirth() {
|
|
6017
|
+
let d = this._dateOfBirth;
|
|
6018
|
+
let day = String(d.getUTCDate()).padStart(2, "0");
|
|
6019
|
+
let month = String(d.getUTCMonth() + 1).padStart(2, "0");
|
|
6020
|
+
let year = d.getUTCFullYear();
|
|
6021
|
+
return `${day}/${month}/${year}`;
|
|
6022
|
+
}
|
|
6023
|
+
toString() {
|
|
6024
|
+
return `${this.formattedEarTag} | ${this.formattedDateOfBirth} | ${this._sex} | ${this._breed} | v${this._passportVersion}`;
|
|
6025
|
+
}
|
|
6026
|
+
}
|
|
6027
|
+
CattlePassport.BARCODE_LENGTH = 30;
|
|
6028
|
+
|
|
5834
6029
|
/**
|
|
5835
6030
|
* Extract the smallest lot number for sorting purposes.
|
|
5836
6031
|
* Handles formats:
|
|
@@ -5992,4 +6187,4 @@ function incrementAlphaSequence(alpha) {
|
|
|
5992
6187
|
return chars.join("");
|
|
5993
6188
|
}
|
|
5994
6189
|
|
|
5995
|
-
export { EarTag, Studio, StudioHeaders, types as StudioTypes, createAppManifest, Studio as default, lotComparator, nextLotNumber, sortByLotNumber };
|
|
6190
|
+
export { CattlePassport, EarTag, Studio, StudioHeaders, types as StudioTypes, createAppManifest, Studio as default, lotComparator, nextLotNumber, sortByLotNumber };
|