@thorprovider/adapters 4.2.0 → 4.2.2

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 (48) hide show
  1. package/.turbo/turbo-build.log +18 -18
  2. package/.turbo/turbo-test.log +1 -0
  3. package/.turbo/turbo-type-check.log +0 -0
  4. package/AGENTS.md +1 -1
  5. package/CHANGELOG.md +12 -0
  6. package/PROVIDER_IMPLEMENTATION_ANALYSIS.md +659 -0
  7. package/README.md +22 -3
  8. package/dist/.tsbuildinfo +1 -1
  9. package/dist/index.d.mts +140 -2
  10. package/dist/index.d.ts +140 -2
  11. package/dist/index.js +1075 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/index.mjs +1070 -0
  14. package/dist/index.mjs.map +1 -1
  15. package/docs/RETRY_SOLUTION_SUMMARY.md +26 -11
  16. package/docs/authentication.md +89 -62
  17. package/docs/capabilities-system.md +100 -38
  18. package/docs/category-customization.md +37 -29
  19. package/docs/fetch-reliability-solution.md +127 -278
  20. package/docs/getting-started.md +43 -29
  21. package/docs/profile-management.md +68 -38
  22. package/docs/providers-overview.md +14 -0
  23. package/docs/services-overview.md +20 -2
  24. package/docs/update-documentation.md +10 -8
  25. package/package.json +11 -6
  26. package/publish.log +93 -0
  27. package/quick-reference.md +1 -0
  28. package/src/factory/index.ts +4 -0
  29. package/src/index.ts +7 -0
  30. package/src/providers/index.ts +3 -0
  31. package/src/providers/medusa/admin.test.ts +404 -0
  32. package/src/providers/medusa/admin.ts +442 -0
  33. package/src/providers/medusa/auth.test.ts +95 -0
  34. package/src/providers/medusa/index.test.ts +392 -0
  35. package/src/providers/medusa/live-smoke.test.ts +412 -0
  36. package/src/providers/stelorder/client.test-helpers.ts +3 -0
  37. package/src/providers/stelorder/client.test.ts +58 -0
  38. package/src/providers/stelorder/client.ts +326 -0
  39. package/src/providers/stelorder/index.test.ts +48 -0
  40. package/src/providers/stelorder/index.ts +685 -0
  41. package/src/providers/stelorder/live-smoke.test.ts +54 -0
  42. package/src/providers/stelorder/transforms.test.ts +103 -0
  43. package/src/providers/stelorder/transforms.ts +631 -0
  44. package/src/resilience/README.md +70 -48
  45. package/src/types/capabilities.types.ts +51 -0
  46. package/vitest.config.ts +13 -0
  47. package/vitest.live.config.ts +18 -0
  48. package/vitest.setup.ts +6 -0
package/dist/index.js CHANGED
@@ -55,8 +55,10 @@ __export(src_exports, {
55
55
  ResourceNotFoundError: () => ResourceNotFoundError,
56
56
  SHOPIFY_CAPABILITIES: () => SHOPIFY_CAPABILITIES,
57
57
  SPREE_CAPABILITIES: () => SPREE_CAPABILITIES,
58
+ STELORDER_CAPABILITIES: () => STELORDER_CAPABILITIES,
58
59
  ShopifyProvider: () => ShopifyProvider,
59
60
  SpreeProvider: () => SpreeProvider,
61
+ StelOrderProvider: () => StelOrderProvider,
60
62
  StorefrontConfigError: () => import_types2.StorefrontConfigError,
61
63
  WOOCOMMERCE_CAPABILITIES: () => WOOCOMMERCE_CAPABILITIES,
62
64
  WooCommerceProvider: () => WooCommerceProvider,
@@ -65,8 +67,11 @@ __export(src_exports, {
65
67
  buildChannelScopeMetadata: () => buildChannelScopeMetadata,
66
68
  calculateDistance: () => calculateDistance,
67
69
  createBackendMetadataAdapter: () => createBackendMetadataAdapter,
70
+ createFetchWithRetry: () => createFetchWithRetry,
68
71
  createLogger: () => createLogger,
69
72
  createProvider: () => createProvider,
73
+ extractErrorMessage: () => extractErrorMessage,
74
+ fetchWithRetry: () => fetchWithRetry,
70
75
  filterByChannel: () => filterByChannel,
71
76
  filterGlobalOnly: () => filterGlobalOnly,
72
77
  geocodeAddress: () => geocodeAddress,
@@ -163,6 +168,41 @@ var MEDUSA_CAPABILITIES = {
163
168
  loyaltyProgram: false
164
169
  // Requires custom implementation
165
170
  };
171
+ var STELORDER_CAPABILITIES = {
172
+ // Profile Management
173
+ updateProfile: false,
174
+ updateEmail: false,
175
+ changePasswordDirect: false,
176
+ changePasswordViaEmail: false,
177
+ deleteAccount: false,
178
+ // Avatar
179
+ uploadAvatar: false,
180
+ avatarViaMetadata: false,
181
+ // Custom Attributes
182
+ customAttributes: false,
183
+ // Orders
184
+ fetchOrders: true,
185
+ cancelOrder: false,
186
+ // Addresses
187
+ manageAddresses: true,
188
+ defaultAddress: false,
189
+ // Cart/Checkout
190
+ applyDiscounts: false,
191
+ shippingCalculation: false,
192
+ guestCheckout: false,
193
+ savedPaymentMethods: false,
194
+ listPaymentProviders: true,
195
+ regionSpecificPayments: false,
196
+ // Wishlist
197
+ wishlist: false,
198
+ // Search
199
+ advancedSearch: false,
200
+ facetedFilters: false,
201
+ // Reviews
202
+ productReviews: false,
203
+ // Loyalty
204
+ loyaltyProgram: false
205
+ };
166
206
  var SHOPIFY_CAPABILITIES = {
167
207
  // Profile Management
168
208
  updateProfile: true,
@@ -580,6 +620,9 @@ async function fetchWithRetry(url, init, retryConfig) {
580
620
  }
581
621
  throw lastError;
582
622
  }
623
+ function createFetchWithRetry(retryConfig) {
624
+ return (url, init) => fetchWithRetry(url, init, retryConfig);
625
+ }
583
626
 
584
627
  // src/resilience/circuit-breaker.ts
585
628
  var CircuitBreaker = class {
@@ -8069,6 +8112,1031 @@ var MagentoProvider = class {
8069
8112
  }
8070
8113
  };
8071
8114
 
8115
+ // src/providers/stelorder/transforms.ts
8116
+ function normalizeStelCollection(payload) {
8117
+ if (!payload) {
8118
+ return [];
8119
+ }
8120
+ return Array.isArray(payload) ? payload : [payload];
8121
+ }
8122
+ function normalizeStelEntity(payload) {
8123
+ if (!payload) {
8124
+ return void 0;
8125
+ }
8126
+ return Array.isArray(payload) ? payload[0] : payload;
8127
+ }
8128
+ function transformStelMoney(amount, currencyCode = "USD") {
8129
+ const normalizedAmount = typeof amount === "string" ? Number.parseFloat(amount) : amount ?? 0;
8130
+ return {
8131
+ amount: Number.isFinite(normalizedAmount) ? normalizedAmount.toFixed(2) : "0.00",
8132
+ currencyCode: currencyCode.toUpperCase()
8133
+ };
8134
+ }
8135
+ function transformStelImage(url, altText = "") {
8136
+ const normalizedUrl = url?.trim();
8137
+ if (!normalizedUrl) {
8138
+ return void 0;
8139
+ }
8140
+ return {
8141
+ url: normalizedUrl,
8142
+ altText,
8143
+ width: 800,
8144
+ height: 800
8145
+ };
8146
+ }
8147
+ function normalizeStelDate(value) {
8148
+ if (!value) {
8149
+ return (/* @__PURE__ */ new Date()).toISOString();
8150
+ }
8151
+ const parsed = new Date(value);
8152
+ return Number.isNaN(parsed.getTime()) ? (/* @__PURE__ */ new Date()).toISOString() : parsed.toISOString();
8153
+ }
8154
+ function toStelStringId(value) {
8155
+ if (value === null || value === void 0) {
8156
+ return "";
8157
+ }
8158
+ return String(value);
8159
+ }
8160
+ function slugify(value) {
8161
+ return value.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
8162
+ }
8163
+ function buildStelHandle(...candidates) {
8164
+ for (const candidate of candidates) {
8165
+ if (candidate === null || candidate === void 0) {
8166
+ continue;
8167
+ }
8168
+ const normalized = slugify(String(candidate).trim());
8169
+ if (normalized) {
8170
+ return normalized;
8171
+ }
8172
+ }
8173
+ return "stel-item";
8174
+ }
8175
+ function transformStelProductImages(product) {
8176
+ const images = [];
8177
+ if (!product["item-images"]) {
8178
+ return images;
8179
+ }
8180
+ const sorted = [...product["item-images"]].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
8181
+ for (const img of sorted) {
8182
+ const transformed = transformStelImage(img["item-image-path"], product.name ?? "");
8183
+ if (transformed) {
8184
+ images.push(transformed);
8185
+ }
8186
+ }
8187
+ return images;
8188
+ }
8189
+ function deriveStelStockStatus(product) {
8190
+ if (!product["stock-enabled"]) {
8191
+ return "in_stock";
8192
+ }
8193
+ const realStock = product["real-stock"] ?? 0;
8194
+ const minimumStock = product["minimum-stock"] ?? 0;
8195
+ if (realStock <= 0) {
8196
+ return "out_of_stock";
8197
+ }
8198
+ if (realStock <= minimumStock) {
8199
+ return "low_stock";
8200
+ }
8201
+ return "in_stock";
8202
+ }
8203
+ function buildSyntheticVariant(product, currencyCode) {
8204
+ const price = transformStelMoney(product["sales-price"], currencyCode);
8205
+ const stockStatus = deriveStelStockStatus(product);
8206
+ const quantityAvailable = product["stock-enabled"] ? product["real-stock"] ?? 0 : void 0;
8207
+ const image = product["item-images"]?.[0] ? transformStelImage(product["item-images"][0]["item-image-path"], product.name ?? "") : void 0;
8208
+ return {
8209
+ id: toStelStringId(product.id),
8210
+ title: "Default",
8211
+ sku: product.barcode ?? product["full-reference"] ?? void 0,
8212
+ availableForSale: stockStatus !== "out_of_stock",
8213
+ selectedOptions: [],
8214
+ price,
8215
+ compareAtPrice: void 0,
8216
+ quantityAvailable,
8217
+ stockStatus,
8218
+ image
8219
+ };
8220
+ }
8221
+ function transformStelProduct(raw, currencyCode) {
8222
+ const id = toStelStringId(raw.id);
8223
+ const handle = buildStelHandle(raw["full-reference"], raw.reference, raw.name, raw.id);
8224
+ const price = transformStelMoney(raw["sales-price"], currencyCode);
8225
+ const images = transformStelProductImages(raw);
8226
+ const variant = buildSyntheticVariant(raw, currencyCode);
8227
+ const now = (/* @__PURE__ */ new Date()).toISOString();
8228
+ return {
8229
+ id,
8230
+ handle,
8231
+ title: raw.name ?? "",
8232
+ description: raw.description ?? "",
8233
+ availableForSale: variant.availableForSale,
8234
+ options: [],
8235
+ variants: [variant],
8236
+ featuredImage: images[0],
8237
+ images,
8238
+ priceRange: {
8239
+ minVariantPrice: price,
8240
+ maxVariantPrice: price
8241
+ },
8242
+ productType: void 0,
8243
+ vendor: void 0,
8244
+ tags: raw.promotional ? ["promotional"] : [],
8245
+ createdAt: normalizeStelDate(raw["creation-date"]),
8246
+ updatedAt: normalizeStelDate(raw["utc-last-modification-date"]) || now,
8247
+ metadata: {
8248
+ stelFullReference: raw["full-reference"],
8249
+ stelReference: raw.reference,
8250
+ stelBarcode: raw.barcode,
8251
+ stelCategoryId: raw["product-category-id"],
8252
+ stelInactive: raw.inactive,
8253
+ stelPromotional: raw.promotional,
8254
+ stelPurchasePrice: raw["purchase-price"]
8255
+ }
8256
+ };
8257
+ }
8258
+ function transformStelCategory(raw) {
8259
+ const id = toStelStringId(raw.id);
8260
+ const handle = buildStelHandle(raw.slug, raw.name, raw.id);
8261
+ return {
8262
+ id,
8263
+ name: raw.name ?? "",
8264
+ handle,
8265
+ description: raw.description ?? void 0,
8266
+ parentCategoryId: raw["parent-category-id"] ? toStelStringId(raw["parent-category-id"]) : void 0,
8267
+ metadata: {
8268
+ stelSlug: raw.slug
8269
+ }
8270
+ };
8271
+ }
8272
+ function transformStelCategoryToCollection(raw) {
8273
+ const id = toStelStringId(raw.id);
8274
+ const handle = buildStelHandle(raw.slug, raw.name, raw.id);
8275
+ return {
8276
+ id,
8277
+ handle,
8278
+ title: raw.name ?? "",
8279
+ description: raw.description ?? "",
8280
+ path: `/collections/${handle}`,
8281
+ updatedAt: normalizeStelDate(raw["utc-last-modification-date"])
8282
+ };
8283
+ }
8284
+ function transformStelWarehouseToStockLocation(raw) {
8285
+ return {
8286
+ id: toStelStringId(raw.id),
8287
+ name: raw.name ?? "Warehouse"
8288
+ };
8289
+ }
8290
+ function transformStelProductWarehouseToInventoryLevel(pw) {
8291
+ return {
8292
+ locationId: toStelStringId(pw["warehouse-id"]),
8293
+ locationName: pw["warehouse-path"] ?? `Warehouse ${pw["warehouse-id"] ?? "unknown"}`,
8294
+ availableQuantity: pw["real-stock"] ?? 0,
8295
+ reservedQuantity: Math.max(0, (pw["virtual-stock"] ?? 0) - (pw["real-stock"] ?? 0)),
8296
+ stockedQuantity: pw["virtual-stock"] ?? pw["real-stock"] ?? 0
8297
+ };
8298
+ }
8299
+ function splitStelName(fullName) {
8300
+ if (!fullName?.trim()) {
8301
+ return { firstName: "", lastName: "" };
8302
+ }
8303
+ const parts = fullName.trim().split(/\s+/);
8304
+ const firstName = parts[0] ?? "";
8305
+ const lastName = parts.length > 1 ? parts.slice(1).join(" ") : "";
8306
+ return { firstName, lastName };
8307
+ }
8308
+ function transformStelClient(raw) {
8309
+ const { firstName, lastName } = splitStelName(raw.name ?? raw["business-name"]);
8310
+ return {
8311
+ id: toStelStringId(raw.id),
8312
+ email: raw.email ?? "",
8313
+ firstName: firstName || null,
8314
+ lastName: lastName || null,
8315
+ phone: raw.phone ?? raw.mobile ?? null,
8316
+ hasAccount: true,
8317
+ createdAt: normalizeStelDate(raw["utc-last-modification-date"]),
8318
+ updatedAt: normalizeStelDate(raw["utc-last-modification-date"]),
8319
+ metadata: {
8320
+ stelBusinessName: raw["business-name"],
8321
+ stelRateId: raw["rate-id"],
8322
+ stelPaymentOptionId: raw["payment-option-id"],
8323
+ stelPaymentTermId: raw["payment-term-id"],
8324
+ stelDeliveryOptionId: raw["delivery-option-id"]
8325
+ }
8326
+ };
8327
+ }
8328
+ function deriveStelOrderStatus(raw) {
8329
+ if (raw.deleted) {
8330
+ return "cancelled";
8331
+ }
8332
+ const status = (raw.status ?? "").toLowerCase();
8333
+ if (status.includes("cancel") || status.includes("anulad")) {
8334
+ return "cancelled";
8335
+ }
8336
+ if (status.includes("complet") || status.includes("cerrad") || status.includes("settled")) {
8337
+ return "completed";
8338
+ }
8339
+ if (status.includes("process") || status.includes("confirm")) {
8340
+ return "processing";
8341
+ }
8342
+ return "pending";
8343
+ }
8344
+ function deriveStelPaymentStatus(raw) {
8345
+ const orderStatus = deriveStelOrderStatus(raw);
8346
+ if (orderStatus === "completed") {
8347
+ return "paid";
8348
+ }
8349
+ if (orderStatus === "cancelled") {
8350
+ return "pending";
8351
+ }
8352
+ return "pending";
8353
+ }
8354
+ function deriveStelFulfillmentStatus(raw) {
8355
+ const orderStatus = deriveStelOrderStatus(raw);
8356
+ if (orderStatus === "completed") {
8357
+ return "fulfilled";
8358
+ }
8359
+ return "unfulfilled";
8360
+ }
8361
+ function transformStelDocumentLine(line, index, currencyCode) {
8362
+ const unitPrice = line["item-base-price"] ?? 0;
8363
+ const quantity = line.units ?? 1;
8364
+ const lineTotal = unitPrice * quantity;
8365
+ return {
8366
+ id: toStelStringId(line["item-id"] ?? index),
8367
+ title: line["item-name"] ?? "",
8368
+ variantTitle: void 0,
8369
+ quantity,
8370
+ price: transformStelMoney(unitPrice, currencyCode),
8371
+ total: transformStelMoney(lineTotal, currencyCode),
8372
+ sku: void 0,
8373
+ productId: line["item-id"] ? toStelStringId(line["item-id"]) : void 0
8374
+ };
8375
+ }
8376
+ function transformStelSalesOrder(raw, currencyCode) {
8377
+ const id = toStelStringId(raw.id);
8378
+ const now = (/* @__PURE__ */ new Date()).toISOString();
8379
+ const items = (raw["document-lines"] ?? []).filter((line) => line["line-type"] === "ITEM" || !line["line-type"]).map((line, i) => transformStelDocumentLine(line, i, currencyCode));
8380
+ const status = deriveStelOrderStatus(raw);
8381
+ return {
8382
+ id,
8383
+ orderNumber: raw.reference ?? id,
8384
+ email: raw.email ?? "",
8385
+ status,
8386
+ paymentStatus: deriveStelPaymentStatus(raw),
8387
+ fulfillmentStatus: deriveStelFulfillmentStatus(raw),
8388
+ customerId: raw["client-id"] ? toStelStringId(raw["client-id"]) : void 0,
8389
+ items,
8390
+ subtotal: transformStelMoney(raw["total-base"], currencyCode),
8391
+ total: transformStelMoney(raw.total, currencyCode),
8392
+ tax: raw["total-tax"] != null ? transformStelMoney(raw["total-tax"], currencyCode) : void 0,
8393
+ createdAt: normalizeStelDate(raw["creation-date"]),
8394
+ updatedAt: normalizeStelDate(raw["utc-last-modification-date"]) || now,
8395
+ cancelledAt: status === "cancelled" ? normalizeStelDate(raw["utc-last-modification-date"]) : void 0,
8396
+ completedAt: status === "completed" ? normalizeStelDate(raw["utc-last-modification-date"]) : void 0,
8397
+ metadata: {
8398
+ stelReference: raw.reference,
8399
+ stelStatus: raw.status,
8400
+ stelPaymentOptionId: raw["payment-option-id"],
8401
+ stelPaymentTermId: raw["payment-term-id"],
8402
+ stelDeliveryOptionId: raw["delivery-option-id"]
8403
+ }
8404
+ };
8405
+ }
8406
+ function inferPaymentMethodType(name) {
8407
+ if (!name) {
8408
+ return "other";
8409
+ }
8410
+ const lower = name.toLowerCase();
8411
+ if (lower.includes("transfer") || lower.includes("bank") || lower.includes("sepa") || lower.includes("iban")) {
8412
+ return "bank_transfer";
8413
+ }
8414
+ if (lower.includes("card") || lower.includes("tarjeta") || lower.includes("visa") || lower.includes("master")) {
8415
+ return "card";
8416
+ }
8417
+ if (lower.includes("paypal") || lower.includes("wallet") || lower.includes("apple") || lower.includes("google")) {
8418
+ return "wallet";
8419
+ }
8420
+ if (lower.includes("cash") || lower.includes("contrar") || lower.includes("efectivo") || lower.includes("cod")) {
8421
+ return "cash_on_delivery";
8422
+ }
8423
+ if (lower.includes("crypto") || lower.includes("bitcoin")) {
8424
+ return "crypto";
8425
+ }
8426
+ return "other";
8427
+ }
8428
+ function transformStelPaymentOption(raw) {
8429
+ return {
8430
+ id: toStelStringId(raw.id),
8431
+ name: raw.name ?? "Payment Option",
8432
+ type: inferPaymentMethodType(raw.name),
8433
+ isEnabled: !raw.deleted,
8434
+ requiresSetup: false,
8435
+ description: raw.description ?? void 0,
8436
+ metadata: {
8437
+ stelPath: raw.path,
8438
+ source: "paymentOption"
8439
+ }
8440
+ };
8441
+ }
8442
+ function transformStelDeliveryOption(raw, currencyCode) {
8443
+ return {
8444
+ id: toStelStringId(raw.id),
8445
+ name: raw.name ?? "Delivery Option",
8446
+ price: transformStelMoney(0, currencyCode),
8447
+ description: raw.description ?? void 0
8448
+ };
8449
+ }
8450
+
8451
+ // src/providers/stelorder/client.ts
8452
+ var DEFAULT_RETRY_CONFIG2 = {
8453
+ maxRetries: 2,
8454
+ initialDelayMs: 300,
8455
+ backoffMultiplier: 2,
8456
+ maxDelayMs: 5e3,
8457
+ timeoutMs: 1e4,
8458
+ retryableStatusCodes: [408, 429, 500, 502, 503, 504]
8459
+ };
8460
+ function sleep2(ms) {
8461
+ return new Promise((resolve) => setTimeout(resolve, ms));
8462
+ }
8463
+ function calculateDelay2(attempt, retryConfig) {
8464
+ const delay = retryConfig.initialDelayMs * Math.pow(retryConfig.backoffMultiplier, attempt);
8465
+ return Math.min(delay, retryConfig.maxDelayMs);
8466
+ }
8467
+ function isRetryableError2(error, retryConfig) {
8468
+ if (error instanceof ProviderAPIError) {
8469
+ return typeof error.status === "number" && retryConfig.retryableStatusCodes.includes(error.status);
8470
+ }
8471
+ if (!(error instanceof Error)) {
8472
+ return false;
8473
+ }
8474
+ const message = error.message.toLowerCase();
8475
+ return error.name === "AbortError" || error.name === "TimeoutError" || message.includes("fetch failed") || message.includes("timeout") || message.includes("econnrefused") || message.includes("etimedout");
8476
+ }
8477
+ function createRetryingFetch(fetchImplementation, retryConfig, logger2) {
8478
+ return async (url, init) => {
8479
+ let lastError = new Error("Unknown STEL Order request error");
8480
+ for (let attempt = 0; attempt <= retryConfig.maxRetries; attempt += 1) {
8481
+ const controller = new AbortController();
8482
+ const timeoutId = setTimeout(() => controller.abort(), retryConfig.timeoutMs);
8483
+ try {
8484
+ const response = await fetchImplementation(url, {
8485
+ ...init,
8486
+ signal: controller.signal
8487
+ });
8488
+ clearTimeout(timeoutId);
8489
+ if (!response.ok && retryConfig.retryableStatusCodes.includes(response.status)) {
8490
+ throw new ProviderAPIError(
8491
+ `STEL Order API error: ${response.status} ${response.statusText}`,
8492
+ "stelorder",
8493
+ response.status
8494
+ );
8495
+ }
8496
+ return response;
8497
+ } catch (error) {
8498
+ clearTimeout(timeoutId);
8499
+ lastError = error;
8500
+ if (attempt >= retryConfig.maxRetries || !isRetryableError2(error, retryConfig)) {
8501
+ throw error;
8502
+ }
8503
+ const delay = calculateDelay2(attempt, retryConfig);
8504
+ logger2.warn("STEL request failed, retrying.", {
8505
+ url,
8506
+ attempt: attempt + 1,
8507
+ maxAttempts: retryConfig.maxRetries + 1,
8508
+ nextRetryIn: delay,
8509
+ error: extractErrorMessage(error)
8510
+ });
8511
+ await sleep2(delay);
8512
+ }
8513
+ }
8514
+ throw lastError;
8515
+ };
8516
+ }
8517
+ async function parseErrorResponse(response) {
8518
+ const contentType = response.headers.get("content-type") ?? "";
8519
+ try {
8520
+ if (contentType.includes("application/json")) {
8521
+ const body = await response.json();
8522
+ const message = extractErrorMessage(body);
8523
+ if (message && message !== "An unknown error occurred") {
8524
+ return message;
8525
+ }
8526
+ }
8527
+ } catch {
8528
+ }
8529
+ try {
8530
+ const text = await response.text();
8531
+ if (text.trim()) {
8532
+ return text.trim();
8533
+ }
8534
+ } catch {
8535
+ }
8536
+ return `STEL Order API error: ${response.status} ${response.statusText}`;
8537
+ }
8538
+ function normalizeStelApiBaseUrl(baseUrl) {
8539
+ const trimmed = baseUrl.trim();
8540
+ if (!trimmed) {
8541
+ throw new ConfigurationError("Stel Order baseUrl is required.");
8542
+ }
8543
+ const normalized = trimmed.replace(/\/api\/openapi\.json$/i, "").replace(/\/+$/, "");
8544
+ return normalized.endsWith("/app") ? normalized : `${normalized}/app`;
8545
+ }
8546
+ var StelOrderClient = class {
8547
+ apiBaseUrl;
8548
+ apiKey;
8549
+ logger;
8550
+ retryConfig;
8551
+ fetchImplementation;
8552
+ constructor(config) {
8553
+ const apiKey = config.apiKey ?? config.publishableKey;
8554
+ if (!apiKey) {
8555
+ throw new ConfigurationError(
8556
+ "Stel Order API key is required. Pass `apiKey` or `publishableKey` to createProvider()."
8557
+ );
8558
+ }
8559
+ this.apiBaseUrl = normalizeStelApiBaseUrl(config.baseUrl);
8560
+ this.apiKey = apiKey;
8561
+ this.logger = createLogger("StelOrderClient", config.debug);
8562
+ this.retryConfig = {
8563
+ ...DEFAULT_RETRY_CONFIG2,
8564
+ ...config.retry
8565
+ };
8566
+ this.fetchImplementation = config.customFetch ? createRetryingFetch(config.customFetch, this.retryConfig, this.logger) : void 0;
8567
+ this.logger.info("Initializing Stel Order client", {
8568
+ apiBaseUrl: this.apiBaseUrl,
8569
+ retryConfig: this.retryConfig
8570
+ });
8571
+ }
8572
+ async list(resource, query) {
8573
+ const payload = await this.request({
8574
+ method: "GET",
8575
+ path: resource,
8576
+ query
8577
+ });
8578
+ return normalizeStelCollection(payload);
8579
+ }
8580
+ async getOne(resource, id, query) {
8581
+ const payload = await this.request({
8582
+ method: "GET",
8583
+ path: `${resource}/${id}`,
8584
+ query
8585
+ });
8586
+ return normalizeStelEntity(payload);
8587
+ }
8588
+ async create(resource, body) {
8589
+ return this.request({
8590
+ method: "POST",
8591
+ path: resource,
8592
+ body
8593
+ });
8594
+ }
8595
+ async update(resource, id, body) {
8596
+ return this.request({
8597
+ method: "PUT",
8598
+ path: `${resource}/${id}`,
8599
+ body
8600
+ });
8601
+ }
8602
+ async remove(resource, id) {
8603
+ await this.request({
8604
+ method: "DELETE",
8605
+ path: `${resource}/${id}`
8606
+ });
8607
+ }
8608
+ buildUrl(path, query) {
8609
+ const normalizedPath = path.replace(/^\/+/, "");
8610
+ const url = new URL(`${this.apiBaseUrl}/${normalizedPath}`);
8611
+ if (!query) {
8612
+ return url.toString();
8613
+ }
8614
+ for (const [key, value] of Object.entries(query)) {
8615
+ if (value === void 0 || value === null || value === "") {
8616
+ continue;
8617
+ }
8618
+ if (Array.isArray(value)) {
8619
+ url.searchParams.set(key, value.map(String).join(","));
8620
+ continue;
8621
+ }
8622
+ url.searchParams.set(key, String(value));
8623
+ }
8624
+ return url.toString();
8625
+ }
8626
+ buildHeaders(headers, hasBody = false) {
8627
+ const normalizedHeaders = new Headers(headers);
8628
+ normalizedHeaders.set("Accept", "application/json");
8629
+ normalizedHeaders.set("APIKEY", this.apiKey);
8630
+ if (hasBody && !normalizedHeaders.has("Content-Type")) {
8631
+ normalizedHeaders.set("Content-Type", "application/json");
8632
+ }
8633
+ return normalizedHeaders;
8634
+ }
8635
+ async executeFetch(url, init) {
8636
+ if (this.fetchImplementation) {
8637
+ return this.fetchImplementation(url, init);
8638
+ }
8639
+ return fetchWithRetry(url, init, this.retryConfig);
8640
+ }
8641
+ async request(options) {
8642
+ const url = this.buildUrl(options.path, options.query);
8643
+ const hasBody = options.body !== void 0;
8644
+ this.logger.debug("STEL request", {
8645
+ method: options.method,
8646
+ url
8647
+ });
8648
+ const response = await this.executeFetch(url, {
8649
+ method: options.method,
8650
+ headers: this.buildHeaders(options.headers, hasBody),
8651
+ body: hasBody ? JSON.stringify(options.body) : void 0
8652
+ });
8653
+ if (!response.ok) {
8654
+ const message = await parseErrorResponse(response);
8655
+ throw new ProviderAPIError(message, "stelorder", response.status);
8656
+ }
8657
+ if (response.status === 204) {
8658
+ return void 0;
8659
+ }
8660
+ const contentType = response.headers.get("content-type") ?? "";
8661
+ if (contentType.includes("application/json")) {
8662
+ return await response.json();
8663
+ }
8664
+ return await response.text();
8665
+ }
8666
+ };
8667
+
8668
+ // src/providers/stelorder/index.ts
8669
+ var StelOrderProvider = class {
8670
+ name = "stelorder";
8671
+ version = "1.0.0";
8672
+ capabilities = STELORDER_CAPABILITIES;
8673
+ client;
8674
+ logger;
8675
+ currencyCode;
8676
+ storefrontId;
8677
+ companyName;
8678
+ constructor(config) {
8679
+ this.client = new StelOrderClient(config);
8680
+ this.logger = createLogger("StelOrderProvider", config.debug);
8681
+ this.currencyCode = config.currencyCode ?? "USD";
8682
+ this.storefrontId = config.storefrontId ?? "stelorder-primary";
8683
+ this.companyName = config.companyName ?? "Stel Order";
8684
+ this.logger.info("Initializing Stel Order provider", {
8685
+ storefrontId: this.storefrontId,
8686
+ companyName: this.companyName,
8687
+ currencyCode: this.currencyCode
8688
+ });
8689
+ }
8690
+ // ============================================
8691
+ // Product Operations
8692
+ // ============================================
8693
+ async getProduct(handle, _options) {
8694
+ this.logger.debug("getProduct", { handle });
8695
+ try {
8696
+ if (/^\d+$/.test(handle)) {
8697
+ const raw = await this.client.getOne("products", handle);
8698
+ return raw ? transformStelProduct(raw, this.currencyCode) : void 0;
8699
+ }
8700
+ const rawProducts = await this.client.list("products", { limit: 100 });
8701
+ for (const raw of rawProducts) {
8702
+ const productHandle = buildStelHandle(raw["full-reference"], raw.reference, raw.name, raw.id);
8703
+ if (productHandle === handle) {
8704
+ return transformStelProduct(raw, this.currencyCode);
8705
+ }
8706
+ }
8707
+ return void 0;
8708
+ } catch (error) {
8709
+ this.logger.error("getProduct failed", { handle, error });
8710
+ throw this.wrapError("getProduct", error);
8711
+ }
8712
+ }
8713
+ async getProducts(options) {
8714
+ this.logger.debug("getProducts", { options });
8715
+ try {
8716
+ const query = {};
8717
+ if (options?.first) {
8718
+ query.limit = options.first;
8719
+ }
8720
+ if (options?.skip) {
8721
+ query.start = options.skip;
8722
+ }
8723
+ if (typeof options?.after === "number") {
8724
+ query.start = options.after;
8725
+ }
8726
+ if (options?.sortKey) {
8727
+ query.sort = options.reverse ? `-${options.sortKey}` : options.sortKey;
8728
+ }
8729
+ if (options?.categoryIds?.length) {
8730
+ query["product-category-id"] = `in:${options.categoryIds.join(",")}`;
8731
+ }
8732
+ const rawProducts = await this.client.list("products", query);
8733
+ let products = rawProducts.filter((p) => !p.deleted && !p.inactive).map((p) => transformStelProduct(p, this.currencyCode));
8734
+ if (options?.query) {
8735
+ const needle = options.query.toLowerCase();
8736
+ products = products.filter(
8737
+ (p) => p.title.toLowerCase().includes(needle) || p.description.toLowerCase().includes(needle) || p.handle.includes(needle)
8738
+ );
8739
+ }
8740
+ return products;
8741
+ } catch (error) {
8742
+ this.logger.error("getProducts failed", { options, error });
8743
+ throw this.wrapError("getProducts", error);
8744
+ }
8745
+ }
8746
+ async getProductRecommendations(_productId) {
8747
+ return [];
8748
+ }
8749
+ // ============================================
8750
+ // Category Operations
8751
+ // ============================================
8752
+ async getCategory(idOrHandle) {
8753
+ this.logger.debug("getCategory", { idOrHandle });
8754
+ try {
8755
+ if (/^\d+$/.test(idOrHandle)) {
8756
+ const raw = await this.client.getOne("productCategories", idOrHandle);
8757
+ return raw ? transformStelCategory(raw) : void 0;
8758
+ }
8759
+ const rawCategories = await this.client.list("productCategories");
8760
+ for (const raw of rawCategories) {
8761
+ const catHandle = buildStelHandle(raw.slug, raw.name, raw.id);
8762
+ if (catHandle === idOrHandle) {
8763
+ return transformStelCategory(raw);
8764
+ }
8765
+ }
8766
+ return void 0;
8767
+ } catch (error) {
8768
+ this.logger.error("getCategory failed", { idOrHandle, error });
8769
+ throw this.wrapError("getCategory", error);
8770
+ }
8771
+ }
8772
+ async getCategories(options) {
8773
+ this.logger.debug("getCategories", { options });
8774
+ try {
8775
+ if (options?.customFetcher) {
8776
+ return options.customFetcher(options);
8777
+ }
8778
+ const query = {};
8779
+ if (options?.limit) {
8780
+ query.limit = options.limit;
8781
+ }
8782
+ if (options?.parentCategoryId) {
8783
+ query["parent-category-id"] = options.parentCategoryId;
8784
+ }
8785
+ const rawCategories = await this.client.list("productCategories", query);
8786
+ let categories = rawCategories.filter((c) => !c.deleted).map(transformStelCategory);
8787
+ if (options?.query) {
8788
+ const needle = options.query.toLowerCase();
8789
+ categories = categories.filter(
8790
+ (c) => c.name.toLowerCase().includes(needle) || c.handle.includes(needle)
8791
+ );
8792
+ }
8793
+ return categories;
8794
+ } catch (error) {
8795
+ this.logger.error("getCategories failed", { options, error });
8796
+ throw this.wrapError("getCategories", error);
8797
+ }
8798
+ }
8799
+ async getCategoryProducts(handle, options) {
8800
+ this.logger.debug("getCategoryProducts", { handle, options });
8801
+ try {
8802
+ const category = await this.getCategory(handle);
8803
+ if (!category) {
8804
+ return [];
8805
+ }
8806
+ return this.getProducts({
8807
+ categoryIds: [category.id],
8808
+ first: options?.first,
8809
+ sortKey: options?.sortKey,
8810
+ reverse: options?.reverse,
8811
+ after: options?.after
8812
+ });
8813
+ } catch (error) {
8814
+ this.logger.error("getCategoryProducts failed", { handle, error });
8815
+ throw this.wrapError("getCategoryProducts", error);
8816
+ }
8817
+ }
8818
+ // ============================================
8819
+ // Collection Operations (alias categories)
8820
+ // ============================================
8821
+ async getCollection(handle) {
8822
+ this.logger.debug("getCollection", { handle });
8823
+ try {
8824
+ if (/^\d+$/.test(handle)) {
8825
+ const raw = await this.client.getOne("productCategories", handle);
8826
+ return raw ? transformStelCategoryToCollection(raw) : void 0;
8827
+ }
8828
+ const rawCategories = await this.client.list("productCategories");
8829
+ for (const raw of rawCategories) {
8830
+ const catHandle = buildStelHandle(raw.slug, raw.name, raw.id);
8831
+ if (catHandle === handle) {
8832
+ return transformStelCategoryToCollection(raw);
8833
+ }
8834
+ }
8835
+ return void 0;
8836
+ } catch (error) {
8837
+ this.logger.error("getCollection failed", { handle, error });
8838
+ throw this.wrapError("getCollection", error);
8839
+ }
8840
+ }
8841
+ async getCollections(options) {
8842
+ this.logger.debug("getCollections", { options });
8843
+ try {
8844
+ const query = {};
8845
+ if (options?.limit) {
8846
+ query.limit = options.limit;
8847
+ }
8848
+ const rawCategories = await this.client.list("productCategories", query);
8849
+ let collections = rawCategories.filter((c) => !c.deleted).map(transformStelCategoryToCollection);
8850
+ if (options?.query) {
8851
+ const needle = options.query.toLowerCase();
8852
+ collections = collections.filter(
8853
+ (c) => c.title.toLowerCase().includes(needle) || c.handle.includes(needle)
8854
+ );
8855
+ }
8856
+ return collections;
8857
+ } catch (error) {
8858
+ this.logger.error("getCollections failed", { options, error });
8859
+ throw this.wrapError("getCollections", error);
8860
+ }
8861
+ }
8862
+ async getCollectionProducts(handle, options) {
8863
+ return this.getCategoryProducts(handle, options);
8864
+ }
8865
+ // ============================================
8866
+ // Inventory Operations
8867
+ // ============================================
8868
+ async getStockLocations(_params) {
8869
+ this.logger.debug("getStockLocations");
8870
+ try {
8871
+ const rawWarehouses = await this.client.list("warehouses");
8872
+ return rawWarehouses.filter((w) => !w.deleted).map(transformStelWarehouseToStockLocation);
8873
+ } catch (error) {
8874
+ this.logger.error("getStockLocations failed", { error });
8875
+ throw this.wrapError("getStockLocations", error);
8876
+ }
8877
+ }
8878
+ async checkInventoryLevels(variantId, _salesChannelId) {
8879
+ this.logger.debug("checkInventoryLevels", { variantId });
8880
+ try {
8881
+ const raw = await this.client.getOne("products", variantId);
8882
+ if (!raw?.["product-warehouses"]?.length) {
8883
+ return [];
8884
+ }
8885
+ return raw["product-warehouses"].map(transformStelProductWarehouseToInventoryLevel);
8886
+ } catch (error) {
8887
+ this.logger.error("checkInventoryLevels failed", { variantId, error });
8888
+ throw this.wrapError("checkInventoryLevels", error);
8889
+ }
8890
+ }
8891
+ validateCartStock(_cartId) {
8892
+ return this.notSupported("validateCartStock");
8893
+ }
8894
+ getFulfillmentOptions(_cartId, _salesChannelId) {
8895
+ return this.notSupported("getFulfillmentOptions");
8896
+ }
8897
+ // ============================================
8898
+ // Cart Operations (unsupported — STEL is ERP, not storefront)
8899
+ // ============================================
8900
+ createCart(_options) {
8901
+ return this.notSupported("createCart");
8902
+ }
8903
+ getCart(_cartId) {
8904
+ return this.notSupported("getCart");
8905
+ }
8906
+ addToCart(_cartId, _lines) {
8907
+ return this.notSupported("addToCart");
8908
+ }
8909
+ removeFromCart(_cartId, _lineIds) {
8910
+ return this.notSupported("removeFromCart");
8911
+ }
8912
+ updateCart(_cartId, _lines) {
8913
+ return this.notSupported("updateCart");
8914
+ }
8915
+ // ============================================
8916
+ // Checkout Operations (unsupported)
8917
+ // ============================================
8918
+ completeCheckout(_cartId) {
8919
+ return this.notSupported("completeCheckout");
8920
+ }
8921
+ getRegionCountries(_regionId) {
8922
+ return this.notSupported("getRegionCountries");
8923
+ }
8924
+ addShippingMethod(_cartId, _methodId) {
8925
+ return this.notSupported("addShippingMethod");
8926
+ }
8927
+ initiatePaymentSession(_cartId, _providerId) {
8928
+ return this.notSupported("initiatePaymentSession");
8929
+ }
8930
+ applyDiscountCode(_cartId, _code) {
8931
+ return this.notSupported("applyDiscountCode");
8932
+ }
8933
+ removeDiscountCode(_cartId, _code) {
8934
+ return this.notSupported("removeDiscountCode");
8935
+ }
8936
+ // ============================================
8937
+ // Payment Methods
8938
+ // ============================================
8939
+ async getPaymentMethods(_options) {
8940
+ this.logger.debug("getPaymentMethods");
8941
+ try {
8942
+ const rawOptions = await this.client.list("paymentOptions");
8943
+ return rawOptions.filter((o) => !o.deleted).map(transformStelPaymentOption);
8944
+ } catch (error) {
8945
+ this.logger.error("getPaymentMethods failed", { error });
8946
+ throw this.wrapError("getPaymentMethods", error);
8947
+ }
8948
+ }
8949
+ // ============================================
8950
+ // Shipping / Delivery Methods
8951
+ // ============================================
8952
+ async getShippingMethods(_cartId) {
8953
+ this.logger.debug("getShippingMethods (delivery options listing)");
8954
+ try {
8955
+ const rawOptions = await this.client.list("deliveryOptions");
8956
+ return rawOptions.filter((o) => !o.deleted).map((o) => transformStelDeliveryOption(o, this.currencyCode));
8957
+ } catch (error) {
8958
+ this.logger.error("getShippingMethods failed", { error });
8959
+ throw this.wrapError("getShippingMethods", error);
8960
+ }
8961
+ }
8962
+ // ============================================
8963
+ // Customer Operations (optional)
8964
+ // ============================================
8965
+ async getCustomer(customerId) {
8966
+ this.logger.debug("getCustomer", { customerId });
8967
+ try {
8968
+ const raw = await this.client.getOne("clients", customerId);
8969
+ return raw ? transformStelClient(raw) : void 0;
8970
+ } catch (error) {
8971
+ this.logger.error("getCustomer failed", { customerId, error });
8972
+ throw this.wrapError("getCustomer", error);
8973
+ }
8974
+ }
8975
+ async getCustomers(options) {
8976
+ this.logger.debug("getCustomers", { options });
8977
+ try {
8978
+ if (options?.customFetcher) {
8979
+ return options.customFetcher(options);
8980
+ }
8981
+ const query = {};
8982
+ if (options?.limit) {
8983
+ query.limit = options.limit;
8984
+ }
8985
+ if (options?.offset) {
8986
+ query.start = options.offset;
8987
+ }
8988
+ const rawClients = await this.client.list("clients", query);
8989
+ let customers = rawClients.filter((c) => !c.deleted).map(transformStelClient);
8990
+ if (options?.search) {
8991
+ const needle = options.search.toLowerCase();
8992
+ customers = customers.filter(
8993
+ (c) => c.email.toLowerCase().includes(needle) || (c.firstName ?? "").toLowerCase().includes(needle) || (c.lastName ?? "").toLowerCase().includes(needle)
8994
+ );
8995
+ }
8996
+ return customers;
8997
+ } catch (error) {
8998
+ this.logger.error("getCustomers failed", { options, error });
8999
+ throw this.wrapError("getCustomers", error);
9000
+ }
9001
+ }
9002
+ async updateCustomer(customerId, data) {
9003
+ this.logger.debug("updateCustomer", { customerId, data });
9004
+ try {
9005
+ const stelPayload = {};
9006
+ if (data.firstName || data.lastName) {
9007
+ stelPayload.name = [data.firstName, data.lastName].filter(Boolean).join(" ");
9008
+ }
9009
+ if (data.email) {
9010
+ stelPayload.email = data.email;
9011
+ }
9012
+ if (data.phone) {
9013
+ stelPayload.phone = data.phone;
9014
+ }
9015
+ const raw = await this.client.update("clients", customerId, stelPayload);
9016
+ return transformStelClient(raw);
9017
+ } catch (error) {
9018
+ this.logger.error("updateCustomer failed", { customerId, error });
9019
+ throw this.wrapError("updateCustomer", error);
9020
+ }
9021
+ }
9022
+ // ============================================
9023
+ // Order Operations (optional)
9024
+ // ============================================
9025
+ async getOrder(orderId) {
9026
+ this.logger.debug("getOrder", { orderId });
9027
+ try {
9028
+ const raw = await this.client.getOne("salesOrders", orderId);
9029
+ return raw ? transformStelSalesOrder(raw, this.currencyCode) : void 0;
9030
+ } catch (error) {
9031
+ this.logger.error("getOrder failed", { orderId, error });
9032
+ throw this.wrapError("getOrder", error);
9033
+ }
9034
+ }
9035
+ async getOrders(options) {
9036
+ this.logger.debug("getOrders", { options });
9037
+ try {
9038
+ if (options?.customFetcher) {
9039
+ return options.customFetcher(options);
9040
+ }
9041
+ const query = {};
9042
+ if (options?.limit) {
9043
+ query.limit = options.limit;
9044
+ }
9045
+ if (options?.offset) {
9046
+ query.start = options.offset;
9047
+ }
9048
+ if (options?.customerId) {
9049
+ query["client-id"] = options.customerId;
9050
+ }
9051
+ const rawOrders = await this.client.list("salesOrders", query);
9052
+ return rawOrders.filter((o) => !o.deleted).map((o) => transformStelSalesOrder(o, this.currencyCode));
9053
+ } catch (error) {
9054
+ this.logger.error("getOrders failed", { options, error });
9055
+ throw this.wrapError("getOrders", error);
9056
+ }
9057
+ }
9058
+ async getAdminOrders(options) {
9059
+ this.logger.debug("getAdminOrders", { options });
9060
+ try {
9061
+ const query = {};
9062
+ if (options?.limit) {
9063
+ query.limit = options.limit;
9064
+ }
9065
+ if (options?.offset) {
9066
+ query.start = options.offset;
9067
+ }
9068
+ const rawOrders = await this.client.list("salesOrders", query);
9069
+ let orders = rawOrders.filter((o) => !o.deleted).map((o) => transformStelSalesOrder(o, this.currencyCode));
9070
+ if (options?.search) {
9071
+ const needle = options.search.toLowerCase();
9072
+ orders = orders.filter(
9073
+ (o) => o.orderNumber.toLowerCase().includes(needle) || o.email.toLowerCase().includes(needle)
9074
+ );
9075
+ }
9076
+ if (options?.status) {
9077
+ const statuses = Array.isArray(options.status) ? options.status : [options.status];
9078
+ orders = orders.filter((o) => statuses.includes(o.status));
9079
+ }
9080
+ return { orders, count: orders.length };
9081
+ } catch (error) {
9082
+ this.logger.error("getAdminOrders failed", { options, error });
9083
+ throw this.wrapError("getAdminOrders", error);
9084
+ }
9085
+ }
9086
+ cancelOrder(_orderId) {
9087
+ return this.notSupported("cancelOrder");
9088
+ }
9089
+ createFulfillment(_orderId, _items) {
9090
+ return this.notSupported("createFulfillment");
9091
+ }
9092
+ createRefund(_orderId, _amount, _reason) {
9093
+ return this.notSupported("createRefund");
9094
+ }
9095
+ // ============================================
9096
+ // Storefront Context
9097
+ // ============================================
9098
+ async getStorefrontContext() {
9099
+ return {
9100
+ id: this.storefrontId,
9101
+ name: this.companyName,
9102
+ platformType: "stelorder",
9103
+ requiresProductScoping: false,
9104
+ currencyCode: this.currencyCode,
9105
+ metadata: {
9106
+ apiBaseUrl: this.client.apiBaseUrl,
9107
+ singleCompany: true,
9108
+ providerVersion: this.version
9109
+ }
9110
+ };
9111
+ }
9112
+ isStorefrontRequired() {
9113
+ return false;
9114
+ }
9115
+ // ============================================
9116
+ // Internal helpers
9117
+ // ============================================
9118
+ notSupported(operation) {
9119
+ return Promise.reject(
9120
+ new ProviderAPIError(
9121
+ `Stel Order does not support \`${operation}\`. STEL is an ERP adapter without cart/checkout/auth capabilities.`,
9122
+ "stelorder",
9123
+ 501
9124
+ )
9125
+ );
9126
+ }
9127
+ wrapError(operation, error) {
9128
+ if (error instanceof ProviderAPIError) {
9129
+ return error;
9130
+ }
9131
+ const message = error instanceof Error ? error.message : String(error);
9132
+ return new ProviderAPIError(
9133
+ `Stel Order \`${operation}\` failed: ${message}`,
9134
+ "stelorder",
9135
+ 500
9136
+ );
9137
+ }
9138
+ };
9139
+
8072
9140
  // src/providers/mock/mock.ts
8073
9141
  var FIXTURE_TIMESTAMP = "2026-01-01T00:00:00.000Z";
8074
9142
  var DEFAULT_SITE_URL = "https://mock.thorcommerce.local";
@@ -9088,6 +10156,8 @@ function createProvider(options) {
9088
10156
  return new MockProvider(config);
9089
10157
  case "medusa":
9090
10158
  return new MedusaProvider(config);
10159
+ case "stelorder":
10160
+ return new StelOrderProvider(config);
9091
10161
  case "shopify":
9092
10162
  return new ShopifyProvider(config);
9093
10163
  case "bigcommerce":
@@ -9132,8 +10202,10 @@ function isProviderType(provider, type) {
9132
10202
  ResourceNotFoundError,
9133
10203
  SHOPIFY_CAPABILITIES,
9134
10204
  SPREE_CAPABILITIES,
10205
+ STELORDER_CAPABILITIES,
9135
10206
  ShopifyProvider,
9136
10207
  SpreeProvider,
10208
+ StelOrderProvider,
9137
10209
  StorefrontConfigError,
9138
10210
  WOOCOMMERCE_CAPABILITIES,
9139
10211
  WooCommerceProvider,
@@ -9142,8 +10214,11 @@ function isProviderType(provider, type) {
9142
10214
  buildChannelScopeMetadata,
9143
10215
  calculateDistance,
9144
10216
  createBackendMetadataAdapter,
10217
+ createFetchWithRetry,
9145
10218
  createLogger,
9146
10219
  createProvider,
10220
+ extractErrorMessage,
10221
+ fetchWithRetry,
9147
10222
  filterByChannel,
9148
10223
  filterGlobalOnly,
9149
10224
  geocodeAddress,