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