@nitida/sdk 0.20.0 → 0.21.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 +1 -1
- package/dist/expo.d.ts +3 -3
- package/dist/expo.js.map +1 -1
- package/dist/index.d.ts +13 -13
- package/dist/index.js +7 -6
- package/dist/index.js.map +1 -1
- package/dist/react.d.ts +7 -7
- package/dist/react.js +9 -7
- package/dist/react.js.map +1 -1
- package/dist/server.d.ts +9 -9
- package/dist/server.js +8 -7
- package/dist/server.js.map +1 -1
- package/dist/web.d.ts +10 -10
- package/dist/web.js +8 -7
- package/dist/web.js.map +1 -1
- package/package.json +16 -9
- package/src/expo/index.ts +3 -3
- package/src/index.ts +30 -17
- package/src/react/index.ts +25 -10
- package/src/server/index.ts +22 -13
- package/src/web/index.ts +22 -13
package/src/index.ts
CHANGED
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
*
|
|
11
11
|
* Usage:
|
|
12
12
|
*
|
|
13
|
-
* import {
|
|
13
|
+
* import { NitidaClient } from "@nitida/sdk";
|
|
14
14
|
*
|
|
15
|
-
* const aq = new
|
|
15
|
+
* const aq = new NitidaClient({
|
|
16
16
|
* endpoint: "https://aquienpz-asset-manager-xxx.run.app",
|
|
17
17
|
* apiKey: process.env.ASSET_MANAGER_RUNTIME_KEY!,
|
|
18
18
|
* tenantCode: "realtyone-cr",
|
|
@@ -65,7 +65,7 @@ import {
|
|
|
65
65
|
// ---------------------------------------------------------------------------
|
|
66
66
|
|
|
67
67
|
/**
|
|
68
|
-
* Permissive constructor options for the root `
|
|
68
|
+
* Permissive constructor options for the root `NitidaClient`.
|
|
69
69
|
*
|
|
70
70
|
* App code should NOT import this type directly — prefer the strict
|
|
71
71
|
* variants from the subpaths:
|
|
@@ -76,7 +76,7 @@ import {
|
|
|
76
76
|
* This root type is the union both modes resolve to; the underlying class
|
|
77
77
|
* accepts both shapes so subpath wrappers can extend without duplication.
|
|
78
78
|
*/
|
|
79
|
-
export type
|
|
79
|
+
export type NitidaClientOptions = {
|
|
80
80
|
/**
|
|
81
81
|
* Base URL of the aquienpz asset-manager (Cloud Run service URL).
|
|
82
82
|
*
|
|
@@ -135,7 +135,7 @@ export type AquienpzClientOptions = {
|
|
|
135
135
|
* site in the SDK must go through this helper instead of `new URL(...)`.
|
|
136
136
|
*/
|
|
137
137
|
function endpointUrl(
|
|
138
|
-
opts: Pick<
|
|
138
|
+
opts: Pick<NitidaClientOptions, "endpoint">,
|
|
139
139
|
path: string,
|
|
140
140
|
searchParams?: Record<string, string | number | boolean | undefined>,
|
|
141
141
|
): URL {
|
|
@@ -165,7 +165,7 @@ function endpointUrl(
|
|
|
165
165
|
|
|
166
166
|
/** Build a request URL as a plain string (no search params). */
|
|
167
167
|
function endpointHref(
|
|
168
|
-
opts: Pick<
|
|
168
|
+
opts: Pick<NitidaClientOptions, "endpoint">,
|
|
169
169
|
path: string,
|
|
170
170
|
): string {
|
|
171
171
|
return endpointUrl(opts, path).toString();
|
|
@@ -176,7 +176,7 @@ function endpointHref(
|
|
|
176
176
|
* `apiKey` is present. In BFF-proxy mode (browser via `/web`) the
|
|
177
177
|
* proxy injects the real bearer header, so we omit it here.
|
|
178
178
|
*/
|
|
179
|
-
function authHeaders(opts:
|
|
179
|
+
function authHeaders(opts: NitidaClientOptions): Record<string, string> {
|
|
180
180
|
const h: Record<string, string> = {
|
|
181
181
|
// Caller-supplied headers first; `X-Tenant-Code` stays authoritative below.
|
|
182
182
|
...opts.headers,
|
|
@@ -227,7 +227,7 @@ export {
|
|
|
227
227
|
// ---------------------------------------------------------------------------
|
|
228
228
|
|
|
229
229
|
class SlotsApi {
|
|
230
|
-
constructor(private readonly opts:
|
|
230
|
+
constructor(private readonly opts: NitidaClientOptions) {}
|
|
231
231
|
|
|
232
232
|
/** Resolve one slot — returns `{slot, preset, url}` or `{slot: null, url: null}` when unbound. */
|
|
233
233
|
resolve(
|
|
@@ -477,7 +477,7 @@ export type ComposeMarketingResult = {
|
|
|
477
477
|
};
|
|
478
478
|
|
|
479
479
|
class AssetsApi {
|
|
480
|
-
constructor(private readonly opts:
|
|
480
|
+
constructor(private readonly opts: NitidaClientOptions) {}
|
|
481
481
|
|
|
482
482
|
/** Look up an asset by full sha256 (64 hex). Returns null on 404. */
|
|
483
483
|
async byHash(sha256: string): Promise<AssetDTO | null> {
|
|
@@ -1020,7 +1020,7 @@ export type UsagePerKey = {
|
|
|
1020
1020
|
};
|
|
1021
1021
|
|
|
1022
1022
|
class UsageApi {
|
|
1023
|
-
constructor(private readonly opts:
|
|
1023
|
+
constructor(private readonly opts: NitidaClientOptions) {}
|
|
1024
1024
|
|
|
1025
1025
|
/** Snapshot for the active tenant — storage + today + last 30 days totals. */
|
|
1026
1026
|
async snapshot(): Promise<UsageSnapshot> {
|
|
@@ -1070,7 +1070,7 @@ class UsageApi {
|
|
|
1070
1070
|
}
|
|
1071
1071
|
}
|
|
1072
1072
|
|
|
1073
|
-
export class
|
|
1073
|
+
export class NitidaClient {
|
|
1074
1074
|
readonly slots: SlotsApi;
|
|
1075
1075
|
readonly assets: AssetsApi;
|
|
1076
1076
|
readonly usage: UsageApi;
|
|
@@ -1079,9 +1079,9 @@ export class AquienpzClient {
|
|
|
1079
1079
|
* subpaths can inherit endpoint / apiKey / tenant scope from the
|
|
1080
1080
|
* configured client without re-passing them per call site.
|
|
1081
1081
|
*/
|
|
1082
|
-
readonly opts:
|
|
1082
|
+
readonly opts: NitidaClientOptions;
|
|
1083
1083
|
|
|
1084
|
-
constructor(opts:
|
|
1084
|
+
constructor(opts: NitidaClientOptions) {
|
|
1085
1085
|
this.opts = opts;
|
|
1086
1086
|
const cdn = opts.cdnBase ?? "https://8ok.uk";
|
|
1087
1087
|
setCdnBase(cdn);
|
|
@@ -1168,7 +1168,7 @@ export class AquienpzClient {
|
|
|
1168
1168
|
}
|
|
1169
1169
|
if (!this.opts.signingKey) {
|
|
1170
1170
|
throw new Error(
|
|
1171
|
-
"aq.transform({ sign: true }) requires `signingKey` in
|
|
1171
|
+
"aq.transform({ sign: true }) requires `signingKey` in NitidaClientOptions. " +
|
|
1172
1172
|
"Pull the tenant's signing key from /admin/tenants/:id and pass it to the SDK constructor on a SERVER-side instance only.",
|
|
1173
1173
|
);
|
|
1174
1174
|
}
|
|
@@ -1207,7 +1207,7 @@ export class AquienpzClient {
|
|
|
1207
1207
|
if (!signOpts?.sign) return getTransformSrcSet(asset, widths, extraOpts);
|
|
1208
1208
|
if (!this.opts.signingKey) {
|
|
1209
1209
|
throw new Error(
|
|
1210
|
-
"aq.transformSrcSet({ sign: true }) requires `signingKey` in
|
|
1210
|
+
"aq.transformSrcSet({ sign: true }) requires `signingKey` in NitidaClientOptions.",
|
|
1211
1211
|
);
|
|
1212
1212
|
}
|
|
1213
1213
|
const key = this.opts.signingKey;
|
|
@@ -1312,9 +1312,9 @@ export class AquienpzClient {
|
|
|
1312
1312
|
*
|
|
1313
1313
|
* @example Deliver an image on a site (the responsive ladder)
|
|
1314
1314
|
* ```ts
|
|
1315
|
-
* import {
|
|
1315
|
+
* import { NitidaClient } from "@nitida/sdk/server";
|
|
1316
1316
|
*
|
|
1317
|
-
* const aq = new
|
|
1317
|
+
* const aq = new NitidaClient({ endpoint, apiKey, tenantCode, tenantId });
|
|
1318
1318
|
* const { assetId, sha256 } = await aq.upload(file, {
|
|
1319
1319
|
* fileName: file.name,
|
|
1320
1320
|
* presets: ["thumb", "sm", "md", "lg"],
|
|
@@ -1560,3 +1560,16 @@ export class AquienpzClient {
|
|
|
1560
1560
|
);
|
|
1561
1561
|
}
|
|
1562
1562
|
}
|
|
1563
|
+
|
|
1564
|
+
// ---------------------------------------------------------------------------
|
|
1565
|
+
// Legacy names (pre-`nitida` rename, 2026-08-16)
|
|
1566
|
+
// ---------------------------------------------------------------------------
|
|
1567
|
+
|
|
1568
|
+
export type { NitidaClientOptions as AquienpzClientOptions };
|
|
1569
|
+
/**
|
|
1570
|
+
* @deprecated Renamed to `Nitida*`. These aliases keep code written against the
|
|
1571
|
+
* old `@aquienpz/*` packages compiling unchanged — same class, same instance,
|
|
1572
|
+
* just a second name. They are not going away on a schedule, but new code
|
|
1573
|
+
* should use the `Nitida*` names.
|
|
1574
|
+
*/
|
|
1575
|
+
export { NitidaClient as AquienpzClient };
|
package/src/react/index.ts
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* Kept in a subpath so the SSR-safe core (`@nitida/sdk`) stays
|
|
5
5
|
* dependency-free of react. Import only what you need:
|
|
6
6
|
*
|
|
7
|
-
* import { useSlot, useSlots,
|
|
7
|
+
* import { useSlot, useSlots, NitidaProvider } from "@nitida/sdk/react";
|
|
8
8
|
*
|
|
9
|
-
* Pattern: wrap your app in `<
|
|
9
|
+
* Pattern: wrap your app in `<NitidaProvider client={…}>` once at
|
|
10
10
|
* the root; hooks read the client from context. No prop-drilling.
|
|
11
11
|
* @module @nitida/sdk/react
|
|
12
12
|
*/
|
|
@@ -20,16 +20,16 @@ import {
|
|
|
20
20
|
useMemo,
|
|
21
21
|
useState,
|
|
22
22
|
} from "react";
|
|
23
|
-
import type {
|
|
23
|
+
import type { NitidaClient, ResolveSlotOptions, SlotResolution } from "..";
|
|
24
24
|
|
|
25
25
|
// ---------------------------------------------------------------------------
|
|
26
26
|
// Provider
|
|
27
27
|
// ---------------------------------------------------------------------------
|
|
28
28
|
|
|
29
|
-
const ClientContext = createContext<
|
|
29
|
+
const ClientContext = createContext<NitidaClient | null>(null);
|
|
30
30
|
|
|
31
|
-
export function
|
|
32
|
-
client:
|
|
31
|
+
export function NitidaProvider(props: {
|
|
32
|
+
client: NitidaClient;
|
|
33
33
|
children: ReactNode;
|
|
34
34
|
}): ReactNode {
|
|
35
35
|
return createElement(
|
|
@@ -39,11 +39,11 @@ export function AquienpzProvider(props: {
|
|
|
39
39
|
);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
export function
|
|
42
|
+
export function useNitidaClient(): NitidaClient {
|
|
43
43
|
const client = useContext(ClientContext);
|
|
44
44
|
if (!client) {
|
|
45
45
|
throw new Error(
|
|
46
|
-
"
|
|
46
|
+
"useNitidaClient: wrap your app in <NitidaProvider client={…}>.",
|
|
47
47
|
);
|
|
48
48
|
}
|
|
49
49
|
return client;
|
|
@@ -77,7 +77,7 @@ export function useSlot(
|
|
|
77
77
|
slotKey: string,
|
|
78
78
|
options: ResolveSlotOptions = {},
|
|
79
79
|
): SlotState {
|
|
80
|
-
const client =
|
|
80
|
+
const client = useNitidaClient();
|
|
81
81
|
const [state, setState] = useState<SlotState>(emptyState);
|
|
82
82
|
|
|
83
83
|
// Stabilize options across renders so the effect only refires on the
|
|
@@ -129,7 +129,7 @@ export function useSlots(
|
|
|
129
129
|
isLoading: boolean;
|
|
130
130
|
error: Error | null;
|
|
131
131
|
} {
|
|
132
|
-
const client =
|
|
132
|
+
const client = useNitidaClient();
|
|
133
133
|
const keysHash = useMemo(() => slotKeys.join("|"), [slotKeys]);
|
|
134
134
|
const presetKey = options.preset ?? "";
|
|
135
135
|
const ttlMs = options.ttlMs ?? 60_000;
|
|
@@ -167,3 +167,18 @@ export function useSlots(
|
|
|
167
167
|
|
|
168
168
|
return state;
|
|
169
169
|
}
|
|
170
|
+
|
|
171
|
+
// ---------------------------------------------------------------------------
|
|
172
|
+
// Legacy names (pre-`nitida` rename, 2026-08-16)
|
|
173
|
+
// ---------------------------------------------------------------------------
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* @deprecated Renamed to `Nitida*`. These aliases keep code written against the
|
|
177
|
+
* old `@aquienpz/*` packages compiling unchanged — same class, same instance,
|
|
178
|
+
* just a second name. They are not going away on a schedule, but new code
|
|
179
|
+
* should use the `Nitida*` names.
|
|
180
|
+
*/
|
|
181
|
+
export {
|
|
182
|
+
NitidaProvider as AquienpzProvider,
|
|
183
|
+
useNitidaClient as useAquienpzClient,
|
|
184
|
+
};
|
package/src/server/index.ts
CHANGED
|
@@ -7,9 +7,9 @@
|
|
|
7
7
|
* bundle. The constructor REQUIRES `apiKey`; the type from `/web` omits
|
|
8
8
|
* it, so the two modes never confuse each other.
|
|
9
9
|
*
|
|
10
|
-
* import {
|
|
10
|
+
* import { NitidaClient } from "@nitida/sdk/server";
|
|
11
11
|
*
|
|
12
|
-
* const aq = new
|
|
12
|
+
* const aq = new NitidaClient({
|
|
13
13
|
* endpoint: process.env.ASSET_MANAGER_URL!,
|
|
14
14
|
* apiKey: process.env.ASSET_MANAGER_API_KEY!, // <- required
|
|
15
15
|
* tenantCode: "realtyone-cr",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* // and your route handler forwards here with the real API key.
|
|
26
26
|
*
|
|
27
27
|
* What you get:
|
|
28
|
-
* - `
|
|
28
|
+
* - `NitidaClient` (slots/assets/usage APIs over plain fetch)
|
|
29
29
|
* - URL builders: `getAssetUrl`, `getTransformUrl`, `getTransformSrcSet`,
|
|
30
30
|
* `getHlsStreamingUrl`, `extractAssetSha`, `signTransformUrl`
|
|
31
31
|
* - `aq.upload(bytes)` works with `Uint8Array` (Node 18+ / Bun ship Blob
|
|
@@ -43,17 +43,14 @@
|
|
|
43
43
|
* @module @nitida/sdk/server
|
|
44
44
|
*/
|
|
45
45
|
|
|
46
|
-
import {
|
|
47
|
-
type AquienpzClientOptions,
|
|
48
|
-
AquienpzClient as BaseAquienpzClient,
|
|
49
|
-
} from "..";
|
|
46
|
+
import { NitidaClient as BaseNitidaClient, type NitidaClientOptions } from "..";
|
|
50
47
|
|
|
51
48
|
/**
|
|
52
49
|
* Server-side constructor options — `apiKey` is REQUIRED here. Use this
|
|
53
50
|
* type whenever you build a client behind a process boundary (Node, Bun,
|
|
54
51
|
* Cloud Run, Vercel Functions, edge runtimes, BFFs).
|
|
55
52
|
*
|
|
56
|
-
* const aq = new
|
|
53
|
+
* const aq = new NitidaClient({
|
|
57
54
|
* endpoint: process.env.ASSET_MANAGER_URL!,
|
|
58
55
|
* apiKey: process.env.ASSET_MANAGER_API_KEY!,
|
|
59
56
|
* tenantCode: "realtyone-cr",
|
|
@@ -61,23 +58,22 @@ import {
|
|
|
61
58
|
* });
|
|
62
59
|
*/
|
|
63
60
|
export type ServerClientOptions = Required<
|
|
64
|
-
Pick<
|
|
61
|
+
Pick<NitidaClientOptions, "endpoint" | "apiKey" | "tenantCode" | "tenantId">
|
|
65
62
|
> &
|
|
66
|
-
Pick<
|
|
63
|
+
Pick<NitidaClientOptions, "cdnBase" | "signingKey">;
|
|
67
64
|
|
|
68
65
|
/**
|
|
69
|
-
* Server-safe `
|
|
66
|
+
* Server-safe `NitidaClient` — same runtime as the root class, but the
|
|
70
67
|
* constructor type enforces `apiKey` so misconfiguration is a TS build
|
|
71
68
|
* error, not a runtime 401.
|
|
72
69
|
*/
|
|
73
|
-
export class
|
|
70
|
+
export class NitidaClient extends BaseNitidaClient {
|
|
74
71
|
constructor(opts: ServerClientOptions) {
|
|
75
72
|
super(opts);
|
|
76
73
|
}
|
|
77
74
|
}
|
|
78
75
|
|
|
79
76
|
export {
|
|
80
|
-
type AquienpzClientOptions,
|
|
81
77
|
type AssetDTO,
|
|
82
78
|
type AssetVariant,
|
|
83
79
|
type ComposeMarketingComposition,
|
|
@@ -98,6 +94,7 @@ export {
|
|
|
98
94
|
getTransformUrl,
|
|
99
95
|
getVideoTransformUrl,
|
|
100
96
|
hasPreset,
|
|
97
|
+
type NitidaClientOptions,
|
|
101
98
|
type PresignUploadUrlOptions,
|
|
102
99
|
type RegenerateResult,
|
|
103
100
|
type ResolveSlotOptions,
|
|
@@ -122,3 +119,15 @@ export {
|
|
|
122
119
|
type UsageWindow,
|
|
123
120
|
type VariantPreset,
|
|
124
121
|
} from "..";
|
|
122
|
+
|
|
123
|
+
// ---------------------------------------------------------------------------
|
|
124
|
+
// Legacy names (pre-`nitida` rename, 2026-08-16)
|
|
125
|
+
// ---------------------------------------------------------------------------
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* @deprecated Renamed to `Nitida*`. These aliases keep code written against the
|
|
129
|
+
* old `@aquienpz/*` packages compiling unchanged — same class, same instance,
|
|
130
|
+
* just a second name. They are not going away on a schedule, but new code
|
|
131
|
+
* should use the `Nitida*` names.
|
|
132
|
+
*/
|
|
133
|
+
export { NitidaClient as AquienpzClient };
|
package/src/web/index.ts
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Use this subpath from any browser context (Next.js client components,
|
|
5
5
|
* Vite/CRA SPAs, browser extensions, web workers — anywhere `window`
|
|
6
|
-
* exists). Bundles the core `
|
|
6
|
+
* exists). Bundles the core `NitidaClient` PLUS browser-only helpers
|
|
7
7
|
* (client-side image compression).
|
|
8
8
|
*
|
|
9
9
|
* // 1. In a client component (browser):
|
|
10
|
-
* import {
|
|
10
|
+
* import { NitidaClient } from "@nitida/sdk/web";
|
|
11
11
|
*
|
|
12
|
-
* const aq = new
|
|
12
|
+
* const aq = new NitidaClient({
|
|
13
13
|
* // Point at your BFF route — the SDK calls
|
|
14
14
|
* // `${endpoint}/assets/by-hash/...`, `${endpoint}/slots/...`, etc.
|
|
15
15
|
* endpoint: "/api/am", // relative ⇒ same-origin proxy
|
|
@@ -51,21 +51,18 @@
|
|
|
51
51
|
* @module @nitida/sdk/web
|
|
52
52
|
*/
|
|
53
53
|
|
|
54
|
-
import {
|
|
55
|
-
type AquienpzClientOptions,
|
|
56
|
-
AquienpzClient as BaseAquienpzClient,
|
|
57
|
-
} from "..";
|
|
54
|
+
import { NitidaClient as BaseNitidaClient, type NitidaClientOptions } from "..";
|
|
58
55
|
|
|
59
56
|
/**
|
|
60
57
|
* Browser-safe constructor options for `@nitida/sdk/web`.
|
|
61
58
|
*
|
|
62
|
-
* Identical to the root `
|
|
59
|
+
* Identical to the root `NitidaClientOptions` except `apiKey` and
|
|
63
60
|
* `signingKey` are **physically absent** — passing them is a TypeScript
|
|
64
61
|
* build error, not a runtime warning. In BFF-proxy mode your route
|
|
65
62
|
* handler injects the bearer header server-side; the browser never
|
|
66
63
|
* sees the long-lived key.
|
|
67
64
|
*
|
|
68
|
-
* const aq = new
|
|
65
|
+
* const aq = new NitidaClient({
|
|
69
66
|
* endpoint: "/api/am", // OK: relative → same-origin BFF
|
|
70
67
|
* tenantCode: "realtyone-cr",
|
|
71
68
|
* tenantId: 1,
|
|
@@ -73,21 +70,21 @@ import {
|
|
|
73
70
|
* });
|
|
74
71
|
*/
|
|
75
72
|
export type WebClientOptions = Omit<
|
|
76
|
-
|
|
73
|
+
NitidaClientOptions,
|
|
77
74
|
"apiKey" | "signingKey"
|
|
78
75
|
>;
|
|
79
76
|
|
|
80
77
|
/**
|
|
81
|
-
* Browser-safe `
|
|
78
|
+
* Browser-safe `NitidaClient` — same runtime as the root class, but
|
|
82
79
|
* the constructor's type rejects `apiKey` / `signingKey`. Calls go
|
|
83
80
|
* through your BFF (typically a same-origin route like `/api/am/...`).
|
|
84
81
|
*
|
|
85
82
|
* For server-side instantiation (Node/Bun/edge), import from
|
|
86
83
|
* `@nitida/sdk/server` instead.
|
|
87
84
|
*/
|
|
88
|
-
export class
|
|
85
|
+
export class NitidaClient extends BaseNitidaClient {
|
|
89
86
|
constructor(opts: WebClientOptions) {
|
|
90
|
-
super(opts as
|
|
87
|
+
super(opts as NitidaClientOptions);
|
|
91
88
|
}
|
|
92
89
|
}
|
|
93
90
|
|
|
@@ -332,3 +329,15 @@ export async function compressImages(
|
|
|
332
329
|
}
|
|
333
330
|
return results;
|
|
334
331
|
}
|
|
332
|
+
|
|
333
|
+
// ---------------------------------------------------------------------------
|
|
334
|
+
// Legacy names (pre-`nitida` rename, 2026-08-16)
|
|
335
|
+
// ---------------------------------------------------------------------------
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* @deprecated Renamed to `Nitida*`. These aliases keep code written against the
|
|
339
|
+
* old `@aquienpz/*` packages compiling unchanged — same class, same instance,
|
|
340
|
+
* just a second name. They are not going away on a schedule, but new code
|
|
341
|
+
* should use the `Nitida*` names.
|
|
342
|
+
*/
|
|
343
|
+
export { NitidaClient as AquienpzClient };
|