@juanito_boop/w-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,126 @@
1
+ # @juanito_boop/w-sdk
2
+
3
+ SDK oficial para la API de TuOrg.
4
+
5
+ ## Instalacion
6
+
7
+ ```bash
8
+ npm install @juanito_boop/w-sdk
9
+ ```
10
+
11
+ ## Uso rapido
12
+
13
+ ```ts
14
+ import { createClient } from "@juanito_boop/w-sdk";
15
+
16
+ const client = createClient({
17
+ baseUrl: "https://api.tuorg.com",
18
+ apiKey: "TU_API_KEY",
19
+ });
20
+
21
+ // Auth
22
+ const login = await client.auth.login({
23
+ email: "user@tuorg.com",
24
+ password: "secret",
25
+ });
26
+
27
+ if (!login.success) {
28
+ console.error(login.error);
29
+ } else {
30
+ console.log(login.data.token);
31
+ }
32
+
33
+ // Realtime
34
+ const wines = await client.realtime.getWines();
35
+ console.log(wines);
36
+ ```
37
+
38
+ ## API
39
+
40
+ ### Client
41
+
42
+ ```ts
43
+ createClient(options: ClientOptions): WineClient
44
+ getClient(options?: ClientOptions): WineClient
45
+ ```
46
+
47
+ `ClientOptions`
48
+
49
+ - `baseUrl` (string, requerido) URL base de la API.
50
+ - `apiKey` (string, opcional) API key para endpoints privados.
51
+
52
+ ### Auth
53
+
54
+ ```ts
55
+ client.auth.login(data: LoginData): Promise<Result<AuthResponse>>
56
+ client.auth.register(data: RegisterData): Promise<Result<AuthResponse>>
57
+ client.auth.requestMagicLink(data: MagicLinkRequestData): Promise<Result<unknown>>
58
+ ```
59
+
60
+ ### Realtime (WebSocket)
61
+
62
+ ```ts
63
+ client.realtime.setApiKey(apiKey?: string): void
64
+ client.realtime.getWines(): Promise<Result<any[]>>
65
+ client.realtime.insertWine(data: unknown): Promise<Result<unknown>>
66
+ client.realtime.editWine(data: unknown): Promise<Result<unknown>>
67
+ ```
68
+
69
+ ## Tipos y schemas
70
+
71
+ Todos los tipos y schemas Zod estan exportados desde el paquete.
72
+
73
+ ```ts
74
+ import {
75
+ type Result,
76
+ type ApiError,
77
+ type ClientOptions,
78
+ type LoginData,
79
+ type RegisterData,
80
+ type MagicLinkRequestData,
81
+ type AuthResponse,
82
+ type RealtimeOptions,
83
+ type Wine,
84
+ type WineDetails,
85
+ type WineData,
86
+ type CreateWine,
87
+ type EditWine,
88
+ type BulkInsertWines,
89
+ ClientOptionsSchema,
90
+ ApiErrorSchema,
91
+ LoginDataSchema,
92
+ RegisterDataSchema,
93
+ MagicLinkRequestDataSchema,
94
+ AuthResponseSchema,
95
+ RealtimeOptionsSchema,
96
+ WineSchema,
97
+ WineDetailsSchema,
98
+ WineDataSchema,
99
+ CreateWineSchema,
100
+ EditWineSchema,
101
+ BulkInsertWinesSchema,
102
+ } from "@juanito_boop/w-sdk";
103
+ ```
104
+
105
+ ## Requisitos
106
+
107
+ - Node.js 18+ (usa `fetch` nativo). En Node 16, agrega un polyfill de `fetch`.
108
+
109
+ ## Scripts
110
+
111
+ ```bash
112
+ npm run build
113
+ npm run dev
114
+ npm run lint
115
+ npm run release
116
+ ```
117
+
118
+ ## Publicar en npm
119
+
120
+ 1. Asegura el build: `npm run build`.
121
+ 2. Inicia sesion: `npm login`.
122
+ 3. Publica: `npm publish --access public`.
123
+
124
+ ## Licencia
125
+
126
+ MIT
@@ -0,0 +1,218 @@
1
+ import type { ClientOptions } from './types';
2
+ export declare class WineClient {
3
+ readonly auth: {
4
+ login: (data: import("./types").LoginData) => Promise<import("./types").Result<{
5
+ token: string;
6
+ user: {
7
+ id: string;
8
+ email: string;
9
+ fullName?: string | undefined;
10
+ };
11
+ apiKey?: {
12
+ id: string;
13
+ key: string;
14
+ name: string;
15
+ expiresAt: string;
16
+ } | undefined;
17
+ }>>;
18
+ register: (data: import("./types").RegisterData) => Promise<import("./types").Result<{
19
+ token: string;
20
+ user: {
21
+ id: string;
22
+ email: string;
23
+ fullName?: string | undefined;
24
+ };
25
+ apiKey?: {
26
+ id: string;
27
+ key: string;
28
+ name: string;
29
+ expiresAt: string;
30
+ } | undefined;
31
+ }>>;
32
+ requestMagicLink: (data: import("./types").MagicLinkRequestData) => Promise<import("./types").Result<unknown>>;
33
+ };
34
+ readonly realtime: {
35
+ connect: () => Promise<void>;
36
+ disconnect: () => void;
37
+ setApiKey: (key?: string) => void;
38
+ getWines: () => Promise<import("./types").Result<{
39
+ id_vino: string;
40
+ nombre: string;
41
+ precio: number;
42
+ url_imagen: string;
43
+ descripcion: string;
44
+ nivel_alcohol: number;
45
+ variedades: string[];
46
+ pais_importacion: string;
47
+ color_vino: string;
48
+ stock: number;
49
+ capacidad: number;
50
+ is_deleted: boolean;
51
+ wine_details: {
52
+ notas_cata: string;
53
+ tipo_crianza: string;
54
+ bodega: string;
55
+ id_detalle?: string | undefined;
56
+ id_vino?: string | undefined;
57
+ };
58
+ }[]>>;
59
+ insertWine: (data: import("./types").CreateWine) => Promise<import("./types").Result<{
60
+ id_vino: string;
61
+ nombre: string;
62
+ precio: number;
63
+ url_imagen: string;
64
+ descripcion: string;
65
+ nivel_alcohol: number;
66
+ variedades: string[];
67
+ pais_importacion: string;
68
+ color_vino: string;
69
+ stock: number;
70
+ capacidad: number;
71
+ is_deleted: boolean;
72
+ wine_details: {
73
+ notas_cata: string;
74
+ tipo_crianza: string;
75
+ bodega: string;
76
+ id_detalle?: string | undefined;
77
+ id_vino?: string | undefined;
78
+ };
79
+ }>>;
80
+ insertBulkWines: (data: import("./types").CreateWine[]) => Promise<import("./types").Result<{
81
+ id_vino: string;
82
+ nombre: string;
83
+ precio: number;
84
+ url_imagen: string;
85
+ descripcion: string;
86
+ nivel_alcohol: number;
87
+ variedades: string[];
88
+ pais_importacion: string;
89
+ color_vino: string;
90
+ stock: number;
91
+ capacidad: number;
92
+ is_deleted: boolean;
93
+ wine_details: {
94
+ notas_cata: string;
95
+ tipo_crianza: string;
96
+ bodega: string;
97
+ id_detalle?: string | undefined;
98
+ id_vino?: string | undefined;
99
+ };
100
+ }[]>>;
101
+ editWine: (data: import("./types").EditWine) => Promise<import("./types").Result<{
102
+ id_vino: string;
103
+ nombre: string;
104
+ precio: number;
105
+ url_imagen: string;
106
+ descripcion: string;
107
+ nivel_alcohol: number;
108
+ variedades: string[];
109
+ pais_importacion: string;
110
+ color_vino: string;
111
+ stock: number;
112
+ capacidad: number;
113
+ is_deleted: boolean;
114
+ wine_details: {
115
+ notas_cata: string;
116
+ tipo_crianza: string;
117
+ bodega: string;
118
+ id_detalle?: string | undefined;
119
+ id_vino?: string | undefined;
120
+ };
121
+ }>>;
122
+ };
123
+ private apiKey?;
124
+ private readonly baseUrl;
125
+ constructor(options: ClientOptions);
126
+ setApiKey(apiKey?: string): void;
127
+ connectRealtime(): Promise<{
128
+ connect: () => Promise<void>;
129
+ disconnect: () => void;
130
+ setApiKey: (key?: string) => void;
131
+ getWines: () => Promise<import("./types").Result<{
132
+ id_vino: string;
133
+ nombre: string;
134
+ precio: number;
135
+ url_imagen: string;
136
+ descripcion: string;
137
+ nivel_alcohol: number;
138
+ variedades: string[];
139
+ pais_importacion: string;
140
+ color_vino: string;
141
+ stock: number;
142
+ capacidad: number;
143
+ is_deleted: boolean;
144
+ wine_details: {
145
+ notas_cata: string;
146
+ tipo_crianza: string;
147
+ bodega: string;
148
+ id_detalle?: string | undefined;
149
+ id_vino?: string | undefined;
150
+ };
151
+ }[]>>;
152
+ insertWine: (data: import("./types").CreateWine) => Promise<import("./types").Result<{
153
+ id_vino: string;
154
+ nombre: string;
155
+ precio: number;
156
+ url_imagen: string;
157
+ descripcion: string;
158
+ nivel_alcohol: number;
159
+ variedades: string[];
160
+ pais_importacion: string;
161
+ color_vino: string;
162
+ stock: number;
163
+ capacidad: number;
164
+ is_deleted: boolean;
165
+ wine_details: {
166
+ notas_cata: string;
167
+ tipo_crianza: string;
168
+ bodega: string;
169
+ id_detalle?: string | undefined;
170
+ id_vino?: string | undefined;
171
+ };
172
+ }>>;
173
+ insertBulkWines: (data: import("./types").CreateWine[]) => Promise<import("./types").Result<{
174
+ id_vino: string;
175
+ nombre: string;
176
+ precio: number;
177
+ url_imagen: string;
178
+ descripcion: string;
179
+ nivel_alcohol: number;
180
+ variedades: string[];
181
+ pais_importacion: string;
182
+ color_vino: string;
183
+ stock: number;
184
+ capacidad: number;
185
+ is_deleted: boolean;
186
+ wine_details: {
187
+ notas_cata: string;
188
+ tipo_crianza: string;
189
+ bodega: string;
190
+ id_detalle?: string | undefined;
191
+ id_vino?: string | undefined;
192
+ };
193
+ }[]>>;
194
+ editWine: (data: import("./types").EditWine) => Promise<import("./types").Result<{
195
+ id_vino: string;
196
+ nombre: string;
197
+ precio: number;
198
+ url_imagen: string;
199
+ descripcion: string;
200
+ nivel_alcohol: number;
201
+ variedades: string[];
202
+ pais_importacion: string;
203
+ color_vino: string;
204
+ stock: number;
205
+ capacidad: number;
206
+ is_deleted: boolean;
207
+ wine_details: {
208
+ notas_cata: string;
209
+ tipo_crianza: string;
210
+ bodega: string;
211
+ id_detalle?: string | undefined;
212
+ id_vino?: string | undefined;
213
+ };
214
+ }>>;
215
+ }>;
216
+ disconnectRealtime(): void;
217
+ }
218
+ export declare function createClient(options: ClientOptions): WineClient;
package/dist/client.js ADDED
@@ -0,0 +1,33 @@
1
+ import { createAuthHttp } from './http/auth';
2
+ import { createRealtime } from './ws/realtime';
3
+ export class WineClient {
4
+ constructor(options) {
5
+ if (!options.baseUrl) {
6
+ throw new Error('baseUrl es requerido');
7
+ }
8
+ this.baseUrl = options.baseUrl;
9
+ this.apiKey = options.apiKey;
10
+ this.auth = createAuthHttp({
11
+ baseUrl: this.baseUrl,
12
+ apiKey: this.apiKey,
13
+ });
14
+ this.realtime = createRealtime({
15
+ baseUrl: this.baseUrl,
16
+ apiKey: this.apiKey,
17
+ });
18
+ }
19
+ setApiKey(apiKey) {
20
+ this.apiKey = apiKey;
21
+ this.realtime.setApiKey(apiKey);
22
+ }
23
+ async connectRealtime() {
24
+ await this.realtime.connect();
25
+ return this.realtime;
26
+ }
27
+ disconnectRealtime() {
28
+ this.realtime.disconnect();
29
+ }
30
+ }
31
+ export function createClient(options) {
32
+ return new WineClient(options);
33
+ }
@@ -0,0 +1,38 @@
1
+ import type { LoginData, RegisterData, MagicLinkRequestData, Result } from '../types';
2
+ type AuthHttpOptions = {
3
+ baseUrl: string;
4
+ apiKey?: string;
5
+ fetch?: typeof fetch;
6
+ };
7
+ export declare function createAuthHttp(opts: AuthHttpOptions): {
8
+ login: (data: LoginData) => Promise<Result<{
9
+ token: string;
10
+ user: {
11
+ id: string;
12
+ email: string;
13
+ fullName?: string | undefined;
14
+ };
15
+ apiKey?: {
16
+ id: string;
17
+ key: string;
18
+ name: string;
19
+ expiresAt: string;
20
+ } | undefined;
21
+ }>>;
22
+ register: (data: RegisterData) => Promise<Result<{
23
+ token: string;
24
+ user: {
25
+ id: string;
26
+ email: string;
27
+ fullName?: string | undefined;
28
+ };
29
+ apiKey?: {
30
+ id: string;
31
+ key: string;
32
+ name: string;
33
+ expiresAt: string;
34
+ } | undefined;
35
+ }>>;
36
+ requestMagicLink: (data: MagicLinkRequestData) => Promise<Result<unknown>>;
37
+ };
38
+ export {};
@@ -0,0 +1,42 @@
1
+ export function createAuthHttp(opts) {
2
+ const fetcher = opts.fetch ?? globalThis.fetch;
3
+ async function post(path, body) {
4
+ try {
5
+ const res = await fetcher(`${opts.baseUrl}${path}`, {
6
+ method: 'POST',
7
+ headers: {
8
+ 'Content-Type': 'application/json',
9
+ ...(opts.apiKey ? { 'x-api-key': opts.apiKey } : {}),
10
+ },
11
+ body: JSON.stringify(body),
12
+ });
13
+ const json = await res.json().catch(() => null);
14
+ if (!res.ok) {
15
+ return {
16
+ success: false,
17
+ error: {
18
+ message: json?.message ?? res.statusText,
19
+ code: json?.code,
20
+ statusCode: res.status,
21
+ details: json,
22
+ },
23
+ };
24
+ }
25
+ return { success: true, data: json };
26
+ }
27
+ catch (err) {
28
+ return {
29
+ success: false,
30
+ error: {
31
+ message: err instanceof Error ? err.message : 'Network error',
32
+ code: 'NETWORK_ERROR',
33
+ },
34
+ };
35
+ }
36
+ }
37
+ return {
38
+ login: (data) => post('/auth/login', data),
39
+ register: (data) => post('/auth/register', data),
40
+ requestMagicLink: (data) => post('/auth/magic-link/request', data)
41
+ };
42
+ }