zone4code-sdk 1.0.10 → 1.0.11
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.cjs +543 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +407 -6
- package/dist/index.d.ts +407 -6
- package/dist/index.js +540 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -59,7 +59,7 @@ var AuthClient = class _AuthClient {
|
|
|
59
59
|
this.storage = storage;
|
|
60
60
|
this.storageKey = storageKey;
|
|
61
61
|
this.refreshStorageKey = refreshStorageKey;
|
|
62
|
-
this.fetchFn = options.fetchFn || (
|
|
62
|
+
this.fetchFn = options.fetchFn || ((...args) => fetch(...args));
|
|
63
63
|
this.autoRefresh = options.autoRefresh !== void 0 ? options.autoRefresh : true;
|
|
64
64
|
this.tokenExpiryBuffer = options.tokenExpiryBuffer !== void 0 ? options.tokenExpiryBuffer : 30;
|
|
65
65
|
this.onSessionExpiredCallback = options.onSessionExpired;
|
|
@@ -513,6 +513,501 @@ var AuthClient = class _AuthClient {
|
|
|
513
513
|
}
|
|
514
514
|
};
|
|
515
515
|
|
|
516
|
+
// src/commerce.ts
|
|
517
|
+
var CommerceClient = class {
|
|
518
|
+
gatewayUrl;
|
|
519
|
+
tenantId;
|
|
520
|
+
fetchWithAuth;
|
|
521
|
+
fetchFn;
|
|
522
|
+
constructor(options) {
|
|
523
|
+
this.gatewayUrl = options.gatewayUrl.replace(/\/+$/, "");
|
|
524
|
+
this.tenantId = options.tenantId;
|
|
525
|
+
this.fetchWithAuth = options.fetchWithAuth;
|
|
526
|
+
this.fetchFn = options.fetchFn;
|
|
527
|
+
}
|
|
528
|
+
// --- Products ---
|
|
529
|
+
/**
|
|
530
|
+
* List catalog products with search, category filtering, and pagination
|
|
531
|
+
*/
|
|
532
|
+
async getProducts(params) {
|
|
533
|
+
const query = new URLSearchParams();
|
|
534
|
+
if (params?.search) query.set("search", params.search);
|
|
535
|
+
if (params?.category) query.set("category", params.category);
|
|
536
|
+
if (params?.status) query.set("status", params.status);
|
|
537
|
+
if (params?.limit) query.set("limit", String(params.limit));
|
|
538
|
+
if (params?.page) query.set("page", String(params.page));
|
|
539
|
+
if (params?.orderBy) query.set("orderBy", params.orderBy);
|
|
540
|
+
if (params?.sortedBy) query.set("sortedBy", params.sortedBy);
|
|
541
|
+
if (params?.language) query.set("language", params.language);
|
|
542
|
+
if (params?.type) query.set("type", params.type);
|
|
543
|
+
const qs = query.toString();
|
|
544
|
+
const url = `${this.gatewayUrl}/commerce/products${qs ? `?${qs}` : ""}`;
|
|
545
|
+
const res = await this.fetchFn(url, {
|
|
546
|
+
method: "GET",
|
|
547
|
+
headers: { "x-tenant-id": this.tenantId }
|
|
548
|
+
});
|
|
549
|
+
if (!res.ok) {
|
|
550
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
551
|
+
throw new Error(err.message || `Failed to fetch products with HTTP ${res.status}`);
|
|
552
|
+
}
|
|
553
|
+
const data = await res.json();
|
|
554
|
+
return Array.isArray(data) ? { data } : data;
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Get a single product by slug or ID
|
|
558
|
+
*/
|
|
559
|
+
async getProductBySlug(slug, language) {
|
|
560
|
+
const query = language ? `?language=${encodeURIComponent(language)}` : "";
|
|
561
|
+
const url = `${this.gatewayUrl}/commerce/products/${encodeURIComponent(slug)}${query}`;
|
|
562
|
+
const res = await this.fetchFn(url, {
|
|
563
|
+
method: "GET",
|
|
564
|
+
headers: { "x-tenant-id": this.tenantId }
|
|
565
|
+
});
|
|
566
|
+
if (!res.ok) {
|
|
567
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
568
|
+
throw new Error(err.message || `Product not found with HTTP ${res.status}`);
|
|
569
|
+
}
|
|
570
|
+
return res.json();
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* Create a new product (requires merchant/admin authentication)
|
|
574
|
+
*/
|
|
575
|
+
async createProduct(product) {
|
|
576
|
+
const url = `${this.gatewayUrl}/commerce/products`;
|
|
577
|
+
const res = await this.fetchWithAuth(url, {
|
|
578
|
+
method: "POST",
|
|
579
|
+
body: JSON.stringify(product),
|
|
580
|
+
headers: {
|
|
581
|
+
"Content-Type": "application/json",
|
|
582
|
+
"x-tenant-id": this.tenantId
|
|
583
|
+
}
|
|
584
|
+
});
|
|
585
|
+
if (!res.ok) {
|
|
586
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
587
|
+
throw new Error(err.message || `Failed to create product with HTTP ${res.status}`);
|
|
588
|
+
}
|
|
589
|
+
return res.json();
|
|
590
|
+
}
|
|
591
|
+
// --- Categories ---
|
|
592
|
+
/**
|
|
593
|
+
* List store categories
|
|
594
|
+
*/
|
|
595
|
+
async getCategories(params) {
|
|
596
|
+
const query = new URLSearchParams();
|
|
597
|
+
if (params?.parent !== void 0) query.set("parent", String(params.parent));
|
|
598
|
+
if (params?.limit) query.set("limit", String(params.limit));
|
|
599
|
+
if (params?.page) query.set("page", String(params.page));
|
|
600
|
+
const qs = query.toString();
|
|
601
|
+
const url = `${this.gatewayUrl}/commerce/categories${qs ? `?${qs}` : ""}`;
|
|
602
|
+
const res = await this.fetchFn(url, {
|
|
603
|
+
method: "GET",
|
|
604
|
+
headers: { "x-tenant-id": this.tenantId }
|
|
605
|
+
});
|
|
606
|
+
if (!res.ok) {
|
|
607
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
608
|
+
throw new Error(err.message || `Failed to fetch categories with HTTP ${res.status}`);
|
|
609
|
+
}
|
|
610
|
+
const data = await res.json();
|
|
611
|
+
return Array.isArray(data) ? data : data.data || [];
|
|
612
|
+
}
|
|
613
|
+
// --- Orders & Checkout ---
|
|
614
|
+
/**
|
|
615
|
+
* Create a new customer checkout order
|
|
616
|
+
*/
|
|
617
|
+
async createOrder(payload) {
|
|
618
|
+
const url = `${this.gatewayUrl}/commerce/orders`;
|
|
619
|
+
const res = await this.fetchWithAuth(url, {
|
|
620
|
+
method: "POST",
|
|
621
|
+
body: JSON.stringify(payload),
|
|
622
|
+
headers: {
|
|
623
|
+
"Content-Type": "application/json",
|
|
624
|
+
"x-tenant-id": this.tenantId
|
|
625
|
+
}
|
|
626
|
+
});
|
|
627
|
+
if (!res.ok) {
|
|
628
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
629
|
+
throw new Error(err.message || `Failed to create order with HTTP ${res.status}`);
|
|
630
|
+
}
|
|
631
|
+
return res.json();
|
|
632
|
+
}
|
|
633
|
+
/**
|
|
634
|
+
* Verify checkout taxes, shipping fees, and product availability
|
|
635
|
+
*/
|
|
636
|
+
async verifyCheckout(payload) {
|
|
637
|
+
const url = `${this.gatewayUrl}/commerce/orders/checkout/verify`;
|
|
638
|
+
const res = await this.fetchWithAuth(url, {
|
|
639
|
+
method: "POST",
|
|
640
|
+
body: JSON.stringify(payload),
|
|
641
|
+
headers: {
|
|
642
|
+
"Content-Type": "application/json",
|
|
643
|
+
"x-tenant-id": this.tenantId
|
|
644
|
+
}
|
|
645
|
+
});
|
|
646
|
+
if (!res.ok) {
|
|
647
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
648
|
+
throw new Error(err.message || `Checkout verification failed with HTTP ${res.status}`);
|
|
649
|
+
}
|
|
650
|
+
return res.json();
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* Track order by tracking number
|
|
654
|
+
*/
|
|
655
|
+
async trackOrder(trackingNumber) {
|
|
656
|
+
const url = `${this.gatewayUrl}/commerce/orders/tracking/${encodeURIComponent(trackingNumber)}`;
|
|
657
|
+
const res = await this.fetchFn(url, {
|
|
658
|
+
method: "GET",
|
|
659
|
+
headers: { "x-tenant-id": this.tenantId }
|
|
660
|
+
});
|
|
661
|
+
if (!res.ok) {
|
|
662
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
663
|
+
throw new Error(err.message || `Order tracking failed with HTTP ${res.status}`);
|
|
664
|
+
}
|
|
665
|
+
return res.json();
|
|
666
|
+
}
|
|
667
|
+
/**
|
|
668
|
+
* List customer orders (authenticated)
|
|
669
|
+
*/
|
|
670
|
+
async getOrders(params) {
|
|
671
|
+
const query = new URLSearchParams();
|
|
672
|
+
if (params?.limit) query.set("limit", String(params.limit));
|
|
673
|
+
if (params?.page) query.set("page", String(params.page));
|
|
674
|
+
if (params?.tracking_number) query.set("tracking_number", params.tracking_number);
|
|
675
|
+
const qs = query.toString();
|
|
676
|
+
const url = `${this.gatewayUrl}/commerce/orders${qs ? `?${qs}` : ""}`;
|
|
677
|
+
const res = await this.fetchWithAuth(url, {
|
|
678
|
+
method: "GET",
|
|
679
|
+
headers: { "x-tenant-id": this.tenantId }
|
|
680
|
+
});
|
|
681
|
+
if (!res.ok) {
|
|
682
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
683
|
+
throw new Error(err.message || `Failed to fetch orders with HTTP ${res.status}`);
|
|
684
|
+
}
|
|
685
|
+
const data = await res.json();
|
|
686
|
+
return Array.isArray(data) ? { data } : data;
|
|
687
|
+
}
|
|
688
|
+
// --- Coupons ---
|
|
689
|
+
/**
|
|
690
|
+
* Verify and calculate discount for a promo coupon code
|
|
691
|
+
*/
|
|
692
|
+
async verifyCoupon(payload) {
|
|
693
|
+
const url = `${this.gatewayUrl}/commerce/coupons/verify`;
|
|
694
|
+
const res = await this.fetchWithAuth(url, {
|
|
695
|
+
method: "POST",
|
|
696
|
+
body: JSON.stringify(payload),
|
|
697
|
+
headers: {
|
|
698
|
+
"Content-Type": "application/json",
|
|
699
|
+
"x-tenant-id": this.tenantId
|
|
700
|
+
}
|
|
701
|
+
});
|
|
702
|
+
if (!res.ok) {
|
|
703
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
704
|
+
throw new Error(err.message || `Coupon verification failed with HTTP ${res.status}`);
|
|
705
|
+
}
|
|
706
|
+
return res.json();
|
|
707
|
+
}
|
|
708
|
+
// --- Settings ---
|
|
709
|
+
/**
|
|
710
|
+
* Get store and commerce configuration settings
|
|
711
|
+
*/
|
|
712
|
+
async getSettings() {
|
|
713
|
+
const url = `${this.gatewayUrl}/commerce/settings`;
|
|
714
|
+
const res = await this.fetchFn(url, {
|
|
715
|
+
method: "GET",
|
|
716
|
+
headers: { "x-tenant-id": this.tenantId }
|
|
717
|
+
});
|
|
718
|
+
if (!res.ok) {
|
|
719
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
720
|
+
throw new Error(err.message || `Failed to fetch settings with HTTP ${res.status}`);
|
|
721
|
+
}
|
|
722
|
+
return res.json();
|
|
723
|
+
}
|
|
724
|
+
};
|
|
725
|
+
|
|
726
|
+
// src/doc.ts
|
|
727
|
+
var DocClient = class {
|
|
728
|
+
gatewayUrl;
|
|
729
|
+
tenantId;
|
|
730
|
+
fetchWithAuth;
|
|
731
|
+
fetchFn;
|
|
732
|
+
constructor(options) {
|
|
733
|
+
this.gatewayUrl = options.gatewayUrl.replace(/\/+$/, "");
|
|
734
|
+
this.tenantId = options.tenantId;
|
|
735
|
+
this.fetchWithAuth = options.fetchWithAuth;
|
|
736
|
+
this.fetchFn = options.fetchFn;
|
|
737
|
+
}
|
|
738
|
+
/**
|
|
739
|
+
* Upload one or more files to object storage (S3/MinIO) with automated thumbnailing
|
|
740
|
+
*/
|
|
741
|
+
async upload(files) {
|
|
742
|
+
const url = `${this.gatewayUrl}/doc/upload`;
|
|
743
|
+
let body;
|
|
744
|
+
if (typeof FormData !== "undefined" && files instanceof FormData) {
|
|
745
|
+
body = files;
|
|
746
|
+
} else {
|
|
747
|
+
body = new FormData();
|
|
748
|
+
if (Array.isArray(files)) {
|
|
749
|
+
for (const file of files) {
|
|
750
|
+
body.append("files", file);
|
|
751
|
+
}
|
|
752
|
+
} else {
|
|
753
|
+
body.append("files", files);
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
const res = await this.fetchWithAuth(url, {
|
|
757
|
+
method: "POST",
|
|
758
|
+
body,
|
|
759
|
+
headers: {
|
|
760
|
+
"x-tenant-id": this.tenantId
|
|
761
|
+
}
|
|
762
|
+
});
|
|
763
|
+
if (!res.ok) {
|
|
764
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
765
|
+
throw new Error(err.message || `File upload failed with HTTP ${res.status}`);
|
|
766
|
+
}
|
|
767
|
+
return res.json();
|
|
768
|
+
}
|
|
769
|
+
/**
|
|
770
|
+
* List documents with optional folder filtering and pagination
|
|
771
|
+
*/
|
|
772
|
+
async list(params) {
|
|
773
|
+
const query = new URLSearchParams();
|
|
774
|
+
if (params?.folderId) query.set("folderId", params.folderId);
|
|
775
|
+
if (params?.page) query.set("page", String(params.page));
|
|
776
|
+
if (params?.limit) query.set("limit", String(params.limit));
|
|
777
|
+
const qs = query.toString();
|
|
778
|
+
const url = `${this.gatewayUrl}/doc/document${qs ? `?${qs}` : ""}`;
|
|
779
|
+
const res = await this.fetchWithAuth(url, {
|
|
780
|
+
method: "GET",
|
|
781
|
+
headers: { "x-tenant-id": this.tenantId }
|
|
782
|
+
});
|
|
783
|
+
if (!res.ok) {
|
|
784
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
785
|
+
throw new Error(err.message || `Failed to fetch documents with HTTP ${res.status}`);
|
|
786
|
+
}
|
|
787
|
+
const data = await res.json();
|
|
788
|
+
return Array.isArray(data) ? data : data.documents || data.items || [];
|
|
789
|
+
}
|
|
790
|
+
/**
|
|
791
|
+
* Get a single document record by ID
|
|
792
|
+
*/
|
|
793
|
+
async get(id) {
|
|
794
|
+
const url = `${this.gatewayUrl}/doc/document/${encodeURIComponent(id)}`;
|
|
795
|
+
const res = await this.fetchWithAuth(url, {
|
|
796
|
+
method: "GET",
|
|
797
|
+
headers: { "x-tenant-id": this.tenantId }
|
|
798
|
+
});
|
|
799
|
+
if (!res.ok) {
|
|
800
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
801
|
+
throw new Error(err.message || `Document not found with HTTP ${res.status}`);
|
|
802
|
+
}
|
|
803
|
+
return res.json();
|
|
804
|
+
}
|
|
805
|
+
/**
|
|
806
|
+
* Delete a document by ID
|
|
807
|
+
*/
|
|
808
|
+
async delete(id) {
|
|
809
|
+
const url = `${this.gatewayUrl}/doc/document/${encodeURIComponent(id)}`;
|
|
810
|
+
const res = await this.fetchWithAuth(url, {
|
|
811
|
+
method: "DELETE",
|
|
812
|
+
headers: { "x-tenant-id": this.tenantId }
|
|
813
|
+
});
|
|
814
|
+
if (!res.ok) {
|
|
815
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
816
|
+
throw new Error(err.message || `Failed to delete document with HTTP ${res.status}`);
|
|
817
|
+
}
|
|
818
|
+
return { success: true };
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
* List document folders
|
|
822
|
+
*/
|
|
823
|
+
async listFolders() {
|
|
824
|
+
const url = `${this.gatewayUrl}/doc/folder`;
|
|
825
|
+
const res = await this.fetchWithAuth(url, {
|
|
826
|
+
method: "GET",
|
|
827
|
+
headers: { "x-tenant-id": this.tenantId }
|
|
828
|
+
});
|
|
829
|
+
if (!res.ok) {
|
|
830
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
831
|
+
throw new Error(err.message || `Failed to fetch folders with HTTP ${res.status}`);
|
|
832
|
+
}
|
|
833
|
+
const data = await res.json();
|
|
834
|
+
return Array.isArray(data) ? data : data.folders || [];
|
|
835
|
+
}
|
|
836
|
+
/**
|
|
837
|
+
* Create a new folder for organizing documents
|
|
838
|
+
*/
|
|
839
|
+
async createFolder(name, parentId) {
|
|
840
|
+
const url = `${this.gatewayUrl}/doc/folder`;
|
|
841
|
+
const res = await this.fetchWithAuth(url, {
|
|
842
|
+
method: "POST",
|
|
843
|
+
body: JSON.stringify({ name, parentId: parentId || null }),
|
|
844
|
+
headers: {
|
|
845
|
+
"Content-Type": "application/json",
|
|
846
|
+
"x-tenant-id": this.tenantId
|
|
847
|
+
}
|
|
848
|
+
});
|
|
849
|
+
if (!res.ok) {
|
|
850
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
851
|
+
throw new Error(err.message || `Failed to create folder with HTTP ${res.status}`);
|
|
852
|
+
}
|
|
853
|
+
return res.json();
|
|
854
|
+
}
|
|
855
|
+
};
|
|
856
|
+
|
|
857
|
+
// src/notification.ts
|
|
858
|
+
var NotificationClient = class {
|
|
859
|
+
gatewayUrl;
|
|
860
|
+
tenantId;
|
|
861
|
+
fetchWithAuth;
|
|
862
|
+
fetchFn;
|
|
863
|
+
constructor(options) {
|
|
864
|
+
this.gatewayUrl = options.gatewayUrl.replace(/\/+$/, "");
|
|
865
|
+
this.tenantId = options.tenantId;
|
|
866
|
+
this.fetchWithAuth = options.fetchWithAuth;
|
|
867
|
+
this.fetchFn = options.fetchFn;
|
|
868
|
+
}
|
|
869
|
+
/**
|
|
870
|
+
* Send an SMS message via configured SMS gateways (Twilio / SMS API)
|
|
871
|
+
*/
|
|
872
|
+
async sendSms(payload) {
|
|
873
|
+
const url = `${this.gatewayUrl}/notification/sms`;
|
|
874
|
+
const res = await this.fetchWithAuth(url, {
|
|
875
|
+
method: "POST",
|
|
876
|
+
body: JSON.stringify({
|
|
877
|
+
to: payload.to,
|
|
878
|
+
body: payload.message,
|
|
879
|
+
from: payload.from,
|
|
880
|
+
provider: payload.provider
|
|
881
|
+
}),
|
|
882
|
+
headers: {
|
|
883
|
+
"Content-Type": "application/json",
|
|
884
|
+
"x-tenant-id": this.tenantId
|
|
885
|
+
}
|
|
886
|
+
});
|
|
887
|
+
if (!res.ok) {
|
|
888
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
889
|
+
throw new Error(err.message || `Failed to send SMS with HTTP ${res.status}`);
|
|
890
|
+
}
|
|
891
|
+
const data = await res.json();
|
|
892
|
+
return {
|
|
893
|
+
success: true,
|
|
894
|
+
messageId: data.id || data.messageId || data.sid,
|
|
895
|
+
status: data.status || "sent"
|
|
896
|
+
};
|
|
897
|
+
}
|
|
898
|
+
/**
|
|
899
|
+
* Send an email or template email
|
|
900
|
+
*/
|
|
901
|
+
async sendEmail(payload) {
|
|
902
|
+
const shopSlug = payload.shopSlug || this.tenantId;
|
|
903
|
+
const localeCode = payload.localeCode || "en";
|
|
904
|
+
const url = `${this.gatewayUrl}/notification/${encodeURIComponent(shopSlug)}/sendEmail/${encodeURIComponent(localeCode)}`;
|
|
905
|
+
const res = await this.fetchWithAuth(url, {
|
|
906
|
+
method: "POST",
|
|
907
|
+
body: JSON.stringify({
|
|
908
|
+
to: Array.isArray(payload.to) ? payload.to.join(",") : payload.to,
|
|
909
|
+
subject: payload.subject,
|
|
910
|
+
html: payload.html,
|
|
911
|
+
text: payload.text,
|
|
912
|
+
templateId: payload.templateId,
|
|
913
|
+
templateData: payload.templateData
|
|
914
|
+
}),
|
|
915
|
+
headers: {
|
|
916
|
+
"Content-Type": "application/json",
|
|
917
|
+
"x-tenant-id": this.tenantId
|
|
918
|
+
}
|
|
919
|
+
});
|
|
920
|
+
if (!res.ok) {
|
|
921
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
922
|
+
throw new Error(err.message || `Failed to send Email with HTTP ${res.status}`);
|
|
923
|
+
}
|
|
924
|
+
const data = await res.json();
|
|
925
|
+
return {
|
|
926
|
+
success: true,
|
|
927
|
+
messageId: data.id || data.messageId,
|
|
928
|
+
status: data.status || "sent"
|
|
929
|
+
};
|
|
930
|
+
}
|
|
931
|
+
/**
|
|
932
|
+
* Send Firebase Cloud Messaging (FCM) Push Notification
|
|
933
|
+
*/
|
|
934
|
+
async sendPush(payload) {
|
|
935
|
+
const url = `${this.gatewayUrl}/notification/firebase_message`;
|
|
936
|
+
const res = await this.fetchWithAuth(url, {
|
|
937
|
+
method: "POST",
|
|
938
|
+
body: JSON.stringify({
|
|
939
|
+
token: payload.token,
|
|
940
|
+
tokens: payload.tokens,
|
|
941
|
+
topic: payload.topic,
|
|
942
|
+
notification: {
|
|
943
|
+
title: payload.title,
|
|
944
|
+
body: payload.body
|
|
945
|
+
},
|
|
946
|
+
data: payload.data || {}
|
|
947
|
+
}),
|
|
948
|
+
headers: {
|
|
949
|
+
"Content-Type": "application/json",
|
|
950
|
+
"x-tenant-id": this.tenantId
|
|
951
|
+
}
|
|
952
|
+
});
|
|
953
|
+
if (!res.ok) {
|
|
954
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
955
|
+
throw new Error(err.message || `Failed to send Push Notification with HTTP ${res.status}`);
|
|
956
|
+
}
|
|
957
|
+
const data = await res.json();
|
|
958
|
+
return {
|
|
959
|
+
success: true,
|
|
960
|
+
messageId: data.messageId || data.id,
|
|
961
|
+
status: "sent"
|
|
962
|
+
};
|
|
963
|
+
}
|
|
964
|
+
/**
|
|
965
|
+
* Register a device push token for push notifications
|
|
966
|
+
*/
|
|
967
|
+
async registerPushToken(payload) {
|
|
968
|
+
const url = `${this.gatewayUrl}/notification/firebase_registration`;
|
|
969
|
+
const res = await this.fetchWithAuth(url, {
|
|
970
|
+
method: "POST",
|
|
971
|
+
body: JSON.stringify({
|
|
972
|
+
token: payload.token,
|
|
973
|
+
userId: payload.userId,
|
|
974
|
+
platform: payload.platform || "web",
|
|
975
|
+
metadata: payload.metadata || {}
|
|
976
|
+
}),
|
|
977
|
+
headers: {
|
|
978
|
+
"Content-Type": "application/json",
|
|
979
|
+
"x-tenant-id": this.tenantId
|
|
980
|
+
}
|
|
981
|
+
});
|
|
982
|
+
if (!res.ok) {
|
|
983
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
984
|
+
throw new Error(err.message || `Failed to register push token with HTTP ${res.status}`);
|
|
985
|
+
}
|
|
986
|
+
const data = await res.json();
|
|
987
|
+
return { success: true, id: data.id };
|
|
988
|
+
}
|
|
989
|
+
/**
|
|
990
|
+
* Get recent in-app notifications
|
|
991
|
+
*/
|
|
992
|
+
async list(params) {
|
|
993
|
+
const query = new URLSearchParams();
|
|
994
|
+
if (params?.page) query.set("page", String(params.page));
|
|
995
|
+
if (params?.limit) query.set("limit", String(params.limit));
|
|
996
|
+
const qs = query.toString();
|
|
997
|
+
const url = `${this.gatewayUrl}/notification/notification${qs ? `?${qs}` : ""}`;
|
|
998
|
+
const res = await this.fetchWithAuth(url, {
|
|
999
|
+
method: "GET",
|
|
1000
|
+
headers: { "x-tenant-id": this.tenantId }
|
|
1001
|
+
});
|
|
1002
|
+
if (!res.ok) {
|
|
1003
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
1004
|
+
throw new Error(err.message || `Failed to fetch notifications with HTTP ${res.status}`);
|
|
1005
|
+
}
|
|
1006
|
+
const data = await res.json();
|
|
1007
|
+
return Array.isArray(data) ? data : data.notifications || data.items || [];
|
|
1008
|
+
}
|
|
1009
|
+
};
|
|
1010
|
+
|
|
516
1011
|
// src/query-builder.ts
|
|
517
1012
|
var EntityQueryBuilder = class {
|
|
518
1013
|
gatewayUrl;
|
|
@@ -527,7 +1022,7 @@ var EntityQueryBuilder = class {
|
|
|
527
1022
|
this.tenantId = options.tenantId;
|
|
528
1023
|
this.typeName = options.typeName;
|
|
529
1024
|
this.getToken = options.getToken || (() => null);
|
|
530
|
-
this.fetchFn = options.fetchFn || (
|
|
1025
|
+
this.fetchFn = options.fetchFn || ((...args) => fetch(...args));
|
|
531
1026
|
this.fetchWithAuth = options.fetchWithAuth;
|
|
532
1027
|
if (options.defaultLanguage) {
|
|
533
1028
|
const langVal = typeof options.defaultLanguage === "function" ? options.defaultLanguage() : options.defaultLanguage;
|
|
@@ -956,7 +1451,7 @@ var SchemaClient = class {
|
|
|
956
1451
|
this.gatewayUrl = options.gatewayUrl.replace(/\/+$/, "");
|
|
957
1452
|
this.tenantId = options.tenantId;
|
|
958
1453
|
this.getToken = options.getToken || (() => null);
|
|
959
|
-
this.fetchFn = options.fetchFn || (
|
|
1454
|
+
this.fetchFn = options.fetchFn || ((...args) => fetch(...args));
|
|
960
1455
|
this.fetchWithAuth = options.fetchWithAuth;
|
|
961
1456
|
}
|
|
962
1457
|
getHeaders() {
|
|
@@ -1014,20 +1509,24 @@ var Zone4CodeClient = class {
|
|
|
1014
1509
|
tenantId;
|
|
1015
1510
|
auth;
|
|
1016
1511
|
schema;
|
|
1512
|
+
doc;
|
|
1513
|
+
notification;
|
|
1514
|
+
commerce;
|
|
1017
1515
|
storage;
|
|
1018
1516
|
fetchFn;
|
|
1019
1517
|
currentLanguage = null;
|
|
1020
|
-
constructor(config) {
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
this.
|
|
1518
|
+
constructor(config = {}) {
|
|
1519
|
+
const globalObj = typeof globalThis !== "undefined" ? globalThis : {};
|
|
1520
|
+
const procEnv = globalObj.process?.env || {};
|
|
1521
|
+
const winEnv = globalObj.window?.env || globalObj.__ZONE4BUILD_ENV__ || {};
|
|
1522
|
+
const envGateway = procEnv.ZONE4BUILD_GATEWAY_URL || procEnv.VITE_ZONE4BUILD_GATEWAY_URL || winEnv.ZONE4BUILD_GATEWAY_URL || globalObj.__ZONE4BUILD_GATEWAY_URL__;
|
|
1523
|
+
const resolvedGatewayUrl = config.gatewayUrl || envGateway || "https://api.zone4build.com";
|
|
1524
|
+
const envTenant = procEnv.ZONE4BUILD_WORKSPACE_ID || procEnv.VITE_ZONE4BUILD_WORKSPACE_ID || winEnv.ZONE4BUILD_WORKSPACE_ID || globalObj.__ZONE4BUILD_WORKSPACE_ID__;
|
|
1525
|
+
const resolvedTenantId = config.tenantId || envTenant || "default";
|
|
1526
|
+
this.gatewayUrl = resolvedGatewayUrl.replace(/\/+$/, "");
|
|
1527
|
+
this.tenantId = resolvedTenantId;
|
|
1029
1528
|
this.storage = config.storage || getDefaultStorage();
|
|
1030
|
-
this.fetchFn = config.fetch || (
|
|
1529
|
+
this.fetchFn = config.fetch || ((...args) => fetch(...args));
|
|
1031
1530
|
this.currentLanguage = config.defaultLanguage !== void 0 ? config.defaultLanguage : "en";
|
|
1032
1531
|
this.auth = new AuthClient({
|
|
1033
1532
|
gatewayUrl: this.gatewayUrl,
|
|
@@ -1048,7 +1547,32 @@ var Zone4CodeClient = class {
|
|
|
1048
1547
|
fetchFn: this.fetchFn,
|
|
1049
1548
|
fetchWithAuth: (url, init) => this.auth.fetchWithAuth(url, init)
|
|
1050
1549
|
});
|
|
1550
|
+
this.doc = new DocClient({
|
|
1551
|
+
gatewayUrl: this.gatewayUrl,
|
|
1552
|
+
tenantId: this.tenantId,
|
|
1553
|
+
fetchWithAuth: (url, init) => this.auth.fetchWithAuth(url, init),
|
|
1554
|
+
fetchFn: this.fetchFn
|
|
1555
|
+
});
|
|
1556
|
+
this.notification = new NotificationClient({
|
|
1557
|
+
gatewayUrl: this.gatewayUrl,
|
|
1558
|
+
tenantId: this.tenantId,
|
|
1559
|
+
fetchWithAuth: (url, init) => this.auth.fetchWithAuth(url, init),
|
|
1560
|
+
fetchFn: this.fetchFn
|
|
1561
|
+
});
|
|
1562
|
+
this.commerce = new CommerceClient({
|
|
1563
|
+
gatewayUrl: this.gatewayUrl,
|
|
1564
|
+
tenantId: this.tenantId,
|
|
1565
|
+
fetchWithAuth: (url, init) => this.auth.fetchWithAuth(url, init),
|
|
1566
|
+
fetchFn: this.fetchFn
|
|
1567
|
+
});
|
|
1568
|
+
this.generic = {
|
|
1569
|
+
from: (typeName) => this.from(typeName),
|
|
1570
|
+
entities: (typeName) => this.from(typeName),
|
|
1571
|
+
schema: this.schema,
|
|
1572
|
+
getMe: () => this.getMe()
|
|
1573
|
+
};
|
|
1051
1574
|
}
|
|
1575
|
+
generic;
|
|
1052
1576
|
/**
|
|
1053
1577
|
* Set the active default language for API requests (e.g., 'en', 'fr', 'ar', or '*' for raw)
|
|
1054
1578
|
*/
|
|
@@ -1115,8 +1639,11 @@ function createClient(config) {
|
|
|
1115
1639
|
}
|
|
1116
1640
|
export {
|
|
1117
1641
|
AuthClient,
|
|
1642
|
+
CommerceClient,
|
|
1643
|
+
DocClient,
|
|
1118
1644
|
EntityQueryBuilder,
|
|
1119
1645
|
MemoryStorage,
|
|
1646
|
+
NotificationClient,
|
|
1120
1647
|
SchemaClient,
|
|
1121
1648
|
Zone4CodeClient,
|
|
1122
1649
|
createClient,
|