arky-sdk 0.1.0 → 0.1.1

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.
Files changed (104) hide show
  1. package/dist/config-CPkOgumU.d.cts +16 -0
  2. package/dist/config-CPkOgumU.d.ts +16 -0
  3. package/dist/index.cjs +1517 -0
  4. package/dist/index.cjs.map +1 -0
  5. package/dist/index.d.cts +268 -0
  6. package/dist/index.d.ts +268 -26
  7. package/dist/index.js +1457 -56
  8. package/dist/index.js.map +1 -0
  9. package/dist/stores.cjs +2148 -0
  10. package/dist/stores.cjs.map +1 -0
  11. package/dist/stores.d.cts +218 -0
  12. package/dist/stores.d.ts +218 -0
  13. package/dist/stores.js +2111 -0
  14. package/dist/stores.js.map +1 -0
  15. package/dist/types.cjs +13 -0
  16. package/dist/types.cjs.map +1 -0
  17. package/dist/{types/index.d.ts → types.d.cts} +25 -24
  18. package/dist/types.d.ts +245 -0
  19. package/dist/types.js +11 -0
  20. package/dist/types.js.map +1 -0
  21. package/dist/utils.cjs +725 -0
  22. package/dist/utils.cjs.map +1 -0
  23. package/dist/utils.d.cts +9 -0
  24. package/dist/utils.d.ts +9 -0
  25. package/dist/utils.js +680 -0
  26. package/dist/utils.js.map +1 -0
  27. package/dist/validation-C9UAYKke.d.cts +245 -0
  28. package/dist/validation-DIvAzYjG.d.ts +245 -0
  29. package/package.json +17 -11
  30. package/dist/api/cms.d.ts +0 -19
  31. package/dist/api/cms.d.ts.map +0 -1
  32. package/dist/api/cms.js +0 -41
  33. package/dist/api/eshop.d.ts +0 -89
  34. package/dist/api/eshop.d.ts.map +0 -1
  35. package/dist/api/eshop.js +0 -183
  36. package/dist/api/index.d.ts +0 -6
  37. package/dist/api/index.d.ts.map +0 -1
  38. package/dist/api/index.js +0 -5
  39. package/dist/api/newsletter.d.ts +0 -32
  40. package/dist/api/newsletter.d.ts.map +0 -1
  41. package/dist/api/newsletter.js +0 -70
  42. package/dist/api/reservation.d.ts +0 -84
  43. package/dist/api/reservation.d.ts.map +0 -1
  44. package/dist/api/reservation.js +0 -239
  45. package/dist/config.d.ts +0 -15
  46. package/dist/config.d.ts.map +0 -1
  47. package/dist/config.js +0 -20
  48. package/dist/index.d.ts.map +0 -1
  49. package/dist/services/auth.d.ts +0 -17
  50. package/dist/services/auth.d.ts.map +0 -1
  51. package/dist/services/auth.js +0 -62
  52. package/dist/services/http.d.ts +0 -20
  53. package/dist/services/http.d.ts.map +0 -1
  54. package/dist/services/http.js +0 -73
  55. package/dist/stores/business.d.ts +0 -28
  56. package/dist/stores/business.d.ts.map +0 -1
  57. package/dist/stores/business.js +0 -122
  58. package/dist/stores/cart.d.ts +0 -8
  59. package/dist/stores/cart.d.ts.map +0 -1
  60. package/dist/stores/cart.js +0 -20
  61. package/dist/stores/eshop.d.ts +0 -121
  62. package/dist/stores/eshop.d.ts.map +0 -1
  63. package/dist/stores/eshop.js +0 -377
  64. package/dist/stores/index.d.ts +0 -7
  65. package/dist/stores/index.d.ts.map +0 -1
  66. package/dist/stores/index.js +0 -19
  67. package/dist/stores/reservation.d.ts +0 -237
  68. package/dist/stores/reservation.d.ts.map +0 -1
  69. package/dist/stores/reservation.js +0 -853
  70. package/dist/types/index.d.ts.map +0 -1
  71. package/dist/types/index.js +0 -8
  72. package/dist/utils/blocks.d.ts +0 -30
  73. package/dist/utils/blocks.d.ts.map +0 -1
  74. package/dist/utils/blocks.js +0 -237
  75. package/dist/utils/currency.d.ts +0 -9
  76. package/dist/utils/currency.d.ts.map +0 -1
  77. package/dist/utils/currency.js +0 -99
  78. package/dist/utils/errors.d.ts +0 -121
  79. package/dist/utils/errors.d.ts.map +0 -1
  80. package/dist/utils/errors.js +0 -114
  81. package/dist/utils/i18n.d.ts +0 -5
  82. package/dist/utils/i18n.d.ts.map +0 -1
  83. package/dist/utils/i18n.js +0 -37
  84. package/dist/utils/index.d.ts +0 -9
  85. package/dist/utils/index.d.ts.map +0 -1
  86. package/dist/utils/index.js +0 -10
  87. package/dist/utils/price.d.ts +0 -33
  88. package/dist/utils/price.d.ts.map +0 -1
  89. package/dist/utils/price.js +0 -141
  90. package/dist/utils/queryParams.d.ts +0 -21
  91. package/dist/utils/queryParams.d.ts.map +0 -1
  92. package/dist/utils/queryParams.js +0 -47
  93. package/dist/utils/svg.d.ts +0 -17
  94. package/dist/utils/svg.d.ts.map +0 -1
  95. package/dist/utils/svg.js +0 -62
  96. package/dist/utils/text.d.ts +0 -26
  97. package/dist/utils/text.d.ts.map +0 -1
  98. package/dist/utils/text.js +0 -64
  99. package/dist/utils/timezone.d.ts +0 -9
  100. package/dist/utils/timezone.d.ts.map +0 -1
  101. package/dist/utils/timezone.js +0 -49
  102. package/dist/utils/validation.d.ts +0 -9
  103. package/dist/utils/validation.d.ts.map +0 -1
  104. package/dist/utils/validation.js +0 -44
package/dist/index.cjs ADDED
@@ -0,0 +1,1517 @@
1
+ 'use strict';
2
+
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __esm = (fn, res) => function __init() {
6
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
7
+ };
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+
13
+ // src/config.ts
14
+ var config_exports = {};
15
+ __export(config_exports, {
16
+ API_URL: () => exports.API_URL,
17
+ BUSINESS_ID: () => exports.BUSINESS_ID,
18
+ STORAGE_URL: () => exports.STORAGE_URL,
19
+ getGlobalConfig: () => getGlobalConfig,
20
+ setGlobalConfig: () => setGlobalConfig
21
+ });
22
+ function setGlobalConfig(config) {
23
+ globalConfig = config;
24
+ exports.API_URL = config.apiUrl;
25
+ exports.BUSINESS_ID = config.businessId;
26
+ exports.STORAGE_URL = config.storageUrl || "";
27
+ }
28
+ function getGlobalConfig() {
29
+ if (!globalConfig) {
30
+ throw new Error(
31
+ "Arky SDK not initialized. Call initArky() or create an ArkyClient instance."
32
+ );
33
+ }
34
+ return globalConfig;
35
+ }
36
+ var globalConfig; exports.API_URL = void 0; exports.BUSINESS_ID = void 0; exports.STORAGE_URL = void 0;
37
+ var init_config = __esm({
38
+ "src/config.ts"() {
39
+ globalConfig = null;
40
+ exports.API_URL = "";
41
+ exports.BUSINESS_ID = "";
42
+ exports.STORAGE_URL = "";
43
+ }
44
+ });
45
+
46
+ // src/index.ts
47
+ init_config();
48
+
49
+ // src/types/index.ts
50
+ var PaymentMethod = /* @__PURE__ */ ((PaymentMethod2) => {
51
+ PaymentMethod2["Cash"] = "CASH";
52
+ PaymentMethod2["CreditCard"] = "CREDIT_CARD";
53
+ PaymentMethod2["Free"] = "FREE";
54
+ return PaymentMethod2;
55
+ })(PaymentMethod || {});
56
+
57
+ // src/api/cms.ts
58
+ init_config();
59
+
60
+ // src/utils/queryParams.ts
61
+ function buildQueryString(params) {
62
+ const queryParts = [];
63
+ Object.entries(params).forEach(([key, value]) => {
64
+ if (value === null || value === void 0) {
65
+ return;
66
+ }
67
+ if (Array.isArray(value)) {
68
+ const jsonString = JSON.stringify(value);
69
+ queryParts.push(`${key}=${encodeURIComponent(jsonString)}`);
70
+ } else if (typeof value === "string") {
71
+ queryParts.push(`${key}=${encodeURIComponent(value)}`);
72
+ } else if (typeof value === "number" || typeof value === "boolean") {
73
+ queryParts.push(`${key}=${value}`);
74
+ } else if (typeof value === "object") {
75
+ const jsonString = JSON.stringify(value);
76
+ queryParts.push(`${key}=${encodeURIComponent(jsonString)}`);
77
+ }
78
+ });
79
+ return queryParts.length > 0 ? `?${queryParts.join("&")}` : "";
80
+ }
81
+ function appendQueryString(url, params) {
82
+ const queryString = buildQueryString(params);
83
+ return queryString ? `${url}${queryString}` : url;
84
+ }
85
+
86
+ // src/services/http.ts
87
+ async function get(url, options) {
88
+ try {
89
+ const finalUrl = options?.params ? appendQueryString(url, options.params) : url;
90
+ const response = await fetch(finalUrl);
91
+ if (!response.ok) {
92
+ throw new Error(`HTTP error! status: ${response.status}`);
93
+ }
94
+ const data = await response.json();
95
+ return {
96
+ value: data,
97
+ success: true
98
+ };
99
+ } catch (error) {
100
+ const errorMsg = error instanceof Error ? error.message : "Unknown error occurred";
101
+ return {
102
+ value: null,
103
+ success: false,
104
+ error: errorMsg
105
+ };
106
+ }
107
+ }
108
+ async function post(url, data, options) {
109
+ try {
110
+ const response = await fetch(url, {
111
+ method: "POST",
112
+ headers: {
113
+ "Content-Type": "application/json"
114
+ },
115
+ body: JSON.stringify(data)
116
+ });
117
+ if (!response.ok) {
118
+ throw new Error(`HTTP error! status: ${response.status}`);
119
+ }
120
+ const responseData = await response.json();
121
+ return {
122
+ value: responseData,
123
+ success: true
124
+ };
125
+ } catch (error) {
126
+ const errorMsg = error instanceof Error ? error.message : "Unknown error occurred";
127
+ return {
128
+ value: null,
129
+ success: false,
130
+ error: errorMsg
131
+ };
132
+ }
133
+ }
134
+ var httpClient = {
135
+ get,
136
+ post
137
+ };
138
+ var http_default = httpClient;
139
+
140
+ // src/api/cms.ts
141
+ var getCollection = async (id) => {
142
+ const url = `${exports.API_URL}/v1/businesses/${exports.BUSINESS_ID}/collections/${id}`;
143
+ const { value } = await http_default.get(url);
144
+ return value;
145
+ };
146
+ var getCollections = async ({ name = null, ids = null }) => {
147
+ const url = `${exports.API_URL}/v1/businesses/${exports.BUSINESS_ID}/collections`;
148
+ const response = await http_default.get(url, {
149
+ params: { name, ids }
150
+ });
151
+ return response.value;
152
+ };
153
+ var getCollectionEntries = async ({
154
+ collectionId,
155
+ limit,
156
+ cursor,
157
+ ids = null
158
+ }) => {
159
+ const url = `${exports.API_URL}/v1/businesses/${exports.BUSINESS_ID}/collections/${collectionId}/entries`;
160
+ const response = await http_default.get(url, {
161
+ params: { limit, cursor, ids }
162
+ });
163
+ return response.value;
164
+ };
165
+ var createCollectionEntry = async (collectionEntryData) => {
166
+ const url = `${exports.API_URL}/v1/businesses/${exports.BUSINESS_ID}/collections/${collectionEntryData.collectionId}/entries`;
167
+ const result = await http_default.post(url, collectionEntryData, {
168
+ successMessage: "Created successfully",
169
+ errorMessage: "Failed to create collection"
170
+ });
171
+ return result;
172
+ };
173
+ var getCollectionEntry = async ({ collectionId, id }) => {
174
+ const url = `${exports.API_URL}/v1/businesses/${exports.BUSINESS_ID}/collections/${collectionId}/entries/${id}`;
175
+ const response = await http_default.get(url);
176
+ return response;
177
+ };
178
+ var cmsApi = {
179
+ getCollection,
180
+ getCollections,
181
+ getCollectionEntries,
182
+ getCollectionEntry,
183
+ createCollectionEntry
184
+ };
185
+
186
+ // src/api/eshop.ts
187
+ init_config();
188
+
189
+ // src/api/reservation.ts
190
+ init_config();
191
+ var reservationApi = {
192
+ // Get quote for reservation parts
193
+ async getQuote({
194
+ token,
195
+ businessId,
196
+ market,
197
+ currency,
198
+ userId,
199
+ parts,
200
+ paymentMethod = "CASH",
201
+ promoCode
202
+ }) {
203
+ try {
204
+ const lines = parts.map((part) => ({
205
+ type: "SERVICE",
206
+ serviceId: part.serviceId,
207
+ quantity: 1
208
+ }));
209
+ const payload = {
210
+ businessId,
211
+ market,
212
+ currency,
213
+ userId,
214
+ paymentMethod,
215
+ lines,
216
+ promoCode: promoCode || void 0,
217
+ shippingMethodId: null
218
+ };
219
+ const res = await fetch(`${exports.API_URL}/v1/payments/quote`, {
220
+ method: "POST",
221
+ headers: {
222
+ "Content-Type": "application/json",
223
+ "Authorization": `Bearer ${token}`
224
+ },
225
+ body: JSON.stringify(payload)
226
+ });
227
+ const text = await res.text();
228
+ if (!res.ok) {
229
+ try {
230
+ const json = JSON.parse(text);
231
+ return { success: false, error: json.reason || json.error || "Failed to fetch quote", code: json.code };
232
+ } catch {
233
+ return { success: false, error: text || "Failed to fetch quote" };
234
+ }
235
+ }
236
+ const quote = text ? JSON.parse(text) : null;
237
+ return { success: true, data: quote };
238
+ } catch (e) {
239
+ return {
240
+ success: false,
241
+ error: e.message || "Failed to fetch quote"
242
+ };
243
+ }
244
+ },
245
+ // Get available slots for a service
246
+ async getAvailableSlots({
247
+ businessId,
248
+ serviceId,
249
+ from,
250
+ to,
251
+ limit = 1e3,
252
+ providerId = null
253
+ }) {
254
+ const url = `${exports.API_URL}/v1/businesses/${businessId}/services/${serviceId}/available-slots`;
255
+ const response = await http_default.get(url, {
256
+ params: {
257
+ from,
258
+ to,
259
+ limit,
260
+ providerId
261
+ }
262
+ });
263
+ if (response.success) {
264
+ const json = response.value;
265
+ return {
266
+ success: true,
267
+ data: json.data?.items || json.items || []
268
+ };
269
+ } else {
270
+ console.error("Error fetching available slots:", response.error);
271
+ return {
272
+ success: false,
273
+ error: response.error,
274
+ data: []
275
+ };
276
+ }
277
+ },
278
+ // Get all providers for a service
279
+ async getProviders({ businessId, serviceId, limit = 50 }) {
280
+ const url = `${exports.API_URL}/v1/businesses/${businessId}/providers`;
281
+ const response = await http_default.get(url, {
282
+ params: {
283
+ serviceId,
284
+ limit
285
+ }
286
+ });
287
+ if (response.success) {
288
+ const json = response.value;
289
+ return {
290
+ success: true,
291
+ data: json.items || []
292
+ };
293
+ } else {
294
+ console.error("Error loading providers:", response.error);
295
+ return {
296
+ success: false,
297
+ error: response.error,
298
+ data: []
299
+ };
300
+ }
301
+ },
302
+ // Get guest token or create a new one
303
+ async getGuestToken() {
304
+ try {
305
+ const res = await fetch(`${exports.API_URL}/v1/users/login`, {
306
+ method: "POST",
307
+ headers: { "Content-Type": "application/json" },
308
+ body: JSON.stringify({ provider: "GUEST" })
309
+ });
310
+ if (!res.ok) throw new Error("Guest login failed");
311
+ const json = await res.json();
312
+ return {
313
+ success: true,
314
+ data: { token: json.accessToken }
315
+ };
316
+ } catch (e) {
317
+ return {
318
+ success: false,
319
+ error: e.message
320
+ };
321
+ }
322
+ },
323
+ // Update user's phone number
324
+ async updateProfilePhone({ token, phoneNumber }) {
325
+ try {
326
+ const res = await fetch(`${exports.API_URL}/v1/users/update`, {
327
+ method: "PUT",
328
+ headers: {
329
+ "Content-Type": "application/json",
330
+ Authorization: `Bearer ${token}`
331
+ },
332
+ body: JSON.stringify({
333
+ phoneNumber,
334
+ phoneNumbers: [],
335
+ addresses: []
336
+ })
337
+ });
338
+ if (!res.ok) {
339
+ const error = await res.text() || res.statusText;
340
+ return {
341
+ success: false,
342
+ error
343
+ };
344
+ }
345
+ return {
346
+ success: true
347
+ };
348
+ } catch (e) {
349
+ return {
350
+ success: false,
351
+ error: e.message
352
+ };
353
+ }
354
+ },
355
+ // Verify phone number with code
356
+ async verifyPhoneCode({ token, phoneNumber, code }) {
357
+ try {
358
+ const res = await fetch(`${exports.API_URL}/v1/users/confirm/phone-number`, {
359
+ method: "PUT",
360
+ headers: {
361
+ "Content-Type": "application/json",
362
+ Authorization: `Bearer ${token}`
363
+ },
364
+ body: JSON.stringify({
365
+ phoneNumber,
366
+ code
367
+ })
368
+ });
369
+ if (!res.ok) {
370
+ const error = await res.text() || res.statusText;
371
+ return {
372
+ success: false,
373
+ error
374
+ };
375
+ }
376
+ return {
377
+ success: true
378
+ };
379
+ } catch (e) {
380
+ return {
381
+ success: false,
382
+ error: e.message
383
+ };
384
+ }
385
+ },
386
+ // Complete reservation checkout - Backend calculates currency from market
387
+ async checkout({
388
+ token,
389
+ businessId,
390
+ parts,
391
+ paymentMethod = "CASH",
392
+ blocks = [],
393
+ market = "US",
394
+ promoCode
395
+ }) {
396
+ try {
397
+ const payload = {
398
+ businessId,
399
+ blocks,
400
+ market,
401
+ parts: parts.map((p) => ({
402
+ serviceId: p.serviceId,
403
+ from: p.from,
404
+ to: p.to,
405
+ blocks: p.blocks,
406
+ reservationMethod: p.reservationMethod,
407
+ providerId: p.providerId
408
+ }))
409
+ };
410
+ if (paymentMethod !== void 0) {
411
+ payload.paymentMethod = paymentMethod;
412
+ }
413
+ if (promoCode) {
414
+ payload.promoCode = promoCode;
415
+ }
416
+ const res = await fetch(`${exports.API_URL}/v1/reservations/checkout`, {
417
+ method: "POST",
418
+ headers: {
419
+ "Content-Type": "application/json",
420
+ Authorization: `Bearer ${token}`
421
+ },
422
+ body: JSON.stringify(payload)
423
+ });
424
+ if (!res.ok) {
425
+ const error = await res.text() || res.statusText;
426
+ throw new Error(error);
427
+ }
428
+ const json = await res.json();
429
+ return {
430
+ success: true,
431
+ data: json
432
+ // Should include reservationId and clientSecret for payments
433
+ };
434
+ } catch (e) {
435
+ return {
436
+ success: false,
437
+ error: e.message
438
+ };
439
+ }
440
+ }
441
+ };
442
+
443
+ // src/api/eshop.ts
444
+ var eshopApi = {
445
+ // Get products
446
+ async getProducts({
447
+ businessId,
448
+ categoryIds = null,
449
+ status = "ACTIVE",
450
+ limit = 20,
451
+ cursor = null
452
+ }) {
453
+ const url = `${exports.API_URL}/v1/businesses/${encodeURIComponent(businessId)}/products`;
454
+ const response = await http_default.get(url, {
455
+ params: {
456
+ categoryIds: categoryIds && categoryIds.length > 0 ? categoryIds : void 0,
457
+ status,
458
+ limit,
459
+ cursor
460
+ }
461
+ });
462
+ if (response.success) {
463
+ const json = response.value;
464
+ return {
465
+ success: true,
466
+ data: json.items || [],
467
+ cursor: json.cursor,
468
+ total: json.total || 0
469
+ };
470
+ } else {
471
+ console.error("Error fetching products:", response.error);
472
+ return {
473
+ success: false,
474
+ error: response.error,
475
+ data: []
476
+ };
477
+ }
478
+ },
479
+ // Get product by slug
480
+ async getProductBySlug({ businessId, slug }) {
481
+ try {
482
+ const url = `${exports.API_URL}/v1/businesses/${encodeURIComponent(businessId)}/products/slug/${encodeURIComponent(businessId)}/${encodeURIComponent(slug)}`;
483
+ const res = await fetch(url);
484
+ if (!res.ok) throw new Error("Product not found");
485
+ const json = await res.json();
486
+ return {
487
+ success: true,
488
+ data: json
489
+ };
490
+ } catch (e) {
491
+ console.error("Error fetching product:", e);
492
+ return {
493
+ success: false,
494
+ error: e.message,
495
+ data: null
496
+ };
497
+ }
498
+ },
499
+ // Get quote for cart (pricing with promo codes, shipping, taxes)
500
+ async getQuote({
501
+ token,
502
+ businessId,
503
+ items,
504
+ market,
505
+ currency,
506
+ userId,
507
+ paymentMethod,
508
+ shippingMethodId,
509
+ promoCode
510
+ }) {
511
+ try {
512
+ const lines = items.map((item) => ({
513
+ type: "PRODUCT_VARIANT",
514
+ productId: item.productId,
515
+ variantId: item.variantId,
516
+ quantity: item.quantity
517
+ }));
518
+ const payload = {
519
+ businessId,
520
+ market,
521
+ currency,
522
+ userId,
523
+ paymentMethod,
524
+ lines,
525
+ ...shippingMethodId && { shippingMethodId },
526
+ ...promoCode && { promoCode }
527
+ };
528
+ const res = await fetch(`${exports.API_URL}/v1/payments/quote`, {
529
+ method: "POST",
530
+ headers: {
531
+ "Content-Type": "application/json",
532
+ Authorization: `Bearer ${token}`
533
+ },
534
+ body: JSON.stringify(payload)
535
+ });
536
+ const text = await res.text();
537
+ if (!res.ok) {
538
+ try {
539
+ const json = JSON.parse(text);
540
+ return { success: false, error: json.reason || json.error || res.statusText, code: json.code };
541
+ } catch {
542
+ return { success: false, error: text || res.statusText };
543
+ }
544
+ }
545
+ const quote = text ? JSON.parse(text) : null;
546
+ return { success: true, data: quote };
547
+ } catch (e) {
548
+ console.error("Quote fetch failed:", e);
549
+ return {
550
+ success: false,
551
+ error: e.message
552
+ };
553
+ }
554
+ },
555
+ // Checkout - Backend calculates currency from market
556
+ async checkout({
557
+ token,
558
+ businessId,
559
+ items,
560
+ paymentMethod,
561
+ blocks,
562
+ market = "US",
563
+ shippingMethodId,
564
+ promoCode,
565
+ paymentIntentId = null
566
+ }) {
567
+ try {
568
+ const payload = {
569
+ businessId,
570
+ items,
571
+ paymentMethod,
572
+ blocks,
573
+ market,
574
+ ...shippingMethodId && { shippingMethodId },
575
+ ...promoCode && { promoCode },
576
+ ...paymentIntentId && { paymentIntentId }
577
+ };
578
+ const res = await fetch(`${exports.API_URL}/v1/businesses/${encodeURIComponent(businessId)}/orders/checkout`, {
579
+ method: "POST",
580
+ headers: {
581
+ "Content-Type": "application/json",
582
+ Authorization: `Bearer ${token}`
583
+ },
584
+ body: JSON.stringify(payload)
585
+ });
586
+ const text = await res.text();
587
+ if (!res.ok) {
588
+ try {
589
+ const json2 = JSON.parse(text);
590
+ return { success: false, error: json2.reason || json2.error || res.statusText, code: json2.code };
591
+ } catch {
592
+ return { success: false, error: text || res.statusText };
593
+ }
594
+ }
595
+ const json = text ? JSON.parse(text) : null;
596
+ return { success: true, data: json };
597
+ } catch (e) {
598
+ return {
599
+ success: false,
600
+ error: e.message
601
+ };
602
+ }
603
+ },
604
+ // Create payment intent for Stripe
605
+ async createPaymentIntent({ amount, currency, businessId }) {
606
+ try {
607
+ const tokenResponse = await reservationApi.getGuestToken();
608
+ if (!tokenResponse.success || !tokenResponse.data) {
609
+ throw new Error("Failed to get guest token");
610
+ }
611
+ const token = tokenResponse.data.token;
612
+ const res = await fetch(`${exports.API_URL}/v1/businesses/${encodeURIComponent(businessId)}/payment/create-intent`, {
613
+ method: "POST",
614
+ headers: {
615
+ "Content-Type": "application/json",
616
+ Authorization: `Bearer ${token}`
617
+ },
618
+ body: JSON.stringify({
619
+ amount,
620
+ currency,
621
+ businessId
622
+ })
623
+ });
624
+ if (!res.ok) {
625
+ const error = await res.text() || res.statusText;
626
+ throw new Error(error);
627
+ }
628
+ const json = await res.json();
629
+ return {
630
+ success: true,
631
+ data: json
632
+ };
633
+ } catch (e) {
634
+ console.error("Payment intent creation failed:", e);
635
+ return {
636
+ success: false,
637
+ error: e.message
638
+ };
639
+ }
640
+ }
641
+ };
642
+
643
+ // src/api/newsletter.ts
644
+ var newsletterApi = {
645
+ async find(payload) {
646
+ const params = new URLSearchParams({
647
+ businessId: payload.business_id
648
+ });
649
+ const { API_URL: API_URL2 } = await Promise.resolve().then(() => (init_config(), config_exports));
650
+ const url = `${API_URL2}/v1/newsletters?${params.toString()}`;
651
+ const response = await fetch(url);
652
+ if (!response.ok) {
653
+ throw new Error(`HTTP error! status: ${response.status}`);
654
+ }
655
+ const backendResponse = await response.json();
656
+ return {
657
+ data: backendResponse.items || [],
658
+ meta: {
659
+ total: backendResponse.items?.length || 0,
660
+ page: 1,
661
+ per_page: backendResponse.items?.length || 0
662
+ }
663
+ };
664
+ },
665
+ async get(id) {
666
+ const { API_URL: API_URL2 } = await Promise.resolve().then(() => (init_config(), config_exports));
667
+ const url = `${API_URL2}/v1/newsletters/${id}`;
668
+ const response = await fetch(url);
669
+ if (!response.ok) {
670
+ throw new Error(`HTTP error! status: ${response.status}`);
671
+ }
672
+ return await response.json();
673
+ },
674
+ async subscribe(payload) {
675
+ try {
676
+ const { API_URL: API_URL2 } = await Promise.resolve().then(() => (init_config(), config_exports));
677
+ const url = `${API_URL2}/v1/newsletters/${payload.newsletterId}/subscribe`;
678
+ const response = await fetch(url, {
679
+ method: "POST",
680
+ headers: {
681
+ "Content-Type": "application/json"
682
+ },
683
+ body: JSON.stringify({
684
+ newsletterId: payload.newsletterId,
685
+ email: payload.email,
686
+ market: "US",
687
+ // Backend resolves currency from market
688
+ ...payload.customerId && { customerId: payload.customerId },
689
+ ...payload.payment && { payment: payload.payment }
690
+ })
691
+ });
692
+ if (!response.ok) {
693
+ const errorData = await response.json().catch(() => ({}));
694
+ throw new Error(errorData.message || `HTTP error! status: ${response.status}`);
695
+ }
696
+ const data = await response.json();
697
+ return {
698
+ success: true,
699
+ data
700
+ };
701
+ } catch (error) {
702
+ console.error("Newsletter subscription error:", error);
703
+ return {
704
+ success: false,
705
+ error: error instanceof Error ? error.message : "Failed to subscribe to newsletter"
706
+ };
707
+ }
708
+ }
709
+ };
710
+
711
+ // src/services/auth.ts
712
+ init_config();
713
+ async function getGuestToken(currentToken = null) {
714
+ if (currentToken) return currentToken;
715
+ const response = await reservationApi.getGuestToken();
716
+ if (response.success && response.data) {
717
+ return response.data.token;
718
+ }
719
+ throw new Error("Failed to get guest token");
720
+ }
721
+ async function updateProfilePhone(token, phoneNumber) {
722
+ if (!phoneNumber) {
723
+ throw new Error("Phone number is required");
724
+ }
725
+ const response = await reservationApi.updateProfilePhone({ token, phoneNumber });
726
+ if (response.success) {
727
+ return { success: true };
728
+ } else {
729
+ throw new Error(response.error || "Failed to send verification code");
730
+ }
731
+ }
732
+ async function verifyPhoneCode(token, phoneNumber, code) {
733
+ if (!code) {
734
+ throw new Error("Verification code is required");
735
+ }
736
+ const response = await reservationApi.verifyPhoneCode({ token, phoneNumber, code });
737
+ if (response.success) {
738
+ return { success: true };
739
+ } else {
740
+ throw new Error(response.error || "Invalid verification code");
741
+ }
742
+ }
743
+ async function getBusinessConfig(businessId) {
744
+ try {
745
+ const response = await fetch(`${exports.API_URL}/v1/businesses/${businessId}`, {
746
+ method: "GET",
747
+ headers: {
748
+ "Content-Type": "application/json"
749
+ }
750
+ });
751
+ if (!response.ok) {
752
+ throw new Error(`Failed to fetch business config: ${response.status}`);
753
+ }
754
+ const business = await response.json();
755
+ return {
756
+ success: true,
757
+ data: business
758
+ };
759
+ } catch (error) {
760
+ return {
761
+ success: false,
762
+ error: error.message
763
+ };
764
+ }
765
+ }
766
+
767
+ // src/utils/blocks.ts
768
+ init_config();
769
+ function getBlockLabel(block, locale = "en") {
770
+ if (!block) return "";
771
+ if (block.properties?.label) {
772
+ if (typeof block.properties.label === "object") {
773
+ return block.properties.label[locale] || block.properties.label.en || Object.values(block.properties.label)[0] || "";
774
+ }
775
+ if (typeof block.properties.label === "string") {
776
+ return block.properties.label;
777
+ }
778
+ }
779
+ return block.key?.replace(/_/g, " ").replace(/\b\w/g, (l) => l.toUpperCase()) || "";
780
+ }
781
+ function formatBlockValue(block) {
782
+ if (!block || block.value === null || block.value === void 0) {
783
+ return "";
784
+ }
785
+ switch (block.type) {
786
+ case "BOOLEAN":
787
+ return block.value ? "Yes" : "No";
788
+ case "NUMBER":
789
+ if (block.properties?.variant === "DATE" || block.properties?.variant === "DATE_TIME") {
790
+ try {
791
+ return new Date(block.value).toLocaleDateString();
792
+ } catch (e) {
793
+ return String(block.value);
794
+ }
795
+ }
796
+ return String(block.value);
797
+ case "RELATIONSHIP":
798
+ if (Array.isArray(block.value) && block.value.length > 0) {
799
+ const firstValue = block.value[0];
800
+ if (firstValue && firstValue.mimeType) {
801
+ return firstValue.name || firstValue.id || "Media";
802
+ }
803
+ return firstValue.title || firstValue.name || firstValue.id || "Entry";
804
+ }
805
+ return String(block.value);
806
+ default:
807
+ return String(block.value);
808
+ }
809
+ }
810
+ function prepareBlocksForSubmission(formData) {
811
+ const preparedBlocks = [];
812
+ Object.keys(formData).forEach((key) => {
813
+ if (formData[key] !== null && formData[key] !== void 0) {
814
+ preparedBlocks.push({
815
+ key,
816
+ value: [formData[key]]
817
+ });
818
+ }
819
+ });
820
+ return preparedBlocks;
821
+ }
822
+ function extractBlockValues(blocks) {
823
+ const values = {};
824
+ blocks.forEach((block) => {
825
+ if (block.value && block.value.length > 0) {
826
+ values[block.key] = block.value[0];
827
+ } else {
828
+ values[block.key] = null;
829
+ }
830
+ });
831
+ return values;
832
+ }
833
+ function getBlockTextValue(block, locale = "en") {
834
+ if (!block || !block.value || block.value.length === 0) return "";
835
+ const firstValue = block.value[0];
836
+ if (typeof firstValue === "object" && firstValue !== null) {
837
+ if (firstValue[locale]) return firstValue[locale];
838
+ if (firstValue.en) return firstValue.en;
839
+ const values = Object.values(firstValue);
840
+ return String(values[0] || "");
841
+ }
842
+ return String(firstValue);
843
+ }
844
+ var getBlockValue = (entry, blockKey) => {
845
+ if (!entry || !entry.blocks) return null;
846
+ const block = entry.blocks.find((f) => f.key === blockKey);
847
+ if (!block || !block.value || block.value.length === 0) return null;
848
+ return block.value[0];
849
+ };
850
+ var getBlockValues = (entry, blockKey) => {
851
+ if (!entry || !entry.blocks) return null;
852
+ const block = entry.blocks.find((f) => f.key === blockKey);
853
+ if (!block || !block.value || block.value.length === 0) return null;
854
+ return block.value;
855
+ };
856
+ function unwrapBlock(block, locale) {
857
+ if (!block?.type || block.value === void 0) return block;
858
+ if (block.type === "BLOCK") {
859
+ return block.value.map((obj) => {
860
+ const parsed = {};
861
+ for (const [k, v] of Object.entries(obj)) {
862
+ parsed[k] = unwrapBlock(v, locale);
863
+ }
864
+ return parsed;
865
+ });
866
+ }
867
+ const isLocalized = block.type === "TEXT";
868
+ const isList = block.properties?.ui === "list" || (block.properties?.maxValues ?? 1) > 1 || block.value.length > 1;
869
+ if (isList) {
870
+ return isLocalized ? block.value.map((v) => v[locale] || v["en"]) : [...block.value];
871
+ }
872
+ return isLocalized ? block.value[0][locale] || block.value[0]["en"] : block.value[0];
873
+ }
874
+ var getBlockObjectValues = (entry, blockKey, locale = "en") => {
875
+ if (!entry) {
876
+ return [];
877
+ }
878
+ const values = getBlockValues(entry, blockKey);
879
+ const parsed = values.map((obj) => {
880
+ const res = obj.value.reduce((acc, current) => {
881
+ acc[current.key] = unwrapBlock(current, locale);
882
+ return acc;
883
+ }, {});
884
+ return res;
885
+ });
886
+ return parsed;
887
+ };
888
+ var getBlockFromArray = (entry, blockKey, locale = "en") => {
889
+ if (!entry) {
890
+ return [];
891
+ }
892
+ const values = getBlockValues(entry, blockKey);
893
+ return values.reduce((acc, current) => {
894
+ acc[current.key] = unwrapBlock(current, locale);
895
+ return acc;
896
+ });
897
+ };
898
+ var getImageUrl = (imageBlock, isBlock = true) => {
899
+ if (!imageBlock) return null;
900
+ const storageUrl = "https://storage.arky.io/dev";
901
+ const isExternalUrl = (url) => {
902
+ return url.startsWith("http://") || url.startsWith("https://");
903
+ };
904
+ if (imageBlock.type === "RELATIONSHIP" && Array.isArray(imageBlock.value)) {
905
+ const mediaValue = imageBlock.value[0];
906
+ if (mediaValue && mediaValue.mimeType) {
907
+ if (mediaValue.resolutions && mediaValue.resolutions.original && mediaValue.resolutions.original.url) {
908
+ const url = mediaValue.resolutions.original.url;
909
+ return isExternalUrl(url) ? url : `${storageUrl}/${url}`;
910
+ }
911
+ if (mediaValue.url) {
912
+ return isExternalUrl(mediaValue.url) ? mediaValue.url : `${storageUrl}/${mediaValue.url}`;
913
+ }
914
+ }
915
+ return null;
916
+ }
917
+ if (isBlock) {
918
+ if (typeof imageBlock === "string") {
919
+ if (isExternalUrl(imageBlock)) {
920
+ return imageBlock;
921
+ }
922
+ return `${storageUrl}/${imageBlock}`;
923
+ }
924
+ if (imageBlock.url) {
925
+ if (isExternalUrl(imageBlock.url)) {
926
+ return imageBlock.url;
927
+ }
928
+ return `${storageUrl}/${imageBlock.url}`;
929
+ }
930
+ }
931
+ if (imageBlock.resolutions && imageBlock.resolutions.original && imageBlock.resolutions.original.url) {
932
+ const url = imageBlock.resolutions.original.url;
933
+ if (isExternalUrl(url)) {
934
+ return url;
935
+ }
936
+ return `${storageUrl}/${url}`;
937
+ }
938
+ return null;
939
+ };
940
+ function getGalleryThumbnail(gallery) {
941
+ if (!gallery?.length) return null;
942
+ const item = gallery.find((g) => g.settings.isThumbnail) || gallery[0];
943
+ const res = item.media.resolutions.thumbnail || item.media.resolutions.original;
944
+ return res?.url || null;
945
+ }
946
+ function thumbnailUrl(service) {
947
+ const storageUrl = exports.STORAGE_URL || "";
948
+ const path = getGalleryThumbnail(service.gallery);
949
+ return path ? `${storageUrl}/${path}` : null;
950
+ }
951
+ var translateMap = (labels, lang, fallback = "unknown") => {
952
+ let parsedLang = "en";
953
+ if (lang === "sr") {
954
+ parsedLang = "bih";
955
+ }
956
+ if (!labels) {
957
+ return fallback;
958
+ }
959
+ const label = labels[parsedLang];
960
+ if (!label) {
961
+ return fallback;
962
+ }
963
+ return label;
964
+ };
965
+
966
+ // src/utils/errors.ts
967
+ var ERROR_CODES = {
968
+ // General errors
969
+ "GENERAL.001": "GENERAL.BAD_REQUEST",
970
+ "GENERAL.002": "GENERAL.VALIDATION_ERROR",
971
+ "GENERAL.003": "GENERAL.FORBIDDEN_ERROR",
972
+ "GENERAL.004": "GENERAL.INTERNAL_SERVER_ERROR",
973
+ "GENERAL.005": "GENERAL.UNAUTHORIZED",
974
+ "GENERAL.006": "GENERAL.UNAUTHENTICATED",
975
+ // Google/OAuth errors
976
+ "GOOGLE.001": "GOOGLE.INVALID_ORIGIN_URI",
977
+ "GOOGLE.002": "GOOGLE.INVALID_REDIRECT_URI",
978
+ "GOOGLE.003": "GOOGLE.FAILED_TO_CALL_API",
979
+ "GOOGLE.004": "GOOGLE.FAILED_LOGIN",
980
+ "GOOGLE.005": "GOOGLE.FAILED_LOGOUT",
981
+ "GOOGLE.006": "GOOGLE.FAILED_REFRESH_TOKEN",
982
+ "GOOGLE.007": "GOOGLE.INVALID_PROVIDER_PASSED",
983
+ // User errors
984
+ "USER.001": "USER.NOT_FOUND",
985
+ "USER.002": "USER.FAILED_TO_CREATE",
986
+ "USER.003": "USER.FAILED_TO_UPDATE",
987
+ "USER.004": "USER.FAILED_TO_DELETE",
988
+ "USER.005": "USER.EMAIL_EXISTS",
989
+ "USER.006": "USER.FAILED_TO_GET_UPLOAD_URL",
990
+ // Business errors
991
+ "BUSINESS.001": "BUSINESS.NOT_FOUND",
992
+ "BUSINESS.002": "BUSINESS.FAILED_TO_CREATE",
993
+ "BUSINESS.003": "BUSINESS.FAILED_TO_UPDATE",
994
+ "BUSINESS.004": "BUSINESS.FAILED_TO_DELETE",
995
+ "BUSINESS.005": "BUSINESS.FAILED_TO_GET_UPLOAD_URL",
996
+ "BUSINESS.006": "BUSINESS.NAME_REQUIRED",
997
+ "BUSINESS.007": "BUSINESS.BUSINESS_ID_REQUIRED",
998
+ "BUSINESS.010": "BUSINESS.DESCRIPTION_REQUIRED",
999
+ "BUSINESS.011": "BUSINESS.SLUG_INVALID",
1000
+ // Provider errors
1001
+ "PROVIDER.001": "PROVIDER.NOT_FOUND",
1002
+ "PROVIDER.002": "PROVIDER.FAILED_TO_CREATE",
1003
+ "PROVIDER.003": "PROVIDER.FAILED_TO_UPDATE",
1004
+ "PROVIDER.004": "PROVIDER.FAILED_TO_DELETE",
1005
+ "PROVIDER.005": "PROVIDER.FAILED_TO_GET_UPLOAD_URL",
1006
+ "PROVIDER.006": "PROVIDER.NAME_REQUIRED",
1007
+ "PROVIDER.007": "PROVIDER.BUSINESS_ID_REQUIRED",
1008
+ "PROVIDER.008": "PROVIDER.DESCRIPTION_REQUIRED"
1009
+ };
1010
+ var ERROR_CONSTANTS = {
1011
+ GENERAL: {
1012
+ BAD_REQUEST: "GENERAL.BAD_REQUEST",
1013
+ VALIDATION_ERROR: "GENERAL.VALIDATION_ERROR",
1014
+ FORBIDDEN_ERROR: "GENERAL.FORBIDDEN_ERROR",
1015
+ INTERNAL_SERVER_ERROR: "GENERAL.INTERNAL_SERVER_ERROR",
1016
+ UNAUTHORIZED: "GENERAL.UNAUTHORIZED",
1017
+ UNAUTHENTICATED: "GENERAL.UNAUTHENTICATED"
1018
+ },
1019
+ USER: {
1020
+ NOT_FOUND: "USER.NOT_FOUND",
1021
+ FAILED_TO_CREATE: "USER.FAILED_TO_CREATE",
1022
+ FAILED_TO_UPDATE: "USER.FAILED_TO_UPDATE",
1023
+ FAILED_TO_DELETE: "USER.FAILED_TO_DELETE",
1024
+ EMAIL_EXISTS: "USER.EMAIL_EXISTS",
1025
+ FAILED_TO_GET_UPLOAD_URL: "USER.FAILED_TO_GET_UPLOAD_URL"
1026
+ },
1027
+ BUSINESS: {
1028
+ NOT_FOUND: "BUSINESS.NOT_FOUND",
1029
+ FAILED_TO_CREATE: "BUSINESS.FAILED_TO_CREATE",
1030
+ FAILED_TO_UPDATE: "BUSINESS.FAILED_TO_UPDATE",
1031
+ FAILED_TO_DELETE: "BUSINESS.FAILED_TO_DELETE",
1032
+ FAILED_TO_GET_UPLOAD_URL: "BUSINESS.FAILED_TO_GET_UPLOAD_URL",
1033
+ NAME_REQUIRED: "BUSINESS.NAME_REQUIRED",
1034
+ BUSINESS_ID_REQUIRED: "BUSINESS.BUSINESS_ID_REQUIRED",
1035
+ DESCRIPTION_REQUIRED: "BUSINESS.DESCRIPTION_REQUIRED",
1036
+ SLUG_INVALID: "BUSINESS.SLUG_INVALID"
1037
+ }
1038
+ };
1039
+ function getErrorMessage(code) {
1040
+ return ERROR_CODES[code] || code;
1041
+ }
1042
+ function isErrorCode(code) {
1043
+ return code in ERROR_CODES;
1044
+ }
1045
+ var transformErrors = (zodError) => {
1046
+ const customErrors = [];
1047
+ if (!zodError.issues) return customErrors;
1048
+ zodError.issues.forEach((issue) => {
1049
+ const field = issue.path.join(".");
1050
+ const message = issue.message;
1051
+ if (!customErrors.some(
1052
+ (customError) => customError.field === field && customError.message === message
1053
+ )) {
1054
+ customErrors.push({ field, message });
1055
+ }
1056
+ });
1057
+ return customErrors;
1058
+ };
1059
+ var convertServerErrorToRequestError = (serverError, renameRules) => {
1060
+ return {
1061
+ ...serverError,
1062
+ validationErrors: serverError.validationErrors.map((validationError) => {
1063
+ const field = renameRules && renameRules[validationError.field] ? renameRules[validationError.field] : validationError.field;
1064
+ return {
1065
+ field,
1066
+ message: ERROR_CODES[validationError.code] || "Unknown error"
1067
+ };
1068
+ })
1069
+ };
1070
+ };
1071
+ var errors = ERROR_CONSTANTS;
1072
+
1073
+ // src/utils/currency.ts
1074
+ function getCurrencySymbol(currency) {
1075
+ const currencySymbols = {
1076
+ USD: "$",
1077
+ EUR: "\u20AC",
1078
+ GBP: "\xA3",
1079
+ CAD: "C$",
1080
+ AUD: "A$",
1081
+ JPY: "\xA5",
1082
+ CHF: "CHF",
1083
+ SEK: "kr",
1084
+ NOK: "kr",
1085
+ DKK: "kr",
1086
+ PLN: "z\u0142",
1087
+ CZK: "K\u010D",
1088
+ HUF: "Ft",
1089
+ RON: "lei",
1090
+ BGN: "\u043B\u0432",
1091
+ HRK: "kn",
1092
+ RSD: "\u0434\u0438\u043D",
1093
+ BAM: "KM",
1094
+ MKD: "\u0434\u0435\u043D",
1095
+ ALL: "L",
1096
+ TRY: "\u20BA",
1097
+ RUB: "\u20BD",
1098
+ UAH: "\u20B4",
1099
+ BYN: "Br",
1100
+ CNY: "\xA5",
1101
+ INR: "\u20B9",
1102
+ KRW: "\u20A9",
1103
+ THB: "\u0E3F",
1104
+ VND: "\u20AB",
1105
+ SGD: "S$",
1106
+ MYR: "RM",
1107
+ IDR: "Rp",
1108
+ PHP: "\u20B1",
1109
+ BRL: "R$",
1110
+ ARS: "$",
1111
+ CLP: "$",
1112
+ COP: "$",
1113
+ PEN: "S/",
1114
+ MXN: "$",
1115
+ ZAR: "R",
1116
+ EGP: "E\xA3",
1117
+ NGN: "\u20A6",
1118
+ KES: "KSh",
1119
+ GHS: "\u20B5",
1120
+ MAD: "DH",
1121
+ TND: "\u062F.\u062A",
1122
+ DZD: "\u062F.\u062C",
1123
+ LYD: "\u0644.\u062F",
1124
+ AED: "\u062F.\u0625",
1125
+ SAR: "\u0631.\u0633",
1126
+ QAR: "\u0631.\u0642",
1127
+ KWD: "\u062F.\u0643",
1128
+ BHD: "\u0628.\u062F",
1129
+ OMR: "\u0631.\u0639",
1130
+ JOD: "\u062F.\u0623",
1131
+ LBP: "\u0644.\u0644",
1132
+ SYP: "\u0644.\u0633",
1133
+ IQD: "\u0639.\u062F",
1134
+ IRR: "\uFDFC",
1135
+ AFN: "\u060B",
1136
+ PKR: "\u20A8",
1137
+ LKR: "\u20A8",
1138
+ NPR: "\u20A8",
1139
+ BDT: "\u09F3",
1140
+ MMK: "K",
1141
+ LAK: "\u20AD",
1142
+ KHR: "\u17DB",
1143
+ MNT: "\u20AE",
1144
+ KZT: "\u20B8",
1145
+ UZS: "\u043B\u0432",
1146
+ KGS: "\u043B\u0432",
1147
+ TJS: "SM",
1148
+ TMT: "T",
1149
+ AZN: "\u20BC",
1150
+ GEL: "\u20BE",
1151
+ AMD: "\u058F",
1152
+ BYR: "p.",
1153
+ MDL: "L"
1154
+ };
1155
+ return currencySymbols[currency.toUpperCase()] || currency;
1156
+ }
1157
+
1158
+ // src/utils/price.ts
1159
+ var CURRENCY_SYMBOLS = {
1160
+ "USD": "$",
1161
+ "EUR": "\u20AC",
1162
+ "GBP": "\xA3",
1163
+ "CAD": "C$",
1164
+ "AUD": "A$"
1165
+ };
1166
+ var MARKET_CURRENCIES = {
1167
+ "US": "USD",
1168
+ "EU": "EUR",
1169
+ "UK": "GBP",
1170
+ "CA": "CAD",
1171
+ "AU": "AUD"
1172
+ };
1173
+ function convertToMajor(minorAmount) {
1174
+ return (minorAmount ?? 0) / 100;
1175
+ }
1176
+ function convertToMinor(majorAmount) {
1177
+ return Math.round((majorAmount ?? 0) * 100);
1178
+ }
1179
+ function getSymbol(currency) {
1180
+ return CURRENCY_SYMBOLS[currency] || "$";
1181
+ }
1182
+ function getCurrencyFromMarket(marketId) {
1183
+ return MARKET_CURRENCIES[marketId] || "USD";
1184
+ }
1185
+ function formatCurrencyAmount(amount, currency, options = {}) {
1186
+ const { showSymbols = true, decimalPlaces = 2, customSymbol } = options;
1187
+ const roundedAmount = amount.toFixed(decimalPlaces);
1188
+ if (!showSymbols) {
1189
+ return `${roundedAmount} ${currency}`;
1190
+ }
1191
+ const symbol = customSymbol || getSymbol(currency);
1192
+ return `${symbol}${roundedAmount}`;
1193
+ }
1194
+ function formatMinor(amountMinor, currency, options = {}) {
1195
+ const major = convertToMajor(amountMinor);
1196
+ return formatCurrencyAmount(major, currency, options);
1197
+ }
1198
+ function formatPayment(payment, options = {}) {
1199
+ if (!payment) return "";
1200
+ const { showSymbols = true, decimalPlaces = 2, showBreakdown = false } = options;
1201
+ if (showBreakdown) {
1202
+ const subtotal = formatMinor(payment.subtotal, payment.currency, { showSymbols, decimalPlaces });
1203
+ const discount = (payment.discount ?? 0) > 0 ? formatMinor(payment.discount, payment.currency, { showSymbols, decimalPlaces }) : null;
1204
+ const tax = (payment.tax ?? 0) > 0 ? formatMinor(payment.tax, payment.currency, { showSymbols, decimalPlaces }) : null;
1205
+ const total = formatMinor(payment.total, payment.currency, { showSymbols, decimalPlaces });
1206
+ let result = `Subtotal: ${subtotal}`;
1207
+ if (discount) result += `, Discount: -${discount}`;
1208
+ if (tax) result += `, Tax: ${tax}`;
1209
+ result += `, Total: ${total}`;
1210
+ return result;
1211
+ }
1212
+ return formatMinor(payment.total, payment.currency, { showSymbols, decimalPlaces });
1213
+ }
1214
+ function getMarketPrice(prices, marketId, businessMarkets, options = {}) {
1215
+ if (!prices || prices.length === 0) return "";
1216
+ const {
1217
+ showSymbols = true,
1218
+ decimalPlaces = 2,
1219
+ showCompareAt = true,
1220
+ fallbackMarket = "US"
1221
+ } = options;
1222
+ let price = prices.find((p) => p.market === marketId);
1223
+ if (!price) {
1224
+ price = prices.find((p) => p.market === fallbackMarket) || prices[0];
1225
+ }
1226
+ if (!price) return "";
1227
+ let currency;
1228
+ let symbol;
1229
+ if (businessMarkets) {
1230
+ const marketData = businessMarkets.find((m) => m.id === price.market || m.code === price.market);
1231
+ if (marketData?.currency) {
1232
+ currency = marketData.currency;
1233
+ symbol = getCurrencySymbol(currency);
1234
+ } else {
1235
+ currency = getCurrencyFromMarket(price.market);
1236
+ symbol = getSymbol(currency);
1237
+ }
1238
+ } else {
1239
+ currency = getCurrencyFromMarket(price.market);
1240
+ symbol = getSymbol(currency);
1241
+ }
1242
+ const formattedPrice = formatMinor(price.amount ?? 0, currency, {
1243
+ showSymbols,
1244
+ decimalPlaces,
1245
+ customSymbol: symbol
1246
+ });
1247
+ if (showCompareAt && price.compareAt && price.compareAt > (price.amount ?? 0)) {
1248
+ const formattedCompareAt = formatMinor(price.compareAt, currency, {
1249
+ showSymbols,
1250
+ decimalPlaces,
1251
+ customSymbol: symbol
1252
+ });
1253
+ return `${formattedPrice} was ${formattedCompareAt}`;
1254
+ }
1255
+ return formattedPrice;
1256
+ }
1257
+ function getPriceAmount(prices, marketId, fallbackMarket = "US") {
1258
+ if (!prices || prices.length === 0) return 0;
1259
+ const price = prices.find((p) => p.market === marketId) || prices.find((p) => p.market === fallbackMarket) || prices[0];
1260
+ return price?.amount || 0;
1261
+ }
1262
+ function createPaymentForCheckout(subtotalMinor, marketId, currency, paymentMethod, options = {}) {
1263
+ const { discount = 0, tax = 0, promoCodeId } = options;
1264
+ const total = subtotalMinor - discount + tax;
1265
+ return {
1266
+ currency,
1267
+ market: marketId,
1268
+ subtotal: subtotalMinor,
1269
+ shipping: 0,
1270
+ discount,
1271
+ tax,
1272
+ total,
1273
+ promoCodeId,
1274
+ method: paymentMethod
1275
+ };
1276
+ }
1277
+
1278
+ // src/utils/svg.ts
1279
+ async function fetchSvgContent(mediaObject) {
1280
+ if (!mediaObject) return null;
1281
+ const svgUrl = getImageUrl(mediaObject, false);
1282
+ try {
1283
+ const response = await fetch(svgUrl);
1284
+ if (!response.ok) {
1285
+ console.error(`Failed to fetch SVG: ${response.status} ${response.statusText}`);
1286
+ return null;
1287
+ }
1288
+ const svgContent = await response.text();
1289
+ return svgContent;
1290
+ } catch (error) {
1291
+ console.error("Error fetching SVG:", error);
1292
+ return null;
1293
+ }
1294
+ }
1295
+ async function getSvgContentForAstro(mediaObject) {
1296
+ try {
1297
+ const svgContent = await fetchSvgContent(mediaObject);
1298
+ return svgContent || "";
1299
+ } catch (error) {
1300
+ console.error("Error getting SVG content for Astro:", error);
1301
+ return "";
1302
+ }
1303
+ }
1304
+ async function injectSvgIntoElement(mediaObject, targetElement, className) {
1305
+ if (!targetElement) return;
1306
+ try {
1307
+ const svgContent = await fetchSvgContent(mediaObject);
1308
+ if (svgContent) {
1309
+ targetElement.innerHTML = svgContent;
1310
+ if (className) {
1311
+ const svgElement = targetElement.querySelector("svg");
1312
+ if (svgElement) {
1313
+ svgElement.classList.add(...className.split(" "));
1314
+ }
1315
+ }
1316
+ }
1317
+ } catch (error) {
1318
+ console.error("Error injecting SVG:", error);
1319
+ }
1320
+ }
1321
+
1322
+ // src/utils/text.ts
1323
+ var locales = ["en", "sr-latn"];
1324
+ var localeMap = {
1325
+ "en": "en-US",
1326
+ "sr-latn": "sr-RS"
1327
+ };
1328
+ function slugify(text) {
1329
+ return text.toString().toLowerCase().replace(/\s+/g, "-").replace(/[^\w-]+/g, "").replace(/--+/g, "-").replace(/^-+/, "").replace(/-+$/, "");
1330
+ }
1331
+ function humanize(text) {
1332
+ const slugifiedText = slugify(text);
1333
+ return slugifiedText.replace(/-/g, " ").replace(
1334
+ // upper case first letter of every word, and lower case the rest
1335
+ /\w\S*/g,
1336
+ (w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase()
1337
+ );
1338
+ }
1339
+ function categorify(text) {
1340
+ const slugifiedText = slugify(text);
1341
+ return slugifiedText.replace(/-/g, " ").toUpperCase();
1342
+ }
1343
+ function formatDate(date, locale) {
1344
+ let localeString = "en-US";
1345
+ if (locales.includes(locale)) {
1346
+ localeString = localeMap[locale];
1347
+ }
1348
+ return new Date(date).toLocaleDateString(localeString, {
1349
+ timeZone: "UTC",
1350
+ year: "numeric",
1351
+ month: "short",
1352
+ day: "numeric"
1353
+ });
1354
+ }
1355
+
1356
+ // src/utils/timezone.ts
1357
+ var tzGroups = [
1358
+ {
1359
+ label: "US",
1360
+ zones: [
1361
+ { label: "Eastern Time", value: "America/New_York" },
1362
+ { label: "Central Time", value: "America/Chicago" },
1363
+ { label: "Mountain Time", value: "America/Denver" },
1364
+ { label: "Pacific Time", value: "America/Los_Angeles" }
1365
+ ]
1366
+ },
1367
+ {
1368
+ label: "Europe",
1369
+ zones: [
1370
+ { label: "London", value: "Europe/London" },
1371
+ { label: "Paris", value: "Europe/Paris" },
1372
+ { label: "Berlin", value: "Europe/Berlin" },
1373
+ { label: "Rome", value: "Europe/Rome" }
1374
+ ]
1375
+ },
1376
+ {
1377
+ label: "Asia",
1378
+ zones: [
1379
+ { label: "Tokyo", value: "Asia/Tokyo" },
1380
+ { label: "Shanghai", value: "Asia/Shanghai" },
1381
+ { label: "Mumbai", value: "Asia/Kolkata" },
1382
+ { label: "Dubai", value: "Asia/Dubai" }
1383
+ ]
1384
+ }
1385
+ ];
1386
+ function findTimeZone(groups) {
1387
+ try {
1388
+ const detected = Intl.DateTimeFormat().resolvedOptions().timeZone;
1389
+ for (const group of groups) {
1390
+ for (const zone of group.zones) {
1391
+ if (zone.value === detected) {
1392
+ return detected;
1393
+ }
1394
+ }
1395
+ }
1396
+ return "UTC";
1397
+ } catch (e) {
1398
+ return "UTC";
1399
+ }
1400
+ }
1401
+
1402
+ // src/utils/validation.ts
1403
+ function validatePhoneNumber(phone) {
1404
+ if (!phone) {
1405
+ return { isValid: false, error: "Phone number is required" };
1406
+ }
1407
+ const cleaned = phone.replace(/\D/g, "");
1408
+ if (cleaned.length < 8) {
1409
+ return { isValid: false, error: "Phone number is too short" };
1410
+ }
1411
+ if (cleaned.length > 15) {
1412
+ return { isValid: false, error: "Phone number is too long" };
1413
+ }
1414
+ return { isValid: true };
1415
+ }
1416
+ function validateEmail(email) {
1417
+ if (!email) {
1418
+ return { isValid: false, error: "Email is required" };
1419
+ }
1420
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
1421
+ if (!emailRegex.test(email)) {
1422
+ return { isValid: false, error: "Please enter a valid email address" };
1423
+ }
1424
+ return { isValid: true };
1425
+ }
1426
+ function validateVerificationCode(code) {
1427
+ if (!code) {
1428
+ return { isValid: false, error: "Verification code is required" };
1429
+ }
1430
+ const cleaned = code.replace(/\D/g, "");
1431
+ if (cleaned.length !== 4) {
1432
+ return { isValid: false, error: "Please enter a 4-digit verification code" };
1433
+ }
1434
+ return { isValid: true };
1435
+ }
1436
+ function validateRequired(value, fieldName = "This field") {
1437
+ if (value === null || value === void 0 || value === "") {
1438
+ return { isValid: false, error: `${fieldName} is required` };
1439
+ }
1440
+ return { isValid: true };
1441
+ }
1442
+
1443
+ // src/index.ts
1444
+ init_config();
1445
+ var SDK_VERSION = "0.1.0";
1446
+ var SUPPORTED_FRAMEWORKS = ["astro", "react", "vue", "svelte", "vanilla"];
1447
+ function initArky(config) {
1448
+ if (!config.apiUrl) {
1449
+ throw new Error("apiUrl is required");
1450
+ }
1451
+ if (!config.businessId) {
1452
+ throw new Error("businessId is required");
1453
+ }
1454
+ setGlobalConfig(config);
1455
+ return config;
1456
+ }
1457
+
1458
+ exports.ERROR_CODES = ERROR_CODES;
1459
+ exports.ERROR_CONSTANTS = ERROR_CONSTANTS;
1460
+ exports.PaymentMethod = PaymentMethod;
1461
+ exports.SDK_VERSION = SDK_VERSION;
1462
+ exports.SUPPORTED_FRAMEWORKS = SUPPORTED_FRAMEWORKS;
1463
+ exports.categorify = categorify;
1464
+ exports.cmsApi = cmsApi;
1465
+ exports.convertServerErrorToRequestError = convertServerErrorToRequestError;
1466
+ exports.convertToMajor = convertToMajor;
1467
+ exports.convertToMinor = convertToMinor;
1468
+ exports.createPaymentForCheckout = createPaymentForCheckout;
1469
+ exports.errors = errors;
1470
+ exports.eshopApi = eshopApi;
1471
+ exports.extractBlockValues = extractBlockValues;
1472
+ exports.fetchSvgContent = fetchSvgContent;
1473
+ exports.findTimeZone = findTimeZone;
1474
+ exports.formatBlockValue = formatBlockValue;
1475
+ exports.formatCurrencyAmount = formatCurrencyAmount;
1476
+ exports.formatDate = formatDate;
1477
+ exports.formatMinor = formatMinor;
1478
+ exports.formatPayment = formatPayment;
1479
+ exports.getBlockFromArray = getBlockFromArray;
1480
+ exports.getBlockLabel = getBlockLabel;
1481
+ exports.getBlockObjectValues = getBlockObjectValues;
1482
+ exports.getBlockTextValue = getBlockTextValue;
1483
+ exports.getBlockValue = getBlockValue;
1484
+ exports.getBlockValues = getBlockValues;
1485
+ exports.getBusinessConfig = getBusinessConfig;
1486
+ exports.getCurrencyFromMarket = getCurrencyFromMarket;
1487
+ exports.getErrorMessage = getErrorMessage;
1488
+ exports.getGalleryThumbnail = getGalleryThumbnail;
1489
+ exports.getGlobalConfig = getGlobalConfig;
1490
+ exports.getGuestToken = getGuestToken;
1491
+ exports.getImageUrl = getImageUrl;
1492
+ exports.getMarketPrice = getMarketPrice;
1493
+ exports.getPriceAmount = getPriceAmount;
1494
+ exports.getSvgContentForAstro = getSvgContentForAstro;
1495
+ exports.getSymbol = getSymbol;
1496
+ exports.httpClient = http_default;
1497
+ exports.humanize = humanize;
1498
+ exports.initArky = initArky;
1499
+ exports.injectSvgIntoElement = injectSvgIntoElement;
1500
+ exports.isErrorCode = isErrorCode;
1501
+ exports.newsletterApi = newsletterApi;
1502
+ exports.prepareBlocksForSubmission = prepareBlocksForSubmission;
1503
+ exports.reservationApi = reservationApi;
1504
+ exports.setGlobalConfig = setGlobalConfig;
1505
+ exports.slugify = slugify;
1506
+ exports.thumbnailUrl = thumbnailUrl;
1507
+ exports.transformErrors = transformErrors;
1508
+ exports.translateMap = translateMap;
1509
+ exports.tzGroups = tzGroups;
1510
+ exports.updateProfilePhone = updateProfilePhone;
1511
+ exports.validateEmail = validateEmail;
1512
+ exports.validatePhoneNumber = validatePhoneNumber;
1513
+ exports.validateRequired = validateRequired;
1514
+ exports.validateVerificationCode = validateVerificationCode;
1515
+ exports.verifyPhoneCode = verifyPhoneCode;
1516
+ //# sourceMappingURL=index.cjs.map
1517
+ //# sourceMappingURL=index.cjs.map