@lasterp/shared 1.0.0-alpha.14 → 1.0.0-alpha.16
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 +118 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +181 -0
- package/dist/index.d.ts +181 -2
- package/dist/index.js +96 -6
- package/dist/index.js.map +1 -0
- package/dist/node/index.d.ts +4 -4
- package/dist/node/index.js +4 -4
- package/dist/rn/index.d.ts +4 -4
- package/dist/rn/index.js +4 -4
- package/package.json +1 -1
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var humps = require('humps');
|
|
4
|
+
|
|
5
|
+
async function request(baseUrl, endpoint, options = {}, auth) {
|
|
6
|
+
const url = `${baseUrl}${endpoint}`;
|
|
7
|
+
const headers = {
|
|
8
|
+
"Content-Type": "application/json",
|
|
9
|
+
Accept: "application/json",
|
|
10
|
+
...options.headers
|
|
11
|
+
};
|
|
12
|
+
if (auth?.token) {
|
|
13
|
+
headers["Authorization"] = `Bearer ${auth.token}`;
|
|
14
|
+
} else if (auth?.apiKey) {
|
|
15
|
+
headers["Authorization"] = `token ${auth.apiKey.key}:${auth.apiKey.secret}`;
|
|
16
|
+
}
|
|
17
|
+
const response = await fetch(url, {
|
|
18
|
+
...options,
|
|
19
|
+
headers,
|
|
20
|
+
credentials: "include"
|
|
21
|
+
});
|
|
22
|
+
const rawData = await response.json();
|
|
23
|
+
if (!response.ok || rawData.exc) {
|
|
24
|
+
const errorMessage = rawData._error_message || rawData.exc || "Request failed";
|
|
25
|
+
const error = new Error(errorMessage);
|
|
26
|
+
error.message = errorMessage;
|
|
27
|
+
error.statusCode = response.status;
|
|
28
|
+
if (rawData.exc) {
|
|
29
|
+
error.exc = rawData.exc;
|
|
30
|
+
}
|
|
31
|
+
if (rawData._server_messages) {
|
|
32
|
+
error.serverMessages = rawData._server_messages;
|
|
33
|
+
}
|
|
34
|
+
if (rawData.exc_type) {
|
|
35
|
+
error.excType = rawData.exc_type;
|
|
36
|
+
}
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
const result = rawData.message ?? rawData;
|
|
40
|
+
return humps.camelizeKeys(result);
|
|
41
|
+
}
|
|
42
|
+
async function frappeCall(baseUrl, method, args, auth) {
|
|
43
|
+
const snakeArgs = humps.decamelizeKeys(args ?? {});
|
|
44
|
+
return request(
|
|
45
|
+
baseUrl,
|
|
46
|
+
`/api/method/${method}`,
|
|
47
|
+
{
|
|
48
|
+
method: "POST",
|
|
49
|
+
body: JSON.stringify(snakeArgs)
|
|
50
|
+
},
|
|
51
|
+
auth
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
async function getDoc(baseUrl, doctype, name, auth) {
|
|
55
|
+
const endpoint = `/api/resource/${doctype}/${encodeURIComponent(name)}`;
|
|
56
|
+
const response = await request(baseUrl, endpoint, {}, auth);
|
|
57
|
+
return response.data;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// src/design/page/api.ts
|
|
61
|
+
async function getPage(baseUrl, slug, auth) {
|
|
62
|
+
return getDoc(baseUrl, "Design Page", slug, auth);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// src/utils/catalog.ts
|
|
66
|
+
function toDescription(modelNumber) {
|
|
67
|
+
if (!modelNumber) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
return modelNumber.simCardType;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// src/utils/types.ts
|
|
74
|
+
function equalsIgnoreCase(str1, str2) {
|
|
75
|
+
return str1.localeCompare(str2, void 0, { sensitivity: "accent" }) === 0;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// src/lasterp/shop/api.ts
|
|
79
|
+
async function getShopContext(baseUrl, params, auth) {
|
|
80
|
+
return frappeCall(
|
|
81
|
+
baseUrl,
|
|
82
|
+
"lasterp.shop.controllers.shop_controller.get_context",
|
|
83
|
+
params,
|
|
84
|
+
auth
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
async function getProductContext(baseUrl, productName, auth) {
|
|
88
|
+
return frappeCall(
|
|
89
|
+
baseUrl,
|
|
90
|
+
"lasterp.shop.controllers.product_controller.get_context",
|
|
91
|
+
{ productName },
|
|
92
|
+
auth
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
Object.defineProperty(exports, "camelToSnake", {
|
|
97
|
+
enumerable: true,
|
|
98
|
+
get: function () { return humps.decamelize; }
|
|
99
|
+
});
|
|
100
|
+
Object.defineProperty(exports, "objectCamelToSnake", {
|
|
101
|
+
enumerable: true,
|
|
102
|
+
get: function () { return humps.decamelizeKeys; }
|
|
103
|
+
});
|
|
104
|
+
Object.defineProperty(exports, "objectSnakeToCamel", {
|
|
105
|
+
enumerable: true,
|
|
106
|
+
get: function () { return humps.camelizeKeys; }
|
|
107
|
+
});
|
|
108
|
+
Object.defineProperty(exports, "snakeToCamel", {
|
|
109
|
+
enumerable: true,
|
|
110
|
+
get: function () { return humps.camelize; }
|
|
111
|
+
});
|
|
112
|
+
exports.equalsIgnoreCase = equalsIgnoreCase;
|
|
113
|
+
exports.getPage = getPage;
|
|
114
|
+
exports.getProductContext = getProductContext;
|
|
115
|
+
exports.getShopContext = getShopContext;
|
|
116
|
+
exports.toDescription = toDescription;
|
|
117
|
+
//# sourceMappingURL=index.cjs.map
|
|
118
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client/core.ts","../src/design/page/api.ts","../src/utils/catalog.ts","../src/utils/types.ts","../src/lasterp/shop/api.ts"],"names":["camelizeKeys","decamelizeKeys"],"mappings":"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","file":"index.cjs","sourcesContent":["import { camelizeKeys, decamelizeKeys } from 'humps';\nimport type { FrappeResponse, FrappeError, AuthOptions } from './types';\n\nasync function request<T = any>(\n baseUrl: string,\n endpoint: string,\n options: RequestInit = {},\n auth?: AuthOptions\n): Promise<T> {\n const url = `${baseUrl}${endpoint}`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n ...(options.headers as Record<string, string>),\n };\n\n if (auth?.token) {\n headers['Authorization'] = `Bearer ${auth.token}`;\n } else if (auth?.apiKey) {\n headers['Authorization'] = `token ${auth.apiKey.key}:${auth.apiKey.secret}`;\n }\n\n const response = await fetch(url, {\n ...options,\n headers,\n credentials: 'include',\n });\n\n const rawData: FrappeResponse<any> = await response.json();\n\n if (!response.ok || rawData.exc) {\n // Create a proper Error object for better serialization in Next.js\n const errorMessage = rawData._error_message || rawData.exc || 'Request failed';\n const error = new Error(errorMessage) as Error & FrappeError;\n\n error.message = errorMessage;\n error.statusCode = response.status;\n\n if (rawData.exc) {\n error.exc = rawData.exc;\n }\n\n if (rawData._server_messages) {\n error.serverMessages = rawData._server_messages;\n }\n\n if (rawData.exc_type) {\n error.excType = rawData.exc_type;\n }\n\n throw error;\n }\n\n const result = rawData.message ?? rawData;\n return camelizeKeys(result) as T;\n}\n\nexport async function frappeCall<T = any>(\n baseUrl: string,\n method: string,\n args?: Record<string, any>,\n auth?: AuthOptions\n): Promise<T> {\n const snakeArgs = decamelizeKeys(args ?? {});\n\n return request<T>(\n baseUrl,\n `/api/method/${method}`,\n {\n method: 'POST',\n body: JSON.stringify(snakeArgs),\n },\n auth\n );\n}\n\nexport async function frappeCallGet<T = any>(\n baseUrl: string,\n method: string,\n args?: Record<string, any>,\n auth?: AuthOptions\n): Promise<T> {\n const snakeArgs = decamelizeKeys(args ?? {});\n const queryParams = new URLSearchParams();\n\n Object.entries(snakeArgs).forEach(([key, value]) => {\n queryParams.append(\n key,\n typeof value === 'string' ? value : JSON.stringify(value)\n );\n });\n\n const endpoint = `/api/method/${method}?${queryParams.toString()}`;\n return request<T>(baseUrl, endpoint, { method: 'GET' }, auth);\n}\n\nexport async function getList<T = any>(\n baseUrl: string,\n params: {\n doctype: string;\n fields?: string[];\n filters?: Record<string, any>;\n orderBy?: string;\n limitStart?: number;\n limitPageLength?: number;\n },\n auth?: AuthOptions\n): Promise<T[]> {\n const {\n doctype,\n fields = ['name'],\n filters = {},\n orderBy = 'modified desc',\n limitStart = 0,\n limitPageLength = 20,\n } = params;\n\n const snakeFilters = decamelizeKeys(filters);\n\n const queryParams = new URLSearchParams({\n fields: JSON.stringify(fields),\n filters: JSON.stringify(snakeFilters),\n order_by: orderBy,\n limit_start: limitStart.toString(),\n limit_page_length: limitPageLength.toString(),\n });\n\n const endpoint = `/api/resource/${doctype}?${queryParams.toString()}`;\n const response = await request<{ data: T[] }>(baseUrl, endpoint, {}, auth);\n return response.data || [];\n}\n\nexport async function getDoc<T = any>(\n baseUrl: string,\n doctype: string,\n name: string,\n auth?: AuthOptions\n): Promise<T> {\n const endpoint = `/api/resource/${doctype}/${encodeURIComponent(name)}`;\n const response = await request<{ data: T }>(baseUrl, endpoint, {}, auth);\n return response.data;\n}\n\nexport async function createDoc<T = any>(\n baseUrl: string,\n doctype: string,\n doc: Record<string, any>,\n auth?: AuthOptions\n): Promise<T> {\n const snakeDoc = decamelizeKeys(doc);\n const endpoint = `/api/resource/${doctype}`;\n const response = await request<{ data: T }>(\n baseUrl,\n endpoint,\n {\n method: 'POST',\n body: JSON.stringify(snakeDoc),\n },\n auth\n );\n return response.data;\n}\n\nexport async function updateDoc<T = any>(\n baseUrl: string,\n doctype: string,\n name: string,\n doc: Record<string, any>,\n auth?: AuthOptions\n): Promise<T> {\n const snakeDoc = decamelizeKeys(doc);\n const endpoint = `/api/resource/${doctype}/${encodeURIComponent(name)}`;\n const response = await request<{ data: T }>(\n baseUrl,\n endpoint,\n {\n method: 'PUT',\n body: JSON.stringify(snakeDoc),\n },\n auth\n );\n return response.data;\n}\n\nexport async function deleteDoc(\n baseUrl: string,\n doctype: string,\n name: string,\n auth?: AuthOptions\n): Promise<void> {\n const endpoint = `/api/resource/${doctype}/${encodeURIComponent(name)}`;\n await request(\n baseUrl,\n endpoint,\n {\n method: 'DELETE',\n },\n auth\n );\n}\n\nexport async function getValue<T = any>(\n baseUrl: string,\n doctype: string,\n name: string,\n fieldname: string,\n auth?: AuthOptions\n): Promise<T> {\n const endpoint = `/api/resource/${doctype}/${encodeURIComponent(name)}?fields=[\"${fieldname}\"]`;\n const response = await request<{ data: Record<string, T> }>(\n baseUrl,\n endpoint,\n {},\n auth\n );\n const value = response.data[fieldname];\n\n if (value === undefined) {\n throw new Error(\n `Field \"${fieldname}\" not found in document \"${doctype}/${name}\"`\n );\n }\n\n return value;\n}\n\nexport async function setValue<T = any>(\n baseUrl: string,\n doctype: string,\n name: string,\n fieldname: string,\n value: any,\n auth?: AuthOptions\n): Promise<T> {\n return updateDoc<T>(baseUrl, doctype, name, { [fieldname]: value }, auth);\n}\n\nexport async function getCount(\n baseUrl: string,\n doctype: string,\n filters: Record<string, any> = {},\n auth?: AuthOptions\n): Promise<number> {\n return frappeCall<number>(\n baseUrl,\n 'frappe.client.get_count',\n {\n doctype,\n filters,\n },\n auth\n );\n}\n\nexport async function getCurrentUser(\n baseUrl: string,\n auth?: AuthOptions\n): Promise<any> {\n return frappeCallGet(baseUrl, 'frappe.auth.get_logged_user', {}, auth);\n}\n","import { getDoc } from '../../client/core'\nimport type { AuthOptions } from '../../client/types'\nimport type { Page } from './types'\n\nexport async function getPage(\n baseUrl: string,\n slug: string,\n auth?: AuthOptions\n): Promise<Page> {\n return getDoc<Page>(baseUrl, 'Design Page', slug, auth)\n}\n","import type {ModelNumber} from \"../lasterp\";\n\nexport function toDescription(modelNumber: ModelNumber) {\n if (!modelNumber) {\n return null;\n }\n return modelNumber.simCardType;\n}\n","export function equalsIgnoreCase(str1: string, str2: string): boolean {\n return str1.localeCompare(str2, undefined, { sensitivity: 'accent' }) === 0;\n};\n","import { frappeCall } from '../../client/core';\nimport type { AuthOptions } from '../../client/types';\nimport type { ShopContext, ProductContext } from './types';\n\nexport async function getShopContext(\n baseUrl: string,\n params?: {\n categoryName?: string;\n gradeName?: string;\n },\n auth?: AuthOptions\n): Promise<ShopContext> {\n return frappeCall<ShopContext>(\n baseUrl,\n 'lasterp.shop.controllers.shop_controller.get_context',\n params,\n auth\n );\n}\n\nexport async function getProductContext(\n baseUrl: string,\n productName: string,\n auth?: AuthOptions\n): Promise<ProductContext> {\n return frappeCall<ProductContext>(\n baseUrl,\n 'lasterp.shop.controllers.product_controller.get_context',\n { productName },\n auth\n );\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
export { decamelize as camelToSnake, decamelizeKeys as objectCamelToSnake, camelizeKeys as objectSnakeToCamel, camelize as snakeToCamel } from 'humps';
|
|
2
|
+
|
|
3
|
+
interface FrappeDoc {
|
|
4
|
+
name: string;
|
|
5
|
+
creation?: string;
|
|
6
|
+
modified?: string;
|
|
7
|
+
modifiedBy?: string;
|
|
8
|
+
owner?: string;
|
|
9
|
+
docStatus?: number;
|
|
10
|
+
idx?: number;
|
|
11
|
+
}
|
|
12
|
+
interface FrappeChildDoc extends FrappeDoc {
|
|
13
|
+
parent: string;
|
|
14
|
+
parentType: string;
|
|
15
|
+
parentField: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface Brand {
|
|
19
|
+
brandImage?: string;
|
|
20
|
+
}
|
|
21
|
+
interface NavbarItem {
|
|
22
|
+
label: string;
|
|
23
|
+
enableDropdown: boolean;
|
|
24
|
+
enableLink: boolean;
|
|
25
|
+
link?: string;
|
|
26
|
+
dropdownDescription?: string;
|
|
27
|
+
dropdownCta?: string;
|
|
28
|
+
groups?: NavbarSubItemGroup[];
|
|
29
|
+
}
|
|
30
|
+
interface NavbarSubItemGroup {
|
|
31
|
+
title?: string;
|
|
32
|
+
items: NavbarSubItem[];
|
|
33
|
+
}
|
|
34
|
+
interface NavbarSubItem {
|
|
35
|
+
label: string;
|
|
36
|
+
description?: string;
|
|
37
|
+
image?: string;
|
|
38
|
+
link?: string;
|
|
39
|
+
}
|
|
40
|
+
interface Topbar {
|
|
41
|
+
topbarEnabled?: boolean;
|
|
42
|
+
items: TopbarItem[];
|
|
43
|
+
}
|
|
44
|
+
interface TopbarItem {
|
|
45
|
+
icon?: string;
|
|
46
|
+
label: string;
|
|
47
|
+
link?: string;
|
|
48
|
+
}
|
|
49
|
+
interface Header {
|
|
50
|
+
brand: Brand;
|
|
51
|
+
headerType?: string;
|
|
52
|
+
tabs: NavbarItem[];
|
|
53
|
+
topbar: Topbar;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
interface FooterItemGroup {
|
|
57
|
+
title: string;
|
|
58
|
+
items: FooterItem[];
|
|
59
|
+
}
|
|
60
|
+
interface FooterItem {
|
|
61
|
+
label: string;
|
|
62
|
+
link?: string;
|
|
63
|
+
}
|
|
64
|
+
interface Footer {
|
|
65
|
+
footerType?: string;
|
|
66
|
+
groups: FooterItemGroup[];
|
|
67
|
+
copyright?: string;
|
|
68
|
+
address?: string;
|
|
69
|
+
country?: string;
|
|
70
|
+
phone?: string;
|
|
71
|
+
email?: string;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
interface Globals {
|
|
75
|
+
header: Header;
|
|
76
|
+
footer: Footer;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
interface Hero {
|
|
80
|
+
type: string;
|
|
81
|
+
data: Record<string, unknown>;
|
|
82
|
+
}
|
|
83
|
+
interface Block {
|
|
84
|
+
type: string;
|
|
85
|
+
data?: Record<string, unknown>;
|
|
86
|
+
}
|
|
87
|
+
interface Page {
|
|
88
|
+
slug: string;
|
|
89
|
+
hero?: Hero;
|
|
90
|
+
blocks: Block[];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
interface AuthOptions {
|
|
94
|
+
token?: string;
|
|
95
|
+
apiKey?: {
|
|
96
|
+
key: string;
|
|
97
|
+
secret: string;
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
declare function getPage(baseUrl: string, slug: string, auth?: AuthOptions): Promise<Page>;
|
|
102
|
+
|
|
103
|
+
interface AaveFeatureSlidesData {
|
|
104
|
+
feature1Title: string;
|
|
105
|
+
feature1Description: string;
|
|
106
|
+
feature1Cta?: string;
|
|
107
|
+
feature2Title: string;
|
|
108
|
+
feature2Description: string;
|
|
109
|
+
feature2Cta?: string;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
interface Item {
|
|
113
|
+
itemCode: string;
|
|
114
|
+
region: string;
|
|
115
|
+
grade: string;
|
|
116
|
+
gradeIssuer: string;
|
|
117
|
+
color: string;
|
|
118
|
+
storage: string;
|
|
119
|
+
memory: string;
|
|
120
|
+
network: string;
|
|
121
|
+
}
|
|
122
|
+
interface ItemVariant extends Item {
|
|
123
|
+
itemVariant: string;
|
|
124
|
+
}
|
|
125
|
+
interface ModelNumber {
|
|
126
|
+
modelNumber: string;
|
|
127
|
+
simCardType: string;
|
|
128
|
+
}
|
|
129
|
+
interface Colour {
|
|
130
|
+
name: string;
|
|
131
|
+
color: string;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
interface Category {
|
|
135
|
+
name: string;
|
|
136
|
+
categoryName: string;
|
|
137
|
+
sequenceId: number;
|
|
138
|
+
itemCode: string[];
|
|
139
|
+
itemGroup: string[];
|
|
140
|
+
brand: string[];
|
|
141
|
+
os: string[];
|
|
142
|
+
}
|
|
143
|
+
interface Product extends Item {
|
|
144
|
+
name: string;
|
|
145
|
+
image: string;
|
|
146
|
+
}
|
|
147
|
+
interface ProductVariant extends ItemVariant {
|
|
148
|
+
id: string;
|
|
149
|
+
specs: Record<string, string>;
|
|
150
|
+
price: number;
|
|
151
|
+
stock: number;
|
|
152
|
+
}
|
|
153
|
+
interface ShopContext {
|
|
154
|
+
title?: string;
|
|
155
|
+
categories?: Category[];
|
|
156
|
+
selectedCategory?: Category;
|
|
157
|
+
grades?: string[];
|
|
158
|
+
selectedGrade?: string;
|
|
159
|
+
products: Product[];
|
|
160
|
+
}
|
|
161
|
+
interface ProductContext {
|
|
162
|
+
currency: string;
|
|
163
|
+
product: Product;
|
|
164
|
+
specs: Record<string, string[]>;
|
|
165
|
+
variants: ProductVariant[];
|
|
166
|
+
modelNumbers: Record<string, ModelNumber>;
|
|
167
|
+
colours: Record<string, Colour>;
|
|
168
|
+
variantImages: Record<string, string[]>;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
declare function getShopContext(baseUrl: string, params?: {
|
|
172
|
+
categoryName?: string;
|
|
173
|
+
gradeName?: string;
|
|
174
|
+
}, auth?: AuthOptions): Promise<ShopContext>;
|
|
175
|
+
declare function getProductContext(baseUrl: string, productName: string, auth?: AuthOptions): Promise<ProductContext>;
|
|
176
|
+
|
|
177
|
+
declare function toDescription(modelNumber: ModelNumber): string | null;
|
|
178
|
+
|
|
179
|
+
declare function equalsIgnoreCase(str1: string, str2: string): boolean;
|
|
180
|
+
|
|
181
|
+
export { type AaveFeatureSlidesData, type Block, type Brand, type Category, type Colour, type Footer, type FooterItem, type FooterItemGroup, type FrappeChildDoc, type FrappeDoc, type Globals, type Header, type Hero, type Item, type ItemVariant, type ModelNumber, type NavbarItem, type NavbarSubItem, type NavbarSubItemGroup, type Page, type Product, type ProductContext, type ProductVariant, type ShopContext, type Topbar, type TopbarItem, equalsIgnoreCase, getPage, getProductContext, getShopContext, toDescription };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,181 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export { decamelize as camelToSnake, decamelizeKeys as objectCamelToSnake, camelizeKeys as objectSnakeToCamel, camelize as snakeToCamel } from 'humps';
|
|
2
|
+
|
|
3
|
+
interface FrappeDoc {
|
|
4
|
+
name: string;
|
|
5
|
+
creation?: string;
|
|
6
|
+
modified?: string;
|
|
7
|
+
modifiedBy?: string;
|
|
8
|
+
owner?: string;
|
|
9
|
+
docStatus?: number;
|
|
10
|
+
idx?: number;
|
|
11
|
+
}
|
|
12
|
+
interface FrappeChildDoc extends FrappeDoc {
|
|
13
|
+
parent: string;
|
|
14
|
+
parentType: string;
|
|
15
|
+
parentField: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface Brand {
|
|
19
|
+
brandImage?: string;
|
|
20
|
+
}
|
|
21
|
+
interface NavbarItem {
|
|
22
|
+
label: string;
|
|
23
|
+
enableDropdown: boolean;
|
|
24
|
+
enableLink: boolean;
|
|
25
|
+
link?: string;
|
|
26
|
+
dropdownDescription?: string;
|
|
27
|
+
dropdownCta?: string;
|
|
28
|
+
groups?: NavbarSubItemGroup[];
|
|
29
|
+
}
|
|
30
|
+
interface NavbarSubItemGroup {
|
|
31
|
+
title?: string;
|
|
32
|
+
items: NavbarSubItem[];
|
|
33
|
+
}
|
|
34
|
+
interface NavbarSubItem {
|
|
35
|
+
label: string;
|
|
36
|
+
description?: string;
|
|
37
|
+
image?: string;
|
|
38
|
+
link?: string;
|
|
39
|
+
}
|
|
40
|
+
interface Topbar {
|
|
41
|
+
topbarEnabled?: boolean;
|
|
42
|
+
items: TopbarItem[];
|
|
43
|
+
}
|
|
44
|
+
interface TopbarItem {
|
|
45
|
+
icon?: string;
|
|
46
|
+
label: string;
|
|
47
|
+
link?: string;
|
|
48
|
+
}
|
|
49
|
+
interface Header {
|
|
50
|
+
brand: Brand;
|
|
51
|
+
headerType?: string;
|
|
52
|
+
tabs: NavbarItem[];
|
|
53
|
+
topbar: Topbar;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
interface FooterItemGroup {
|
|
57
|
+
title: string;
|
|
58
|
+
items: FooterItem[];
|
|
59
|
+
}
|
|
60
|
+
interface FooterItem {
|
|
61
|
+
label: string;
|
|
62
|
+
link?: string;
|
|
63
|
+
}
|
|
64
|
+
interface Footer {
|
|
65
|
+
footerType?: string;
|
|
66
|
+
groups: FooterItemGroup[];
|
|
67
|
+
copyright?: string;
|
|
68
|
+
address?: string;
|
|
69
|
+
country?: string;
|
|
70
|
+
phone?: string;
|
|
71
|
+
email?: string;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
interface Globals {
|
|
75
|
+
header: Header;
|
|
76
|
+
footer: Footer;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
interface Hero {
|
|
80
|
+
type: string;
|
|
81
|
+
data: Record<string, unknown>;
|
|
82
|
+
}
|
|
83
|
+
interface Block {
|
|
84
|
+
type: string;
|
|
85
|
+
data?: Record<string, unknown>;
|
|
86
|
+
}
|
|
87
|
+
interface Page {
|
|
88
|
+
slug: string;
|
|
89
|
+
hero?: Hero;
|
|
90
|
+
blocks: Block[];
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
interface AuthOptions {
|
|
94
|
+
token?: string;
|
|
95
|
+
apiKey?: {
|
|
96
|
+
key: string;
|
|
97
|
+
secret: string;
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
declare function getPage(baseUrl: string, slug: string, auth?: AuthOptions): Promise<Page>;
|
|
102
|
+
|
|
103
|
+
interface AaveFeatureSlidesData {
|
|
104
|
+
feature1Title: string;
|
|
105
|
+
feature1Description: string;
|
|
106
|
+
feature1Cta?: string;
|
|
107
|
+
feature2Title: string;
|
|
108
|
+
feature2Description: string;
|
|
109
|
+
feature2Cta?: string;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
interface Item {
|
|
113
|
+
itemCode: string;
|
|
114
|
+
region: string;
|
|
115
|
+
grade: string;
|
|
116
|
+
gradeIssuer: string;
|
|
117
|
+
color: string;
|
|
118
|
+
storage: string;
|
|
119
|
+
memory: string;
|
|
120
|
+
network: string;
|
|
121
|
+
}
|
|
122
|
+
interface ItemVariant extends Item {
|
|
123
|
+
itemVariant: string;
|
|
124
|
+
}
|
|
125
|
+
interface ModelNumber {
|
|
126
|
+
modelNumber: string;
|
|
127
|
+
simCardType: string;
|
|
128
|
+
}
|
|
129
|
+
interface Colour {
|
|
130
|
+
name: string;
|
|
131
|
+
color: string;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
interface Category {
|
|
135
|
+
name: string;
|
|
136
|
+
categoryName: string;
|
|
137
|
+
sequenceId: number;
|
|
138
|
+
itemCode: string[];
|
|
139
|
+
itemGroup: string[];
|
|
140
|
+
brand: string[];
|
|
141
|
+
os: string[];
|
|
142
|
+
}
|
|
143
|
+
interface Product extends Item {
|
|
144
|
+
name: string;
|
|
145
|
+
image: string;
|
|
146
|
+
}
|
|
147
|
+
interface ProductVariant extends ItemVariant {
|
|
148
|
+
id: string;
|
|
149
|
+
specs: Record<string, string>;
|
|
150
|
+
price: number;
|
|
151
|
+
stock: number;
|
|
152
|
+
}
|
|
153
|
+
interface ShopContext {
|
|
154
|
+
title?: string;
|
|
155
|
+
categories?: Category[];
|
|
156
|
+
selectedCategory?: Category;
|
|
157
|
+
grades?: string[];
|
|
158
|
+
selectedGrade?: string;
|
|
159
|
+
products: Product[];
|
|
160
|
+
}
|
|
161
|
+
interface ProductContext {
|
|
162
|
+
currency: string;
|
|
163
|
+
product: Product;
|
|
164
|
+
specs: Record<string, string[]>;
|
|
165
|
+
variants: ProductVariant[];
|
|
166
|
+
modelNumbers: Record<string, ModelNumber>;
|
|
167
|
+
colours: Record<string, Colour>;
|
|
168
|
+
variantImages: Record<string, string[]>;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
declare function getShopContext(baseUrl: string, params?: {
|
|
172
|
+
categoryName?: string;
|
|
173
|
+
gradeName?: string;
|
|
174
|
+
}, auth?: AuthOptions): Promise<ShopContext>;
|
|
175
|
+
declare function getProductContext(baseUrl: string, productName: string, auth?: AuthOptions): Promise<ProductContext>;
|
|
176
|
+
|
|
177
|
+
declare function toDescription(modelNumber: ModelNumber): string | null;
|
|
178
|
+
|
|
179
|
+
declare function equalsIgnoreCase(str1: string, str2: string): boolean;
|
|
180
|
+
|
|
181
|
+
export { type AaveFeatureSlidesData, type Block, type Brand, type Category, type Colour, type Footer, type FooterItem, type FooterItemGroup, type FrappeChildDoc, type FrappeDoc, type Globals, type Header, type Hero, type Item, type ItemVariant, type ModelNumber, type NavbarItem, type NavbarSubItem, type NavbarSubItemGroup, type Page, type Product, type ProductContext, type ProductVariant, type ShopContext, type Topbar, type TopbarItem, equalsIgnoreCase, getPage, getProductContext, getShopContext, toDescription };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,97 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { decamelizeKeys, camelizeKeys } from 'humps';
|
|
2
|
+
export { decamelize as camelToSnake, decamelizeKeys as objectCamelToSnake, camelizeKeys as objectSnakeToCamel, camelize as snakeToCamel } from 'humps';
|
|
3
|
+
|
|
4
|
+
async function request(baseUrl, endpoint, options = {}, auth) {
|
|
5
|
+
const url = `${baseUrl}${endpoint}`;
|
|
6
|
+
const headers = {
|
|
7
|
+
"Content-Type": "application/json",
|
|
8
|
+
Accept: "application/json",
|
|
9
|
+
...options.headers
|
|
10
|
+
};
|
|
11
|
+
if (auth?.token) {
|
|
12
|
+
headers["Authorization"] = `Bearer ${auth.token}`;
|
|
13
|
+
} else if (auth?.apiKey) {
|
|
14
|
+
headers["Authorization"] = `token ${auth.apiKey.key}:${auth.apiKey.secret}`;
|
|
15
|
+
}
|
|
16
|
+
const response = await fetch(url, {
|
|
17
|
+
...options,
|
|
18
|
+
headers,
|
|
19
|
+
credentials: "include"
|
|
20
|
+
});
|
|
21
|
+
const rawData = await response.json();
|
|
22
|
+
if (!response.ok || rawData.exc) {
|
|
23
|
+
const errorMessage = rawData._error_message || rawData.exc || "Request failed";
|
|
24
|
+
const error = new Error(errorMessage);
|
|
25
|
+
error.message = errorMessage;
|
|
26
|
+
error.statusCode = response.status;
|
|
27
|
+
if (rawData.exc) {
|
|
28
|
+
error.exc = rawData.exc;
|
|
29
|
+
}
|
|
30
|
+
if (rawData._server_messages) {
|
|
31
|
+
error.serverMessages = rawData._server_messages;
|
|
32
|
+
}
|
|
33
|
+
if (rawData.exc_type) {
|
|
34
|
+
error.excType = rawData.exc_type;
|
|
35
|
+
}
|
|
36
|
+
throw error;
|
|
37
|
+
}
|
|
38
|
+
const result = rawData.message ?? rawData;
|
|
39
|
+
return camelizeKeys(result);
|
|
4
40
|
}
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
41
|
+
async function frappeCall(baseUrl, method, args, auth) {
|
|
42
|
+
const snakeArgs = decamelizeKeys(args ?? {});
|
|
43
|
+
return request(
|
|
44
|
+
baseUrl,
|
|
45
|
+
`/api/method/${method}`,
|
|
46
|
+
{
|
|
47
|
+
method: "POST",
|
|
48
|
+
body: JSON.stringify(snakeArgs)
|
|
49
|
+
},
|
|
50
|
+
auth
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
async function getDoc(baseUrl, doctype, name, auth) {
|
|
54
|
+
const endpoint = `/api/resource/${doctype}/${encodeURIComponent(name)}`;
|
|
55
|
+
const response = await request(baseUrl, endpoint, {}, auth);
|
|
56
|
+
return response.data;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// src/design/page/api.ts
|
|
60
|
+
async function getPage(baseUrl, slug, auth) {
|
|
61
|
+
return getDoc(baseUrl, "Design Page", slug, auth);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// src/utils/catalog.ts
|
|
65
|
+
function toDescription(modelNumber) {
|
|
66
|
+
if (!modelNumber) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
return modelNumber.simCardType;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// src/utils/types.ts
|
|
73
|
+
function equalsIgnoreCase(str1, str2) {
|
|
74
|
+
return str1.localeCompare(str2, void 0, { sensitivity: "accent" }) === 0;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// src/lasterp/shop/api.ts
|
|
78
|
+
async function getShopContext(baseUrl, params, auth) {
|
|
79
|
+
return frappeCall(
|
|
80
|
+
baseUrl,
|
|
81
|
+
"lasterp.shop.controllers.shop_controller.get_context",
|
|
82
|
+
params,
|
|
83
|
+
auth
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
async function getProductContext(baseUrl, productName, auth) {
|
|
87
|
+
return frappeCall(
|
|
88
|
+
baseUrl,
|
|
89
|
+
"lasterp.shop.controllers.product_controller.get_context",
|
|
90
|
+
{ productName },
|
|
91
|
+
auth
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export { equalsIgnoreCase, getPage, getProductContext, getShopContext, toDescription };
|
|
96
|
+
//# sourceMappingURL=index.js.map
|
|
97
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client/core.ts","../src/design/page/api.ts","../src/utils/catalog.ts","../src/utils/types.ts","../src/lasterp/shop/api.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { camelizeKeys, decamelizeKeys } from 'humps';\nimport type { FrappeResponse, FrappeError, AuthOptions } from './types';\n\nasync function request<T = any>(\n baseUrl: string,\n endpoint: string,\n options: RequestInit = {},\n auth?: AuthOptions\n): Promise<T> {\n const url = `${baseUrl}${endpoint}`;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n ...(options.headers as Record<string, string>),\n };\n\n if (auth?.token) {\n headers['Authorization'] = `Bearer ${auth.token}`;\n } else if (auth?.apiKey) {\n headers['Authorization'] = `token ${auth.apiKey.key}:${auth.apiKey.secret}`;\n }\n\n const response = await fetch(url, {\n ...options,\n headers,\n credentials: 'include',\n });\n\n const rawData: FrappeResponse<any> = await response.json();\n\n if (!response.ok || rawData.exc) {\n // Create a proper Error object for better serialization in Next.js\n const errorMessage = rawData._error_message || rawData.exc || 'Request failed';\n const error = new Error(errorMessage) as Error & FrappeError;\n\n error.message = errorMessage;\n error.statusCode = response.status;\n\n if (rawData.exc) {\n error.exc = rawData.exc;\n }\n\n if (rawData._server_messages) {\n error.serverMessages = rawData._server_messages;\n }\n\n if (rawData.exc_type) {\n error.excType = rawData.exc_type;\n }\n\n throw error;\n }\n\n const result = rawData.message ?? rawData;\n return camelizeKeys(result) as T;\n}\n\nexport async function frappeCall<T = any>(\n baseUrl: string,\n method: string,\n args?: Record<string, any>,\n auth?: AuthOptions\n): Promise<T> {\n const snakeArgs = decamelizeKeys(args ?? {});\n\n return request<T>(\n baseUrl,\n `/api/method/${method}`,\n {\n method: 'POST',\n body: JSON.stringify(snakeArgs),\n },\n auth\n );\n}\n\nexport async function frappeCallGet<T = any>(\n baseUrl: string,\n method: string,\n args?: Record<string, any>,\n auth?: AuthOptions\n): Promise<T> {\n const snakeArgs = decamelizeKeys(args ?? {});\n const queryParams = new URLSearchParams();\n\n Object.entries(snakeArgs).forEach(([key, value]) => {\n queryParams.append(\n key,\n typeof value === 'string' ? value : JSON.stringify(value)\n );\n });\n\n const endpoint = `/api/method/${method}?${queryParams.toString()}`;\n return request<T>(baseUrl, endpoint, { method: 'GET' }, auth);\n}\n\nexport async function getList<T = any>(\n baseUrl: string,\n params: {\n doctype: string;\n fields?: string[];\n filters?: Record<string, any>;\n orderBy?: string;\n limitStart?: number;\n limitPageLength?: number;\n },\n auth?: AuthOptions\n): Promise<T[]> {\n const {\n doctype,\n fields = ['name'],\n filters = {},\n orderBy = 'modified desc',\n limitStart = 0,\n limitPageLength = 20,\n } = params;\n\n const snakeFilters = decamelizeKeys(filters);\n\n const queryParams = new URLSearchParams({\n fields: JSON.stringify(fields),\n filters: JSON.stringify(snakeFilters),\n order_by: orderBy,\n limit_start: limitStart.toString(),\n limit_page_length: limitPageLength.toString(),\n });\n\n const endpoint = `/api/resource/${doctype}?${queryParams.toString()}`;\n const response = await request<{ data: T[] }>(baseUrl, endpoint, {}, auth);\n return response.data || [];\n}\n\nexport async function getDoc<T = any>(\n baseUrl: string,\n doctype: string,\n name: string,\n auth?: AuthOptions\n): Promise<T> {\n const endpoint = `/api/resource/${doctype}/${encodeURIComponent(name)}`;\n const response = await request<{ data: T }>(baseUrl, endpoint, {}, auth);\n return response.data;\n}\n\nexport async function createDoc<T = any>(\n baseUrl: string,\n doctype: string,\n doc: Record<string, any>,\n auth?: AuthOptions\n): Promise<T> {\n const snakeDoc = decamelizeKeys(doc);\n const endpoint = `/api/resource/${doctype}`;\n const response = await request<{ data: T }>(\n baseUrl,\n endpoint,\n {\n method: 'POST',\n body: JSON.stringify(snakeDoc),\n },\n auth\n );\n return response.data;\n}\n\nexport async function updateDoc<T = any>(\n baseUrl: string,\n doctype: string,\n name: string,\n doc: Record<string, any>,\n auth?: AuthOptions\n): Promise<T> {\n const snakeDoc = decamelizeKeys(doc);\n const endpoint = `/api/resource/${doctype}/${encodeURIComponent(name)}`;\n const response = await request<{ data: T }>(\n baseUrl,\n endpoint,\n {\n method: 'PUT',\n body: JSON.stringify(snakeDoc),\n },\n auth\n );\n return response.data;\n}\n\nexport async function deleteDoc(\n baseUrl: string,\n doctype: string,\n name: string,\n auth?: AuthOptions\n): Promise<void> {\n const endpoint = `/api/resource/${doctype}/${encodeURIComponent(name)}`;\n await request(\n baseUrl,\n endpoint,\n {\n method: 'DELETE',\n },\n auth\n );\n}\n\nexport async function getValue<T = any>(\n baseUrl: string,\n doctype: string,\n name: string,\n fieldname: string,\n auth?: AuthOptions\n): Promise<T> {\n const endpoint = `/api/resource/${doctype}/${encodeURIComponent(name)}?fields=[\"${fieldname}\"]`;\n const response = await request<{ data: Record<string, T> }>(\n baseUrl,\n endpoint,\n {},\n auth\n );\n const value = response.data[fieldname];\n\n if (value === undefined) {\n throw new Error(\n `Field \"${fieldname}\" not found in document \"${doctype}/${name}\"`\n );\n }\n\n return value;\n}\n\nexport async function setValue<T = any>(\n baseUrl: string,\n doctype: string,\n name: string,\n fieldname: string,\n value: any,\n auth?: AuthOptions\n): Promise<T> {\n return updateDoc<T>(baseUrl, doctype, name, { [fieldname]: value }, auth);\n}\n\nexport async function getCount(\n baseUrl: string,\n doctype: string,\n filters: Record<string, any> = {},\n auth?: AuthOptions\n): Promise<number> {\n return frappeCall<number>(\n baseUrl,\n 'frappe.client.get_count',\n {\n doctype,\n filters,\n },\n auth\n );\n}\n\nexport async function getCurrentUser(\n baseUrl: string,\n auth?: AuthOptions\n): Promise<any> {\n return frappeCallGet(baseUrl, 'frappe.auth.get_logged_user', {}, auth);\n}\n","import { getDoc } from '../../client/core'\nimport type { AuthOptions } from '../../client/types'\nimport type { Page } from './types'\n\nexport async function getPage(\n baseUrl: string,\n slug: string,\n auth?: AuthOptions\n): Promise<Page> {\n return getDoc<Page>(baseUrl, 'Design Page', slug, auth)\n}\n","import type {ModelNumber} from \"../lasterp\";\n\nexport function toDescription(modelNumber: ModelNumber) {\n if (!modelNumber) {\n return null;\n }\n return modelNumber.simCardType;\n}\n","export function equalsIgnoreCase(str1: string, str2: string): boolean {\n return str1.localeCompare(str2, undefined, { sensitivity: 'accent' }) === 0;\n};\n","import { frappeCall } from '../../client/core';\nimport type { AuthOptions } from '../../client/types';\nimport type { ShopContext, ProductContext } from './types';\n\nexport async function getShopContext(\n baseUrl: string,\n params?: {\n categoryName?: string;\n gradeName?: string;\n },\n auth?: AuthOptions\n): Promise<ShopContext> {\n return frappeCall<ShopContext>(\n baseUrl,\n 'lasterp.shop.controllers.shop_controller.get_context',\n params,\n auth\n );\n}\n\nexport async function getProductContext(\n baseUrl: string,\n productName: string,\n auth?: AuthOptions\n): Promise<ProductContext> {\n return frappeCall<ProductContext>(\n baseUrl,\n 'lasterp.shop.controllers.product_controller.get_context',\n { productName },\n auth\n );\n}\n"]}
|
package/dist/node/index.d.ts
CHANGED
|
@@ -604,7 +604,7 @@ interface VariantSelectorOption {
|
|
|
604
604
|
}
|
|
605
605
|
interface VariantSelectorResult {
|
|
606
606
|
variantId?: string;
|
|
607
|
-
onOptionSelect: (
|
|
607
|
+
onOptionSelect: (key: string, value: string) => void;
|
|
608
608
|
getOptions: (key: string) => VariantSelectorOption[];
|
|
609
609
|
}
|
|
610
610
|
declare const useVariantSelector: <T extends {
|
|
@@ -621,10 +621,12 @@ interface Product {
|
|
|
621
621
|
description: string;
|
|
622
622
|
}
|
|
623
623
|
interface ProductVariant extends ItemVariant {
|
|
624
|
+
name: string;
|
|
624
625
|
currency: string;
|
|
625
626
|
rate: number;
|
|
626
627
|
qty: number;
|
|
627
628
|
images: string[];
|
|
629
|
+
specs: Record<string, string>;
|
|
628
630
|
}
|
|
629
631
|
interface ShopContext {
|
|
630
632
|
categories: Category[];
|
|
@@ -636,9 +638,7 @@ interface ShopContext {
|
|
|
636
638
|
interface ProductContext {
|
|
637
639
|
product: Product;
|
|
638
640
|
specs: Record<string, string[]>;
|
|
639
|
-
variants: ProductVariant
|
|
640
|
-
specs: Record<string, string>;
|
|
641
|
-
}[];
|
|
641
|
+
variants: ProductVariant[];
|
|
642
642
|
models: Model[];
|
|
643
643
|
colors: Colour[];
|
|
644
644
|
}
|
package/dist/node/index.js
CHANGED
|
@@ -466,7 +466,7 @@ var useFrappeUpdateDoc = () => {
|
|
|
466
466
|
};
|
|
467
467
|
};
|
|
468
468
|
// src/hooks/use-variant-selector/hook.ts
|
|
469
|
-
import {
|
|
469
|
+
import { useMemo as useMemo2, useState as useState5 } from "react";
|
|
470
470
|
|
|
471
471
|
// src/hooks/use-variant-selector/utils.ts
|
|
472
472
|
function findVariant(variants, specs, caseInsensitive) {
|
|
@@ -532,13 +532,13 @@ var useVariantSelector = (props) => {
|
|
|
532
532
|
});
|
|
533
533
|
return result;
|
|
534
534
|
}, [variants, attributes, selectedSpecs]);
|
|
535
|
-
const onOptionSelect =
|
|
535
|
+
const onOptionSelect = (key, value) => {
|
|
536
536
|
setSelectedSpecs((prev) => {
|
|
537
537
|
const specs = { ...prev };
|
|
538
|
-
specs[
|
|
538
|
+
specs[key] = value;
|
|
539
539
|
return specs;
|
|
540
540
|
});
|
|
541
|
-
}
|
|
541
|
+
};
|
|
542
542
|
return {
|
|
543
543
|
variantId,
|
|
544
544
|
onOptionSelect,
|
package/dist/rn/index.d.ts
CHANGED
|
@@ -604,7 +604,7 @@ interface VariantSelectorOption {
|
|
|
604
604
|
}
|
|
605
605
|
interface VariantSelectorResult {
|
|
606
606
|
variantId?: string;
|
|
607
|
-
onOptionSelect: (
|
|
607
|
+
onOptionSelect: (key: string, value: string) => void;
|
|
608
608
|
getOptions: (key: string) => VariantSelectorOption[];
|
|
609
609
|
}
|
|
610
610
|
declare const useVariantSelector: <T extends {
|
|
@@ -621,10 +621,12 @@ interface Product {
|
|
|
621
621
|
description: string;
|
|
622
622
|
}
|
|
623
623
|
interface ProductVariant extends ItemVariant {
|
|
624
|
+
name: string;
|
|
624
625
|
currency: string;
|
|
625
626
|
rate: number;
|
|
626
627
|
qty: number;
|
|
627
628
|
images: string[];
|
|
629
|
+
specs: Record<string, string>;
|
|
628
630
|
}
|
|
629
631
|
interface ShopContext {
|
|
630
632
|
categories: Category[];
|
|
@@ -636,9 +638,7 @@ interface ShopContext {
|
|
|
636
638
|
interface ProductContext {
|
|
637
639
|
product: Product;
|
|
638
640
|
specs: Record<string, string[]>;
|
|
639
|
-
variants: ProductVariant
|
|
640
|
-
specs: Record<string, string>;
|
|
641
|
-
}[];
|
|
641
|
+
variants: ProductVariant[];
|
|
642
642
|
models: Model[];
|
|
643
643
|
colors: Colour[];
|
|
644
644
|
}
|
package/dist/rn/index.js
CHANGED
|
@@ -466,7 +466,7 @@ var useFrappeUpdateDoc = () => {
|
|
|
466
466
|
};
|
|
467
467
|
};
|
|
468
468
|
// src/hooks/use-variant-selector/hook.ts
|
|
469
|
-
import {
|
|
469
|
+
import { useMemo as useMemo2, useState as useState5 } from "react";
|
|
470
470
|
|
|
471
471
|
// src/hooks/use-variant-selector/utils.ts
|
|
472
472
|
function findVariant(variants, specs, caseInsensitive) {
|
|
@@ -532,13 +532,13 @@ var useVariantSelector = (props) => {
|
|
|
532
532
|
});
|
|
533
533
|
return result;
|
|
534
534
|
}, [variants, attributes, selectedSpecs]);
|
|
535
|
-
const onOptionSelect =
|
|
535
|
+
const onOptionSelect = (key, value) => {
|
|
536
536
|
setSelectedSpecs((prev) => {
|
|
537
537
|
const specs = { ...prev };
|
|
538
|
-
specs[
|
|
538
|
+
specs[key] = value;
|
|
539
539
|
return specs;
|
|
540
540
|
});
|
|
541
|
-
}
|
|
541
|
+
};
|
|
542
542
|
return {
|
|
543
543
|
variantId,
|
|
544
544
|
onOptionSelect,
|