@cimplify/sdk 0.6.10 → 0.6.12

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/react.mjs CHANGED
@@ -750,6 +750,10 @@ var ERROR_SUGGESTIONS = {
750
750
  CHECKOUT_VALIDATION_FAILED: "Checkout payload failed validation. Verify customer, order type, and address fields are complete.",
751
751
  DELIVERY_ADDRESS_REQUIRED: "Delivery orders require an address. Collect and pass address info before processing checkout.",
752
752
  CUSTOMER_INFO_REQUIRED: "Customer details are required. Ensure name/email/phone are available before checkout.",
753
+ QUOTE_NOT_FOUND: "Quote could not be found. Refresh pricing and create a new quote before checkout.",
754
+ QUOTE_EXPIRED: "Quote has expired. Re-fetch pricing to generate a new quote with a valid expiry window.",
755
+ QUOTE_CONSUMED: "Quote has already been used. Request a fresh quote to prevent duplicate checkout attempts.",
756
+ QUOTE_STORAGE_UNAVAILABLE: "Quote storage is temporarily unavailable. Retry shortly and avoid charging until quote fetch succeeds.",
753
757
  PAYMENT_FAILED: "Payment provider rejected or failed processing. Show retry/change-method options to the shopper.",
754
758
  PAYMENT_CANCELLED: "Payment was cancelled by the shopper or provider flow. Allow a safe retry path.",
755
759
  INSUFFICIENT_FUNDS: "Payment method has insufficient funds. Prompt shopper to use another method.",
@@ -851,6 +855,23 @@ async function safe(promise) {
851
855
  return err(toCimplifyError(error));
852
856
  }
853
857
  }
858
+ async function safeWithFallback(primary, fallback) {
859
+ const primaryResult = await safe(primary());
860
+ if (primaryResult.ok) return primaryResult;
861
+ if (primaryResult.error.code !== "HTTP_404" && primaryResult.error.code !== "API_ERROR") {
862
+ return primaryResult;
863
+ }
864
+ return safe(fallback());
865
+ }
866
+ function withQuery(path, params) {
867
+ const query = new URLSearchParams();
868
+ for (const [key, value] of Object.entries(params)) {
869
+ if (value === void 0) continue;
870
+ query.set(key, String(value));
871
+ }
872
+ const queryString = query.toString();
873
+ return queryString ? `${path}?${queryString}` : path;
874
+ }
854
875
  function isRecord(value) {
855
876
  return typeof value === "object" && value !== null;
856
877
  }
@@ -908,11 +929,79 @@ function findProductBySlug(products, slug) {
908
929
  return typeof value === "string" && value === slug;
909
930
  });
910
931
  }
932
+ function findCategoryBySlug(categories, slug) {
933
+ return categories.find((category) => {
934
+ const value = category["slug"];
935
+ return typeof value === "string" && value === slug;
936
+ });
937
+ }
938
+ function hasCategorySlug(category) {
939
+ const value = category["slug"];
940
+ return typeof value === "string" && value.trim().length > 0;
941
+ }
942
+ function toFiniteNumber(value) {
943
+ if (typeof value === "number" && Number.isFinite(value)) {
944
+ return value;
945
+ }
946
+ if (typeof value === "string" && value.trim().length > 0) {
947
+ const parsed = Number(value);
948
+ if (Number.isFinite(parsed)) {
949
+ return parsed;
950
+ }
951
+ }
952
+ return void 0;
953
+ }
954
+ function normalizePagination(value) {
955
+ if (!isRecord(value)) {
956
+ return void 0;
957
+ }
958
+ const totalCount = toFiniteNumber(value.total_count);
959
+ const currentPage = toFiniteNumber(value.current_page);
960
+ const pageSize = toFiniteNumber(value.page_size);
961
+ const totalPages = toFiniteNumber(value.total_pages);
962
+ if (totalCount === void 0 || currentPage === void 0 || pageSize === void 0 || totalPages === void 0) {
963
+ return void 0;
964
+ }
965
+ return {
966
+ total_count: totalCount,
967
+ current_page: currentPage,
968
+ page_size: pageSize,
969
+ total_pages: totalPages,
970
+ has_more: value.has_more === true,
971
+ next_cursor: typeof value.next_cursor === "string" ? value.next_cursor : void 0
972
+ };
973
+ }
974
+ function normalizeCatalogueResult(payload) {
975
+ if (Array.isArray(payload)) {
976
+ return {
977
+ items: payload.map((product) => normalizeCatalogueProductPayload(product)),
978
+ is_complete: true
979
+ };
980
+ }
981
+ if (!isRecord(payload)) {
982
+ return {
983
+ items: [],
984
+ is_complete: true
985
+ };
986
+ }
987
+ const rawItems = Array.isArray(payload.products) ? payload.products : Array.isArray(payload.items) ? payload.items : [];
988
+ return {
989
+ items: rawItems.map((product) => normalizeCatalogueProductPayload(product)),
990
+ is_complete: typeof payload.is_complete === "boolean" ? payload.is_complete : true,
991
+ total_available: toFiniteNumber(payload.total_available),
992
+ pagination: normalizePagination(payload.pagination)
993
+ };
994
+ }
911
995
  var CatalogueQueries = class {
912
996
  constructor(client) {
913
997
  this.client = client;
914
998
  }
915
999
  async getProducts(options) {
1000
+ const result = await this.getProductsWithMeta(options);
1001
+ if (!result.ok) return result;
1002
+ return ok(result.value.items);
1003
+ }
1004
+ async getProductsWithMeta(options) {
916
1005
  let query = "products";
917
1006
  const filters = [];
918
1007
  if (options?.category) {
@@ -927,6 +1016,13 @@ var CatalogueQueries = class {
927
1016
  if (options?.search) {
928
1017
  filters.push(`@.name contains '${escapeQueryValue(options.search)}'`);
929
1018
  }
1019
+ if (options?.tags?.length) {
1020
+ for (const tag of options.tags) {
1021
+ if (tag.trim().length > 0) {
1022
+ filters.push(`@.tags contains '${escapeQueryValue(tag)}'`);
1023
+ }
1024
+ }
1025
+ }
930
1026
  if (options?.min_price !== void 0) {
931
1027
  filters.push(`@.price>=${options.min_price}`);
932
1028
  }
@@ -939,25 +1035,57 @@ var CatalogueQueries = class {
939
1035
  if (options?.sort_by) {
940
1036
  query += `#sort(${options.sort_by},${options.sort_order || "asc"})`;
941
1037
  }
942
- if (options?.limit) {
1038
+ if (options?.limit !== void 0) {
943
1039
  query += `#limit(${options.limit})`;
944
1040
  }
945
- if (options?.offset) {
1041
+ if (options?.offset !== void 0) {
946
1042
  query += `#offset(${options.offset})`;
947
1043
  }
948
- const result = await safe(this.client.query(query));
1044
+ const path = withQuery("/api/v1/catalogue/products", {
1045
+ category_id: options?.category,
1046
+ search: options?.search,
1047
+ page: options?.page,
1048
+ tags: options?.tags?.join(","),
1049
+ featured: options?.featured,
1050
+ in_stock: options?.in_stock,
1051
+ min_price: options?.min_price,
1052
+ max_price: options?.max_price,
1053
+ sort_by: options?.sort_by,
1054
+ sort_order: options?.sort_order,
1055
+ limit: options?.limit,
1056
+ offset: options?.offset,
1057
+ cursor: options?.cursor
1058
+ });
1059
+ const result = await safeWithFallback(
1060
+ () => this.client.get(path),
1061
+ () => this.client.query(query)
1062
+ );
949
1063
  if (!result.ok) return result;
950
- return ok(result.value.map((product) => normalizeCatalogueProductPayload(product)));
1064
+ return ok(normalizeCatalogueResult(result.value));
951
1065
  }
952
1066
  async getProduct(id) {
953
- const result = await safe(this.client.query(`products.${id}`));
1067
+ const encodedId = encodeURIComponent(id);
1068
+ const result = await safeWithFallback(
1069
+ () => this.client.get(`/api/v1/catalogue/products/${encodedId}`),
1070
+ () => this.client.query(`products.${id}`)
1071
+ );
954
1072
  if (!result.ok) return result;
955
1073
  return ok(normalizeCatalogueProductPayload(result.value));
956
1074
  }
957
1075
  async getProductBySlug(slug) {
1076
+ const encodedSlug = encodeURIComponent(slug);
1077
+ const restResult = await safe(
1078
+ this.client.get(`/api/v1/catalogue/products/slug/${encodedSlug}`)
1079
+ );
1080
+ if (restResult.ok) {
1081
+ return ok(normalizeCatalogueProductPayload(restResult.value));
1082
+ }
1083
+ if (restResult.error.code !== "HTTP_404" && restResult.error.code !== "API_ERROR") {
1084
+ return restResult;
1085
+ }
958
1086
  const filteredResult = await safe(
959
1087
  this.client.query(
960
- `products[?(@.slug=='${escapeQueryValue(slug)}')]`
1088
+ `products[?(@.slug=='${escapeQueryValue(slug)}')]#limit(50)`
961
1089
  )
962
1090
  );
963
1091
  if (!filteredResult.ok) return filteredResult;
@@ -968,7 +1096,9 @@ var CatalogueQueries = class {
968
1096
  if (filteredResult.value.length === 1) {
969
1097
  return ok(normalizeCatalogueProductPayload(filteredResult.value[0]));
970
1098
  }
971
- const unfilteredResult = await safe(this.client.query("products"));
1099
+ const unfilteredResult = await safe(
1100
+ this.client.query("products#limit(200)")
1101
+ );
972
1102
  if (!unfilteredResult.ok) return unfilteredResult;
973
1103
  const fallbackMatch = findProductBySlug(unfilteredResult.value, slug);
974
1104
  if (!fallbackMatch) {
@@ -977,18 +1107,33 @@ var CatalogueQueries = class {
977
1107
  return ok(normalizeCatalogueProductPayload(fallbackMatch));
978
1108
  }
979
1109
  async getVariants(productId) {
980
- return safe(this.client.query(`products.${productId}.variants`));
1110
+ const encodedId = encodeURIComponent(productId);
1111
+ return safeWithFallback(
1112
+ () => this.client.get(`/api/v1/catalogue/products/${encodedId}/variants`),
1113
+ () => this.client.query(`products.${productId}.variants`)
1114
+ );
981
1115
  }
982
1116
  async getVariantAxes(productId) {
983
- return safe(this.client.query(`products.${productId}.variant_axes`));
1117
+ const encodedId = encodeURIComponent(productId);
1118
+ return safeWithFallback(
1119
+ () => this.client.get(`/api/v1/catalogue/products/${encodedId}/variant-axes`),
1120
+ () => this.client.query(`products.${productId}.variant_axes`)
1121
+ );
984
1122
  }
985
1123
  /**
986
1124
  * Find a variant by axis selections (e.g., { "Size": "Large", "Color": "Red" })
987
1125
  * Returns the matching variant or null if no match found.
988
1126
  */
989
1127
  async getVariantByAxisSelections(productId, selections) {
990
- return safe(
991
- this.client.query(`products.${productId}.variant`, {
1128
+ const encodedId = encodeURIComponent(productId);
1129
+ return safeWithFallback(
1130
+ () => this.client.post(
1131
+ `/api/v1/catalogue/products/${encodedId}/variants/find`,
1132
+ {
1133
+ axis_selections: selections
1134
+ }
1135
+ ),
1136
+ () => this.client.query(`products.${productId}.variant`, {
992
1137
  axis_selections: selections
993
1138
  })
994
1139
  );
@@ -997,45 +1142,107 @@ var CatalogueQueries = class {
997
1142
  * Get a specific variant by its ID
998
1143
  */
999
1144
  async getVariantById(productId, variantId) {
1000
- return safe(this.client.query(`products.${productId}.variant.${variantId}`));
1145
+ const encodedProductId = encodeURIComponent(productId);
1146
+ const encodedVariantId = encodeURIComponent(variantId);
1147
+ return safeWithFallback(
1148
+ () => this.client.get(
1149
+ `/api/v1/catalogue/products/${encodedProductId}/variants/${encodedVariantId}`
1150
+ ),
1151
+ () => this.client.query(`products.${productId}.variant.${variantId}`)
1152
+ );
1001
1153
  }
1002
1154
  async getAddOns(productId) {
1003
- return safe(this.client.query(`products.${productId}.add_ons`));
1155
+ const encodedId = encodeURIComponent(productId);
1156
+ return safeWithFallback(
1157
+ () => this.client.get(`/api/v1/catalogue/products/${encodedId}/add-ons`),
1158
+ () => this.client.query(`products.${productId}.add_ons`)
1159
+ );
1004
1160
  }
1005
1161
  async getCategories() {
1006
- return safe(this.client.query("categories"));
1162
+ const result = await safeWithFallback(
1163
+ () => this.client.get("/api/v1/catalogue/categories"),
1164
+ () => this.client.query("categories")
1165
+ );
1166
+ if (!result.ok) return result;
1167
+ if (result.value.some(hasCategorySlug)) {
1168
+ return result;
1169
+ }
1170
+ const catalogueResult = await safe(
1171
+ this.client.query("catalogue#limit(1)")
1172
+ );
1173
+ if (!catalogueResult.ok) {
1174
+ return result;
1175
+ }
1176
+ const fallbackCategories = Array.isArray(catalogueResult.value.categories) ? catalogueResult.value.categories : [];
1177
+ return fallbackCategories.length > 0 ? ok(fallbackCategories) : result;
1007
1178
  }
1008
1179
  async getCategory(id) {
1009
- return safe(this.client.query(`categories.${id}`));
1180
+ const encodedId = encodeURIComponent(id);
1181
+ return safeWithFallback(
1182
+ () => this.client.get(`/api/v1/catalogue/categories/${encodedId}`),
1183
+ () => this.client.query(`categories.${id}`)
1184
+ );
1010
1185
  }
1011
1186
  async getCategoryBySlug(slug) {
1187
+ const encodedSlug = encodeURIComponent(slug);
1188
+ const restResult = await safe(this.client.get(`/api/v1/catalogue/categories/slug/${encodedSlug}`));
1189
+ if (restResult.ok) {
1190
+ return restResult;
1191
+ }
1192
+ if (restResult.error.code !== "HTTP_404" && restResult.error.code !== "API_ERROR") {
1193
+ return restResult;
1194
+ }
1012
1195
  const result = await safe(
1013
1196
  this.client.query(`categories[?(@.slug=='${escapeQueryValue(slug)}')]`)
1014
1197
  );
1015
1198
  if (!result.ok) return result;
1016
- if (!result.value.length) {
1199
+ const exactMatch = findCategoryBySlug(result.value, slug);
1200
+ if (exactMatch) {
1201
+ return ok(exactMatch);
1202
+ }
1203
+ const categoriesResult = await this.getCategories();
1204
+ if (!categoriesResult.ok) {
1205
+ return categoriesResult;
1206
+ }
1207
+ const fallbackMatch = findCategoryBySlug(categoriesResult.value, slug);
1208
+ if (!fallbackMatch) {
1017
1209
  return err(new CimplifyError("NOT_FOUND", `Category not found: ${slug}`, false));
1018
1210
  }
1019
- return ok(result.value[0]);
1211
+ return ok(fallbackMatch);
1020
1212
  }
1021
1213
  async getCategoryProducts(categoryId) {
1022
- return safe(
1023
- this.client.query(
1214
+ const encodedId = encodeURIComponent(categoryId);
1215
+ return safeWithFallback(
1216
+ () => this.client.get(`/api/v1/catalogue/categories/${encodedId}/products`),
1217
+ () => this.client.query(
1024
1218
  `products[?(@.category_id=='${escapeQueryValue(categoryId)}')]`
1025
1219
  )
1026
1220
  );
1027
1221
  }
1028
1222
  async getCollections() {
1029
- return safe(this.client.query("collections"));
1223
+ return safeWithFallback(
1224
+ () => this.client.get("/api/v1/catalogue/collections"),
1225
+ () => this.client.query("collections")
1226
+ );
1030
1227
  }
1031
1228
  async getCollection(id) {
1032
- return safe(this.client.query(`collections.${id}`));
1229
+ const encodedId = encodeURIComponent(id);
1230
+ return safeWithFallback(
1231
+ () => this.client.get(`/api/v1/catalogue/collections/${encodedId}`),
1232
+ () => this.client.query(`collections.${id}`)
1233
+ );
1033
1234
  }
1034
1235
  async getCollectionBySlug(slug) {
1236
+ const encodedSlug = encodeURIComponent(slug);
1237
+ const restResult = await safe(
1238
+ this.client.get(`/api/v1/catalogue/collections/slug/${encodedSlug}`)
1239
+ );
1240
+ if (restResult.ok) return restResult;
1241
+ if (restResult.error.code !== "HTTP_404" && restResult.error.code !== "API_ERROR") {
1242
+ return restResult;
1243
+ }
1035
1244
  const result = await safe(
1036
- this.client.query(
1037
- `collections[?(@.slug=='${escapeQueryValue(slug)}')]`
1038
- )
1245
+ this.client.query(`collections[?(@.slug=='${escapeQueryValue(slug)}')]`)
1039
1246
  );
1040
1247
  if (!result.ok) return result;
1041
1248
  if (!result.value.length) {
@@ -1044,22 +1251,43 @@ var CatalogueQueries = class {
1044
1251
  return ok(result.value[0]);
1045
1252
  }
1046
1253
  async getCollectionProducts(collectionId) {
1047
- return safe(this.client.query(`collections.${collectionId}.products`));
1254
+ const encodedId = encodeURIComponent(collectionId);
1255
+ return safeWithFallback(
1256
+ () => this.client.get(`/api/v1/catalogue/collections/${encodedId}/products`),
1257
+ () => this.client.query(`collections.${collectionId}.products`)
1258
+ );
1048
1259
  }
1049
1260
  async searchCollections(query, limit = 20) {
1050
- return safe(
1051
- this.client.query(
1261
+ const path = withQuery("/api/v1/catalogue/collections", { search: query, limit });
1262
+ return safeWithFallback(
1263
+ () => this.client.get(path),
1264
+ () => this.client.query(
1052
1265
  `collections[?(@.name contains '${escapeQueryValue(query)}')]#limit(${limit})`
1053
1266
  )
1054
1267
  );
1055
1268
  }
1056
1269
  async getBundles() {
1057
- return safe(this.client.query("bundles"));
1270
+ return safeWithFallback(
1271
+ () => this.client.get("/api/v1/catalogue/bundles"),
1272
+ () => this.client.query("bundles")
1273
+ );
1058
1274
  }
1059
1275
  async getBundle(id) {
1060
- return safe(this.client.query(`bundles.${id}`));
1276
+ const encodedId = encodeURIComponent(id);
1277
+ return safeWithFallback(
1278
+ () => this.client.get(`/api/v1/catalogue/bundles/${encodedId}`),
1279
+ () => this.client.query(`bundles.${id}`)
1280
+ );
1061
1281
  }
1062
1282
  async getBundleBySlug(slug) {
1283
+ const encodedSlug = encodeURIComponent(slug);
1284
+ const restResult = await safe(
1285
+ this.client.get(`/api/v1/catalogue/bundles/slug/${encodedSlug}`)
1286
+ );
1287
+ if (restResult.ok) return restResult;
1288
+ if (restResult.error.code !== "HTTP_404" && restResult.error.code !== "API_ERROR") {
1289
+ return restResult;
1290
+ }
1063
1291
  const result = await safe(
1064
1292
  this.client.query(
1065
1293
  `bundles[?(@.slug=='${escapeQueryValue(slug)}')]`
@@ -1072,8 +1300,10 @@ var CatalogueQueries = class {
1072
1300
  return ok(result.value[0]);
1073
1301
  }
1074
1302
  async searchBundles(query, limit = 20) {
1075
- return safe(
1076
- this.client.query(
1303
+ const path = withQuery("/api/v1/catalogue/bundles", { search: query, limit });
1304
+ return safeWithFallback(
1305
+ () => this.client.get(path),
1306
+ () => this.client.query(
1077
1307
  `bundles[?(@.name contains '${escapeQueryValue(query)}')]#limit(${limit})`
1078
1308
  )
1079
1309
  );
@@ -1083,17 +1313,39 @@ var CatalogueQueries = class {
1083
1313
  if (options?.limit) {
1084
1314
  query += `#limit(${options.limit})`;
1085
1315
  }
1086
- return safe(this.client.query(query));
1316
+ const path = withQuery("/api/v1/catalogue/composites", { limit: options?.limit });
1317
+ return safeWithFallback(
1318
+ () => this.client.get(path),
1319
+ () => this.client.query(query)
1320
+ );
1087
1321
  }
1088
1322
  async getComposite(id) {
1089
- return safe(this.client.query(`composites.${id}`));
1323
+ const encodedId = encodeURIComponent(id);
1324
+ return safeWithFallback(
1325
+ () => this.client.get(`/api/v1/catalogue/composites/${encodedId}`),
1326
+ () => this.client.query(`composites.${id}`)
1327
+ );
1090
1328
  }
1091
1329
  async getCompositeByProductId(productId) {
1092
- return safe(this.client.query(`composites.by_product.${productId}`));
1330
+ const encodedId = encodeURIComponent(productId);
1331
+ return safeWithFallback(
1332
+ () => this.client.get(
1333
+ `/api/v1/catalogue/composites/by-product/${encodedId}`
1334
+ ),
1335
+ () => this.client.query(`composites.by_product.${productId}`)
1336
+ );
1093
1337
  }
1094
1338
  async calculateCompositePrice(compositeId, selections, locationId) {
1095
- return safe(
1096
- this.client.call("composite.calculatePrice", {
1339
+ const encodedId = encodeURIComponent(compositeId);
1340
+ return safeWithFallback(
1341
+ () => this.client.post(
1342
+ `/api/v1/catalogue/composites/${encodedId}/calculate-price`,
1343
+ {
1344
+ selections,
1345
+ location_id: locationId
1346
+ }
1347
+ ),
1348
+ () => this.client.call("composite.calculatePrice", {
1097
1349
  composite_id: compositeId,
1098
1350
  selections,
1099
1351
  location_id: locationId
@@ -1101,35 +1353,41 @@ var CatalogueQueries = class {
1101
1353
  );
1102
1354
  }
1103
1355
  async fetchQuote(input) {
1104
- return safe(this.client.call("catalogue.createQuote", input));
1356
+ return safeWithFallback(
1357
+ () => this.client.post("/api/v1/catalogue/quotes", input),
1358
+ () => this.client.call("catalogue.createQuote", input)
1359
+ );
1105
1360
  }
1106
1361
  async getQuote(quoteId) {
1107
- return safe(
1108
- this.client.call("catalogue.getQuote", {
1362
+ const encodedQuoteId = encodeURIComponent(quoteId);
1363
+ return safeWithFallback(
1364
+ () => this.client.get(`/api/v1/catalogue/quotes/${encodedQuoteId}`),
1365
+ () => this.client.call("catalogue.getQuote", {
1109
1366
  quote_id: quoteId
1110
1367
  })
1111
1368
  );
1112
1369
  }
1113
1370
  async refreshQuote(input) {
1114
- return safe(this.client.call("catalogue.refreshQuote", input));
1371
+ const encodedQuoteId = encodeURIComponent(input.quote_id);
1372
+ return safeWithFallback(
1373
+ () => this.client.post(
1374
+ `/api/v1/catalogue/quotes/${encodedQuoteId}/refresh`,
1375
+ input
1376
+ ),
1377
+ () => this.client.call("catalogue.refreshQuote", input)
1378
+ );
1115
1379
  }
1116
1380
  async search(query, options) {
1117
- const limit = options?.limit ?? 20;
1118
- let searchQuery = `products[?(@.name contains '${escapeQueryValue(query)}')]`;
1119
- if (options?.category) {
1120
- searchQuery = `products[?(@.name contains '${escapeQueryValue(query)}' && @.category_id=='${escapeQueryValue(options.category)}')]`;
1121
- }
1122
- searchQuery += `#limit(${limit})`;
1123
- return safe(this.client.query(searchQuery));
1381
+ const result = await this.getProducts({
1382
+ search: query,
1383
+ category: options?.category,
1384
+ limit: options?.limit ?? 20
1385
+ });
1386
+ if (!result.ok) return result;
1387
+ return ok(result.value);
1124
1388
  }
1125
1389
  async searchProducts(query, options) {
1126
- return safe(
1127
- this.client.call("catalogue.search", {
1128
- query,
1129
- limit: options?.limit ?? 20,
1130
- category: options?.category
1131
- })
1132
- );
1390
+ return this.search(query, options);
1133
1391
  }
1134
1392
  async getMenu(options) {
1135
1393
  let query = "menu";
@@ -1139,13 +1397,28 @@ var CatalogueQueries = class {
1139
1397
  if (options?.limit) {
1140
1398
  query += `#limit(${options.limit})`;
1141
1399
  }
1142
- return safe(this.client.query(query));
1400
+ const path = withQuery("/api/v1/catalogue/menu", {
1401
+ category_id: options?.category,
1402
+ limit: options?.limit
1403
+ });
1404
+ return safeWithFallback(
1405
+ () => this.client.get(path),
1406
+ () => this.client.query(query)
1407
+ );
1143
1408
  }
1144
1409
  async getMenuCategory(categoryId) {
1145
- return safe(this.client.query(`menu.category.${categoryId}`));
1410
+ const encodedId = encodeURIComponent(categoryId);
1411
+ return safeWithFallback(
1412
+ () => this.client.get(`/api/v1/catalogue/menu/categories/${encodedId}`),
1413
+ () => this.client.query(`menu.category.${categoryId}`)
1414
+ );
1146
1415
  }
1147
1416
  async getMenuItem(itemId) {
1148
- return safe(this.client.query(`menu.${itemId}`));
1417
+ const encodedId = encodeURIComponent(itemId);
1418
+ return safeWithFallback(
1419
+ () => this.client.get(`/api/v1/catalogue/menu/items/${encodedId}`),
1420
+ () => this.client.query(`menu.${itemId}`)
1421
+ );
1149
1422
  }
1150
1423
  };
1151
1424
 
@@ -1164,6 +1437,14 @@ async function safe2(promise) {
1164
1437
  return err(toCimplifyError2(error));
1165
1438
  }
1166
1439
  }
1440
+ async function safeWithFallback2(primary, fallback) {
1441
+ const primaryResult = await safe2(primary());
1442
+ if (primaryResult.ok) return primaryResult;
1443
+ if (primaryResult.error.code !== "HTTP_404" && primaryResult.error.code !== "API_ERROR") {
1444
+ return primaryResult;
1445
+ }
1446
+ return safe2(fallback());
1447
+ }
1167
1448
  function isUICartResponse(value) {
1168
1449
  return "cart" in value;
1169
1450
  }
@@ -1175,21 +1456,36 @@ var CartOperations = class {
1175
1456
  this.client = client;
1176
1457
  }
1177
1458
  async get() {
1178
- const result = await safe2(this.client.query("cart#enriched"));
1459
+ const result = await safeWithFallback2(
1460
+ () => this.client.get("/api/v1/cart"),
1461
+ () => this.client.query("cart#enriched")
1462
+ );
1179
1463
  if (!result.ok) return result;
1180
1464
  return ok(unwrapEnrichedCart(result.value));
1181
1465
  }
1182
1466
  async getRaw() {
1183
- return safe2(this.client.query("cart"));
1467
+ return safeWithFallback2(
1468
+ () => this.client.get("/api/v1/cart"),
1469
+ () => this.client.query("cart")
1470
+ );
1184
1471
  }
1185
1472
  async getItems() {
1186
- return safe2(this.client.query("cart_items"));
1473
+ return safeWithFallback2(
1474
+ () => this.client.get("/api/v1/cart/items"),
1475
+ () => this.client.query("cart_items")
1476
+ );
1187
1477
  }
1188
1478
  async getCount() {
1189
- return safe2(this.client.query("cart#count"));
1479
+ return safeWithFallback2(
1480
+ () => this.client.get("/api/v1/cart/count"),
1481
+ () => this.client.query("cart#count")
1482
+ );
1190
1483
  }
1191
1484
  async getTotal() {
1192
- return safe2(this.client.query("cart#total"));
1485
+ return safeWithFallback2(
1486
+ () => this.client.get("/api/v1/cart/total"),
1487
+ () => this.client.query("cart#total")
1488
+ );
1193
1489
  }
1194
1490
  async getSummary() {
1195
1491
  const cartResult = await this.get();
@@ -1206,43 +1502,66 @@ var CartOperations = class {
1206
1502
  });
1207
1503
  }
1208
1504
  async addItem(input) {
1209
- return safe2(this.client.call("cart.addItem", input));
1505
+ return safeWithFallback2(
1506
+ () => this.client.post("/api/v1/cart/items", input),
1507
+ () => this.client.call("cart.addItem", input)
1508
+ );
1210
1509
  }
1211
1510
  async updateItem(cartItemId, updates) {
1212
- return safe2(
1213
- this.client.call("cart.updateItem", {
1511
+ if (typeof updates.quantity === "number") {
1512
+ return this.updateQuantity(cartItemId, updates.quantity);
1513
+ }
1514
+ const encodedId = encodeURIComponent(cartItemId);
1515
+ return safeWithFallback2(
1516
+ () => this.client.patch(`/api/v1/cart/items/${encodedId}`, updates),
1517
+ () => this.client.call("cart.updateItem", {
1214
1518
  cart_item_id: cartItemId,
1215
1519
  ...updates
1216
1520
  })
1217
1521
  );
1218
1522
  }
1219
1523
  async updateQuantity(cartItemId, quantity) {
1220
- return safe2(
1221
- this.client.call("cart.updateItemQuantity", {
1524
+ const encodedId = encodeURIComponent(cartItemId);
1525
+ return safeWithFallback2(
1526
+ () => this.client.patch(`/api/v1/cart/items/${encodedId}`, {
1527
+ quantity
1528
+ }),
1529
+ () => this.client.call("cart.updateItemQuantity", {
1222
1530
  cart_item_id: cartItemId,
1223
1531
  quantity
1224
1532
  })
1225
1533
  );
1226
1534
  }
1227
1535
  async removeItem(cartItemId) {
1228
- return safe2(
1229
- this.client.call("cart.removeItem", {
1536
+ const encodedId = encodeURIComponent(cartItemId);
1537
+ return safeWithFallback2(
1538
+ () => this.client.delete(`/api/v1/cart/items/${encodedId}`),
1539
+ () => this.client.call("cart.removeItem", {
1230
1540
  cart_item_id: cartItemId
1231
1541
  })
1232
1542
  );
1233
1543
  }
1234
1544
  async clear() {
1235
- return safe2(this.client.call("cart.clearCart"));
1545
+ return safeWithFallback2(
1546
+ () => this.client.delete("/api/v1/cart"),
1547
+ () => this.client.call("cart.clearCart")
1548
+ );
1236
1549
  }
1237
1550
  async applyCoupon(code) {
1238
- return safe2(
1239
- this.client.call("cart.applyCoupon", {
1551
+ return safeWithFallback2(
1552
+ () => this.client.post("/api/v1/cart/coupons", {
1553
+ coupon_code: code
1554
+ }),
1555
+ () => this.client.call("cart.applyCoupon", {
1240
1556
  coupon_code: code
1241
1557
  })
1242
1558
  );
1243
1559
  }
1244
1560
  async removeCoupon() {
1245
- return safe2(this.client.call("cart.removeCoupon"));
1561
+ return safeWithFallback2(
1562
+ () => this.client.delete("/api/v1/cart/coupons/current"),
1563
+ () => this.client.call("cart.removeCoupon")
1564
+ );
1246
1565
  }
1247
1566
  async isEmpty() {
1248
1567
  const countResult = await this.getCount();
@@ -2015,6 +2334,14 @@ async function safe3(promise) {
2015
2334
  return err(toCimplifyError3(error));
2016
2335
  }
2017
2336
  }
2337
+ async function safeWithFallback3(primary, fallback) {
2338
+ const primaryResult = await safe3(primary());
2339
+ if (primaryResult.ok) return primaryResult;
2340
+ if (primaryResult.error.code !== "HTTP_404" && primaryResult.error.code !== "API_ERROR") {
2341
+ return primaryResult;
2342
+ }
2343
+ return safe3(fallback());
2344
+ }
2018
2345
  function toTerminalFailure(code, message, recoverable) {
2019
2346
  return {
2020
2347
  success: false,
@@ -2042,8 +2369,11 @@ var CheckoutService = class {
2042
2369
  ...data,
2043
2370
  idempotency_key: data.idempotency_key || generateIdempotencyKey()
2044
2371
  };
2045
- return safe3(
2046
- this.client.call(CHECKOUT_MUTATION.PROCESS, {
2372
+ return safeWithFallback3(
2373
+ () => this.client.post("/api/v1/checkout", {
2374
+ checkout_data: checkoutData
2375
+ }),
2376
+ () => this.client.call(CHECKOUT_MUTATION.PROCESS, {
2047
2377
  checkout_data: checkoutData
2048
2378
  })
2049
2379
  );
@@ -2057,18 +2387,23 @@ var CheckoutService = class {
2057
2387
  );
2058
2388
  }
2059
2389
  async submitAuthorization(input) {
2060
- return safe3(
2061
- this.client.call(PAYMENT_MUTATION.SUBMIT_AUTHORIZATION, input)
2390
+ return safeWithFallback3(
2391
+ () => this.client.post("/api/v1/payments/authorization", input),
2392
+ () => this.client.call(PAYMENT_MUTATION.SUBMIT_AUTHORIZATION, input)
2062
2393
  );
2063
2394
  }
2064
2395
  async pollPaymentStatus(orderId) {
2065
- return safe3(
2066
- this.client.call(PAYMENT_MUTATION.CHECK_STATUS, orderId)
2396
+ const encodedId = encodeURIComponent(orderId);
2397
+ return safeWithFallback3(
2398
+ () => this.client.get(`/api/v1/orders/${encodedId}/payment-status`),
2399
+ () => this.client.call(PAYMENT_MUTATION.CHECK_STATUS, orderId)
2067
2400
  );
2068
2401
  }
2069
2402
  async updateOrderCustomer(orderId, customer) {
2070
- return safe3(
2071
- this.client.call(ORDER_MUTATION.UPDATE_CUSTOMER, {
2403
+ const encodedId = encodeURIComponent(orderId);
2404
+ return safeWithFallback3(
2405
+ () => this.client.post(`/api/v1/orders/${encodedId}/customer`, customer),
2406
+ () => this.client.call(ORDER_MUTATION.UPDATE_CUSTOMER, {
2072
2407
  order_id: orderId,
2073
2408
  ...customer
2074
2409
  })
@@ -2198,6 +2533,14 @@ async function safe4(promise) {
2198
2533
  return err(toCimplifyError4(error));
2199
2534
  }
2200
2535
  }
2536
+ async function safeWithFallback4(primary, fallback) {
2537
+ const primaryResult = await safe4(primary());
2538
+ if (primaryResult.ok) return primaryResult;
2539
+ if (primaryResult.error.code !== "HTTP_404" && primaryResult.error.code !== "API_ERROR") {
2540
+ return primaryResult;
2541
+ }
2542
+ return safe4(fallback());
2543
+ }
2201
2544
  var OrderQueries = class {
2202
2545
  constructor(client) {
2203
2546
  this.client = client;
@@ -2214,20 +2557,36 @@ var OrderQueries = class {
2214
2557
  if (options?.offset) {
2215
2558
  query += `#offset(${options.offset})`;
2216
2559
  }
2217
- return safe4(this.client.query(query));
2560
+ const params = new URLSearchParams();
2561
+ if (options?.status) params.set("status", options.status);
2562
+ if (options?.limit) params.set("limit", String(options.limit));
2563
+ if (options?.offset) params.set("offset", String(options.offset));
2564
+ const path = params.toString() ? `/api/v1/orders?${params.toString()}` : "/api/v1/orders";
2565
+ return safeWithFallback4(
2566
+ () => this.client.get(path),
2567
+ () => this.client.query(query)
2568
+ );
2218
2569
  }
2219
2570
  async get(orderId) {
2220
- return safe4(this.client.query(`orders.${orderId}`));
2571
+ const encodedId = encodeURIComponent(orderId);
2572
+ return safeWithFallback4(
2573
+ () => this.client.get(`/api/v1/orders/${encodedId}`),
2574
+ () => this.client.query(`orders.${orderId}`)
2575
+ );
2221
2576
  }
2222
2577
  async getRecent(limit = 5) {
2223
2578
  return safe4(this.client.query(`orders#sort(created_at,desc)#limit(${limit})`));
2224
2579
  }
2225
2580
  async getByStatus(status) {
2226
- return safe4(this.client.query(`orders[?(@.status=='${status}')]`));
2581
+ return this.list({ status });
2227
2582
  }
2228
2583
  async cancel(orderId, reason) {
2229
- return safe4(
2230
- this.client.call("order.cancelOrder", {
2584
+ const encodedId = encodeURIComponent(orderId);
2585
+ return safeWithFallback4(
2586
+ () => this.client.post(`/api/v1/orders/${encodedId}/cancel`, {
2587
+ reason
2588
+ }),
2589
+ () => this.client.call("order.cancelOrder", {
2231
2590
  order_id: orderId,
2232
2591
  reason
2233
2592
  })
@@ -2402,12 +2761,23 @@ async function safe6(promise) {
2402
2761
  return err(toCimplifyError6(error));
2403
2762
  }
2404
2763
  }
2764
+ async function safeWithFallback5(primary, fallback) {
2765
+ const primaryResult = await safe6(primary());
2766
+ if (primaryResult.ok) return primaryResult;
2767
+ if (primaryResult.error.code !== "HTTP_404" && primaryResult.error.code !== "API_ERROR") {
2768
+ return primaryResult;
2769
+ }
2770
+ return safe6(fallback());
2771
+ }
2405
2772
  var AuthService = class {
2406
2773
  constructor(client) {
2407
2774
  this.client = client;
2408
2775
  }
2409
2776
  async getStatus() {
2410
- return safe6(this.client.query("auth"));
2777
+ return safeWithFallback5(
2778
+ () => this.client.get("/api/v1/auth/status"),
2779
+ () => this.client.query("auth")
2780
+ );
2411
2781
  }
2412
2782
  async getCurrentUser() {
2413
2783
  const result = await this.getStatus();
@@ -2420,23 +2790,34 @@ var AuthService = class {
2420
2790
  return ok(result.value.is_authenticated);
2421
2791
  }
2422
2792
  async requestOtp(contact, contactType) {
2423
- return safe6(
2424
- this.client.call(AUTH_MUTATION.REQUEST_OTP, {
2793
+ return safeWithFallback5(
2794
+ () => this.client.post("/api/v1/auth/request-otp", {
2795
+ contact,
2796
+ contact_type: contactType
2797
+ }),
2798
+ () => this.client.call(AUTH_MUTATION.REQUEST_OTP, {
2425
2799
  contact,
2426
2800
  contact_type: contactType
2427
2801
  })
2428
2802
  );
2429
2803
  }
2430
2804
  async verifyOtp(code, contact) {
2431
- return safe6(
2432
- this.client.call(AUTH_MUTATION.VERIFY_OTP, {
2805
+ return safeWithFallback5(
2806
+ () => this.client.post("/api/v1/auth/verify-otp", {
2807
+ otp_code: code,
2808
+ contact
2809
+ }),
2810
+ () => this.client.call(AUTH_MUTATION.VERIFY_OTP, {
2433
2811
  otp_code: code,
2434
2812
  contact
2435
2813
  })
2436
2814
  );
2437
2815
  }
2438
2816
  async logout() {
2439
- return safe6(this.client.call("auth.logout"));
2817
+ return safeWithFallback5(
2818
+ () => this.client.post("/api/v1/auth/logout"),
2819
+ () => this.client.call("auth.logout")
2820
+ );
2440
2821
  }
2441
2822
  async updateProfile(input) {
2442
2823
  return safe6(this.client.call("auth.update_profile", input));
@@ -2464,12 +2845,23 @@ async function safe7(promise) {
2464
2845
  return err(toCimplifyError7(error));
2465
2846
  }
2466
2847
  }
2848
+ async function safeWithFallback6(primary, fallback) {
2849
+ const primaryResult = await safe7(primary());
2850
+ if (primaryResult.ok) return primaryResult;
2851
+ if (primaryResult.error.code !== "HTTP_404" && primaryResult.error.code !== "API_ERROR") {
2852
+ return primaryResult;
2853
+ }
2854
+ return safe7(fallback());
2855
+ }
2467
2856
  var BusinessService = class {
2468
2857
  constructor(client) {
2469
2858
  this.client = client;
2470
2859
  }
2471
2860
  async getInfo() {
2472
- return safe7(this.client.query("business.info"));
2861
+ return safeWithFallback6(
2862
+ () => this.client.get("/api/v1/business"),
2863
+ () => this.client.query("business.info")
2864
+ );
2473
2865
  }
2474
2866
  async getByHandle(handle) {
2475
2867
  return safe7(this.client.query(`business.handle.${handle}`));
@@ -2478,24 +2870,48 @@ var BusinessService = class {
2478
2870
  return safe7(this.client.query("business.domain", { domain }));
2479
2871
  }
2480
2872
  async getSettings() {
2481
- return safe7(this.client.query("business.settings"));
2873
+ return safeWithFallback6(
2874
+ () => this.client.get("/api/v1/business/settings"),
2875
+ () => this.client.query("business.settings")
2876
+ );
2482
2877
  }
2483
2878
  async getTheme() {
2484
- return safe7(this.client.query("business.theme"));
2879
+ return safeWithFallback6(
2880
+ () => this.client.get("/api/v1/business/theme"),
2881
+ () => this.client.query("business.theme")
2882
+ );
2485
2883
  }
2486
2884
  async getLocations() {
2487
- return safe7(this.client.query("business.locations"));
2885
+ return safeWithFallback6(
2886
+ () => this.client.get("/api/v1/business/locations"),
2887
+ () => this.client.query("business.locations")
2888
+ );
2488
2889
  }
2489
2890
  async getLocation(locationId) {
2490
- return safe7(this.client.query(`business.locations.${locationId}`));
2891
+ const result = await this.getLocations();
2892
+ if (!result.ok) return err(result.error);
2893
+ const location = result.value.find((item) => item.id === locationId);
2894
+ if (!location) {
2895
+ return err(new CimplifyError(ErrorCode.NOT_FOUND, `Location not found: ${locationId}`, false));
2896
+ }
2897
+ return ok(location);
2491
2898
  }
2492
2899
  async getHours() {
2493
- return safe7(this.client.query("business.hours"));
2900
+ return safeWithFallback6(
2901
+ () => this.client.get("/api/v1/business/hours"),
2902
+ () => this.client.query("business.hours")
2903
+ );
2494
2904
  }
2495
2905
  async getLocationHours(locationId) {
2496
- return safe7(this.client.query(`business.locations.${locationId}.hours`));
2906
+ const result = await this.getHours();
2907
+ if (!result.ok) return result;
2908
+ return ok(result.value.filter((hour) => hour.location_id === locationId));
2497
2909
  }
2498
2910
  async getBootstrap() {
2911
+ const restBootstrap = await safe7(this.client.get("/api/v1/bootstrap"));
2912
+ if (restBootstrap.ok) {
2913
+ return restBootstrap;
2914
+ }
2499
2915
  const [businessResult, locationsResult, categoriesResult] = await Promise.all([
2500
2916
  this.getInfo(),
2501
2917
  this.getLocations(),
@@ -2788,15 +3204,30 @@ async function safe11(promise) {
2788
3204
  return err(toCimplifyError11(error));
2789
3205
  }
2790
3206
  }
3207
+ async function safeWithFallback7(primary, fallback) {
3208
+ const primaryResult = await safe11(primary());
3209
+ if (primaryResult.ok) return primaryResult;
3210
+ if (primaryResult.error.code !== "HTTP_404" && primaryResult.error.code !== "API_ERROR") {
3211
+ return primaryResult;
3212
+ }
3213
+ return safe11(fallback());
3214
+ }
2791
3215
  var FxService = class {
2792
3216
  constructor(client) {
2793
3217
  this.client = client;
2794
3218
  }
2795
3219
  async getRate(from, to) {
2796
- return safe11(this.client.call("fx.getRate", { from, to }));
3220
+ const path = `/api/v1/fx/rate?from=${encodeURIComponent(from)}&to=${encodeURIComponent(to)}`;
3221
+ return safeWithFallback7(
3222
+ () => this.client.get(path),
3223
+ () => this.client.call("fx.getRate", { from, to })
3224
+ );
2797
3225
  }
2798
3226
  async lockQuote(request) {
2799
- return safe11(this.client.call("fx.lockQuote", request));
3227
+ return safeWithFallback7(
3228
+ () => this.client.post("/api/v1/fx/quotes", request),
3229
+ () => this.client.call("fx.lockQuote", request)
3230
+ );
2800
3231
  }
2801
3232
  };
2802
3233
 
@@ -3765,6 +4196,15 @@ var CimplifyClient = class {
3765
4196
  });
3766
4197
  return this.handleRestResponse(response);
3767
4198
  }
4199
+ async patch(path, body) {
4200
+ const response = await this.resilientFetch(`${this.baseUrl}${path}`, {
4201
+ method: "PATCH",
4202
+ credentials: this.credentials,
4203
+ headers: this.getHeaders(),
4204
+ body: body ? JSON.stringify(body) : void 0
4205
+ });
4206
+ return this.handleRestResponse(response);
4207
+ }
3768
4208
  async delete(path) {
3769
4209
  const response = await this.resilientFetch(`${this.baseUrl}${path}`, {
3770
4210
  method: "DELETE",
@@ -3804,11 +4244,14 @@ var CimplifyClient = class {
3804
4244
  async handleRestResponse(response) {
3805
4245
  const json = await response.json();
3806
4246
  if (!response.ok) {
4247
+ const errorCode = typeof json.error === "object" && json.error?.error_code || typeof json.error === "object" && json.error?.code || "API_ERROR";
4248
+ const errorMessage = typeof json.error === "object" && json.error?.error_message || typeof json.error === "object" && json.error?.message || typeof json.error === "string" && json.error || typeof json.message === "string" && json.message || "An error occurred";
4249
+ const retryable = typeof json.error === "object" && typeof json.error?.retryable === "boolean" ? json.error.retryable : false;
3807
4250
  const error = enrichError(
3808
4251
  new CimplifyError(
3809
- json.error?.error_code || "API_ERROR",
3810
- json.error?.error_message || "An error occurred",
3811
- false
4252
+ errorCode,
4253
+ errorMessage,
4254
+ retryable
3812
4255
  ),
3813
4256
  { isTestMode: this.isTestMode() }
3814
4257
  );
@@ -3819,7 +4262,21 @@ var CimplifyClient = class {
3819
4262
  }
3820
4263
  throw error;
3821
4264
  }
3822
- return json.data;
4265
+ if (json?.success === false || json?.error?.code || json?.error?.message) {
4266
+ const error = enrichError(
4267
+ new CimplifyError(
4268
+ json.error?.code || "API_ERROR",
4269
+ json.error?.message || "An error occurred",
4270
+ json.error?.retryable || false
4271
+ ),
4272
+ { isTestMode: this.isTestMode() }
4273
+ );
4274
+ throw error;
4275
+ }
4276
+ if (json?.data !== void 0) {
4277
+ return json.data;
4278
+ }
4279
+ return json;
3823
4280
  }
3824
4281
  async handleResponse(response) {
3825
4282
  const json = await response.json();