@bacano/sdk 1.2.6 → 1.2.7
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/CONTENT_ICONS.md +113 -0
- package/CONTENT_TYPE_MANAGEMENT.md +8 -2
- package/README.md +1 -0
- package/STOREFRONT_PAYMENTS.md +8 -0
- package/STOREFRONT_PERFORMANCE.md +35 -0
- package/content-management-types.d.ts +9 -1
- package/icons.cjs +5515 -0
- package/icons.d.ts +20 -0
- package/icons.js +5496 -0
- package/package.json +11 -1
- package/react/icon.cjs +5555 -0
- package/react/icon.d.ts +10 -0
- package/react/icon.js +5534 -0
- package/skills/bacano-web/references/common.md +13 -0
- package/skills/bacano-web/references/storefront.md +5 -0
package/CONTENT_ICONS.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Iconos Bacano en Content y sitios web
|
|
2
|
+
|
|
3
|
+
La biblioteca v6 ofrece **605 iconos**: los 600 dibujos de Bacano y cinco marcas sociales adicionales. Content guarda un ID estable como
|
|
4
|
+
`bacano:carrito` dentro de `contentJson`; nunca guarda SVG, HTML ni una URL
|
|
5
|
+
editable. Los dibujos propios heredan el color del texto. Instagram, Facebook,
|
|
6
|
+
WhatsApp, YouTube y TikTok usan imágenes procedentes de sus paquetes de marca,
|
|
7
|
+
sin recoloración. Sus nuevos IDs son `bacano:instagram`, `bacano:facebook`,
|
|
8
|
+
`bacano:whatsapp`, `bacano:youtube` y `bacano:tiktok`. Los cinco símbolos
|
|
9
|
+
genéricos anteriores mantienen sus IDs y se pueden recolorear. Cada par
|
|
10
|
+
comparte el nombre de la red; en el selector se distinguen por «Color editable»
|
|
11
|
+
y «Marca original». Consulta `provenance` si construyes tu propio selector.
|
|
12
|
+
|
|
13
|
+
## Elegir el ID desde un agente
|
|
14
|
+
|
|
15
|
+
Con un permiso temporal de Content, consulta las referencias antes de crear un
|
|
16
|
+
tipo o una entrada:
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
const references = await content.getReferences();
|
|
20
|
+
const icon = references.icons.find((item) => item.id === "bacano:carrito");
|
|
21
|
+
if (!icon) throw new Error("El icono no está disponible en Bacano");
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`icons` trae `id`, `concept`, `label`, `category`, `keywords` y `provenance`.
|
|
25
|
+
Dos iconos pueden tener el mismo nombre: usa el ID para distinguirlos y
|
|
26
|
+
`provenance` para saber si permiten cambiar el color. No inventes IDs. Define
|
|
27
|
+
un campo `{ key: "icono", label: "Icono",
|
|
28
|
+
type: "icon", sortOrder: 1 }` en un tipo editorial y envía el ID como valor:
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
await content.createEntry({
|
|
32
|
+
contentType: "beneficio",
|
|
33
|
+
key: "entrega_segura",
|
|
34
|
+
name: "Entrega segura",
|
|
35
|
+
locale: "es-CO",
|
|
36
|
+
content: { icono: icon.id, titulo: "Entrega segura" },
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Los iconos son válidos en entradas, componentes, filas repetibles y bloques
|
|
41
|
+
adicionales de producto. No son un tipo de ficha técnica. Los ID desconocidos,
|
|
42
|
+
URLs, SVG y HTML se rechazan al guardar.
|
|
43
|
+
|
|
44
|
+
## Mostrar el icono en una web
|
|
45
|
+
|
|
46
|
+
```tsx
|
|
47
|
+
import { BacanoIcon } from "@bacano/sdk/react/icon";
|
|
48
|
+
|
|
49
|
+
<BacanoIcon
|
|
50
|
+
id={String(entry.contentJson.icono)}
|
|
51
|
+
apiUrl="https://api.tudominio.com"
|
|
52
|
+
size={28}
|
|
53
|
+
className="text-blue-600"
|
|
54
|
+
decorative
|
|
55
|
+
/>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`BacanoIcon` valida el ID. Para dibujos propios usa `mask-image` con
|
|
59
|
+
`currentColor`; para las cinco marcas usa `background-image` y conserva sus
|
|
60
|
+
colores. Solo solicita el archivo de cada icono renderizado: no importa los
|
|
61
|
+
605 assets al bundle.
|
|
62
|
+
Si el icono comunica información por sí mismo, usa `decorative={false}` y
|
|
63
|
+
proporciona `label`. Para una web sin React:
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
import { resolveBacanoIcon } from "@bacano/sdk/icons";
|
|
67
|
+
|
|
68
|
+
const icon = resolveBacanoIcon(
|
|
69
|
+
entry.contentJson.icono,
|
|
70
|
+
"https://api.tudominio.com",
|
|
71
|
+
);
|
|
72
|
+
// icon?.url es una URL pública de asset solo para IDs conocidos.
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Para consultar un ID sin configurar la URL de la API, usa
|
|
76
|
+
`getBacanoIcon(id)`. Devuelve sus metadatos o `null`. Si `resolveBacanoIcon`
|
|
77
|
+
recibe un ID desconocido o una URL base vacía, también devuelve `null`.
|
|
78
|
+
Importa estas funciones desde `@bacano/sdk/icons` y el componente desde
|
|
79
|
+
`@bacano/sdk/react/icon`: así una web que no usa iconos no incluye el catálogo
|
|
80
|
+
en sus entradas generales del SDK.
|
|
81
|
+
|
|
82
|
+
Para los dibujos propios en una web sin React:
|
|
83
|
+
|
|
84
|
+
```css
|
|
85
|
+
.bacano-icon {
|
|
86
|
+
display: inline-block;
|
|
87
|
+
width: 1.5em;
|
|
88
|
+
height: 1.5em;
|
|
89
|
+
background: currentColor;
|
|
90
|
+
mask: var(--bacano-icon-url) center / contain no-repeat;
|
|
91
|
+
-webkit-mask: var(--bacano-icon-url) center / contain no-repeat;
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
El sitio coloca `--bacano-icon-url: url("<icon.url>")` en el elemento. Si
|
|
96
|
+
`icon.provenance === "official-brand"`, usa `<img src={icon.url}>` o una imagen
|
|
97
|
+
de fondo con `contain`, sin `mask` ni `currentColor`; dale un nombre accesible
|
|
98
|
+
si el icono no es decorativo. Usa las marcas para enlazar a los perfiles o
|
|
99
|
+
contenidos correspondientes y respeta sus normas de uso.
|
|
100
|
+
También puedes usar `listBacanoIcons()` para construir una lista local de
|
|
101
|
+
opciones; esta función entrega metadatos, no los archivos. Los assets se
|
|
102
|
+
sirven por `/assets/icons/v6/<asset>` con permiso de origen cruzado. Mantén
|
|
103
|
+
el `apiUrl` del SDK apuntando a la API pública de Bacano, no a Hasura.
|
|
104
|
+
|
|
105
|
+
## Publicación y compatibilidad
|
|
106
|
+
|
|
107
|
+
Primero despliega API/assets y la migración de `content_field_types`; después
|
|
108
|
+
el SDK y el editor. Una web antigua verá el ID en `contentJson` aunque todavía
|
|
109
|
+
no dibuje el icono. Los IDs publicados no se reutilizan ni se retiran. Los diez SVG de
|
|
110
|
+
la aprobación visual inicial siguen en `apps/frontend/public/iconos-muestra`
|
|
111
|
+
solo como revisión; la fuente servida por la API es
|
|
112
|
+
`apps/api/src/assets/icons/v6`. La API conserva las rutas v1, v2, v3 y v4 para webs que
|
|
113
|
+
todavía usan los catálogos anteriores.
|
|
@@ -73,8 +73,8 @@ console.log(context.companyId, context.scopes, context.expiresAt);
|
|
|
73
73
|
El cliente ofrece:
|
|
74
74
|
|
|
75
75
|
- `getContext()` para confirmar empresa, alcance y vencimiento.
|
|
76
|
-
- `getReferences()` para consultar categorías, subcategorías, listas de opciones
|
|
77
|
-
|
|
76
|
+
- `getReferences()` para consultar categorías, subcategorías, listas de opciones,
|
|
77
|
+
unidades de medida e iconos Bacano válidos.
|
|
78
78
|
- `listTypes()` y `getType(idOrKey)`.
|
|
79
79
|
- `createType(input)` y `updateType(idOrKey, input)`.
|
|
80
80
|
- `inspectLifecycle(idOrKey, operation)`.
|
|
@@ -98,6 +98,12 @@ El cliente ofrece:
|
|
|
98
98
|
`reorderProductBlocks(productId, input)` y
|
|
99
99
|
`retireProductBlock(productId, blockId, expectedUpdatedAt)`.
|
|
100
100
|
|
|
101
|
+
Para campos editoriales `type: "icon"`, consulta `getReferences().icons` y
|
|
102
|
+
guarda uno de sus IDs (por ejemplo `bacano:carrito`) en el contenido. No envíes
|
|
103
|
+
SVG ni URL. La validación también cubre componentes y repetibles; las fichas
|
|
104
|
+
técnicas no admiten este tipo. [CONTENT_ICONS.md](CONTENT_ICONS.md) explica
|
|
105
|
+
cómo renderizarlo en la web sin descargar los 605 archivos de icono.
|
|
106
|
+
|
|
101
107
|
## Bloques adicionales de un producto
|
|
102
108
|
|
|
103
109
|
Al generar un acceso con `product_content:manage`, indica de 1 a 50 IDs de
|
package/README.md
CHANGED
|
@@ -38,6 +38,7 @@ import { createContentManagementClient } from "@bacano/sdk/content-management";
|
|
|
38
38
|
```
|
|
39
39
|
|
|
40
40
|
Lee [`CONTENT_TYPE_MANAGEMENT.md`](./CONTENT_TYPE_MANAGEMENT.md) antes de usarlo.
|
|
41
|
+
Para iconos editoriales, consulta [`CONTENT_ICONS.md`](./CONTENT_ICONS.md).
|
|
41
42
|
La guía contiene el flujo de autorización, contratos de campos, entradas y
|
|
42
43
|
media, estados, referencias, cambios destructivos y límites de seguridad. Con
|
|
43
44
|
el scope `content_media:upload`, un agente puede buscar imágenes existentes y
|
package/STOREFRONT_PAYMENTS.md
CHANGED
|
@@ -194,6 +194,14 @@ Referencia oficial: [API Openpay Colombia](https://documents.openpay.co/api/inde
|
|
|
194
194
|
El comprador usa los medios habilitados por Openpay dentro de su página
|
|
195
195
|
alojada; el SDK no pide tarjeta, PSE ni efectivo de forma separada.
|
|
196
196
|
|
|
197
|
+
Si el storefront muestra el logotipo de Openpay, hacerlo solo para la opción
|
|
198
|
+
devuelta por `getPaymentOptions()` con `gatewayCode === "OPENPAY"`. Es la marca
|
|
199
|
+
de la pasarela, no otro método seleccionable; puede preceder a los logotipos
|
|
200
|
+
de redes en la misma tarjeta. Mostrar logos de tarjetas, PSE o pago en tienda
|
|
201
|
+
solo cuando su disponibilidad esté confirmada para esa integración y ambiente:
|
|
202
|
+
la lista efectiva de medios pertenece al checkout alojado. El logotipo debe
|
|
203
|
+
tener un nombre accesible y no sustituye la descripción ni el estado del método.
|
|
204
|
+
|
|
197
205
|
### Diagnóstico rápido
|
|
198
206
|
|
|
199
207
|
| Síntoma | Acción segura |
|
|
@@ -135,6 +135,19 @@ The first visible product image may use eager loading/high priority. Images
|
|
|
135
135
|
below the fold and recommendation blocks must remain lazy. Storefronts must not
|
|
136
136
|
append storage transformation query parameters manually.
|
|
137
137
|
|
|
138
|
+
For image carousels, inspect the mobile network trace rather than assuming
|
|
139
|
+
`loading="lazy"` prevents every offscreen request. Some carousel layouts still
|
|
140
|
+
cause all slides to download. Keep the active and nearby slides ready, load
|
|
141
|
+
additional slides as the user navigates, and verify that moving directly to a
|
|
142
|
+
distant thumbnail still displays its image. Recommendations should not download
|
|
143
|
+
every card image before the section is viewed.
|
|
144
|
+
|
|
145
|
+
Test the product page and its cart/gallery interactions in the mobile browsers
|
|
146
|
+
the storefront supports. If older Safari versions are in scope, do not rely on
|
|
147
|
+
unpolyfilled newer array methods such as `toSorted()`; a copied array followed
|
|
148
|
+
by `sort()` is a compatible alternative. A minified browser error alone is not
|
|
149
|
+
enough to identify the failing component: reproduce it and inspect the stack.
|
|
150
|
+
|
|
138
151
|
### Banners and full-width heroes
|
|
139
152
|
|
|
140
153
|
Editorial `ContentMedia` images additionally expose:
|
|
@@ -261,6 +274,24 @@ If the storefront refreshes public configuration in the browser, it must keep
|
|
|
261
274
|
the static bootstrap while the refresh is pending and only replace it when the
|
|
262
275
|
payload actually changes. Configuration failure must not blank the storefront.
|
|
263
276
|
|
|
277
|
+
## Sitemap and robots delivery
|
|
278
|
+
|
|
279
|
+
Static exports often publish all non-HTML files with the same cache policy.
|
|
280
|
+
Keep long-lived `immutable` caching for fingerprinted assets, **not** for stable
|
|
281
|
+
discovery URLs such as `/sitemap.xml` and `/robots.txt`. Serve those files with
|
|
282
|
+
a short, revalidating TTL and invalidate the CDN on publication so a rebuilt
|
|
283
|
+
catalog can be discovered. This is a hosting rule, not an SDK request.
|
|
284
|
+
|
|
285
|
+
After deployment, check the canonical public URL with a real `GET`: status
|
|
286
|
+
`200`, suitable content type, valid XML, expected URL count and canonical
|
|
287
|
+
hosts. Compare that count with the generated routes and catalog snapshot;
|
|
288
|
+
confirm that `robots.txt` names the sitemap and does not block it. A sitemap
|
|
289
|
+
that opens in a browser can still have a delivery or search-console problem.
|
|
290
|
+
If Search Console reports that it could not fetch the file, compare its last
|
|
291
|
+
attempt with a live URL inspection before changing the XML. Once a delivery
|
|
292
|
+
issue is fixed, submit the sitemap again as described in
|
|
293
|
+
[Google's sitemap troubleshooting guide](https://support.google.com/webmasters/answer/7451001).
|
|
294
|
+
|
|
264
295
|
Mount third-party authentication only on routes that require it, such as
|
|
265
296
|
checkout, sign-in and customer account pages. Public catalog and product pages
|
|
266
297
|
must not download an authentication runtime merely because buyer accounts are
|
|
@@ -304,6 +335,10 @@ not verified instead of inferring it from source code.
|
|
|
304
335
|
- [ ] `srcset` and `sizes` are present on catalog and product media.
|
|
305
336
|
- [ ] Live refresh is batched, debounced and failure-safe.
|
|
306
337
|
- [ ] Recommendations and below-fold media do not block the primary content.
|
|
338
|
+
- [ ] Carousels do not fetch every offscreen image on mobile; supported Safari
|
|
339
|
+
versions can navigate the product gallery after using the cart.
|
|
340
|
+
- [ ] Public sitemap and robots responses are current and are not cached as
|
|
341
|
+
immutable assets.
|
|
307
342
|
- [ ] Mobile and desktop Lighthouse runs show no material layout shift.
|
|
308
343
|
- [ ] A production trace confirms no duplicated catalog, shipping or website
|
|
309
344
|
bootstrap calls during the first navigation.
|
|
@@ -3,7 +3,7 @@ export type ContentManagementTypeKind = "entry" | "component";
|
|
|
3
3
|
export type ContentManagementTypeStatus = "draft" | "active" | "archived";
|
|
4
4
|
export type ContentManagementTypeUsage = "website_content" | "product_additional" | "product_specification";
|
|
5
5
|
export type ContentManagementScope = "content_types:manage" | "content_entries:manage" | "content_media:upload" | "content_entries:publish" | "forms:manage" | "forms:publish" | "product_content:manage";
|
|
6
|
-
export type ContentManagementFieldType = "boolean" | "component" | "date" | "link" | "measure" | "media" | "number" | "reference" | "repeater" | "rich_text" | "rich_text_full" | "select" | "slug" | "text" | "textarea";
|
|
6
|
+
export type ContentManagementFieldType = "icon" | "boolean" | "component" | "date" | "link" | "measure" | "media" | "number" | "reference" | "repeater" | "rich_text" | "rich_text_full" | "select" | "slug" | "text" | "textarea";
|
|
7
7
|
export interface ContentManagementChildFieldInput {
|
|
8
8
|
id?: string | null;
|
|
9
9
|
key: string;
|
|
@@ -182,6 +182,14 @@ export interface ContentManagementImageUploadResult extends ContentManagementMed
|
|
|
182
182
|
reused: boolean;
|
|
183
183
|
}
|
|
184
184
|
export interface ContentManagementReferences {
|
|
185
|
+
icons: Array<{
|
|
186
|
+
id: string;
|
|
187
|
+
concept: string;
|
|
188
|
+
label: string;
|
|
189
|
+
category: string;
|
|
190
|
+
keywords: string[];
|
|
191
|
+
provenance: "original-bacano" | "official-brand";
|
|
192
|
+
}>;
|
|
185
193
|
categories: Array<{
|
|
186
194
|
code: string;
|
|
187
195
|
name: string;
|