@marteye/studiojs 1.1.23 → 1.1.25
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 +174 -109
- package/dist/index.esm.js +310 -6
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +313 -5
- package/dist/index.js.map +1 -1
- package/dist/resources/files.d.ts +6 -2
- package/dist/resources/lots.d.ts +1 -0
- package/dist/resources.d.ts +6 -1
- package/dist/studio.d.ts +6 -1
- package/dist/types.d.ts +6 -0
- package/dist/utils/eartag.d.ts +4 -3
- package/dist/utils/lots.d.ts +10 -0
- package/dist/utils/multipart-upload.d.ts +23 -3
- package/package.json +2 -1
package/dist/index.js
CHANGED
|
@@ -4558,7 +4558,12 @@ z.object({
|
|
|
4558
4558
|
suffix: z.string().min(1, { message: "Suffix Type is required" }),
|
|
4559
4559
|
});
|
|
4560
4560
|
// Adding Sizes here will make more end points in the mainConfig object
|
|
4561
|
-
const IMAGE_SIZES_VALUES$1 = [
|
|
4561
|
+
const IMAGE_SIZES_VALUES$1 = [
|
|
4562
|
+
"thumbnail",
|
|
4563
|
+
"small",
|
|
4564
|
+
"medium",
|
|
4565
|
+
"large",
|
|
4566
|
+
];
|
|
4562
4567
|
const VIDEO_TASKS_VALUES$1 = ["compressed", "thumbnail"];
|
|
4563
4568
|
z.enum(VIDEO_TASKS_VALUES$1);
|
|
4564
4569
|
z.enum(IMAGE_SIZES_VALUES$1);
|
|
@@ -4568,12 +4573,29 @@ const UPLOAD_PATHS = {
|
|
|
4568
4573
|
FINISH_UPLOAD: "finishMultipartUpload",
|
|
4569
4574
|
CANCEL_UPLOAD: "cancelUpload",
|
|
4570
4575
|
DELETE_UPLOAD: "deleteUpload",
|
|
4576
|
+
UPLOAD_SINGLE_FILE: "upload",
|
|
4571
4577
|
};
|
|
4572
4578
|
/**
|
|
4573
4579
|
|--------------------------------------------------
|
|
4574
4580
|
| Helper Functions
|
|
4575
4581
|
|--------------------------------------------------
|
|
4576
4582
|
*/
|
|
4583
|
+
const MIME_TYPE_MAP = {
|
|
4584
|
+
png: "image/png",
|
|
4585
|
+
jpg: "image/jpeg",
|
|
4586
|
+
jpeg: "image/jpeg",
|
|
4587
|
+
mp4: "video/mp4",
|
|
4588
|
+
mov: "video/quicktime",
|
|
4589
|
+
qt: "video/quicktime",
|
|
4590
|
+
};
|
|
4591
|
+
/**
|
|
4592
|
+
|--------------------------------------------------
|
|
4593
|
+
| Make a File Path
|
|
4594
|
+
|--------------------------------------------------
|
|
4595
|
+
*/
|
|
4596
|
+
function createFilePath(marketId, saleId, lotId, attributeId, fileName) {
|
|
4597
|
+
return `/${marketId}/${saleId}/${lotId}/${attributeId}/${fileName}`;
|
|
4598
|
+
}
|
|
4577
4599
|
const getHeaders = (mimeType, bucket = "raw", token) => {
|
|
4578
4600
|
const headers = new Headers();
|
|
4579
4601
|
headers.append("mbtype", bucket);
|
|
@@ -4595,7 +4617,7 @@ const startUpload = async ({ fileName, fileMimeType, fileExtension, token, optio
|
|
|
4595
4617
|
var _a;
|
|
4596
4618
|
const headers = getHeaders(fileMimeType, (_a = options.options) === null || _a === void 0 ? void 0 : _a.bucket, token);
|
|
4597
4619
|
const formData = new FormData();
|
|
4598
|
-
const filePath =
|
|
4620
|
+
const filePath = createFilePath(options.marketId, options.saleId, options.lotId, options.attributeId, `${fileName}.${fileExtension}`);
|
|
4599
4621
|
formData.append("filePath", filePath);
|
|
4600
4622
|
headers.append("Authorization", `Bearer ${token}`);
|
|
4601
4623
|
let uploadIdResponse = await fetch(new URL(`${BASE_CF_URL}/${UPLOAD_PATHS.START_UPLOAD}`), {
|
|
@@ -4762,7 +4784,7 @@ const deleteUpload = async (fileUrl, token) => {
|
|
|
4762
4784
|
* @returns {Promise<MediaFinishUploadResponse>}
|
|
4763
4785
|
* @throws {Error} When upload fails
|
|
4764
4786
|
*/
|
|
4765
|
-
const
|
|
4787
|
+
const uploadMultipartFile = async (input, token) => {
|
|
4766
4788
|
var _a, _b, _c, _d, _e;
|
|
4767
4789
|
let uploadId = "";
|
|
4768
4790
|
let filePath = "";
|
|
@@ -4866,12 +4888,61 @@ const uploadFile = async (input, token) => {
|
|
|
4866
4888
|
throw new Error("Upload failed and canceled " + error);
|
|
4867
4889
|
}
|
|
4868
4890
|
};
|
|
4891
|
+
const uploadSingleFile = async (input, token) => {
|
|
4892
|
+
const { file, filePath, uploadConfig } = input;
|
|
4893
|
+
let fileMimeType = "";
|
|
4894
|
+
let destinationPath = "";
|
|
4895
|
+
let fileName = "";
|
|
4896
|
+
let fileExtension = "";
|
|
4897
|
+
if (!filePath && !file) {
|
|
4898
|
+
throw new Error("Either filePath or file must be provided");
|
|
4899
|
+
}
|
|
4900
|
+
if (filePath && file) {
|
|
4901
|
+
throw new Error("Only one of filePath or file can be provided");
|
|
4902
|
+
}
|
|
4903
|
+
// We perform a copy form one file to another
|
|
4904
|
+
if (filePath) {
|
|
4905
|
+
fileName = filePath.split("/").pop() || "";
|
|
4906
|
+
fileExtension = fileName.split(".").pop() || "";
|
|
4907
|
+
fileMimeType = MIME_TYPE_MAP[fileExtension] || "";
|
|
4908
|
+
destinationPath = createFilePath(uploadConfig.marketId, uploadConfig.saleId, uploadConfig.lotId, uploadConfig.attributeId, `${fileName}`);
|
|
4909
|
+
}
|
|
4910
|
+
// We upload a single File
|
|
4911
|
+
if (file) {
|
|
4912
|
+
fileName = file.name.replace(/\.[^/.]+$/, "");
|
|
4913
|
+
fileExtension = file.name.split(".").pop() || "";
|
|
4914
|
+
fileMimeType = file.type;
|
|
4915
|
+
destinationPath = createFilePath(uploadConfig.marketId, uploadConfig.saleId, uploadConfig.lotId, uploadConfig.attributeId, `${fileName}.${fileExtension}`);
|
|
4916
|
+
}
|
|
4917
|
+
// Construct the Fetch Request
|
|
4918
|
+
const uploadUrl = new URL(`${BASE_CF_URL}/${UPLOAD_PATHS.UPLOAD_SINGLE_FILE}`);
|
|
4919
|
+
const headers = new Headers();
|
|
4920
|
+
headers.append("mbtype", "raw");
|
|
4921
|
+
headers.append("Authorization", `Bearer ${token}`);
|
|
4922
|
+
headers.append("mmimetype", fileMimeType);
|
|
4923
|
+
const formData = new FormData();
|
|
4924
|
+
filePath && formData.append("existingFilePath", filePath);
|
|
4925
|
+
destinationPath && formData.append("filePath", destinationPath);
|
|
4926
|
+
file && formData.append("file", file);
|
|
4927
|
+
const uploadResponse = await fetch(uploadUrl, {
|
|
4928
|
+
headers: headers,
|
|
4929
|
+
method: "POST",
|
|
4930
|
+
body: formData,
|
|
4931
|
+
});
|
|
4932
|
+
if (!uploadResponse.ok) {
|
|
4933
|
+
throw new Error("Failed to upload single file");
|
|
4934
|
+
}
|
|
4935
|
+
return (await uploadResponse.json());
|
|
4936
|
+
};
|
|
4869
4937
|
|
|
4870
4938
|
// Multipart Upload for Media to the MARTEYE Media Service
|
|
4871
4939
|
function create$9() {
|
|
4872
4940
|
const files = {
|
|
4873
|
-
|
|
4874
|
-
return await
|
|
4941
|
+
uploadSingleFile: async (input, token) => {
|
|
4942
|
+
return await uploadSingleFile(input, token);
|
|
4943
|
+
},
|
|
4944
|
+
uploadMultipartFile: async (input, token) => {
|
|
4945
|
+
return await uploadMultipartFile(input, token);
|
|
4875
4946
|
},
|
|
4876
4947
|
deleteFile: async (fileUrl, token) => {
|
|
4877
4948
|
return await deleteUpload(fileUrl, token);
|
|
@@ -5216,9 +5287,246 @@ function createAppManifest(appConfig) {
|
|
|
5216
5287
|
};
|
|
5217
5288
|
}
|
|
5218
5289
|
|
|
5290
|
+
class EarTag {
|
|
5291
|
+
static get countryCodesByNumber() {
|
|
5292
|
+
let reversed = {};
|
|
5293
|
+
for (const key of Object.keys(EarTag.countryCodes)) {
|
|
5294
|
+
reversed[EarTag.countryCodes[key]] = key;
|
|
5295
|
+
}
|
|
5296
|
+
return reversed;
|
|
5297
|
+
}
|
|
5298
|
+
normalisedCountryCode(countryCode) {
|
|
5299
|
+
if (!countryCode || typeof countryCode !== "string") {
|
|
5300
|
+
return null;
|
|
5301
|
+
}
|
|
5302
|
+
switch (countryCode) {
|
|
5303
|
+
case "GB-ENG":
|
|
5304
|
+
case "GB-SCT":
|
|
5305
|
+
case "GB-WLS":
|
|
5306
|
+
return "UK";
|
|
5307
|
+
case "GB-NIR":
|
|
5308
|
+
return "XI";
|
|
5309
|
+
default:
|
|
5310
|
+
return countryCode;
|
|
5311
|
+
}
|
|
5312
|
+
}
|
|
5313
|
+
get raw() {
|
|
5314
|
+
return this._raw;
|
|
5315
|
+
}
|
|
5316
|
+
isEartag() {
|
|
5317
|
+
return this._isEartag;
|
|
5318
|
+
}
|
|
5319
|
+
get isoCountryCode() {
|
|
5320
|
+
return this._isoCountryCode;
|
|
5321
|
+
}
|
|
5322
|
+
get nationalIdentifier() {
|
|
5323
|
+
return this._nationalIdentifier;
|
|
5324
|
+
}
|
|
5325
|
+
// private constructor
|
|
5326
|
+
constructor(input, fallbackCountryCode) {
|
|
5327
|
+
// readonly properties
|
|
5328
|
+
this._isEartag = false;
|
|
5329
|
+
fallbackCountryCode = this.normalisedCountryCode(fallbackCountryCode);
|
|
5330
|
+
let workingInput = input.replace(/\s/g, "").replace(/[^ -~]+/g, "");
|
|
5331
|
+
this._raw = workingInput; // Store the initial cleaned input. May get updated if prefix is added.
|
|
5332
|
+
// Part 1: Handle explicit country codes (alpha or numeric) in the input string
|
|
5333
|
+
let parsedCountryCode;
|
|
5334
|
+
let parsedNationalIdentifier;
|
|
5335
|
+
// 1a. Alpha prefix
|
|
5336
|
+
if (workingInput.length > 2 && /^[A-Z]{2}/.test(workingInput)) {
|
|
5337
|
+
const alphaCode = workingInput.slice(0, 2);
|
|
5338
|
+
const numericCode = EarTag.countryCodes[alphaCode];
|
|
5339
|
+
if (numericCode) {
|
|
5340
|
+
// Replace alpha with numeric for further parsing
|
|
5341
|
+
workingInput = numericCode + workingInput.slice(2);
|
|
5342
|
+
this._raw = workingInput; // Update _raw as it now contains numeric country code
|
|
5343
|
+
}
|
|
5344
|
+
// If unknown alpha, workingInput remains as is, will be handled by numeric check or fallback
|
|
5345
|
+
}
|
|
5346
|
+
// 1b. Numeric country code (already in workingInput, or converted from alpha)
|
|
5347
|
+
const countryPattern = "(372|826|899|528|250|276|056)";
|
|
5348
|
+
const regex12 = new RegExp(`^[0-9]{0,7}(${countryPattern})([0-9]{7})([0-9]{5})`);
|
|
5349
|
+
let match12 = regex12.exec(workingInput);
|
|
5350
|
+
if (match12) {
|
|
5351
|
+
parsedCountryCode = match12[1];
|
|
5352
|
+
parsedNationalIdentifier = `${match12[3]}${match12[4]}`;
|
|
5353
|
+
}
|
|
5354
|
+
else {
|
|
5355
|
+
const regex11 = new RegExp(`^[0-9]{0,7}(${countryPattern})([0-9]{6})([0-9]{5})`);
|
|
5356
|
+
let match11 = regex11.exec(workingInput);
|
|
5357
|
+
if (match11) {
|
|
5358
|
+
parsedCountryCode = match11[1];
|
|
5359
|
+
parsedNationalIdentifier = `${match11[3]}${match11[4]}`;
|
|
5360
|
+
}
|
|
5361
|
+
}
|
|
5362
|
+
// Part 2: If no country code parsed yet, try fallback
|
|
5363
|
+
if (!parsedCountryCode && fallbackCountryCode) {
|
|
5364
|
+
const numericFallback = EarTag.countryCodes[fallbackCountryCode];
|
|
5365
|
+
if (numericFallback) {
|
|
5366
|
+
// `workingInput` at this point is the original input (cleaned, no recognized country code)
|
|
5367
|
+
// Assume `workingInput` is the national identifier part (must be 11 or 12 digits)
|
|
5368
|
+
if (workingInput.length === 12 || workingInput.length === 11) {
|
|
5369
|
+
parsedCountryCode = numericFallback;
|
|
5370
|
+
parsedNationalIdentifier = workingInput;
|
|
5371
|
+
// Update _raw to reflect the tag as if it had the country code
|
|
5372
|
+
this._raw = numericFallback + workingInput;
|
|
5373
|
+
}
|
|
5374
|
+
}
|
|
5375
|
+
}
|
|
5376
|
+
// Part 3: Finalize and set properties
|
|
5377
|
+
if (parsedCountryCode && parsedNationalIdentifier) {
|
|
5378
|
+
this._isoCountryCode = parsedCountryCode;
|
|
5379
|
+
if (parsedNationalIdentifier.length === 11) {
|
|
5380
|
+
// Pad 11-digit national ID to 12-digits by prepending "0"
|
|
5381
|
+
this._nationalIdentifier = "0" + parsedNationalIdentifier;
|
|
5382
|
+
}
|
|
5383
|
+
else if (parsedNationalIdentifier.length === 12) {
|
|
5384
|
+
this._nationalIdentifier = parsedNationalIdentifier;
|
|
5385
|
+
}
|
|
5386
|
+
else {
|
|
5387
|
+
// This case should ideally not be reached if lengths are checked properly before.
|
|
5388
|
+
this._isEartag = false;
|
|
5389
|
+
return;
|
|
5390
|
+
}
|
|
5391
|
+
this._isEartag = true;
|
|
5392
|
+
}
|
|
5393
|
+
else {
|
|
5394
|
+
this._isEartag = false;
|
|
5395
|
+
}
|
|
5396
|
+
}
|
|
5397
|
+
static parse(str, fallbackCountryCode) {
|
|
5398
|
+
return new EarTag(str, fallbackCountryCode);
|
|
5399
|
+
}
|
|
5400
|
+
static format(str, marketCountry) {
|
|
5401
|
+
let t = EarTag.parse(str, marketCountry);
|
|
5402
|
+
if (t.isEartag()) {
|
|
5403
|
+
return t.toString();
|
|
5404
|
+
}
|
|
5405
|
+
return null;
|
|
5406
|
+
}
|
|
5407
|
+
toString() {
|
|
5408
|
+
if (!this._isEartag) {
|
|
5409
|
+
return "Invalid EarTag";
|
|
5410
|
+
}
|
|
5411
|
+
return `${EarTag.countryCodesByNumber[this.isoCountryCode]} ${this.nationalIdentifier.slice(0, 7)} ${this.nationalIdentifier.slice(7)}`;
|
|
5412
|
+
}
|
|
5413
|
+
isISO24631() {
|
|
5414
|
+
return EarTag.regexISO24631.test(this._raw);
|
|
5415
|
+
}
|
|
5416
|
+
toISO24631() {
|
|
5417
|
+
if (!this.isISO24631()) {
|
|
5418
|
+
return "Not a ISO24631 EarTag";
|
|
5419
|
+
}
|
|
5420
|
+
// ISO 24631 Formatting for movements
|
|
5421
|
+
const res = EarTag.regexISO24631.exec(this._raw);
|
|
5422
|
+
return `${res[1]} ${res[2]} ${res[3]} ${res[4]} ${res[5]} ${res[6]} ${res[7]} ${res[8]}`;
|
|
5423
|
+
}
|
|
5424
|
+
}
|
|
5425
|
+
EarTag.regexISO24631 = /^([0-9]{1})([0-9]{1})([0-9]{2})([0-9]{2})([0-9]{1})(372|826|899|528|250|276)([0-9]{7})([0-9]{5})/;
|
|
5426
|
+
EarTag.countryCodes = {
|
|
5427
|
+
IE: "372",
|
|
5428
|
+
UK: "826",
|
|
5429
|
+
XI: "899",
|
|
5430
|
+
NL: "528",
|
|
5431
|
+
FR: "250",
|
|
5432
|
+
DE: "276",
|
|
5433
|
+
BE: "056",
|
|
5434
|
+
};
|
|
5435
|
+
|
|
5436
|
+
function lotComparator(a, b) {
|
|
5437
|
+
const aMatch = a.lotNumber.match(/^(\d+)(\D*)$/);
|
|
5438
|
+
const bMatch = b.lotNumber.match(/^(\d+)(\D*)$/);
|
|
5439
|
+
// If neither matches the pattern, fall back to string comparison
|
|
5440
|
+
if (!aMatch && !bMatch) {
|
|
5441
|
+
return a.lotNumber.localeCompare(b.lotNumber);
|
|
5442
|
+
}
|
|
5443
|
+
// If only one matches, the one with numbers comes after
|
|
5444
|
+
if (!aMatch)
|
|
5445
|
+
return -1;
|
|
5446
|
+
if (!bMatch)
|
|
5447
|
+
return 1;
|
|
5448
|
+
// Handle cases with numbers
|
|
5449
|
+
const aNum = parseInt(aMatch[1], 10);
|
|
5450
|
+
const bNum = parseInt(bMatch[1], 10);
|
|
5451
|
+
// Compare numeric parts first
|
|
5452
|
+
if (aNum !== bNum)
|
|
5453
|
+
return aNum - bNum;
|
|
5454
|
+
// Get alphabetic suffixes (or empty string if none)
|
|
5455
|
+
const aAlpha = (aMatch === null || aMatch === void 0 ? void 0 : aMatch[2]) || "";
|
|
5456
|
+
const bAlpha = (bMatch === null || bMatch === void 0 ? void 0 : bMatch[2]) || "";
|
|
5457
|
+
// Compare by length first (shorter comes first)
|
|
5458
|
+
if (aAlpha.length !== bAlpha.length)
|
|
5459
|
+
return aAlpha.length - bAlpha.length;
|
|
5460
|
+
// Then compare alphabetically
|
|
5461
|
+
return aAlpha.localeCompare(bAlpha);
|
|
5462
|
+
}
|
|
5463
|
+
function sortByLotNumber(lots) {
|
|
5464
|
+
return [...lots].sort(lotComparator);
|
|
5465
|
+
}
|
|
5466
|
+
/***
|
|
5467
|
+
* Generate the next lot number in a sequence:
|
|
5468
|
+
*/
|
|
5469
|
+
function nextLotNumber(previousLotNumber) {
|
|
5470
|
+
const match = previousLotNumber.match(/^(\d+)(\D*)$/);
|
|
5471
|
+
if (match) {
|
|
5472
|
+
// Has numeric part
|
|
5473
|
+
const numPart = parseInt(match[1], 10);
|
|
5474
|
+
const alphaPart = match[2];
|
|
5475
|
+
if (alphaPart === "") {
|
|
5476
|
+
// Just a number: 1 -> 2
|
|
5477
|
+
return (numPart + 1).toString();
|
|
5478
|
+
}
|
|
5479
|
+
else {
|
|
5480
|
+
// Alphanumeric: increment the alpha part
|
|
5481
|
+
const nextAlpha = incrementAlphaSequence(alphaPart);
|
|
5482
|
+
return numPart + nextAlpha;
|
|
5483
|
+
}
|
|
5484
|
+
}
|
|
5485
|
+
else {
|
|
5486
|
+
// Pure alphabetic: A -> B, Z -> AA, etc.
|
|
5487
|
+
return incrementAlphaSequence(previousLotNumber);
|
|
5488
|
+
}
|
|
5489
|
+
}
|
|
5490
|
+
function incrementAlphaSequence(alpha) {
|
|
5491
|
+
if (alpha === "") {
|
|
5492
|
+
return "A";
|
|
5493
|
+
}
|
|
5494
|
+
// Convert to uppercase for consistent handling
|
|
5495
|
+
alpha = alpha.toUpperCase();
|
|
5496
|
+
// Check if we're at the end of sequence (all Z's)
|
|
5497
|
+
if (alpha === "Z".repeat(alpha.length)) {
|
|
5498
|
+
// Z -> AA, ZZ -> AAA, etc.
|
|
5499
|
+
return "A".repeat(alpha.length + 1);
|
|
5500
|
+
}
|
|
5501
|
+
// Convert string to array for easier manipulation
|
|
5502
|
+
let chars = alpha.split("");
|
|
5503
|
+
let carry = true;
|
|
5504
|
+
// Start from the rightmost character and work backwards
|
|
5505
|
+
for (let i = chars.length - 1; i >= 0 && carry; i--) {
|
|
5506
|
+
if (chars[i] === "Z") {
|
|
5507
|
+
chars[i] = "A";
|
|
5508
|
+
// carry remains true
|
|
5509
|
+
}
|
|
5510
|
+
else {
|
|
5511
|
+
// Increment the character
|
|
5512
|
+
chars[i] = String.fromCharCode(chars[i].charCodeAt(0) + 1);
|
|
5513
|
+
carry = false;
|
|
5514
|
+
}
|
|
5515
|
+
}
|
|
5516
|
+
// If we still have carry, prepend an A
|
|
5517
|
+
if (carry) {
|
|
5518
|
+
chars.unshift("A");
|
|
5519
|
+
}
|
|
5520
|
+
return chars.join("");
|
|
5521
|
+
}
|
|
5522
|
+
|
|
5523
|
+
exports.EarTag = EarTag;
|
|
5219
5524
|
exports.Studio = Studio;
|
|
5220
5525
|
exports.StudioHeaders = StudioHeaders;
|
|
5221
5526
|
exports.StudioTypes = types;
|
|
5222
5527
|
exports.createAppManifest = createAppManifest;
|
|
5223
5528
|
exports.default = Studio;
|
|
5529
|
+
exports.lotComparator = lotComparator;
|
|
5530
|
+
exports.nextLotNumber = nextLotNumber;
|
|
5531
|
+
exports.sortByLotNumber = sortByLotNumber;
|
|
5224
5532
|
//# sourceMappingURL=index.js.map
|