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.cjs
CHANGED
|
@@ -21,8 +21,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
AuthClient: () => AuthClient,
|
|
24
|
+
CommerceClient: () => CommerceClient,
|
|
25
|
+
DocClient: () => DocClient,
|
|
24
26
|
EntityQueryBuilder: () => EntityQueryBuilder,
|
|
25
27
|
MemoryStorage: () => MemoryStorage,
|
|
28
|
+
NotificationClient: () => NotificationClient,
|
|
26
29
|
SchemaClient: () => SchemaClient,
|
|
27
30
|
Zone4CodeClient: () => Zone4CodeClient,
|
|
28
31
|
createClient: () => createClient,
|
|
@@ -92,7 +95,7 @@ var AuthClient = class _AuthClient {
|
|
|
92
95
|
this.storage = storage;
|
|
93
96
|
this.storageKey = storageKey;
|
|
94
97
|
this.refreshStorageKey = refreshStorageKey;
|
|
95
|
-
this.fetchFn = options.fetchFn || (
|
|
98
|
+
this.fetchFn = options.fetchFn || ((...args) => fetch(...args));
|
|
96
99
|
this.autoRefresh = options.autoRefresh !== void 0 ? options.autoRefresh : true;
|
|
97
100
|
this.tokenExpiryBuffer = options.tokenExpiryBuffer !== void 0 ? options.tokenExpiryBuffer : 30;
|
|
98
101
|
this.onSessionExpiredCallback = options.onSessionExpired;
|
|
@@ -546,6 +549,501 @@ var AuthClient = class _AuthClient {
|
|
|
546
549
|
}
|
|
547
550
|
};
|
|
548
551
|
|
|
552
|
+
// src/commerce.ts
|
|
553
|
+
var CommerceClient = class {
|
|
554
|
+
gatewayUrl;
|
|
555
|
+
tenantId;
|
|
556
|
+
fetchWithAuth;
|
|
557
|
+
fetchFn;
|
|
558
|
+
constructor(options) {
|
|
559
|
+
this.gatewayUrl = options.gatewayUrl.replace(/\/+$/, "");
|
|
560
|
+
this.tenantId = options.tenantId;
|
|
561
|
+
this.fetchWithAuth = options.fetchWithAuth;
|
|
562
|
+
this.fetchFn = options.fetchFn;
|
|
563
|
+
}
|
|
564
|
+
// --- Products ---
|
|
565
|
+
/**
|
|
566
|
+
* List catalog products with search, category filtering, and pagination
|
|
567
|
+
*/
|
|
568
|
+
async getProducts(params) {
|
|
569
|
+
const query = new URLSearchParams();
|
|
570
|
+
if (params?.search) query.set("search", params.search);
|
|
571
|
+
if (params?.category) query.set("category", params.category);
|
|
572
|
+
if (params?.status) query.set("status", params.status);
|
|
573
|
+
if (params?.limit) query.set("limit", String(params.limit));
|
|
574
|
+
if (params?.page) query.set("page", String(params.page));
|
|
575
|
+
if (params?.orderBy) query.set("orderBy", params.orderBy);
|
|
576
|
+
if (params?.sortedBy) query.set("sortedBy", params.sortedBy);
|
|
577
|
+
if (params?.language) query.set("language", params.language);
|
|
578
|
+
if (params?.type) query.set("type", params.type);
|
|
579
|
+
const qs = query.toString();
|
|
580
|
+
const url = `${this.gatewayUrl}/commerce/products${qs ? `?${qs}` : ""}`;
|
|
581
|
+
const res = await this.fetchFn(url, {
|
|
582
|
+
method: "GET",
|
|
583
|
+
headers: { "x-tenant-id": this.tenantId }
|
|
584
|
+
});
|
|
585
|
+
if (!res.ok) {
|
|
586
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
587
|
+
throw new Error(err.message || `Failed to fetch products with HTTP ${res.status}`);
|
|
588
|
+
}
|
|
589
|
+
const data = await res.json();
|
|
590
|
+
return Array.isArray(data) ? { data } : data;
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* Get a single product by slug or ID
|
|
594
|
+
*/
|
|
595
|
+
async getProductBySlug(slug, language) {
|
|
596
|
+
const query = language ? `?language=${encodeURIComponent(language)}` : "";
|
|
597
|
+
const url = `${this.gatewayUrl}/commerce/products/${encodeURIComponent(slug)}${query}`;
|
|
598
|
+
const res = await this.fetchFn(url, {
|
|
599
|
+
method: "GET",
|
|
600
|
+
headers: { "x-tenant-id": this.tenantId }
|
|
601
|
+
});
|
|
602
|
+
if (!res.ok) {
|
|
603
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
604
|
+
throw new Error(err.message || `Product not found with HTTP ${res.status}`);
|
|
605
|
+
}
|
|
606
|
+
return res.json();
|
|
607
|
+
}
|
|
608
|
+
/**
|
|
609
|
+
* Create a new product (requires merchant/admin authentication)
|
|
610
|
+
*/
|
|
611
|
+
async createProduct(product) {
|
|
612
|
+
const url = `${this.gatewayUrl}/commerce/products`;
|
|
613
|
+
const res = await this.fetchWithAuth(url, {
|
|
614
|
+
method: "POST",
|
|
615
|
+
body: JSON.stringify(product),
|
|
616
|
+
headers: {
|
|
617
|
+
"Content-Type": "application/json",
|
|
618
|
+
"x-tenant-id": this.tenantId
|
|
619
|
+
}
|
|
620
|
+
});
|
|
621
|
+
if (!res.ok) {
|
|
622
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
623
|
+
throw new Error(err.message || `Failed to create product with HTTP ${res.status}`);
|
|
624
|
+
}
|
|
625
|
+
return res.json();
|
|
626
|
+
}
|
|
627
|
+
// --- Categories ---
|
|
628
|
+
/**
|
|
629
|
+
* List store categories
|
|
630
|
+
*/
|
|
631
|
+
async getCategories(params) {
|
|
632
|
+
const query = new URLSearchParams();
|
|
633
|
+
if (params?.parent !== void 0) query.set("parent", String(params.parent));
|
|
634
|
+
if (params?.limit) query.set("limit", String(params.limit));
|
|
635
|
+
if (params?.page) query.set("page", String(params.page));
|
|
636
|
+
const qs = query.toString();
|
|
637
|
+
const url = `${this.gatewayUrl}/commerce/categories${qs ? `?${qs}` : ""}`;
|
|
638
|
+
const res = await this.fetchFn(url, {
|
|
639
|
+
method: "GET",
|
|
640
|
+
headers: { "x-tenant-id": this.tenantId }
|
|
641
|
+
});
|
|
642
|
+
if (!res.ok) {
|
|
643
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
644
|
+
throw new Error(err.message || `Failed to fetch categories with HTTP ${res.status}`);
|
|
645
|
+
}
|
|
646
|
+
const data = await res.json();
|
|
647
|
+
return Array.isArray(data) ? data : data.data || [];
|
|
648
|
+
}
|
|
649
|
+
// --- Orders & Checkout ---
|
|
650
|
+
/**
|
|
651
|
+
* Create a new customer checkout order
|
|
652
|
+
*/
|
|
653
|
+
async createOrder(payload) {
|
|
654
|
+
const url = `${this.gatewayUrl}/commerce/orders`;
|
|
655
|
+
const res = await this.fetchWithAuth(url, {
|
|
656
|
+
method: "POST",
|
|
657
|
+
body: JSON.stringify(payload),
|
|
658
|
+
headers: {
|
|
659
|
+
"Content-Type": "application/json",
|
|
660
|
+
"x-tenant-id": this.tenantId
|
|
661
|
+
}
|
|
662
|
+
});
|
|
663
|
+
if (!res.ok) {
|
|
664
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
665
|
+
throw new Error(err.message || `Failed to create order with HTTP ${res.status}`);
|
|
666
|
+
}
|
|
667
|
+
return res.json();
|
|
668
|
+
}
|
|
669
|
+
/**
|
|
670
|
+
* Verify checkout taxes, shipping fees, and product availability
|
|
671
|
+
*/
|
|
672
|
+
async verifyCheckout(payload) {
|
|
673
|
+
const url = `${this.gatewayUrl}/commerce/orders/checkout/verify`;
|
|
674
|
+
const res = await this.fetchWithAuth(url, {
|
|
675
|
+
method: "POST",
|
|
676
|
+
body: JSON.stringify(payload),
|
|
677
|
+
headers: {
|
|
678
|
+
"Content-Type": "application/json",
|
|
679
|
+
"x-tenant-id": this.tenantId
|
|
680
|
+
}
|
|
681
|
+
});
|
|
682
|
+
if (!res.ok) {
|
|
683
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
684
|
+
throw new Error(err.message || `Checkout verification failed with HTTP ${res.status}`);
|
|
685
|
+
}
|
|
686
|
+
return res.json();
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* Track order by tracking number
|
|
690
|
+
*/
|
|
691
|
+
async trackOrder(trackingNumber) {
|
|
692
|
+
const url = `${this.gatewayUrl}/commerce/orders/tracking/${encodeURIComponent(trackingNumber)}`;
|
|
693
|
+
const res = await this.fetchFn(url, {
|
|
694
|
+
method: "GET",
|
|
695
|
+
headers: { "x-tenant-id": this.tenantId }
|
|
696
|
+
});
|
|
697
|
+
if (!res.ok) {
|
|
698
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
699
|
+
throw new Error(err.message || `Order tracking failed with HTTP ${res.status}`);
|
|
700
|
+
}
|
|
701
|
+
return res.json();
|
|
702
|
+
}
|
|
703
|
+
/**
|
|
704
|
+
* List customer orders (authenticated)
|
|
705
|
+
*/
|
|
706
|
+
async getOrders(params) {
|
|
707
|
+
const query = new URLSearchParams();
|
|
708
|
+
if (params?.limit) query.set("limit", String(params.limit));
|
|
709
|
+
if (params?.page) query.set("page", String(params.page));
|
|
710
|
+
if (params?.tracking_number) query.set("tracking_number", params.tracking_number);
|
|
711
|
+
const qs = query.toString();
|
|
712
|
+
const url = `${this.gatewayUrl}/commerce/orders${qs ? `?${qs}` : ""}`;
|
|
713
|
+
const res = await this.fetchWithAuth(url, {
|
|
714
|
+
method: "GET",
|
|
715
|
+
headers: { "x-tenant-id": this.tenantId }
|
|
716
|
+
});
|
|
717
|
+
if (!res.ok) {
|
|
718
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
719
|
+
throw new Error(err.message || `Failed to fetch orders with HTTP ${res.status}`);
|
|
720
|
+
}
|
|
721
|
+
const data = await res.json();
|
|
722
|
+
return Array.isArray(data) ? { data } : data;
|
|
723
|
+
}
|
|
724
|
+
// --- Coupons ---
|
|
725
|
+
/**
|
|
726
|
+
* Verify and calculate discount for a promo coupon code
|
|
727
|
+
*/
|
|
728
|
+
async verifyCoupon(payload) {
|
|
729
|
+
const url = `${this.gatewayUrl}/commerce/coupons/verify`;
|
|
730
|
+
const res = await this.fetchWithAuth(url, {
|
|
731
|
+
method: "POST",
|
|
732
|
+
body: JSON.stringify(payload),
|
|
733
|
+
headers: {
|
|
734
|
+
"Content-Type": "application/json",
|
|
735
|
+
"x-tenant-id": this.tenantId
|
|
736
|
+
}
|
|
737
|
+
});
|
|
738
|
+
if (!res.ok) {
|
|
739
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
740
|
+
throw new Error(err.message || `Coupon verification failed with HTTP ${res.status}`);
|
|
741
|
+
}
|
|
742
|
+
return res.json();
|
|
743
|
+
}
|
|
744
|
+
// --- Settings ---
|
|
745
|
+
/**
|
|
746
|
+
* Get store and commerce configuration settings
|
|
747
|
+
*/
|
|
748
|
+
async getSettings() {
|
|
749
|
+
const url = `${this.gatewayUrl}/commerce/settings`;
|
|
750
|
+
const res = await this.fetchFn(url, {
|
|
751
|
+
method: "GET",
|
|
752
|
+
headers: { "x-tenant-id": this.tenantId }
|
|
753
|
+
});
|
|
754
|
+
if (!res.ok) {
|
|
755
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
756
|
+
throw new Error(err.message || `Failed to fetch settings with HTTP ${res.status}`);
|
|
757
|
+
}
|
|
758
|
+
return res.json();
|
|
759
|
+
}
|
|
760
|
+
};
|
|
761
|
+
|
|
762
|
+
// src/doc.ts
|
|
763
|
+
var DocClient = class {
|
|
764
|
+
gatewayUrl;
|
|
765
|
+
tenantId;
|
|
766
|
+
fetchWithAuth;
|
|
767
|
+
fetchFn;
|
|
768
|
+
constructor(options) {
|
|
769
|
+
this.gatewayUrl = options.gatewayUrl.replace(/\/+$/, "");
|
|
770
|
+
this.tenantId = options.tenantId;
|
|
771
|
+
this.fetchWithAuth = options.fetchWithAuth;
|
|
772
|
+
this.fetchFn = options.fetchFn;
|
|
773
|
+
}
|
|
774
|
+
/**
|
|
775
|
+
* Upload one or more files to object storage (S3/MinIO) with automated thumbnailing
|
|
776
|
+
*/
|
|
777
|
+
async upload(files) {
|
|
778
|
+
const url = `${this.gatewayUrl}/doc/upload`;
|
|
779
|
+
let body;
|
|
780
|
+
if (typeof FormData !== "undefined" && files instanceof FormData) {
|
|
781
|
+
body = files;
|
|
782
|
+
} else {
|
|
783
|
+
body = new FormData();
|
|
784
|
+
if (Array.isArray(files)) {
|
|
785
|
+
for (const file of files) {
|
|
786
|
+
body.append("files", file);
|
|
787
|
+
}
|
|
788
|
+
} else {
|
|
789
|
+
body.append("files", files);
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
const res = await this.fetchWithAuth(url, {
|
|
793
|
+
method: "POST",
|
|
794
|
+
body,
|
|
795
|
+
headers: {
|
|
796
|
+
"x-tenant-id": this.tenantId
|
|
797
|
+
}
|
|
798
|
+
});
|
|
799
|
+
if (!res.ok) {
|
|
800
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
801
|
+
throw new Error(err.message || `File upload failed with HTTP ${res.status}`);
|
|
802
|
+
}
|
|
803
|
+
return res.json();
|
|
804
|
+
}
|
|
805
|
+
/**
|
|
806
|
+
* List documents with optional folder filtering and pagination
|
|
807
|
+
*/
|
|
808
|
+
async list(params) {
|
|
809
|
+
const query = new URLSearchParams();
|
|
810
|
+
if (params?.folderId) query.set("folderId", params.folderId);
|
|
811
|
+
if (params?.page) query.set("page", String(params.page));
|
|
812
|
+
if (params?.limit) query.set("limit", String(params.limit));
|
|
813
|
+
const qs = query.toString();
|
|
814
|
+
const url = `${this.gatewayUrl}/doc/document${qs ? `?${qs}` : ""}`;
|
|
815
|
+
const res = await this.fetchWithAuth(url, {
|
|
816
|
+
method: "GET",
|
|
817
|
+
headers: { "x-tenant-id": this.tenantId }
|
|
818
|
+
});
|
|
819
|
+
if (!res.ok) {
|
|
820
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
821
|
+
throw new Error(err.message || `Failed to fetch documents with HTTP ${res.status}`);
|
|
822
|
+
}
|
|
823
|
+
const data = await res.json();
|
|
824
|
+
return Array.isArray(data) ? data : data.documents || data.items || [];
|
|
825
|
+
}
|
|
826
|
+
/**
|
|
827
|
+
* Get a single document record by ID
|
|
828
|
+
*/
|
|
829
|
+
async get(id) {
|
|
830
|
+
const url = `${this.gatewayUrl}/doc/document/${encodeURIComponent(id)}`;
|
|
831
|
+
const res = await this.fetchWithAuth(url, {
|
|
832
|
+
method: "GET",
|
|
833
|
+
headers: { "x-tenant-id": this.tenantId }
|
|
834
|
+
});
|
|
835
|
+
if (!res.ok) {
|
|
836
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
837
|
+
throw new Error(err.message || `Document not found with HTTP ${res.status}`);
|
|
838
|
+
}
|
|
839
|
+
return res.json();
|
|
840
|
+
}
|
|
841
|
+
/**
|
|
842
|
+
* Delete a document by ID
|
|
843
|
+
*/
|
|
844
|
+
async delete(id) {
|
|
845
|
+
const url = `${this.gatewayUrl}/doc/document/${encodeURIComponent(id)}`;
|
|
846
|
+
const res = await this.fetchWithAuth(url, {
|
|
847
|
+
method: "DELETE",
|
|
848
|
+
headers: { "x-tenant-id": this.tenantId }
|
|
849
|
+
});
|
|
850
|
+
if (!res.ok) {
|
|
851
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
852
|
+
throw new Error(err.message || `Failed to delete document with HTTP ${res.status}`);
|
|
853
|
+
}
|
|
854
|
+
return { success: true };
|
|
855
|
+
}
|
|
856
|
+
/**
|
|
857
|
+
* List document folders
|
|
858
|
+
*/
|
|
859
|
+
async listFolders() {
|
|
860
|
+
const url = `${this.gatewayUrl}/doc/folder`;
|
|
861
|
+
const res = await this.fetchWithAuth(url, {
|
|
862
|
+
method: "GET",
|
|
863
|
+
headers: { "x-tenant-id": this.tenantId }
|
|
864
|
+
});
|
|
865
|
+
if (!res.ok) {
|
|
866
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
867
|
+
throw new Error(err.message || `Failed to fetch folders with HTTP ${res.status}`);
|
|
868
|
+
}
|
|
869
|
+
const data = await res.json();
|
|
870
|
+
return Array.isArray(data) ? data : data.folders || [];
|
|
871
|
+
}
|
|
872
|
+
/**
|
|
873
|
+
* Create a new folder for organizing documents
|
|
874
|
+
*/
|
|
875
|
+
async createFolder(name, parentId) {
|
|
876
|
+
const url = `${this.gatewayUrl}/doc/folder`;
|
|
877
|
+
const res = await this.fetchWithAuth(url, {
|
|
878
|
+
method: "POST",
|
|
879
|
+
body: JSON.stringify({ name, parentId: parentId || null }),
|
|
880
|
+
headers: {
|
|
881
|
+
"Content-Type": "application/json",
|
|
882
|
+
"x-tenant-id": this.tenantId
|
|
883
|
+
}
|
|
884
|
+
});
|
|
885
|
+
if (!res.ok) {
|
|
886
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
887
|
+
throw new Error(err.message || `Failed to create folder with HTTP ${res.status}`);
|
|
888
|
+
}
|
|
889
|
+
return res.json();
|
|
890
|
+
}
|
|
891
|
+
};
|
|
892
|
+
|
|
893
|
+
// src/notification.ts
|
|
894
|
+
var NotificationClient = class {
|
|
895
|
+
gatewayUrl;
|
|
896
|
+
tenantId;
|
|
897
|
+
fetchWithAuth;
|
|
898
|
+
fetchFn;
|
|
899
|
+
constructor(options) {
|
|
900
|
+
this.gatewayUrl = options.gatewayUrl.replace(/\/+$/, "");
|
|
901
|
+
this.tenantId = options.tenantId;
|
|
902
|
+
this.fetchWithAuth = options.fetchWithAuth;
|
|
903
|
+
this.fetchFn = options.fetchFn;
|
|
904
|
+
}
|
|
905
|
+
/**
|
|
906
|
+
* Send an SMS message via configured SMS gateways (Twilio / SMS API)
|
|
907
|
+
*/
|
|
908
|
+
async sendSms(payload) {
|
|
909
|
+
const url = `${this.gatewayUrl}/notification/sms`;
|
|
910
|
+
const res = await this.fetchWithAuth(url, {
|
|
911
|
+
method: "POST",
|
|
912
|
+
body: JSON.stringify({
|
|
913
|
+
to: payload.to,
|
|
914
|
+
body: payload.message,
|
|
915
|
+
from: payload.from,
|
|
916
|
+
provider: payload.provider
|
|
917
|
+
}),
|
|
918
|
+
headers: {
|
|
919
|
+
"Content-Type": "application/json",
|
|
920
|
+
"x-tenant-id": this.tenantId
|
|
921
|
+
}
|
|
922
|
+
});
|
|
923
|
+
if (!res.ok) {
|
|
924
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
925
|
+
throw new Error(err.message || `Failed to send SMS with HTTP ${res.status}`);
|
|
926
|
+
}
|
|
927
|
+
const data = await res.json();
|
|
928
|
+
return {
|
|
929
|
+
success: true,
|
|
930
|
+
messageId: data.id || data.messageId || data.sid,
|
|
931
|
+
status: data.status || "sent"
|
|
932
|
+
};
|
|
933
|
+
}
|
|
934
|
+
/**
|
|
935
|
+
* Send an email or template email
|
|
936
|
+
*/
|
|
937
|
+
async sendEmail(payload) {
|
|
938
|
+
const shopSlug = payload.shopSlug || this.tenantId;
|
|
939
|
+
const localeCode = payload.localeCode || "en";
|
|
940
|
+
const url = `${this.gatewayUrl}/notification/${encodeURIComponent(shopSlug)}/sendEmail/${encodeURIComponent(localeCode)}`;
|
|
941
|
+
const res = await this.fetchWithAuth(url, {
|
|
942
|
+
method: "POST",
|
|
943
|
+
body: JSON.stringify({
|
|
944
|
+
to: Array.isArray(payload.to) ? payload.to.join(",") : payload.to,
|
|
945
|
+
subject: payload.subject,
|
|
946
|
+
html: payload.html,
|
|
947
|
+
text: payload.text,
|
|
948
|
+
templateId: payload.templateId,
|
|
949
|
+
templateData: payload.templateData
|
|
950
|
+
}),
|
|
951
|
+
headers: {
|
|
952
|
+
"Content-Type": "application/json",
|
|
953
|
+
"x-tenant-id": this.tenantId
|
|
954
|
+
}
|
|
955
|
+
});
|
|
956
|
+
if (!res.ok) {
|
|
957
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
958
|
+
throw new Error(err.message || `Failed to send Email with HTTP ${res.status}`);
|
|
959
|
+
}
|
|
960
|
+
const data = await res.json();
|
|
961
|
+
return {
|
|
962
|
+
success: true,
|
|
963
|
+
messageId: data.id || data.messageId,
|
|
964
|
+
status: data.status || "sent"
|
|
965
|
+
};
|
|
966
|
+
}
|
|
967
|
+
/**
|
|
968
|
+
* Send Firebase Cloud Messaging (FCM) Push Notification
|
|
969
|
+
*/
|
|
970
|
+
async sendPush(payload) {
|
|
971
|
+
const url = `${this.gatewayUrl}/notification/firebase_message`;
|
|
972
|
+
const res = await this.fetchWithAuth(url, {
|
|
973
|
+
method: "POST",
|
|
974
|
+
body: JSON.stringify({
|
|
975
|
+
token: payload.token,
|
|
976
|
+
tokens: payload.tokens,
|
|
977
|
+
topic: payload.topic,
|
|
978
|
+
notification: {
|
|
979
|
+
title: payload.title,
|
|
980
|
+
body: payload.body
|
|
981
|
+
},
|
|
982
|
+
data: payload.data || {}
|
|
983
|
+
}),
|
|
984
|
+
headers: {
|
|
985
|
+
"Content-Type": "application/json",
|
|
986
|
+
"x-tenant-id": this.tenantId
|
|
987
|
+
}
|
|
988
|
+
});
|
|
989
|
+
if (!res.ok) {
|
|
990
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
991
|
+
throw new Error(err.message || `Failed to send Push Notification with HTTP ${res.status}`);
|
|
992
|
+
}
|
|
993
|
+
const data = await res.json();
|
|
994
|
+
return {
|
|
995
|
+
success: true,
|
|
996
|
+
messageId: data.messageId || data.id,
|
|
997
|
+
status: "sent"
|
|
998
|
+
};
|
|
999
|
+
}
|
|
1000
|
+
/**
|
|
1001
|
+
* Register a device push token for push notifications
|
|
1002
|
+
*/
|
|
1003
|
+
async registerPushToken(payload) {
|
|
1004
|
+
const url = `${this.gatewayUrl}/notification/firebase_registration`;
|
|
1005
|
+
const res = await this.fetchWithAuth(url, {
|
|
1006
|
+
method: "POST",
|
|
1007
|
+
body: JSON.stringify({
|
|
1008
|
+
token: payload.token,
|
|
1009
|
+
userId: payload.userId,
|
|
1010
|
+
platform: payload.platform || "web",
|
|
1011
|
+
metadata: payload.metadata || {}
|
|
1012
|
+
}),
|
|
1013
|
+
headers: {
|
|
1014
|
+
"Content-Type": "application/json",
|
|
1015
|
+
"x-tenant-id": this.tenantId
|
|
1016
|
+
}
|
|
1017
|
+
});
|
|
1018
|
+
if (!res.ok) {
|
|
1019
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
1020
|
+
throw new Error(err.message || `Failed to register push token with HTTP ${res.status}`);
|
|
1021
|
+
}
|
|
1022
|
+
const data = await res.json();
|
|
1023
|
+
return { success: true, id: data.id };
|
|
1024
|
+
}
|
|
1025
|
+
/**
|
|
1026
|
+
* Get recent in-app notifications
|
|
1027
|
+
*/
|
|
1028
|
+
async list(params) {
|
|
1029
|
+
const query = new URLSearchParams();
|
|
1030
|
+
if (params?.page) query.set("page", String(params.page));
|
|
1031
|
+
if (params?.limit) query.set("limit", String(params.limit));
|
|
1032
|
+
const qs = query.toString();
|
|
1033
|
+
const url = `${this.gatewayUrl}/notification/notification${qs ? `?${qs}` : ""}`;
|
|
1034
|
+
const res = await this.fetchWithAuth(url, {
|
|
1035
|
+
method: "GET",
|
|
1036
|
+
headers: { "x-tenant-id": this.tenantId }
|
|
1037
|
+
});
|
|
1038
|
+
if (!res.ok) {
|
|
1039
|
+
const err = await res.json().catch(() => ({ message: res.statusText }));
|
|
1040
|
+
throw new Error(err.message || `Failed to fetch notifications with HTTP ${res.status}`);
|
|
1041
|
+
}
|
|
1042
|
+
const data = await res.json();
|
|
1043
|
+
return Array.isArray(data) ? data : data.notifications || data.items || [];
|
|
1044
|
+
}
|
|
1045
|
+
};
|
|
1046
|
+
|
|
549
1047
|
// src/query-builder.ts
|
|
550
1048
|
var EntityQueryBuilder = class {
|
|
551
1049
|
gatewayUrl;
|
|
@@ -560,7 +1058,7 @@ var EntityQueryBuilder = class {
|
|
|
560
1058
|
this.tenantId = options.tenantId;
|
|
561
1059
|
this.typeName = options.typeName;
|
|
562
1060
|
this.getToken = options.getToken || (() => null);
|
|
563
|
-
this.fetchFn = options.fetchFn || (
|
|
1061
|
+
this.fetchFn = options.fetchFn || ((...args) => fetch(...args));
|
|
564
1062
|
this.fetchWithAuth = options.fetchWithAuth;
|
|
565
1063
|
if (options.defaultLanguage) {
|
|
566
1064
|
const langVal = typeof options.defaultLanguage === "function" ? options.defaultLanguage() : options.defaultLanguage;
|
|
@@ -989,7 +1487,7 @@ var SchemaClient = class {
|
|
|
989
1487
|
this.gatewayUrl = options.gatewayUrl.replace(/\/+$/, "");
|
|
990
1488
|
this.tenantId = options.tenantId;
|
|
991
1489
|
this.getToken = options.getToken || (() => null);
|
|
992
|
-
this.fetchFn = options.fetchFn || (
|
|
1490
|
+
this.fetchFn = options.fetchFn || ((...args) => fetch(...args));
|
|
993
1491
|
this.fetchWithAuth = options.fetchWithAuth;
|
|
994
1492
|
}
|
|
995
1493
|
getHeaders() {
|
|
@@ -1047,20 +1545,24 @@ var Zone4CodeClient = class {
|
|
|
1047
1545
|
tenantId;
|
|
1048
1546
|
auth;
|
|
1049
1547
|
schema;
|
|
1548
|
+
doc;
|
|
1549
|
+
notification;
|
|
1550
|
+
commerce;
|
|
1050
1551
|
storage;
|
|
1051
1552
|
fetchFn;
|
|
1052
1553
|
currentLanguage = null;
|
|
1053
|
-
constructor(config) {
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
}
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
this.
|
|
1554
|
+
constructor(config = {}) {
|
|
1555
|
+
const globalObj = typeof globalThis !== "undefined" ? globalThis : {};
|
|
1556
|
+
const procEnv = globalObj.process?.env || {};
|
|
1557
|
+
const winEnv = globalObj.window?.env || globalObj.__ZONE4BUILD_ENV__ || {};
|
|
1558
|
+
const envGateway = procEnv.ZONE4BUILD_GATEWAY_URL || procEnv.VITE_ZONE4BUILD_GATEWAY_URL || winEnv.ZONE4BUILD_GATEWAY_URL || globalObj.__ZONE4BUILD_GATEWAY_URL__;
|
|
1559
|
+
const resolvedGatewayUrl = config.gatewayUrl || envGateway || "https://api.zone4build.com";
|
|
1560
|
+
const envTenant = procEnv.ZONE4BUILD_WORKSPACE_ID || procEnv.VITE_ZONE4BUILD_WORKSPACE_ID || winEnv.ZONE4BUILD_WORKSPACE_ID || globalObj.__ZONE4BUILD_WORKSPACE_ID__;
|
|
1561
|
+
const resolvedTenantId = config.tenantId || envTenant || "default";
|
|
1562
|
+
this.gatewayUrl = resolvedGatewayUrl.replace(/\/+$/, "");
|
|
1563
|
+
this.tenantId = resolvedTenantId;
|
|
1062
1564
|
this.storage = config.storage || getDefaultStorage();
|
|
1063
|
-
this.fetchFn = config.fetch || (
|
|
1565
|
+
this.fetchFn = config.fetch || ((...args) => fetch(...args));
|
|
1064
1566
|
this.currentLanguage = config.defaultLanguage !== void 0 ? config.defaultLanguage : "en";
|
|
1065
1567
|
this.auth = new AuthClient({
|
|
1066
1568
|
gatewayUrl: this.gatewayUrl,
|
|
@@ -1081,7 +1583,32 @@ var Zone4CodeClient = class {
|
|
|
1081
1583
|
fetchFn: this.fetchFn,
|
|
1082
1584
|
fetchWithAuth: (url, init) => this.auth.fetchWithAuth(url, init)
|
|
1083
1585
|
});
|
|
1586
|
+
this.doc = new DocClient({
|
|
1587
|
+
gatewayUrl: this.gatewayUrl,
|
|
1588
|
+
tenantId: this.tenantId,
|
|
1589
|
+
fetchWithAuth: (url, init) => this.auth.fetchWithAuth(url, init),
|
|
1590
|
+
fetchFn: this.fetchFn
|
|
1591
|
+
});
|
|
1592
|
+
this.notification = new NotificationClient({
|
|
1593
|
+
gatewayUrl: this.gatewayUrl,
|
|
1594
|
+
tenantId: this.tenantId,
|
|
1595
|
+
fetchWithAuth: (url, init) => this.auth.fetchWithAuth(url, init),
|
|
1596
|
+
fetchFn: this.fetchFn
|
|
1597
|
+
});
|
|
1598
|
+
this.commerce = new CommerceClient({
|
|
1599
|
+
gatewayUrl: this.gatewayUrl,
|
|
1600
|
+
tenantId: this.tenantId,
|
|
1601
|
+
fetchWithAuth: (url, init) => this.auth.fetchWithAuth(url, init),
|
|
1602
|
+
fetchFn: this.fetchFn
|
|
1603
|
+
});
|
|
1604
|
+
this.generic = {
|
|
1605
|
+
from: (typeName) => this.from(typeName),
|
|
1606
|
+
entities: (typeName) => this.from(typeName),
|
|
1607
|
+
schema: this.schema,
|
|
1608
|
+
getMe: () => this.getMe()
|
|
1609
|
+
};
|
|
1084
1610
|
}
|
|
1611
|
+
generic;
|
|
1085
1612
|
/**
|
|
1086
1613
|
* Set the active default language for API requests (e.g., 'en', 'fr', 'ar', or '*' for raw)
|
|
1087
1614
|
*/
|
|
@@ -1149,8 +1676,11 @@ function createClient(config) {
|
|
|
1149
1676
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1150
1677
|
0 && (module.exports = {
|
|
1151
1678
|
AuthClient,
|
|
1679
|
+
CommerceClient,
|
|
1680
|
+
DocClient,
|
|
1152
1681
|
EntityQueryBuilder,
|
|
1153
1682
|
MemoryStorage,
|
|
1683
|
+
NotificationClient,
|
|
1154
1684
|
SchemaClient,
|
|
1155
1685
|
Zone4CodeClient,
|
|
1156
1686
|
createClient,
|