@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/geonicdb.mjs CHANGED
@@ -544,6 +544,46 @@ function isCacheableMethod(method) {
544
544
  }
545
545
 
546
546
  // src/sdk/auth.ts
547
+ var SDK_RESERVED_REQUEST_HEADERS = /* @__PURE__ */ new Set([
548
+ "authorization",
549
+ "dpop",
550
+ "fiware-service",
551
+ "ngsild-tenant"
552
+ ]);
553
+ function assertCallerHeadersAllowed(headers) {
554
+ if (!headers) return;
555
+ for (const [name, value] of Object.entries(headers)) {
556
+ if (/[\r\n]/.test(name) || /[\r\n]/.test(value)) {
557
+ throw new TypeError("Header name or value contains CR or LF");
558
+ }
559
+ if (SDK_RESERVED_REQUEST_HEADERS.has(name.toLowerCase())) {
560
+ throw new TypeError(
561
+ `Header "${name}" is reserved; the SDK sets Authorization, DPoP, Fiware-Service, and NGSILD-Tenant`
562
+ );
563
+ }
564
+ }
565
+ }
566
+ function mergeCallerHeaders(defaults, extraHeaders) {
567
+ const merged = new Headers(defaults);
568
+ const callerNames = /* @__PURE__ */ new Map();
569
+ if (extraHeaders) {
570
+ for (const [name, value] of Object.entries(extraHeaders)) {
571
+ merged.set(name, value);
572
+ callerNames.set(name.toLowerCase(), name);
573
+ }
574
+ }
575
+ const headers = {};
576
+ for (const name of Object.keys(defaults)) {
577
+ if (callerNames.has(name.toLowerCase())) continue;
578
+ const value = merged.get(name);
579
+ if (value !== null) headers[name] = value;
580
+ }
581
+ for (const [lower, name] of callerNames) {
582
+ const value = merged.get(lower);
583
+ if (value !== null) headers[name] = value;
584
+ }
585
+ return headers;
586
+ }
547
587
  var _AuthManager = class _AuthManager {
548
588
  constructor(baseUrl, apiKey, tenant, debug = false, anonymous = false) {
549
589
  __publicField(this, "_baseUrl");
@@ -1164,11 +1204,12 @@ var _AuthManager = class _AuthManager {
1164
1204
  * the cache.
1165
1205
  * - Deduplicates concurrent in-flight requests to the same path.
1166
1206
  */
1167
- async request(method, path, body) {
1207
+ async request(method, path, body, headers) {
1168
1208
  this._log(method, path);
1169
- if (!this._cache || !isCacheableMethod(method) || body !== void 0) {
1209
+ assertCallerHeadersAllowed(headers);
1210
+ if (!this._cache || !isCacheableMethod(method) || body !== void 0 || headers !== void 0) {
1170
1211
  const token = this.isAnonymous() ? null : await this.ensureToken();
1171
- const res = await this._doAuthenticatedRequest(method, path, body, token);
1212
+ const res = await this._doAuthenticatedRequest(method, path, body, token, 0, headers);
1172
1213
  this._log(method, path, "\u2192", res.status);
1173
1214
  return res;
1174
1215
  }
@@ -1263,11 +1304,13 @@ var _AuthManager = class _AuthManager {
1263
1304
  reqToken,
1264
1305
  dpopNonce
1265
1306
  ) : null;
1266
- const headers = {
1267
- "Content-Type": "application/ld+json",
1268
- Accept: "application/ld+json",
1269
- ...extraHeaders
1270
- };
1307
+ const headers = mergeCallerHeaders(
1308
+ {
1309
+ "Content-Type": "application/ld+json",
1310
+ Accept: "application/ld+json"
1311
+ },
1312
+ extraHeaders
1313
+ );
1271
1314
  if (reqToken !== null) {
1272
1315
  headers["Authorization"] = (reqIsDPoP ? "DPoP " : "Bearer ") + reqToken;
1273
1316
  }
@@ -2175,8 +2218,8 @@ var GeonicDB = class extends EventEmitter {
2175
2218
  * 空だが、サーバ実装が `Content-Type: application/ld+json` を付けて返す
2176
2219
  * ケースがあり、そこで `res.json()` が SyntaxError を投げて止まっていた。
2177
2220
  */
2178
- async request(method, path, body) {
2179
- const res = await this._auth.request(method, path, body);
2221
+ async request(method, path, body, options) {
2222
+ const res = await this._auth.request(method, path, body, options?.headers);
2180
2223
  if (!res.ok) {
2181
2224
  const e = await res.json().catch(() => ({}));
2182
2225
  throw createErrorFromResponse(res.status, e, "Request failed: " + res.status);
@@ -2196,8 +2239,8 @@ var GeonicDB = class extends EventEmitter {
2196
2239
  * Make an authenticated API request and return the raw Response object.
2197
2240
  * Use this when you need access to response headers (e.g. NGSILD-Results-Count).
2198
2241
  */
2199
- async requestRaw(method, path, body) {
2200
- return this._auth.request(method, path, body);
2242
+ async requestRaw(method, path, body, options) {
2243
+ return this._auth.request(method, path, body, options?.headers);
2201
2244
  }
2202
2245
  // --- WebSocket ---
2203
2246
  /** Establish WebSocket connection (authentication is automatic). */