@nitida/asset-client 0.24.0 → 0.24.1

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
@@ -11,11 +11,12 @@ bun add @nitida/asset-client
11
11
 
12
12
  ## Where these symbols live
13
13
 
14
- Everything documented here is exported by **`@nitida/asset-client`**, and all
15
- 53 exports are re-exported by the root **`@nitida/sdk`** — if you already
16
- installed the SDK, importing from its root works and needs no second dependency.
14
+ Everything documented here is exported by **`@nitida/asset-client`**, and
15
+ **every one of those exports** is re-exported by the root **`@nitida/sdk`** — if
16
+ you already installed the SDK, importing from its root works and needs no second
17
+ dependency.
17
18
 
18
- `@nitida/sdk/server` and `@nitida/sdk/web` carry the same 53 as well, so any of
19
+ `@nitida/sdk/server` and `@nitida/sdk/web` carry the full set as well, so any of
19
20
  the three works. ⚠️ Not so before 2026-08-21 — `/server` was short 28 of the
20
21
  root's exports and `/web` short 37. On an older SDK, import these from the root
21
22
  or from this package.
package/dist/index.cjs CHANGED
@@ -298,10 +298,16 @@ function extractAssetSha(url) {
298
298
  function serializeTransform(opts) {
299
299
  const entries = [];
300
300
  const keys = Object.keys(opts).sort();
301
+ const VALUE_RE = /^[a-z0-9._-]+$/;
301
302
  for (const k of keys) {
302
303
  const v = opts[k];
303
304
  if (v == null) continue;
304
305
  const serialized = typeof v === "string" ? v.toLowerCase() : String(v);
306
+ if (!VALUE_RE.test(serialized)) {
307
+ throw new Error(
308
+ `invalid transform value for "${k}": ${JSON.stringify(serialized)} (only [a-z0-9._-] allowed)`
309
+ );
310
+ }
305
311
  entries.push([k, serialized]);
306
312
  }
307
313
  return entries.map(([k, v]) => `${k}=${v}`).join(",");
@@ -497,6 +503,14 @@ var cache = /* @__PURE__ */ new Map();
497
503
  var endpoint = "https://api.nitida.gofuture.space";
498
504
  var apiKey = null;
499
505
  var tenantCode = null;
506
+ function effectiveConfig(cfg) {
507
+ if (!cfg) return { endpoint, apiKey, tenantCode };
508
+ return {
509
+ endpoint: cfg.endpoint ? cfg.endpoint.replace(/\/+$/, "") : endpoint,
510
+ apiKey: cfg.apiKey ?? null,
511
+ tenantCode: cfg.tenantCode ?? null
512
+ };
513
+ }
500
514
  function configureSlotResolver(opts) {
501
515
  if (opts.endpoint) endpoint = opts.endpoint.replace(/\/+$/, "");
502
516
  if (opts.apiKey !== void 0) apiKey = opts.apiKey;
@@ -508,25 +522,25 @@ function invalidateSlotCache(slotKey) {
508
522
  for (const k of cache.keys())
509
523
  if (k.endsWith(`:${slotKey}`)) cache.delete(k);
510
524
  }
511
- var baseHeaders = () => {
525
+ var baseHeaders = (cfg) => {
512
526
  const h = {};
513
- if (apiKey) h.Authorization = `Bearer ${apiKey}`;
514
- if (tenantCode) h["X-Tenant-Code"] = tenantCode;
527
+ if (cfg.apiKey) h.Authorization = `Bearer ${cfg.apiKey}`;
528
+ if (cfg.tenantCode) h["X-Tenant-Code"] = cfg.tenantCode;
515
529
  return h;
516
530
  };
517
- async function fetchSlot(slotKey) {
518
- const r = await fetch(`${endpoint}/slots/${encodeURIComponent(slotKey)}`, {
519
- headers: baseHeaders()
531
+ async function fetchSlot(slotKey, cfg) {
532
+ const r = await fetch(`${cfg.endpoint}/slots/${encodeURIComponent(slotKey)}`, {
533
+ headers: baseHeaders(cfg)
520
534
  });
521
535
  if (r.status === 404) return null;
522
536
  if (!r.ok) throw new Error(`slot fetch ${r.status}: ${await r.text()}`);
523
537
  return await r.json();
524
538
  }
525
- async function fetchSlotsBulk(slotKeys) {
539
+ async function fetchSlotsBulk(slotKeys, cfg) {
526
540
  if (slotKeys.length === 0) return {};
527
- const r = await fetch(`${endpoint}/slots/resolve`, {
541
+ const r = await fetch(`${cfg.endpoint}/slots/resolve`, {
528
542
  method: "POST",
529
- headers: { ...baseHeaders(), "Content-Type": "application/json" },
543
+ headers: { ...baseHeaders(cfg), "Content-Type": "application/json" },
530
544
  body: JSON.stringify({ keys: slotKeys })
531
545
  });
532
546
  if (!r.ok) throw new Error(`slots resolve ${r.status}: ${await r.text()}`);
@@ -535,14 +549,15 @@ async function fetchSlotsBulk(slotKeys) {
535
549
  }
536
550
  async function resolveSlot(slotKey, opts = {}) {
537
551
  const ttl = opts.ttlMs ?? DEFAULT_TTL_MS;
538
- const cacheKey = `${tenantCode ?? "_"}:${slotKey}`;
552
+ const cfg = effectiveConfig(opts.config);
553
+ const cacheKey = `${cfg.tenantCode ?? "_"}:${slotKey}`;
539
554
  const now = Date.now();
540
555
  let dto;
541
556
  const hit = cache.get(cacheKey);
542
557
  if (hit && now - hit.fetchedAt < ttl) {
543
558
  dto = hit.value;
544
559
  } else {
545
- dto = await fetchSlot(slotKey);
560
+ dto = await fetchSlot(slotKey, cfg);
546
561
  cache.set(cacheKey, { fetchedAt: now, value: dto });
547
562
  }
548
563
  return materializeResolution(dto, opts.preset);
@@ -550,11 +565,12 @@ async function resolveSlot(slotKey, opts = {}) {
550
565
  async function resolveSlots(slotKeys, opts = {}) {
551
566
  if (slotKeys.length === 0) return {};
552
567
  const ttl = opts.ttlMs ?? DEFAULT_TTL_MS;
568
+ const cfg = effectiveConfig(opts.config);
553
569
  const now = Date.now();
554
570
  const missing = [];
555
571
  const out = {};
556
572
  for (const k of slotKeys) {
557
- const cacheKey = `${tenantCode ?? "_"}:${k}`;
573
+ const cacheKey = `${cfg.tenantCode ?? "_"}:${k}`;
558
574
  const hit = cache.get(cacheKey);
559
575
  if (hit && now - hit.fetchedAt < ttl) {
560
576
  out[k] = materializeResolution(hit.value, opts.preset);
@@ -563,10 +579,10 @@ async function resolveSlots(slotKeys, opts = {}) {
563
579
  }
564
580
  }
565
581
  if (missing.length > 0) {
566
- const resolved = await fetchSlotsBulk(missing);
582
+ const resolved = await fetchSlotsBulk(missing, cfg);
567
583
  for (const k of missing) {
568
584
  const dto = resolved[k] ?? null;
569
- cache.set(`${tenantCode ?? "_"}:${k}`, { fetchedAt: now, value: dto });
585
+ cache.set(`${cfg.tenantCode ?? "_"}:${k}`, { fetchedAt: now, value: dto });
570
586
  out[k] = materializeResolution(dto, opts.preset);
571
587
  }
572
588
  }