@marteye/studiojs 1.1.45 → 1.1.47-beta.0

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
@@ -73,7 +73,7 @@ function SimpleHttpClient(baseUrl, apiKey, fetch, defaultTimeout, debug = false)
73
73
  }
74
74
 
75
75
  // Path: studiojs/src/resources/markets.ts
76
- function create$o(_) {
76
+ function create$q(_) {
77
77
  const actions = {
78
78
  /***
79
79
  * This is used to construct the action from the request body
@@ -103,7 +103,7 @@ function create$o(_) {
103
103
  return actions;
104
104
  }
105
105
 
106
- function create$n(httpClient) {
106
+ function create$p(httpClient) {
107
107
  let activity = {
108
108
  /**
109
109
  * List activity logs for a market with pagination and filtering
@@ -155,7 +155,7 @@ function create$n(httpClient) {
155
155
  return activity;
156
156
  }
157
157
 
158
- function create$m(httpClient) {
158
+ function create$o(httpClient) {
159
159
  return {
160
160
  list: async (marketId) => {
161
161
  return httpClient.get(`/${marketId}/adjustments`);
@@ -172,7 +172,7 @@ function create$m(httpClient) {
172
172
  };
173
173
  }
174
174
 
175
- function create$l(httpClient) {
175
+ function create$n(httpClient) {
176
176
  return {
177
177
  /**
178
178
  * Get the full cart for a customer including extras and uninvoiced lots
@@ -195,7 +195,7 @@ function create$l(httpClient) {
195
195
  };
196
196
  }
197
197
 
198
- function create$k(httpClient) {
198
+ function create$m(httpClient) {
199
199
  return {
200
200
  list: async (marketId) => {
201
201
  return httpClient.get(`/${marketId}/extras`);
@@ -215,7 +215,7 @@ function create$k(httpClient) {
215
215
  /***
216
216
  * Bidder applications
217
217
  */
218
- function create$j(httpClient) {
218
+ function create$l(httpClient) {
219
219
  let applications = {
220
220
  /**
221
221
  * List applications for a market with optional filtering
@@ -299,7 +299,7 @@ function create$j(httpClient) {
299
299
  }
300
300
 
301
301
  // Path: studiojs/src/resources/markets.ts
302
- function create$i(httpClient) {
302
+ function create$k(httpClient) {
303
303
  let customers = {
304
304
  list: async (marketId, lastId) => {
305
305
  let params = {};
@@ -346,6 +346,599 @@ function create$i(httpClient) {
346
346
  return customers;
347
347
  }
348
348
 
349
+ const DEFAULT_PAGE_SIZE = 100;
350
+ const MAX_MEMBER_BATCH_SIZE = 100;
351
+ function create$j(httpClient) {
352
+ const customerLists = {
353
+ list: async (marketId, options) => {
354
+ return httpClient.get(`/${marketId}/lists`, buildListQueryParams(options));
355
+ },
356
+ listAll: async (marketId, options) => {
357
+ var _a;
358
+ let lists = [];
359
+ let offset = 0;
360
+ let total = Number.POSITIVE_INFINITY;
361
+ let limit = (_a = options === null || options === void 0 ? void 0 : options.limit) !== null && _a !== void 0 ? _a : DEFAULT_PAGE_SIZE;
362
+ while (offset < total) {
363
+ let page = await customerLists.list(marketId, {
364
+ type: options === null || options === void 0 ? void 0 : options.type,
365
+ limit,
366
+ offset,
367
+ });
368
+ lists = lists.concat(page.lists);
369
+ total = page.total;
370
+ if (page.lists.length === 0) {
371
+ break;
372
+ }
373
+ offset += page.lists.length;
374
+ }
375
+ return lists;
376
+ },
377
+ get: async (marketId, listId) => {
378
+ return httpClient.get(`/${marketId}/lists/${listId}`);
379
+ },
380
+ getBySlug: async (marketId, slug) => {
381
+ return httpClient.get(`/${marketId}/lists/by-slug/${encodeURIComponent(slug)}`);
382
+ },
383
+ create: async (marketId, payload) => {
384
+ return httpClient.post(`/${marketId}/lists`, normalizeCreatePayload(payload));
385
+ },
386
+ update: async (marketId, listId, payload) => {
387
+ let body = await buildUpdatePayload(customerLists, marketId, listId, payload);
388
+ return httpClient.post(`/${marketId}/lists/${listId}`, body);
389
+ },
390
+ delete: async (marketId, listId) => {
391
+ return httpClient.delete(`/${marketId}/lists/${listId}`);
392
+ },
393
+ refresh: async (marketId, listId) => {
394
+ return httpClient.post(`/${marketId}/lists/${listId}/refresh`, {});
395
+ },
396
+ getMembers: async (marketId, listId, options) => {
397
+ return httpClient.get(`/${marketId}/lists/${listId}/members`, buildMembersQueryParams(options));
398
+ },
399
+ getAllMembers: async (marketId, listId, options) => {
400
+ var _a;
401
+ let members = [];
402
+ let offset = 0;
403
+ let limit = (_a = options === null || options === void 0 ? void 0 : options.limit) !== null && _a !== void 0 ? _a : DEFAULT_PAGE_SIZE;
404
+ let hasMore = true;
405
+ while (hasMore) {
406
+ let page = await customerLists.getMembers(marketId, listId, {
407
+ limit,
408
+ offset,
409
+ includeArchived: options === null || options === void 0 ? void 0 : options.includeArchived,
410
+ });
411
+ members = members.concat(page.members);
412
+ hasMore = page.hasMore;
413
+ if (page.members.length === 0) {
414
+ break;
415
+ }
416
+ offset += page.members.length;
417
+ }
418
+ return members;
419
+ },
420
+ addMembers: async (marketId, listId, customerIds) => {
421
+ if (customerIds.length === 0) {
422
+ return {
423
+ added: 0,
424
+ alreadyMembers: 0,
425
+ notFound: 0,
426
+ memberCount: 0,
427
+ };
428
+ }
429
+ let result = {
430
+ added: 0,
431
+ alreadyMembers: 0,
432
+ notFound: 0,
433
+ memberCount: 0,
434
+ };
435
+ for (let i = 0; i < customerIds.length; i += MAX_MEMBER_BATCH_SIZE) {
436
+ let chunk = customerIds.slice(i, i + MAX_MEMBER_BATCH_SIZE);
437
+ let response = await httpClient.post(`/${marketId}/lists/${listId}/members`, { customerIds: chunk });
438
+ result.added += response.added;
439
+ result.alreadyMembers += response.alreadyMembers;
440
+ result.notFound += response.notFound;
441
+ result.memberCount = response.memberCount;
442
+ }
443
+ return result;
444
+ },
445
+ removeMember: async (marketId, listId, customerId) => {
446
+ return httpClient.delete(`/${marketId}/lists/${listId}/members/${customerId}`);
447
+ },
448
+ preview: async (marketId, filters) => {
449
+ return httpClient.get(`/${marketId}/reports/customer-lists`, buildPreviewQueryParams(filters));
450
+ },
451
+ listProductCodes: async (marketId) => {
452
+ let response = await httpClient.get(`/${marketId}/reports/customer-lists`, { productCodesOnly: "true" });
453
+ return {
454
+ uniqueProductCodes: response.summary.uniqueProductCodes,
455
+ };
456
+ },
457
+ view: async (marketId, listIdOrSlug, options) => {
458
+ var _a;
459
+ let list = await resolveList(customerLists, marketId, listIdOrSlug, options);
460
+ if (list.type === "simple") {
461
+ let shouldFetchAllMembers = (_a = options === null || options === void 0 ? void 0 : options.allMembers) !== null && _a !== void 0 ? _a : ((options === null || options === void 0 ? void 0 : options.limit) === undefined && (options === null || options === void 0 ? void 0 : options.offset) === undefined);
462
+ if (shouldFetchAllMembers) {
463
+ let members = await customerLists.getAllMembers(marketId, list.id);
464
+ return {
465
+ mode: "simple",
466
+ list,
467
+ members,
468
+ total: members.length,
469
+ };
470
+ }
471
+ let response = await customerLists.getMembers(marketId, list.id, {
472
+ limit: options === null || options === void 0 ? void 0 : options.limit,
473
+ offset: options === null || options === void 0 ? void 0 : options.offset,
474
+ });
475
+ return {
476
+ mode: "simple",
477
+ list,
478
+ members: response.members,
479
+ total: response.total,
480
+ };
481
+ }
482
+ if (!list.query) {
483
+ throw new Error(`Smart list ${list.id} has no query defined`);
484
+ }
485
+ if ((options === null || options === void 0 ? void 0 : options.refresh) || hasRollingDates(list)) {
486
+ try {
487
+ await customerLists.refresh(marketId, list.id);
488
+ }
489
+ catch (error) {
490
+ if (!isRateLimitError(error)) {
491
+ throw error;
492
+ }
493
+ }
494
+ }
495
+ let effectiveQuery = applyRollingDatesToQuery(list);
496
+ let effectiveFilters = queryToFilters(effectiveQuery);
497
+ let preview = await customerLists.preview(marketId, effectiveFilters);
498
+ let excludedCustomerIds = new Set(list.excludedCustomerIds || []);
499
+ let rows = preview.rows.filter((row) => !excludedCustomerIds.has(row.customerId));
500
+ return {
501
+ mode: "smart",
502
+ list,
503
+ effectiveFilters,
504
+ rows,
505
+ summary: summariseRows(rows),
506
+ };
507
+ },
508
+ };
509
+ return customerLists;
510
+ }
511
+ async function buildUpdatePayload(customerLists, marketId, listId, payload) {
512
+ if (payload.query !== undefined && payload.filters !== undefined) {
513
+ throw new Error("Provide either query or filters when updating a customer list, not both");
514
+ }
515
+ let body = {};
516
+ if (payload.name !== undefined) {
517
+ body.name = payload.name;
518
+ }
519
+ if (payload.description !== undefined) {
520
+ body.description = payload.description;
521
+ }
522
+ if (payload.query !== undefined) {
523
+ body.query = payload.query;
524
+ }
525
+ if (payload.filters !== undefined) {
526
+ let existing = await customerLists.get(marketId, listId);
527
+ if (existing.type !== "smart") {
528
+ throw new Error("Cannot update filters on a simple list");
529
+ }
530
+ let existingFilters = queryToFilters(existing.query);
531
+ body.query = filtersToCustomerListQuery(mergeCustomerListFilters(existingFilters, payload.filters));
532
+ }
533
+ if (Object.keys(body).length === 0) {
534
+ throw new Error("No update fields provided");
535
+ }
536
+ return body;
537
+ }
538
+ function normalizeCreatePayload(payload) {
539
+ var _a;
540
+ if (payload.type === "simple") {
541
+ return {
542
+ name: payload.name,
543
+ description: payload.description,
544
+ type: payload.type,
545
+ };
546
+ }
547
+ if (payload.query !== undefined && payload.filters !== undefined) {
548
+ throw new Error("Provide either query or filters when creating a smart list, not both");
549
+ }
550
+ let query = (_a = payload.query) !== null && _a !== void 0 ? _a : filtersToCustomerListQuery(payload.filters || {});
551
+ return {
552
+ name: payload.name,
553
+ description: payload.description,
554
+ type: payload.type,
555
+ query,
556
+ };
557
+ }
558
+ function buildListQueryParams(options) {
559
+ let queryParams = {};
560
+ if (options === null || options === void 0 ? void 0 : options.type) {
561
+ queryParams.type = options.type;
562
+ }
563
+ if ((options === null || options === void 0 ? void 0 : options.limit) !== undefined) {
564
+ queryParams.limit = String(options.limit);
565
+ }
566
+ if ((options === null || options === void 0 ? void 0 : options.offset) !== undefined) {
567
+ queryParams.offset = String(options.offset);
568
+ }
569
+ return Object.keys(queryParams).length > 0 ? queryParams : undefined;
570
+ }
571
+ function buildMembersQueryParams(options) {
572
+ let queryParams = {};
573
+ if ((options === null || options === void 0 ? void 0 : options.limit) !== undefined) {
574
+ queryParams.limit = String(options.limit);
575
+ }
576
+ if ((options === null || options === void 0 ? void 0 : options.offset) !== undefined) {
577
+ queryParams.offset = String(options.offset);
578
+ }
579
+ if ((options === null || options === void 0 ? void 0 : options.includeArchived) !== undefined) {
580
+ queryParams.includeArchived = String(options.includeArchived);
581
+ }
582
+ return Object.keys(queryParams).length > 0 ? queryParams : undefined;
583
+ }
584
+ function buildPreviewQueryParams(filters) {
585
+ var _a;
586
+ let params = {};
587
+ let filter = buildFilterExpression(filters);
588
+ let excludeFilters = buildExcludeFilters(filters);
589
+ if (filter) {
590
+ params.filter = filter;
591
+ }
592
+ if (excludeFilters.length > 0) {
593
+ params.excludeFilters = JSON.stringify(excludeFilters);
594
+ }
595
+ params.role = (_a = filters.role) !== null && _a !== void 0 ? _a : "both";
596
+ if (filters.geoBounds) {
597
+ params.bounds = JSON.stringify(filters.geoBounds);
598
+ }
599
+ if (filters.secondaryFilter) {
600
+ params.secondaryFilter = JSON.stringify({
601
+ role: filters.secondaryFilter.role,
602
+ filter: buildFilterExpression(filters.secondaryFilter),
603
+ ...(filters.secondaryFilter.geoBounds
604
+ ? { bounds: filters.secondaryFilter.geoBounds }
605
+ : {}),
606
+ });
607
+ }
608
+ return params;
609
+ }
610
+ function filtersToCustomerListQuery(filters) {
611
+ var _a;
612
+ let excludeFilters = buildExcludeFilters(filters);
613
+ let query = {
614
+ role: (_a = filters.role) !== null && _a !== void 0 ? _a : "both",
615
+ };
616
+ let filter = buildFilterExpression(filters);
617
+ if (filter) {
618
+ query.filter = filter;
619
+ }
620
+ if (excludeFilters.length > 0) {
621
+ query.excludeFilters = excludeFilters;
622
+ }
623
+ if (filters.geoBounds) {
624
+ query.bounds = filters.geoBounds;
625
+ }
626
+ if (filters.rollingDateConfig) {
627
+ query.rollingDateConfig = filters.rollingDateConfig;
628
+ }
629
+ if (filters.secondaryFilter) {
630
+ query.secondaryFilter = {
631
+ role: filters.secondaryFilter.role,
632
+ filter: buildFilterExpression(filters.secondaryFilter),
633
+ ...(filters.secondaryFilter.geoBounds
634
+ ? { bounds: filters.secondaryFilter.geoBounds }
635
+ : {}),
636
+ ...(filters.secondaryFilter.rollingDateConfig
637
+ ? { rollingDateConfig: filters.secondaryFilter.rollingDateConfig }
638
+ : {}),
639
+ };
640
+ }
641
+ return query;
642
+ }
643
+ function queryToFilters(query) {
644
+ if (!query) {
645
+ return { role: "both", productCodes: [] };
646
+ }
647
+ let filters = {
648
+ role: query.role,
649
+ dateStart: extractDate(query.filter, ">="),
650
+ dateEnd: extractDate(query.filter, "<="),
651
+ productCodes: extractProductCodes(query.filter),
652
+ excludedProductCodes: [],
653
+ geoBounds: query.bounds || null,
654
+ boughtOnlineOnly: /@boughtOnline\s*=\s*true/.test(query.filter || ""),
655
+ cattleBreeds: extractAllMatches(query.filter, /@breedCodeOfCattle\s*=\s*"([^"]+)"/g),
656
+ sheepBreeds: extractAllMatches(query.filter, /breedOfSheep\s*=\s*"([^"]+)"/g),
657
+ rollingDateConfig: query.rollingDateConfig,
658
+ };
659
+ for (let excludeFilter of query.excludeFilters || []) {
660
+ if (filters.excludeDateStart == null) {
661
+ filters.excludeDateStart = extractDate(excludeFilter, ">=");
662
+ }
663
+ if (filters.excludeDateEnd == null) {
664
+ filters.excludeDateEnd = extractDate(excludeFilter, "<=");
665
+ }
666
+ filters.excludedProductCodes = uniqueStrings((filters.excludedProductCodes || []).concat(extractProductCodes(excludeFilter)));
667
+ }
668
+ if (query.secondaryFilter) {
669
+ filters.secondaryFilter = {
670
+ role: query.secondaryFilter.role,
671
+ dateStart: extractDate(query.secondaryFilter.filter, ">="),
672
+ dateEnd: extractDate(query.secondaryFilter.filter, "<="),
673
+ productCodes: extractProductCodes(query.secondaryFilter.filter),
674
+ geoBounds: query.secondaryFilter.bounds || null,
675
+ rollingDateConfig: query.secondaryFilter.rollingDateConfig,
676
+ };
677
+ }
678
+ return filters;
679
+ }
680
+ function mergeCustomerListFilters(base, updates) {
681
+ let merged = { ...base };
682
+ if (updates.role !== undefined)
683
+ merged.role = updates.role;
684
+ if (updates.dateStart !== undefined)
685
+ merged.dateStart = updates.dateStart;
686
+ if (updates.dateEnd !== undefined)
687
+ merged.dateEnd = updates.dateEnd;
688
+ if (updates.productCodes !== undefined)
689
+ merged.productCodes = [...updates.productCodes];
690
+ if (updates.excludeDateStart !== undefined) {
691
+ merged.excludeDateStart = updates.excludeDateStart;
692
+ }
693
+ if (updates.excludeDateEnd !== undefined) {
694
+ merged.excludeDateEnd = updates.excludeDateEnd;
695
+ }
696
+ if (updates.excludedProductCodes !== undefined) {
697
+ merged.excludedProductCodes = [...updates.excludedProductCodes];
698
+ }
699
+ if (updates.geoBounds !== undefined)
700
+ merged.geoBounds = updates.geoBounds;
701
+ if (updates.boughtOnlineOnly !== undefined) {
702
+ merged.boughtOnlineOnly = updates.boughtOnlineOnly;
703
+ }
704
+ if (updates.cattleBreeds !== undefined) {
705
+ merged.cattleBreeds = [...updates.cattleBreeds];
706
+ }
707
+ if (updates.sheepBreeds !== undefined) {
708
+ merged.sheepBreeds = [...updates.sheepBreeds];
709
+ }
710
+ if (updates.rollingDateConfig !== undefined) {
711
+ merged.rollingDateConfig = updates.rollingDateConfig;
712
+ }
713
+ if (updates.secondaryFilter !== undefined) {
714
+ if (updates.secondaryFilter === null) {
715
+ merged.secondaryFilter = null;
716
+ }
717
+ else {
718
+ let nextSecondary = merged.secondaryFilter
719
+ ? { ...merged.secondaryFilter }
720
+ : { role: updates.secondaryFilter.role || "both", productCodes: [] };
721
+ if (updates.secondaryFilter.role !== undefined) {
722
+ nextSecondary.role = updates.secondaryFilter.role;
723
+ }
724
+ if (updates.secondaryFilter.dateStart !== undefined) {
725
+ nextSecondary.dateStart = updates.secondaryFilter.dateStart;
726
+ }
727
+ if (updates.secondaryFilter.dateEnd !== undefined) {
728
+ nextSecondary.dateEnd = updates.secondaryFilter.dateEnd;
729
+ }
730
+ if (updates.secondaryFilter.productCodes !== undefined) {
731
+ nextSecondary.productCodes = [...updates.secondaryFilter.productCodes];
732
+ }
733
+ if (updates.secondaryFilter.geoBounds !== undefined) {
734
+ nextSecondary.geoBounds = updates.secondaryFilter.geoBounds;
735
+ }
736
+ if (updates.secondaryFilter.rollingDateConfig !== undefined) {
737
+ nextSecondary.rollingDateConfig =
738
+ updates.secondaryFilter.rollingDateConfig;
739
+ }
740
+ merged.secondaryFilter = nextSecondary;
741
+ }
742
+ }
743
+ return merged;
744
+ }
745
+ function buildExcludeFilters(filters) {
746
+ let excludeFilters = [];
747
+ if (filters.excludeDateStart || filters.excludeDateEnd) {
748
+ let clauses = [];
749
+ if (filters.excludeDateStart) {
750
+ clauses.push(`saleDate >= "${filters.excludeDateStart}"`);
751
+ }
752
+ if (filters.excludeDateEnd) {
753
+ clauses.push(`saleDate <= "${filters.excludeDateEnd}"`);
754
+ }
755
+ if (clauses.length > 0) {
756
+ excludeFilters.push(clauses.join(" AND "));
757
+ }
758
+ }
759
+ if (filters.excludedProductCodes && filters.excludedProductCodes.length > 0) {
760
+ if (filters.excludedProductCodes.length === 1) {
761
+ excludeFilters.push(`productCode = "${filters.excludedProductCodes[0]}"`);
762
+ }
763
+ else {
764
+ excludeFilters.push(`(${filters.excludedProductCodes
765
+ .map((code) => `productCode = "${code}"`)
766
+ .join(" OR ")})`);
767
+ }
768
+ }
769
+ return excludeFilters;
770
+ }
771
+ function buildFilterExpression(filters) {
772
+ let clauses = [];
773
+ if (filters.dateStart)
774
+ clauses.push(`saleDate >= "${filters.dateStart}"`);
775
+ if (filters.dateEnd)
776
+ clauses.push(`saleDate <= "${filters.dateEnd}"`);
777
+ if (filters.productCodes && filters.productCodes.length > 0) {
778
+ if (filters.productCodes.length === 1) {
779
+ clauses.push(`productCode = "${filters.productCodes[0]}"`);
780
+ }
781
+ else {
782
+ clauses.push(`(${filters.productCodes
783
+ .map((code) => `productCode = "${code}"`)
784
+ .join(" OR ")})`);
785
+ }
786
+ }
787
+ if (filters.boughtOnlineOnly) {
788
+ clauses.push(`@boughtOnline = true`);
789
+ }
790
+ let breedClauses = [];
791
+ for (let breed of filters.cattleBreeds || []) {
792
+ breedClauses.push(`@breedCodeOfCattle = "${breed}"`);
793
+ }
794
+ for (let breed of filters.sheepBreeds || []) {
795
+ breedClauses.push(`breedOfSheep = "${breed}"`);
796
+ }
797
+ if (breedClauses.length === 1) {
798
+ clauses.push(breedClauses[0]);
799
+ }
800
+ else if (breedClauses.length > 1) {
801
+ clauses.push(`(${breedClauses.join(" OR ")})`);
802
+ }
803
+ return clauses.length > 0 ? clauses.join(" AND ") : undefined;
804
+ }
805
+ async function resolveList(customerLists, marketId, listIdOrSlug, options) {
806
+ let identifierType = (options === null || options === void 0 ? void 0 : options.identifierType) || "auto";
807
+ if (identifierType === "id") {
808
+ return customerLists.get(marketId, listIdOrSlug);
809
+ }
810
+ if (identifierType === "slug") {
811
+ return customerLists.getBySlug(marketId, listIdOrSlug);
812
+ }
813
+ let firstLookup = listIdOrSlug.startsWith("list_") ? "id" : "slug";
814
+ try {
815
+ return firstLookup === "id"
816
+ ? await customerLists.get(marketId, listIdOrSlug)
817
+ : await customerLists.getBySlug(marketId, listIdOrSlug);
818
+ }
819
+ catch (error) {
820
+ if (!isNotFoundError(error)) {
821
+ throw error;
822
+ }
823
+ }
824
+ return firstLookup === "id"
825
+ ? customerLists.getBySlug(marketId, listIdOrSlug)
826
+ : customerLists.get(marketId, listIdOrSlug);
827
+ }
828
+ function applyRollingDatesToQuery(list) {
829
+ var _a;
830
+ if (!list.query) {
831
+ throw new Error(`Smart list ${list.id} has no query defined`);
832
+ }
833
+ let query = {
834
+ ...list.query,
835
+ ...(list.query.secondaryFilter
836
+ ? { secondaryFilter: { ...list.query.secondaryFilter } }
837
+ : {}),
838
+ };
839
+ let topLevelRollingConfig = list.query.rollingDateConfig || list.rollingDateConfig;
840
+ if (topLevelRollingConfig) {
841
+ query.filter = applyRollingDatesToFilter(query.filter, topLevelRollingConfig, list.createdAt);
842
+ }
843
+ if ((_a = query.secondaryFilter) === null || _a === void 0 ? void 0 : _a.rollingDateConfig) {
844
+ query.secondaryFilter.filter = applyRollingDatesToFilter(query.secondaryFilter.filter, query.secondaryFilter.rollingDateConfig, list.createdAt);
845
+ }
846
+ return query;
847
+ }
848
+ function applyRollingDatesToFilter(filter, rollingDateConfig, createdAt) {
849
+ if (!filter) {
850
+ return filter;
851
+ }
852
+ let createdAtDate = new Date(createdAt);
853
+ if (Number.isNaN(createdAtDate.getTime())) {
854
+ return filter;
855
+ }
856
+ let originalStart = new Date(rollingDateConfig.originalStart);
857
+ let originalEnd = new Date(rollingDateConfig.originalEnd);
858
+ if (Number.isNaN(originalStart.getTime()) ||
859
+ Number.isNaN(originalEnd.getTime())) {
860
+ return filter;
861
+ }
862
+ let now = new Date();
863
+ let daysElapsed = Math.floor((now.getTime() - createdAtDate.getTime()) / (24 * 60 * 60 * 1000));
864
+ let nextStart = new Date(originalStart.getTime() + daysElapsed * 24 * 60 * 60 * 1000);
865
+ let nextEnd = new Date(originalEnd.getTime() + daysElapsed * 24 * 60 * 60 * 1000);
866
+ return filter
867
+ .replace(/saleDate\s*>=\s*"[^"]+"/g, `saleDate >= "${formatDate(nextStart)}"`)
868
+ .replace(/saleDate\s*<=\s*"[^"]+"/g, `saleDate <= "${formatDate(nextEnd)}"`);
869
+ }
870
+ function hasRollingDates(list) {
871
+ var _a, _b, _c;
872
+ return Boolean(((_a = list.query) === null || _a === void 0 ? void 0 : _a.rollingDateConfig) ||
873
+ list.rollingDateConfig ||
874
+ ((_c = (_b = list.query) === null || _b === void 0 ? void 0 : _b.secondaryFilter) === null || _c === void 0 ? void 0 : _c.rollingDateConfig));
875
+ }
876
+ function summariseRows(rows) {
877
+ let uniqueProductCodes = new Set();
878
+ let totalSoldValueInCents = 0;
879
+ let totalPurchasedValueInCents = 0;
880
+ let customersWithLocation = 0;
881
+ for (let row of rows) {
882
+ totalSoldValueInCents += Number(row.totalSoldValueInCents || 0);
883
+ totalPurchasedValueInCents += Number(row.totalPurchasedValueInCents || 0);
884
+ if (row.latitude != null && row.longitude != null) {
885
+ customersWithLocation += 1;
886
+ }
887
+ for (let productCode of row.productCodesSold || []) {
888
+ uniqueProductCodes.add(productCode);
889
+ }
890
+ for (let productCode of row.productCodesBought || []) {
891
+ uniqueProductCodes.add(productCode);
892
+ }
893
+ }
894
+ return {
895
+ totalCustomers: rows.length,
896
+ totalSoldValueInCents,
897
+ totalPurchasedValueInCents,
898
+ customersWithLocation,
899
+ uniqueProductCodes: Array.from(uniqueProductCodes),
900
+ };
901
+ }
902
+ function extractDate(filter, operator) {
903
+ if (!filter) {
904
+ return null;
905
+ }
906
+ let escapedOperator = operator.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
907
+ let match = filter.match(new RegExp(`saleDate\\s*${escapedOperator}\\s*"([^"]+)"`));
908
+ return match ? match[1] : null;
909
+ }
910
+ function extractProductCodes(filter) {
911
+ if (!filter) {
912
+ return [];
913
+ }
914
+ let inMatch = filter.match(/productCode\s+IN\s*\(([^)]+)\)/);
915
+ if (inMatch) {
916
+ return uniqueStrings(inMatch[1]
917
+ .split(",")
918
+ .map((value) => value.trim().replace(/^"|"$/g, ""))
919
+ .filter(Boolean));
920
+ }
921
+ return uniqueStrings(extractAllMatches(filter, /productCode\s*=\s*"([^"]+)"/g));
922
+ }
923
+ function extractAllMatches(filter, regex) {
924
+ if (!filter) {
925
+ return [];
926
+ }
927
+ return [...filter.matchAll(regex)].map((match) => match[1]).filter(Boolean);
928
+ }
929
+ function uniqueStrings(values) {
930
+ return Array.from(new Set(values));
931
+ }
932
+ function formatDate(date) {
933
+ return date.toISOString().split("T")[0];
934
+ }
935
+ function isNotFoundError(error) {
936
+ return error instanceof Error && error.message.includes(" not found");
937
+ }
938
+ function isRateLimitError(error) {
939
+ return error instanceof Error && error.message.includes("status 429");
940
+ }
941
+
349
942
  var util;
350
943
  (function (util) {
351
944
  util.assertEqual = (val) => val;
@@ -5136,7 +5729,7 @@ const uploadSingleFile = async (input, token) => {
5136
5729
  };
5137
5730
 
5138
5731
  // Multipart Upload for Media to the MARTEYE Media Service
5139
- function create$h() {
5732
+ function create$i() {
5140
5733
  const files = {
5141
5734
  uploadSingleFile: async (input, token) => {
5142
5735
  return await uploadSingleFile(input, token);
@@ -5151,7 +5744,7 @@ function create$h() {
5151
5744
  return files;
5152
5745
  }
5153
5746
 
5154
- function create$g(httpClient) {
5747
+ function create$h(httpClient) {
5155
5748
  const invoices = {
5156
5749
  /**
5157
5750
  * List all invoices for a market with pagination
@@ -5179,7 +5772,7 @@ function create$g(httpClient) {
5179
5772
  return invoices;
5180
5773
  }
5181
5774
 
5182
- function create$f(httpClient) {
5775
+ function create$g(httpClient) {
5183
5776
  return {
5184
5777
  create: async (marketId, saleId, lotId, data) => {
5185
5778
  return httpClient.post(`/${marketId}/sales/${saleId}/lots/${lotId}/items`, data);
@@ -5196,7 +5789,7 @@ function create$f(httpClient) {
5196
5789
  /**
5197
5790
  * Defines the possible status values for a lot in a sale
5198
5791
  */
5199
- function create$e(httpClient) {
5792
+ function create$f(httpClient) {
5200
5793
  return {
5201
5794
  get: async (marketId, saleId, lotId, options) => {
5202
5795
  return httpClient.get(`/${marketId}/sales/${saleId}/lots/${lotId}`, (options === null || options === void 0 ? void 0 : options.at) ? { at: options.at } : undefined);
@@ -5213,10 +5806,19 @@ function create$e(httpClient) {
5213
5806
  delete: async (marketId, saleId, lotId) => {
5214
5807
  return httpClient.delete(`/${marketId}/sales/${saleId}/lots/${lotId}`);
5215
5808
  },
5809
+ deletePreflight: async (marketId, saleId, lotId) => {
5810
+ return httpClient.get(`/${marketId}/sales/${saleId}/lots/${lotId}/delete-preflight`);
5811
+ },
5812
+ deletePreflightBatch: async (marketId, saleId, lotIds) => {
5813
+ return httpClient.post(`/${marketId}/sales/${saleId}/lots/delete-preflight`, { lotIds });
5814
+ },
5815
+ deleteBatch: async (marketId, saleId, lotIds, confirmedLotIds) => {
5816
+ return httpClient.post(`/${marketId}/sales/${saleId}/lots/delete`, { lotIds, confirmedLotIds });
5817
+ },
5216
5818
  };
5217
5819
  }
5218
5820
 
5219
- function create$d(httpClient) {
5821
+ function create$e(httpClient) {
5220
5822
  const markets = {
5221
5823
  get: async (marketId, options) => {
5222
5824
  return httpClient.get(`/${marketId}`, (options === null || options === void 0 ? void 0 : options.at) ? { at: options.at } : undefined);
@@ -5238,7 +5840,7 @@ function create$d(httpClient) {
5238
5840
  return markets;
5239
5841
  }
5240
5842
 
5241
- function create$c(httpClient) {
5843
+ function create$d(httpClient) {
5242
5844
  let members = {
5243
5845
  /**
5244
5846
  * List members (staff accounts) for a market with pagination
@@ -5269,7 +5871,7 @@ function create$c(httpClient) {
5269
5871
  return members;
5270
5872
  }
5271
5873
 
5272
- function create$b(httpClient) {
5874
+ function create$c(httpClient) {
5273
5875
  const payments = {
5274
5876
  /**
5275
5877
  * List all payments for a market with pagination
@@ -5297,7 +5899,7 @@ function create$b(httpClient) {
5297
5899
  return payments;
5298
5900
  }
5299
5901
 
5300
- function create$a(httpClient) {
5902
+ function create$b(httpClient) {
5301
5903
  const payouts = {
5302
5904
  /**
5303
5905
  * List all payouts for a market with pagination
@@ -5336,7 +5938,7 @@ function create$a(httpClient) {
5336
5938
  return payouts;
5337
5939
  }
5338
5940
 
5339
- function create$9(httpClient) {
5941
+ function create$a(httpClient) {
5340
5942
  return {
5341
5943
  list: async (marketId) => {
5342
5944
  return httpClient.get(`/${marketId}/product-codes`);
@@ -5353,7 +5955,7 @@ function create$9(httpClient) {
5353
5955
  };
5354
5956
  }
5355
5957
 
5356
- function create$8(httpClient) {
5958
+ function create$9(httpClient) {
5357
5959
  return {
5358
5960
  get: async (marketId, saleId, options) => {
5359
5961
  return httpClient.get(`/${marketId}/sales/${saleId}`, (options === null || options === void 0 ? void 0 : options.at) ? { at: options.at } : undefined);
@@ -5370,7 +5972,7 @@ function create$8(httpClient) {
5370
5972
  };
5371
5973
  }
5372
5974
 
5373
- function create$7(httpClient) {
5975
+ function create$8(httpClient) {
5374
5976
  return {
5375
5977
  list: async (marketId) => {
5376
5978
  return httpClient.get(`/${marketId}/sale-templates`);
@@ -5390,7 +5992,7 @@ function create$7(httpClient) {
5390
5992
  };
5391
5993
  }
5392
5994
 
5393
- function create$6(httpClient) {
5995
+ function create$7(httpClient) {
5394
5996
  let search = {
5395
5997
  /**
5396
5998
  * Search for documents within a market
@@ -5405,7 +6007,7 @@ function create$6(httpClient) {
5405
6007
  return search;
5406
6008
  }
5407
6009
 
5408
- function create$5(httpClient) {
6010
+ function create$6(httpClient) {
5409
6011
  return {
5410
6012
  get: async (marketId, options) => {
5411
6013
  return httpClient.get(`/${marketId}/settings`, (options === null || options === void 0 ? void 0 : options.at) ? { at: options.at } : undefined);
@@ -5413,7 +6015,7 @@ function create$5(httpClient) {
5413
6015
  };
5414
6016
  }
5415
6017
 
5416
- function create$4(httpClient) {
6018
+ function create$5(httpClient) {
5417
6019
  return {
5418
6020
  list: async (marketId) => {
5419
6021
  return httpClient.get(`/${marketId}/tax_rates`);
@@ -5425,7 +6027,7 @@ function create$4(httpClient) {
5425
6027
  }
5426
6028
 
5427
6029
  // Path: studiojs/src/resources/markets.ts
5428
- function create$3(_) {
6030
+ function create$4(_) {
5429
6031
  const webhooks = {
5430
6032
  /***
5431
6033
  * This is used to construct the webhook event from the request body
@@ -5460,13 +6062,13 @@ function create$3(_) {
5460
6062
  return webhooks;
5461
6063
  }
5462
6064
 
5463
- function create$2(httpClient) {
6065
+ function create$3(httpClient) {
5464
6066
  return {
5465
6067
  lookup: async (marketId, cph) => httpClient.get(`/${marketId}/cph`, { cph }),
5466
6068
  };
5467
6069
  }
5468
6070
 
5469
- function create$1(httpClient) {
6071
+ function create$2(httpClient) {
5470
6072
  return {
5471
6073
  list: async (marketId, customerId, params) => {
5472
6074
  const query = {};
@@ -5491,7 +6093,7 @@ function create$1(httpClient) {
5491
6093
  };
5492
6094
  }
5493
6095
 
5494
- function create(httpClient) {
6096
+ function create$1(httpClient) {
5495
6097
  let ledger = {
5496
6098
  /**
5497
6099
  * Get the current balance for a ledger account
@@ -5552,33 +6154,42 @@ function create(httpClient) {
5552
6154
  return ledger;
5553
6155
  }
5554
6156
 
6157
+ function create(httpClient) {
6158
+ return {
6159
+ sendSMS: async (marketId, data) => httpClient.post(`/${marketId}/sms/send`, data),
6160
+ getSMS: async (marketId, smsId) => httpClient.get(`/${marketId}/sms/${smsId}`),
6161
+ };
6162
+ }
6163
+
5555
6164
  function resources(httpClient) {
5556
6165
  return {
5557
- activity: create$n(httpClient),
5558
- markets: create$d(httpClient),
5559
- members: create$c(httpClient),
5560
- sales: create$8(httpClient),
5561
- lots: create$e(httpClient),
5562
- lotitems: create$f(httpClient),
5563
- carts: create$l(httpClient),
5564
- cph: create$2(httpClient),
5565
- webhooks: create$3(),
5566
- actions: create$o(),
5567
- bidderApplications: create$j(httpClient),
5568
- settings: create$5(httpClient),
5569
- adjustments: create$m(httpClient),
5570
- extras: create$k(httpClient),
5571
- productCodes: create$9(httpClient),
5572
- saleTemplates: create$7(httpClient),
5573
- taxRates: create$4(httpClient),
5574
- customers: create$i(httpClient),
5575
- invoices: create$g(httpClient),
5576
- payments: create$b(httpClient),
5577
- payouts: create$a(httpClient),
5578
- search: create$6(httpClient),
5579
- files: create$h(),
5580
- contacts: create$1(httpClient),
5581
- ledger: create(httpClient),
6166
+ activity: create$p(httpClient),
6167
+ markets: create$e(httpClient),
6168
+ members: create$d(httpClient),
6169
+ sales: create$9(httpClient),
6170
+ lots: create$f(httpClient),
6171
+ lotitems: create$g(httpClient),
6172
+ carts: create$n(httpClient),
6173
+ cph: create$3(httpClient),
6174
+ webhooks: create$4(),
6175
+ actions: create$q(),
6176
+ bidderApplications: create$l(httpClient),
6177
+ settings: create$6(httpClient),
6178
+ adjustments: create$o(httpClient),
6179
+ extras: create$m(httpClient),
6180
+ productCodes: create$a(httpClient),
6181
+ saleTemplates: create$8(httpClient),
6182
+ taxRates: create$5(httpClient),
6183
+ customers: create$k(httpClient),
6184
+ customerLists: create$j(httpClient),
6185
+ invoices: create$h(httpClient),
6186
+ payments: create$c(httpClient),
6187
+ payouts: create$b(httpClient),
6188
+ search: create$7(httpClient),
6189
+ files: create$i(),
6190
+ contacts: create$2(httpClient),
6191
+ ledger: create$1(httpClient),
6192
+ sms: create(httpClient),
5582
6193
  };
5583
6194
  }
5584
6195
 
@@ -5668,6 +6279,10 @@ const supportedWebhookEvents = [
5668
6279
  "member.created",
5669
6280
  "member.updated",
5670
6281
  "member.deleted",
6282
+ // sms tasks
6283
+ "sms-task.created",
6284
+ "sms-task.updated",
6285
+ "sms-task.deleted",
5671
6286
  ];
5672
6287
 
5673
6288
  var types = /*#__PURE__*/Object.freeze({
@@ -5938,8 +6553,8 @@ class CattlePassport {
5938
6553
  }
5939
6554
  static parse(code) {
5940
6555
  let raw = code;
5941
- // Strip ASCII control characters (GS, CR, etc.) that barcode scanners may append
5942
- let trimmed = code.replace(/[\x00-\x1F\x7F]/g, "").trim();
6556
+ // Normalise: uppercase (some scanners send lowercase) and strip control characters
6557
+ let trimmed = code.toUpperCase().replace(/[\x00-\x1F\x7F]/g, "").trim();
5943
6558
  if (trimmed.length < CattlePassport.BARCODE_MIN_LENGTH ||
5944
6559
  trimmed.length > CattlePassport.BARCODE_MAX_LENGTH)
5945
6560
  return null;