@bacano/sdk 1.0.0 → 1.1.0

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 (68) hide show
  1. package/README.md +342 -7
  2. package/STOREFRONT_CLARITY.md +140 -0
  3. package/STOREFRONT_CONSTRUCTION.md +92 -0
  4. package/STOREFRONT_LEADS.md +130 -0
  5. package/STOREFRONT_LEGAL.md +66 -0
  6. package/STOREFRONT_MARKETING.md +286 -0
  7. package/STOREFRONT_PERFORMANCE.md +265 -0
  8. package/STOREFRONT_PREVIEW.md +474 -0
  9. package/client.d.ts +7 -1
  10. package/errors.d.ts +9 -1
  11. package/graphql.cjs +63 -0
  12. package/graphql.d.ts +2 -2
  13. package/graphql.js +63 -0
  14. package/index.cjs +1542 -192
  15. package/index.d.ts +8 -6
  16. package/index.js +1542 -192
  17. package/marketing/attribution.d.ts +51 -0
  18. package/marketing/clarity.d.ts +3 -0
  19. package/marketing/domain.d.ts +1 -0
  20. package/marketing/ga4.d.ts +2 -0
  21. package/marketing/index.d.ts +5 -0
  22. package/marketing/runtime.d.ts +2 -0
  23. package/marketing/sanitize.d.ts +2 -0
  24. package/marketing/types.d.ts +109 -0
  25. package/media.d.ts +45 -2
  26. package/modules/auth.d.ts +3 -2
  27. package/modules/availability.d.ts +2 -2
  28. package/modules/cart-session.d.ts +2 -2
  29. package/modules/cart.d.ts +3 -3
  30. package/modules/catalog.d.ts +15 -3
  31. package/modules/content.d.ts +2 -2
  32. package/modules/marketing.d.ts +5 -0
  33. package/modules/orders.d.ts +2 -2
  34. package/modules/profile.d.ts +1 -1
  35. package/modules/static-catalog.d.ts +13 -0
  36. package/modules/website.d.ts +7 -1
  37. package/package.json +14 -3
  38. package/react/context-registry.d.ts +9 -0
  39. package/react/context.d.ts +1 -1
  40. package/react/hooks.d.ts +23 -2
  41. package/react/marketing-context.d.ts +3 -0
  42. package/react/marketing-provider.d.ts +10 -0
  43. package/react/preview/cache.d.ts +23 -0
  44. package/react/preview/context.d.ts +5 -0
  45. package/react/preview/navigation.d.ts +9 -0
  46. package/react/preview/provider.d.ts +3 -0
  47. package/react/preview/shell.d.ts +3 -0
  48. package/react/preview/toolbar.d.ts +3 -0
  49. package/react/preview/types.d.ts +60 -0
  50. package/react/preview.cjs +742 -0
  51. package/react/preview.d.ts +14 -0
  52. package/react/preview.js +730 -0
  53. package/react/website-gate.d.ts +22 -0
  54. package/react.cjs +3432 -1780
  55. package/react.d.ts +8 -4
  56. package/react.js +3428 -1772
  57. package/skills/bacano-web/SKILL.md +109 -0
  58. package/skills/bacano-web/agents/openai.yaml +4 -0
  59. package/skills/bacano-web/references/common.md +91 -0
  60. package/skills/bacano-web/references/informational.md +39 -0
  61. package/skills/bacano-web/references/report.md +52 -0
  62. package/skills/bacano-web/references/storefront.md +116 -0
  63. package/skills/bacano-web/scripts/audit-http.mjs +247 -0
  64. package/skills/bacano-web/scripts/cli.mjs +222 -0
  65. package/skills/bacano-web/scripts/postinstall.mjs +8 -0
  66. package/transport/documents.d.ts +8 -6
  67. package/transport/graphql.d.ts +13 -1
  68. package/types.d.ts +202 -0
@@ -0,0 +1,474 @@
1
+ # Bacano Storefront Content Preview
2
+
3
+ Official guide for `@bacano/sdk/react/preview`, available since SDK `1.0.5`.
4
+
5
+ ## Problem solved
6
+
7
+ Static storefronts should keep their public catalog and editorial pages frozen
8
+ at build time for SEO, speed, reliability, and predictable hosting costs. That
9
+ also means a published Content change is not visible on the public page until
10
+ the storefront is rebuilt and deployed.
11
+
12
+ The preview entrypoint provides a separate client-side route that reads the
13
+ current **published** Bacano Content on demand and renders it with the
14
+ storefront's own production components:
15
+
16
+ ```text
17
+ Public route: Bacano Content -> Next build -> static HTML
18
+ Preview route: Browser -> @bacano/sdk -> current published Content
19
+ ```
20
+
21
+ Preview V1 is not a draft bypass and is not a realtime subscription. An editor
22
+ publishes the entry and then opens or refreshes the preview without rebuilding
23
+ the storefront.
24
+
25
+ ## Architectural contract
26
+
27
+ ### Bacano SDK owns
28
+
29
+ - Loading, ready, and safe error states.
30
+ - Per-route in-memory cache and simultaneous-request deduplication.
31
+ - Protection against stale responses after navigation or unmount.
32
+ - Forced refresh.
33
+ - Expanded state and four toolbar positions.
34
+ - `sessionStorage` persistence isolated by website slug.
35
+ - The official responsive and accessible toolbar.
36
+ - Neutral route normalization and internal-link interception.
37
+ - A preview-mode signal.
38
+ - A marketing no-op boundary inside the preview tree.
39
+ - SSR-safe module evaluation.
40
+
41
+ ### The storefront owns
42
+
43
+ - The single preview route, for example `/vista-previa/`.
44
+ - The route map and routes that are safe to preview.
45
+ - The loader that combines Content keys for each route.
46
+ - Mapping Bacano Content to storefront view models.
47
+ - Rendering with the same visual components used by production.
48
+ - Translating preview navigation to its router or query-string convention.
49
+ - `noindex` metadata and sitemap exclusion.
50
+ - Hiding or disabling popups, automatic chat, capture banners, cart drawers,
51
+ checkout links, and other non-editorial features outside the preview tree.
52
+
53
+ The SDK does not know whether `/` needs one Content key or six, and it does not
54
+ render Home, About, Blog, Product, Catalog, or Checkout pages.
55
+
56
+ ## Packaging
57
+
58
+ Import preview only from its dedicated entrypoint:
59
+
60
+ ```tsx
61
+ import {
62
+ BacanoPreviewShell,
63
+ interceptPreviewLink,
64
+ type PreviewRouteLoader,
65
+ } from "@bacano/sdk/react/preview";
66
+ ```
67
+
68
+ It is a separate ESM/CJS entrypoint and is not re-exported by
69
+ `@bacano/sdk/react`. It has no Next.js or Tailwind dependency. The official
70
+ toolbar carries self-contained styles and does not require a stylesheet import.
71
+ Both React entrypoints share the same Bacano client and marketing contexts, so
72
+ preview must remain under the storefront's single `BacanoProvider`.
73
+
74
+ React `>=18` remains the only peer dependency.
75
+
76
+ ## Required provider hierarchy
77
+
78
+ Mount exactly one `BacanoProvider` for the storefront, independently of whether
79
+ buyer accounts are enabled:
80
+
81
+ ```tsx
82
+ import { BacanoProvider } from "@bacano/sdk/react";
83
+
84
+ export function StorefrontProviders({
85
+ children,
86
+ }: {
87
+ children: React.ReactNode;
88
+ }) {
89
+ return (
90
+ <BacanoProvider
91
+ config={{
92
+ apiUrl: process.env.NEXT_PUBLIC_BACANO_API_URL!,
93
+ websiteSlug: process.env.NEXT_PUBLIC_BACANO_WEBSITE_SLUG!,
94
+ }}
95
+ >
96
+ {children}
97
+ </BacanoProvider>
98
+ );
99
+ }
100
+ ```
101
+
102
+ `BacanoPreviewProvider` consumes this existing client. Do not create another
103
+ client inside the preview loader and do not mount a second `BacanoProvider`.
104
+
105
+ If Clerk supplies buyer tokens, keep its token callback in this same provider.
106
+ The presence or absence of Clerk must not determine whether the public Bacano
107
+ client exists.
108
+
109
+ ## Public API
110
+
111
+ ### `BacanoPreviewProvider<TDocument>`
112
+
113
+ Required props:
114
+
115
+ | Prop | Purpose |
116
+ | ------------- | ------------------------------------------------------- |
117
+ | `websiteSlug` | Isolates persisted toolbar state between stores. |
118
+ | `route` | Current controlled storefront route. |
119
+ | `loadRoute` | Storefront loader receiving `{ route, force, client }`. |
120
+ | `navigate` | Updates the preview URL using the storefront router. |
121
+
122
+ Optional props:
123
+
124
+ | Prop | Default | Purpose |
125
+ | -------------------- | ----------------------- | -------------------------------------------- |
126
+ | `normalizeRoute` | `normalizePreviewRoute` | Canonicalizes route input. |
127
+ | `isPreviewableRoute` | all normalized routes | Rejects private or transactional routes. |
128
+ | `initialExpanded` | `true` | Initial toolbar visibility before hydration. |
129
+ | `initialPosition` | `top-right` | Initial toolbar corner. |
130
+ | `cacheMaxEntries` | `50` | Maximum cached route documents per provider. |
131
+
132
+ Loader contract:
133
+
134
+ ```ts
135
+ type PreviewRouteLoader<TDocument> = (context: {
136
+ route: string;
137
+ force: boolean;
138
+ client: BacanoClient;
139
+ }) => Promise<TDocument>;
140
+ ```
141
+
142
+ A `null` or `undefined` result becomes the safe `EMPTY_DOCUMENT` state. Loader
143
+ errors are not exposed verbatim in the public UI.
144
+
145
+ ### `useBacanoPreview<TDocument>()`
146
+
147
+ Returns:
148
+
149
+ ```ts
150
+ {
151
+ isPreview: true;
152
+ websiteSlug: string;
153
+ route: string;
154
+ status: "idle" | "loading" | "ready" | "error";
155
+ document: TDocument | null;
156
+ error: { code: string; message: string } | null;
157
+ refreshedAt: Date | null;
158
+ isExpanded: boolean;
159
+ position: "top-left" | "top-right" | "bottom-left" | "bottom-right";
160
+ refresh(): Promise<void>;
161
+ navigate(route: string): void;
162
+ setExpanded(expanded: boolean): void;
163
+ setPosition(position): void;
164
+ }
165
+ ```
166
+
167
+ ### `BacanoPreviewToolbar`
168
+
169
+ The optional tokens are deliberately limited:
170
+
171
+ ```tsx
172
+ <BacanoPreviewToolbar
173
+ websiteName="My store"
174
+ logo={<img src="/logo.svg" alt="" />}
175
+ primaryColor="#172033"
176
+ accentColor="#2f80ed"
177
+ backgroundColor="#ffffff"
178
+ locale="es-CO"
179
+ zIndex={2147483000}
180
+ suggestedRoutes={["/", "/about", "/blog"]}
181
+ />
182
+ ```
183
+
184
+ The toolbar provides route input, refresh, collapse/expand, last refresh time,
185
+ safe status messages, keyboard focus, `aria-live`, responsive layout, reduced
186
+ motion support, and four positions.
187
+
188
+ ### `BacanoPreviewShell<TDocument>`
189
+
190
+ Convenience composition of the provider and toolbar:
191
+
192
+ ```tsx
193
+ <BacanoPreviewShell {...providerProps} toolbar={toolbarProps}>
194
+ {(preview) => renderPreviewState(preview)}
195
+ </BacanoPreviewShell>
196
+ ```
197
+
198
+ Pass `toolbar={false}` only when the storefront supplies another accessible
199
+ control surface.
200
+
201
+ ## Minimal Next.js static-export example
202
+
203
+ The SDK contains no Next.js imports. This adapter belongs to the storefront.
204
+
205
+ ```tsx
206
+ // app/vista-previa/page.tsx
207
+ import type { Metadata } from "next";
208
+ import { Suspense } from "react";
209
+ import { PreviewClient } from "./PreviewClient";
210
+
211
+ export const metadata: Metadata = {
212
+ title: "Vista previa del sitio",
213
+ robots: { index: false, follow: false },
214
+ };
215
+
216
+ export default function PreviewPage() {
217
+ return (
218
+ <Suspense fallback={<p>Cargando vista previa...</p>}>
219
+ <PreviewClient />
220
+ </Suspense>
221
+ );
222
+ }
223
+ ```
224
+
225
+ ```tsx
226
+ // app/vista-previa/PreviewClient.tsx
227
+ "use client";
228
+
229
+ import { useSearchParams } from "next/navigation";
230
+ import {
231
+ BacanoPreviewShell,
232
+ interceptPreviewLink,
233
+ normalizePreviewRoute,
234
+ type PreviewRouteLoader,
235
+ } from "@bacano/sdk/react/preview";
236
+
237
+ type PreviewDocument =
238
+ | { kind: "home"; hero: unknown; story: unknown }
239
+ | { kind: "about"; content: unknown }
240
+ | { kind: "unsupported"; route: string };
241
+
242
+ const previewable = new Set(["/", "/about"]);
243
+
244
+ const loadRoute: PreviewRouteLoader<PreviewDocument> = async ({
245
+ route,
246
+ client,
247
+ }) => {
248
+ if (route === "/") {
249
+ const [hero, story] = await Promise.all([
250
+ client.content.getByKey("home-hero"),
251
+ client.content.getByKey("home-story"),
252
+ ]);
253
+ return { kind: "home", hero, story };
254
+ }
255
+
256
+ if (route === "/about") {
257
+ return {
258
+ kind: "about",
259
+ content: await client.content.getByKey("about"),
260
+ };
261
+ }
262
+
263
+ return { kind: "unsupported", route };
264
+ };
265
+
266
+ export function PreviewClient() {
267
+ const searchParams = useSearchParams();
268
+ const route = normalizePreviewRoute(searchParams.get("route"));
269
+
270
+ return (
271
+ <BacanoPreviewShell
272
+ websiteSlug={process.env.NEXT_PUBLIC_BACANO_WEBSITE_SLUG!}
273
+ route={route}
274
+ loadRoute={loadRoute}
275
+ isPreviewableRoute={(nextRoute) => previewable.has(nextRoute)}
276
+ navigate={(nextRoute) => {
277
+ window.location.assign(
278
+ `/vista-previa/?route=${encodeURIComponent(nextRoute)}`,
279
+ );
280
+ }}
281
+ toolbar={{
282
+ websiteName: "My store",
283
+ suggestedRoutes: Array.from(previewable),
284
+ }}
285
+ >
286
+ {(preview) => {
287
+ if (preview.status === "loading" && !preview.document) {
288
+ return <PreviewSkeleton />;
289
+ }
290
+ if (preview.status === "error" && !preview.document) {
291
+ return <PreviewError onRetry={preview.refresh} />;
292
+ }
293
+ if (!preview.document) return null;
294
+
295
+ return (
296
+ <div
297
+ onClickCapture={(event) =>
298
+ interceptPreviewLink(event, {
299
+ navigate: preview.navigate,
300
+ isPreviewableRoute: (nextRoute) => previewable.has(nextRoute),
301
+ })
302
+ }
303
+ >
304
+ <ProductionRenderer document={preview.document} />
305
+ </div>
306
+ );
307
+ }}
308
+ </BacanoPreviewShell>
309
+ );
310
+ }
311
+ ```
312
+
313
+ The example intentionally leaves `PreviewSkeleton`, `PreviewError`, and
314
+ `ProductionRenderer` to the storefront so the page retains its visual language.
315
+
316
+ ## Route map guidance
317
+
318
+ Keep a finite allowlist. Typical V1 routes include:
319
+
320
+ - Home.
321
+ - About and other editorial pages.
322
+ - Blog index and published articles.
323
+ - Content-driven catalog landing pages.
324
+ - Published legal pages.
325
+
326
+ Do not preview in V1:
327
+
328
+ - Checkout or payment response.
329
+ - Account creation, login, or private account pages.
330
+ - Private orders.
331
+ - Gateway sessions.
332
+ - Any route whose primary purpose is transactional.
333
+
334
+ Product pages can be added later if the storefront defines an explicit loader
335
+ and non-transactional renderer. The SDK does not enable them automatically.
336
+
337
+ ## Internal-link interception
338
+
339
+ `interceptPreviewLink()` only captures plain primary clicks on same-origin
340
+ links. It preserves:
341
+
342
+ - Ctrl/Cmd click.
343
+ - Shift and Alt click.
344
+ - External origins.
345
+ - `target="_blank"`.
346
+ - `download` links.
347
+ - Routes rejected by `isPreviewableRoute`.
348
+
349
+ The callback receives the normalized public route. The storefront decides how
350
+ to encode it into `/vista-previa/?route=...`.
351
+
352
+ ## Marketing and commercial UI isolation
353
+
354
+ `BacanoPreviewProvider` overrides `useMarketing()` with a synchronous no-op in
355
+ its subtree. This prevents GA4, Meta, and Clarity browser events from preview renderers,
356
+ even if the root storefront marketing runtime is active.
357
+
358
+ `useBacanoPreviewMode()` is also available to components placed inside the
359
+ preview boundary:
360
+
361
+ ```tsx
362
+ const isPreview = useBacanoPreviewMode();
363
+ if (isPreview) return null;
364
+ return <CommercialPopup />;
365
+ ```
366
+
367
+ Components rendered above or beside the preview provider cannot read a child
368
+ context. The storefront must therefore hide or disable root-level commercial
369
+ elements on its preview route, including:
370
+
371
+ - Marketing popups and lead banners.
372
+ - Automatic chat and WhatsApp launchers.
373
+ - Cart drawers and checkout calls to action.
374
+ - Independently mounted analytics providers.
375
+
376
+ When `BacanoMarketingProvider` is nested inside a preview-mode boundary, it also
377
+ recognizes the signal and remains a no-op.
378
+
379
+ Server-side conversion events remain protected by keeping all transactional
380
+ routes and actions outside preview. A browser preview flag is not an
381
+ authorization mechanism and must never be sent to bypass commercial rules.
382
+
383
+ ## Security and privacy
384
+
385
+ V1 calls only the existing public Content methods:
386
+
387
+ - `client.content.getByKey()`
388
+ - `client.content.getByCategory()`
389
+ - `client.content.getByTag()`
390
+
391
+ Those contracts return current published content. There is no `includeDrafts`,
392
+ GraphQL bypass, alternate endpoint, admin secret, or permission change.
393
+
394
+ The route remains publicly reachable, so it must show only information that is
395
+ already public. Keep `noindex`, exclude it from sitemap, and do not place tokens,
396
+ customer data, payment data, or secret identifiers in the preview query string.
397
+
398
+ A future draft preview requires a Bacano-signed session containing website,
399
+ user, scopes, allowed routes, expiration, revocation, and audit information.
400
+ Never implement drafts using `?includeDrafts=true`.
401
+
402
+ ## Static production guarantees
403
+
404
+ When the storefront follows this contract:
405
+
406
+ - Public pages keep their build-time Content snapshots.
407
+ - `output: "export"` remains valid.
408
+ - `generateStaticParams`, sitemap, and public metadata do not change.
409
+ - The preview entrypoint is imported only by its one route.
410
+ - Preview API errors affect only the preview route.
411
+ - A temporary Bacano outage while someone uses preview does not alter the
412
+ already deployed public storefront.
413
+
414
+ The build still depends on whatever Bacano data the public static pages request
415
+ at build time. Preview does not change or replace that build contract.
416
+
417
+ ## Validated reference implementation: Baby Rex
418
+
419
+ Baby Rex validated the official integration with `@bacano/sdk` `1.0.5` on
420
+ 2026-08-06. It uses one global `BacanoProvider`; `BacanoPreviewShell` consumes
421
+ that initialized client and the loader receives `{ route, force, client }`.
422
+
423
+ The validated static production build generated all `417/417` pages. TypeScript,
424
+ lint, unit tests, E2E, preview navigation, cache, refresh, toolbar behavior, and
425
+ the `idle -> loading -> ready` transition passed. No marketing event was emitted
426
+ inside preview.
427
+
428
+ The implementation removed these generic storefront responsibilities:
429
+
430
+ - Local `PreviewToolbar.tsx`.
431
+ - Local expanded/position/sessionStorage state.
432
+ - Local loading/error/refreshed-at controller state.
433
+ - Local request-promise cache and forced-refresh orchestration.
434
+ - Generic internal-link interception.
435
+ - Pathname-based marketing suppression inside preview renderers once the SDK
436
+ boundary covers them.
437
+
438
+ Baby Rex retained these storefront-specific responsibilities:
439
+
440
+ - `/vista-previa/page.tsx` and its `noindex` metadata.
441
+ - Sitemap exclusion.
442
+ - `PreviewDocument` union.
443
+ - Route allowlist and suggested routes.
444
+ - `loadPreviewDocument()` mappings for Home, About, Blog, legal pages, and
445
+ content-driven catalog sections.
446
+ - `PreviewDocumentView` and all production renderers.
447
+ - Storefront-specific skeleton, missing-content, and unsupported-route views.
448
+ - The Next.js adapter that writes `?ruta={encodedRoute}`.
449
+
450
+ Baby Rex is the implementation reference for integration shape, not a source to
451
+ copy blindly. Other storefronts keep their own route maps, Content keys,
452
+ mappers, and visual components.
453
+
454
+ ## Short checklist for agents
455
+
456
+ - [ ] Use `@bacano/sdk` `1.0.5` or newer.
457
+ - [ ] Mount exactly one global `BacanoProvider`.
458
+ - [ ] Place `BacanoPreviewShell` below that provider; never create a preview client.
459
+ - [ ] Load only published Content through the `client` supplied to `loadRoute`.
460
+ - [ ] Keep route allowlists, Content keys, mappers, and renderers in the storefront.
461
+ - [ ] Keep preview `noindex`, outside the sitemap, and free of transactional routes.
462
+ - [ ] Hide root-level commercial UI and verify zero marketing events in preview.
463
+ - [ ] Test idle, loading, ready, safe error, refresh, cache, and navigation states.
464
+ - [ ] Verify static public pages and their build output remain unchanged.
465
+ - [ ] Run typecheck, lint, unit tests, E2E, and the complete production build.
466
+
467
+ ## V1 limitations
468
+
469
+ - Published Content only.
470
+ - Manual refresh; no WebSocket, polling, or subscriptions.
471
+ - In-memory document cache lasts for the mounted provider session.
472
+ - Toolbar preferences use browser `sessionStorage`.
473
+ - The storefront owns all route-specific loaders and renderers.
474
+ - Transactional and private pages are intentionally excluded.
package/client.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { BacanoClientConfig, BacanoClientContext, Brand, Cart, CartItem, CatalogAttributeList, CatalogPageResult, CatalogCategoryList, CheckoutResult, CheckoutSubmission, ContentEntry, ProductContentBlock, CustomerAddress, CustomerProfile, CustomerProfileUpdate, GetAttributeListOptions, GetCatalogPageOptions, GetCategoryListOptions, GetContentOptions, GetOrdersOptions, GetProductFiltersOptions, GetProductSeoEntriesOptions, GetProductRecommendationsOptions, ProductRecommendationsResult, GetProductsOptions, GetSearchSuggestionsOptions, Order, Product, ProductAvailability, ProductCategory, ProductFilters, ProductSeoEntriesResult, PublicOrder, PublicOrderLookupInput, WaitForPublicOrderPaymentInput, SearchSuggestion, StartGuestCheckoutInput, WebsiteCheckoutAddress, WebsiteCheckoutItem, WebsiteCouponActionResult, WebsiteDeliveryOption, WebsiteFreeShippingProgress, WebsiteFulfillmentFamily, WebsiteGuestContact, WebsiteLocationOptions, WebsitePaymentMethod, WebsitePaymentOption, WebsitePaymentSessionResult, WebsiteShippingQuote, WebsiteShippingPolicy } from "./types";
1
+ import type { BacanoClientConfig, BacanoClientContext, Brand, Cart, CartItem, CatalogAttributeList, CatalogCategoryList, CatalogPageResult, CheckoutResult, CheckoutSubmission, ContentEntry, CustomerAddress, CustomerProfile, CustomerProfileUpdate, GetAttributeListOptions, GetCatalogPageOptions, GetCategoryListOptions, GetContentOptions, GetOrdersOptions, GetProductFiltersOptions, GetProductRecommendationsOptions, GetProductSeoEntriesOptions, GetProductsOptions, GetSearchSuggestionsOptions, GetStaticCatalogBootstrapOptions, GetStaticCatalogSnapshotOptions, Order, Product, ProductAvailability, ProductCategory, ProductContentBlock, ProductFilters, ProductRecommendationsResult, ProductSeoEntriesResult, ProductVariantLiveState, PublicOrder, PublicOrderLookupInput, SearchSuggestion, StartGuestCheckoutInput, StaticCatalogBootstrap, StaticCatalogSnapshot, WaitForPublicOrderPaymentInput, WebsiteCampaignCaptureInput, WebsiteCampaignCaptureResult, WebsiteCheckoutAddress, WebsiteCheckoutItem, WebsiteCouponActionResult, WebsiteDeliveryOption, WebsiteFreeShippingProgress, WebsiteFulfillmentFamily, WebsiteGuestContact, WebsiteLocationOptions, WebsitePaymentMethod, WebsitePaymentOption, WebsitePaymentSessionResult, WebsiteShippingPolicy, WebsiteShippingQuote } from "./types";
2
2
  export interface BacanoClient {
3
3
  /** Initialize the client and resolve its website context. */
4
4
  init(): Promise<void>;
@@ -12,8 +12,11 @@ export interface BacanoClient {
12
12
  };
13
13
  catalog: {
14
14
  getCatalogPage(opts: GetCatalogPageOptions): Promise<CatalogPageResult>;
15
+ getStaticCatalogSnapshot(opts: GetStaticCatalogSnapshotOptions): Promise<StaticCatalogSnapshot>;
16
+ getStaticCatalogBootstrap(opts: GetStaticCatalogBootstrapOptions): Promise<StaticCatalogBootstrap>;
15
17
  getProductSeoEntries(opts?: GetProductSeoEntriesOptions): Promise<ProductSeoEntriesResult>;
16
18
  getProductRecommendations(opts: GetProductRecommendationsOptions): Promise<ProductRecommendationsResult>;
19
+ getProductLiveState(productVariantIds: string[]): Promise<ProductVariantLiveState[]>;
17
20
  getProducts(opts?: GetProductsOptions): Promise<Product[]>;
18
21
  getProduct(productId: string): Promise<Product | null>;
19
22
  getProductBySlug(slug: string): Promise<Product | null>;
@@ -92,5 +95,8 @@ export interface BacanoClient {
92
95
  getAddresses(): Promise<CustomerAddress[]>;
93
96
  update(data: CustomerProfileUpdate): Promise<CustomerProfile>;
94
97
  };
98
+ marketing: {
99
+ captureLead(input: WebsiteCampaignCaptureInput): Promise<WebsiteCampaignCaptureResult>;
100
+ };
95
101
  }
96
102
  export declare function createBacanoClient(config: BacanoClientConfig): BacanoClient;
package/errors.d.ts CHANGED
@@ -1,6 +1,14 @@
1
1
  export declare class WebsiteError extends Error {
2
2
  readonly code: string;
3
- constructor(message: string, code?: string);
3
+ readonly status: number | null;
4
+ readonly retryAfterSeconds: number | null;
5
+ constructor(message: string, code?: string, options?: {
6
+ status?: number;
7
+ retryAfterSeconds?: number;
8
+ });
9
+ }
10
+ export declare class RateLimitError extends WebsiteError {
11
+ constructor(message: string, retryAfterSeconds: number);
4
12
  }
5
13
  export declare class NotInitializedError extends WebsiteError {
6
14
  constructor();
package/graphql.cjs CHANGED
@@ -888,6 +888,62 @@ var CHECK_AVAILABILITY = (
888
888
  product_variant_id
889
889
  in_stock
890
890
  label
891
+ max_purchasable_quantity
892
+ }
893
+ }
894
+ `
895
+ );
896
+ var GET_PRODUCT_LIVE_STATE = (
897
+ /* GraphQL */
898
+ `
899
+ query GetProductLiveState(
900
+ $variantIds: [uuid!]!
901
+ $companyId: uuid!
902
+ $chainId: uuid!
903
+ $websiteId: uuid!
904
+ ) {
905
+ product_variants(
906
+ where: {
907
+ id: { _in: $variantIds }
908
+ is_disabled: { _eq: false }
909
+ product: {
910
+ company_id: { _eq: $companyId }
911
+ product_website_publications: {
912
+ website_id: { _eq: $websiteId }
913
+ is_visible: { _eq: true }
914
+ }
915
+ chain_products: {
916
+ chain_id: { _eq: $chainId }
917
+ is_enabled: { _eq: true }
918
+ status: { _eq: active }
919
+ }
920
+ }
921
+ }
922
+ ) {
923
+ id
924
+ product_variant_prices(
925
+ where: {
926
+ price_type: { _in: [CLIENT, SALE, WHOLESALE, WHOLESALE_2] }
927
+ _or: [
928
+ { chain_id: { _eq: $chainId } }
929
+ { chain_id: { _is_null: true } }
930
+ ]
931
+ }
932
+ ) {
933
+ id
934
+ price
935
+ price_type
936
+ chain_id
937
+ }
938
+ }
939
+ websiteProductAvailability(
940
+ product_variant_ids: $variantIds
941
+ chain_id: $chainId
942
+ ) {
943
+ product_variant_id
944
+ in_stock
945
+ label
946
+ max_purchasable_quantity
891
947
  }
892
948
  }
893
949
  `
@@ -997,6 +1053,7 @@ var START_GUEST_CHECKOUT = (
997
1053
  $contact: WebsiteGuestContactInput!
998
1054
  $items: [WebsiteCheckoutItemInput!]!
999
1055
  $fulfillmentFamily: String
1056
+ $marketingAttribution: WebsiteMarketingAttributionInput
1000
1057
  ) {
1001
1058
  websiteStartGuestCheckout(
1002
1059
  website_id: $websiteId
@@ -1004,6 +1061,7 @@ var START_GUEST_CHECKOUT = (
1004
1061
  contact: $contact
1005
1062
  items: $items
1006
1063
  fulfillment_family: $fulfillmentFamily
1064
+ marketing_attribution: $marketingAttribution
1007
1065
  ) {
1008
1066
  success
1009
1067
  order_id
@@ -1161,6 +1219,8 @@ var CHECKOUT = (
1161
1219
  $paymentMethodId: uuid
1162
1220
  $buyerAccountOptIn: Boolean
1163
1221
  $initialPayment: WebsiteInitialPaymentInput
1222
+ $marketingAttribution: WebsiteMarketingAttributionInput
1223
+ $advertisingConsent: WebsiteAdvertisingConsentInput
1164
1224
  ) {
1165
1225
  websiteCheckout(
1166
1226
  order_id: $orderId
@@ -1173,6 +1233,8 @@ var CHECKOUT = (
1173
1233
  payment_method_id: $paymentMethodId
1174
1234
  buyer_account_opt_in: $buyerAccountOptIn
1175
1235
  initial_payment: $initialPayment
1236
+ marketing_attribution: $marketingAttribution
1237
+ advertising_consent: $advertisingConsent
1176
1238
  ) {
1177
1239
  success
1178
1240
  order_id
@@ -2028,6 +2090,7 @@ var documents = {
2028
2090
  WEBSITE_GET_PRODUCT_RECOMMENDATIONS,
2029
2091
  GET_BRANDS,
2030
2092
  CHECK_AVAILABILITY,
2093
+ GET_PRODUCT_LIVE_STATE,
2031
2094
  GET_PRODUCT_FILTERS,
2032
2095
  GET_SEARCH_SUGGESTIONS,
2033
2096
  WEBSITE_GET_CONTENT,
package/graphql.d.ts CHANGED
@@ -13,5 +13,5 @@
13
13
  * ```
14
14
  */
15
15
  export { createAuthHeaders } from "./modules/auth";
16
- export { APPLY_COUPON, CHECK_AVAILABILITY, CHECKOUT, CREATE_CART, CREATE_PAYMENT_SESSION, documents, GET_BRANDS, GET_CART, GET_CATALOG_ATTRIBUTE_LIST, GET_CATALOG_CATEGORY_LIST, GET_CATEGORIES, GET_CONTEXTUAL_CATALOG_ATTRIBUTE_LIST, GET_DELIVERY_OPTIONS, GET_FREE_SHIPPING_PROGRESS, GET_LOCATION_OPTIONS, GET_ORDER_BY_PK, GET_ORDERS, GET_PUBLIC_ORDER, GET_PAYMENT_METHODS, GET_PRODUCT_BY_PK, GET_PRODUCT_BY_SLUG, GET_PRODUCT_SEO_ENTRIES, GET_PRODUCTS, GET_PROFILE, GET_SHIPPING_POLICY, GET_SHIPPING_QUOTES, REMOVE_CART_ITEM, REMOVE_COUPON, RESOLVE_WEBSITE_BY_SLUG, SET_CART_ITEM, START_GUEST_CHECKOUT, UPDATE_PROFILE, VALIDATE_COUPON, WEBSITE_GET_CONTENT, } from "./transport/documents";
17
- export type { AccessTokenProvider, BacanoClientConfig, BacanoClientContext, Brand, Cart, CartItem, CatalogAttributeList, CatalogAttributeListFilters, CatalogAttributeListItem, CatalogAttributeListValue, CatalogCategoryList, CatalogCategoryListItem, CatalogCategoryListItemSourceType, CheckoutResult, CheckoutSubmission, ContentEntry, ContentJson, ContentMedia, ContentTypeSummary, CustomerProfile, CustomerProfileUpdate, GetAttributeListOptions, GetCategoryListOptions, GetContentOptions, GetOrdersOptions, GetProductSeoEntriesOptions, GetProductsOptions, Order, OrderItem, Product, ProductAttribute, ProductAvailability, ProductCategory, ProductMedia, ProductMediaKind, ProductPrice, ProductPriceType, ProductSeoEntriesResult, ProductSeoEntry, ProductSubcategory, ProductVariant, ProductVariantPricing, PublicOrder, PublicOrderDeliverySummary, PublicOrderItem, PublicOrderLookupInput, PublicOrderPaymentSummary, StartGuestCheckoutInput, VariantAttribute, WebsiteCheckoutAddress, WebsiteCheckoutItem, WebsiteCouponActionResult, WebsiteDeliveryOption, WebsiteDepartmentOption, WebsiteFreeShippingProgress, WebsiteFulfillmentFamily, WebsiteGuestContact, WebsiteLocationOptions, WebsiteMunicipalityOption, WebsitePaymentMethod, WebsitePaymentSessionResult, WebsitePickupInfo, WebsiteShippingQuote, WebsiteShippingPolicy, } from "./types";
16
+ export { APPLY_COUPON, CHECK_AVAILABILITY, CHECKOUT, CREATE_CART, CREATE_PAYMENT_SESSION, documents, GET_BRANDS, GET_CART, GET_CATALOG_ATTRIBUTE_LIST, GET_CATALOG_CATEGORY_LIST, GET_CATEGORIES, GET_CONTEXTUAL_CATALOG_ATTRIBUTE_LIST, GET_DELIVERY_OPTIONS, GET_FREE_SHIPPING_PROGRESS, GET_LOCATION_OPTIONS, GET_ORDER_BY_PK, GET_ORDERS, GET_PAYMENT_METHODS, GET_PRODUCT_BY_PK, GET_PRODUCT_BY_SLUG, GET_PRODUCT_SEO_ENTRIES, GET_PRODUCTS, GET_PROFILE, GET_PUBLIC_ORDER, GET_SHIPPING_POLICY, GET_SHIPPING_QUOTES, REMOVE_CART_ITEM, REMOVE_COUPON, RESOLVE_WEBSITE_BY_SLUG, SET_CART_ITEM, START_GUEST_CHECKOUT, UPDATE_PROFILE, VALIDATE_COUPON, WEBSITE_GET_CONTENT, } from "./transport/documents";
17
+ export type { AccessTokenProvider, BacanoClientConfig, BacanoClientContext, Brand, Cart, CartItem, CatalogAttributeList, CatalogAttributeListFilters, CatalogAttributeListItem, CatalogAttributeListValue, CatalogCategoryList, CatalogCategoryListItem, CatalogCategoryListItemSourceType, CheckoutResult, CheckoutSubmission, ContentEntry, ContentJson, ContentMedia, ContentTypeSummary, CustomerProfile, CustomerProfileUpdate, GetAttributeListOptions, GetCategoryListOptions, GetContentOptions, GetOrdersOptions, GetProductSeoEntriesOptions, GetProductsOptions, Order, OrderItem, Product, ProductAttribute, ProductAvailability, ProductCategory, ProductMedia, ProductMediaKind, ProductPrice, ProductPriceType, ProductSeoEntriesResult, ProductSeoEntry, ProductSubcategory, ProductVariant, ProductVariantPricing, PublicOrder, PublicOrderDeliverySummary, PublicOrderItem, PublicOrderLookupInput, PublicOrderPaymentSummary, StartGuestCheckoutInput, VariantAttribute, WebsiteCheckoutAddress, WebsiteCheckoutItem, WebsiteCouponActionResult, WebsiteDeliveryOption, WebsiteDepartmentOption, WebsiteFreeShippingProgress, WebsiteFulfillmentFamily, WebsiteGuestContact, WebsiteLocationOptions, WebsiteMunicipalityOption, WebsitePaymentMethod, WebsitePaymentSessionResult, WebsitePickupInfo, WebsiteShippingPolicy, WebsiteShippingQuote, } from "./types";