@pcreative/commerce-contract 1.3.2 → 1.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/adapters/api.js +65 -0
- package/src/index.d.ts +83 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pcreative/commerce-contract",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.4",
|
|
4
4
|
"description": "Contrato de datos de commerce: los tipos que consume un tema y los adaptadores que los resuelven. Sin dependencias ni SDK del backend.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"type": "module",
|
package/src/adapters/api.js
CHANGED
|
@@ -225,6 +225,7 @@ export function createCommerce({
|
|
|
225
225
|
if (params.q) qs.set("q", String(params.q))
|
|
226
226
|
if (params.category) qs.set("categoria_handle", params.category)
|
|
227
227
|
if (params.categoryId) qs.set("categoria", params.categoryId)
|
|
228
|
+
if (params.type) qs.set("tipo", params.type)
|
|
228
229
|
if (params.ids?.length) qs.set("ids", params.ids.join(","))
|
|
229
230
|
if (ORDEN_DEL_CONTRATO[params.sort]) qs.set("orden", ORDEN_DEL_CONTRATO[params.sort])
|
|
230
231
|
const r = await api(`/tienda/productos?${qs}`)
|
|
@@ -593,6 +594,22 @@ export function createCommerce({
|
|
|
593
594
|
throw e
|
|
594
595
|
}
|
|
595
596
|
},
|
|
597
|
+
async getLicenses(orderId) {
|
|
598
|
+
try {
|
|
599
|
+
const { licencias } = await api(`/tienda/pedidos/${encodeURIComponent(orderId)}/licencias`)
|
|
600
|
+
return (licencias ?? []).map((l) => ({
|
|
601
|
+
key: l.key,
|
|
602
|
+
status: l.status,
|
|
603
|
+
title: l.title ?? null,
|
|
604
|
+
sites: Number(l.sites ?? 0),
|
|
605
|
+
limit: Number(l.limit ?? 1),
|
|
606
|
+
supportedUntil: l.supportedUntil ? String(l.supportedUntil).slice(0, 10) : null,
|
|
607
|
+
}))
|
|
608
|
+
} catch (e) {
|
|
609
|
+
if (e.status === 404) return []
|
|
610
|
+
throw e
|
|
611
|
+
}
|
|
612
|
+
},
|
|
596
613
|
async getCodes(orderId) {
|
|
597
614
|
try {
|
|
598
615
|
const { codigos } = await api(`/tienda/pedidos/${encodeURIComponent(orderId)}/codigos`)
|
|
@@ -609,6 +626,54 @@ export function createCommerce({
|
|
|
609
626
|
)
|
|
610
627
|
return codigo ?? null
|
|
611
628
|
},
|
|
629
|
+
newsletter: {
|
|
630
|
+
async subscribe(email, consent = {}) {
|
|
631
|
+
await api("/tienda/boletin", {
|
|
632
|
+
method: "POST",
|
|
633
|
+
body: {
|
|
634
|
+
email,
|
|
635
|
+
texto: consent.text,
|
|
636
|
+
version: consent.version,
|
|
637
|
+
idioma: consent.locale,
|
|
638
|
+
origen: consent.source,
|
|
639
|
+
ip: consent.ip,
|
|
640
|
+
navegador: consent.userAgent,
|
|
641
|
+
},
|
|
642
|
+
})
|
|
643
|
+
return { status: "pendiente" }
|
|
644
|
+
},
|
|
645
|
+
async confirm(token) {
|
|
646
|
+
try {
|
|
647
|
+
await api("/tienda/boletin/confirmar", { method: "POST", body: { token } })
|
|
648
|
+
return true
|
|
649
|
+
} catch (e) {
|
|
650
|
+
if (e.status === 400) return false
|
|
651
|
+
throw e
|
|
652
|
+
}
|
|
653
|
+
},
|
|
654
|
+
async unsubscribe(token) {
|
|
655
|
+
await api("/tienda/boletin/baja", { method: "POST", body: { token } })
|
|
656
|
+
return true
|
|
657
|
+
},
|
|
658
|
+
},
|
|
659
|
+
async applyAsAuthor(a) {
|
|
660
|
+
const vende = [...new Set((a.sells ?? []).filter((x) => x === "tema" || x === "extension"))]
|
|
661
|
+
const r = await api("/tienda/autores/solicitudes", {
|
|
662
|
+
method: "POST",
|
|
663
|
+
body: {
|
|
664
|
+
nombre: a.name,
|
|
665
|
+
email: a.email,
|
|
666
|
+
portafolio: a.portfolio,
|
|
667
|
+
vende: vende.length === 2 ? ["los-dos"] : vende,
|
|
668
|
+
slug: a.handle,
|
|
669
|
+
pais: a.country,
|
|
670
|
+
web: a.website,
|
|
671
|
+
stacks: a.stacks,
|
|
672
|
+
experiencia: a.experience,
|
|
673
|
+
},
|
|
674
|
+
})
|
|
675
|
+
return { id: r.id }
|
|
676
|
+
},
|
|
612
677
|
async getAuthor(handle) {
|
|
613
678
|
try {
|
|
614
679
|
const { autor } = await api(`/tienda/autores/${encodeURIComponent(handle)}`)
|
package/src/index.d.ts
CHANGED
|
@@ -78,6 +78,11 @@ export interface WithdrawalState {
|
|
|
78
78
|
pais: string
|
|
79
79
|
dias: number | null
|
|
80
80
|
diasHabiles: boolean
|
|
81
|
+
/**
|
|
82
|
+
* El plazo cuenta desde que se recibe. Con `caduca` en null y esto en true,
|
|
83
|
+
* todavía no ha empezado: aún no ha llegado todo lo físico del pedido.
|
|
84
|
+
*/
|
|
85
|
+
empiezaAlRecibir?: boolean
|
|
81
86
|
caduca: string | null
|
|
82
87
|
dentroDePlazo: boolean
|
|
83
88
|
lineas: { id: string; titulo: string; cantidad: number; excluida: string | null }[]
|
|
@@ -98,6 +103,24 @@ export interface BundleComponent {
|
|
|
98
103
|
* ensena `hint` (los ultimos caracteres) y `revealed` dice si ya se destapo,
|
|
99
104
|
* que es lo que cuenta como entregado.
|
|
100
105
|
*/
|
|
106
|
+
/**
|
|
107
|
+
* La licencia de una pieza del mercado comprada en un pedido. La clave es la
|
|
108
|
+
* credencial con la que el comprador activa el tema o la extensión en su sitio
|
|
109
|
+
* y con la que abre soporte con el autor: por eso se enseña entera.
|
|
110
|
+
*/
|
|
111
|
+
export interface License {
|
|
112
|
+
key: string
|
|
113
|
+
status: "activa" | "caducada" | "anulada"
|
|
114
|
+
/** Nombre del producto al que da derecho. */
|
|
115
|
+
title: string | null
|
|
116
|
+
/** Sitios donde está activada ahora mismo. */
|
|
117
|
+
sites: number
|
|
118
|
+
/** Cuántos sitios admite. */
|
|
119
|
+
limit: number
|
|
120
|
+
/** Hasta cuándo incluye soporte y versiones nuevas (AAAA-MM-DD). null: sin fecha. */
|
|
121
|
+
supportedUntil: string | null
|
|
122
|
+
}
|
|
123
|
+
|
|
101
124
|
export interface ProductCode {
|
|
102
125
|
id: string
|
|
103
126
|
lineId: string
|
|
@@ -119,6 +142,9 @@ export interface ProductCode {
|
|
|
119
142
|
* Lo que anade un producto que viene del mercado de temas y extensiones:
|
|
120
143
|
* version, cuando se actualizo, demo y changelog. Es lo que mira quien compra
|
|
121
144
|
* software y lo que un producto normal no tiene.
|
|
145
|
+
*
|
|
146
|
+
* En los listados llega un resumen: `screenshots` y `changelog` vienen vacíos
|
|
147
|
+
* y se rellenan en `getProduct`, que es donde se enseñan.
|
|
122
148
|
*/
|
|
123
149
|
export interface MarketInfo {
|
|
124
150
|
type: "tema" | "extension"
|
|
@@ -131,6 +157,11 @@ export interface MarketInfo {
|
|
|
131
157
|
demoUrl: string | null
|
|
132
158
|
screenshots: string[]
|
|
133
159
|
changelog: { version: string; date: string | null; notes: string | null }[]
|
|
160
|
+
/**
|
|
161
|
+
* Meses de soporte del autor que incluye la compra (0: sin soporte). Las
|
|
162
|
+
* versiones nuevas no tienen fecha: le llegan al comprador siempre.
|
|
163
|
+
*/
|
|
164
|
+
supportMonths?: number
|
|
134
165
|
}
|
|
135
166
|
|
|
136
167
|
export interface Download {
|
|
@@ -479,6 +510,11 @@ export interface ListProductsParams {
|
|
|
479
510
|
categoryId?: string
|
|
480
511
|
ids?: string[]
|
|
481
512
|
tags?: string[]
|
|
513
|
+
/**
|
|
514
|
+
* Solo piezas del mercado de ese tipo. Sin él salen todos los productos,
|
|
515
|
+
* sean o no del mercado. Un adaptador sin mercado lo ignora.
|
|
516
|
+
*/
|
|
517
|
+
type?: "tema" | "extension"
|
|
482
518
|
limit?: number
|
|
483
519
|
offset?: number
|
|
484
520
|
sort?: SortProductos
|
|
@@ -538,6 +574,23 @@ export interface Author {
|
|
|
538
574
|
support: AuthorSupport | null
|
|
539
575
|
}
|
|
540
576
|
|
|
577
|
+
/** Lo que manda quien quiere vender en el mercado. Lo revisa una persona. */
|
|
578
|
+
export interface AuthorApplication {
|
|
579
|
+
/** Nombre con el que publicará. */
|
|
580
|
+
name: string
|
|
581
|
+
email: string
|
|
582
|
+
/** Enlace a algo que haya hecho: sin eso no hay nada que revisar. */
|
|
583
|
+
portfolio: string
|
|
584
|
+
sells: ("tema" | "extension")[]
|
|
585
|
+
/** Identificador público; si falta, sale del nombre. */
|
|
586
|
+
handle?: string
|
|
587
|
+
/** Código de dos letras. */
|
|
588
|
+
country?: string
|
|
589
|
+
website?: string
|
|
590
|
+
stacks?: string[]
|
|
591
|
+
experience?: string
|
|
592
|
+
}
|
|
593
|
+
|
|
541
594
|
export interface SupportMessage {
|
|
542
595
|
from: "buyer" | "author" | "store"
|
|
543
596
|
text: string
|
|
@@ -574,6 +627,8 @@ export interface CommerceClient {
|
|
|
574
627
|
subirFichero?(archivo: File): Promise<{ id: string; nombre: string; tipo: string; bytes: number; firma: string }>
|
|
575
628
|
/** Opcional: las descargas de un pedido con contenido digital. */
|
|
576
629
|
getDownloads?(orderId: string): Promise<Download[]>
|
|
630
|
+
/** Opcional: las licencias de las piezas del mercado compradas en un pedido. */
|
|
631
|
+
getLicenses?(orderId: string): Promise<License[]>
|
|
577
632
|
/** Los codigos de un pedido, tapados. */
|
|
578
633
|
getCodes?(orderId: string): Promise<ProductCode[]>
|
|
579
634
|
/** Destapa uno y devuelve el codigo entero. Queda apuntado quien y cuando. */
|
|
@@ -582,6 +637,34 @@ export interface CommerceClient {
|
|
|
582
637
|
getWithdrawal?(orderId: string): Promise<WithdrawalState | null>
|
|
583
638
|
/** Opcional: solicita el desistimiento de un pedido (botón obligatorio en la UE). */
|
|
584
639
|
requestWithdrawal?(orderId: string, datos?: { lineas?: string[]; motivo?: string }): Promise<{ solicitud: string; aceptadas: number }>
|
|
640
|
+
/**
|
|
641
|
+
* Opcional: pedir vender en el mercado. Devuelve el id de la solicitud; la
|
|
642
|
+
* cuenta se crea cuando alguien la acepta. Si el correo ya pidió, falla con
|
|
643
|
+
* `err.status` 400 y el motivo en `err.detalle`.
|
|
644
|
+
*/
|
|
645
|
+
applyAsAuthor?(application: AuthorApplication): Promise<{ id: string }>
|
|
646
|
+
/**
|
|
647
|
+
* Opcional: el boletín, con doble confirmación. `subscribe` NO apunta a nadie:
|
|
648
|
+
* manda un correo con un enlace, y solo al pulsarlo (`confirm`) queda dentro.
|
|
649
|
+
* Contesta siempre lo mismo para que no sirva para averiguar quién está.
|
|
650
|
+
*/
|
|
651
|
+
newsletter?: {
|
|
652
|
+
subscribe(
|
|
653
|
+
email: string,
|
|
654
|
+
consent: {
|
|
655
|
+
/** El texto EXACTO que vio la persona junto a la casilla. Es la prueba. */
|
|
656
|
+
text: string
|
|
657
|
+
/** Versión de ese texto: cambia cuando cambia el texto. */
|
|
658
|
+
version: string
|
|
659
|
+
locale?: string
|
|
660
|
+
source?: string
|
|
661
|
+
ip?: string
|
|
662
|
+
userAgent?: string
|
|
663
|
+
},
|
|
664
|
+
): Promise<{ status: "pendiente" }>
|
|
665
|
+
confirm(token: string): Promise<boolean>
|
|
666
|
+
unsubscribe(token: string): Promise<boolean>
|
|
667
|
+
}
|
|
585
668
|
/** Opcional: la ficha pública de un autor del mercado. */
|
|
586
669
|
getAuthor?(handle: string): Promise<Author | null>
|
|
587
670
|
|