@bacano/sdk 1.2.8 → 1.2.10

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.
@@ -131,6 +131,49 @@ El paquete exporta `CatalogCreateProposal`, `CatalogContentProposal` y
131
131
  IDs, convertir atributos informativos en variantes, inventar bodegas ni escoger
132
132
  automáticamente la primera web. Preguntar las decisiones de mostrar/ocultar por web.
133
133
 
134
+ ### Preguntas obligatorias antes de crear el lote
135
+
136
+ El SDK expone datos y operaciones; **el agente que lo utiliza** debe consultar
137
+ `getContext()` y `getReferences()` y confirmar estas decisiones con la persona
138
+ **antes** de `createBatch` o `sendProposals`. Puede agruparlas en una conversación,
139
+ pero no omitirlas aunque el archivo de origen parezca completo:
140
+
141
+ `getCatalogImportPreflight(references)` (exportado desde
142
+ `@bacano/sdk/catalog-management`) devuelve las cuatro preguntas, los perfiles
143
+ y precios disponibles, la base tributaria de la empresa y las bodegas únicas
144
+ que pueden preseleccionarse. El agente debe presentar y resolver esas preguntas;
145
+ la función no reemplaza la confirmación humana.
146
+
147
+ 1. **Destinos y publicación:** ¿en cuáles sucursales autorizadas se crearán los
148
+ productos y en cuáles webs se mostrarán? Confirmar también el estado inicial
149
+ (borrador o activo) por sucursal. No escoger la primera opción por orden.
150
+ 2. **Precios:** ¿solo el precio normal `CLIENT` o todos/alguno de los tipos
151
+ habilitados (`WHOLESALE`, `WHOLESALE_2`, `SALE`)? ¿De qué columna o regla sale
152
+ cada importe y difiere entre sucursales? `CLIENT` es el precio principal;
153
+ no generar precios faltantes ni interpretar un importe vacío como cero.
154
+ 3. **IVA:** ¿qué perfil de `taxProfiles` corresponde a los productos y los
155
+ precios de la fuente incluyen IVA o lo excluyen? Mostrar el valor actual de
156
+ `company.sales_prices_include_tax_default` para que la persona confirme la
157
+ base. `price_tax_basis` del borrador debe coincidir con ese valor de empresa;
158
+ si la fuente usa otra base, acordar explícitamente la conversión antes de
159
+ normalizar. No inferir tarifa, responsabilidad tributaria ni convertir
160
+ importes silenciosamente; si hay productos con IVA distinto, pedir una regla
161
+ por grupo.
162
+ 4. **Inventario:** ¿se cargará inventario inicial? Si sí, ¿qué cantidad para cada
163
+ variante, sucursal y bodega? El cero explícito es válido; una celda vacía
164
+ queda pendiente. Si una sucursal tiene **una sola bodega vinculada**, usarla
165
+ como selección predeterminada y confirmarla. Si tiene varias, preguntar cuál
166
+ o cuáles corresponden a cada cantidad, sin escoger la primera ni repetir la
167
+ misma cantidad en todas. Si no hay bodegas vinculadas, pedir configuración
168
+ en Bacano antes de continuar.
169
+
170
+ Resumir las respuestas y pedir confirmación antes del primer envío. Si una
171
+ respuesta esencial falta, detener esa parte y conservarla como pendiente de
172
+ revisión; nunca rellenarla por conjetura. Los precios son por sucursal y tipo;
173
+ el inventario es por sucursal, bodega y variante. `getReferences()` puede
174
+ cambiar, así que volver a consultarlo si la persona configura nuevos destinos,
175
+ bodegas, perfiles o tipos de precio.
176
+
134
177
  ```ts
135
178
  // Guardar este identificador y el nombre ANTES de hacer la petición.
136
179
  const batchRequest = {
@@ -0,0 +1,19 @@
1
+ import type { CatalogReferences } from "./catalog-management-types";
2
+ export interface CatalogImportPreflightQuestion {
3
+ id: "destinations" | "prices" | "tax" | "inventory";
4
+ prompt: string;
5
+ options?: Array<{
6
+ id: string;
7
+ name: string;
8
+ }>;
9
+ }
10
+ /** Questions for the agent to resolve with a person before creating a batch. */
11
+ export declare function getCatalogImportPreflight(references: CatalogReferences): {
12
+ questions: CatalogImportPreflightQuestion[];
13
+ taxBasis: "included" | "excluded";
14
+ soleWarehouseDefaults: Array<{
15
+ chainId: string;
16
+ warehouseId: string;
17
+ warehouseName: string;
18
+ }>;
19
+ };
@@ -21,9 +21,57 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var catalog_management_exports = {};
22
22
  __export(catalog_management_exports, {
23
23
  CatalogManagementError: () => CatalogManagementError,
24
- createCatalogManagementClient: () => createCatalogManagementClient
24
+ createCatalogManagementClient: () => createCatalogManagementClient,
25
+ getCatalogImportPreflight: () => getCatalogImportPreflight
25
26
  });
26
27
  module.exports = __toCommonJS(catalog_management_exports);
28
+
29
+ // libs/sdk/src/catalog-import-preflight.ts
30
+ function getCatalogImportPreflight(references) {
31
+ const taxBasis = references.company.sales_prices_include_tax_default ? "included" : "excluded";
32
+ return {
33
+ taxBasis,
34
+ soleWarehouseDefaults: references.branches.flatMap((branch) => {
35
+ const link = branch.chains_warehouses[0];
36
+ return branch.chains_warehouses.length === 1 && link ? [
37
+ {
38
+ chainId: branch.id,
39
+ warehouseId: link.warehouse.id,
40
+ warehouseName: link.warehouse.name
41
+ }
42
+ ] : [];
43
+ }),
44
+ questions: [
45
+ {
46
+ id: "destinations",
47
+ prompt: "\xBFEn qu\xE9 sucursales se crear\xE1n los productos, en qu\xE9 webs se mostrar\xE1n y con qu\xE9 estado inicial?",
48
+ options: references.branches.map((branch) => ({
49
+ id: branch.id,
50
+ name: branch.name
51
+ }))
52
+ },
53
+ {
54
+ id: "prices",
55
+ prompt: "\xBFUsaremos solo el precio normal o tambi\xE9n otros precios habilitados? \xBFQu\xE9 importe corresponde a cada sucursal?",
56
+ options: references.priceTypes.filter((type) => type.is_enabled).map((type) => ({ id: type.price_type, name: type.price_type }))
57
+ },
58
+ {
59
+ id: "tax",
60
+ prompt: `\xBFQu\xE9 perfil de IVA corresponde? \xBFLos precios de origen incluyen o excluyen IVA? La empresa espera precios con IVA ${taxBasis === "included" ? "incluido" : "excluido"}.`,
61
+ options: references.taxProfiles.map((profile) => ({
62
+ id: profile.code,
63
+ name: `${profile.name} (${profile.rate} %)`
64
+ }))
65
+ },
66
+ {
67
+ id: "inventory",
68
+ prompt: "\xBFCargaremos inventario inicial? Si s\xED, \xBFqu\xE9 cantidad va en cada variante, sucursal y bodega? Confirma la bodega \xFAnica o elige entre las disponibles."
69
+ }
70
+ ]
71
+ };
72
+ }
73
+
74
+ // libs/sdk/src/catalog-management.ts
27
75
  var CatalogManagementError = class extends Error {
28
76
  constructor(code, status, message, details) {
29
77
  super(message);
@@ -1,5 +1,6 @@
1
1
  import type { CatalogManagementConfig, CatalogManagementContext, CatalogProductPage, CatalogReferences, CatalogTaxonomy } from "./catalog-management-types";
2
2
  export * from "./catalog-draft-types";
3
+ export * from "./catalog-import-preflight";
3
4
  export * from "./catalog-management-types";
4
5
  import type { CatalogDraftBatch, CatalogDraftBatchPage, CatalogDraftChunkResult, CatalogDraftImageResult, CatalogDraftResult, CatalogDraftWrite } from "./catalog-draft-types";
5
6
  export declare class CatalogManagementError extends Error {
@@ -1,3 +1,48 @@
1
+ // libs/sdk/src/catalog-import-preflight.ts
2
+ function getCatalogImportPreflight(references) {
3
+ const taxBasis = references.company.sales_prices_include_tax_default ? "included" : "excluded";
4
+ return {
5
+ taxBasis,
6
+ soleWarehouseDefaults: references.branches.flatMap((branch) => {
7
+ const link = branch.chains_warehouses[0];
8
+ return branch.chains_warehouses.length === 1 && link ? [
9
+ {
10
+ chainId: branch.id,
11
+ warehouseId: link.warehouse.id,
12
+ warehouseName: link.warehouse.name
13
+ }
14
+ ] : [];
15
+ }),
16
+ questions: [
17
+ {
18
+ id: "destinations",
19
+ prompt: "\xBFEn qu\xE9 sucursales se crear\xE1n los productos, en qu\xE9 webs se mostrar\xE1n y con qu\xE9 estado inicial?",
20
+ options: references.branches.map((branch) => ({
21
+ id: branch.id,
22
+ name: branch.name
23
+ }))
24
+ },
25
+ {
26
+ id: "prices",
27
+ prompt: "\xBFUsaremos solo el precio normal o tambi\xE9n otros precios habilitados? \xBFQu\xE9 importe corresponde a cada sucursal?",
28
+ options: references.priceTypes.filter((type) => type.is_enabled).map((type) => ({ id: type.price_type, name: type.price_type }))
29
+ },
30
+ {
31
+ id: "tax",
32
+ prompt: `\xBFQu\xE9 perfil de IVA corresponde? \xBFLos precios de origen incluyen o excluyen IVA? La empresa espera precios con IVA ${taxBasis === "included" ? "incluido" : "excluido"}.`,
33
+ options: references.taxProfiles.map((profile) => ({
34
+ id: profile.code,
35
+ name: `${profile.name} (${profile.rate} %)`
36
+ }))
37
+ },
38
+ {
39
+ id: "inventory",
40
+ prompt: "\xBFCargaremos inventario inicial? Si s\xED, \xBFqu\xE9 cantidad va en cada variante, sucursal y bodega? Confirma la bodega \xFAnica o elige entre las disponibles."
41
+ }
42
+ ]
43
+ };
44
+ }
45
+
1
46
  // libs/sdk/src/catalog-management.ts
2
47
  var CatalogManagementError = class extends Error {
3
48
  constructor(code, status, message, details) {
@@ -100,5 +145,6 @@ function createCatalogManagementClient(config) {
100
145
  }
101
146
  export {
102
147
  CatalogManagementError,
103
- createCatalogManagementClient
148
+ createCatalogManagementClient,
149
+ getCatalogImportPreflight
104
150
  };
package/graphql.cjs CHANGED
@@ -121,6 +121,19 @@ var GET_PRODUCTS = (
121
121
  ) {
122
122
  id
123
123
  name
124
+ product_tag_assignments(
125
+ where: { tag: { company_id: { _eq: $companyId }, is_active: { _eq: true } } }
126
+ ) {
127
+ tag {
128
+ id
129
+ category_id
130
+ key
131
+ name
132
+ slug
133
+ color
134
+ sort_order
135
+ }
136
+ }
124
137
  description
125
138
  product_website_publications(
126
139
  where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
@@ -363,6 +376,19 @@ var GET_PRODUCT_BY_PK = (
363
376
  limit: 1
364
377
  ) {
365
378
  id
379
+ product_tag_assignments(
380
+ where: { tag: { company_id: { _eq: $companyId }, is_active: { _eq: true } } }
381
+ ) {
382
+ tag {
383
+ id
384
+ category_id
385
+ key
386
+ name
387
+ slug
388
+ color
389
+ sort_order
390
+ }
391
+ }
366
392
  product_website_publications(
367
393
  where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
368
394
  limit: 1
package/graphql.js CHANGED
@@ -61,6 +61,19 @@ var GET_PRODUCTS = (
61
61
  ) {
62
62
  id
63
63
  name
64
+ product_tag_assignments(
65
+ where: { tag: { company_id: { _eq: $companyId }, is_active: { _eq: true } } }
66
+ ) {
67
+ tag {
68
+ id
69
+ category_id
70
+ key
71
+ name
72
+ slug
73
+ color
74
+ sort_order
75
+ }
76
+ }
64
77
  description
65
78
  product_website_publications(
66
79
  where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
@@ -303,6 +316,19 @@ var GET_PRODUCT_BY_PK = (
303
316
  limit: 1
304
317
  ) {
305
318
  id
319
+ product_tag_assignments(
320
+ where: { tag: { company_id: { _eq: $companyId }, is_active: { _eq: true } } }
321
+ ) {
322
+ tag {
323
+ id
324
+ category_id
325
+ key
326
+ name
327
+ slug
328
+ color
329
+ sort_order
330
+ }
331
+ }
306
332
  product_website_publications(
307
333
  where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
308
334
  limit: 1
package/index.cjs CHANGED
@@ -550,6 +550,19 @@ var GET_PRODUCTS = (
550
550
  ) {
551
551
  id
552
552
  name
553
+ product_tag_assignments(
554
+ where: { tag: { company_id: { _eq: $companyId }, is_active: { _eq: true } } }
555
+ ) {
556
+ tag {
557
+ id
558
+ category_id
559
+ key
560
+ name
561
+ slug
562
+ color
563
+ sort_order
564
+ }
565
+ }
553
566
  description
554
567
  product_website_publications(
555
568
  where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
@@ -792,6 +805,19 @@ var GET_PRODUCT_BY_PK = (
792
805
  limit: 1
793
806
  ) {
794
807
  id
808
+ product_tag_assignments(
809
+ where: { tag: { company_id: { _eq: $companyId }, is_active: { _eq: true } } }
810
+ ) {
811
+ tag {
812
+ id
813
+ category_id
814
+ key
815
+ name
816
+ slug
817
+ color
818
+ sort_order
819
+ }
820
+ }
795
821
  product_website_publications(
796
822
  where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
797
823
  limit: 1
@@ -4106,6 +4132,19 @@ function mapProduct(raw, storageUrl, labels, chainId) {
4106
4132
  return {
4107
4133
  id: raw.id,
4108
4134
  name: raw.name,
4135
+ tags: (raw.product_tag_assignments ?? []).map(
4136
+ ({ tag }) => ({
4137
+ id: tag.id,
4138
+ categoryId: tag.category_id,
4139
+ key: tag.key,
4140
+ name: tag.name,
4141
+ slug: tag.slug,
4142
+ color: tag.color,
4143
+ sortOrder: tag.sort_order
4144
+ })
4145
+ ).sort(
4146
+ (left, right) => left.sortOrder - right.sortOrder || left.name.localeCompare(right.name) || left.id.localeCompare(right.id)
4147
+ ),
4109
4148
  description: raw.description,
4110
4149
  longDescription: raw.long_description ?? null,
4111
4150
  slug: raw.slug ?? null,
package/index.d.ts CHANGED
@@ -12,4 +12,4 @@ export type { MediaResponsiveSource, MediaResponsiveSourceOptions, MediaTransfor
12
12
  export { buildStorageContentMediaUrls, buildStorageFileUrl, buildStorageMediaUrls, buildStorageResponsiveSources, buildStorageTransformedFileUrl, formatMediaSrcSet, } from "./media";
13
13
  export { getWebsiteContextFromPublicConfig, getWebsitePublicConfig, } from "./modules/auth";
14
14
  export { getPrimaryProductImage, getProductDetailVariants, getProductImages, getProductMediaByKind, getProductMediaKind, getProductVideos, resolveProductPricing, } from "./modules/catalog";
15
- export type { AccessTokenProvider, AttributeFilter, BacanoClientConfig, BacanoClientContext, Brand, Cart, CartItem, CatalogAttributeList, CatalogAttributeListFilters, CatalogAttributeListItem, CatalogAttributeListValue, CatalogCategoryList, CatalogCategoryListItem, CatalogCategoryListItemSourceType, CheckoutResult, CheckoutSubmission, ContentEntry, ContentJson, ContentMedia, ContentTypeSummary, CustomerAddress, CustomerAddressType, CustomerProfile, CustomerProfileUpdate, GetAttributeListOptions, GetCategoryListOptions, GetContentOptions, GetOrdersOptions, GetProductFiltersOptions, GetProductSeoEntriesOptions, GetProductsOptions, GetSearchSuggestionsOptions, GetStaticCatalogBootstrapOptions, GetStaticCatalogSnapshotOptions, GetWebsitePublicConfigOptions, Order, OrderItem, Product, ProductAttribute, ProductAvailability, ProductCategory, ProductContentBlock, ProductFilters, ProductMedia, ProductMediaKind, ProductOptionGroup, ProductOptionGroupMember, ProductPrice, ProductPriceType, ProductRelatedProduct, ProductSeoEntriesResult, ProductSeoEntry, ProductSortBy, ProductSpecification, ProductSpecificationFacet, ProductSpecificationField, ProductSpecificationFilterSelection, ProductSpecificationMeasure, ProductSpecificationOption, ProductSpecificationSection, ProductSubcategory, ProductVariant, ProductVariantLiveState, ProductVariantPricing, PublicOrder, PublicOrderDeliverySummary, PublicOrderItem, PublicOrderLookupInput, PublicOrderPaymentSummary, ResolvedWebsitePublicConfig, SearchSuggestion, StartGuestCheckoutInput, StaticCatalogBootstrap, StaticCatalogSnapshot, VariantAttribute, WaitForPublicOrderPaymentInput, WebsiteBrandingMedia, WebsiteBrandingPublicConfig, WebsiteCampaignCaptureContact, WebsiteCampaignCaptureInput, WebsiteCampaignCaptureResult, WebsiteCampaignCaptureSource, WebsiteCheckoutAddress, WebsiteCheckoutItem, WebsiteCouponActionResult, WebsiteDeliveryOption, WebsiteDepartmentOption, WebsiteFormAction, WebsiteFormDefinition, WebsiteFormField, WebsiteFormFieldType, WebsiteFormOption, WebsiteFormOptionSource, WebsiteFormResponseInput, WebsiteFormResponseResult, WebsiteFormResponseSource, WebsiteFormResponseValue, WebsiteFormSection, WebsiteFormStatus, WebsiteFormStep, WebsiteFreeShippingProgress, WebsiteFulfillmentFamily, WebsiteGuestContact, WebsiteLegalPublicConfig, WebsiteLocationOptions, WebsiteMunicipalityOption, WebsitePaymentMethod, WebsitePaymentMode, WebsitePaymentOption, WebsitePaymentOptionMethod, WebsitePaymentSessionResult, WebsitePickupInfo, WebsitePublicConfig, WebsitePublishedForm, WebsiteShippingPolicy, WebsiteShippingQuote, } from "./types";
15
+ export type { AccessTokenProvider, AttributeFilter, BacanoClientConfig, BacanoClientContext, Brand, Cart, CartItem, CatalogAttributeList, CatalogAttributeListFilters, CatalogAttributeListItem, CatalogAttributeListValue, CatalogCategoryList, CatalogCategoryListItem, CatalogCategoryListItemSourceType, CheckoutResult, CheckoutSubmission, ContentEntry, ContentJson, ContentMedia, ContentTypeSummary, CustomerAddress, CustomerAddressType, CustomerProfile, CustomerProfileUpdate, GetAttributeListOptions, GetCategoryListOptions, GetContentOptions, GetOrdersOptions, GetProductFiltersOptions, GetProductSeoEntriesOptions, GetProductsOptions, GetSearchSuggestionsOptions, GetStaticCatalogBootstrapOptions, GetStaticCatalogSnapshotOptions, GetWebsitePublicConfigOptions, Order, OrderItem, Product, ProductAttribute, ProductAvailability, ProductCategory, ProductContentBlock, ProductFilters, ProductMedia, ProductMediaKind, ProductOptionGroup, ProductOptionGroupMember, ProductPrice, ProductPriceType, ProductRelatedProduct, ProductSeoEntriesResult, ProductSeoEntry, ProductSortBy, ProductSpecification, ProductSpecificationFacet, ProductSpecificationField, ProductSpecificationFilterSelection, ProductSpecificationMeasure, ProductSpecificationOption, ProductSpecificationSection, ProductSubcategory, ProductTag, ProductVariant, ProductVariantLiveState, ProductVariantPricing, PublicOrder, PublicOrderDeliverySummary, PublicOrderItem, PublicOrderLookupInput, PublicOrderPaymentSummary, ResolvedWebsitePublicConfig, SearchSuggestion, StartGuestCheckoutInput, StaticCatalogBootstrap, StaticCatalogSnapshot, VariantAttribute, WaitForPublicOrderPaymentInput, WebsiteBrandingMedia, WebsiteBrandingPublicConfig, WebsiteCampaignCaptureContact, WebsiteCampaignCaptureInput, WebsiteCampaignCaptureResult, WebsiteCampaignCaptureSource, WebsiteCheckoutAddress, WebsiteCheckoutItem, WebsiteCouponActionResult, WebsiteDeliveryOption, WebsiteDepartmentOption, WebsiteFormAction, WebsiteFormDefinition, WebsiteFormField, WebsiteFormFieldType, WebsiteFormOption, WebsiteFormOptionSource, WebsiteFormResponseInput, WebsiteFormResponseResult, WebsiteFormResponseSource, WebsiteFormResponseValue, WebsiteFormSection, WebsiteFormStatus, WebsiteFormStep, WebsiteFreeShippingProgress, WebsiteFulfillmentFamily, WebsiteGuestContact, WebsiteLegalPublicConfig, WebsiteLocationOptions, WebsiteMunicipalityOption, WebsitePaymentMethod, WebsitePaymentMode, WebsitePaymentOption, WebsitePaymentOptionMethod, WebsitePaymentSessionResult, WebsitePickupInfo, WebsitePublicConfig, WebsitePublishedForm, WebsiteShippingPolicy, WebsiteShippingQuote, } from "./types";
package/index.js CHANGED
@@ -489,6 +489,19 @@ var GET_PRODUCTS = (
489
489
  ) {
490
490
  id
491
491
  name
492
+ product_tag_assignments(
493
+ where: { tag: { company_id: { _eq: $companyId }, is_active: { _eq: true } } }
494
+ ) {
495
+ tag {
496
+ id
497
+ category_id
498
+ key
499
+ name
500
+ slug
501
+ color
502
+ sort_order
503
+ }
504
+ }
492
505
  description
493
506
  product_website_publications(
494
507
  where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
@@ -731,6 +744,19 @@ var GET_PRODUCT_BY_PK = (
731
744
  limit: 1
732
745
  ) {
733
746
  id
747
+ product_tag_assignments(
748
+ where: { tag: { company_id: { _eq: $companyId }, is_active: { _eq: true } } }
749
+ ) {
750
+ tag {
751
+ id
752
+ category_id
753
+ key
754
+ name
755
+ slug
756
+ color
757
+ sort_order
758
+ }
759
+ }
734
760
  product_website_publications(
735
761
  where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
736
762
  limit: 1
@@ -4045,6 +4071,19 @@ function mapProduct(raw, storageUrl, labels, chainId) {
4045
4071
  return {
4046
4072
  id: raw.id,
4047
4073
  name: raw.name,
4074
+ tags: (raw.product_tag_assignments ?? []).map(
4075
+ ({ tag }) => ({
4076
+ id: tag.id,
4077
+ categoryId: tag.category_id,
4078
+ key: tag.key,
4079
+ name: tag.name,
4080
+ slug: tag.slug,
4081
+ color: tag.color,
4082
+ sortOrder: tag.sort_order
4083
+ })
4084
+ ).sort(
4085
+ (left, right) => left.sortOrder - right.sortOrder || left.name.localeCompare(right.name) || left.id.localeCompare(right.id)
4086
+ ),
4048
4087
  description: raw.description,
4049
4088
  longDescription: raw.long_description ?? null,
4050
4089
  slug: raw.slug ?? null,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bacano/sdk",
3
- "version": "1.2.8",
3
+ "version": "1.2.10",
4
4
  "description": "TypeScript SDK for building websites on the Bacano ERP",
5
5
  "main": "./index.cjs",
6
6
  "module": "./index.js",
package/react.cjs CHANGED
@@ -258,6 +258,19 @@ var GET_PRODUCTS = (
258
258
  ) {
259
259
  id
260
260
  name
261
+ product_tag_assignments(
262
+ where: { tag: { company_id: { _eq: $companyId }, is_active: { _eq: true } } }
263
+ ) {
264
+ tag {
265
+ id
266
+ category_id
267
+ key
268
+ name
269
+ slug
270
+ color
271
+ sort_order
272
+ }
273
+ }
261
274
  description
262
275
  product_website_publications(
263
276
  where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
@@ -500,6 +513,19 @@ var GET_PRODUCT_BY_PK = (
500
513
  limit: 1
501
514
  ) {
502
515
  id
516
+ product_tag_assignments(
517
+ where: { tag: { company_id: { _eq: $companyId }, is_active: { _eq: true } } }
518
+ ) {
519
+ tag {
520
+ id
521
+ category_id
522
+ key
523
+ name
524
+ slug
525
+ color
526
+ sort_order
527
+ }
528
+ }
503
529
  product_website_publications(
504
530
  where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
505
531
  limit: 1
@@ -3047,6 +3073,19 @@ function mapProduct(raw, storageUrl, labels, chainId) {
3047
3073
  return {
3048
3074
  id: raw.id,
3049
3075
  name: raw.name,
3076
+ tags: (raw.product_tag_assignments ?? []).map(
3077
+ ({ tag }) => ({
3078
+ id: tag.id,
3079
+ categoryId: tag.category_id,
3080
+ key: tag.key,
3081
+ name: tag.name,
3082
+ slug: tag.slug,
3083
+ color: tag.color,
3084
+ sortOrder: tag.sort_order
3085
+ })
3086
+ ).sort(
3087
+ (left, right) => left.sortOrder - right.sortOrder || left.name.localeCompare(right.name) || left.id.localeCompare(right.id)
3088
+ ),
3050
3089
  description: raw.description,
3051
3090
  longDescription: raw.long_description ?? null,
3052
3091
  slug: raw.slug ?? null,
package/react.js CHANGED
@@ -201,6 +201,19 @@ var GET_PRODUCTS = (
201
201
  ) {
202
202
  id
203
203
  name
204
+ product_tag_assignments(
205
+ where: { tag: { company_id: { _eq: $companyId }, is_active: { _eq: true } } }
206
+ ) {
207
+ tag {
208
+ id
209
+ category_id
210
+ key
211
+ name
212
+ slug
213
+ color
214
+ sort_order
215
+ }
216
+ }
204
217
  description
205
218
  product_website_publications(
206
219
  where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
@@ -443,6 +456,19 @@ var GET_PRODUCT_BY_PK = (
443
456
  limit: 1
444
457
  ) {
445
458
  id
459
+ product_tag_assignments(
460
+ where: { tag: { company_id: { _eq: $companyId }, is_active: { _eq: true } } }
461
+ ) {
462
+ tag {
463
+ id
464
+ category_id
465
+ key
466
+ name
467
+ slug
468
+ color
469
+ sort_order
470
+ }
471
+ }
446
472
  product_website_publications(
447
473
  where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }
448
474
  limit: 1
@@ -2990,6 +3016,19 @@ function mapProduct(raw, storageUrl, labels, chainId) {
2990
3016
  return {
2991
3017
  id: raw.id,
2992
3018
  name: raw.name,
3019
+ tags: (raw.product_tag_assignments ?? []).map(
3020
+ ({ tag }) => ({
3021
+ id: tag.id,
3022
+ categoryId: tag.category_id,
3023
+ key: tag.key,
3024
+ name: tag.name,
3025
+ slug: tag.slug,
3026
+ color: tag.color,
3027
+ sortOrder: tag.sort_order
3028
+ })
3029
+ ).sort(
3030
+ (left, right) => left.sortOrder - right.sortOrder || left.name.localeCompare(right.name) || left.id.localeCompare(right.id)
3031
+ ),
2993
3032
  description: raw.description,
2994
3033
  longDescription: raw.long_description ?? null,
2995
3034
  slug: raw.slug ?? null,
@@ -1,6 +1,6 @@
1
1
  export declare const RESOLVE_WEBSITE_BY_SLUG = "\n query ResolveWebsiteBySlug($slug: String!) {\n websites(\n where: { slug: { _eq: $slug }, is_active: { _eq: true } }\n limit: 1\n ) {\n id\n company_id\n chain_id\n name\n slug\n domain\n config\n }\n }\n";
2
- export declare const GET_PRODUCTS = "\n query GetProducts(\n $companyId: uuid!\n $chainId: uuid!\n $websiteId: uuid!\n $limit: Int = 20\n $offset: Int = 0\n $where: products_bool_exp = {}\n $orderBy: [products_order_by!] = [{ name: asc }]\n ) {\n products(\n where: {\n _and: [\n { company_id: { _eq: $companyId } }\n {\n product_website_publications: {\n website_id: { _eq: $websiteId }\n is_visible: { _eq: true }\n }\n }\n {\n chain_products: {\n chain_id: { _eq: $chainId }\n is_enabled: { _eq: true }\n status: { _eq: active }\n }\n }\n $where\n ]\n }\n limit: $limit\n offset: $offset\n order_by: $orderBy\n ) {\n id\n name\n description\n product_website_publications(\n where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }\n limit: 1\n ) {\n show_when_out_of_stock\n }\n long_description\n slug\n seo_title\n seo_description\n seo_image_file_id\n category\n subcategory\n color\n measurement_unit\n created_at\n updated_at\n brand {\n id\n name\n }\n seo_image_file {\n mimeType\n name\n }\n product_variants(\n where: { is_disabled: { _eq: false } }\n order_by: { order: asc }\n ) {\n id\n sku\n barcode\n order\n weight\n depth\n height\n length\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 product_variant_attributes(order_by: { order: asc }) {\n id\n value\n order\n attribute_value {\n id\n code\n sort_order\n metadata\n }\n attribute {\n id\n name\n }\n }\n }\n product_media(order_by: { order: asc }) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n product_related_products(\n where: {\n related_product: {\n chain_products: {\n chain_id: { _eq: $chainId }\n is_enabled: { _eq: true }\n status: { _eq: active }\n }\n }\n }\n order_by: { sort_order: asc }\n ) {\n id\n related_product_id\n sort_order\n related_product {\n id\n slug\n name\n sku\n product_media(\n where: { file: { mimeType: { _ilike: \"image/%\" } } }\n order_by: { order: asc }\n limit: 1\n ) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n }\n }\n product_option_group_members(limit: 1) {\n group {\n id\n display_title\n members(\n where: {\n product: {\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 order_by: { sort_order: asc }\n ) {\n id\n product_id\n display_label\n sort_order\n product {\n id\n slug\n name\n sku\n product_media(\n where: { file: { mimeType: { _ilike: \"image/%\" } } }\n order_by: { order: asc }\n limit: 1\n ) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n }\n }\n }\n }\n product_attributes {\n id\n value\n attribute_value {\n id\n code\n sort_order\n metadata\n }\n attribute {\n id\n name\n }\n }\n }\n catalog_attribute_lists(\n where: { company_id: { _eq: $companyId }, status: { _eq: published } }\n order_by: { updated_at: desc }\n ) {\n id\n key\n name\n description\n status\n items(\n where: { is_visible: { _eq: true } }\n order_by: [{ sort_order: asc }, { public_label: asc }]\n ) {\n id\n attribute_id\n public_label\n public_slug\n sort_order\n attribute {\n id\n name\n type\n }\n values(\n where: { is_visible: { _eq: true } }\n order_by: [{ sort_order: asc }, { public_label: asc }]\n ) {\n id\n attribute_value_id\n public_label\n public_slug\n sort_order\n attribute_value {\n id\n code\n metadata\n }\n }\n }\n }\n }\n";
3
- export declare const GET_PRODUCT_BY_PK = "\n query GetProductByPk(\n $productId: uuid!\n $companyId: uuid!\n $chainId: uuid!\n $websiteId: uuid!\n ) {\n products(\n where: {\n id: { _eq: $productId }\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 limit: 1\n ) {\n id\n product_website_publications(\n where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }\n limit: 1\n ) {\n show_when_out_of_stock\n }\n product_option_group_members(limit: 1) {\n group {\n id\n display_title\n members(\n where: {\n product: {\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 order_by: { sort_order: asc }\n ) {\n id\n product_id\n display_label\n sort_order\n product {\n id\n slug\n name\n sku\n product_media(\n where: { file: { mimeType: { _ilike: \"image/%\" } } }\n order_by: { order: asc }\n limit: 1\n ) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n }\n }\n }\n }\n name\n description\n long_description\n slug\n seo_title\n seo_description\n seo_image_file_id\n category\n subcategory\n color\n measurement_unit\n created_at\n updated_at\n brand {\n id\n name\n }\n seo_image_file {\n mimeType\n name\n }\n product_variants(\n where: { is_disabled: { _eq: false } }\n order_by: { order: asc }\n ) {\n id\n sku\n barcode\n order\n weight\n depth\n height\n length\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 product_variant_attributes(order_by: { order: asc }) {\n id\n value\n order\n attribute_value {\n id\n code\n sort_order\n metadata\n }\n attribute {\n id\n name\n }\n }\n }\n product_media(order_by: { order: asc }) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n product_related_products(\n where: {\n related_product: {\n chain_products: {\n chain_id: { _eq: $chainId }\n is_enabled: { _eq: true }\n status: { _eq: active }\n }\n }\n }\n order_by: { sort_order: asc }\n ) {\n id\n related_product_id\n sort_order\n related_product {\n id\n slug\n name\n sku\n product_media(\n where: { file: { mimeType: { _ilike: \"image/%\" } } }\n order_by: { order: asc }\n limit: 1\n ) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n }\n }\n product_attributes {\n id\n value\n attribute_value {\n id\n code\n sort_order\n metadata\n }\n attribute {\n id\n name\n }\n }\n }\n catalog_attribute_lists(\n where: { company_id: { _eq: $companyId }, status: { _eq: published } }\n order_by: { updated_at: desc }\n ) {\n id\n key\n name\n description\n status\n items(\n where: { is_visible: { _eq: true } }\n order_by: [{ sort_order: asc }, { public_label: asc }]\n ) {\n id\n attribute_id\n public_label\n public_slug\n sort_order\n attribute {\n id\n name\n type\n }\n values(\n where: { is_visible: { _eq: true } }\n order_by: [{ sort_order: asc }, { public_label: asc }]\n ) {\n id\n attribute_value_id\n public_label\n public_slug\n sort_order\n attribute_value {\n id\n code\n metadata\n }\n }\n }\n }\n }\n";
2
+ export declare const GET_PRODUCTS = "\n query GetProducts(\n $companyId: uuid!\n $chainId: uuid!\n $websiteId: uuid!\n $limit: Int = 20\n $offset: Int = 0\n $where: products_bool_exp = {}\n $orderBy: [products_order_by!] = [{ name: asc }]\n ) {\n products(\n where: {\n _and: [\n { company_id: { _eq: $companyId } }\n {\n product_website_publications: {\n website_id: { _eq: $websiteId }\n is_visible: { _eq: true }\n }\n }\n {\n chain_products: {\n chain_id: { _eq: $chainId }\n is_enabled: { _eq: true }\n status: { _eq: active }\n }\n }\n $where\n ]\n }\n limit: $limit\n offset: $offset\n order_by: $orderBy\n ) {\n id\n name\n product_tag_assignments(\n where: { tag: { company_id: { _eq: $companyId }, is_active: { _eq: true } } }\n ) {\n tag {\n id\n category_id\n key\n name\n slug\n color\n sort_order\n }\n }\n description\n product_website_publications(\n where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }\n limit: 1\n ) {\n show_when_out_of_stock\n }\n long_description\n slug\n seo_title\n seo_description\n seo_image_file_id\n category\n subcategory\n color\n measurement_unit\n created_at\n updated_at\n brand {\n id\n name\n }\n seo_image_file {\n mimeType\n name\n }\n product_variants(\n where: { is_disabled: { _eq: false } }\n order_by: { order: asc }\n ) {\n id\n sku\n barcode\n order\n weight\n depth\n height\n length\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 product_variant_attributes(order_by: { order: asc }) {\n id\n value\n order\n attribute_value {\n id\n code\n sort_order\n metadata\n }\n attribute {\n id\n name\n }\n }\n }\n product_media(order_by: { order: asc }) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n product_related_products(\n where: {\n related_product: {\n chain_products: {\n chain_id: { _eq: $chainId }\n is_enabled: { _eq: true }\n status: { _eq: active }\n }\n }\n }\n order_by: { sort_order: asc }\n ) {\n id\n related_product_id\n sort_order\n related_product {\n id\n slug\n name\n sku\n product_media(\n where: { file: { mimeType: { _ilike: \"image/%\" } } }\n order_by: { order: asc }\n limit: 1\n ) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n }\n }\n product_option_group_members(limit: 1) {\n group {\n id\n display_title\n members(\n where: {\n product: {\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 order_by: { sort_order: asc }\n ) {\n id\n product_id\n display_label\n sort_order\n product {\n id\n slug\n name\n sku\n product_media(\n where: { file: { mimeType: { _ilike: \"image/%\" } } }\n order_by: { order: asc }\n limit: 1\n ) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n }\n }\n }\n }\n product_attributes {\n id\n value\n attribute_value {\n id\n code\n sort_order\n metadata\n }\n attribute {\n id\n name\n }\n }\n }\n catalog_attribute_lists(\n where: { company_id: { _eq: $companyId }, status: { _eq: published } }\n order_by: { updated_at: desc }\n ) {\n id\n key\n name\n description\n status\n items(\n where: { is_visible: { _eq: true } }\n order_by: [{ sort_order: asc }, { public_label: asc }]\n ) {\n id\n attribute_id\n public_label\n public_slug\n sort_order\n attribute {\n id\n name\n type\n }\n values(\n where: { is_visible: { _eq: true } }\n order_by: [{ sort_order: asc }, { public_label: asc }]\n ) {\n id\n attribute_value_id\n public_label\n public_slug\n sort_order\n attribute_value {\n id\n code\n metadata\n }\n }\n }\n }\n }\n";
3
+ export declare const GET_PRODUCT_BY_PK = "\n query GetProductByPk(\n $productId: uuid!\n $companyId: uuid!\n $chainId: uuid!\n $websiteId: uuid!\n ) {\n products(\n where: {\n id: { _eq: $productId }\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 limit: 1\n ) {\n id\n product_tag_assignments(\n where: { tag: { company_id: { _eq: $companyId }, is_active: { _eq: true } } }\n ) {\n tag {\n id\n category_id\n key\n name\n slug\n color\n sort_order\n }\n }\n product_website_publications(\n where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }\n limit: 1\n ) {\n show_when_out_of_stock\n }\n product_option_group_members(limit: 1) {\n group {\n id\n display_title\n members(\n where: {\n product: {\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 order_by: { sort_order: asc }\n ) {\n id\n product_id\n display_label\n sort_order\n product {\n id\n slug\n name\n sku\n product_media(\n where: { file: { mimeType: { _ilike: \"image/%\" } } }\n order_by: { order: asc }\n limit: 1\n ) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n }\n }\n }\n }\n name\n description\n long_description\n slug\n seo_title\n seo_description\n seo_image_file_id\n category\n subcategory\n color\n measurement_unit\n created_at\n updated_at\n brand {\n id\n name\n }\n seo_image_file {\n mimeType\n name\n }\n product_variants(\n where: { is_disabled: { _eq: false } }\n order_by: { order: asc }\n ) {\n id\n sku\n barcode\n order\n weight\n depth\n height\n length\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 product_variant_attributes(order_by: { order: asc }) {\n id\n value\n order\n attribute_value {\n id\n code\n sort_order\n metadata\n }\n attribute {\n id\n name\n }\n }\n }\n product_media(order_by: { order: asc }) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n product_related_products(\n where: {\n related_product: {\n chain_products: {\n chain_id: { _eq: $chainId }\n is_enabled: { _eq: true }\n status: { _eq: active }\n }\n }\n }\n order_by: { sort_order: asc }\n ) {\n id\n related_product_id\n sort_order\n related_product {\n id\n slug\n name\n sku\n product_media(\n where: { file: { mimeType: { _ilike: \"image/%\" } } }\n order_by: { order: asc }\n limit: 1\n ) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n }\n }\n product_attributes {\n id\n value\n attribute_value {\n id\n code\n sort_order\n metadata\n }\n attribute {\n id\n name\n }\n }\n }\n catalog_attribute_lists(\n where: { company_id: { _eq: $companyId }, status: { _eq: published } }\n order_by: { updated_at: desc }\n ) {\n id\n key\n name\n description\n status\n items(\n where: { is_visible: { _eq: true } }\n order_by: [{ sort_order: asc }, { public_label: asc }]\n ) {\n id\n attribute_id\n public_label\n public_slug\n sort_order\n attribute {\n id\n name\n type\n }\n values(\n where: { is_visible: { _eq: true } }\n order_by: [{ sort_order: asc }, { public_label: asc }]\n ) {\n id\n attribute_value_id\n public_label\n public_slug\n sort_order\n attribute_value {\n id\n code\n metadata\n }\n }\n }\n }\n }\n";
4
4
  export declare const GET_PRODUCT_BY_SLUG: string;
5
5
  export declare const GET_PRODUCT_SEO_ENTRIES = "\n query GetProductSeoEntries(\n $companyId: uuid!\n $chainId: uuid!\n $websiteId: uuid!\n $limit: Int!\n $offset: Int!\n ) {\n products(\n where: {\n company_id: { _eq: $companyId }\n slug: { _is_null: false }\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 limit: $limit\n offset: $offset\n order_by: [{ updated_at: desc }, { created_at: desc }]\n ) {\n id\n name\n slug\n product_website_publications(\n where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }\n limit: 1\n ) {\n show_when_out_of_stock\n }\n seo_title\n seo_description\n seo_image_file_id\n category\n subcategory\n created_at\n updated_at\n seo_image_file {\n mimeType\n name\n }\n product_media(\n where: { file: { mimeType: { _ilike: \"image/%\" } } }\n order_by: { order: asc }\n limit: 1\n ) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n product_variants(\n where: { is_disabled: { _eq: false } }\n order_by: { order: asc }\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 }\n }\n";
6
6
  export declare const GET_CATEGORIES = "\n query GetCategories {\n product_categories {\n name\n description\n product_subcategories {\n id\n name\n description\n }\n }\n }\n";
@@ -46,8 +46,8 @@ export declare const GET_SEARCH_SUGGESTIONS = "\n query GetSearchSuggestions(\n
46
46
  /** All documents as a named record for the advanced graphql entry point */
47
47
  export declare const documents: {
48
48
  readonly RESOLVE_WEBSITE_BY_SLUG: "\n query ResolveWebsiteBySlug($slug: String!) {\n websites(\n where: { slug: { _eq: $slug }, is_active: { _eq: true } }\n limit: 1\n ) {\n id\n company_id\n chain_id\n name\n slug\n domain\n config\n }\n }\n";
49
- readonly GET_PRODUCTS: "\n query GetProducts(\n $companyId: uuid!\n $chainId: uuid!\n $websiteId: uuid!\n $limit: Int = 20\n $offset: Int = 0\n $where: products_bool_exp = {}\n $orderBy: [products_order_by!] = [{ name: asc }]\n ) {\n products(\n where: {\n _and: [\n { company_id: { _eq: $companyId } }\n {\n product_website_publications: {\n website_id: { _eq: $websiteId }\n is_visible: { _eq: true }\n }\n }\n {\n chain_products: {\n chain_id: { _eq: $chainId }\n is_enabled: { _eq: true }\n status: { _eq: active }\n }\n }\n $where\n ]\n }\n limit: $limit\n offset: $offset\n order_by: $orderBy\n ) {\n id\n name\n description\n product_website_publications(\n where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }\n limit: 1\n ) {\n show_when_out_of_stock\n }\n long_description\n slug\n seo_title\n seo_description\n seo_image_file_id\n category\n subcategory\n color\n measurement_unit\n created_at\n updated_at\n brand {\n id\n name\n }\n seo_image_file {\n mimeType\n name\n }\n product_variants(\n where: { is_disabled: { _eq: false } }\n order_by: { order: asc }\n ) {\n id\n sku\n barcode\n order\n weight\n depth\n height\n length\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 product_variant_attributes(order_by: { order: asc }) {\n id\n value\n order\n attribute_value {\n id\n code\n sort_order\n metadata\n }\n attribute {\n id\n name\n }\n }\n }\n product_media(order_by: { order: asc }) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n product_related_products(\n where: {\n related_product: {\n chain_products: {\n chain_id: { _eq: $chainId }\n is_enabled: { _eq: true }\n status: { _eq: active }\n }\n }\n }\n order_by: { sort_order: asc }\n ) {\n id\n related_product_id\n sort_order\n related_product {\n id\n slug\n name\n sku\n product_media(\n where: { file: { mimeType: { _ilike: \"image/%\" } } }\n order_by: { order: asc }\n limit: 1\n ) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n }\n }\n product_option_group_members(limit: 1) {\n group {\n id\n display_title\n members(\n where: {\n product: {\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 order_by: { sort_order: asc }\n ) {\n id\n product_id\n display_label\n sort_order\n product {\n id\n slug\n name\n sku\n product_media(\n where: { file: { mimeType: { _ilike: \"image/%\" } } }\n order_by: { order: asc }\n limit: 1\n ) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n }\n }\n }\n }\n product_attributes {\n id\n value\n attribute_value {\n id\n code\n sort_order\n metadata\n }\n attribute {\n id\n name\n }\n }\n }\n catalog_attribute_lists(\n where: { company_id: { _eq: $companyId }, status: { _eq: published } }\n order_by: { updated_at: desc }\n ) {\n id\n key\n name\n description\n status\n items(\n where: { is_visible: { _eq: true } }\n order_by: [{ sort_order: asc }, { public_label: asc }]\n ) {\n id\n attribute_id\n public_label\n public_slug\n sort_order\n attribute {\n id\n name\n type\n }\n values(\n where: { is_visible: { _eq: true } }\n order_by: [{ sort_order: asc }, { public_label: asc }]\n ) {\n id\n attribute_value_id\n public_label\n public_slug\n sort_order\n attribute_value {\n id\n code\n metadata\n }\n }\n }\n }\n }\n";
50
- readonly GET_PRODUCT_BY_PK: "\n query GetProductByPk(\n $productId: uuid!\n $companyId: uuid!\n $chainId: uuid!\n $websiteId: uuid!\n ) {\n products(\n where: {\n id: { _eq: $productId }\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 limit: 1\n ) {\n id\n product_website_publications(\n where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }\n limit: 1\n ) {\n show_when_out_of_stock\n }\n product_option_group_members(limit: 1) {\n group {\n id\n display_title\n members(\n where: {\n product: {\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 order_by: { sort_order: asc }\n ) {\n id\n product_id\n display_label\n sort_order\n product {\n id\n slug\n name\n sku\n product_media(\n where: { file: { mimeType: { _ilike: \"image/%\" } } }\n order_by: { order: asc }\n limit: 1\n ) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n }\n }\n }\n }\n name\n description\n long_description\n slug\n seo_title\n seo_description\n seo_image_file_id\n category\n subcategory\n color\n measurement_unit\n created_at\n updated_at\n brand {\n id\n name\n }\n seo_image_file {\n mimeType\n name\n }\n product_variants(\n where: { is_disabled: { _eq: false } }\n order_by: { order: asc }\n ) {\n id\n sku\n barcode\n order\n weight\n depth\n height\n length\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 product_variant_attributes(order_by: { order: asc }) {\n id\n value\n order\n attribute_value {\n id\n code\n sort_order\n metadata\n }\n attribute {\n id\n name\n }\n }\n }\n product_media(order_by: { order: asc }) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n product_related_products(\n where: {\n related_product: {\n chain_products: {\n chain_id: { _eq: $chainId }\n is_enabled: { _eq: true }\n status: { _eq: active }\n }\n }\n }\n order_by: { sort_order: asc }\n ) {\n id\n related_product_id\n sort_order\n related_product {\n id\n slug\n name\n sku\n product_media(\n where: { file: { mimeType: { _ilike: \"image/%\" } } }\n order_by: { order: asc }\n limit: 1\n ) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n }\n }\n product_attributes {\n id\n value\n attribute_value {\n id\n code\n sort_order\n metadata\n }\n attribute {\n id\n name\n }\n }\n }\n catalog_attribute_lists(\n where: { company_id: { _eq: $companyId }, status: { _eq: published } }\n order_by: { updated_at: desc }\n ) {\n id\n key\n name\n description\n status\n items(\n where: { is_visible: { _eq: true } }\n order_by: [{ sort_order: asc }, { public_label: asc }]\n ) {\n id\n attribute_id\n public_label\n public_slug\n sort_order\n attribute {\n id\n name\n type\n }\n values(\n where: { is_visible: { _eq: true } }\n order_by: [{ sort_order: asc }, { public_label: asc }]\n ) {\n id\n attribute_value_id\n public_label\n public_slug\n sort_order\n attribute_value {\n id\n code\n metadata\n }\n }\n }\n }\n }\n";
49
+ readonly GET_PRODUCTS: "\n query GetProducts(\n $companyId: uuid!\n $chainId: uuid!\n $websiteId: uuid!\n $limit: Int = 20\n $offset: Int = 0\n $where: products_bool_exp = {}\n $orderBy: [products_order_by!] = [{ name: asc }]\n ) {\n products(\n where: {\n _and: [\n { company_id: { _eq: $companyId } }\n {\n product_website_publications: {\n website_id: { _eq: $websiteId }\n is_visible: { _eq: true }\n }\n }\n {\n chain_products: {\n chain_id: { _eq: $chainId }\n is_enabled: { _eq: true }\n status: { _eq: active }\n }\n }\n $where\n ]\n }\n limit: $limit\n offset: $offset\n order_by: $orderBy\n ) {\n id\n name\n product_tag_assignments(\n where: { tag: { company_id: { _eq: $companyId }, is_active: { _eq: true } } }\n ) {\n tag {\n id\n category_id\n key\n name\n slug\n color\n sort_order\n }\n }\n description\n product_website_publications(\n where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }\n limit: 1\n ) {\n show_when_out_of_stock\n }\n long_description\n slug\n seo_title\n seo_description\n seo_image_file_id\n category\n subcategory\n color\n measurement_unit\n created_at\n updated_at\n brand {\n id\n name\n }\n seo_image_file {\n mimeType\n name\n }\n product_variants(\n where: { is_disabled: { _eq: false } }\n order_by: { order: asc }\n ) {\n id\n sku\n barcode\n order\n weight\n depth\n height\n length\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 product_variant_attributes(order_by: { order: asc }) {\n id\n value\n order\n attribute_value {\n id\n code\n sort_order\n metadata\n }\n attribute {\n id\n name\n }\n }\n }\n product_media(order_by: { order: asc }) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n product_related_products(\n where: {\n related_product: {\n chain_products: {\n chain_id: { _eq: $chainId }\n is_enabled: { _eq: true }\n status: { _eq: active }\n }\n }\n }\n order_by: { sort_order: asc }\n ) {\n id\n related_product_id\n sort_order\n related_product {\n id\n slug\n name\n sku\n product_media(\n where: { file: { mimeType: { _ilike: \"image/%\" } } }\n order_by: { order: asc }\n limit: 1\n ) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n }\n }\n product_option_group_members(limit: 1) {\n group {\n id\n display_title\n members(\n where: {\n product: {\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 order_by: { sort_order: asc }\n ) {\n id\n product_id\n display_label\n sort_order\n product {\n id\n slug\n name\n sku\n product_media(\n where: { file: { mimeType: { _ilike: \"image/%\" } } }\n order_by: { order: asc }\n limit: 1\n ) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n }\n }\n }\n }\n product_attributes {\n id\n value\n attribute_value {\n id\n code\n sort_order\n metadata\n }\n attribute {\n id\n name\n }\n }\n }\n catalog_attribute_lists(\n where: { company_id: { _eq: $companyId }, status: { _eq: published } }\n order_by: { updated_at: desc }\n ) {\n id\n key\n name\n description\n status\n items(\n where: { is_visible: { _eq: true } }\n order_by: [{ sort_order: asc }, { public_label: asc }]\n ) {\n id\n attribute_id\n public_label\n public_slug\n sort_order\n attribute {\n id\n name\n type\n }\n values(\n where: { is_visible: { _eq: true } }\n order_by: [{ sort_order: asc }, { public_label: asc }]\n ) {\n id\n attribute_value_id\n public_label\n public_slug\n sort_order\n attribute_value {\n id\n code\n metadata\n }\n }\n }\n }\n }\n";
50
+ readonly GET_PRODUCT_BY_PK: "\n query GetProductByPk(\n $productId: uuid!\n $companyId: uuid!\n $chainId: uuid!\n $websiteId: uuid!\n ) {\n products(\n where: {\n id: { _eq: $productId }\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 limit: 1\n ) {\n id\n product_tag_assignments(\n where: { tag: { company_id: { _eq: $companyId }, is_active: { _eq: true } } }\n ) {\n tag {\n id\n category_id\n key\n name\n slug\n color\n sort_order\n }\n }\n product_website_publications(\n where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }\n limit: 1\n ) {\n show_when_out_of_stock\n }\n product_option_group_members(limit: 1) {\n group {\n id\n display_title\n members(\n where: {\n product: {\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 order_by: { sort_order: asc }\n ) {\n id\n product_id\n display_label\n sort_order\n product {\n id\n slug\n name\n sku\n product_media(\n where: { file: { mimeType: { _ilike: \"image/%\" } } }\n order_by: { order: asc }\n limit: 1\n ) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n }\n }\n }\n }\n name\n description\n long_description\n slug\n seo_title\n seo_description\n seo_image_file_id\n category\n subcategory\n color\n measurement_unit\n created_at\n updated_at\n brand {\n id\n name\n }\n seo_image_file {\n mimeType\n name\n }\n product_variants(\n where: { is_disabled: { _eq: false } }\n order_by: { order: asc }\n ) {\n id\n sku\n barcode\n order\n weight\n depth\n height\n length\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 product_variant_attributes(order_by: { order: asc }) {\n id\n value\n order\n attribute_value {\n id\n code\n sort_order\n metadata\n }\n attribute {\n id\n name\n }\n }\n }\n product_media(order_by: { order: asc }) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n product_related_products(\n where: {\n related_product: {\n chain_products: {\n chain_id: { _eq: $chainId }\n is_enabled: { _eq: true }\n status: { _eq: active }\n }\n }\n }\n order_by: { sort_order: asc }\n ) {\n id\n related_product_id\n sort_order\n related_product {\n id\n slug\n name\n sku\n product_media(\n where: { file: { mimeType: { _ilike: \"image/%\" } } }\n order_by: { order: asc }\n limit: 1\n ) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n }\n }\n product_attributes {\n id\n value\n attribute_value {\n id\n code\n sort_order\n metadata\n }\n attribute {\n id\n name\n }\n }\n }\n catalog_attribute_lists(\n where: { company_id: { _eq: $companyId }, status: { _eq: published } }\n order_by: { updated_at: desc }\n ) {\n id\n key\n name\n description\n status\n items(\n where: { is_visible: { _eq: true } }\n order_by: [{ sort_order: asc }, { public_label: asc }]\n ) {\n id\n attribute_id\n public_label\n public_slug\n sort_order\n attribute {\n id\n name\n type\n }\n values(\n where: { is_visible: { _eq: true } }\n order_by: [{ sort_order: asc }, { public_label: asc }]\n ) {\n id\n attribute_value_id\n public_label\n public_slug\n sort_order\n attribute_value {\n id\n code\n metadata\n }\n }\n }\n }\n }\n";
51
51
  readonly GET_PRODUCT_BY_SLUG: string;
52
52
  readonly GET_PRODUCT_SEO_ENTRIES: "\n query GetProductSeoEntries(\n $companyId: uuid!\n $chainId: uuid!\n $websiteId: uuid!\n $limit: Int!\n $offset: Int!\n ) {\n products(\n where: {\n company_id: { _eq: $companyId }\n slug: { _is_null: false }\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 limit: $limit\n offset: $offset\n order_by: [{ updated_at: desc }, { created_at: desc }]\n ) {\n id\n name\n slug\n product_website_publications(\n where: { website_id: { _eq: $websiteId }, is_visible: { _eq: true } }\n limit: 1\n ) {\n show_when_out_of_stock\n }\n seo_title\n seo_description\n seo_image_file_id\n category\n subcategory\n created_at\n updated_at\n seo_image_file {\n mimeType\n name\n }\n product_media(\n where: { file: { mimeType: { _ilike: \"image/%\" } } }\n order_by: { order: asc }\n limit: 1\n ) {\n id\n file_id\n order\n file {\n mimeType\n name\n }\n }\n product_variants(\n where: { is_disabled: { _eq: false } }\n order_by: { order: asc }\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 }\n }\n";
53
53
  readonly GET_CATEGORIES: "\n query GetCategories {\n product_categories {\n name\n description\n product_subcategories {\n id\n name\n description\n }\n }\n }\n";
package/types.d.ts CHANGED
@@ -328,6 +328,8 @@ export interface BacanoClientContext {
328
328
  export interface Product {
329
329
  id: string;
330
330
  name: string;
331
+ /** Active, public tags assigned to this product, ordered for display. */
332
+ tags: ProductTag[];
331
333
  description: string | null;
332
334
  longDescription: Record<string, unknown> | null;
333
335
  slug: string | null;
@@ -360,6 +362,15 @@ export interface Product {
360
362
  /** Public, non-empty technical specification resolved by Bacano. */
361
363
  specification: ProductSpecification | null;
362
364
  }
365
+ export interface ProductTag {
366
+ id: string;
367
+ categoryId: string;
368
+ key: string;
369
+ name: string;
370
+ slug: string;
371
+ color: string | null;
372
+ sortOrder: number;
373
+ }
363
374
  export interface ProductSpecification {
364
375
  contentTypeId: string;
365
376
  key: string;