webs-sdk 0.19.64 → 0.19.65
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/AGENTS.md +44 -0
- package/CLAUDE.md +80 -0
- package/README.md +513 -490
- package/dist/components/ARFilters/ARFilters.js +54 -54
- package/dist/components/ArtGenerator.js +141 -141
- package/dist/components/AvatarAI.js +14 -14
- package/dist/components/CookieConsent/constants.js +31 -31
- package/dist/components/CreativeFaceSwap.js +23 -23
- package/dist/components/GifsIa.js +76 -76
- package/dist/components/MemeGenerator.js +12 -12
- package/dist/components/PasswordReset/constants.js +33 -33
- package/dist/components/RecoveryPassword/constants.js +27 -27
- package/dist/components/SpinningWheel/SpinningWheel.js +7 -7
- package/dist/components/SpinningWheel/index.d.ts +1 -1
- package/dist/components/SpinningWheel/index.d.ts.map +1 -1
- package/dist/components/SpinningWheel/index.js +2 -1
- package/dist/components/SpinningWheel/index.js.map +1 -1
- package/dist/components/ui/ConfiguredMediaPlayer.d.ts +49 -0
- package/dist/components/ui/ConfiguredMediaPlayer.d.ts.map +1 -0
- package/dist/components/ui/ConfiguredMediaPlayer.js +111 -0
- package/dist/components/ui/ConfiguredMediaPlayer.js.map +1 -0
- package/dist/components/ui/badge.d.ts +1 -0
- package/dist/components/ui/badge.d.ts.map +1 -1
- package/dist/components/ui/badge.js +1 -1
- package/dist/components/ui/badge.js.map +1 -1
- package/dist/components/ui/compose-refs.d.ts +6 -0
- package/dist/components/ui/compose-refs.d.ts.map +1 -0
- package/dist/components/ui/compose-refs.js +57 -0
- package/dist/components/ui/compose-refs.js.map +1 -0
- package/dist/components/ui/dropdown-menu.d.ts +3 -1
- package/dist/components/ui/dropdown-menu.d.ts.map +1 -1
- package/dist/components/ui/dropdown-menu.js +2 -2
- package/dist/components/ui/dropdown-menu.js.map +1 -1
- package/dist/components/ui/index.d.ts +2 -0
- package/dist/components/ui/index.d.ts.map +1 -1
- package/dist/components/ui/index.js +2 -0
- package/dist/components/ui/index.js.map +1 -1
- package/dist/components/ui/media-player.d.ts +127 -0
- package/dist/components/ui/media-player.d.ts.map +1 -0
- package/dist/components/ui/media-player.js +1633 -0
- package/dist/components/ui/media-player.js.map +1 -0
- package/dist/components/ui/tooltip.d.ts +3 -1
- package/dist/components/ui/tooltip.d.ts.map +1 -1
- package/dist/components/ui/tooltip.js +2 -2
- package/dist/components/ui/tooltip.js.map +1 -1
- package/dist/components/ui/use-lazy-ref.d.ts +4 -0
- package/dist/components/ui/use-lazy-ref.d.ts.map +1 -0
- package/dist/components/ui/use-lazy-ref.js +45 -0
- package/dist/components/ui/use-lazy-ref.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/network.d.ts +12 -0
- package/dist/network.d.ts.map +1 -0
- package/dist/network.js +15 -0
- package/dist/network.js.map +1 -0
- package/dist/server.d.ts +54 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +74 -0
- package/dist/server.js.map +1 -0
- package/dist/types/media-chrome-store-types.d.ts +107 -0
- package/dist/types/media-chrome-store-types.d.ts.map +1 -0
- package/dist/types/media-chrome-store-types.js +3 -0
- package/dist/types/media-chrome-store-types.js.map +1 -0
- package/dist/utils/QRCode.d.ts +1 -0
- package/dist/utils/QRCode.d.ts.map +1 -0
- package/dist/utils/QRCode.js +2 -0
- package/dist/utils/QRCode.js.map +1 -0
- package/dist/utils/imageValidation.d.ts +6 -0
- package/dist/utils/imageValidation.d.ts.map +1 -0
- package/dist/utils/imageValidation.js +64 -0
- package/dist/utils/imageValidation.js.map +1 -0
- package/docs/CONFIGURED_MEDIA_PLAYER.md +40 -0
- package/docs/CORP_AUTH_USAGE.md +687 -0
- package/docs/EXAMPLES_WALLPAPERSNAME_IMPLEMENTATION.md +1445 -0
- package/docs/EXAMPLE_ENDPOINTS_COMUNICATION.md +55 -0
- package/docs/EXTERNAL_SDK_GUIDE.md +1340 -0
- package/docs/FOR_YOU_360_FACESWAP_FIX.md +400 -0
- package/docs/FOR_YOU_IMPLEMENTATION_GUIDE.md +1413 -0
- package/docs/FOR_YOU_QUIZ_ARCHITECTURE.md +753 -0
- package/docs/FOR_YOU_SDK_WALLPAPERSNAME_BUG.md +106 -0
- package/docs/FOR_YOU_WALLPAPERSNAME_ENHANCEMENT_PLAN.md +210 -0
- package/docs/LEGAL_USAGE.md +190 -0
- package/docs/STREAK_IMPLEMENTATION_GUIDE.md +430 -0
- package/package.json +106 -84
- package/public/spin2win/assets/border-afristream.svg +26 -26
- package/public/spin2win/assets/border-efc.svg +23 -23
- package/public/spin2win/assets/border-streetreel.svg +23 -23
- package/public/spin2win/assets/border-totalgym.svg +27 -27
- package/public/spin2win/assets/border-womantoday.svg +26 -26
- package/public/spin2win/assets/indicator-afristream.svg +28 -28
- package/public/spin2win/assets/indicator-efc.svg +29 -29
- package/public/spin2win/assets/indicator-streetreel.svg +29 -29
- package/public/spin2win/assets/indicator-totalgym.svg +29 -29
- package/public/spin2win/fonts/switzer/README.md +22 -22
- package/scripts/install-agent-skill.cjs +34 -0
- package/skills/webs-sdk-package/SKILL.md +11 -0
- package/skills/webs-sdk-package/references/components.md +30 -0
- package/skills/webs-sdk-package/references/integration.md +32 -0
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
# CreativeFaceSwap — Ajustes necesarios en 360vrtube
|
|
2
|
+
|
|
3
|
+
> **SDK v0.18.83+** requerido
|
|
4
|
+
> Afecta al componente `creativeFaceSwap` dentro de `ForYouPage`
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Contexto
|
|
9
|
+
|
|
10
|
+
En `v0.18.83` se han corregido dos bugs del componente `CreativeFaceSwap` que se manifestaban
|
|
11
|
+
en el proyecto 360vrtube:
|
|
12
|
+
|
|
13
|
+
| # | Síntoma | Causa |
|
|
14
|
+
|---|---------|-------|
|
|
15
|
+
| Bug 1 | Los ejemplos del carrusel izquierdo no se muestran | `contentsConfig` no estaba conectado al componente |
|
|
16
|
+
| Bug 2 | `"Unexpected token '<'..."` al pulsar CREATE | El endpoint devuelve HTML (404/500) en lugar de JSON |
|
|
17
|
+
|
|
18
|
+
Ambos bugs requieren **cambios en el proyecto 360vrtube** además de actualizar el SDK.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Paso 1 — Actualizar el SDK
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm install webs-sdk@0.18.83
|
|
26
|
+
# o
|
|
27
|
+
yarn add webs-sdk@0.18.83
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Paso 2 — Bug 1: conectar los ejemplos con `contentsConfig`
|
|
33
|
+
|
|
34
|
+
### ¿Qué cambia?
|
|
35
|
+
|
|
36
|
+
Antes se pasaba `config.contents[]` dentro del objeto `config` de la feature. Eso funciona para
|
|
37
|
+
cargar el **listado** del componente principal (generate), pero **no tiene efecto** en los
|
|
38
|
+
ejemplos del carrusel. Ahora hay una prop específica para ello: **`contentsConfig`**.
|
|
39
|
+
|
|
40
|
+
### Cómo debe quedar la config en 360vrtube
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
// ❌ ANTES — los ejemplos no se cargan
|
|
44
|
+
creativeFaceSwap: {
|
|
45
|
+
card: {
|
|
46
|
+
desktopImage: '/images/faceswap-card.jpg',
|
|
47
|
+
ctaColor: '#FF5500',
|
|
48
|
+
},
|
|
49
|
+
config: {
|
|
50
|
+
userId: USER_ID,
|
|
51
|
+
userLogin: USER_LOGIN,
|
|
52
|
+
wid: WEBSITE_ID,
|
|
53
|
+
apiEndpoints: {
|
|
54
|
+
generate: '/api/face-swap/generate',
|
|
55
|
+
progress: '/api/face-swap/progress',
|
|
56
|
+
getImage: '/api/face-swap/get-image',
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
// ← antes se intentaba pasar contents aquí dentro, no funciona
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ✅ AHORA — usar contentsConfig para los ejemplos
|
|
63
|
+
creativeFaceSwap: {
|
|
64
|
+
card: {
|
|
65
|
+
desktopImage: '/images/faceswap-card.jpg',
|
|
66
|
+
ctaColor: '#FF5500',
|
|
67
|
+
},
|
|
68
|
+
config: {
|
|
69
|
+
userId: USER_ID,
|
|
70
|
+
userLogin: USER_LOGIN,
|
|
71
|
+
wid: WEBSITE_ID,
|
|
72
|
+
apiEndpoints: {
|
|
73
|
+
generate: '/api/face-swap/generate',
|
|
74
|
+
progress: '/api/face-swap/progress',
|
|
75
|
+
getImage: '/api/face-swap/get-image',
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
// ← prop nueva: carga los ejemplos del carrusel izquierdo
|
|
79
|
+
contentsConfig: {
|
|
80
|
+
apiBaseUrl: 'https://api.360vrtube.com', // ← ajustar a la URL real
|
|
81
|
+
locale: 'en',
|
|
82
|
+
website_id: WEBSITE_ID,
|
|
83
|
+
contents: [
|
|
84
|
+
{
|
|
85
|
+
preset: 'getGlobalContentsByIDs',
|
|
86
|
+
includeIds: [104557, 100180, 98423, 97811], // ← IDs de tus ejemplos
|
|
87
|
+
},
|
|
88
|
+
// también puedes combinar con tags:
|
|
89
|
+
// { preset: 'getGlobalContentsByTags', tags: ['faceswap-examples'] },
|
|
90
|
+
],
|
|
91
|
+
},
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Alternativa: tag simple
|
|
96
|
+
|
|
97
|
+
Si los ejemplos están en un solo tag sin necesidad de IDs concretos:
|
|
98
|
+
|
|
99
|
+
```tsx
|
|
100
|
+
contentsConfig: {
|
|
101
|
+
apiBaseUrl: 'https://api.360vrtube.com',
|
|
102
|
+
locale: 'en',
|
|
103
|
+
tags: 'faceswap-examples', // ← tag de los ejemplos en vuestro CMS
|
|
104
|
+
},
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Prioridad de ejemplos
|
|
108
|
+
|
|
109
|
+
El SDK aplica este orden de prioridad (el primero que tenga datos gana):
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
1. examples[] (array estático pasado directamente)
|
|
113
|
+
2. contentsConfig (fetch interno — NUEVO)
|
|
114
|
+
3. examplesTag (fetch simple por tag dentro del componente)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Qué debe tener cada item en el CMS para que aparezca como ejemplo
|
|
118
|
+
|
|
119
|
+
El SDK mapea los items recibidos a `FaceSwapExample` de la siguiente forma:
|
|
120
|
+
|
|
121
|
+
| Campo del item | Se usa como |
|
|
122
|
+
|----------------|-------------|
|
|
123
|
+
| `thumbnail` | Imagen del ejemplo en el carrusel |
|
|
124
|
+
| `images.img1` | Imagen del ejemplo (fallback si no hay thumbnail) |
|
|
125
|
+
| `imageUrl` | Imagen del ejemplo (segundo fallback) |
|
|
126
|
+
| `title` | Descripción debajo de la imagen |
|
|
127
|
+
| `description` | Descripción (fallback si no hay title) |
|
|
128
|
+
|
|
129
|
+
> ⚠️ Si el item no tiene imagen (`thumbnail`, `images.img1` ni `imageUrl`), **se descarta**
|
|
130
|
+
> y no aparecerá en el carrusel.
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Paso 3 — Bug 2: crear las rutas API del endpoint generate
|
|
135
|
+
|
|
136
|
+
### ¿Qué ocurría?
|
|
137
|
+
|
|
138
|
+
Al pulsar el botón **CREATE**, el SDK llamaba a `/api/face-swap/generate` (u otra ruta).
|
|
139
|
+
Si esa ruta no existe en el proyecto Next.js, el servidor devuelve una página HTML de 404
|
|
140
|
+
en lugar de JSON. El SDK intentaba `response.json()` sobre ese HTML y crasheaba con:
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Fix en el SDK (ya incluido en v0.18.83)
|
|
147
|
+
|
|
148
|
+
El SDK ahora detecta el `Content-Type` de la respuesta antes de parsear. Si no es JSON,
|
|
149
|
+
muestra un mensaje de error claro en la UI:
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
HTTP 404: The generate endpoint returned an unexpected response.
|
|
153
|
+
Check that the API route exists and is correctly configured in this project.
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Acción requerida en 360vrtube: crear las rutas API
|
|
157
|
+
|
|
158
|
+
Necesitáis crear **tres rutas API** en el proyecto Next.js que hagan de proxy hacia vuestro
|
|
159
|
+
servicio de generación de imágenes. El SDK llama a estas rutas directamente (son `config.apiEndpoints`).
|
|
160
|
+
|
|
161
|
+
#### App Router (`app/api/...`)
|
|
162
|
+
|
|
163
|
+
**`app/api/face-swap/generate/route.ts`**
|
|
164
|
+
|
|
165
|
+
```ts
|
|
166
|
+
import { NextRequest, NextResponse } from 'next/server'
|
|
167
|
+
|
|
168
|
+
const FACESWAP_API = process.env.FACESWAP_API_URL // ← URL interna del servicio
|
|
169
|
+
|
|
170
|
+
export async function POST(req: NextRequest) {
|
|
171
|
+
try {
|
|
172
|
+
const body = await req.json()
|
|
173
|
+
const upstream = await fetch(`${FACESWAP_API}/generate`, {
|
|
174
|
+
method: 'POST',
|
|
175
|
+
headers: { 'Content-Type': 'application/json' },
|
|
176
|
+
body: JSON.stringify(body),
|
|
177
|
+
})
|
|
178
|
+
const data = await upstream.json()
|
|
179
|
+
return NextResponse.json(data, { status: upstream.status })
|
|
180
|
+
} catch (err) {
|
|
181
|
+
console.error('[face-swap/generate]', err)
|
|
182
|
+
return NextResponse.json({ success: false, error: 'Internal server error' }, { status: 500 })
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**`app/api/face-swap/progress/route.ts`**
|
|
188
|
+
|
|
189
|
+
```ts
|
|
190
|
+
import { NextRequest, NextResponse } from 'next/server'
|
|
191
|
+
|
|
192
|
+
const FACESWAP_API = process.env.FACESWAP_API_URL
|
|
193
|
+
|
|
194
|
+
export async function POST(req: NextRequest) {
|
|
195
|
+
try {
|
|
196
|
+
const body = await req.json()
|
|
197
|
+
const upstream = await fetch(`${FACESWAP_API}/progress`, {
|
|
198
|
+
method: 'POST',
|
|
199
|
+
headers: { 'Content-Type': 'application/json' },
|
|
200
|
+
body: JSON.stringify(body),
|
|
201
|
+
})
|
|
202
|
+
const data = await upstream.json()
|
|
203
|
+
return NextResponse.json(data, { status: upstream.status })
|
|
204
|
+
} catch (err) {
|
|
205
|
+
console.error('[face-swap/progress]', err)
|
|
206
|
+
return NextResponse.json({ success: false, error: 'Internal server error' }, { status: 500 })
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**`app/api/face-swap/get-image/route.ts`**
|
|
212
|
+
|
|
213
|
+
```ts
|
|
214
|
+
import { NextRequest, NextResponse } from 'next/server'
|
|
215
|
+
|
|
216
|
+
const FACESWAP_API = process.env.FACESWAP_API_URL
|
|
217
|
+
|
|
218
|
+
export async function POST(req: NextRequest) {
|
|
219
|
+
try {
|
|
220
|
+
const body = await req.json()
|
|
221
|
+
const upstream = await fetch(`${FACESWAP_API}/get-image`, {
|
|
222
|
+
method: 'POST',
|
|
223
|
+
headers: { 'Content-Type': 'application/json' },
|
|
224
|
+
body: JSON.stringify(body),
|
|
225
|
+
})
|
|
226
|
+
const data = await upstream.json()
|
|
227
|
+
return NextResponse.json(data, { status: upstream.status })
|
|
228
|
+
} catch (err) {
|
|
229
|
+
console.error('[face-swap/get-image]', err)
|
|
230
|
+
return NextResponse.json({ success: false, error: 'Internal server error' }, { status: 500 })
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
#### Pages Router (`pages/api/...`) — si el proyecto usa Pages Router
|
|
236
|
+
|
|
237
|
+
```ts
|
|
238
|
+
// pages/api/face-swap/generate.ts
|
|
239
|
+
import type { NextApiRequest, NextApiResponse } from 'next'
|
|
240
|
+
|
|
241
|
+
const FACESWAP_API = process.env.FACESWAP_API_URL
|
|
242
|
+
|
|
243
|
+
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
244
|
+
if (req.method !== 'POST') return res.status(405).end()
|
|
245
|
+
try {
|
|
246
|
+
const upstream = await fetch(`${FACESWAP_API}/generate`, {
|
|
247
|
+
method: 'POST',
|
|
248
|
+
headers: { 'Content-Type': 'application/json' },
|
|
249
|
+
body: JSON.stringify(req.body),
|
|
250
|
+
})
|
|
251
|
+
const data = await upstream.json()
|
|
252
|
+
res.status(upstream.status).json(data)
|
|
253
|
+
} catch {
|
|
254
|
+
res.status(500).json({ success: false, error: 'Internal server error' })
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
Repetir el mismo patrón para `progress.ts` y `get-image.ts`.
|
|
260
|
+
|
|
261
|
+
### Variable de entorno
|
|
262
|
+
|
|
263
|
+
Añadir al `.env.local`:
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
FACESWAP_API_URL=https://tu-servicio-faceswap.com # URL del servicio real
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## Paso 4 — Configuración completa de referencia
|
|
272
|
+
|
|
273
|
+
Este es el bloque final con los dos fixes aplicados:
|
|
274
|
+
|
|
275
|
+
```tsx
|
|
276
|
+
import { ForYouPage } from 'webs-sdk'
|
|
277
|
+
import type { ForYouFeatures } from 'webs-sdk'
|
|
278
|
+
|
|
279
|
+
const features: ForYouFeatures = {
|
|
280
|
+
creativeFaceSwap: {
|
|
281
|
+
card: {
|
|
282
|
+
desktopImage: '/images/faceswap-card-desktop.jpg',
|
|
283
|
+
mobileImage: '/images/faceswap-card-mobile.jpg',
|
|
284
|
+
ctaColor: '#FF5500',
|
|
285
|
+
backgroundColor: '#F9F9F9',
|
|
286
|
+
},
|
|
287
|
+
|
|
288
|
+
// Endpoints de generación — rutas API del proyecto
|
|
289
|
+
config: {
|
|
290
|
+
userId: USER_ID,
|
|
291
|
+
userLogin: USER_LOGIN,
|
|
292
|
+
wid: WEBSITE_ID,
|
|
293
|
+
apiEndpoints: {
|
|
294
|
+
generate: '/api/face-swap/generate', // POST → crea el job
|
|
295
|
+
progress: '/api/face-swap/progress', // POST → polling del progreso
|
|
296
|
+
getImage: '/api/face-swap/get-image', // POST → obtiene la imagen final
|
|
297
|
+
},
|
|
298
|
+
},
|
|
299
|
+
|
|
300
|
+
// Ejemplos del carrusel izquierdo — Bug 1 fix
|
|
301
|
+
contentsConfig: {
|
|
302
|
+
apiBaseUrl: 'https://api.360vrtube.com',
|
|
303
|
+
locale: 'en',
|
|
304
|
+
website_id: WEBSITE_ID,
|
|
305
|
+
contents: [
|
|
306
|
+
{
|
|
307
|
+
preset: 'getGlobalContentsByIDs',
|
|
308
|
+
includeIds: [104557, 100180, 98423], // ← IDs reales de los ejemplos
|
|
309
|
+
},
|
|
310
|
+
],
|
|
311
|
+
},
|
|
312
|
+
|
|
313
|
+
// Textos opcionales (override sobre los del SDK)
|
|
314
|
+
texts: {
|
|
315
|
+
uploadTitle: 'Your photo',
|
|
316
|
+
createButton: 'GENERATE',
|
|
317
|
+
examplesTitle: 'Try these examples',
|
|
318
|
+
},
|
|
319
|
+
|
|
320
|
+
// Callbacks opcionales
|
|
321
|
+
onGenerationComplete: (imageUrl) => {
|
|
322
|
+
console.log('Generated:', imageUrl)
|
|
323
|
+
},
|
|
324
|
+
onError: (error) => {
|
|
325
|
+
console.error('FaceSwap error:', error)
|
|
326
|
+
},
|
|
327
|
+
},
|
|
328
|
+
|
|
329
|
+
// ... resto de features
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
export default function ForYouSection() {
|
|
333
|
+
return (
|
|
334
|
+
<ForYouPage
|
|
335
|
+
locale="en"
|
|
336
|
+
features={features}
|
|
337
|
+
/>
|
|
338
|
+
)
|
|
339
|
+
}
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## Checklist de verificación
|
|
345
|
+
|
|
346
|
+
Antes de hacer deploy, verificar:
|
|
347
|
+
|
|
348
|
+
- [ ] SDK actualizado a `v0.18.83` o superior (`npm ls webs-sdk`)
|
|
349
|
+
- [ ] `contentsConfig` añadido con los IDs o tags correctos de los ejemplos
|
|
350
|
+
- [ ] Los items del CMS tienen `thumbnail` o imagen equivalente
|
|
351
|
+
- [ ] Ruta `/api/face-swap/generate` existe y responde `{ success: true, data: { md5, i_jobs } }`
|
|
352
|
+
- [ ] Ruta `/api/face-swap/progress` existe y responde `{ success: true, data: { pct: 0-100 } }`
|
|
353
|
+
- [ ] Ruta `/api/face-swap/get-image` existe y responde `{ success: true, data: { s3_image: '...' } }`
|
|
354
|
+
- [ ] Variable de entorno `FACESWAP_API_URL` configurada en `.env.local` y en producción
|
|
355
|
+
- [ ] El carrusel de ejemplos se muestra con imágenes al abrir la feature
|
|
356
|
+
- [ ] Al pulsar CREATE con foto + descripción, el proceso arranca sin errores
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## Respuesta esperada de cada endpoint
|
|
361
|
+
|
|
362
|
+
El SDK espera estas estructuras JSON. Si el servicio devuelve algo diferente,
|
|
363
|
+
hay que adaptar la ruta proxy para transformar la respuesta.
|
|
364
|
+
|
|
365
|
+
### `/generate`
|
|
366
|
+
```json
|
|
367
|
+
{
|
|
368
|
+
"success": true,
|
|
369
|
+
"data": {
|
|
370
|
+
"md5": "abc123def456",
|
|
371
|
+
"i_jobs": 1
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### `/progress`
|
|
377
|
+
```json
|
|
378
|
+
{
|
|
379
|
+
"success": true,
|
|
380
|
+
"data": {
|
|
381
|
+
"pct": 45
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### `/get-image`
|
|
387
|
+
```json
|
|
388
|
+
{
|
|
389
|
+
"success": true,
|
|
390
|
+
"data": {
|
|
391
|
+
"s3_image": "https%3A%2F%2Fcdn.example.com%2Fresult.jpg"
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
> Nota: `s3_image` debe estar **URL-encoded**. El SDK aplica `decodeURIComponent()` internamente.
|
|
397
|
+
|
|
398
|
+
---
|
|
399
|
+
|
|
400
|
+
*Generado automáticamente por el SDK — webs_sdk v0.18.83 — 2026-06-30*
|