@geolonia/geonicdb-sdk 0.11.0 → 0.12.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 CHANGED
@@ -414,6 +414,7 @@ handle.stop();
414
414
  | `limit` | `number` | Max results |
415
415
  | `offset` | `number` | Pagination offset |
416
416
  | `q` | `string` | NGSI-LD query expression |
417
+ | `options` | `string` | NGSI-LD representation options (comma-separated): `sysAttrs` (include `createdAt`/`modifiedAt`), `keyValues`, `concise`, `normalized` |
417
418
 
418
419
  #### `CountEntitiesParams`
419
420
 
@@ -453,6 +454,7 @@ handle.stop();
453
454
  | `timerel` | `string` | Temporal relation (`before`, `after`, `between`) |
454
455
  | `limit` | `number` | Max results |
455
456
  | `offset` | `number` | Pagination offset |
457
+ | `options` | `string` | NGSI-LD representation options (comma-separated): `sysAttrs`, `temporalValues`, `aggregatedValues` |
456
458
 
457
459
  ### Batch Operations
458
460
 
@@ -556,6 +558,55 @@ try {
556
558
  | `RateLimitError` | 429 | Rate limited (`retryAfter` property) |
557
559
  | `NetworkError` | — | Fetch failure, DNS error, timeout |
558
560
 
561
+ ## React Hooks (`@geolonia/geonicdb-sdk/react`)
562
+
563
+ Optional React integration, shipped as a separate subpath so the core SDK stays
564
+ framework-agnostic. Requires React 18 or 19 (declared as an **optional peer
565
+ dependency** — core consumers are unaffected).
566
+
567
+ ```tsx
568
+ import GeonicDB from '@geolonia/geonicdb-sdk';
569
+ import { useLdEntities, useTemporalData, GeonicDbMap } from '@geolonia/geonicdb-sdk/react';
570
+
571
+ const db = new GeonicDB({ baseUrl, tenant });
572
+
573
+ function Rooms() {
574
+ const { entities, loading, error, refetch } = useLdEntities(db, { type: 'Room', limit: 100 });
575
+ if (loading) return <p>Loading…</p>;
576
+ if (error) return <p>{error.message}</p>;
577
+ return <GeonicDbMap entities={entities} apiKey="YOUR-GEOLONIA-KEY" />;
578
+ }
579
+ ```
580
+
581
+ | Export | Type | Description |
582
+ |--------|------|-------------|
583
+ | `useLdEntities(client, options?)` | hook | NGSI-LD エンティティ取得。`{ entities, loading, error, refetch }` を返す。`options`: `type` / `limit` / `attrs` / `q` / `scopeQ` |
584
+ | `useTemporalData(client, options)` | hook | Temporal API 取得。`{ data, loading, error, refetch }` を返す。`options.id` 指定時は単一エンティティ、`options.enabled === false` で取得スキップ |
585
+ | `GeonicDbMap` | component | Geolonia 地図にエンティティをマーカー描画。`@geolonia/embed`(optional peer)を動的 import |
586
+
587
+ 両 hook は in-flight リクエストを世代管理しており、`options` 変更やアンマウント時に古いレスポンスが新しい結果を上書きしない。`GeonicDbMap` のポップアップは `entity.id` / `entity.type` を HTML エスケープして描画する。
588
+
589
+ ## NGSIv2 Client (`@geolonia/geonicdb-sdk/ngsi-v2`)
590
+
591
+ NGSIv2 (`/v2/entities`) を叩く軽量クライアント。NGSI-LD を使うコア SDK とは独立した
592
+ サブパスで、NGSIv2 のみを使う利用者向け。
593
+
594
+ ```ts
595
+ import { createNgsiV2Client } from '@geolonia/geonicdb-sdk/ngsi-v2';
596
+
597
+ const client = createNgsiV2Client({ baseUrl: 'https://geonicdb.example.com', apiKey: 'KEY', service: 'mytenant' });
598
+ const rooms = await client.getEntities({ type: 'Room', limit: 20 });
599
+ ```
600
+
601
+ | Method | Description |
602
+ |--------|-------------|
603
+ | `createNgsiV2Client(config)` | `NgsiV2Client` を生成。`config`: `baseUrl`(必須)/ `apiKey` / `service` |
604
+ | `getEntities(options?)` | エンティティ一覧(`type` / `q` / `limit` / `offset` / `attrs` / `options`) |
605
+ | `getEntity(id, options?)` | 単一エンティティ取得 |
606
+ | `createEntity(entity)` | エンティティ作成 |
607
+ | `updateEntityAttributes(id, attrs)` | 属性の部分更新 |
608
+ | `deleteEntity(id)` | エンティティ削除 |
609
+
559
610
  ## License
560
611
 
561
612
  MIT
package/geonicdb.d.ts CHANGED
@@ -121,6 +121,16 @@ export interface GetEntitiesParams {
121
121
  count?: boolean;
122
122
  /** GeoProperty key to use (default `location`) */
123
123
  geoproperty?: string;
124
+ /**
125
+ * NGSI-LD representation options (`options` query param)。カンマ区切りで複数指定可。
126
+ * - `sysAttrs` — システム属性 (`createdAt` / `modifiedAt`) を含める
127
+ * - `keyValues` — 簡易表現 (属性を値だけに圧縮)
128
+ * - `concise` — concise 表現
129
+ * - `normalized` — 正規化表現 (デフォルト)
130
+ *
131
+ * 例: `'sysAttrs'`, `'keyValues,sysAttrs'`。
132
+ */
133
+ options?: string;
124
134
  }
125
135
  /** Parameters for counting entities. */
126
136
  export interface CountEntitiesParams {
@@ -254,6 +264,15 @@ export interface GetTemporalEntitiesParams {
254
264
  limit?: number;
255
265
  /** Pagination offset */
256
266
  offset?: number;
267
+ /**
268
+ * NGSI-LD representation options (`options` query param)。カンマ区切りで複数指定可。
269
+ * - `sysAttrs` — システム属性 (`createdAt` / `modifiedAt`) を含める
270
+ * - `temporalValues` — 時系列を簡易配列表現で返す
271
+ * - `aggregatedValues` — 集約表現で返す
272
+ *
273
+ * 例: `'sysAttrs'`, `'temporalValues'`。
274
+ */
275
+ options?: string;
257
276
  }
258
277
  export type Listener<T> = (data: T) => void;
259
278
  declare class EventEmitter {
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
21
+
22
+ // src/sdk/ngsi-v2/index.ts
23
+ var index_exports = {};
24
+ __export(index_exports, {
25
+ NgsiV2Client: () => NgsiV2Client,
26
+ createNgsiV2Client: () => createNgsiV2Client
27
+ });
28
+ module.exports = __toCommonJS(index_exports);
29
+ var NgsiV2Client = class {
30
+ constructor(config) {
31
+ __publicField(this, "baseUrl");
32
+ __publicField(this, "headers");
33
+ this.baseUrl = config.baseUrl.replace(/\/$/, "");
34
+ this.headers = {
35
+ "Content-Type": "application/json",
36
+ Accept: "application/json"
37
+ };
38
+ if (config.service) this.headers["Fiware-Service"] = config.service;
39
+ if (config.servicePath) this.headers["Fiware-ServicePath"] = config.servicePath;
40
+ }
41
+ async request(method, path, body) {
42
+ const res = await fetch(`${this.baseUrl}${path}`, {
43
+ method,
44
+ headers: this.headers,
45
+ body: body !== void 0 ? JSON.stringify(body) : void 0
46
+ });
47
+ if (!res.ok) {
48
+ const err = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
49
+ const description = typeof err["description"] === "string" ? err["description"] : void 0;
50
+ const error = typeof err["error"] === "string" ? err["error"] : void 0;
51
+ throw new Error(description ?? error ?? `HTTP ${res.status}`);
52
+ }
53
+ if (res.status === 201 || res.status === 204) return void 0;
54
+ return res.json();
55
+ }
56
+ /** List entities */
57
+ async getEntities(options) {
58
+ const sp = new URLSearchParams();
59
+ if (options?.type) sp.set("type", options.type);
60
+ if (options?.q) sp.set("q", options.q);
61
+ if (options?.limit !== void 0) sp.set("limit", String(options.limit));
62
+ if (options?.offset !== void 0) sp.set("offset", String(options.offset));
63
+ if (options?.attrs) sp.set("attrs", options.attrs);
64
+ if (options?.options) sp.set("options", options.options);
65
+ const qs = sp.toString();
66
+ return this.request("GET", `/v2/entities${qs ? "?" + qs : ""}`);
67
+ }
68
+ /** Get single entity by ID */
69
+ async getEntity(entityId, options) {
70
+ const sp = new URLSearchParams();
71
+ if (options?.attrs) sp.set("attrs", options.attrs);
72
+ if (options?.options) sp.set("options", options.options);
73
+ const qs = sp.toString();
74
+ return this.request("GET", `/v2/entities/${encodeURIComponent(entityId)}${qs ? "?" + qs : ""}`);
75
+ }
76
+ /** Create entity */
77
+ async createEntity(entity) {
78
+ await this.request("POST", "/v2/entities", entity);
79
+ }
80
+ /** Update entity attributes (partial) */
81
+ async updateEntityAttributes(entityId, attrs) {
82
+ await this.request("PATCH", `/v2/entities/${encodeURIComponent(entityId)}/attrs`, attrs);
83
+ }
84
+ /** Delete entity */
85
+ async deleteEntity(entityId) {
86
+ await this.request("DELETE", `/v2/entities/${encodeURIComponent(entityId)}`);
87
+ }
88
+ };
89
+ function createNgsiV2Client(config) {
90
+ return new NgsiV2Client(config);
91
+ }
92
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/sdk/ngsi-v2/index.ts"],
4
+ "sourcesContent": ["// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 Geolonia Inc.\n// See LICENSE in src/sdk/ for full license text.\n\n/**\n * NGSIv2 basic client \u2014 bundled per ADR\u8AD6\u70B92=a (\u6BBF\u88C1\u53EF\u78BA\u5B9A)\n *\n * Scope: basic entity CRUD only. No subscriptions, no batch ops.\n * For NGSI-LD, use the core GeonicDB client instead.\n */\n\nexport interface NgsiV2ClientConfig {\n baseUrl: string;\n /** FIWARE service (tenant) */\n service?: string;\n /** FIWARE service path */\n servicePath?: string;\n}\n\nexport interface NgsiV2Entity {\n id: string;\n type: string;\n [key: string]: string | NgsiV2Attribute | undefined;\n}\n\nexport interface NgsiV2Attribute {\n type: string;\n value: string | number | boolean | object | null;\n metadata?: Record<string, { type: string; value: unknown }>;\n}\n\nexport interface NgsiV2QueryOptions {\n type?: string;\n q?: string;\n limit?: number;\n offset?: number;\n attrs?: string;\n options?: string;\n}\n\nexport class NgsiV2Client {\n private baseUrl: string;\n private headers: Record<string, string>;\n\n constructor(config: NgsiV2ClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, '');\n this.headers = {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n };\n if (config.service) this.headers['Fiware-Service'] = config.service;\n if (config.servicePath) this.headers['Fiware-ServicePath'] = config.servicePath;\n }\n\n private async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const res = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers: this.headers,\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n if (!res.ok) {\n const err = await res.json().catch(() => ({ error: `HTTP ${res.status}` })) as Record<string, unknown>;\n const description = typeof err['description'] === 'string' ? err['description'] : undefined;\n const error = typeof err['error'] === 'string' ? err['error'] : undefined;\n throw new Error(description ?? error ?? `HTTP ${res.status}`);\n }\n if (res.status === 201 || res.status === 204) return undefined as T;\n return res.json() as Promise<T>;\n }\n\n /** List entities */\n async getEntities(options?: NgsiV2QueryOptions): Promise<NgsiV2Entity[]> {\n const sp = new URLSearchParams();\n if (options?.type) sp.set('type', options.type);\n if (options?.q) sp.set('q', options.q);\n if (options?.limit !== undefined) sp.set('limit', String(options.limit));\n if (options?.offset !== undefined) sp.set('offset', String(options.offset));\n if (options?.attrs) sp.set('attrs', options.attrs);\n if (options?.options) sp.set('options', options.options);\n const qs = sp.toString();\n return this.request<NgsiV2Entity[]>('GET', `/v2/entities${qs ? '?' + qs : ''}`);\n }\n\n /** Get single entity by ID */\n async getEntity(entityId: string, options?: { attrs?: string; options?: string }): Promise<NgsiV2Entity> {\n const sp = new URLSearchParams();\n if (options?.attrs) sp.set('attrs', options.attrs);\n if (options?.options) sp.set('options', options.options);\n const qs = sp.toString();\n return this.request<NgsiV2Entity>('GET', `/v2/entities/${encodeURIComponent(entityId)}${qs ? '?' + qs : ''}`);\n }\n\n /** Create entity */\n async createEntity(entity: NgsiV2Entity): Promise<void> {\n await this.request<void>('POST', '/v2/entities', entity);\n }\n\n /** Update entity attributes (partial) */\n async updateEntityAttributes(entityId: string, attrs: Record<string, NgsiV2Attribute>): Promise<void> {\n await this.request<void>('PATCH', `/v2/entities/${encodeURIComponent(entityId)}/attrs`, attrs);\n }\n\n /** Delete entity */\n async deleteEntity(entityId: string): Promise<void> {\n await this.request<void>('DELETE', `/v2/entities/${encodeURIComponent(entityId)}`);\n }\n}\n\nexport function createNgsiV2Client(config: NgsiV2ClientConfig): NgsiV2Client {\n return new NgsiV2Client(config);\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAwCO,IAAM,eAAN,MAAmB;AAAA,EAIxB,YAAY,QAA4B;AAHxC,wBAAQ;AACR,wBAAQ;AAGN,SAAK,UAAU,OAAO,QAAQ,QAAQ,OAAO,EAAE;AAC/C,SAAK,UAAU;AAAA,MACb,gBAAgB;AAAA,MAChB,QAAQ;AAAA,IACV;AACA,QAAI,OAAO,QAAS,MAAK,QAAQ,gBAAgB,IAAI,OAAO;AAC5D,QAAI,OAAO,YAAa,MAAK,QAAQ,oBAAoB,IAAI,OAAO;AAAA,EACtE;AAAA,EAEA,MAAc,QAAW,QAAgB,MAAc,MAA4B;AACjF,UAAM,MAAM,MAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,MAChD;AAAA,MACA,SAAS,KAAK;AAAA,MACd,MAAM,SAAS,SAAY,KAAK,UAAU,IAAI,IAAI;AAAA,IACpD,CAAC;AACD,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,MAAM,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,EAAE,OAAO,QAAQ,IAAI,MAAM,GAAG,EAAE;AAC1E,YAAM,cAAc,OAAO,IAAI,aAAa,MAAM,WAAW,IAAI,aAAa,IAAI;AAClF,YAAM,QAAQ,OAAO,IAAI,OAAO,MAAM,WAAW,IAAI,OAAO,IAAI;AAChE,YAAM,IAAI,MAAM,eAAe,SAAS,QAAQ,IAAI,MAAM,EAAE;AAAA,IAC9D;AACA,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,IAAK,QAAO;AACrD,WAAO,IAAI,KAAK;AAAA,EAClB;AAAA;AAAA,EAGA,MAAM,YAAY,SAAuD;AACvE,UAAM,KAAK,IAAI,gBAAgB;AAC/B,QAAI,SAAS,KAAM,IAAG,IAAI,QAAQ,QAAQ,IAAI;AAC9C,QAAI,SAAS,EAAG,IAAG,IAAI,KAAK,QAAQ,CAAC;AACrC,QAAI,SAAS,UAAU,OAAW,IAAG,IAAI,SAAS,OAAO,QAAQ,KAAK,CAAC;AACvE,QAAI,SAAS,WAAW,OAAW,IAAG,IAAI,UAAU,OAAO,QAAQ,MAAM,CAAC;AAC1E,QAAI,SAAS,MAAO,IAAG,IAAI,SAAS,QAAQ,KAAK;AACjD,QAAI,SAAS,QAAS,IAAG,IAAI,WAAW,QAAQ,OAAO;AACvD,UAAM,KAAK,GAAG,SAAS;AACvB,WAAO,KAAK,QAAwB,OAAO,eAAe,KAAK,MAAM,KAAK,EAAE,EAAE;AAAA,EAChF;AAAA;AAAA,EAGA,MAAM,UAAU,UAAkB,SAAuE;AACvG,UAAM,KAAK,IAAI,gBAAgB;AAC/B,QAAI,SAAS,MAAO,IAAG,IAAI,SAAS,QAAQ,KAAK;AACjD,QAAI,SAAS,QAAS,IAAG,IAAI,WAAW,QAAQ,OAAO;AACvD,UAAM,KAAK,GAAG,SAAS;AACvB,WAAO,KAAK,QAAsB,OAAO,gBAAgB,mBAAmB,QAAQ,CAAC,GAAG,KAAK,MAAM,KAAK,EAAE,EAAE;AAAA,EAC9G;AAAA;AAAA,EAGA,MAAM,aAAa,QAAqC;AACtD,UAAM,KAAK,QAAc,QAAQ,gBAAgB,MAAM;AAAA,EACzD;AAAA;AAAA,EAGA,MAAM,uBAAuB,UAAkB,OAAuD;AACpG,UAAM,KAAK,QAAc,SAAS,gBAAgB,mBAAmB,QAAQ,CAAC,UAAU,KAAK;AAAA,EAC/F;AAAA;AAAA,EAGA,MAAM,aAAa,UAAiC;AAClD,UAAM,KAAK,QAAc,UAAU,gBAAgB,mBAAmB,QAAQ,CAAC,EAAE;AAAA,EACnF;AACF;AAEO,SAAS,mBAAmB,QAA0C;AAC3E,SAAO,IAAI,aAAa,MAAM;AAChC;",
6
+ "names": []
7
+ }
@@ -0,0 +1,58 @@
1
+ // Generated by dts-bundle-generator v9.5.1
2
+
3
+ /**
4
+ * NGSIv2 basic client — bundled per ADR論点2=a (殿裁可確定)
5
+ *
6
+ * Scope: basic entity CRUD only. No subscriptions, no batch ops.
7
+ * For NGSI-LD, use the core GeonicDB client instead.
8
+ */
9
+ export interface NgsiV2ClientConfig {
10
+ baseUrl: string;
11
+ /** FIWARE service (tenant) */
12
+ service?: string;
13
+ /** FIWARE service path */
14
+ servicePath?: string;
15
+ }
16
+ export interface NgsiV2Entity {
17
+ id: string;
18
+ type: string;
19
+ [key: string]: string | NgsiV2Attribute | undefined;
20
+ }
21
+ export interface NgsiV2Attribute {
22
+ type: string;
23
+ value: string | number | boolean | object | null;
24
+ metadata?: Record<string, {
25
+ type: string;
26
+ value: unknown;
27
+ }>;
28
+ }
29
+ export interface NgsiV2QueryOptions {
30
+ type?: string;
31
+ q?: string;
32
+ limit?: number;
33
+ offset?: number;
34
+ attrs?: string;
35
+ options?: string;
36
+ }
37
+ export declare class NgsiV2Client {
38
+ private baseUrl;
39
+ private headers;
40
+ constructor(config: NgsiV2ClientConfig);
41
+ private request;
42
+ /** List entities */
43
+ getEntities(options?: NgsiV2QueryOptions): Promise<NgsiV2Entity[]>;
44
+ /** Get single entity by ID */
45
+ getEntity(entityId: string, options?: {
46
+ attrs?: string;
47
+ options?: string;
48
+ }): Promise<NgsiV2Entity>;
49
+ /** Create entity */
50
+ createEntity(entity: NgsiV2Entity): Promise<void>;
51
+ /** Update entity attributes (partial) */
52
+ updateEntityAttributes(entityId: string, attrs: Record<string, NgsiV2Attribute>): Promise<void>;
53
+ /** Delete entity */
54
+ deleteEntity(entityId: string): Promise<void>;
55
+ }
56
+ export declare function createNgsiV2Client(config: NgsiV2ClientConfig): NgsiV2Client;
57
+
58
+ export {};
@@ -0,0 +1,73 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
+
5
+ // src/sdk/ngsi-v2/index.ts
6
+ var NgsiV2Client = class {
7
+ constructor(config) {
8
+ __publicField(this, "baseUrl");
9
+ __publicField(this, "headers");
10
+ this.baseUrl = config.baseUrl.replace(/\/$/, "");
11
+ this.headers = {
12
+ "Content-Type": "application/json",
13
+ Accept: "application/json"
14
+ };
15
+ if (config.service) this.headers["Fiware-Service"] = config.service;
16
+ if (config.servicePath) this.headers["Fiware-ServicePath"] = config.servicePath;
17
+ }
18
+ async request(method, path, body) {
19
+ const res = await fetch(`${this.baseUrl}${path}`, {
20
+ method,
21
+ headers: this.headers,
22
+ body: body !== void 0 ? JSON.stringify(body) : void 0
23
+ });
24
+ if (!res.ok) {
25
+ const err = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
26
+ const description = typeof err["description"] === "string" ? err["description"] : void 0;
27
+ const error = typeof err["error"] === "string" ? err["error"] : void 0;
28
+ throw new Error(description ?? error ?? `HTTP ${res.status}`);
29
+ }
30
+ if (res.status === 201 || res.status === 204) return void 0;
31
+ return res.json();
32
+ }
33
+ /** List entities */
34
+ async getEntities(options) {
35
+ const sp = new URLSearchParams();
36
+ if (options?.type) sp.set("type", options.type);
37
+ if (options?.q) sp.set("q", options.q);
38
+ if (options?.limit !== void 0) sp.set("limit", String(options.limit));
39
+ if (options?.offset !== void 0) sp.set("offset", String(options.offset));
40
+ if (options?.attrs) sp.set("attrs", options.attrs);
41
+ if (options?.options) sp.set("options", options.options);
42
+ const qs = sp.toString();
43
+ return this.request("GET", `/v2/entities${qs ? "?" + qs : ""}`);
44
+ }
45
+ /** Get single entity by ID */
46
+ async getEntity(entityId, options) {
47
+ const sp = new URLSearchParams();
48
+ if (options?.attrs) sp.set("attrs", options.attrs);
49
+ if (options?.options) sp.set("options", options.options);
50
+ const qs = sp.toString();
51
+ return this.request("GET", `/v2/entities/${encodeURIComponent(entityId)}${qs ? "?" + qs : ""}`);
52
+ }
53
+ /** Create entity */
54
+ async createEntity(entity) {
55
+ await this.request("POST", "/v2/entities", entity);
56
+ }
57
+ /** Update entity attributes (partial) */
58
+ async updateEntityAttributes(entityId, attrs) {
59
+ await this.request("PATCH", `/v2/entities/${encodeURIComponent(entityId)}/attrs`, attrs);
60
+ }
61
+ /** Delete entity */
62
+ async deleteEntity(entityId) {
63
+ await this.request("DELETE", `/v2/entities/${encodeURIComponent(entityId)}`);
64
+ }
65
+ };
66
+ function createNgsiV2Client(config) {
67
+ return new NgsiV2Client(config);
68
+ }
69
+ export {
70
+ NgsiV2Client,
71
+ createNgsiV2Client
72
+ };
73
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/sdk/ngsi-v2/index.ts"],
4
+ "sourcesContent": ["// SPDX-License-Identifier: MIT\n// Copyright (c) 2026 Geolonia Inc.\n// See LICENSE in src/sdk/ for full license text.\n\n/**\n * NGSIv2 basic client \u2014 bundled per ADR\u8AD6\u70B92=a (\u6BBF\u88C1\u53EF\u78BA\u5B9A)\n *\n * Scope: basic entity CRUD only. No subscriptions, no batch ops.\n * For NGSI-LD, use the core GeonicDB client instead.\n */\n\nexport interface NgsiV2ClientConfig {\n baseUrl: string;\n /** FIWARE service (tenant) */\n service?: string;\n /** FIWARE service path */\n servicePath?: string;\n}\n\nexport interface NgsiV2Entity {\n id: string;\n type: string;\n [key: string]: string | NgsiV2Attribute | undefined;\n}\n\nexport interface NgsiV2Attribute {\n type: string;\n value: string | number | boolean | object | null;\n metadata?: Record<string, { type: string; value: unknown }>;\n}\n\nexport interface NgsiV2QueryOptions {\n type?: string;\n q?: string;\n limit?: number;\n offset?: number;\n attrs?: string;\n options?: string;\n}\n\nexport class NgsiV2Client {\n private baseUrl: string;\n private headers: Record<string, string>;\n\n constructor(config: NgsiV2ClientConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, '');\n this.headers = {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n };\n if (config.service) this.headers['Fiware-Service'] = config.service;\n if (config.servicePath) this.headers['Fiware-ServicePath'] = config.servicePath;\n }\n\n private async request<T>(method: string, path: string, body?: unknown): Promise<T> {\n const res = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers: this.headers,\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n if (!res.ok) {\n const err = await res.json().catch(() => ({ error: `HTTP ${res.status}` })) as Record<string, unknown>;\n const description = typeof err['description'] === 'string' ? err['description'] : undefined;\n const error = typeof err['error'] === 'string' ? err['error'] : undefined;\n throw new Error(description ?? error ?? `HTTP ${res.status}`);\n }\n if (res.status === 201 || res.status === 204) return undefined as T;\n return res.json() as Promise<T>;\n }\n\n /** List entities */\n async getEntities(options?: NgsiV2QueryOptions): Promise<NgsiV2Entity[]> {\n const sp = new URLSearchParams();\n if (options?.type) sp.set('type', options.type);\n if (options?.q) sp.set('q', options.q);\n if (options?.limit !== undefined) sp.set('limit', String(options.limit));\n if (options?.offset !== undefined) sp.set('offset', String(options.offset));\n if (options?.attrs) sp.set('attrs', options.attrs);\n if (options?.options) sp.set('options', options.options);\n const qs = sp.toString();\n return this.request<NgsiV2Entity[]>('GET', `/v2/entities${qs ? '?' + qs : ''}`);\n }\n\n /** Get single entity by ID */\n async getEntity(entityId: string, options?: { attrs?: string; options?: string }): Promise<NgsiV2Entity> {\n const sp = new URLSearchParams();\n if (options?.attrs) sp.set('attrs', options.attrs);\n if (options?.options) sp.set('options', options.options);\n const qs = sp.toString();\n return this.request<NgsiV2Entity>('GET', `/v2/entities/${encodeURIComponent(entityId)}${qs ? '?' + qs : ''}`);\n }\n\n /** Create entity */\n async createEntity(entity: NgsiV2Entity): Promise<void> {\n await this.request<void>('POST', '/v2/entities', entity);\n }\n\n /** Update entity attributes (partial) */\n async updateEntityAttributes(entityId: string, attrs: Record<string, NgsiV2Attribute>): Promise<void> {\n await this.request<void>('PATCH', `/v2/entities/${encodeURIComponent(entityId)}/attrs`, attrs);\n }\n\n /** Delete entity */\n async deleteEntity(entityId: string): Promise<void> {\n await this.request<void>('DELETE', `/v2/entities/${encodeURIComponent(entityId)}`);\n }\n}\n\nexport function createNgsiV2Client(config: NgsiV2ClientConfig): NgsiV2Client {\n return new NgsiV2Client(config);\n}\n"],
5
+ "mappings": ";;;;;AAwCO,IAAM,eAAN,MAAmB;AAAA,EAIxB,YAAY,QAA4B;AAHxC,wBAAQ;AACR,wBAAQ;AAGN,SAAK,UAAU,OAAO,QAAQ,QAAQ,OAAO,EAAE;AAC/C,SAAK,UAAU;AAAA,MACb,gBAAgB;AAAA,MAChB,QAAQ;AAAA,IACV;AACA,QAAI,OAAO,QAAS,MAAK,QAAQ,gBAAgB,IAAI,OAAO;AAC5D,QAAI,OAAO,YAAa,MAAK,QAAQ,oBAAoB,IAAI,OAAO;AAAA,EACtE;AAAA,EAEA,MAAc,QAAW,QAAgB,MAAc,MAA4B;AACjF,UAAM,MAAM,MAAM,MAAM,GAAG,KAAK,OAAO,GAAG,IAAI,IAAI;AAAA,MAChD;AAAA,MACA,SAAS,KAAK;AAAA,MACd,MAAM,SAAS,SAAY,KAAK,UAAU,IAAI,IAAI;AAAA,IACpD,CAAC;AACD,QAAI,CAAC,IAAI,IAAI;AACX,YAAM,MAAM,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,EAAE,OAAO,QAAQ,IAAI,MAAM,GAAG,EAAE;AAC1E,YAAM,cAAc,OAAO,IAAI,aAAa,MAAM,WAAW,IAAI,aAAa,IAAI;AAClF,YAAM,QAAQ,OAAO,IAAI,OAAO,MAAM,WAAW,IAAI,OAAO,IAAI;AAChE,YAAM,IAAI,MAAM,eAAe,SAAS,QAAQ,IAAI,MAAM,EAAE;AAAA,IAC9D;AACA,QAAI,IAAI,WAAW,OAAO,IAAI,WAAW,IAAK,QAAO;AACrD,WAAO,IAAI,KAAK;AAAA,EAClB;AAAA;AAAA,EAGA,MAAM,YAAY,SAAuD;AACvE,UAAM,KAAK,IAAI,gBAAgB;AAC/B,QAAI,SAAS,KAAM,IAAG,IAAI,QAAQ,QAAQ,IAAI;AAC9C,QAAI,SAAS,EAAG,IAAG,IAAI,KAAK,QAAQ,CAAC;AACrC,QAAI,SAAS,UAAU,OAAW,IAAG,IAAI,SAAS,OAAO,QAAQ,KAAK,CAAC;AACvE,QAAI,SAAS,WAAW,OAAW,IAAG,IAAI,UAAU,OAAO,QAAQ,MAAM,CAAC;AAC1E,QAAI,SAAS,MAAO,IAAG,IAAI,SAAS,QAAQ,KAAK;AACjD,QAAI,SAAS,QAAS,IAAG,IAAI,WAAW,QAAQ,OAAO;AACvD,UAAM,KAAK,GAAG,SAAS;AACvB,WAAO,KAAK,QAAwB,OAAO,eAAe,KAAK,MAAM,KAAK,EAAE,EAAE;AAAA,EAChF;AAAA;AAAA,EAGA,MAAM,UAAU,UAAkB,SAAuE;AACvG,UAAM,KAAK,IAAI,gBAAgB;AAC/B,QAAI,SAAS,MAAO,IAAG,IAAI,SAAS,QAAQ,KAAK;AACjD,QAAI,SAAS,QAAS,IAAG,IAAI,WAAW,QAAQ,OAAO;AACvD,UAAM,KAAK,GAAG,SAAS;AACvB,WAAO,KAAK,QAAsB,OAAO,gBAAgB,mBAAmB,QAAQ,CAAC,GAAG,KAAK,MAAM,KAAK,EAAE,EAAE;AAAA,EAC9G;AAAA;AAAA,EAGA,MAAM,aAAa,QAAqC;AACtD,UAAM,KAAK,QAAc,QAAQ,gBAAgB,MAAM;AAAA,EACzD;AAAA;AAAA,EAGA,MAAM,uBAAuB,UAAkB,OAAuD;AACpG,UAAM,KAAK,QAAc,SAAS,gBAAgB,mBAAmB,QAAQ,CAAC,UAAU,KAAK;AAAA,EAC/F;AAAA;AAAA,EAGA,MAAM,aAAa,UAAiC;AAClD,UAAM,KAAK,QAAc,UAAU,gBAAgB,mBAAmB,QAAQ,CAAC,EAAE;AAAA,EACnF;AACF;AAEO,SAAS,mBAAmB,QAA0C;AAC3E,SAAO,IAAI,aAAa,MAAM;AAChC;",
6
+ "names": []
7
+ }
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@geolonia/geonicdb-sdk",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "description": "GeonicDB JavaScript SDK — NGSI-LD Context Broker client for browser and Node.js",
5
5
  "main": "geonicdb.cjs",
6
6
  "module": "geonicdb.mjs",
7
7
  "types": "geonicdb.d.ts",
8
8
  "browser": "geonicdb.iife.js",
9
+ "sideEffects": false,
9
10
  "exports": {
10
11
  ".": {
11
12
  "import": {
@@ -16,12 +17,46 @@
16
17
  "types": "./geonicdb.d.ts",
17
18
  "default": "./geonicdb.cjs"
18
19
  }
20
+ },
21
+ "./react": {
22
+ "import": {
23
+ "types": "./react/index.d.ts",
24
+ "default": "./react/index.mjs"
25
+ },
26
+ "require": {
27
+ "types": "./react/index.d.ts",
28
+ "default": "./react/index.cjs"
29
+ }
30
+ },
31
+ "./ngsi-v2": {
32
+ "import": {
33
+ "types": "./ngsi-v2/index.d.ts",
34
+ "default": "./ngsi-v2/index.mjs"
35
+ },
36
+ "require": {
37
+ "types": "./ngsi-v2/index.d.ts",
38
+ "default": "./ngsi-v2/index.cjs"
39
+ }
19
40
  }
20
41
  },
21
42
  "files": [
22
43
  "geonicdb.*",
44
+ "react/",
45
+ "ngsi-v2/",
23
46
  "LICENSE"
24
47
  ],
48
+ "peerDependencies": {
49
+ "react": "^18 || ^19",
50
+ "@geolonia/embed": "^1.0.0"
51
+ },
52
+ "peerDependenciesMeta": {
53
+ "react": {
54
+ "optional": true
55
+ },
56
+ "@geolonia/embed": {
57
+ "optional": true
58
+ }
59
+ },
25
60
  "license": "MIT",
26
61
  "publishConfig": {
27
62
  "access": "public"