zenit-sdk 0.0.1
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 +279 -0
- package/dist/chunk-RGS6AZWV.mjs +3057 -0
- package/dist/chunk-RGS6AZWV.mjs.map +1 -0
- package/dist/index-C_2fk0Fk.d.mts +690 -0
- package/dist/index-C_2fk0Fk.d.ts +690 -0
- package/dist/index.d.mts +105 -0
- package/dist/index.d.ts +105 -0
- package/dist/index.js +4165 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1095 -0
- package/dist/index.mjs.map +1 -0
- package/dist/react/index.d.mts +4 -0
- package/dist/react/index.d.ts +4 -0
- package/dist/react/index.js +3088 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/index.mjs +53 -0
- package/dist/react/index.mjs.map +1 -0
- package/package.json +65 -0
package/README.md
ADDED
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
# zenit-sdk
|
|
2
|
+
|
|
3
|
+
## Introducción
|
|
4
|
+
`zenit-sdk` es una librería en TypeScript para consumir el backend de Zenit de forma sencilla. El core es agnóstico al framework y se enfoca en ofrecer clientes HTTP y helpers de autenticación. Además, incluye un componente React (`ZenitMap`) para integraciones de UI basado en Leaflet.
|
|
5
|
+
|
|
6
|
+
## Instalación
|
|
7
|
+
```bash
|
|
8
|
+
npm install zenit-sdk
|
|
9
|
+
# o con yarn
|
|
10
|
+
yarn add zenit-sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Para usar el componente React instala también sus peer dependencies en tu proyecto:
|
|
14
|
+
```bash
|
|
15
|
+
npm install react react-dom leaflet react-leaflet
|
|
16
|
+
# o con yarn
|
|
17
|
+
yarn add react react-dom leaflet react-leaflet
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Entradas del SDK
|
|
21
|
+
- **Core (Node/HTTP)**: `import { ZenitClient } from 'zenit-sdk';`
|
|
22
|
+
- **React (UI)**: `import { ZenitMap } from 'zenit-sdk/react';`
|
|
23
|
+
|
|
24
|
+
### Uso básico – Cliente de usuario (core)
|
|
25
|
+
```ts
|
|
26
|
+
import { ZenitClient } from 'zenit-sdk';
|
|
27
|
+
|
|
28
|
+
const client = new ZenitClient({
|
|
29
|
+
baseUrl: 'https://mi-zenit.com/api/v1'
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
async function demo() {
|
|
33
|
+
const login = await client.auth.login({
|
|
34
|
+
email: '<EMAIL>',
|
|
35
|
+
password: '<PASSWORD>'
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
console.log('User:', login.user);
|
|
39
|
+
|
|
40
|
+
const me = await client.auth.me();
|
|
41
|
+
console.log('Me:', me);
|
|
42
|
+
|
|
43
|
+
const valid = await client.auth.validate();
|
|
44
|
+
console.log('Validate:', valid);
|
|
45
|
+
|
|
46
|
+
const refreshed = await client.auth.refresh(login.refreshToken);
|
|
47
|
+
console.log('Refresh:', refreshed);
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Uso básico – SDK Token (core)
|
|
52
|
+
```ts
|
|
53
|
+
import { ZenitClient } from 'zenit-sdk';
|
|
54
|
+
|
|
55
|
+
const client = new ZenitClient({
|
|
56
|
+
baseUrl: 'https://mi-zenit.com/api/v1',
|
|
57
|
+
sdkToken: '<SDK_TOKEN>'
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
async function demoSdk() {
|
|
61
|
+
const validation = await client.sdkAuth.validateSdkToken();
|
|
62
|
+
console.log('SDK token validation:', validation);
|
|
63
|
+
|
|
64
|
+
const exchange = await client.sdkAuth.exchangeSdkToken();
|
|
65
|
+
console.log('SDK exchange:', exchange);
|
|
66
|
+
|
|
67
|
+
const me = await client.auth.me();
|
|
68
|
+
console.log('Me using SDK access token:', me);
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Uso básico – Componente React `ZenitMap`
|
|
73
|
+
```tsx
|
|
74
|
+
import React from 'react';
|
|
75
|
+
import { ZenitClient } from 'zenit-sdk';
|
|
76
|
+
import { ZenitMap } from 'zenit-sdk/react';
|
|
77
|
+
import 'leaflet/dist/leaflet.css';
|
|
78
|
+
|
|
79
|
+
const client = new ZenitClient({
|
|
80
|
+
baseUrl: 'https://mi-zenit.com/api/v1',
|
|
81
|
+
sdkToken: '<SDK_TOKEN>'
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
export function App() {
|
|
85
|
+
return (
|
|
86
|
+
<div>
|
|
87
|
+
<h1>Demo ZenitMap</h1>
|
|
88
|
+
<ZenitMap client={client} mapId={123} />
|
|
89
|
+
</div>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
Si las capas del mapa incluyen `layer.label`, ZenitMap mostrará marcadores de etiqueta usando esa propiedad de las
|
|
94
|
+
features (respeta visibilidad y opacidad de la capa).
|
|
95
|
+
|
|
96
|
+
### Chat flotante `FloatingChatBox` (Zenit AI)
|
|
97
|
+
El SDK incluye un chat flotante para conversar con Zenit AI usando los endpoints de mapas. Solo necesitas entregar
|
|
98
|
+
`baseUrl` y `mapId` (el token es opcional, pero se puede inyectar con `accessToken` o `getAccessToken`).
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
import React from 'react';
|
|
102
|
+
import { FloatingChatBox } from 'zenit-sdk/react';
|
|
103
|
+
|
|
104
|
+
export function App() {
|
|
105
|
+
return (
|
|
106
|
+
<>
|
|
107
|
+
<FloatingChatBox
|
|
108
|
+
baseUrl="https://mi-zenit.com/api/v1"
|
|
109
|
+
mapId={123}
|
|
110
|
+
filteredLayerIds={[45, 98]}
|
|
111
|
+
filters={{ CODREGION: 10 }}
|
|
112
|
+
getAccessToken={() => localStorage.getItem('access_token') ?? ''}
|
|
113
|
+
/>
|
|
114
|
+
</>
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
El chat funciona también en modo guest (`userId` nulo/omitido). Si no hay `mapId`, el componente muestra un estado
|
|
120
|
+
deshabilitado con el mensaje “Selecciona un mapa para usar el asistente”.
|
|
121
|
+
|
|
122
|
+
### Panel reutilizable de capas y filtros `ZenitLayerManager`
|
|
123
|
+
El SDK incluye un panel listo para usar que administra visibilidad, opacidad y filtros por propiedades usando los endpoints `getLayerFeaturesCatalog` y `filter-multiple`. Puedes combinarlo con `ZenitMap` para mostrar el GeoJSON filtrado como overlay:
|
|
124
|
+
|
|
125
|
+
```tsx
|
|
126
|
+
import React, { useState } from 'react';
|
|
127
|
+
import { ZenitClient, type FilterMultipleMetadata, type GeoJsonFeatureCollection } from 'zenit-sdk';
|
|
128
|
+
import { ZenitLayerManager, ZenitMap } from 'zenit-sdk/react';
|
|
129
|
+
import 'leaflet/dist/leaflet.css';
|
|
130
|
+
|
|
131
|
+
const client = new ZenitClient({ baseUrl: 'https://mi-zenit.com/api/v1', sdkToken: '<SDK_TOKEN>' });
|
|
132
|
+
|
|
133
|
+
export function App() {
|
|
134
|
+
const [overlay, setOverlay] = useState<GeoJsonFeatureCollection | null>(null);
|
|
135
|
+
const [metadata, setMetadata] = useState<FilterMultipleMetadata | undefined>();
|
|
136
|
+
const [layerControls, setLayerControls] = useState<
|
|
137
|
+
Array<{ layerId: number | string; visible: boolean; opacity: number }>
|
|
138
|
+
>([]);
|
|
139
|
+
|
|
140
|
+
return (
|
|
141
|
+
<div style={{ display: 'flex', height: 600 }}>
|
|
142
|
+
<ZenitLayerManager
|
|
143
|
+
client={client}
|
|
144
|
+
mapId={11}
|
|
145
|
+
onFilteredGeojson={(geojson, meta) => {
|
|
146
|
+
setOverlay(geojson);
|
|
147
|
+
setMetadata(meta);
|
|
148
|
+
}}
|
|
149
|
+
onLayerStatesChange={setLayerControls}
|
|
150
|
+
/>
|
|
151
|
+
<ZenitMap
|
|
152
|
+
client={client}
|
|
153
|
+
mapId={11}
|
|
154
|
+
showLayerPanel={false}
|
|
155
|
+
overlayGeojson={overlay}
|
|
156
|
+
layerControls={layerControls}
|
|
157
|
+
/>
|
|
158
|
+
<pre>{JSON.stringify(metadata, null, 2)}</pre>
|
|
159
|
+
</div>
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### API de mapas y capas (core)
|
|
165
|
+
```ts
|
|
166
|
+
import { ZenitClient, getCatalogSupport, ZenitCatalogNotSupportedError } from 'zenit-sdk';
|
|
167
|
+
|
|
168
|
+
const client = new ZenitClient({ baseUrl: 'https://mi-zenit.com/api/v1', accessToken: '<JWT>' });
|
|
169
|
+
|
|
170
|
+
// Metadatos de mapa (incluye capas visibles si includeLayers=true)
|
|
171
|
+
const map = await client.maps.getMap(11, true);
|
|
172
|
+
|
|
173
|
+
// Metadatos de capa (las respuestas usan ApiResponse con `data` y metadata opcional)
|
|
174
|
+
const layer = await client.layers.getLayer(123);
|
|
175
|
+
console.log('Layer:', layer.data);
|
|
176
|
+
|
|
177
|
+
// GeoJSON completo
|
|
178
|
+
const geojson = await client.layers.getLayerGeoJson(123);
|
|
179
|
+
console.log('GeoJSON features:', geojson.data.features?.length ?? 0);
|
|
180
|
+
|
|
181
|
+
// GeoJSON limitado por bounding box
|
|
182
|
+
const geojsonBBox = await client.layers.getLayerGeoJsonBBox({
|
|
183
|
+
id: 123,
|
|
184
|
+
bbox: {
|
|
185
|
+
minLon: -58.6,
|
|
186
|
+
minLat: -34.7,
|
|
187
|
+
maxLon: -58.3,
|
|
188
|
+
maxLat: -34.4,
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
console.log('GeoJSON bbox features:', geojsonBBox.data.features?.length ?? 0);
|
|
192
|
+
|
|
193
|
+
// Intersección con una geometría
|
|
194
|
+
const intersected = await client.layers.getLayerGeoJsonIntersect({ id: 123, geometry, maxFeatures: 5000 });
|
|
195
|
+
console.log('GeoJSON intersected features:', intersected.data.features?.length ?? 0);
|
|
196
|
+
|
|
197
|
+
// Catálogo de propiedades de features de una capa
|
|
198
|
+
const catalog = await client.layers.getLayerFeaturesCatalog(17);
|
|
199
|
+
console.log('Catalogo de capa', catalog.data);
|
|
200
|
+
|
|
201
|
+
// Catálogo con validación previa
|
|
202
|
+
const support = getCatalogSupport({ layerType: 'polygon' });
|
|
203
|
+
if (support.supported) {
|
|
204
|
+
const safeCatalog = await client.layers.getLayerFeaturesCatalog(17, {
|
|
205
|
+
layerType: 'polygon',
|
|
206
|
+
strict: true, // fail-fast sin request si la geometría no está soportada
|
|
207
|
+
});
|
|
208
|
+
console.log('Catálogo soportado', safeCatalog.data);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Filtrado simultáneo en múltiples capas multipolygon
|
|
212
|
+
const filtered = await client.layers.filterMultipleLayersFeatures({
|
|
213
|
+
layerIds: [32, 17],
|
|
214
|
+
filters: { CODREGION: 10 },
|
|
215
|
+
});
|
|
216
|
+
console.log('filter-multiple data', filtered.data);
|
|
217
|
+
|
|
218
|
+
// Filtrado resiliente con capas mixtas (multipolygon + otras)
|
|
219
|
+
const mixedFiltered = await client.layers.filterMultipleWithFallback({
|
|
220
|
+
layerIds: [32, 17, 99],
|
|
221
|
+
filters: { CODREGION: 10 },
|
|
222
|
+
layerMetas: [
|
|
223
|
+
{ layerId: 32, layerType: 'multipolygon' },
|
|
224
|
+
{ layerId: 17, layerType: 'polygon' },
|
|
225
|
+
{ layerId: 99, layerType: 'mixed' },
|
|
226
|
+
],
|
|
227
|
+
});
|
|
228
|
+
console.log('filter-multiple fallback perLayer', mixedFiltered.perLayer);
|
|
229
|
+
|
|
230
|
+
// Helper de alto nivel
|
|
231
|
+
const loaded = await client.layers.loadFilteredFeatures({
|
|
232
|
+
layerIds: [32, 17],
|
|
233
|
+
filters: { CODREGION: 10 },
|
|
234
|
+
});
|
|
235
|
+
console.log('GeoJSON filtrado', loaded.geojson.features.length, 'elementos');
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
El endpoint de catálogo solo admite capas `polygon`/`multipolygon`. Usa `getCatalogSupport` para decidir si corresponde
|
|
239
|
+
llamarlo, o pasa `{ strict: true }` a `getLayerFeaturesCatalog` para que el SDK arroje un `ZenitCatalogNotSupportedError`
|
|
240
|
+
antes de hacer la request.
|
|
241
|
+
|
|
242
|
+
Los métodos expuestos en `client.layers` permiten construir el panel de filtros sin dependencias externas:
|
|
243
|
+
- `getLayerFeaturesCatalog(layerId)` carga el catálogo de propiedades para cada capa.
|
|
244
|
+
- `filterMultipleLayersFeatures({ layerIds, filters })` ejecuta `filter-multiple` y retorna GeoJSON + metadata.
|
|
245
|
+
- `loadFilteredFeatures` es un helper tipado que entrega `geojson`, `metadata` y `totalFeatures` listos para usar.
|
|
246
|
+
|
|
247
|
+
Notas de filtrado:
|
|
248
|
+
|
|
249
|
+
- `layerIds` se envía como CSV (`[32,17]` -> `layerIds=32,17`).
|
|
250
|
+
- Los filtros son pares dinámicos `key/value`. Valores en arreglos se serializan como `a,b,c`.
|
|
251
|
+
- Valores `null`/`undefined` o cadenas vacías no se envían en la query.
|
|
252
|
+
|
|
253
|
+
## Ejecutar ejemplos con `.env` opcional
|
|
254
|
+
Los ejemplos usan `ts-node` y leen variables de entorno. Puedes definirlas en tu shell o en un archivo `.env` (no se publica):
|
|
255
|
+
|
|
256
|
+
```env
|
|
257
|
+
ZENIT_BASE_URL=http://localhost:3200/api/v1
|
|
258
|
+
ZENIT_EMAIL=<EMAIL>
|
|
259
|
+
ZENIT_PASSWORD=<PASSWORD>
|
|
260
|
+
ZENIT_SDK_TOKEN=<SDK_TOKEN>
|
|
261
|
+
ZENIT_ACCESS_TOKEN=<ACCESS_TOKEN>
|
|
262
|
+
ZENIT_MAP_ID=11
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
En PowerShell:
|
|
266
|
+
```powershell
|
|
267
|
+
$env:ZENIT_BASE_URL="http://localhost:3200/api/v1"
|
|
268
|
+
$env:ZENIT_EMAIL="user@example.com"
|
|
269
|
+
$env:ZENIT_PASSWORD="secret"
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Comandos disponibles:
|
|
273
|
+
```bash
|
|
274
|
+
npm run example:auth
|
|
275
|
+
npm run example:sdk
|
|
276
|
+
npm run example:map
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
El `baseUrl` por defecto de los ejemplos es `http://localhost:3200/api/v1` si no se especifica.
|