geo-engine-node 1.1.2 → 1.1.3
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/.idea/modules.xml +8 -0
- package/.idea/node.js.iml +8 -0
- package/Readme.md +48 -51
- package/index.js +1 -1
- package/package.json +1 -1
- package/dist/index.cjs +0 -115
- package/dist/index.d.cts +0 -110
- package/dist/index.d.ts +0 -110
- package/dist/index.js +0 -95
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<module type="WEB_MODULE" version="4">
|
|
3
|
+
<component name="NewModuleRootManager">
|
|
4
|
+
<content url="file://$MODULE_DIR$" />
|
|
5
|
+
<orderEntry type="inheritedJdk" />
|
|
6
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
|
7
|
+
</component>
|
|
8
|
+
</module>
|
package/Readme.md
CHANGED
|
@@ -1,10 +1,21 @@
|
|
|
1
|
+
# 📦 Geo-Engine Node.js SDK
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
Cliente oficial de alto rendimiento para interactuar con la plataforma **Geo-Engine**.
|
|
9
|
+
Procesa ubicaciones en tiempo real, detecta cruces de geocercas y dispara webhooks en milisegundos.
|
|
1
10
|
|
|
2
11
|
---
|
|
3
12
|
|
|
4
|
-
|
|
13
|
+
## ✨ Características
|
|
5
14
|
|
|
6
|
-
|
|
7
|
-
|
|
15
|
+
- 🚀 **Rendimiento:** Diseñado para manejar alta ingestión de datos.
|
|
16
|
+
- 🛡️ **Type-Safe:** Incluye definiciones TypeScript (`.d.ts`) nativas.
|
|
17
|
+
- 📦 **Híbrido:** Funciona con `require` (CommonJS) y `import` (ES Modules).
|
|
18
|
+
- ⚡ **Ligero:** Cero dependencias pesadas.
|
|
8
19
|
|
|
9
20
|
---
|
|
10
21
|
|
|
@@ -12,24 +23,37 @@ Permite enviar ubicaciones en tiempo real y gestionar **geocercas** desde tus ap
|
|
|
12
23
|
|
|
13
24
|
```bash
|
|
14
25
|
npm install geo-engine-node
|
|
15
|
-
|
|
26
|
+
````
|
|
16
27
|
|
|
17
28
|
---
|
|
18
29
|
|
|
19
30
|
## ⚡ Inicio Rápido
|
|
20
31
|
|
|
21
|
-
|
|
32
|
+
Geo-Engine soporta tanto sintaxis moderna como clásica.
|
|
33
|
+
|
|
34
|
+
### Opción A: ES Modules (Recomendado)
|
|
22
35
|
|
|
23
36
|
```js
|
|
24
|
-
|
|
37
|
+
import GeoEngine from 'geo-engine-node';
|
|
25
38
|
|
|
26
|
-
// Inicializa con tu API Key
|
|
39
|
+
// Inicializa con tu API Key
|
|
27
40
|
const geo = new GeoEngine('sk_test_12345abcdef');
|
|
28
41
|
|
|
29
42
|
// Envía una coordenada (ID, Latitud, Longitud)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
43
|
+
try {
|
|
44
|
+
const res = await geo.sendLocation('camion-01', 19.4326, -99.1332);
|
|
45
|
+
console.log('✅ Ubicación procesada:', res);
|
|
46
|
+
} catch (err) {
|
|
47
|
+
console.error('❌ Error:', err.message);
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Opción B: CommonJS (Legacy)
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
const GeoEngine = require('geo-engine-node');
|
|
55
|
+
|
|
56
|
+
const geo = new GeoEngine('sk_test_...');
|
|
33
57
|
```
|
|
34
58
|
|
|
35
59
|
---
|
|
@@ -45,45 +69,34 @@ Crea una nueva instancia del cliente.
|
|
|
45
69
|
* `apiKey` (`string`): Tu clave secreta de API.
|
|
46
70
|
* `options` (`object`, opcional):
|
|
47
71
|
|
|
48
|
-
* `timeout`: Tiempo de espera en ms
|
|
49
|
-
* `ingestUrl`: URL personalizada
|
|
50
|
-
* `managementUrl`: URL
|
|
72
|
+
* `timeout`: Tiempo de espera en ms (default: `10000`)
|
|
73
|
+
* `ingestUrl`: URL personalizada (útil para proxies o testing)
|
|
74
|
+
* `managementUrl`: URL del servicio de administración
|
|
51
75
|
|
|
52
76
|
---
|
|
53
77
|
|
|
54
78
|
### `geo.sendLocation(deviceId, lat, lng)`
|
|
55
79
|
|
|
56
80
|
Envía un punto de rastreo al motor de ingestión.
|
|
57
|
-
El sistema
|
|
81
|
+
El sistema evaluará automáticamente las reglas espaciales.
|
|
58
82
|
|
|
59
83
|
**Parámetros:**
|
|
60
84
|
|
|
61
|
-
* `deviceId` (`string`):
|
|
62
|
-
* `lat` (`number`): Latitud decimal.
|
|
63
|
-
* `lng` (`number`): Longitud decimal.
|
|
64
|
-
|
|
65
|
-
**Retorna:**
|
|
66
|
-
`Promise<Object>` con el estado de la cola (`queued`).
|
|
85
|
+
* `deviceId` (`string`): ID único (placa, UUID, etc).
|
|
86
|
+
* `lat` (`number`): Latitud decimal (Ej: `19.43`)
|
|
87
|
+
* `lng` (`number`): Longitud decimal (Ej: `-99.13`)
|
|
67
88
|
|
|
68
89
|
---
|
|
69
90
|
|
|
70
91
|
### `geo.createGeofence(name, coordinates, webhookUrl)`
|
|
71
92
|
|
|
72
|
-
Crea
|
|
73
|
-
|
|
74
|
-
**Parámetros:**
|
|
75
|
-
|
|
76
|
-
* `name` (`string`): Nombre descriptivo (ej: `"Almacén Central"`).
|
|
77
|
-
* `coordinates` (`Array<Array<number>>`):
|
|
78
|
-
Lista de puntos que forman el polígono
|
|
79
|
-
`[[lat, lng], [lat, lng], ...]`
|
|
80
|
-
*(El SDK se encarga de cerrar el polígono si es necesario).*
|
|
81
|
-
* `webhookUrl` (`string`):
|
|
82
|
-
URL donde Geo-Engine enviará una petición **POST** cuando un dispositivo entre en esta zona.
|
|
93
|
+
Crea dinámicamente una zona de monitoreo.
|
|
94
|
+
Geo-Engine enviará un `POST` a tu webhook cuando un activo entre o salga.
|
|
83
95
|
|
|
84
96
|
**Ejemplo:**
|
|
85
97
|
|
|
86
98
|
```js
|
|
99
|
+
// Definir polígono: Array de [Lat, Lng]
|
|
87
100
|
const zona = [
|
|
88
101
|
[19.42, -99.16],
|
|
89
102
|
[19.41, -99.16],
|
|
@@ -92,35 +105,20 @@ const zona = [
|
|
|
92
105
|
];
|
|
93
106
|
|
|
94
107
|
await geo.createGeofence(
|
|
95
|
-
'
|
|
108
|
+
'Almacén Central',
|
|
96
109
|
zona,
|
|
97
|
-
'https://mi-api.com/
|
|
110
|
+
'https://mi-api.com/webhooks/geofence-alert'
|
|
98
111
|
);
|
|
99
112
|
```
|
|
100
113
|
|
|
101
114
|
---
|
|
102
115
|
|
|
103
|
-
## 🛡️ Manejo de Errores
|
|
104
|
-
|
|
105
|
-
El SDK lanza errores descriptivos que puedes capturar fácilmente:
|
|
106
|
-
|
|
107
|
-
```js
|
|
108
|
-
try {
|
|
109
|
-
await geo.sendLocation('x', 0, 0);
|
|
110
|
-
} catch (error) {
|
|
111
|
-
console.error(error.message);
|
|
112
|
-
// Ej: "GeoEngine API Error (401): Invalid API Key"
|
|
113
|
-
}
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
---
|
|
117
|
-
|
|
118
116
|
## 🧪 Desarrollo Local
|
|
119
117
|
|
|
120
|
-
|
|
118
|
+
Ideal para probar con tu propia instancia de Geo-Engine corriendo en Docker o Localhost.
|
|
121
119
|
|
|
122
120
|
```js
|
|
123
|
-
const geo = new GeoEngine('
|
|
121
|
+
const geo = new GeoEngine('local-key', {
|
|
124
122
|
ingestUrl: 'http://localhost:8080',
|
|
125
123
|
managementUrl: 'http://localhost:8081'
|
|
126
124
|
});
|
|
@@ -132,4 +130,3 @@ const geo = new GeoEngine('mi-clave-local', {
|
|
|
132
130
|
|
|
133
131
|
MIT © Geo-Engine Team
|
|
134
132
|
|
|
135
|
-
---
|
package/index.js
CHANGED
package/package.json
CHANGED
package/dist/index.cjs
DELETED
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
-
var __export = (target, all) => {
|
|
6
|
-
for (var name in all)
|
|
7
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
8
|
-
};
|
|
9
|
-
var __copyProps = (to, from, except, desc) => {
|
|
10
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
-
for (let key of __getOwnPropNames(from))
|
|
12
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
-
}
|
|
15
|
-
return to;
|
|
16
|
-
};
|
|
17
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
18
|
-
|
|
19
|
-
// index.js
|
|
20
|
-
var index_exports = {};
|
|
21
|
-
__export(index_exports, {
|
|
22
|
-
default: () => index_default
|
|
23
|
-
});
|
|
24
|
-
module.exports = __toCommonJS(index_exports);
|
|
25
|
-
var DEFAULTS = {
|
|
26
|
-
managementUrl: "https://api.geoengine.dev",
|
|
27
|
-
ingestUrl: "https://ingest.geoengine.dev",
|
|
28
|
-
timeout: 1e4
|
|
29
|
-
};
|
|
30
|
-
var GeoEngine = class {
|
|
31
|
-
/**
|
|
32
|
-
* Inicializa el cliente de Geo-Engine.
|
|
33
|
-
* @param {string} apiKey - Tu API Key.
|
|
34
|
-
* @param {Object} [options] - Configuración opcional.
|
|
35
|
-
*/
|
|
36
|
-
constructor(apiKey, options = {}) {
|
|
37
|
-
if (!apiKey) {
|
|
38
|
-
throw new Error("GeoEngine: API Key es requerida.");
|
|
39
|
-
}
|
|
40
|
-
this.apiKey = apiKey;
|
|
41
|
-
this.config = { ...DEFAULTS, ...options };
|
|
42
|
-
this.userAgent = "GeoEngineNode/1.1.2";
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Helper privado para hacer peticiones con timeout
|
|
46
|
-
*/
|
|
47
|
-
async _request(url, method, body) {
|
|
48
|
-
const controller = new AbortController();
|
|
49
|
-
const id = setTimeout(() => controller.abort(), this.config.timeout);
|
|
50
|
-
try {
|
|
51
|
-
const response = await fetch(url, {
|
|
52
|
-
method,
|
|
53
|
-
headers: {
|
|
54
|
-
"Content-Type": "application/json",
|
|
55
|
-
"X-API-Key": this.apiKey,
|
|
56
|
-
"User-Agent": this.userAgent
|
|
57
|
-
},
|
|
58
|
-
body: JSON.stringify(body),
|
|
59
|
-
signal: controller.signal
|
|
60
|
-
});
|
|
61
|
-
clearTimeout(id);
|
|
62
|
-
if (!response.ok) {
|
|
63
|
-
const errorText = await response.text();
|
|
64
|
-
throw new Error(`GeoEngine API Error (${response.status}): ${errorText}`);
|
|
65
|
-
}
|
|
66
|
-
if (response.status === 204) return null;
|
|
67
|
-
return await response.json();
|
|
68
|
-
} catch (error) {
|
|
69
|
-
clearTimeout(id);
|
|
70
|
-
if (error.name === "AbortError") {
|
|
71
|
-
throw new Error(`GeoEngine: La petici\xF3n excedi\xF3 el tiempo l\xEDmite de ${this.config.timeout}ms`);
|
|
72
|
-
}
|
|
73
|
-
throw error;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Envía una ubicación al motor de ingestión.
|
|
78
|
-
*/
|
|
79
|
-
async sendLocation(deviceId, lat, lng) {
|
|
80
|
-
if (!deviceId || lat === void 0 || lng === void 0) {
|
|
81
|
-
throw new Error("GeoEngine: deviceId, lat y lng son obligatorios.");
|
|
82
|
-
}
|
|
83
|
-
const payload = {
|
|
84
|
-
device_id: deviceId,
|
|
85
|
-
latitude: parseFloat(lat),
|
|
86
|
-
longitude: parseFloat(lng),
|
|
87
|
-
timestamp: Math.floor(Date.now() / 1e3)
|
|
88
|
-
};
|
|
89
|
-
return this._request(`${this.config.ingestUrl}/ingest`, "POST", payload);
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Crea una nueva geocerca.
|
|
93
|
-
*/
|
|
94
|
-
async createGeofence(name, coordinates, webhookUrl) {
|
|
95
|
-
if (!name || !coordinates || coordinates.length < 3) {
|
|
96
|
-
throw new Error("GeoEngine: Se requiere un nombre y al menos 3 coordenadas.");
|
|
97
|
-
}
|
|
98
|
-
const polygon = coordinates.map((p) => [p[1], p[0]]);
|
|
99
|
-
const first = polygon[0];
|
|
100
|
-
const last = polygon[polygon.length - 1];
|
|
101
|
-
if (first[0] !== last[0] || first[1] !== last[1]) {
|
|
102
|
-
polygon.push(first);
|
|
103
|
-
}
|
|
104
|
-
const payload = {
|
|
105
|
-
name,
|
|
106
|
-
webhook_url: webhookUrl,
|
|
107
|
-
geojson: {
|
|
108
|
-
type: "Polygon",
|
|
109
|
-
coordinates: [polygon]
|
|
110
|
-
}
|
|
111
|
-
};
|
|
112
|
-
return this._request(`${this.config.managementUrl}/geofences`, "POST", payload);
|
|
113
|
-
}
|
|
114
|
-
};
|
|
115
|
-
var index_default = GeoEngine;
|
package/dist/index.d.cts
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
const DEFAULTS = {
|
|
2
|
-
managementUrl: 'https://api.geoengine.dev',
|
|
3
|
-
ingestUrl: 'https://ingest.geoengine.dev',
|
|
4
|
-
timeout: 10000
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
class GeoEngine {
|
|
8
|
-
/**
|
|
9
|
-
* Inicializa el cliente de Geo-Engine.
|
|
10
|
-
* @param {string} apiKey - Tu API Key.
|
|
11
|
-
* @param {Object} [options] - Configuración opcional.
|
|
12
|
-
*/
|
|
13
|
-
constructor(apiKey, options = {}) {
|
|
14
|
-
if (!apiKey) {
|
|
15
|
-
throw new Error('GeoEngine: API Key es requerida.');
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
this.apiKey = apiKey;
|
|
19
|
-
this.config = { ...DEFAULTS, ...options };
|
|
20
|
-
this.userAgent = 'GeoEngineNode/1.1.2';
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Helper privado para hacer peticiones con timeout
|
|
25
|
-
*/
|
|
26
|
-
async _request(url, method, body) {
|
|
27
|
-
const controller = new AbortController();
|
|
28
|
-
const id = setTimeout(() => controller.abort(), this.config.timeout);
|
|
29
|
-
|
|
30
|
-
try {
|
|
31
|
-
const response = await fetch(url, {
|
|
32
|
-
method: method,
|
|
33
|
-
headers: {
|
|
34
|
-
'Content-Type': 'application/json',
|
|
35
|
-
'X-API-Key': this.apiKey,
|
|
36
|
-
'User-Agent': this.userAgent
|
|
37
|
-
},
|
|
38
|
-
body: JSON.stringify(body),
|
|
39
|
-
signal: controller.signal
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
clearTimeout(id);
|
|
43
|
-
|
|
44
|
-
if (!response.ok) {
|
|
45
|
-
const errorText = await response.text();
|
|
46
|
-
throw new Error(`GeoEngine API Error (${response.status}): ${errorText}`);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (response.status === 204) return null;
|
|
50
|
-
|
|
51
|
-
return await response.json();
|
|
52
|
-
} catch (error) {
|
|
53
|
-
clearTimeout(id);
|
|
54
|
-
if (error.name === 'AbortError') {
|
|
55
|
-
throw new Error(`GeoEngine: La petición excedió el tiempo límite de ${this.config.timeout}ms`);
|
|
56
|
-
}
|
|
57
|
-
throw error;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Envía una ubicación al motor de ingestión.
|
|
63
|
-
*/
|
|
64
|
-
async sendLocation(deviceId, lat, lng) {
|
|
65
|
-
if (!deviceId || lat === undefined || lng === undefined) {
|
|
66
|
-
throw new Error("GeoEngine: deviceId, lat y lng son obligatorios.");
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const payload = {
|
|
70
|
-
device_id: deviceId,
|
|
71
|
-
latitude: parseFloat(lat),
|
|
72
|
-
longitude: parseFloat(lng),
|
|
73
|
-
timestamp: Math.floor(Date.now() / 1000)
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
return this._request(`${this.config.ingestUrl}/ingest`, 'POST', payload);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Crea una nueva geocerca.
|
|
81
|
-
*/
|
|
82
|
-
async createGeofence(name, coordinates, webhookUrl) {
|
|
83
|
-
if (!name || !coordinates || coordinates.length < 3) {
|
|
84
|
-
throw new Error("GeoEngine: Se requiere un nombre y al menos 3 coordenadas.");
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Convertir formato simple [[lat,lng]] a GeoJSON [Lng, Lat]
|
|
88
|
-
const polygon = coordinates.map(p => [p[1], p[0]]);
|
|
89
|
-
|
|
90
|
-
// Cerrar polígono automáticamente
|
|
91
|
-
const first = polygon[0];
|
|
92
|
-
const last = polygon[polygon.length - 1];
|
|
93
|
-
if (first[0] !== last[0] || first[1] !== last[1]) {
|
|
94
|
-
polygon.push(first);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const payload = {
|
|
98
|
-
name,
|
|
99
|
-
webhook_url: webhookUrl,
|
|
100
|
-
geojson: {
|
|
101
|
-
type: 'Polygon',
|
|
102
|
-
coordinates: [polygon]
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
return this._request(`${this.config.managementUrl}/geofences`, 'POST', payload);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
export { GeoEngine as default };
|
package/dist/index.d.ts
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
const DEFAULTS = {
|
|
2
|
-
managementUrl: 'https://api.geoengine.dev',
|
|
3
|
-
ingestUrl: 'https://ingest.geoengine.dev',
|
|
4
|
-
timeout: 10000
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
class GeoEngine {
|
|
8
|
-
/**
|
|
9
|
-
* Inicializa el cliente de Geo-Engine.
|
|
10
|
-
* @param {string} apiKey - Tu API Key.
|
|
11
|
-
* @param {Object} [options] - Configuración opcional.
|
|
12
|
-
*/
|
|
13
|
-
constructor(apiKey, options = {}) {
|
|
14
|
-
if (!apiKey) {
|
|
15
|
-
throw new Error('GeoEngine: API Key es requerida.');
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
this.apiKey = apiKey;
|
|
19
|
-
this.config = { ...DEFAULTS, ...options };
|
|
20
|
-
this.userAgent = 'GeoEngineNode/1.1.2';
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Helper privado para hacer peticiones con timeout
|
|
25
|
-
*/
|
|
26
|
-
async _request(url, method, body) {
|
|
27
|
-
const controller = new AbortController();
|
|
28
|
-
const id = setTimeout(() => controller.abort(), this.config.timeout);
|
|
29
|
-
|
|
30
|
-
try {
|
|
31
|
-
const response = await fetch(url, {
|
|
32
|
-
method: method,
|
|
33
|
-
headers: {
|
|
34
|
-
'Content-Type': 'application/json',
|
|
35
|
-
'X-API-Key': this.apiKey,
|
|
36
|
-
'User-Agent': this.userAgent
|
|
37
|
-
},
|
|
38
|
-
body: JSON.stringify(body),
|
|
39
|
-
signal: controller.signal
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
clearTimeout(id);
|
|
43
|
-
|
|
44
|
-
if (!response.ok) {
|
|
45
|
-
const errorText = await response.text();
|
|
46
|
-
throw new Error(`GeoEngine API Error (${response.status}): ${errorText}`);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (response.status === 204) return null;
|
|
50
|
-
|
|
51
|
-
return await response.json();
|
|
52
|
-
} catch (error) {
|
|
53
|
-
clearTimeout(id);
|
|
54
|
-
if (error.name === 'AbortError') {
|
|
55
|
-
throw new Error(`GeoEngine: La petición excedió el tiempo límite de ${this.config.timeout}ms`);
|
|
56
|
-
}
|
|
57
|
-
throw error;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Envía una ubicación al motor de ingestión.
|
|
63
|
-
*/
|
|
64
|
-
async sendLocation(deviceId, lat, lng) {
|
|
65
|
-
if (!deviceId || lat === undefined || lng === undefined) {
|
|
66
|
-
throw new Error("GeoEngine: deviceId, lat y lng son obligatorios.");
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const payload = {
|
|
70
|
-
device_id: deviceId,
|
|
71
|
-
latitude: parseFloat(lat),
|
|
72
|
-
longitude: parseFloat(lng),
|
|
73
|
-
timestamp: Math.floor(Date.now() / 1000)
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
return this._request(`${this.config.ingestUrl}/ingest`, 'POST', payload);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Crea una nueva geocerca.
|
|
81
|
-
*/
|
|
82
|
-
async createGeofence(name, coordinates, webhookUrl) {
|
|
83
|
-
if (!name || !coordinates || coordinates.length < 3) {
|
|
84
|
-
throw new Error("GeoEngine: Se requiere un nombre y al menos 3 coordenadas.");
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Convertir formato simple [[lat,lng]] a GeoJSON [Lng, Lat]
|
|
88
|
-
const polygon = coordinates.map(p => [p[1], p[0]]);
|
|
89
|
-
|
|
90
|
-
// Cerrar polígono automáticamente
|
|
91
|
-
const first = polygon[0];
|
|
92
|
-
const last = polygon[polygon.length - 1];
|
|
93
|
-
if (first[0] !== last[0] || first[1] !== last[1]) {
|
|
94
|
-
polygon.push(first);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const payload = {
|
|
98
|
-
name,
|
|
99
|
-
webhook_url: webhookUrl,
|
|
100
|
-
geojson: {
|
|
101
|
-
type: 'Polygon',
|
|
102
|
-
coordinates: [polygon]
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
return this._request(`${this.config.managementUrl}/geofences`, 'POST', payload);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
export { GeoEngine as default };
|
package/dist/index.js
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
// index.js
|
|
2
|
-
var DEFAULTS = {
|
|
3
|
-
managementUrl: "https://api.geoengine.dev",
|
|
4
|
-
ingestUrl: "https://ingest.geoengine.dev",
|
|
5
|
-
timeout: 1e4
|
|
6
|
-
};
|
|
7
|
-
var GeoEngine = class {
|
|
8
|
-
/**
|
|
9
|
-
* Inicializa el cliente de Geo-Engine.
|
|
10
|
-
* @param {string} apiKey - Tu API Key.
|
|
11
|
-
* @param {Object} [options] - Configuración opcional.
|
|
12
|
-
*/
|
|
13
|
-
constructor(apiKey, options = {}) {
|
|
14
|
-
if (!apiKey) {
|
|
15
|
-
throw new Error("GeoEngine: API Key es requerida.");
|
|
16
|
-
}
|
|
17
|
-
this.apiKey = apiKey;
|
|
18
|
-
this.config = { ...DEFAULTS, ...options };
|
|
19
|
-
this.userAgent = "GeoEngineNode/1.1.2";
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Helper privado para hacer peticiones con timeout
|
|
23
|
-
*/
|
|
24
|
-
async _request(url, method, body) {
|
|
25
|
-
const controller = new AbortController();
|
|
26
|
-
const id = setTimeout(() => controller.abort(), this.config.timeout);
|
|
27
|
-
try {
|
|
28
|
-
const response = await fetch(url, {
|
|
29
|
-
method,
|
|
30
|
-
headers: {
|
|
31
|
-
"Content-Type": "application/json",
|
|
32
|
-
"X-API-Key": this.apiKey,
|
|
33
|
-
"User-Agent": this.userAgent
|
|
34
|
-
},
|
|
35
|
-
body: JSON.stringify(body),
|
|
36
|
-
signal: controller.signal
|
|
37
|
-
});
|
|
38
|
-
clearTimeout(id);
|
|
39
|
-
if (!response.ok) {
|
|
40
|
-
const errorText = await response.text();
|
|
41
|
-
throw new Error(`GeoEngine API Error (${response.status}): ${errorText}`);
|
|
42
|
-
}
|
|
43
|
-
if (response.status === 204) return null;
|
|
44
|
-
return await response.json();
|
|
45
|
-
} catch (error) {
|
|
46
|
-
clearTimeout(id);
|
|
47
|
-
if (error.name === "AbortError") {
|
|
48
|
-
throw new Error(`GeoEngine: La petici\xF3n excedi\xF3 el tiempo l\xEDmite de ${this.config.timeout}ms`);
|
|
49
|
-
}
|
|
50
|
-
throw error;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Envía una ubicación al motor de ingestión.
|
|
55
|
-
*/
|
|
56
|
-
async sendLocation(deviceId, lat, lng) {
|
|
57
|
-
if (!deviceId || lat === void 0 || lng === void 0) {
|
|
58
|
-
throw new Error("GeoEngine: deviceId, lat y lng son obligatorios.");
|
|
59
|
-
}
|
|
60
|
-
const payload = {
|
|
61
|
-
device_id: deviceId,
|
|
62
|
-
latitude: parseFloat(lat),
|
|
63
|
-
longitude: parseFloat(lng),
|
|
64
|
-
timestamp: Math.floor(Date.now() / 1e3)
|
|
65
|
-
};
|
|
66
|
-
return this._request(`${this.config.ingestUrl}/ingest`, "POST", payload);
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Crea una nueva geocerca.
|
|
70
|
-
*/
|
|
71
|
-
async createGeofence(name, coordinates, webhookUrl) {
|
|
72
|
-
if (!name || !coordinates || coordinates.length < 3) {
|
|
73
|
-
throw new Error("GeoEngine: Se requiere un nombre y al menos 3 coordenadas.");
|
|
74
|
-
}
|
|
75
|
-
const polygon = coordinates.map((p) => [p[1], p[0]]);
|
|
76
|
-
const first = polygon[0];
|
|
77
|
-
const last = polygon[polygon.length - 1];
|
|
78
|
-
if (first[0] !== last[0] || first[1] !== last[1]) {
|
|
79
|
-
polygon.push(first);
|
|
80
|
-
}
|
|
81
|
-
const payload = {
|
|
82
|
-
name,
|
|
83
|
-
webhook_url: webhookUrl,
|
|
84
|
-
geojson: {
|
|
85
|
-
type: "Polygon",
|
|
86
|
-
coordinates: [polygon]
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
return this._request(`${this.config.managementUrl}/geofences`, "POST", payload);
|
|
90
|
-
}
|
|
91
|
-
};
|
|
92
|
-
var index_default = GeoEngine;
|
|
93
|
-
export {
|
|
94
|
-
index_default as default
|
|
95
|
-
};
|