@nitida/sdk 0.20.1 → 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/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 +6 -6
- package/dist/index.js.map +1 -1
- package/dist/react.d.ts +7 -7
- package/dist/react.js +7 -7
- package/dist/react.js.map +1 -1
- package/dist/server.d.ts +9 -9
- package/dist/server.js +7 -7
- package/dist/server.js.map +1 -1
- package/dist/web.d.ts +10 -10
- package/dist/web.js +7 -7
- package/dist/web.js.map +1 -1
- package/package.json +1 -1
- package/skills/nitida-sdk/SKILL.md +97 -0
- package/src/expo/index.ts +3 -3
- package/src/index.ts +17 -17
- package/src/react/index.ts +10 -10
- package/src/server/index.ts +10 -13
- package/src/web/index.ts +10 -13
package/dist/react.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { NitidaClient } from './index.js';
|
|
3
3
|
import { ResolveSlotOptions, SlotResolution } from '@nitida/asset-client';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -8,18 +8,18 @@ import { ResolveSlotOptions, SlotResolution } from '@nitida/asset-client';
|
|
|
8
8
|
* Kept in a subpath so the SSR-safe core (`@nitida/sdk`) stays
|
|
9
9
|
* dependency-free of react. Import only what you need:
|
|
10
10
|
*
|
|
11
|
-
* import { useSlot, useSlots,
|
|
11
|
+
* import { useSlot, useSlots, NitidaProvider } from "@nitida/sdk/react";
|
|
12
12
|
*
|
|
13
|
-
* Pattern: wrap your app in `<
|
|
13
|
+
* Pattern: wrap your app in `<NitidaProvider client={…}>` once at
|
|
14
14
|
* the root; hooks read the client from context. No prop-drilling.
|
|
15
15
|
* @module @nitida/sdk/react
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
declare function
|
|
19
|
-
client:
|
|
18
|
+
declare function NitidaProvider(props: {
|
|
19
|
+
client: NitidaClient;
|
|
20
20
|
children: ReactNode;
|
|
21
21
|
}): ReactNode;
|
|
22
|
-
declare function
|
|
22
|
+
declare function useNitidaClient(): NitidaClient;
|
|
23
23
|
type SlotState = {
|
|
24
24
|
/** Resolved DTO (`null` while loading or unbound). */
|
|
25
25
|
resolution: SlotResolution | null;
|
|
@@ -44,4 +44,4 @@ declare function useSlots(slotKeys: string[], options?: ResolveSlotOptions): {
|
|
|
44
44
|
error: Error | null;
|
|
45
45
|
};
|
|
46
46
|
|
|
47
|
-
export {
|
|
47
|
+
export { NitidaProvider, useNitidaClient, useSlot, useSlots };
|
package/dist/react.js
CHANGED
|
@@ -8,18 +8,18 @@ import {
|
|
|
8
8
|
useState
|
|
9
9
|
} from "react";
|
|
10
10
|
var ClientContext = createContext(null);
|
|
11
|
-
function
|
|
11
|
+
function NitidaProvider(props) {
|
|
12
12
|
return createElement(
|
|
13
13
|
ClientContext.Provider,
|
|
14
14
|
{ value: props.client },
|
|
15
15
|
props.children
|
|
16
16
|
);
|
|
17
17
|
}
|
|
18
|
-
function
|
|
18
|
+
function useNitidaClient() {
|
|
19
19
|
const client = useContext(ClientContext);
|
|
20
20
|
if (!client) {
|
|
21
21
|
throw new Error(
|
|
22
|
-
"
|
|
22
|
+
"useNitidaClient: wrap your app in <NitidaProvider client={\u2026}>."
|
|
23
23
|
);
|
|
24
24
|
}
|
|
25
25
|
return client;
|
|
@@ -31,7 +31,7 @@ var emptyState = {
|
|
|
31
31
|
error: null
|
|
32
32
|
};
|
|
33
33
|
function useSlot(slotKey, options = {}) {
|
|
34
|
-
const client =
|
|
34
|
+
const client = useNitidaClient();
|
|
35
35
|
const [state, setState] = useState(emptyState);
|
|
36
36
|
const presetKey = options.preset ?? "";
|
|
37
37
|
const ttlMs = options.ttlMs ?? 6e4;
|
|
@@ -62,7 +62,7 @@ function useSlot(slotKey, options = {}) {
|
|
|
62
62
|
return state;
|
|
63
63
|
}
|
|
64
64
|
function useSlots(slotKeys, options = {}) {
|
|
65
|
-
const client =
|
|
65
|
+
const client = useNitidaClient();
|
|
66
66
|
const keysHash = useMemo(() => slotKeys.join("|"), [slotKeys]);
|
|
67
67
|
const presetKey = options.preset ?? "";
|
|
68
68
|
const ttlMs = options.ttlMs ?? 6e4;
|
|
@@ -88,8 +88,8 @@ function useSlots(slotKeys, options = {}) {
|
|
|
88
88
|
return state;
|
|
89
89
|
}
|
|
90
90
|
export {
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
NitidaProvider,
|
|
92
|
+
useNitidaClient,
|
|
93
93
|
useSlot,
|
|
94
94
|
useSlots
|
|
95
95
|
};
|
package/dist/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/react/index.ts"],"sourcesContent":["/**\n * @nitida/sdk/react — React hooks layered on top of the universal SDK.\n *\n * Kept in a subpath so the SSR-safe core (`@nitida/sdk`) stays\n * dependency-free of react. Import only what you need:\n *\n * import { useSlot, useSlots,
|
|
1
|
+
{"version":3,"sources":["../src/react/index.ts"],"sourcesContent":["/**\n * @nitida/sdk/react — React hooks layered on top of the universal SDK.\n *\n * Kept in a subpath so the SSR-safe core (`@nitida/sdk`) stays\n * dependency-free of react. Import only what you need:\n *\n * import { useSlot, useSlots, NitidaProvider } from \"@nitida/sdk/react\";\n *\n * Pattern: wrap your app in `<NitidaProvider client={…}>` once at\n * the root; hooks read the client from context. No prop-drilling.\n * @module @nitida/sdk/react\n */\n\nimport {\n createContext,\n createElement,\n type ReactNode,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\nimport type { NitidaClient, ResolveSlotOptions, SlotResolution } from \"..\";\n\n// ---------------------------------------------------------------------------\n// Provider\n// ---------------------------------------------------------------------------\n\nconst ClientContext = createContext<NitidaClient | null>(null);\n\nexport function NitidaProvider(props: {\n client: NitidaClient;\n children: ReactNode;\n}): ReactNode {\n return createElement(\n ClientContext.Provider,\n { value: props.client },\n props.children,\n );\n}\n\nexport function useNitidaClient(): NitidaClient {\n const client = useContext(ClientContext);\n if (!client) {\n throw new Error(\n \"useNitidaClient: wrap your app in <NitidaProvider client={…}>.\",\n );\n }\n return client;\n}\n\n// ---------------------------------------------------------------------------\n// Slot hooks\n// ---------------------------------------------------------------------------\n\ntype SlotState = {\n /** Resolved DTO (`null` while loading or unbound). */\n resolution: SlotResolution | null;\n /** Convenience: the CDN URL, when resolved. */\n url: string | null;\n isLoading: boolean;\n error: Error | null;\n};\n\nconst emptyState: SlotState = {\n resolution: null,\n url: null,\n isLoading: true,\n error: null,\n};\n\n/**\n * Subscribe to a single slot. Re-resolves when the key changes or the\n * cache is invalidated. Returns `{resolution, url, isLoading, error}`.\n */\nexport function useSlot(\n slotKey: string,\n options: ResolveSlotOptions = {},\n): SlotState {\n const client = useNitidaClient();\n const [state, setState] = useState<SlotState>(emptyState);\n\n // Stabilize options across renders so the effect only refires on the\n // values that matter.\n const presetKey = options.preset ?? \"\";\n const ttlMs = options.ttlMs ?? 60_000;\n\n useEffect(() => {\n let alive = true;\n setState((prev) => ({ ...prev, isLoading: true, error: null }));\n client.slots\n .resolve(slotKey, { preset: options.preset, ttlMs })\n .then((resolution) => {\n if (!alive) return;\n setState({\n resolution,\n url: resolution.url,\n isLoading: false,\n error: null,\n });\n })\n .catch((err: unknown) => {\n if (!alive) return;\n setState({\n resolution: null,\n url: null,\n isLoading: false,\n error: err instanceof Error ? err : new Error(String(err)),\n });\n });\n return () => {\n alive = false;\n };\n }, [client, slotKey, presetKey, ttlMs, options.preset]);\n\n return state;\n}\n\n/**\n * Bulk version — fetches N keys in one round-trip. Returns a map keyed\n * by slot key. Pass a STABLE array reference (memoize with useMemo) to\n * avoid re-fetches on every render.\n */\nexport function useSlots(\n slotKeys: string[],\n options: ResolveSlotOptions = {},\n): {\n resolutions: Record<string, SlotResolution>;\n isLoading: boolean;\n error: Error | null;\n} {\n const client = useNitidaClient();\n const keysHash = useMemo(() => slotKeys.join(\"|\"), [slotKeys]);\n const presetKey = options.preset ?? \"\";\n const ttlMs = options.ttlMs ?? 60_000;\n\n const [state, setState] = useState<{\n resolutions: Record<string, SlotResolution>;\n isLoading: boolean;\n error: Error | null;\n }>({ resolutions: {}, isLoading: true, error: null });\n\n useEffect(() => {\n let alive = true;\n setState((prev) => ({ ...prev, isLoading: true, error: null }));\n client.slots\n .resolveMany(slotKeys, { preset: options.preset, ttlMs })\n .then((resolutions) => {\n if (!alive) return;\n setState({ resolutions, isLoading: false, error: null });\n })\n .catch((err: unknown) => {\n if (!alive) return;\n setState({\n resolutions: {},\n isLoading: false,\n error: err instanceof Error ? err : new Error(String(err)),\n });\n });\n return () => {\n alive = false;\n };\n // slotKeys is hashed via keysHash; using it directly here would\n // re-fire on every render (new array identity each render).\n // biome-ignore lint/correctness/useExhaustiveDependencies: keysHash captures slotKeys identity\n }, [client, keysHash, presetKey, ttlMs]);\n\n return state;\n}\n"],"mappings":";AAaA;AAAA,EACE;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAOP,IAAM,gBAAgB,cAAmC,IAAI;AAEtD,SAAS,eAAe,OAGjB;AACZ,SAAO;AAAA,IACL,cAAc;AAAA,IACd,EAAE,OAAO,MAAM,OAAO;AAAA,IACtB,MAAM;AAAA,EACR;AACF;AAEO,SAAS,kBAAgC;AAC9C,QAAM,SAAS,WAAW,aAAa;AACvC,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAeA,IAAM,aAAwB;AAAA,EAC5B,YAAY;AAAA,EACZ,KAAK;AAAA,EACL,WAAW;AAAA,EACX,OAAO;AACT;AAMO,SAAS,QACd,SACA,UAA8B,CAAC,GACpB;AACX,QAAM,SAAS,gBAAgB;AAC/B,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAoB,UAAU;AAIxD,QAAM,YAAY,QAAQ,UAAU;AACpC,QAAM,QAAQ,QAAQ,SAAS;AAE/B,YAAU,MAAM;AACd,QAAI,QAAQ;AACZ,aAAS,CAAC,UAAU,EAAE,GAAG,MAAM,WAAW,MAAM,OAAO,KAAK,EAAE;AAC9D,WAAO,MACJ,QAAQ,SAAS,EAAE,QAAQ,QAAQ,QAAQ,MAAM,CAAC,EAClD,KAAK,CAAC,eAAe;AACpB,UAAI,CAAC,MAAO;AACZ,eAAS;AAAA,QACP;AAAA,QACA,KAAK,WAAW;AAAA,QAChB,WAAW;AAAA,QACX,OAAO;AAAA,MACT,CAAC;AAAA,IACH,CAAC,EACA,MAAM,CAAC,QAAiB;AACvB,UAAI,CAAC,MAAO;AACZ,eAAS;AAAA,QACP,YAAY;AAAA,QACZ,KAAK;AAAA,QACL,WAAW;AAAA,QACX,OAAO,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC;AAAA,MAC3D,CAAC;AAAA,IACH,CAAC;AACH,WAAO,MAAM;AACX,cAAQ;AAAA,IACV;AAAA,EACF,GAAG,CAAC,QAAQ,SAAS,WAAW,OAAO,QAAQ,MAAM,CAAC;AAEtD,SAAO;AACT;AAOO,SAAS,SACd,UACA,UAA8B,CAAC,GAK/B;AACA,QAAM,SAAS,gBAAgB;AAC/B,QAAM,WAAW,QAAQ,MAAM,SAAS,KAAK,GAAG,GAAG,CAAC,QAAQ,CAAC;AAC7D,QAAM,YAAY,QAAQ,UAAU;AACpC,QAAM,QAAQ,QAAQ,SAAS;AAE/B,QAAM,CAAC,OAAO,QAAQ,IAAI,SAIvB,EAAE,aAAa,CAAC,GAAG,WAAW,MAAM,OAAO,KAAK,CAAC;AAEpD,YAAU,MAAM;AACd,QAAI,QAAQ;AACZ,aAAS,CAAC,UAAU,EAAE,GAAG,MAAM,WAAW,MAAM,OAAO,KAAK,EAAE;AAC9D,WAAO,MACJ,YAAY,UAAU,EAAE,QAAQ,QAAQ,QAAQ,MAAM,CAAC,EACvD,KAAK,CAAC,gBAAgB;AACrB,UAAI,CAAC,MAAO;AACZ,eAAS,EAAE,aAAa,WAAW,OAAO,OAAO,KAAK,CAAC;AAAA,IACzD,CAAC,EACA,MAAM,CAAC,QAAiB;AACvB,UAAI,CAAC,MAAO;AACZ,eAAS;AAAA,QACP,aAAa,CAAC;AAAA,QACd,WAAW;AAAA,QACX,OAAO,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,GAAG,CAAC;AAAA,MAC3D,CAAC;AAAA,IACH,CAAC;AACH,WAAO,MAAM;AACX,cAAQ;AAAA,IACV;AAAA,EAIF,GAAG,CAAC,QAAQ,UAAU,WAAW,KAAK,CAAC;AAEvC,SAAO;AACT;","names":[]}
|
package/dist/server.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NitidaClient as NitidaClient$1, NitidaClientOptions } from './index.js';
|
|
2
2
|
export { ComposeMarketingComposition, ComposeMarketingOptions, ComposeMarketingResult, ComposeMarketingSegment, CompressOptions, PresignUploadUrlOptions, RegenerateResult, SlotHistoryEntry, UploadOptions, UploadResult, UploadUrlResult, UsageDailyPoint, UsagePerKey, UsageSnapshot, UsageWindow } from './index.js';
|
|
3
3
|
export { AssetDTO, AssetVariant, ResolveSlotOptions, SignedTransformOptions, SlotDTO, SlotResolution, TransformEffect, TransformFit, TransformFormat, TransformGravity, TransformOptions, VariantPreset, computeVariantDimensions, extractAssetSha, getAssetDimensions, getAssetSrcSet, getAssetUrl, getHlsStreamingUrl, getSignedTransformUrl, getTenantId, getTransformSrcSet, getTransformUrl, getVideoTransformUrl, hasPreset, serializeTransform, setTenantId, signTransformUrl } from '@nitida/asset-client';
|
|
4
4
|
|
|
@@ -11,9 +11,9 @@ export { AssetDTO, AssetVariant, ResolveSlotOptions, SignedTransformOptions, Slo
|
|
|
11
11
|
* bundle. The constructor REQUIRES `apiKey`; the type from `/web` omits
|
|
12
12
|
* it, so the two modes never confuse each other.
|
|
13
13
|
*
|
|
14
|
-
* import {
|
|
14
|
+
* import { NitidaClient } from "@nitida/sdk/server";
|
|
15
15
|
*
|
|
16
|
-
* const aq = new
|
|
16
|
+
* const aq = new NitidaClient({
|
|
17
17
|
* endpoint: process.env.ASSET_MANAGER_URL!,
|
|
18
18
|
* apiKey: process.env.ASSET_MANAGER_API_KEY!, // <- required
|
|
19
19
|
* tenantCode: "realtyone-cr",
|
|
@@ -29,7 +29,7 @@ export { AssetDTO, AssetVariant, ResolveSlotOptions, SignedTransformOptions, Slo
|
|
|
29
29
|
* // and your route handler forwards here with the real API key.
|
|
30
30
|
*
|
|
31
31
|
* What you get:
|
|
32
|
-
* - `
|
|
32
|
+
* - `NitidaClient` (slots/assets/usage APIs over plain fetch)
|
|
33
33
|
* - URL builders: `getAssetUrl`, `getTransformUrl`, `getTransformSrcSet`,
|
|
34
34
|
* `getHlsStreamingUrl`, `extractAssetSha`, `signTransformUrl`
|
|
35
35
|
* - `aq.upload(bytes)` works with `Uint8Array` (Node 18+ / Bun ship Blob
|
|
@@ -52,21 +52,21 @@ export { AssetDTO, AssetVariant, ResolveSlotOptions, SignedTransformOptions, Slo
|
|
|
52
52
|
* type whenever you build a client behind a process boundary (Node, Bun,
|
|
53
53
|
* Cloud Run, Vercel Functions, edge runtimes, BFFs).
|
|
54
54
|
*
|
|
55
|
-
* const aq = new
|
|
55
|
+
* const aq = new NitidaClient({
|
|
56
56
|
* endpoint: process.env.ASSET_MANAGER_URL!,
|
|
57
57
|
* apiKey: process.env.ASSET_MANAGER_API_KEY!,
|
|
58
58
|
* tenantCode: "realtyone-cr",
|
|
59
59
|
* tenantId: 1,
|
|
60
60
|
* });
|
|
61
61
|
*/
|
|
62
|
-
type ServerClientOptions = Required<Pick<
|
|
62
|
+
type ServerClientOptions = Required<Pick<NitidaClientOptions, "endpoint" | "apiKey" | "tenantCode" | "tenantId">> & Pick<NitidaClientOptions, "cdnBase" | "signingKey">;
|
|
63
63
|
/**
|
|
64
|
-
* Server-safe `
|
|
64
|
+
* Server-safe `NitidaClient` — same runtime as the root class, but the
|
|
65
65
|
* constructor type enforces `apiKey` so misconfiguration is a TS build
|
|
66
66
|
* error, not a runtime 401.
|
|
67
67
|
*/
|
|
68
|
-
declare class
|
|
68
|
+
declare class NitidaClient extends NitidaClient$1 {
|
|
69
69
|
constructor(opts: ServerClientOptions);
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
export {
|
|
72
|
+
export { NitidaClient, NitidaClientOptions, type ServerClientOptions };
|
package/dist/server.js
CHANGED
|
@@ -477,7 +477,7 @@ var UsageApi = class {
|
|
|
477
477
|
return authHeaders(this.opts);
|
|
478
478
|
}
|
|
479
479
|
};
|
|
480
|
-
var
|
|
480
|
+
var NitidaClient = class {
|
|
481
481
|
slots;
|
|
482
482
|
assets;
|
|
483
483
|
usage;
|
|
@@ -519,7 +519,7 @@ var AquienpzClient = class {
|
|
|
519
519
|
}
|
|
520
520
|
if (!this.opts.signingKey) {
|
|
521
521
|
throw new Error(
|
|
522
|
-
"aq.transform({ sign: true }) requires `signingKey` in
|
|
522
|
+
"aq.transform({ sign: true }) requires `signingKey` in NitidaClientOptions. Pull the tenant's signing key from /admin/tenants/:id and pass it to the SDK constructor on a SERVER-side instance only."
|
|
523
523
|
);
|
|
524
524
|
}
|
|
525
525
|
return getSignedTransformUrl(asset, opts, this.opts.signingKey) ?? Promise.resolve(this.urlFor(asset, "lg"));
|
|
@@ -528,7 +528,7 @@ var AquienpzClient = class {
|
|
|
528
528
|
if (!signOpts?.sign) return getTransformSrcSet(asset, widths, extraOpts);
|
|
529
529
|
if (!this.opts.signingKey) {
|
|
530
530
|
throw new Error(
|
|
531
|
-
"aq.transformSrcSet({ sign: true }) requires `signingKey` in
|
|
531
|
+
"aq.transformSrcSet({ sign: true }) requires `signingKey` in NitidaClientOptions."
|
|
532
532
|
);
|
|
533
533
|
}
|
|
534
534
|
const key = this.opts.signingKey;
|
|
@@ -621,9 +621,9 @@ var AquienpzClient = class {
|
|
|
621
621
|
*
|
|
622
622
|
* @example Deliver an image on a site (the responsive ladder)
|
|
623
623
|
* ```ts
|
|
624
|
-
* import {
|
|
624
|
+
* import { NitidaClient } from "@nitida/sdk/server";
|
|
625
625
|
*
|
|
626
|
-
* const aq = new
|
|
626
|
+
* const aq = new NitidaClient({ endpoint, apiKey, tenantCode, tenantId });
|
|
627
627
|
* const { assetId, sha256 } = await aq.upload(file, {
|
|
628
628
|
* fileName: file.name,
|
|
629
629
|
* presets: ["thumb", "sm", "md", "lg"],
|
|
@@ -782,13 +782,13 @@ var AquienpzClient = class {
|
|
|
782
782
|
};
|
|
783
783
|
|
|
784
784
|
// src/server/index.ts
|
|
785
|
-
var
|
|
785
|
+
var NitidaClient2 = class extends NitidaClient {
|
|
786
786
|
constructor(opts) {
|
|
787
787
|
super(opts);
|
|
788
788
|
}
|
|
789
789
|
};
|
|
790
790
|
export {
|
|
791
|
-
|
|
791
|
+
NitidaClient2 as NitidaClient,
|
|
792
792
|
computeVariantDimensions,
|
|
793
793
|
extractAssetSha,
|
|
794
794
|
getAssetDimensions,
|