@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 +5 -4
- package/dist/index.cjs +30 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +12 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +30 -14
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/slots.ts +56 -13
- package/src/transform.ts +11 -0
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
|
|
15
|
-
|
|
16
|
-
installed the SDK, importing from its root works and needs no second
|
|
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
|
|
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
|
|
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
|
}
|