@geolonia/geonicdb-sdk 0.20.0 → 0.22.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 +26 -4
- package/geonicdb.cjs +55 -12
- package/geonicdb.cjs.map +2 -2
- package/geonicdb.d.ts +14 -2
- package/geonicdb.iife.js +55 -12
- package/geonicdb.iife.js.map +2 -2
- package/geonicdb.mjs +55 -12
- package/geonicdb.mjs.map +2 -2
- package/package.json +1 -1
- package/react/index.d.ts +14 -2
package/geonicdb.d.ts
CHANGED
|
@@ -40,6 +40,18 @@ export interface GeonicDBOptions {
|
|
|
40
40
|
*/
|
|
41
41
|
anonymous?: boolean;
|
|
42
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Options for {@link GeonicDB.request} and `requestRaw` (#3322).
|
|
45
|
+
*
|
|
46
|
+
* `headers` overrides the SDK defaults `Content-Type` / `Accept`
|
|
47
|
+
* (header names are matched case-insensitively; the caller's spelling is sent).
|
|
48
|
+
* `Authorization`, `DPoP`, `Fiware-Service`, and `NGSILD-Tenant` (any casing)
|
|
49
|
+
* are reserved and throw `TypeError` — the SDK sets those itself.
|
|
50
|
+
* A GET or HEAD that includes `headers` skips the ETag cache and in-flight dedup.
|
|
51
|
+
*/
|
|
52
|
+
export interface RequestOptions {
|
|
53
|
+
headers?: Record<string, string>;
|
|
54
|
+
}
|
|
43
55
|
/** Options for the SDK polling helper. */
|
|
44
56
|
export interface PollOptions<T = unknown> {
|
|
45
57
|
/** Polling interval in milliseconds (default: 5000). */
|
|
@@ -860,12 +872,12 @@ export declare class GeonicDB extends EventEmitter {
|
|
|
860
872
|
* 空だが、サーバ実装が `Content-Type: application/ld+json` を付けて返す
|
|
861
873
|
* ケースがあり、そこで `res.json()` が SyntaxError を投げて止まっていた。
|
|
862
874
|
*/
|
|
863
|
-
request(method: string, path: string, body?: unknown): Promise<unknown>;
|
|
875
|
+
request(method: string, path: string, body?: unknown, options?: RequestOptions): Promise<unknown>;
|
|
864
876
|
/**
|
|
865
877
|
* Make an authenticated API request and return the raw Response object.
|
|
866
878
|
* Use this when you need access to response headers (e.g. NGSILD-Results-Count).
|
|
867
879
|
*/
|
|
868
|
-
requestRaw(method: string, path: string, body?: unknown): Promise<Response>;
|
|
880
|
+
requestRaw(method: string, path: string, body?: unknown, options?: RequestOptions): Promise<Response>;
|
|
869
881
|
/** Establish WebSocket connection (authentication is automatic). */
|
|
870
882
|
connect(): Promise<void>;
|
|
871
883
|
/** Force-reconnect (closes existing connection, preserves subscriptions). */
|
package/geonicdb.iife.js
CHANGED
|
@@ -585,6 +585,46 @@ var GeonicDBModule = (() => {
|
|
|
585
585
|
}
|
|
586
586
|
|
|
587
587
|
// src/sdk/auth.ts
|
|
588
|
+
var SDK_RESERVED_REQUEST_HEADERS = /* @__PURE__ */ new Set([
|
|
589
|
+
"authorization",
|
|
590
|
+
"dpop",
|
|
591
|
+
"fiware-service",
|
|
592
|
+
"ngsild-tenant"
|
|
593
|
+
]);
|
|
594
|
+
function assertCallerHeadersAllowed(headers) {
|
|
595
|
+
if (!headers) return;
|
|
596
|
+
for (const [name, value] of Object.entries(headers)) {
|
|
597
|
+
if (/[\r\n]/.test(name) || /[\r\n]/.test(value)) {
|
|
598
|
+
throw new TypeError("Header name or value contains CR or LF");
|
|
599
|
+
}
|
|
600
|
+
if (SDK_RESERVED_REQUEST_HEADERS.has(name.toLowerCase())) {
|
|
601
|
+
throw new TypeError(
|
|
602
|
+
`Header "${name}" is reserved; the SDK sets Authorization, DPoP, Fiware-Service, and NGSILD-Tenant`
|
|
603
|
+
);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
function mergeCallerHeaders(defaults, extraHeaders) {
|
|
608
|
+
const merged = new Headers(defaults);
|
|
609
|
+
const callerNames = /* @__PURE__ */ new Map();
|
|
610
|
+
if (extraHeaders) {
|
|
611
|
+
for (const [name, value] of Object.entries(extraHeaders)) {
|
|
612
|
+
merged.set(name, value);
|
|
613
|
+
callerNames.set(name.toLowerCase(), name);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
const headers = {};
|
|
617
|
+
for (const name of Object.keys(defaults)) {
|
|
618
|
+
if (callerNames.has(name.toLowerCase())) continue;
|
|
619
|
+
const value = merged.get(name);
|
|
620
|
+
if (value !== null) headers[name] = value;
|
|
621
|
+
}
|
|
622
|
+
for (const [lower, name] of callerNames) {
|
|
623
|
+
const value = merged.get(lower);
|
|
624
|
+
if (value !== null) headers[name] = value;
|
|
625
|
+
}
|
|
626
|
+
return headers;
|
|
627
|
+
}
|
|
588
628
|
var _AuthManager = class _AuthManager {
|
|
589
629
|
constructor(baseUrl, apiKey, tenant, debug = false, anonymous = false) {
|
|
590
630
|
__publicField(this, "_baseUrl");
|
|
@@ -1205,11 +1245,12 @@ var GeonicDBModule = (() => {
|
|
|
1205
1245
|
* the cache.
|
|
1206
1246
|
* - Deduplicates concurrent in-flight requests to the same path.
|
|
1207
1247
|
*/
|
|
1208
|
-
async request(method, path, body) {
|
|
1248
|
+
async request(method, path, body, headers) {
|
|
1209
1249
|
this._log(method, path);
|
|
1210
|
-
|
|
1250
|
+
assertCallerHeadersAllowed(headers);
|
|
1251
|
+
if (!this._cache || !isCacheableMethod(method) || body !== void 0 || headers !== void 0) {
|
|
1211
1252
|
const token = this.isAnonymous() ? null : await this.ensureToken();
|
|
1212
|
-
const res = await this._doAuthenticatedRequest(method, path, body, token);
|
|
1253
|
+
const res = await this._doAuthenticatedRequest(method, path, body, token, 0, headers);
|
|
1213
1254
|
this._log(method, path, "\u2192", res.status);
|
|
1214
1255
|
return res;
|
|
1215
1256
|
}
|
|
@@ -1304,11 +1345,13 @@ var GeonicDBModule = (() => {
|
|
|
1304
1345
|
reqToken,
|
|
1305
1346
|
dpopNonce
|
|
1306
1347
|
) : null;
|
|
1307
|
-
const headers =
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1348
|
+
const headers = mergeCallerHeaders(
|
|
1349
|
+
{
|
|
1350
|
+
"Content-Type": "application/ld+json",
|
|
1351
|
+
Accept: "application/ld+json"
|
|
1352
|
+
},
|
|
1353
|
+
extraHeaders
|
|
1354
|
+
);
|
|
1312
1355
|
if (reqToken !== null) {
|
|
1313
1356
|
headers["Authorization"] = (reqIsDPoP ? "DPoP " : "Bearer ") + reqToken;
|
|
1314
1357
|
}
|
|
@@ -2216,8 +2259,8 @@ var GeonicDBModule = (() => {
|
|
|
2216
2259
|
* 空だが、サーバ実装が `Content-Type: application/ld+json` を付けて返す
|
|
2217
2260
|
* ケースがあり、そこで `res.json()` が SyntaxError を投げて止まっていた。
|
|
2218
2261
|
*/
|
|
2219
|
-
async request(method, path, body) {
|
|
2220
|
-
const res = await this._auth.request(method, path, body);
|
|
2262
|
+
async request(method, path, body, options) {
|
|
2263
|
+
const res = await this._auth.request(method, path, body, options?.headers);
|
|
2221
2264
|
if (!res.ok) {
|
|
2222
2265
|
const e = await res.json().catch(() => ({}));
|
|
2223
2266
|
throw createErrorFromResponse(res.status, e, "Request failed: " + res.status);
|
|
@@ -2237,8 +2280,8 @@ var GeonicDBModule = (() => {
|
|
|
2237
2280
|
* Make an authenticated API request and return the raw Response object.
|
|
2238
2281
|
* Use this when you need access to response headers (e.g. NGSILD-Results-Count).
|
|
2239
2282
|
*/
|
|
2240
|
-
async requestRaw(method, path, body) {
|
|
2241
|
-
return this._auth.request(method, path, body);
|
|
2283
|
+
async requestRaw(method, path, body, options) {
|
|
2284
|
+
return this._auth.request(method, path, body, options?.headers);
|
|
2242
2285
|
}
|
|
2243
2286
|
// --- WebSocket ---
|
|
2244
2287
|
/** Establish WebSocket connection (authentication is automatic). */
|