@gzl10/baserow 1.2.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/CHANGELOG.md +435 -0
- package/README.md +847 -0
- package/dist/index.d.ts +8749 -0
- package/dist/index.js +11167 -0
- package/dist/index.js.map +1 -0
- package/package.json +91 -0
- package/src/BaserowClient.ts +501 -0
- package/src/ClientWithCreds.ts +545 -0
- package/src/ClientWithCredsWs.ts +852 -0
- package/src/ClientWithToken.ts +171 -0
- package/src/contexts/DatabaseClientContext.ts +114 -0
- package/src/contexts/DatabaseContext.ts +870 -0
- package/src/contexts/DatabaseTokenContext.ts +331 -0
- package/src/contexts/FieldContext.ts +399 -0
- package/src/contexts/RowContext.ts +99 -0
- package/src/contexts/TableClientContext.ts +291 -0
- package/src/contexts/TableContext.ts +1247 -0
- package/src/contexts/TableOnlyContext.ts +74 -0
- package/src/contexts/WorkspaceContext.ts +490 -0
- package/src/express/errors.ts +260 -0
- package/src/express/index.ts +69 -0
- package/src/express/middleware.ts +225 -0
- package/src/express/serializers.ts +314 -0
- package/src/index.ts +247 -0
- package/src/presets/performance.ts +262 -0
- package/src/services/AuthService.ts +472 -0
- package/src/services/DatabaseService.ts +246 -0
- package/src/services/DatabaseTokenService.ts +186 -0
- package/src/services/FieldService.ts +1543 -0
- package/src/services/RowService.ts +982 -0
- package/src/services/SchemaControlService.ts +420 -0
- package/src/services/TableService.ts +781 -0
- package/src/services/WorkspaceService.ts +113 -0
- package/src/services/core/BaseAuthClient.ts +111 -0
- package/src/services/core/BaseClient.ts +107 -0
- package/src/services/core/BaseService.ts +71 -0
- package/src/services/core/HttpService.ts +115 -0
- package/src/services/core/ValidationService.ts +149 -0
- package/src/types/auth.ts +177 -0
- package/src/types/core.ts +91 -0
- package/src/types/errors.ts +105 -0
- package/src/types/fields.ts +456 -0
- package/src/types/index.ts +222 -0
- package/src/types/requests.ts +333 -0
- package/src/types/responses.ts +50 -0
- package/src/types/schema.ts +446 -0
- package/src/types/tokens.ts +36 -0
- package/src/types.ts +11 -0
- package/src/utils/auth.ts +174 -0
- package/src/utils/axios.ts +647 -0
- package/src/utils/field-cache.ts +164 -0
- package/src/utils/httpFactory.ts +66 -0
- package/src/utils/jwt-decoder.ts +188 -0
- package/src/utils/jwtTokens.ts +50 -0
- package/src/utils/performance.ts +105 -0
- package/src/utils/prisma-mapper.ts +961 -0
- package/src/utils/validation.ts +463 -0
- package/src/validators/schema.ts +419 -0
package/package.json
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gzl10/baserow",
|
|
3
|
+
"version": "1.2.0",
|
|
4
|
+
"description": "Cliente TypeScript avanzado para Baserow API con arquitectura de 3 clientes, 21 tipos de campos soportados y operaciones bulk optimizadas",
|
|
5
|
+
"private": false,
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"module": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"types": "./dist/index.d.ts"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"src",
|
|
19
|
+
"README.md",
|
|
20
|
+
"CHANGELOG.md"
|
|
21
|
+
],
|
|
22
|
+
"keywords": [
|
|
23
|
+
"baserow",
|
|
24
|
+
"typescript",
|
|
25
|
+
"api",
|
|
26
|
+
"crud",
|
|
27
|
+
"database",
|
|
28
|
+
"client",
|
|
29
|
+
"rest",
|
|
30
|
+
"sdk",
|
|
31
|
+
"admin",
|
|
32
|
+
"jwt",
|
|
33
|
+
"database-token",
|
|
34
|
+
"fields",
|
|
35
|
+
"bulk-operations",
|
|
36
|
+
"rate-limiting",
|
|
37
|
+
"retry-logic",
|
|
38
|
+
"hierarchical-api",
|
|
39
|
+
"workspace",
|
|
40
|
+
"table",
|
|
41
|
+
"row",
|
|
42
|
+
"field"
|
|
43
|
+
],
|
|
44
|
+
"repository": {
|
|
45
|
+
"type": "git",
|
|
46
|
+
"url": "git@ssh.gitlab.gzl10.com:oss/baserow.git"
|
|
47
|
+
},
|
|
48
|
+
"homepage": "https://gitlab.gzl10.com/oss/baserow",
|
|
49
|
+
"bugs": "https://gitlab.gzl10.com/oss/baserow/-/issues",
|
|
50
|
+
"author": {
|
|
51
|
+
"name": "Gonzalo Díez",
|
|
52
|
+
"email": "gonzalo@gzl10.com",
|
|
53
|
+
"url": "https://gitlab.gzl10.com/oss"
|
|
54
|
+
},
|
|
55
|
+
"license": "UNLICENSED",
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@types/chance": "^1.1.7",
|
|
58
|
+
"@types/node": "^20.19.5",
|
|
59
|
+
"@typescript-eslint/eslint-plugin": "^8.18.1",
|
|
60
|
+
"@typescript-eslint/parser": "^8.18.1",
|
|
61
|
+
"chance": "^1.1.13",
|
|
62
|
+
"dotenv": "^16.6.1",
|
|
63
|
+
"eslint": "^9.17.0",
|
|
64
|
+
"prettier": "^3.4.2",
|
|
65
|
+
"tsup": "^8.5.0",
|
|
66
|
+
"typescript": "^5.6.3",
|
|
67
|
+
"vitest": "^3.2.4"
|
|
68
|
+
},
|
|
69
|
+
"engines": {
|
|
70
|
+
"node": ">=20.19.5"
|
|
71
|
+
},
|
|
72
|
+
"packageManager": "pnpm@8.15.1",
|
|
73
|
+
"dependencies": {
|
|
74
|
+
"axios": "^1.7.9",
|
|
75
|
+
"axios-rate-limit": "^1.4.0",
|
|
76
|
+
"axios-retry": "^4.5.0",
|
|
77
|
+
"zod": "^3.25.1"
|
|
78
|
+
},
|
|
79
|
+
"scripts": {
|
|
80
|
+
"build": "tsup",
|
|
81
|
+
"build:tsc": "tsc",
|
|
82
|
+
"typecheck": "tsc --noEmit",
|
|
83
|
+
"test": "vitest run",
|
|
84
|
+
"test:watch": "vitest",
|
|
85
|
+
"test:smoke": "vitest run --config vitest.config.smoke.ts",
|
|
86
|
+
"lint": "eslint .",
|
|
87
|
+
"lint:fix": "eslint . --fix",
|
|
88
|
+
"format": "prettier --check .",
|
|
89
|
+
"format:fix": "prettier --write ."
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,501 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cliente unificado principal de Baserow API v1.35+ (2025)
|
|
3
|
+
*
|
|
4
|
+
* **Arquitectura de 3 clientes especializados con auto-detección inteligente**
|
|
5
|
+
*
|
|
6
|
+
* Detecta automáticamente el tipo de autenticación basado en la configuración
|
|
7
|
+
* y devuelve el cliente apropiado con tipos TypeScript perfectos.
|
|
8
|
+
*
|
|
9
|
+
* **Características principales v1.1.0+:**
|
|
10
|
+
* - 🎯 **Arquitectura de 3 Clientes**: Auto-detección Token/Admin Global/Admin Workspace
|
|
11
|
+
* - 🗺️ **PrismaBaserowMapper**: Sintaxis familiar Prisma con 35+ tests de transformaciones
|
|
12
|
+
* - 📋 **21/22 Tipos de Campos**: Cobertura prácticamente completa incluyendo campos avanzados
|
|
13
|
+
* - 🚀 **HTTP Optimizado**: 36% menos código con axios-retry + axios-rate-limit oficiales
|
|
14
|
+
* - ⚡ **Operaciones Bulk**: Procesamiento optimizado con retry logic y rate limiting
|
|
15
|
+
* - 🧪 **Testing Robusto**: 35+ tests de integración + tests comprehensivos del mapper
|
|
16
|
+
*
|
|
17
|
+
* **Un solo método: `BaserowClient.create()`**
|
|
18
|
+
* - Detecta automáticamente si usas token o credenciales
|
|
19
|
+
* - Infiere el tipo correcto de cliente
|
|
20
|
+
* - Sin necesidad de elegir entre múltiples clases
|
|
21
|
+
*
|
|
22
|
+
* @aiComparison
|
|
23
|
+
* ## 📊 Matriz de Selección de Cliente por Escenario
|
|
24
|
+
*
|
|
25
|
+
* | Escenario | Cliente Recomendado | Razón | Config Example |
|
|
26
|
+
* |-----------|-------------------|-------|----------------|
|
|
27
|
+
* | **Frontend/Mobile App** | `ClientWithToken` | Máxima seguridad, scope limitado a tablas específicas | `{ token: 'db_xxx' }` |
|
|
28
|
+
* | **Admin Dashboard Web** | `ClientWithCreds` (Global) | Gestión multi-workspace, crear/editar estructuras | `{ credentials: {...} }` |
|
|
29
|
+
* | **Backend API** | `ClientWithToken` | Performance óptimo, solo CRUD de datos | `{ token: 'db_xxx' }` |
|
|
30
|
+
* | **CLI Tool Admin** | `ClientWithCreds` (Global) | Operaciones admin en múltiples workspaces | `{ credentials: {...} }` |
|
|
31
|
+
* | **Microservicio Single-Tenant** | `ClientWithCredsWs` | API simplificada, workspace fijo | `{ credentials: {...}, workspace: 'X' }` |
|
|
32
|
+
* | **Background Job/Cron** | `ClientWithToken` | Sin riesgo de sesión expirada (token no expira) | `{ token: 'db_xxx' }` |
|
|
33
|
+
* | **Data Migration Script** | `ClientWithCreds` (Global) | Crear workspaces/databases/tablas completas | `{ credentials: {...} }` |
|
|
34
|
+
* | **Edge Functions** | `ClientWithToken` | Stateless, no maneja refresh tokens | `{ token: 'db_xxx' }` |
|
|
35
|
+
* | **Desktop App (Electron)** | `ClientWithCredsWs` | UX simplificada, workspace predefinido | `{ credentials: {...}, workspace: 'X' }` |
|
|
36
|
+
* | **Testing/E2E** | `ClientWithCreds` (Global) | Setup/teardown completo de fixtures | `{ credentials: {...} }` |
|
|
37
|
+
* | **Webhook Handler** | `ClientWithToken` | Read-only verification, performance crítico | `{ token: 'db_xxx' }` |
|
|
38
|
+
* | **Serverless Functions** | `ClientWithToken` | Cold start rápido, sin estado de sesión | `{ token: 'db_xxx' }` |
|
|
39
|
+
*
|
|
40
|
+
* @aiDecisionFactors
|
|
41
|
+
* ## 🔑 5 Factores Clave para Elegir Cliente
|
|
42
|
+
*
|
|
43
|
+
* **1. Operaciones Requeridas**
|
|
44
|
+
* - Solo CRUD de datos → `ClientWithToken`
|
|
45
|
+
* - Crear/modificar estructura (tablas, campos) → `ClientWithCreds*`
|
|
46
|
+
* - Gestión de workspaces → `ClientWithCreds` (Global)
|
|
47
|
+
*
|
|
48
|
+
* **2. Scope de Acceso**
|
|
49
|
+
* - Single workspace → `ClientWithCredsWs` o `ClientWithToken`
|
|
50
|
+
* - Multi-workspace → `ClientWithCreds` (Global)
|
|
51
|
+
* - Tablas específicas → `ClientWithToken` (mejor seguridad)
|
|
52
|
+
*
|
|
53
|
+
* **3. Ambiente de Ejecución**
|
|
54
|
+
* - Stateless (serverless, edge) → `ClientWithToken`
|
|
55
|
+
* - Stateful (backend server) → Cualquiera
|
|
56
|
+
* - Cliente (frontend, mobile) → `ClientWithToken`
|
|
57
|
+
*
|
|
58
|
+
* **4. Seguridad y Permisos**
|
|
59
|
+
* - Máxima seguridad (least privilege) → `ClientWithToken`
|
|
60
|
+
* - Admin operations trusted → `ClientWithCreds*`
|
|
61
|
+
* - Credenciales en código → ⚠️ Evitar (usar env vars)
|
|
62
|
+
*
|
|
63
|
+
* **5. Mantenimiento de Sesión**
|
|
64
|
+
* - Sin preocuparse de sesiones → `ClientWithToken` (no expira)
|
|
65
|
+
* - Manejo de refresh tokens OK → `ClientWithCreds*`
|
|
66
|
+
* - Background jobs largos → `ClientWithToken` (no requiere refresh)
|
|
67
|
+
*
|
|
68
|
+
* @aiComparison
|
|
69
|
+
* ## 🎯 Ejemplos de Decisión por Caso de Uso
|
|
70
|
+
*
|
|
71
|
+
* **Caso: Aplicación React de E-Commerce**
|
|
72
|
+
* ```typescript
|
|
73
|
+
* // ✅ CORRECTO - Token limitado a tablas de productos/carritos
|
|
74
|
+
* const client = await BaserowClient.create({
|
|
75
|
+
* token: process.env.VITE_BASEROW_TOKEN
|
|
76
|
+
* })
|
|
77
|
+
* // Scope: Solo products + carts (configurado en Baserow)
|
|
78
|
+
* const products = await client.database(DB_ID).table(PRODUCTS_TABLE).rows.list()
|
|
79
|
+
* ```
|
|
80
|
+
*
|
|
81
|
+
* **Caso: Dashboard Admin Multi-Tenant**
|
|
82
|
+
* ```typescript
|
|
83
|
+
* // ✅ CORRECTO - Credenciales globales para gestión completa
|
|
84
|
+
* const admin = await BaserowClient.create({
|
|
85
|
+
* credentials: {
|
|
86
|
+
* email: process.env.ADMIN_EMAIL,
|
|
87
|
+
* password: process.env.ADMIN_PASSWORD
|
|
88
|
+
* }
|
|
89
|
+
* })
|
|
90
|
+
* // Puede crear/eliminar workspaces, databases, tables
|
|
91
|
+
* const workspace = await admin.workspaces.create({ name: 'Nuevo Cliente' })
|
|
92
|
+
* ```
|
|
93
|
+
*
|
|
94
|
+
* **Caso: Microservicio de Reportes para Empresa X**
|
|
95
|
+
* ```typescript
|
|
96
|
+
* // ✅ CORRECTO - Workspace-scoped para UX simplificada
|
|
97
|
+
* const reports = await BaserowClient.create({
|
|
98
|
+
* credentials: {
|
|
99
|
+
* email: process.env.SERVICE_EMAIL,
|
|
100
|
+
* password: process.env.SERVICE_PASSWORD
|
|
101
|
+
* },
|
|
102
|
+
* workspace: 'Empresa X'
|
|
103
|
+
* })
|
|
104
|
+
* // API simplificada: admin.databases.list() en vez de admin.workspace('X').databases.list()
|
|
105
|
+
* const databases = await reports.databases.list()
|
|
106
|
+
* ```
|
|
107
|
+
*
|
|
108
|
+
* **Caso: Webhook Processor (Vercel Edge Function)**
|
|
109
|
+
* ```typescript
|
|
110
|
+
* // ✅ CORRECTO - Token para stateless execution
|
|
111
|
+
* export default async function handler(req: Request) {
|
|
112
|
+
* const client = await BaserowClient.create({
|
|
113
|
+
* token: process.env.BASEROW_TOKEN
|
|
114
|
+
* })
|
|
115
|
+
*
|
|
116
|
+
* // Verificar evento sin mantener sesión
|
|
117
|
+
* const row = await client.database(DB_ID).table(TBL_ID).rows.get(rowId)
|
|
118
|
+
* return Response.json({ verified: true })
|
|
119
|
+
* }
|
|
120
|
+
* ```
|
|
121
|
+
*
|
|
122
|
+
* **Caso: CLI Tool de Migración**
|
|
123
|
+
* ```typescript
|
|
124
|
+
* // ✅ CORRECTO - Credenciales globales para setup completo
|
|
125
|
+
* const migrator = await BaserowClient.create({
|
|
126
|
+
* credentials: {
|
|
127
|
+
* email: await promptEmail(),
|
|
128
|
+
* password: await promptPassword()
|
|
129
|
+
* }
|
|
130
|
+
* })
|
|
131
|
+
*
|
|
132
|
+
* // Crear estructura completa: workspace → database → tables → fields → data
|
|
133
|
+
* const ws = await migrator.workspaces.create({ name: 'Production' })
|
|
134
|
+
* const db = await migrator.workspace('Production').databases.create('Main DB')
|
|
135
|
+
* const table = await migrator.workspace('Production').database('Main DB').tables.create({ name: 'Users' })
|
|
136
|
+
* ```
|
|
137
|
+
*
|
|
138
|
+
* @aiWarning
|
|
139
|
+
* ## ⚠️ Errores Comunes de Selección
|
|
140
|
+
*
|
|
141
|
+
* **❌ Error 1: Usar Credentials en Frontend**
|
|
142
|
+
* ```typescript
|
|
143
|
+
* // ❌ PELIGROSO - Credenciales expuestas en bundle
|
|
144
|
+
* const client = await BaserowClient.create({
|
|
145
|
+
* credentials: {
|
|
146
|
+
* email: 'admin@company.com', // ❌ Visible en DevTools
|
|
147
|
+
* password: 'secret123' // ❌ Comprometido
|
|
148
|
+
* }
|
|
149
|
+
* })
|
|
150
|
+
* ```
|
|
151
|
+
* **✅ Solución: Usar Database Token**
|
|
152
|
+
* ```typescript
|
|
153
|
+
* const client = await BaserowClient.create({
|
|
154
|
+
* token: import.meta.env.VITE_BASEROW_TOKEN // ✅ Scope limitado
|
|
155
|
+
* })
|
|
156
|
+
* ```
|
|
157
|
+
*
|
|
158
|
+
* **❌ Error 2: Token para Operaciones Admin**
|
|
159
|
+
* ```typescript
|
|
160
|
+
* // ❌ IMPOSIBLE - Database Token no puede crear campos
|
|
161
|
+
* const client = await BaserowClient.create({ token: 'db_xxx' })
|
|
162
|
+
* await client.database(1).table(2).field.createText('name') // ❌ 403 Forbidden
|
|
163
|
+
* ```
|
|
164
|
+
* **✅ Solución: Usar Credentials**
|
|
165
|
+
* ```typescript
|
|
166
|
+
* const admin = await BaserowClient.create({ credentials: {...} })
|
|
167
|
+
* await admin.workspace('X').database('Y').table('Z').field.createText('name') // ✅
|
|
168
|
+
* ```
|
|
169
|
+
*
|
|
170
|
+
* **❌ Error 3: Global Credentials para Single Workspace**
|
|
171
|
+
* ```typescript
|
|
172
|
+
* // ❌ VERBOSE - API innecesariamente compleja
|
|
173
|
+
* const admin = await BaserowClient.create({ credentials: {...} })
|
|
174
|
+
* await admin.workspace('My Company').databases.list()
|
|
175
|
+
* await admin.workspace('My Company').database('DB').tables.list()
|
|
176
|
+
* // Repetir 'My Company' en cada llamada
|
|
177
|
+
* ```
|
|
178
|
+
* **✅ Solución: Usar Workspace-Scoped**
|
|
179
|
+
* ```typescript
|
|
180
|
+
* const admin = await BaserowClient.create({
|
|
181
|
+
* credentials: {...},
|
|
182
|
+
* workspace: 'My Company' // ✅ Workspace automático
|
|
183
|
+
* })
|
|
184
|
+
* await admin.databases.list() // ✅ Simplificado
|
|
185
|
+
* await admin.database('DB').tables.list() // ✅ Sin prefijo workspace
|
|
186
|
+
* ```
|
|
187
|
+
*
|
|
188
|
+
* @example Uso básico con auto-detección
|
|
189
|
+
* ```typescript
|
|
190
|
+
* import { BaserowClient, PrismaBaserowMapper } from '@gzl10/baserow'
|
|
191
|
+
*
|
|
192
|
+
* // === ARQUITECTURA DE 3 CLIENTES ===
|
|
193
|
+
*
|
|
194
|
+
* // 🎯 Token-based (auto-detectado) - para operaciones de datos
|
|
195
|
+
* const client = await BaserowClient.create({
|
|
196
|
+
* url: 'https://baserow.com',
|
|
197
|
+
* token: 'db_token_123'
|
|
198
|
+
* })
|
|
199
|
+
* // Tipo inferido automáticamente: BaserowWithToken
|
|
200
|
+
* const rows = await client.database(123).table(456).rows.list()
|
|
201
|
+
*
|
|
202
|
+
* // Operaciones bulk optimizadas
|
|
203
|
+
* const bulkRows = await client.database(123).table(456).rows.createBulk([
|
|
204
|
+
* { name: 'Alice', email: 'alice@example.com' },
|
|
205
|
+
* { name: 'Bob', email: 'bob@example.com' }
|
|
206
|
+
* ], { batchSize: 100 })
|
|
207
|
+
*
|
|
208
|
+
* // 🎯 Credentials global (auto-detectado) - para administración multi-workspace
|
|
209
|
+
* const admin = await BaserowClient.create({
|
|
210
|
+
* url: 'https://baserow.com',
|
|
211
|
+
* credentials: { email: 'admin@co.com', password: 'pass' }
|
|
212
|
+
* })
|
|
213
|
+
* // Tipo inferido automáticamente: BaserowWithCredentialsGlobal
|
|
214
|
+
* const workspaces = await admin.workspaces.list()
|
|
215
|
+
* const newWS = await admin.workspaces.create({ name: 'Nueva Empresa' })
|
|
216
|
+
* const updatedWS = await admin.workspace('My Workspace').update({ name: 'New Name' })
|
|
217
|
+
* const database = await admin.workspace('My Workspace').databases.create('CRM')
|
|
218
|
+
* await admin.workspace('Old Workspace').delete()
|
|
219
|
+
*
|
|
220
|
+
* // 🎯 Credentials workspace (auto-detectado) - para workspace específico
|
|
221
|
+
* const adminWS = await BaserowClient.create({
|
|
222
|
+
* url: 'https://baserow.com',
|
|
223
|
+
* credentials: { email: 'admin@co.com', password: 'pass' },
|
|
224
|
+
* workspace: 'My Workspace' // Esto activa modo workspace
|
|
225
|
+
* })
|
|
226
|
+
* // Tipo inferido automáticamente: BaserowWithCredentialsWorkspace
|
|
227
|
+
* const databases = await adminWS.databases.list()
|
|
228
|
+
* const table = await adminWS.database('My DB').tables.create({ name: 'Customers' })
|
|
229
|
+
*
|
|
230
|
+
* // === PRISMA MAPPER ===
|
|
231
|
+
* // Sintaxis familiar Prisma para consultas complejas
|
|
232
|
+
* const prismaQuery = {
|
|
233
|
+
* where: {
|
|
234
|
+
* AND: [
|
|
235
|
+
* { status: 'active' },
|
|
236
|
+
* { age: { gte: 18, lt: 65 } },
|
|
237
|
+
* { email: { contains: '@company.com' } }
|
|
238
|
+
* ]
|
|
239
|
+
* },
|
|
240
|
+
* orderBy: [{ created_at: 'desc' }, { name: 'asc' }],
|
|
241
|
+
* take: 20,
|
|
242
|
+
* skip: 40,
|
|
243
|
+
* select: { id: true, name: true, email: true }
|
|
244
|
+
* }
|
|
245
|
+
*
|
|
246
|
+
* const baserowOptions = PrismaBaserowMapper.transformPrismaToBaserow(prismaQuery)
|
|
247
|
+
* const filteredRows = await client.database(123).table(456).rows.list(baserowOptions)
|
|
248
|
+
*
|
|
249
|
+
* // === COBERTURA COMPLETA DE CAMPOS ===
|
|
250
|
+
* // 21/22 tipos de campos soportados incluyendo campos avanzados v1.1.0+
|
|
251
|
+
* const textField = await table.field.createText('full_name')
|
|
252
|
+
* const emailField = await table.field.createEmail('contact_email')
|
|
253
|
+
* const fileField = await table.field.createFile('documents') // ¡Nuevo!
|
|
254
|
+
* const autoField = await table.field.createAutonumber('ticket_id') // ¡Nuevo!
|
|
255
|
+
* const countField = await table.field.createCount('items_count', targetTableId) // ¡Nuevo!
|
|
256
|
+
* const rollupField = await table.field.createRollup('total_amount', tableId, fieldId, 'sum') // ¡Nuevo!
|
|
257
|
+
* const lookupField = await table.field.createLookup('item_names', tableId, fieldId) // ¡Nuevo!
|
|
258
|
+
* ```
|
|
259
|
+
*
|
|
260
|
+
* @example Uso con presets de performance
|
|
261
|
+
* ```typescript
|
|
262
|
+
* import { BaserowClient, PERFORMANCE_PRESETS } from '@gzl10/baserow'
|
|
263
|
+
*
|
|
264
|
+
* // Cliente con preset de producción (balanceado)
|
|
265
|
+
* const prodClient = await BaserowClient.create({
|
|
266
|
+
* url: 'https://api.baserow.com',
|
|
267
|
+
* token: process.env.BASEROW_TOKEN,
|
|
268
|
+
* performance: PERFORMANCE_PRESETS.production
|
|
269
|
+
* })
|
|
270
|
+
*
|
|
271
|
+
* // Cliente para desarrollo (más relajado)
|
|
272
|
+
* const devClient = await BaserowClient.create({
|
|
273
|
+
* url: 'http://localhost:3000',
|
|
274
|
+
* credentials: { email: 'dev@example.com', password: 'dev123' },
|
|
275
|
+
* performance: PERFORMANCE_PRESETS.development
|
|
276
|
+
* })
|
|
277
|
+
*
|
|
278
|
+
* // Cliente para tests (conservador)
|
|
279
|
+
* const testClient = await BaserowClient.create({
|
|
280
|
+
* url: 'https://test.baserow.com',
|
|
281
|
+
* token: process.env.TEST_TOKEN,
|
|
282
|
+
* performance: PERFORMANCE_PRESETS.testing
|
|
283
|
+
* })
|
|
284
|
+
* ```
|
|
285
|
+
*
|
|
286
|
+
*/
|
|
287
|
+
|
|
288
|
+
import { ClientWithToken } from './ClientWithToken'
|
|
289
|
+
import { ClientWithCreds } from './ClientWithCreds'
|
|
290
|
+
import { ClientWithCredsWs } from './ClientWithCredsWs'
|
|
291
|
+
import { PerformanceManager } from './utils/performance'
|
|
292
|
+
import { verifyLogin, verifyBaserowHealth } from './utils/auth'
|
|
293
|
+
import {
|
|
294
|
+
BaserowTokenConfig,
|
|
295
|
+
BaserowCredentialsConfig,
|
|
296
|
+
BaserowCredentialsWorkspaceConfig,
|
|
297
|
+
BaserowUnifiedConfig,
|
|
298
|
+
BaserowCredentials
|
|
299
|
+
} from './types'
|
|
300
|
+
|
|
301
|
+
// Conditional types para inferencia automática de tipos
|
|
302
|
+
type InferClientType<T> = T extends { token: string }
|
|
303
|
+
? ClientWithToken
|
|
304
|
+
: T extends { workspace: string }
|
|
305
|
+
? ClientWithCredsWs
|
|
306
|
+
: T extends { credentials: any }
|
|
307
|
+
? ClientWithCreds
|
|
308
|
+
: never
|
|
309
|
+
|
|
310
|
+
export class BaserowClient {
|
|
311
|
+
/**
|
|
312
|
+
* Crea un cliente con Database Token para operaciones de datos
|
|
313
|
+
* @internal
|
|
314
|
+
*/
|
|
315
|
+
private static withToken(config: BaserowTokenConfig): ClientWithToken {
|
|
316
|
+
return new ClientWithToken(config)
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Crea un cliente admin con credenciales
|
|
321
|
+
* @internal
|
|
322
|
+
*/
|
|
323
|
+
private static async withCredentials(config: BaserowCredentialsConfig): Promise<ClientWithCreds>
|
|
324
|
+
private static async withCredentials(config: BaserowCredentialsWorkspaceConfig): Promise<ClientWithCredsWs>
|
|
325
|
+
private static async withCredentials(
|
|
326
|
+
config: BaserowCredentialsConfig | BaserowCredentialsWorkspaceConfig
|
|
327
|
+
): Promise<ClientWithCreds | ClientWithCredsWs> {
|
|
328
|
+
// Si tiene workspace, crear cliente de workspace específico
|
|
329
|
+
if ('workspace' in config && config.workspace) {
|
|
330
|
+
return await ClientWithCredsWs.create({
|
|
331
|
+
url: config.url,
|
|
332
|
+
credentials: config.credentials,
|
|
333
|
+
workspace: config.workspace,
|
|
334
|
+
logger: config.logger,
|
|
335
|
+
performance: config.performance
|
|
336
|
+
})
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Si no, crear cliente global
|
|
340
|
+
return await ClientWithCreds.create({
|
|
341
|
+
url: config.url,
|
|
342
|
+
credentials: config.credentials,
|
|
343
|
+
logger: config.logger,
|
|
344
|
+
performance: config.performance
|
|
345
|
+
})
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* Auto-detecta el tipo de configuración y crea el cliente apropiado (overload para token)
|
|
350
|
+
*/
|
|
351
|
+
static create(config: BaserowTokenConfig): Promise<ClientWithToken>
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Auto-detecta el tipo de configuración y crea el cliente apropiado (overload para credentials)
|
|
355
|
+
*/
|
|
356
|
+
static create(config: BaserowCredentialsConfig): Promise<ClientWithCreds>
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Auto-detecta el tipo de configuración y crea el cliente apropiado (overload para credentials + workspace)
|
|
360
|
+
*/
|
|
361
|
+
static create(config: BaserowCredentialsWorkspaceConfig): Promise<ClientWithCredsWs>
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Auto-detecta el tipo de configuración y crea el cliente apropiado (generic)
|
|
365
|
+
*/
|
|
366
|
+
static create<T extends BaserowUnifiedConfig>(config: T): Promise<InferClientType<T>>
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Implementación de create con auto-detección
|
|
370
|
+
*/
|
|
371
|
+
static async create(config: BaserowUnifiedConfig): Promise<ClientWithToken | ClientWithCreds | ClientWithCredsWs> {
|
|
372
|
+
// Detectar tipo basado en propiedades
|
|
373
|
+
if ('token' in config) {
|
|
374
|
+
// Es configuración de token
|
|
375
|
+
return this.withToken(config as BaserowTokenConfig)
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if ('credentials' in config) {
|
|
379
|
+
// Es configuración de credenciales
|
|
380
|
+
if ('workspace' in config && config.workspace) {
|
|
381
|
+
// Con workspace específico
|
|
382
|
+
return await this.withCredentials(config as BaserowCredentialsWorkspaceConfig)
|
|
383
|
+
} else {
|
|
384
|
+
// Sin workspace (global)
|
|
385
|
+
return await this.withCredentials(config as BaserowCredentialsConfig)
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
throw new Error('Invalid configuration: must provide either "token" or "credentials"')
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Establece configuración global de rendimiento para todos los tipos de clientes
|
|
394
|
+
*
|
|
395
|
+
* @param defaults - Configuración parcial de performance para sobrescribir defaults
|
|
396
|
+
*
|
|
397
|
+
* @example
|
|
398
|
+
* ```typescript
|
|
399
|
+
* // Configurar defaults más agresivos para toda la aplicación
|
|
400
|
+
* BaserowClient.setGlobalPerformanceDefaults({
|
|
401
|
+
* timeout: 45000,
|
|
402
|
+
* retries: 5,
|
|
403
|
+
* maxRequestsPerSecond: 20
|
|
404
|
+
* })
|
|
405
|
+
* ```
|
|
406
|
+
*/
|
|
407
|
+
static setGlobalPerformanceDefaults(defaults: Partial<import('./types.js').BaserowPerformanceOptions>): void {
|
|
408
|
+
PerformanceManager.setGlobal(defaults)
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Obtiene la configuración global actual de rendimiento
|
|
413
|
+
*
|
|
414
|
+
* @returns Configuración global actual de performance
|
|
415
|
+
*
|
|
416
|
+
* @example
|
|
417
|
+
* ```typescript
|
|
418
|
+
* const currentDefaults = BaserowClient.getGlobalPerformanceDefaults()
|
|
419
|
+
* console.log('Timeout global:', currentDefaults.timeout)
|
|
420
|
+
* ```
|
|
421
|
+
*/
|
|
422
|
+
static getGlobalPerformanceDefaults(): import('./types.js').BaserowPerformanceOptions {
|
|
423
|
+
return PerformanceManager.getGlobal()
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Verificar si las credenciales de Baserow son válidas sin crear cliente
|
|
428
|
+
*
|
|
429
|
+
* Esta función es útil para:
|
|
430
|
+
* - Validar credenciales en formularios de login
|
|
431
|
+
* - Health checks de credenciales
|
|
432
|
+
* - Verificación de configuración antes de inicializar la aplicación
|
|
433
|
+
*
|
|
434
|
+
* @param url URL base de Baserow (ej: 'https://baserow.com')
|
|
435
|
+
* @param credentials Credenciales de usuario (email y password)
|
|
436
|
+
* @param options Opciones adicionales (timeout, logger)
|
|
437
|
+
* @returns Promise<boolean> - true si las credenciales son válidas
|
|
438
|
+
*
|
|
439
|
+
* @example
|
|
440
|
+
* ```typescript
|
|
441
|
+
* // Verificar credenciales antes de crear cliente
|
|
442
|
+
* const isValid = await BaserowClient.verifyLogin('https://baserow.com', {
|
|
443
|
+
* email: 'user@example.com',
|
|
444
|
+
* password: 'password123'
|
|
445
|
+
* })
|
|
446
|
+
*
|
|
447
|
+
* if (isValid) {
|
|
448
|
+
* // Proceder a crear cliente admin
|
|
449
|
+
* const admin = await BaserowClient.create({
|
|
450
|
+
* url: 'https://baserow.com',
|
|
451
|
+
* credentials: { email: 'user@example.com', password: 'password123' }
|
|
452
|
+
* })
|
|
453
|
+
* } else {
|
|
454
|
+
* console.error('Credenciales inválidas')
|
|
455
|
+
* }
|
|
456
|
+
* ```
|
|
457
|
+
*/
|
|
458
|
+
static async verifyLogin(
|
|
459
|
+
url: string,
|
|
460
|
+
credentials: BaserowCredentials,
|
|
461
|
+
options?: import('./utils/auth.js').VerifyLoginOptions
|
|
462
|
+
): Promise<boolean> {
|
|
463
|
+
return verifyLogin(url, credentials, options)
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Verificar si una URL de Baserow es accesible (health check básico)
|
|
468
|
+
*
|
|
469
|
+
* Útil para verificar conectividad del servidor antes de realizar operaciones.
|
|
470
|
+
* No requiere autenticación.
|
|
471
|
+
*
|
|
472
|
+
* @param url URL base de Baserow (ej: 'https://baserow.com')
|
|
473
|
+
* @param options Opciones de verificación (timeout, logger)
|
|
474
|
+
* @returns Promise<boolean> - true si el servidor es accesible
|
|
475
|
+
*
|
|
476
|
+
* @example
|
|
477
|
+
* ```typescript
|
|
478
|
+
* // Verificar si Baserow está disponible
|
|
479
|
+
* const isHealthy = await BaserowClient.health('https://baserow.com')
|
|
480
|
+
*
|
|
481
|
+
* if (!isHealthy) {
|
|
482
|
+
* console.log('Servidor Baserow no disponible')
|
|
483
|
+
* return
|
|
484
|
+
* }
|
|
485
|
+
*
|
|
486
|
+
* // Proceder con operaciones normales
|
|
487
|
+
* const client = await BaserowClient.create({ ... })
|
|
488
|
+
* ```
|
|
489
|
+
*/
|
|
490
|
+
static async health(
|
|
491
|
+
url: string,
|
|
492
|
+
options?: Pick<import('./utils/auth.js').VerifyLoginOptions, 'timeout' | 'logger'>
|
|
493
|
+
): Promise<boolean> {
|
|
494
|
+
return verifyBaserowHealth(url, options)
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
// Re-export de las clases internas para uso avanzado (pero marcadas como internas)
|
|
499
|
+
export { ClientWithToken } from './ClientWithToken'
|
|
500
|
+
export { ClientWithCreds } from './ClientWithCreds'
|
|
501
|
+
export { ClientWithCredsWs } from './ClientWithCredsWs'
|