@marteye/studiojs 1.1.24 → 1.1.26

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.js CHANGED
@@ -71,7 +71,7 @@ function SimpleHttpClient(baseUrl, apiKey, fetch, defaultTimeout, debug = false)
71
71
  }
72
72
 
73
73
  // Path: studiojs/src/resources/markets.ts
74
- function create$c(_) {
74
+ function create$d(_) {
75
75
  const actions = {
76
76
  /***
77
77
  * This is used to construct the action from the request body
@@ -101,7 +101,7 @@ function create$c(_) {
101
101
  return actions;
102
102
  }
103
103
 
104
- function create$b(httpClient) {
104
+ function create$c(httpClient) {
105
105
  return {
106
106
  list: async (marketId) => {
107
107
  return httpClient.get(`/${marketId}/adjustments`);
@@ -112,6 +112,72 @@ function create$b(httpClient) {
112
112
  };
113
113
  }
114
114
 
115
+ function create$b(httpClient) {
116
+ let applications = {
117
+ /**
118
+ * List applications for a market with optional filtering
119
+ * @param marketId - ID of the market
120
+ * @param options - Optional query parameters for filtering and pagination
121
+ * @returns Paginated list of applications
122
+ */
123
+ list: async (marketId, options) => {
124
+ return httpClient.get(`/${marketId}/applications`, options);
125
+ },
126
+ /**
127
+ * Get a single application by ID
128
+ * @param marketId - ID of the market
129
+ * @param applicationId - ID of the application
130
+ * @returns The application details
131
+ */
132
+ get: async (marketId, applicationId) => {
133
+ return httpClient.get(`/${marketId}/applications/${applicationId}`);
134
+ },
135
+ /**
136
+ * Create a new application
137
+ * @param marketId - ID of the market
138
+ * @param applicationData - The application data
139
+ * @returns The created application
140
+ */
141
+ create: async (marketId, applicationData) => {
142
+ return httpClient.post(`/${marketId}/applications`, applicationData);
143
+ },
144
+ /**
145
+ * Update an existing application
146
+ * @param marketId - ID of the market
147
+ * @param applicationId - ID of the application to update
148
+ * @param updateData - The fields to update
149
+ * @returns The updated application
150
+ * @throws Error if the application is already approved or rejected
151
+ */
152
+ update: async (marketId, applicationId, updateData) => {
153
+ return httpClient.post(`/${marketId}/applications/${applicationId}`, updateData);
154
+ },
155
+ /**
156
+ * Approve an application
157
+ * @param marketId - ID of the market
158
+ * @param applicationId - ID of the application to approve
159
+ * @param notes - Optional notes for the approval
160
+ * @returns The approved application
161
+ * @throws Error if the application is not in pending status
162
+ */
163
+ approve: async (marketId, applicationId, notes) => {
164
+ return httpClient.post(`/${marketId}/applications/${applicationId}/approve`, { notes });
165
+ },
166
+ /**
167
+ * Reject an application
168
+ * @param marketId - ID of the market
169
+ * @param applicationId - ID of the application to reject
170
+ * @param notes - Optional notes for the rejection
171
+ * @returns The rejected application
172
+ * @throws Error if the application is not in pending status
173
+ */
174
+ reject: async (marketId, applicationId, notes) => {
175
+ return httpClient.post(`/${marketId}/applications/${applicationId}/reject`, { notes });
176
+ },
177
+ };
178
+ return applications;
179
+ }
180
+
115
181
  // Path: studiojs/src/resources/markets.ts
116
182
  function create$a(httpClient) {
117
183
  let customers = {
@@ -4558,7 +4624,12 @@ z.object({
4558
4624
  suffix: z.string().min(1, { message: "Suffix Type is required" }),
4559
4625
  });
4560
4626
  // Adding Sizes here will make more end points in the mainConfig object
4561
- const IMAGE_SIZES_VALUES$1 = ["small", "medium", "large"];
4627
+ const IMAGE_SIZES_VALUES$1 = [
4628
+ "thumbnail",
4629
+ "small",
4630
+ "medium",
4631
+ "large",
4632
+ ];
4562
4633
  const VIDEO_TASKS_VALUES$1 = ["compressed", "thumbnail"];
4563
4634
  z.enum(VIDEO_TASKS_VALUES$1);
4564
4635
  z.enum(IMAGE_SIZES_VALUES$1);
@@ -4568,12 +4639,29 @@ const UPLOAD_PATHS = {
4568
4639
  FINISH_UPLOAD: "finishMultipartUpload",
4569
4640
  CANCEL_UPLOAD: "cancelUpload",
4570
4641
  DELETE_UPLOAD: "deleteUpload",
4642
+ UPLOAD_SINGLE_FILE: "upload",
4571
4643
  };
4572
4644
  /**
4573
4645
  |--------------------------------------------------
4574
4646
  | Helper Functions
4575
4647
  |--------------------------------------------------
4576
4648
  */
4649
+ const MIME_TYPE_MAP = {
4650
+ png: "image/png",
4651
+ jpg: "image/jpeg",
4652
+ jpeg: "image/jpeg",
4653
+ mp4: "video/mp4",
4654
+ mov: "video/quicktime",
4655
+ qt: "video/quicktime",
4656
+ };
4657
+ /**
4658
+ |--------------------------------------------------
4659
+ | Make a File Path
4660
+ |--------------------------------------------------
4661
+ */
4662
+ function createFilePath(marketId, saleId, lotId, attributeId, fileName) {
4663
+ return `/${marketId}/${saleId}/${lotId}/${attributeId}/${fileName}`;
4664
+ }
4577
4665
  const getHeaders = (mimeType, bucket = "raw", token) => {
4578
4666
  const headers = new Headers();
4579
4667
  headers.append("mbtype", bucket);
@@ -4595,7 +4683,7 @@ const startUpload = async ({ fileName, fileMimeType, fileExtension, token, optio
4595
4683
  var _a;
4596
4684
  const headers = getHeaders(fileMimeType, (_a = options.options) === null || _a === void 0 ? void 0 : _a.bucket, token);
4597
4685
  const formData = new FormData();
4598
- const filePath = `${options.marketId}/${options.saleId}/${options.lotId}/${options.attributeId}/${fileName}.${fileExtension}`;
4686
+ const filePath = createFilePath(options.marketId, options.saleId, options.lotId, options.attributeId, `${fileName}.${fileExtension}`);
4599
4687
  formData.append("filePath", filePath);
4600
4688
  headers.append("Authorization", `Bearer ${token}`);
4601
4689
  let uploadIdResponse = await fetch(new URL(`${BASE_CF_URL}/${UPLOAD_PATHS.START_UPLOAD}`), {
@@ -4762,7 +4850,7 @@ const deleteUpload = async (fileUrl, token) => {
4762
4850
  * @returns {Promise<MediaFinishUploadResponse>}
4763
4851
  * @throws {Error} When upload fails
4764
4852
  */
4765
- const uploadFile = async (input, token) => {
4853
+ const uploadMultipartFile = async (input, token) => {
4766
4854
  var _a, _b, _c, _d, _e;
4767
4855
  let uploadId = "";
4768
4856
  let filePath = "";
@@ -4866,12 +4954,61 @@ const uploadFile = async (input, token) => {
4866
4954
  throw new Error("Upload failed and canceled " + error);
4867
4955
  }
4868
4956
  };
4957
+ const uploadSingleFile = async (input, token) => {
4958
+ const { file, filePath, uploadConfig } = input;
4959
+ let fileMimeType = "";
4960
+ let destinationPath = "";
4961
+ let fileName = "";
4962
+ let fileExtension = "";
4963
+ if (!filePath && !file) {
4964
+ throw new Error("Either filePath or file must be provided");
4965
+ }
4966
+ if (filePath && file) {
4967
+ throw new Error("Only one of filePath or file can be provided");
4968
+ }
4969
+ // We perform a copy form one file to another
4970
+ if (filePath) {
4971
+ fileName = filePath.split("/").pop() || "";
4972
+ fileExtension = fileName.split(".").pop() || "";
4973
+ fileMimeType = MIME_TYPE_MAP[fileExtension] || "";
4974
+ destinationPath = createFilePath(uploadConfig.marketId, uploadConfig.saleId, uploadConfig.lotId, uploadConfig.attributeId, `${fileName}`);
4975
+ }
4976
+ // We upload a single File
4977
+ if (file) {
4978
+ fileName = file.name.replace(/\.[^/.]+$/, "");
4979
+ fileExtension = file.name.split(".").pop() || "";
4980
+ fileMimeType = file.type;
4981
+ destinationPath = createFilePath(uploadConfig.marketId, uploadConfig.saleId, uploadConfig.lotId, uploadConfig.attributeId, `${fileName}.${fileExtension}`);
4982
+ }
4983
+ // Construct the Fetch Request
4984
+ const uploadUrl = new URL(`${BASE_CF_URL}/${UPLOAD_PATHS.UPLOAD_SINGLE_FILE}`);
4985
+ const headers = new Headers();
4986
+ headers.append("mbtype", "raw");
4987
+ headers.append("Authorization", `Bearer ${token}`);
4988
+ headers.append("mmimetype", fileMimeType);
4989
+ const formData = new FormData();
4990
+ filePath && formData.append("existingFilePath", filePath);
4991
+ destinationPath && formData.append("filePath", destinationPath);
4992
+ file && formData.append("file", file);
4993
+ const uploadResponse = await fetch(uploadUrl, {
4994
+ headers: headers,
4995
+ method: "POST",
4996
+ body: formData,
4997
+ });
4998
+ if (!uploadResponse.ok) {
4999
+ throw new Error("Failed to upload single file");
5000
+ }
5001
+ return (await uploadResponse.json());
5002
+ };
4869
5003
 
4870
5004
  // Multipart Upload for Media to the MARTEYE Media Service
4871
5005
  function create$9() {
4872
5006
  const files = {
4873
- uploadFile: async (input, token) => {
4874
- return await uploadFile(input, token);
5007
+ uploadSingleFile: async (input, token) => {
5008
+ return await uploadSingleFile(input, token);
5009
+ },
5010
+ uploadMultipartFile: async (input, token) => {
5011
+ return await uploadMultipartFile(input, token);
4875
5012
  },
4876
5013
  deleteFile: async (fileUrl, token) => {
4877
5014
  return await deleteUpload(fileUrl, token);
@@ -5044,9 +5181,10 @@ function resources(httpClient) {
5044
5181
  lots: create$7(httpClient),
5045
5182
  lotitems: create$8(httpClient),
5046
5183
  webhooks: create(),
5047
- actions: create$c(),
5184
+ actions: create$d(),
5185
+ applications: create$b(httpClient),
5048
5186
  settings: create$2(httpClient),
5049
- adjustments: create$b(httpClient),
5187
+ adjustments: create$c(httpClient),
5050
5188
  productCodes: create$5(httpClient),
5051
5189
  taxRates: create$1(httpClient),
5052
5190
  customers: create$a(httpClient),
@@ -5216,9 +5354,246 @@ function createAppManifest(appConfig) {
5216
5354
  };
5217
5355
  }
5218
5356
 
5357
+ class EarTag {
5358
+ static get countryCodesByNumber() {
5359
+ let reversed = {};
5360
+ for (const key of Object.keys(EarTag.countryCodes)) {
5361
+ reversed[EarTag.countryCodes[key]] = key;
5362
+ }
5363
+ return reversed;
5364
+ }
5365
+ normalisedCountryCode(countryCode) {
5366
+ if (!countryCode || typeof countryCode !== "string") {
5367
+ return null;
5368
+ }
5369
+ switch (countryCode) {
5370
+ case "GB-ENG":
5371
+ case "GB-SCT":
5372
+ case "GB-WLS":
5373
+ return "UK";
5374
+ case "GB-NIR":
5375
+ return "XI";
5376
+ default:
5377
+ return countryCode;
5378
+ }
5379
+ }
5380
+ get raw() {
5381
+ return this._raw;
5382
+ }
5383
+ isEartag() {
5384
+ return this._isEartag;
5385
+ }
5386
+ get isoCountryCode() {
5387
+ return this._isoCountryCode;
5388
+ }
5389
+ get nationalIdentifier() {
5390
+ return this._nationalIdentifier;
5391
+ }
5392
+ // private constructor
5393
+ constructor(input, fallbackCountryCode) {
5394
+ // readonly properties
5395
+ this._isEartag = false;
5396
+ fallbackCountryCode = this.normalisedCountryCode(fallbackCountryCode);
5397
+ let workingInput = input.replace(/\s/g, "").replace(/[^ -~]+/g, "");
5398
+ this._raw = workingInput; // Store the initial cleaned input. May get updated if prefix is added.
5399
+ // Part 1: Handle explicit country codes (alpha or numeric) in the input string
5400
+ let parsedCountryCode;
5401
+ let parsedNationalIdentifier;
5402
+ // 1a. Alpha prefix
5403
+ if (workingInput.length > 2 && /^[A-Z]{2}/.test(workingInput)) {
5404
+ const alphaCode = workingInput.slice(0, 2);
5405
+ const numericCode = EarTag.countryCodes[alphaCode];
5406
+ if (numericCode) {
5407
+ // Replace alpha with numeric for further parsing
5408
+ workingInput = numericCode + workingInput.slice(2);
5409
+ this._raw = workingInput; // Update _raw as it now contains numeric country code
5410
+ }
5411
+ // If unknown alpha, workingInput remains as is, will be handled by numeric check or fallback
5412
+ }
5413
+ // 1b. Numeric country code (already in workingInput, or converted from alpha)
5414
+ const countryPattern = "(372|826|899|528|250|276|056)";
5415
+ const regex12 = new RegExp(`^[0-9]{0,7}(${countryPattern})([0-9]{7})([0-9]{5})`);
5416
+ let match12 = regex12.exec(workingInput);
5417
+ if (match12) {
5418
+ parsedCountryCode = match12[1];
5419
+ parsedNationalIdentifier = `${match12[3]}${match12[4]}`;
5420
+ }
5421
+ else {
5422
+ const regex11 = new RegExp(`^[0-9]{0,7}(${countryPattern})([0-9]{6})([0-9]{5})`);
5423
+ let match11 = regex11.exec(workingInput);
5424
+ if (match11) {
5425
+ parsedCountryCode = match11[1];
5426
+ parsedNationalIdentifier = `${match11[3]}${match11[4]}`;
5427
+ }
5428
+ }
5429
+ // Part 2: If no country code parsed yet, try fallback
5430
+ if (!parsedCountryCode && fallbackCountryCode) {
5431
+ const numericFallback = EarTag.countryCodes[fallbackCountryCode];
5432
+ if (numericFallback) {
5433
+ // `workingInput` at this point is the original input (cleaned, no recognized country code)
5434
+ // Assume `workingInput` is the national identifier part (must be 11 or 12 digits)
5435
+ if (workingInput.length === 12 || workingInput.length === 11) {
5436
+ parsedCountryCode = numericFallback;
5437
+ parsedNationalIdentifier = workingInput;
5438
+ // Update _raw to reflect the tag as if it had the country code
5439
+ this._raw = numericFallback + workingInput;
5440
+ }
5441
+ }
5442
+ }
5443
+ // Part 3: Finalize and set properties
5444
+ if (parsedCountryCode && parsedNationalIdentifier) {
5445
+ this._isoCountryCode = parsedCountryCode;
5446
+ if (parsedNationalIdentifier.length === 11) {
5447
+ // Pad 11-digit national ID to 12-digits by prepending "0"
5448
+ this._nationalIdentifier = "0" + parsedNationalIdentifier;
5449
+ }
5450
+ else if (parsedNationalIdentifier.length === 12) {
5451
+ this._nationalIdentifier = parsedNationalIdentifier;
5452
+ }
5453
+ else {
5454
+ // This case should ideally not be reached if lengths are checked properly before.
5455
+ this._isEartag = false;
5456
+ return;
5457
+ }
5458
+ this._isEartag = true;
5459
+ }
5460
+ else {
5461
+ this._isEartag = false;
5462
+ }
5463
+ }
5464
+ static parse(str, fallbackCountryCode) {
5465
+ return new EarTag(str, fallbackCountryCode);
5466
+ }
5467
+ static format(str, marketCountry) {
5468
+ let t = EarTag.parse(str, marketCountry);
5469
+ if (t.isEartag()) {
5470
+ return t.toString();
5471
+ }
5472
+ return null;
5473
+ }
5474
+ toString() {
5475
+ if (!this._isEartag) {
5476
+ return "Invalid EarTag";
5477
+ }
5478
+ return `${EarTag.countryCodesByNumber[this.isoCountryCode]} ${this.nationalIdentifier.slice(0, 7)} ${this.nationalIdentifier.slice(7)}`;
5479
+ }
5480
+ isISO24631() {
5481
+ return EarTag.regexISO24631.test(this._raw);
5482
+ }
5483
+ toISO24631() {
5484
+ if (!this.isISO24631()) {
5485
+ return "Not a ISO24631 EarTag";
5486
+ }
5487
+ // ISO 24631 Formatting for movements
5488
+ const res = EarTag.regexISO24631.exec(this._raw);
5489
+ return `${res[1]} ${res[2]} ${res[3]} ${res[4]} ${res[5]} ${res[6]} ${res[7]} ${res[8]}`;
5490
+ }
5491
+ }
5492
+ 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})/;
5493
+ EarTag.countryCodes = {
5494
+ IE: "372",
5495
+ UK: "826",
5496
+ XI: "899",
5497
+ NL: "528",
5498
+ FR: "250",
5499
+ DE: "276",
5500
+ BE: "056",
5501
+ };
5502
+
5503
+ function lotComparator(a, b) {
5504
+ const aMatch = a.lotNumber.match(/^(\d+)(\D*)$/);
5505
+ const bMatch = b.lotNumber.match(/^(\d+)(\D*)$/);
5506
+ // If neither matches the pattern, fall back to string comparison
5507
+ if (!aMatch && !bMatch) {
5508
+ return a.lotNumber.localeCompare(b.lotNumber);
5509
+ }
5510
+ // If only one matches, the one with numbers comes after
5511
+ if (!aMatch)
5512
+ return -1;
5513
+ if (!bMatch)
5514
+ return 1;
5515
+ // Handle cases with numbers
5516
+ const aNum = parseInt(aMatch[1], 10);
5517
+ const bNum = parseInt(bMatch[1], 10);
5518
+ // Compare numeric parts first
5519
+ if (aNum !== bNum)
5520
+ return aNum - bNum;
5521
+ // Get alphabetic suffixes (or empty string if none)
5522
+ const aAlpha = (aMatch === null || aMatch === void 0 ? void 0 : aMatch[2]) || "";
5523
+ const bAlpha = (bMatch === null || bMatch === void 0 ? void 0 : bMatch[2]) || "";
5524
+ // Compare by length first (shorter comes first)
5525
+ if (aAlpha.length !== bAlpha.length)
5526
+ return aAlpha.length - bAlpha.length;
5527
+ // Then compare alphabetically
5528
+ return aAlpha.localeCompare(bAlpha);
5529
+ }
5530
+ function sortByLotNumber(lots) {
5531
+ return [...lots].sort(lotComparator);
5532
+ }
5533
+ /***
5534
+ * Generate the next lot number in a sequence:
5535
+ */
5536
+ function nextLotNumber(previousLotNumber) {
5537
+ const match = previousLotNumber.match(/^(\d+)(\D*)$/);
5538
+ if (match) {
5539
+ // Has numeric part
5540
+ const numPart = parseInt(match[1], 10);
5541
+ const alphaPart = match[2];
5542
+ if (alphaPart === "") {
5543
+ // Just a number: 1 -> 2
5544
+ return (numPart + 1).toString();
5545
+ }
5546
+ else {
5547
+ // Alphanumeric: increment the alpha part
5548
+ const nextAlpha = incrementAlphaSequence(alphaPart);
5549
+ return numPart + nextAlpha;
5550
+ }
5551
+ }
5552
+ else {
5553
+ // Pure alphabetic: A -> B, Z -> AA, etc.
5554
+ return incrementAlphaSequence(previousLotNumber);
5555
+ }
5556
+ }
5557
+ function incrementAlphaSequence(alpha) {
5558
+ if (alpha === "") {
5559
+ return "A";
5560
+ }
5561
+ // Convert to uppercase for consistent handling
5562
+ alpha = alpha.toUpperCase();
5563
+ // Check if we're at the end of sequence (all Z's)
5564
+ if (alpha === "Z".repeat(alpha.length)) {
5565
+ // Z -> AA, ZZ -> AAA, etc.
5566
+ return "A".repeat(alpha.length + 1);
5567
+ }
5568
+ // Convert string to array for easier manipulation
5569
+ let chars = alpha.split("");
5570
+ let carry = true;
5571
+ // Start from the rightmost character and work backwards
5572
+ for (let i = chars.length - 1; i >= 0 && carry; i--) {
5573
+ if (chars[i] === "Z") {
5574
+ chars[i] = "A";
5575
+ // carry remains true
5576
+ }
5577
+ else {
5578
+ // Increment the character
5579
+ chars[i] = String.fromCharCode(chars[i].charCodeAt(0) + 1);
5580
+ carry = false;
5581
+ }
5582
+ }
5583
+ // If we still have carry, prepend an A
5584
+ if (carry) {
5585
+ chars.unshift("A");
5586
+ }
5587
+ return chars.join("");
5588
+ }
5589
+
5590
+ exports.EarTag = EarTag;
5219
5591
  exports.Studio = Studio;
5220
5592
  exports.StudioHeaders = StudioHeaders;
5221
5593
  exports.StudioTypes = types;
5222
5594
  exports.createAppManifest = createAppManifest;
5223
5595
  exports.default = Studio;
5596
+ exports.lotComparator = lotComparator;
5597
+ exports.nextLotNumber = nextLotNumber;
5598
+ exports.sortByLotNumber = sortByLotNumber;
5224
5599
  //# sourceMappingURL=index.js.map