@geolonia/geonicdb-sdk 0.21.0 → 0.23.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/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
- if (!this._cache || !isCacheableMethod(method) || body !== void 0) {
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
- "Content-Type": "application/ld+json",
1309
- Accept: "application/ld+json",
1310
- ...extraHeaders
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). */