@bacano/sdk 1.2.2 → 1.2.4

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/react.js CHANGED
@@ -1065,6 +1065,35 @@ var WEBSITE_GET_PRODUCT_CONTENT = (
1065
1065
  }
1066
1066
  `
1067
1067
  );
1068
+ var WEBSITE_GET_PRODUCT_CONTENT_BATCH = (
1069
+ /* GraphQL */
1070
+ `
1071
+ mutation WebsiteGetProductContentBatch(
1072
+ $websiteId: uuid!
1073
+ $productIds: [uuid!]!
1074
+ $locale: String
1075
+ ) {
1076
+ result: websiteGetProductContentBatch(
1077
+ website_id: $websiteId
1078
+ product_ids: $productIds
1079
+ locale: $locale
1080
+ ) {
1081
+ success
1082
+ errors
1083
+ blocks {
1084
+ id
1085
+ product_id
1086
+ locale
1087
+ content_json
1088
+ resolved_fields
1089
+ sort_order
1090
+ updated_at
1091
+ content_type { id key name kind }
1092
+ }
1093
+ }
1094
+ }
1095
+ `
1096
+ );
1068
1097
  var CHECK_AVAILABILITY = (
1069
1098
  /* GraphQL */
1070
1099
  `
@@ -1941,7 +1970,7 @@ var RECONCILE_PAYMENT_SESSION = (
1941
1970
  $orderId: uuid!
1942
1971
  $publicOrderToken: String!
1943
1972
  $paymentSessionId: uuid!
1944
- $gatewayTransactionId: String!
1973
+ $gatewayTransactionId: String
1945
1974
  ) {
1946
1975
  websiteReconcilePaymentSession(
1947
1976
  order_id: $orderId
@@ -5405,6 +5434,52 @@ function BacanoMarketingProvider({
5405
5434
  // libs/sdk/src/react/provider.tsx
5406
5435
  import { useEffect as useEffect3, useRef as useRef3, useState as useState3 } from "react";
5407
5436
 
5437
+ // libs/sdk/src/flows.ts
5438
+ function createFlowsClient(config) {
5439
+ const base = config.apiUrl.replace(/\/+$/, "") + "/api/v1/website/flows";
5440
+ async function request(path, body, binary = false) {
5441
+ const token = await config.getAccessToken?.();
5442
+ const response = await fetch(base + path, {
5443
+ method: body === void 0 ? "GET" : "POST",
5444
+ cache: "no-store",
5445
+ headers: {
5446
+ ...token ? { Authorization: `Bearer ${token}` } : {},
5447
+ ...body !== void 0 ? { "Content-Type": "application/json" } : {},
5448
+ ...config.websiteSlug ? { "x-bacano-website-slug": config.websiteSlug } : {}
5449
+ },
5450
+ ...body !== void 0 ? { body: JSON.stringify(body) } : {}
5451
+ });
5452
+ if (!response.ok) {
5453
+ const result = await response.json().catch(() => ({ error: "FLOW_REQUEST_FAILED" }));
5454
+ throw new WebsiteError(
5455
+ result.error ?? "FLOW_REQUEST_FAILED",
5456
+ result.error ?? "FLOW_REQUEST_FAILED"
5457
+ );
5458
+ }
5459
+ return binary ? await response.blob() : await response.json();
5460
+ }
5461
+ const stepPath = (caseId, stepId) => `/cases/${encodeURIComponent(caseId)}/steps/${encodeURIComponent(stepId)}`;
5462
+ return {
5463
+ /** Only the explicitly enabled local demo gateway accepts these credentials. */
5464
+ localDemoLogin: (email, password) => request("/local-session", { email, password }),
5465
+ logout: () => request("/logout", {}),
5466
+ listCases: () => request("/cases"),
5467
+ getJourney: (caseId) => request(`/cases/${encodeURIComponent(caseId)}`),
5468
+ getContent: (caseId, stepId) => request(stepPath(caseId, stepId) + "/content"),
5469
+ getForm: (caseId, stepId) => request(stepPath(caseId, stepId) + "/form"),
5470
+ getResponse: (caseId, stepId) => request(stepPath(caseId, stepId) + "/response"),
5471
+ getFile: (caseId, stepId, fileId) => request(
5472
+ stepPath(caseId, stepId) + `/files/${encodeURIComponent(fileId)}`,
5473
+ void 0,
5474
+ true
5475
+ ),
5476
+ act: (caseId, command) => request(
5477
+ `/cases/${encodeURIComponent(caseId)}/actions`,
5478
+ command
5479
+ )
5480
+ };
5481
+ }
5482
+
5408
5483
  // libs/sdk/src/modules/auth.ts
5409
5484
  function createAuthHeaders(accessToken) {
5410
5485
  return accessToken ? { Authorization: `Bearer ${accessToken}` } : {};
@@ -6715,6 +6790,33 @@ function createContentModule(graphqlUrl, getHeaders, getContext, storageUrl) {
6715
6790
  return (data.result.blocks ?? []).map(
6716
6791
  (block) => mapProductContentBlock(block, storageUrl)
6717
6792
  );
6793
+ },
6794
+ async getForProducts(productIds, opts) {
6795
+ const uniqueIds = [...new Set(productIds.map((id) => id.toLowerCase()))];
6796
+ const blocksByProduct = Object.fromEntries(uniqueIds.map((id) => [id, []]));
6797
+ if (uniqueIds.length === 0) return blocksByProduct;
6798
+ const ctx = getContext();
6799
+ for (let start = 0; start < uniqueIds.length; start += 50) {
6800
+ const batch = uniqueIds.slice(start, start + 50);
6801
+ const data = await executeGraphQL(
6802
+ graphqlUrl,
6803
+ WEBSITE_GET_PRODUCT_CONTENT_BATCH,
6804
+ {
6805
+ websiteId: ctx.websiteId,
6806
+ productIds: batch,
6807
+ locale: opts?.locale ?? DEFAULT_LOCALE
6808
+ },
6809
+ getHeaders
6810
+ );
6811
+ if (!data.result?.success) continue;
6812
+ for (const block of data.result.blocks ?? []) {
6813
+ const id = block.product_id.toLowerCase();
6814
+ if (Object.prototype.hasOwnProperty.call(blocksByProduct, id)) {
6815
+ blocksByProduct[id].push(mapProductContentBlock(block, storageUrl));
6816
+ }
6817
+ }
6818
+ }
6819
+ return blocksByProduct;
6718
6820
  }
6719
6821
  };
6720
6822
  }
@@ -7429,6 +7531,7 @@ function createBacanoClient(config) {
7429
7531
  await initialization;
7430
7532
  },
7431
7533
  getContext,
7534
+ flows: createFlowsClient(config),
7432
7535
  auth: {
7433
7536
  async getAccessToken() {
7434
7537
  return config.getAccessToken ? await config.getAccessToken() : null;
@@ -7461,7 +7564,8 @@ function createBacanoClient(config) {
7461
7564
  getByKey: contentModule.getByKey.bind(contentModule),
7462
7565
  getByCategory: contentModule.getByCategory.bind(contentModule),
7463
7566
  getByTag: contentModule.getByTag.bind(contentModule),
7464
- getForProduct: contentModule.getForProduct.bind(contentModule)
7567
+ getForProduct: contentModule.getForProduct.bind(contentModule),
7568
+ getForProducts: contentModule.getForProducts.bind(contentModule)
7465
7569
  },
7466
7570
  forms: {
7467
7571
  getDefinition: formsModule.getDefinition.bind(formsModule),
@@ -52,6 +52,8 @@ aplicar obligatoriamente `STOREFRONT_CONTENT_LOCATOR.md`; añadir
52
52
  `AUTHENTICATION.md`, `STOREFRONT_LEADS.md`, `STOREFRONT_CLARITY.md` y
53
53
  otros contratos únicamente cuando esas capacidades existan. Leer
54
54
  `STOREFRONT_CONSTRUCTION.md` cuando el website permita ocultarse temporalmente.
55
+ Si la tienda acepta pagos, leer obligatoriamente `STOREFRONT_PAYMENTS.md` antes
56
+ de implementar, depurar o auditar checkout, retorno, reintentos o webhooks.
55
57
  Si existen formularios administrados desde Bacano, leer obligatoriamente
56
58
  `STOREFRONT_FORMS.md` y
57
59
  [references/forms.md](references/forms.md) antes de auditarlos o modificarlos.
@@ -54,6 +54,8 @@ Aplicar además de los controles comunes.
54
54
 
55
55
  ## Pagos y pedidos
56
56
 
57
+ - Leer y aplicar `STOREFRONT_PAYMENTS.md`; no reconstruir en la tienda URLs,
58
+ credenciales ni payloads privados de Wompi, Mercado Pago o Addi.
57
59
  - Ejecutar al menos un happy path real o sandbox por cada método crítico
58
60
  publicado. Probar pago inmediato, transferencia, Wompi y contraentrega solo
59
61
  si están activos; los estados alternos de cada proveedor quedan en su matriz
@@ -13,6 +13,7 @@ export declare const WEBSITE_GET_PRODUCT_SPECIFICATIONS = "\n mutation WebsiteG
13
13
  export declare const GET_BRANDS = "\n query GetBrands($companyId: uuid!, $chainId: uuid!) {\n brands(\n where: {\n company_id: { _eq: $companyId }\n products: {\n chain_products: {\n chain_id: { _eq: $chainId }\n is_enabled: { _eq: true }\n status: { _eq: active }\n }\n }\n }\n order_by: { name: asc }\n ) {\n id\n name\n }\n }\n";
14
14
  export declare const WEBSITE_GET_CONTENT = "\n mutation WebsiteGetContent(\n $websiteId: uuid!\n $key: String\n $categoryKey: String\n $tag: String\n $locale: String\n ) {\n result: websiteGetContent(\n website_id: $websiteId\n key: $key\n category_key: $categoryKey\n tag: $tag\n locale: $locale\n ) {\n success\n errors\n entries {\n \n id\n key\n category_key\n name\n locale\n status\n tags\n content_json\n resolved_fields\n published_at\n updated_at\n content_type {\n id\n key\n name\n kind\n }\n\n }\n }\n }\n";
15
15
  export declare const WEBSITE_GET_PRODUCT_CONTENT = "\n mutation WebsiteGetProductContent(\n $websiteId: uuid!\n $productId: uuid!\n $locale: String\n ) {\n result: websiteGetProductContent(\n website_id: $websiteId\n product_id: $productId\n locale: $locale\n ) {\n success\n errors\n blocks {\n id\n product_id\n locale\n content_json\n resolved_fields\n sort_order\n updated_at\n content_type {\n id\n key\n name\n kind\n }\n }\n }\n }\n";
16
+ export declare const WEBSITE_GET_PRODUCT_CONTENT_BATCH = "\n mutation WebsiteGetProductContentBatch(\n $websiteId: uuid!\n $productIds: [uuid!]!\n $locale: String\n ) {\n result: websiteGetProductContentBatch(\n website_id: $websiteId\n product_ids: $productIds\n locale: $locale\n ) {\n success\n errors\n blocks {\n id\n product_id\n locale\n content_json\n resolved_fields\n sort_order\n updated_at\n content_type { id key name kind }\n }\n }\n }\n";
16
17
  export declare const CHECK_AVAILABILITY = "\n query CheckAvailability(\n $variantIds: [uuid!]!\n $chainId: uuid!\n $websiteId: uuid\n ) {\n websiteProductAvailability(\n product_variant_ids: $variantIds\n chain_id: $chainId\n website_id: $websiteId\n ) {\n product_variant_id\n in_stock\n label\n max_purchasable_quantity\n }\n }\n";
17
18
  export declare const GET_PRODUCT_LIVE_STATE = "\n query GetProductLiveState(\n $variantIds: [uuid!]!\n $companyId: uuid!\n $chainId: uuid!\n $websiteId: uuid!\n ) {\n product_variants(\n where: {\n id: { _in: $variantIds }\n is_disabled: { _eq: false }\n product: {\n company_id: { _eq: $companyId }\n product_website_publications: {\n website_id: { _eq: $websiteId }\n is_visible: { _eq: true }\n }\n chain_products: {\n chain_id: { _eq: $chainId }\n is_enabled: { _eq: true }\n status: { _eq: active }\n }\n }\n }\n ) {\n id\n product_variant_prices(\n where: {\n price_type: { _in: [CLIENT, SALE, WHOLESALE, WHOLESALE_2] }\n _or: [\n { chain_id: { _eq: $chainId } }\n { chain_id: { _is_null: true } }\n ]\n }\n ) {\n id\n price\n price_type\n chain_id\n }\n }\n websiteProductAvailability(\n product_variant_ids: $variantIds\n chain_id: $chainId\n website_id: $websiteId\n ) {\n product_variant_id\n in_stock\n label\n max_purchasable_quantity\n }\n }\n";
18
19
  export declare const CREATE_CART = "\n mutation CreateCart(\n $websiteId: uuid!\n $cartToken: String\n $contact: WebsiteGuestContactInput\n $fulfillmentFamily: String\n ) {\n websiteCreateCart(\n website_id: $websiteId\n cart_token: $cartToken\n contact: $contact\n fulfillment_family: $fulfillmentFamily\n ) {\n success\n order_id\n cart_token\n cart {\n id\n status\n discount\n tax\n total_without_tax\n total_with_tax\n total_with_discount\n created_at\n updated_at\n volume_pricing {\n enabled\n eligibleQuantity\n appliedPriceType\n appliedMinQuantity\n nextPriceType\n nextMinQuantity\n remainingQuantity\n totalSavings\n }\n items {\n id\n product_variant_id\n quantity\n unit_price\n line_total\n base_unit_price\n unit_savings\n line_savings\n volume_pricing_eligible\n resolved_price_type\n volume_pricing_min_quantity\n product_variant {\n id\n sku\n product {\n id\n name\n }\n prices {\n id\n price\n price_type\n chain_id\n }\n }\n }\n }\n errors\n }\n }\n";
@@ -33,7 +34,7 @@ export declare const VALIDATE_COUPON = "\n mutation ValidateCoupon(\n $order
33
34
  export declare const APPLY_COUPON = "\n mutation ApplyCoupon($orderId: uuid!, $cartToken: String!, $code: String!) {\n websiteApplyCoupon(\n order_id: $orderId\n cart_token: $cartToken\n code: $code\n ) {\n success\n order_id\n coupon_id\n code\n name\n coupon_type\n discount_amount\n eligible_subtotal\n message\n cart {\n id\n status\n discount\n total_without_tax\n tax\n total_with_tax\n total_with_discount\n created_at\n updated_at\n items {\n id\n product_variant_id\n quantity\n product_variant {\n id\n sku\n product {\n id\n name\n }\n prices {\n id\n price\n price_type\n chain_id\n }\n }\n }\n }\n errors\n }\n }\n";
34
35
  export declare const REMOVE_COUPON = "\n mutation RemoveCoupon(\n $orderId: uuid!\n $cartToken: String!\n $couponId: uuid!\n ) {\n websiteRemoveCoupon(\n order_id: $orderId\n cart_token: $cartToken\n coupon_id: $couponId\n ) {\n success\n order_id\n coupon_id\n code\n name\n coupon_type\n discount_amount\n eligible_subtotal\n message\n cart {\n id\n status\n discount\n total_without_tax\n tax\n total_with_tax\n total_with_discount\n created_at\n updated_at\n items {\n id\n product_variant_id\n quantity\n product_variant {\n id\n sku\n product {\n id\n name\n }\n prices {\n id\n price\n price_type\n chain_id\n }\n }\n }\n }\n errors\n }\n }\n";
35
36
  export declare const CREATE_PAYMENT_SESSION = "\n mutation CreatePaymentSession(\n $orderId: uuid!\n $cartToken: String\n $publicOrderToken: String\n $paymentMethodId: uuid!\n $returnUrl: String!\n ) {\n websiteCreatePaymentSession(\n order_id: $orderId\n cart_token: $cartToken\n public_order_token: $publicOrderToken\n payment_method_id: $paymentMethodId\n return_url: $returnUrl\n ) {\n success\n order_id\n payment_method_id\n payment_session_id\n gateway_code\n integration_mode\n status\n redirect_url\n public_payload\n errors\n }\n }\n";
36
- export declare const RECONCILE_PAYMENT_SESSION = "\n mutation ReconcilePaymentSession(\n $orderId: uuid!\n $publicOrderToken: String!\n $paymentSessionId: uuid!\n $gatewayTransactionId: String!\n ) {\n websiteReconcilePaymentSession(\n order_id: $orderId\n public_order_token: $publicOrderToken\n payment_session_id: $paymentSessionId\n gateway_transaction_id: $gatewayTransactionId\n ) {\n success\n order_id\n payment_method_id\n payment_session_id\n gateway_code\n integration_mode\n status\n redirect_url\n public_payload\n errors\n }\n }\n";
37
+ export declare const RECONCILE_PAYMENT_SESSION = "\n mutation ReconcilePaymentSession(\n $orderId: uuid!\n $publicOrderToken: String!\n $paymentSessionId: uuid!\n $gatewayTransactionId: String\n ) {\n websiteReconcilePaymentSession(\n order_id: $orderId\n public_order_token: $publicOrderToken\n payment_session_id: $paymentSessionId\n gateway_transaction_id: $gatewayTransactionId\n ) {\n success\n order_id\n payment_method_id\n payment_session_id\n gateway_code\n integration_mode\n status\n redirect_url\n public_payload\n errors\n }\n }\n";
37
38
  export declare const GET_ORDERS = "\n query GetOrders($limit: Int = 20, $offset: Int = 0) {\n orders(\n where: { order_number: { _is_null: false } }\n order_by: { created_at: desc }\n limit: $limit\n offset: $offset\n ) {\n id\n order_number\n status\n fulfillment_family\n discount\n tax\n total_without_tax\n total_with_tax\n total_with_discount\n created_at\n updated_at\n order_product_variants {\n id\n product_variant_id\n quantity\n product_variant {\n sku\n product {\n id\n name\n }\n }\n }\n }\n }\n";
38
39
  export declare const GET_ORDER_BY_PK = "\n query GetOrderByPk($orderId: uuid!) {\n orders(where: { id: { _eq: $orderId } }) {\n id\n order_number\n status\n fulfillment_family\n discount\n tax\n total_without_tax\n total_with_tax\n total_with_discount\n created_at\n updated_at\n order_product_variants {\n id\n product_variant_id\n quantity\n product_variant {\n sku\n product {\n id\n name\n }\n }\n }\n }\n }\n";
39
40
  export declare const GET_PUBLIC_ORDER = "\n mutation GetPublicOrder($websiteId: uuid!, $orderId: uuid!, $token: String!) {\n websiteGetPublicOrder(\n website_id: $websiteId\n order_id: $orderId\n token: $token\n ) {\n success\n order {\n order_id\n order_number\n status\n payment_status\n fulfillment_family\n delivery {\n fulfillment_family\n shipping {\n label\n amount\n method_type\n collection_mode\n total_policy\n address\n }\n pickup {\n label\n }\n }\n payment {\n mode\n label\n method {\n id\n label\n payment_method_type\n gateway_code\n requires_payment_session\n }\n initial_payment {\n amount\n payment_method_id\n method_label\n payment_method_type\n gateway_code\n requires_payment_session\n }\n requires_payment_session\n next_action\n session {\n id\n gateway_code\n integration_mode\n status\n reference\n amount\n currency\n gateway_transaction_id\n error_message\n expires_at\n created_at\n updated_at\n }\n }\n totals {\n subtotal\n tax\n discount\n total\n total_with_discount\n }\n items {\n id\n product_variant_id\n sku\n name\n image_file_id\n quantity\n unit_price\n line_total\n }\n next_steps\n created_at\n updated_at\n }\n errors\n }\n }\n";
package/types.d.ts CHANGED
@@ -151,7 +151,7 @@ export interface WebsiteCampaignCaptureResult {
151
151
  }
152
152
  export type WebsiteFormAction = "STORE_RESPONSE" | "CAPTURE_LEAD";
153
153
  export type WebsiteFormStatus = "ACTIVE" | "PAUSED";
154
- export type WebsiteFormFieldType = "text" | "textarea" | "email" | "phone" | "number" | "date" | "select" | "radio" | "multi_select" | "checkbox";
154
+ export type WebsiteFormFieldType = "text" | "textarea" | "email" | "phone" | "number" | "scale" | "date" | "select" | "radio" | "multi_select" | "checkbox";
155
155
  export interface WebsiteFormOption {
156
156
  value: string;
157
157
  label: string;
@@ -164,10 +164,23 @@ export type WebsiteFormOptionSource = {
164
164
  listKey: string;
165
165
  };
166
166
  export interface WebsiteFormField {
167
+ /** A single-choice question may reveal one branch, recursively. */
168
+ branches?: Array<{
169
+ value: string;
170
+ fields: WebsiteFormField[];
171
+ }>;
167
172
  key: string;
168
173
  label: string;
169
174
  type: WebsiteFormFieldType;
170
175
  required: boolean;
176
+ /** Discrete integer scale; submitted as a string, stored as a number. */
177
+ scale?: {
178
+ min: number;
179
+ max: number;
180
+ display: "numbers" | "stars";
181
+ minLabel?: string;
182
+ maxLabel?: string;
183
+ };
171
184
  placeholder?: string | null;
172
185
  helpText?: string | null;
173
186
  optionSource?: WebsiteFormOptionSource | null;