@ecommaps/client 1.1.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.
@@ -0,0 +1,168 @@
1
+ interface EcommapsSite {
2
+ id: string;
3
+ name: string;
4
+ slug: string;
5
+ description: string | null;
6
+ logo_url: string | null;
7
+ custom_domain: string | null;
8
+ theme: any | null;
9
+ theme_settings: any | null;
10
+ settings: any | null;
11
+ contact_info: any | null;
12
+ social_links: any | null;
13
+ }
14
+ interface EcommapsProductVariant {
15
+ title: string;
16
+ prices: any[];
17
+ options: any[];
18
+ inventory_quantity: number;
19
+ sku: string | null;
20
+ id?: string;
21
+ }
22
+ interface EcommapsProduct {
23
+ id: string;
24
+ site_id: string;
25
+ name: string;
26
+ slug: string;
27
+ description: string | null;
28
+ price: number;
29
+ compare_at_price: number | null;
30
+ currency: string | null;
31
+ images: any | null;
32
+ category: string | null;
33
+ tags: string[] | null;
34
+ inventory_quantity: number | null;
35
+ is_active: boolean | null;
36
+ created_at: string | null;
37
+ updated_at: string | null;
38
+ sku: string | null;
39
+ barcode: string | null;
40
+ cost_per_item: number | null;
41
+ track_quantity: boolean | null;
42
+ continue_selling_when_out_of_stock: boolean | null;
43
+ weight: number | null;
44
+ weight_unit: string | null;
45
+ vendor: string | null;
46
+ product_type: string | null;
47
+ options: any | null;
48
+ variants: any | null;
49
+ charge_tax: boolean | null;
50
+ is_physical: boolean | null;
51
+ }
52
+ interface EcommapsCollection {
53
+ id: string;
54
+ site_id: string;
55
+ title: string;
56
+ description: string | null;
57
+ slug: string;
58
+ image_url: string | null;
59
+ is_active: boolean | null;
60
+ sort_order: string | null;
61
+ created_at: string;
62
+ updated_at: string;
63
+ }
64
+ interface PaginationMeta {
65
+ total: number;
66
+ limit: number;
67
+ offset: number;
68
+ has_more: boolean;
69
+ }
70
+ interface PaginatedResponse<T> {
71
+ data: T[];
72
+ pagination: PaginationMeta;
73
+ }
74
+ interface EcommapsCartItem {
75
+ id: string;
76
+ product_id: string;
77
+ variant_id: string | null;
78
+ product_name: string;
79
+ product_price: number;
80
+ product_image: string | null;
81
+ quantity: number;
82
+ subtotal: number;
83
+ }
84
+ interface EcommapsCart {
85
+ id: string;
86
+ site_id: string;
87
+ items: EcommapsCartItem[];
88
+ items_count: number;
89
+ subtotal: number;
90
+ created_at: string | null;
91
+ }
92
+ interface EcommapsCustomer {
93
+ id: string;
94
+ store_id: string;
95
+ email: string;
96
+ full_name: string;
97
+ phone: string | null;
98
+ addresses: any[];
99
+ created_at: string;
100
+ }
101
+ interface EcommapsAuthResponse {
102
+ token: string;
103
+ user: EcommapsCustomer;
104
+ }
105
+
106
+ declare class EcommapsAPIError extends Error {
107
+ status: number;
108
+ constructor(message: string, status: number);
109
+ }
110
+ declare const ecommapsClient: {
111
+ store: {
112
+ retrieve: (options?: RequestInit) => Promise<EcommapsSite>;
113
+ menus: (options?: RequestInit) => Promise<any>;
114
+ };
115
+ products: {
116
+ list: (params?: Record<string, string | number>, options?: RequestInit) => Promise<PaginatedResponse<EcommapsProduct>>;
117
+ retrieve: (slug: string, options?: RequestInit) => Promise<EcommapsProduct>;
118
+ };
119
+ collections: {
120
+ list: (options?: RequestInit) => Promise<{
121
+ data: EcommapsCollection[];
122
+ }>;
123
+ retrieve: (slug: string, limit?: number, offset?: number, options?: RequestInit) => Promise<{
124
+ collection: EcommapsCollection;
125
+ products: EcommapsProduct[];
126
+ pagination: any;
127
+ }>;
128
+ };
129
+ cart: {
130
+ create: (options?: RequestInit) => Promise<EcommapsCart>;
131
+ retrieve: (cartId: string, options?: RequestInit) => Promise<EcommapsCart>;
132
+ addItem: (cartId: string, body: {
133
+ product_id: string;
134
+ variant_id?: string;
135
+ quantity: number;
136
+ }, options?: RequestInit) => Promise<EcommapsCart>;
137
+ updateItem: (cartId: string, itemId: string, body: {
138
+ quantity: number;
139
+ }, options?: RequestInit) => Promise<EcommapsCart>;
140
+ removeItem: (cartId: string, itemId: string, options?: RequestInit) => Promise<EcommapsCart>;
141
+ };
142
+ orders: {
143
+ create: (body: any, options?: RequestInit) => Promise<any>;
144
+ retrieve: (orderNumber: string, options?: RequestInit) => Promise<any>;
145
+ list: (options?: RequestInit & {
146
+ params?: {
147
+ limit?: number;
148
+ offset?: number;
149
+ };
150
+ }) => Promise<{
151
+ data: any[];
152
+ pagination: any;
153
+ }>;
154
+ };
155
+ auth: {
156
+ login: (body: any, options?: RequestInit) => Promise<EcommapsAuthResponse>;
157
+ signup: (body: any, options?: RequestInit) => Promise<EcommapsAuthResponse>;
158
+ me: (options?: RequestInit) => Promise<{
159
+ customer: EcommapsCustomer;
160
+ }>;
161
+ addAddress: (body: any, options?: RequestInit) => Promise<{
162
+ success: boolean;
163
+ address: any;
164
+ }>;
165
+ };
166
+ };
167
+
168
+ export { EcommapsAPIError, type EcommapsAuthResponse, type EcommapsCart, type EcommapsCartItem, type EcommapsCollection, type EcommapsCustomer, type EcommapsProduct, type EcommapsProductVariant, type EcommapsSite, type PaginatedResponse, type PaginationMeta, ecommapsClient };
@@ -0,0 +1,168 @@
1
+ interface EcommapsSite {
2
+ id: string;
3
+ name: string;
4
+ slug: string;
5
+ description: string | null;
6
+ logo_url: string | null;
7
+ custom_domain: string | null;
8
+ theme: any | null;
9
+ theme_settings: any | null;
10
+ settings: any | null;
11
+ contact_info: any | null;
12
+ social_links: any | null;
13
+ }
14
+ interface EcommapsProductVariant {
15
+ title: string;
16
+ prices: any[];
17
+ options: any[];
18
+ inventory_quantity: number;
19
+ sku: string | null;
20
+ id?: string;
21
+ }
22
+ interface EcommapsProduct {
23
+ id: string;
24
+ site_id: string;
25
+ name: string;
26
+ slug: string;
27
+ description: string | null;
28
+ price: number;
29
+ compare_at_price: number | null;
30
+ currency: string | null;
31
+ images: any | null;
32
+ category: string | null;
33
+ tags: string[] | null;
34
+ inventory_quantity: number | null;
35
+ is_active: boolean | null;
36
+ created_at: string | null;
37
+ updated_at: string | null;
38
+ sku: string | null;
39
+ barcode: string | null;
40
+ cost_per_item: number | null;
41
+ track_quantity: boolean | null;
42
+ continue_selling_when_out_of_stock: boolean | null;
43
+ weight: number | null;
44
+ weight_unit: string | null;
45
+ vendor: string | null;
46
+ product_type: string | null;
47
+ options: any | null;
48
+ variants: any | null;
49
+ charge_tax: boolean | null;
50
+ is_physical: boolean | null;
51
+ }
52
+ interface EcommapsCollection {
53
+ id: string;
54
+ site_id: string;
55
+ title: string;
56
+ description: string | null;
57
+ slug: string;
58
+ image_url: string | null;
59
+ is_active: boolean | null;
60
+ sort_order: string | null;
61
+ created_at: string;
62
+ updated_at: string;
63
+ }
64
+ interface PaginationMeta {
65
+ total: number;
66
+ limit: number;
67
+ offset: number;
68
+ has_more: boolean;
69
+ }
70
+ interface PaginatedResponse<T> {
71
+ data: T[];
72
+ pagination: PaginationMeta;
73
+ }
74
+ interface EcommapsCartItem {
75
+ id: string;
76
+ product_id: string;
77
+ variant_id: string | null;
78
+ product_name: string;
79
+ product_price: number;
80
+ product_image: string | null;
81
+ quantity: number;
82
+ subtotal: number;
83
+ }
84
+ interface EcommapsCart {
85
+ id: string;
86
+ site_id: string;
87
+ items: EcommapsCartItem[];
88
+ items_count: number;
89
+ subtotal: number;
90
+ created_at: string | null;
91
+ }
92
+ interface EcommapsCustomer {
93
+ id: string;
94
+ store_id: string;
95
+ email: string;
96
+ full_name: string;
97
+ phone: string | null;
98
+ addresses: any[];
99
+ created_at: string;
100
+ }
101
+ interface EcommapsAuthResponse {
102
+ token: string;
103
+ user: EcommapsCustomer;
104
+ }
105
+
106
+ declare class EcommapsAPIError extends Error {
107
+ status: number;
108
+ constructor(message: string, status: number);
109
+ }
110
+ declare const ecommapsClient: {
111
+ store: {
112
+ retrieve: (options?: RequestInit) => Promise<EcommapsSite>;
113
+ menus: (options?: RequestInit) => Promise<any>;
114
+ };
115
+ products: {
116
+ list: (params?: Record<string, string | number>, options?: RequestInit) => Promise<PaginatedResponse<EcommapsProduct>>;
117
+ retrieve: (slug: string, options?: RequestInit) => Promise<EcommapsProduct>;
118
+ };
119
+ collections: {
120
+ list: (options?: RequestInit) => Promise<{
121
+ data: EcommapsCollection[];
122
+ }>;
123
+ retrieve: (slug: string, limit?: number, offset?: number, options?: RequestInit) => Promise<{
124
+ collection: EcommapsCollection;
125
+ products: EcommapsProduct[];
126
+ pagination: any;
127
+ }>;
128
+ };
129
+ cart: {
130
+ create: (options?: RequestInit) => Promise<EcommapsCart>;
131
+ retrieve: (cartId: string, options?: RequestInit) => Promise<EcommapsCart>;
132
+ addItem: (cartId: string, body: {
133
+ product_id: string;
134
+ variant_id?: string;
135
+ quantity: number;
136
+ }, options?: RequestInit) => Promise<EcommapsCart>;
137
+ updateItem: (cartId: string, itemId: string, body: {
138
+ quantity: number;
139
+ }, options?: RequestInit) => Promise<EcommapsCart>;
140
+ removeItem: (cartId: string, itemId: string, options?: RequestInit) => Promise<EcommapsCart>;
141
+ };
142
+ orders: {
143
+ create: (body: any, options?: RequestInit) => Promise<any>;
144
+ retrieve: (orderNumber: string, options?: RequestInit) => Promise<any>;
145
+ list: (options?: RequestInit & {
146
+ params?: {
147
+ limit?: number;
148
+ offset?: number;
149
+ };
150
+ }) => Promise<{
151
+ data: any[];
152
+ pagination: any;
153
+ }>;
154
+ };
155
+ auth: {
156
+ login: (body: any, options?: RequestInit) => Promise<EcommapsAuthResponse>;
157
+ signup: (body: any, options?: RequestInit) => Promise<EcommapsAuthResponse>;
158
+ me: (options?: RequestInit) => Promise<{
159
+ customer: EcommapsCustomer;
160
+ }>;
161
+ addAddress: (body: any, options?: RequestInit) => Promise<{
162
+ success: boolean;
163
+ address: any;
164
+ }>;
165
+ };
166
+ };
167
+
168
+ export { EcommapsAPIError, type EcommapsAuthResponse, type EcommapsCart, type EcommapsCartItem, type EcommapsCollection, type EcommapsCustomer, type EcommapsProduct, type EcommapsProductVariant, type EcommapsSite, type PaginatedResponse, type PaginationMeta, ecommapsClient };
package/dist/index.js ADDED
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ EcommapsAPIError: () => EcommapsAPIError,
24
+ ecommapsClient: () => ecommapsClient
25
+ });
26
+ module.exports = __toCommonJS(index_exports);
27
+
28
+ // src/client.ts
29
+ var API_URL = process.env.NEXT_PUBLIC_ECOMMAPS_API_URL || "http://127.0.0.1:8001/api/v1/storefront";
30
+ var API_KEY = process.env.ECOMMAPS_API_KEY || "";
31
+ var EcommapsAPIError = class extends Error {
32
+ status;
33
+ constructor(message, status) {
34
+ super(message);
35
+ this.name = "EcommapsAPIError";
36
+ this.status = status;
37
+ }
38
+ };
39
+ async function ecommapsFetch(endpoint, options) {
40
+ const url = `${API_URL}${endpoint}`;
41
+ const headers = {
42
+ "Content-Type": "application/json",
43
+ "x-api-key": API_KEY,
44
+ ...options?.headers || {}
45
+ };
46
+ const response = await fetch(url, {
47
+ ...options,
48
+ headers
49
+ });
50
+ if (!response.ok) {
51
+ let errorMessage = response.statusText;
52
+ try {
53
+ const errorData = await response.json();
54
+ errorMessage = errorData.detail || errorMessage;
55
+ } catch (e) {
56
+ }
57
+ console.error(`[EcommapsClient] ${response.status} error fetching ${url} - ${errorMessage}`);
58
+ throw new EcommapsAPIError(errorMessage, response.status);
59
+ }
60
+ return response.json();
61
+ }
62
+ var ecommapsClient = {
63
+ store: {
64
+ retrieve: (options) => ecommapsFetch("/store", options),
65
+ menus: (options) => ecommapsFetch("/store/menus", options)
66
+ },
67
+ products: {
68
+ list: (params, options) => {
69
+ const query = new URLSearchParams();
70
+ if (params) {
71
+ Object.entries(params).forEach(([key, value]) => {
72
+ if (value !== void 0 && value !== null) {
73
+ query.append(key, String(value));
74
+ }
75
+ });
76
+ }
77
+ return ecommapsFetch(
78
+ `/products?${query.toString()}`,
79
+ options
80
+ );
81
+ },
82
+ retrieve: (slug, options) => ecommapsFetch(`/products/${slug}`, options)
83
+ },
84
+ collections: {
85
+ list: (options) => ecommapsFetch("/collections", options),
86
+ retrieve: (slug, limit = 20, offset = 0, options) => ecommapsFetch(`/collections/${slug}?limit=${limit}&offset=${offset}`, options)
87
+ },
88
+ cart: {
89
+ create: (options) => ecommapsFetch("/cart", { ...options, method: "POST" }),
90
+ retrieve: (cartId, options) => ecommapsFetch(`/cart/${cartId}`, options),
91
+ addItem: (cartId, body, options) => ecommapsFetch(`/cart/${cartId}/items`, {
92
+ ...options,
93
+ method: "POST",
94
+ body: JSON.stringify(body)
95
+ }),
96
+ updateItem: (cartId, itemId, body, options) => ecommapsFetch(`/cart/${cartId}/items/${itemId}`, {
97
+ ...options,
98
+ method: "PATCH",
99
+ body: JSON.stringify(body)
100
+ }),
101
+ removeItem: (cartId, itemId, options) => ecommapsFetch(`/cart/${cartId}/items/${itemId}`, {
102
+ ...options,
103
+ method: "DELETE"
104
+ })
105
+ },
106
+ orders: {
107
+ create: (body, options) => ecommapsFetch("/orders", {
108
+ ...options,
109
+ method: "POST",
110
+ body: JSON.stringify(body)
111
+ }),
112
+ retrieve: (orderNumber, options) => ecommapsFetch(`/orders/${orderNumber}`, options),
113
+ list: (options) => {
114
+ const searchParams = new URLSearchParams();
115
+ if (options?.params?.limit) searchParams.append("limit", options.params.limit.toString());
116
+ if (options?.params?.offset) searchParams.append("offset", options.params.offset.toString());
117
+ const qs = searchParams.toString() ? `?${searchParams.toString()}` : "";
118
+ return ecommapsFetch(`/orders${qs}`, options);
119
+ }
120
+ },
121
+ auth: {
122
+ login: (body, options) => ecommapsFetch("/auth/login", {
123
+ ...options,
124
+ method: "POST",
125
+ body: JSON.stringify(body)
126
+ }),
127
+ signup: (body, options) => ecommapsFetch("/auth/signup", {
128
+ ...options,
129
+ method: "POST",
130
+ body: JSON.stringify(body)
131
+ }),
132
+ me: (options) => ecommapsFetch("/auth/me", options),
133
+ addAddress: (body, options) => ecommapsFetch("/auth/me/addresses", {
134
+ ...options,
135
+ method: "POST",
136
+ body: JSON.stringify(body)
137
+ })
138
+ }
139
+ };
140
+ // Annotate the CommonJS export names for ESM import in node:
141
+ 0 && (module.exports = {
142
+ EcommapsAPIError,
143
+ ecommapsClient
144
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,116 @@
1
+ // src/client.ts
2
+ var API_URL = process.env.NEXT_PUBLIC_ECOMMAPS_API_URL || "http://127.0.0.1:8001/api/v1/storefront";
3
+ var API_KEY = process.env.ECOMMAPS_API_KEY || "";
4
+ var EcommapsAPIError = class extends Error {
5
+ status;
6
+ constructor(message, status) {
7
+ super(message);
8
+ this.name = "EcommapsAPIError";
9
+ this.status = status;
10
+ }
11
+ };
12
+ async function ecommapsFetch(endpoint, options) {
13
+ const url = `${API_URL}${endpoint}`;
14
+ const headers = {
15
+ "Content-Type": "application/json",
16
+ "x-api-key": API_KEY,
17
+ ...options?.headers || {}
18
+ };
19
+ const response = await fetch(url, {
20
+ ...options,
21
+ headers
22
+ });
23
+ if (!response.ok) {
24
+ let errorMessage = response.statusText;
25
+ try {
26
+ const errorData = await response.json();
27
+ errorMessage = errorData.detail || errorMessage;
28
+ } catch (e) {
29
+ }
30
+ console.error(`[EcommapsClient] ${response.status} error fetching ${url} - ${errorMessage}`);
31
+ throw new EcommapsAPIError(errorMessage, response.status);
32
+ }
33
+ return response.json();
34
+ }
35
+ var ecommapsClient = {
36
+ store: {
37
+ retrieve: (options) => ecommapsFetch("/store", options),
38
+ menus: (options) => ecommapsFetch("/store/menus", options)
39
+ },
40
+ products: {
41
+ list: (params, options) => {
42
+ const query = new URLSearchParams();
43
+ if (params) {
44
+ Object.entries(params).forEach(([key, value]) => {
45
+ if (value !== void 0 && value !== null) {
46
+ query.append(key, String(value));
47
+ }
48
+ });
49
+ }
50
+ return ecommapsFetch(
51
+ `/products?${query.toString()}`,
52
+ options
53
+ );
54
+ },
55
+ retrieve: (slug, options) => ecommapsFetch(`/products/${slug}`, options)
56
+ },
57
+ collections: {
58
+ list: (options) => ecommapsFetch("/collections", options),
59
+ retrieve: (slug, limit = 20, offset = 0, options) => ecommapsFetch(`/collections/${slug}?limit=${limit}&offset=${offset}`, options)
60
+ },
61
+ cart: {
62
+ create: (options) => ecommapsFetch("/cart", { ...options, method: "POST" }),
63
+ retrieve: (cartId, options) => ecommapsFetch(`/cart/${cartId}`, options),
64
+ addItem: (cartId, body, options) => ecommapsFetch(`/cart/${cartId}/items`, {
65
+ ...options,
66
+ method: "POST",
67
+ body: JSON.stringify(body)
68
+ }),
69
+ updateItem: (cartId, itemId, body, options) => ecommapsFetch(`/cart/${cartId}/items/${itemId}`, {
70
+ ...options,
71
+ method: "PATCH",
72
+ body: JSON.stringify(body)
73
+ }),
74
+ removeItem: (cartId, itemId, options) => ecommapsFetch(`/cart/${cartId}/items/${itemId}`, {
75
+ ...options,
76
+ method: "DELETE"
77
+ })
78
+ },
79
+ orders: {
80
+ create: (body, options) => ecommapsFetch("/orders", {
81
+ ...options,
82
+ method: "POST",
83
+ body: JSON.stringify(body)
84
+ }),
85
+ retrieve: (orderNumber, options) => ecommapsFetch(`/orders/${orderNumber}`, options),
86
+ list: (options) => {
87
+ const searchParams = new URLSearchParams();
88
+ if (options?.params?.limit) searchParams.append("limit", options.params.limit.toString());
89
+ if (options?.params?.offset) searchParams.append("offset", options.params.offset.toString());
90
+ const qs = searchParams.toString() ? `?${searchParams.toString()}` : "";
91
+ return ecommapsFetch(`/orders${qs}`, options);
92
+ }
93
+ },
94
+ auth: {
95
+ login: (body, options) => ecommapsFetch("/auth/login", {
96
+ ...options,
97
+ method: "POST",
98
+ body: JSON.stringify(body)
99
+ }),
100
+ signup: (body, options) => ecommapsFetch("/auth/signup", {
101
+ ...options,
102
+ method: "POST",
103
+ body: JSON.stringify(body)
104
+ }),
105
+ me: (options) => ecommapsFetch("/auth/me", options),
106
+ addAddress: (body, options) => ecommapsFetch("/auth/me/addresses", {
107
+ ...options,
108
+ method: "POST",
109
+ body: JSON.stringify(body)
110
+ })
111
+ }
112
+ };
113
+ export {
114
+ EcommapsAPIError,
115
+ ecommapsClient
116
+ };
package/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "@ecommaps/client",
3
+ "version": "1.1.0",
4
+ "description": "The official JS SDK for Ecommaps Headless Storefronts.",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "scripts": {
9
+ "build": "tsup src/index.ts --format cjs,esm --dts",
10
+ "dev": "tsup src/index.ts --format cjs,esm --dts --watch",
11
+ "lint": "eslint src/",
12
+ "clean": "rm -rf dist node_modules"
13
+ },
14
+ "devDependencies": {
15
+ "@types/node": "^25.3.0",
16
+ "tsup": "^8.0.2",
17
+ "typescript": "^5.4.5"
18
+ },
19
+ "author": "EcoBaseAI",
20
+ "license": "ISC"
21
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "ecommaps-client",
3
+ "version": "1.0.0",
4
+ "description": "",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "echo \"Error: no test specified\" && exit 1"
8
+ },
9
+ "keywords": [],
10
+ "author": "",
11
+ "license": "ISC",
12
+ "packageManager": "pnpm@10.24.0"
13
+ }
package/src/client.ts ADDED
@@ -0,0 +1,149 @@
1
+ import {
2
+ EcommapsProduct,
3
+ EcommapsCollection,
4
+ EcommapsSite,
5
+ EcommapsCart,
6
+ PaginatedResponse,
7
+ } from "./types"
8
+
9
+ const API_URL =
10
+ process.env.NEXT_PUBLIC_ECOMMAPS_API_URL ||
11
+ "http://127.0.0.1:8001/api/v1/storefront"
12
+ const API_KEY = process.env.ECOMMAPS_API_KEY || ""
13
+
14
+ export class EcommapsAPIError extends Error {
15
+ public status: number
16
+ constructor(message: string, status: number) {
17
+ super(message)
18
+ this.name = "EcommapsAPIError"
19
+ this.status = status
20
+ }
21
+ }
22
+
23
+ async function ecommapsFetch<T>(
24
+ endpoint: string,
25
+ options?: RequestInit
26
+ ): Promise<T> {
27
+ const url = `${API_URL}${endpoint}`
28
+
29
+ const headers: HeadersInit = {
30
+ "Content-Type": "application/json",
31
+ "x-api-key": API_KEY,
32
+ ...(options?.headers || {}),
33
+ }
34
+
35
+ const response = await fetch(url, {
36
+ ...options,
37
+ headers,
38
+ })
39
+
40
+ if (!response.ok) {
41
+ let errorMessage = response.statusText
42
+ try {
43
+ const errorData = await response.json()
44
+ errorMessage = errorData.detail || errorMessage
45
+ } catch (e) {
46
+ // Ignore
47
+ }
48
+ console.error(`[EcommapsClient] ${response.status} error fetching ${url} - ${errorMessage}`);
49
+ throw new EcommapsAPIError(errorMessage, response.status)
50
+ }
51
+
52
+ return response.json()
53
+ }
54
+
55
+ export const ecommapsClient = {
56
+ store: {
57
+ retrieve: (options?: RequestInit) => ecommapsFetch<EcommapsSite>("/store", options),
58
+ menus: (options?: RequestInit) => ecommapsFetch<any>("/store/menus", options),
59
+ },
60
+ products: {
61
+ list: (params?: Record<string, string | number>, options?: RequestInit) => {
62
+ const query = new URLSearchParams()
63
+ if (params) {
64
+ Object.entries(params).forEach(([key, value]) => {
65
+ if (value !== undefined && value !== null) {
66
+ query.append(key, String(value))
67
+ }
68
+ })
69
+ }
70
+ return ecommapsFetch<PaginatedResponse<EcommapsProduct>>(
71
+ `/products?${query.toString()}`,
72
+ options
73
+ )
74
+ },
75
+ retrieve: (slug: string, options?: RequestInit) =>
76
+ ecommapsFetch<EcommapsProduct>(`/products/${slug}`, options),
77
+ },
78
+ collections: {
79
+ list: (options?: RequestInit) => ecommapsFetch<{ data: EcommapsCollection[] }>("/collections", options),
80
+ retrieve: (slug: string, limit = 20, offset = 0, options?: RequestInit) =>
81
+ ecommapsFetch<{
82
+ collection: EcommapsCollection
83
+ products: EcommapsProduct[]
84
+ pagination: any
85
+ }>(`/collections/${slug}?limit=${limit}&offset=${offset}`, options),
86
+ },
87
+ cart: {
88
+ create: (options?: RequestInit) =>
89
+ ecommapsFetch<EcommapsCart>("/cart", { ...options, method: "POST" }),
90
+ retrieve: (cartId: string, options?: RequestInit) =>
91
+ ecommapsFetch<EcommapsCart>(`/cart/${cartId}`, options),
92
+ addItem: (cartId: string, body: { product_id: string; variant_id?: string; quantity: number }, options?: RequestInit) =>
93
+ ecommapsFetch<EcommapsCart>(`/cart/${cartId}/items`, {
94
+ ...options,
95
+ method: "POST",
96
+ body: JSON.stringify(body),
97
+ }),
98
+ updateItem: (cartId: string, itemId: string, body: { quantity: number }, options?: RequestInit) =>
99
+ ecommapsFetch<EcommapsCart>(`/cart/${cartId}/items/${itemId}`, {
100
+ ...options,
101
+ method: "PATCH",
102
+ body: JSON.stringify(body),
103
+ }),
104
+ removeItem: (cartId: string, itemId: string, options?: RequestInit) =>
105
+ ecommapsFetch<EcommapsCart>(`/cart/${cartId}/items/${itemId}`, {
106
+ ...options,
107
+ method: "DELETE",
108
+ }),
109
+ },
110
+ orders: {
111
+ create: (body: any, options?: RequestInit) =>
112
+ ecommapsFetch<any>("/orders", {
113
+ ...options,
114
+ method: "POST",
115
+ body: JSON.stringify(body),
116
+ }),
117
+ retrieve: (orderNumber: string, options?: RequestInit) =>
118
+ ecommapsFetch<any>(`/orders/${orderNumber}`, options),
119
+ list: (options?: RequestInit & { params?: { limit?: number; offset?: number } }) => {
120
+ const searchParams = new URLSearchParams()
121
+ if (options?.params?.limit) searchParams.append("limit", options.params.limit.toString())
122
+ if (options?.params?.offset) searchParams.append("offset", options.params.offset.toString())
123
+ const qs = searchParams.toString() ? `?${searchParams.toString()}` : ""
124
+ return ecommapsFetch<{ data: any[]; pagination: any }>(`/orders${qs}`, options)
125
+ },
126
+ },
127
+ auth: {
128
+ login: (body: any, options?: RequestInit) =>
129
+ ecommapsFetch<import("./types").EcommapsAuthResponse>("/auth/login", {
130
+ ...options,
131
+ method: "POST",
132
+ body: JSON.stringify(body),
133
+ }),
134
+ signup: (body: any, options?: RequestInit) =>
135
+ ecommapsFetch<import("./types").EcommapsAuthResponse>("/auth/signup", {
136
+ ...options,
137
+ method: "POST",
138
+ body: JSON.stringify(body),
139
+ }),
140
+ me: (options?: RequestInit) =>
141
+ ecommapsFetch<{ customer: import("./types").EcommapsCustomer }>("/auth/me", options),
142
+ addAddress: (body: any, options?: RequestInit) =>
143
+ ecommapsFetch<{ success: boolean; address: any }>("/auth/me/addresses", {
144
+ ...options,
145
+ method: "POST",
146
+ body: JSON.stringify(body),
147
+ }),
148
+ },
149
+ }
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./types";
2
+ export * from "./client";
package/src/types.ts ADDED
@@ -0,0 +1,113 @@
1
+ export interface EcommapsSite {
2
+ id: string
3
+ name: string
4
+ slug: string
5
+ description: string | null
6
+ logo_url: string | null
7
+ custom_domain: string | null
8
+ theme: any | null
9
+ theme_settings: any | null
10
+ settings: any | null
11
+ contact_info: any | null
12
+ social_links: any | null
13
+ }
14
+
15
+ export interface EcommapsProductVariant {
16
+ title: string
17
+ prices: any[]
18
+ options: any[]
19
+ inventory_quantity: number
20
+ sku: string | null
21
+ id?: string
22
+ }
23
+
24
+ export interface EcommapsProduct {
25
+ id: string
26
+ site_id: string
27
+ name: string
28
+ slug: string
29
+ description: string | null
30
+ price: number
31
+ compare_at_price: number | null
32
+ currency: string | null
33
+ images: any | null
34
+ category: string | null
35
+ tags: string[] | null
36
+ inventory_quantity: number | null
37
+ is_active: boolean | null
38
+ created_at: string | null
39
+ updated_at: string | null
40
+ sku: string | null
41
+ barcode: string | null
42
+ cost_per_item: number | null
43
+ track_quantity: boolean | null
44
+ continue_selling_when_out_of_stock: boolean | null
45
+ weight: number | null
46
+ weight_unit: string | null
47
+ vendor: string | null
48
+ product_type: string | null
49
+ options: any | null
50
+ variants: any | null
51
+ charge_tax: boolean | null
52
+ is_physical: boolean | null
53
+ }
54
+
55
+ export interface EcommapsCollection {
56
+ id: string
57
+ site_id: string
58
+ title: string
59
+ description: string | null
60
+ slug: string
61
+ image_url: string | null
62
+ is_active: boolean | null
63
+ sort_order: string | null
64
+ created_at: string
65
+ updated_at: string
66
+ }
67
+
68
+ export interface PaginationMeta {
69
+ total: number
70
+ limit: number
71
+ offset: number
72
+ has_more: boolean
73
+ }
74
+
75
+ export interface PaginatedResponse<T> {
76
+ data: T[]
77
+ pagination: PaginationMeta
78
+ }
79
+
80
+ export interface EcommapsCartItem {
81
+ id: string
82
+ product_id: string
83
+ variant_id: string | null
84
+ product_name: string
85
+ product_price: number
86
+ product_image: string | null
87
+ quantity: number
88
+ subtotal: number
89
+ }
90
+
91
+ export interface EcommapsCart {
92
+ id: string
93
+ site_id: string
94
+ items: EcommapsCartItem[]
95
+ items_count: number
96
+ subtotal: number
97
+ created_at: string | null
98
+ }
99
+
100
+ export interface EcommapsCustomer {
101
+ id: string
102
+ store_id: string
103
+ email: string
104
+ full_name: string
105
+ phone: string | null
106
+ addresses: any[]
107
+ created_at: string
108
+ }
109
+
110
+ export interface EcommapsAuthResponse {
111
+ token: string
112
+ user: EcommapsCustomer
113
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "Bundler",
6
+ "esModuleInterop": true,
7
+ "strict": true,
8
+ "skipLibCheck": true,
9
+ "forceConsistentCasingInFileNames": true,
10
+ "declaration": true,
11
+ "declarationMap": true
12
+ },
13
+ "include": [
14
+ "src/**/*"
15
+ ]
16
+ }