@quikturn/logos-next 1.0.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 +262 -0
- package/dist/index.cjs +101 -0
- package/dist/index.d.cts +115 -0
- package/dist/index.d.ts +115 -0
- package/dist/index.mjs +75 -0
- package/dist/server.cjs +29 -0
- package/dist/server.d.cts +23 -0
- package/dist/server.d.ts +23 -0
- package/dist/server.mjs +23 -0
- package/package.json +90 -0
package/README.md
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
# @quikturn/logos-next
|
|
2
|
+
|
|
3
|
+
> Next.js components for the [Quikturn Logos API](https://getquikturn.io) -- `<QuikturnImage>` with `next/image` integration, image loaders, and server helpers.
|
|
4
|
+
|
|
5
|
+
**[Get your API key](https://getquikturn.io)** -- free tier available, no credit card required.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **`<QuikturnImage>`** -- `next/image` wrapper that renders a Quikturn logo with automatic optimization
|
|
10
|
+
- **`quikturnImageLoader`** -- basic Next.js image loader for the Logos API
|
|
11
|
+
- **`createQuikturnImageLoader()`** -- factory for pre-configured image loaders with token, format, theme
|
|
12
|
+
- **`<QuikturnProvider>`** -- context provider for token and base URL propagation
|
|
13
|
+
- **Server helpers** -- `getServerClient()` and `getLogoBuffer()` for API routes and server components
|
|
14
|
+
- **Re-exports** -- all `@quikturn/logos-react` components (`QuikturnLogo`, `QuikturnLogoCarousel`, `QuikturnLogoGrid`, `useLogoUrl`)
|
|
15
|
+
- **Tree-shakeable** -- ESM and CJS dual builds; import only what you use
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# pnpm (recommended)
|
|
21
|
+
pnpm add @quikturn/logos-next @quikturn/logos @quikturn/logos-react next react react-dom
|
|
22
|
+
|
|
23
|
+
# npm
|
|
24
|
+
npm install @quikturn/logos-next @quikturn/logos @quikturn/logos-react next react react-dom
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Peer dependencies:** `next >= 14`, `react >= 18`, `react-dom >= 18`
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
```tsx
|
|
32
|
+
import { QuikturnProvider, QuikturnImage } from "@quikturn/logos-next";
|
|
33
|
+
|
|
34
|
+
export default function Page() {
|
|
35
|
+
return (
|
|
36
|
+
<QuikturnProvider token="qt_your_publishable_key">
|
|
37
|
+
<QuikturnImage domain="github.com" width={128} height={128} alt="GitHub" />
|
|
38
|
+
</QuikturnProvider>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## API Reference
|
|
44
|
+
|
|
45
|
+
### `<QuikturnImage>`
|
|
46
|
+
|
|
47
|
+
A `next/image` wrapper that renders a Quikturn logo for the given domain. Automatically constructs a custom `loader`, fires an attribution beacon on mount, and reads a token from `<QuikturnProvider>` context when available.
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
<QuikturnImage
|
|
51
|
+
domain="stripe.com"
|
|
52
|
+
width={256}
|
|
53
|
+
height={256}
|
|
54
|
+
format="webp"
|
|
55
|
+
greyscale
|
|
56
|
+
theme="dark"
|
|
57
|
+
alt="Stripe"
|
|
58
|
+
priority
|
|
59
|
+
/>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
| Prop | Type | Default | Description |
|
|
63
|
+
|------|------|---------|-------------|
|
|
64
|
+
| `domain` | `string` | **required** | Domain to fetch logo for |
|
|
65
|
+
| `token` | `string` | from context | Publishable API key (`qt_`/`pk_` prefix) |
|
|
66
|
+
| `format` | `string` | -- | Output format (`"png"`, `"jpeg"`, `"webp"`, `"avif"`, or MIME type) |
|
|
67
|
+
| `greyscale` | `boolean` | `false` | Greyscale transformation |
|
|
68
|
+
| `theme` | `"light" \| "dark"` | -- | Background-optimized rendering |
|
|
69
|
+
| `width` | `number` | **required** | Image width in pixels (from `next/image`) |
|
|
70
|
+
| `height` | `number` | **required** | Image height in pixels (from `next/image`) |
|
|
71
|
+
| `alt` | `string` | `"<domain> logo"` | Image alt text |
|
|
72
|
+
| `priority` | `boolean` | `false` | Disable lazy loading (from `next/image`) |
|
|
73
|
+
| ...rest | `ImageProps` | -- | All other `next/image` props are forwarded |
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
### `quikturnImageLoader`
|
|
78
|
+
|
|
79
|
+
Basic image loader compatible with `next/image`. Converts a domain + width into a Logos API URL without any pre-configured options.
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
import Image from "next/image";
|
|
83
|
+
import { quikturnImageLoader } from "@quikturn/logos-next";
|
|
84
|
+
|
|
85
|
+
<Image
|
|
86
|
+
loader={quikturnImageLoader}
|
|
87
|
+
src="github.com"
|
|
88
|
+
width={256}
|
|
89
|
+
height={256}
|
|
90
|
+
alt="GitHub"
|
|
91
|
+
/>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
### `createQuikturnImageLoader(options)`
|
|
97
|
+
|
|
98
|
+
Factory that creates a pre-configured image loader with baked-in token, format, theme, and other options.
|
|
99
|
+
|
|
100
|
+
```tsx
|
|
101
|
+
import Image from "next/image";
|
|
102
|
+
import { createQuikturnImageLoader } from "@quikturn/logos-next";
|
|
103
|
+
|
|
104
|
+
const loader = createQuikturnImageLoader({
|
|
105
|
+
token: "qt_abc123",
|
|
106
|
+
format: "webp",
|
|
107
|
+
greyscale: true,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
<Image loader={loader} src="github.com" width={256} height={256} alt="GitHub" />
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
| Option | Type | Description |
|
|
114
|
+
|--------|------|-------------|
|
|
115
|
+
| `token` | `string` | Publishable API key |
|
|
116
|
+
| `format` | `string` | Output format |
|
|
117
|
+
| `greyscale` | `boolean` | Greyscale transformation |
|
|
118
|
+
| `theme` | `"light" \| "dark"` | Theme optimization |
|
|
119
|
+
| `baseUrl` | `string` | Override the Quikturn API base URL |
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
### `<QuikturnProvider>`
|
|
124
|
+
|
|
125
|
+
Provides `token` and `baseUrl` to all nested `QuikturnImage` components via React Context.
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
<QuikturnProvider token="qt_abc123" baseUrl="https://custom.api">
|
|
129
|
+
{children}
|
|
130
|
+
</QuikturnProvider>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
| Prop | Type | Required | Description |
|
|
134
|
+
|------|------|----------|-------------|
|
|
135
|
+
| `token` | `string` | yes | Publishable API key (`qt_`/`pk_` prefix) |
|
|
136
|
+
| `baseUrl` | `string` | no | Override the Quikturn API base URL |
|
|
137
|
+
| `children` | `ReactNode` | yes | Child components |
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
### Server Helpers
|
|
142
|
+
|
|
143
|
+
Import from `@quikturn/logos-next/server` for use in API routes and server components. This entry point is gated by `server-only` and will throw at build time if imported in client code.
|
|
144
|
+
|
|
145
|
+
#### `getServerClient()`
|
|
146
|
+
|
|
147
|
+
Returns a singleton `QuikturnLogos` server client. Reads the `QUIKTURN_SECRET_KEY` environment variable on first call and caches the instance.
|
|
148
|
+
|
|
149
|
+
#### `getLogoBuffer(domain, options?)`
|
|
150
|
+
|
|
151
|
+
Convenience wrapper that fetches a logo buffer using the cached server client.
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
// app/api/logo/route.ts
|
|
155
|
+
import { getLogoBuffer } from "@quikturn/logos-next/server";
|
|
156
|
+
|
|
157
|
+
export async function GET(request: Request) {
|
|
158
|
+
const { searchParams } = new URL(request.url);
|
|
159
|
+
const domain = searchParams.get("domain") ?? "example.com";
|
|
160
|
+
|
|
161
|
+
const result = await getLogoBuffer(domain, { format: "image/webp" });
|
|
162
|
+
|
|
163
|
+
return new Response(result.buffer, {
|
|
164
|
+
headers: { "Content-Type": result.contentType },
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Environment variable required:** `QUIKTURN_SECRET_KEY` (set in `.env.local` or your deployment environment).
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Re-exported Components
|
|
174
|
+
|
|
175
|
+
The following are re-exported from `@quikturn/logos-react` for convenience, so you can import everything from a single package:
|
|
176
|
+
|
|
177
|
+
- **`<QuikturnLogo>`** -- single logo image with lazy loading and optional link wrapper
|
|
178
|
+
- **`<QuikturnLogoCarousel>`** -- infinite scrolling logo ticker
|
|
179
|
+
- **`<QuikturnLogoGrid>`** -- responsive CSS grid of logos
|
|
180
|
+
- **`useLogoUrl()`** -- hook that returns a memoized Quikturn logo URL
|
|
181
|
+
|
|
182
|
+
See the [@quikturn/logos-react README](https://www.npmjs.com/package/@quikturn/logos-react) for full documentation on these components.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## Examples
|
|
187
|
+
|
|
188
|
+
### Logo Grid with Next.js Image Optimization
|
|
189
|
+
|
|
190
|
+
```tsx
|
|
191
|
+
import { QuikturnProvider, QuikturnImage } from "@quikturn/logos-next";
|
|
192
|
+
|
|
193
|
+
const PARTNERS = ["github.com", "stripe.com", "vercel.com", "figma.com"];
|
|
194
|
+
|
|
195
|
+
export default function Partners() {
|
|
196
|
+
return (
|
|
197
|
+
<QuikturnProvider token="qt_your_key">
|
|
198
|
+
<div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 24 }}>
|
|
199
|
+
{PARTNERS.map((domain) => (
|
|
200
|
+
<QuikturnImage key={domain} domain={domain} width={128} height={128} alt={domain} />
|
|
201
|
+
))}
|
|
202
|
+
</div>
|
|
203
|
+
</QuikturnProvider>
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Custom Loader with Global Config
|
|
209
|
+
|
|
210
|
+
```tsx
|
|
211
|
+
// lib/quikturn-loader.ts
|
|
212
|
+
import { createQuikturnImageLoader } from "@quikturn/logos-next";
|
|
213
|
+
|
|
214
|
+
export const logoLoader = createQuikturnImageLoader({
|
|
215
|
+
token: process.env.NEXT_PUBLIC_QUIKTURN_KEY!,
|
|
216
|
+
format: "webp",
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
// app/page.tsx
|
|
220
|
+
import Image from "next/image";
|
|
221
|
+
import { logoLoader } from "@/lib/quikturn-loader";
|
|
222
|
+
|
|
223
|
+
export default function Page() {
|
|
224
|
+
return <Image loader={logoLoader} src="github.com" width={64} height={64} alt="GitHub" />;
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Server-Side Logo Proxy
|
|
229
|
+
|
|
230
|
+
```ts
|
|
231
|
+
// app/api/logo/[domain]/route.ts
|
|
232
|
+
import { getLogoBuffer } from "@quikturn/logos-next/server";
|
|
233
|
+
|
|
234
|
+
export async function GET(
|
|
235
|
+
_request: Request,
|
|
236
|
+
{ params }: { params: { domain: string } },
|
|
237
|
+
) {
|
|
238
|
+
const result = await getLogoBuffer(params.domain, {
|
|
239
|
+
format: "image/png",
|
|
240
|
+
size: 256,
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
return new Response(result.buffer, {
|
|
244
|
+
headers: {
|
|
245
|
+
"Content-Type": result.contentType,
|
|
246
|
+
"Cache-Control": "public, max-age=86400",
|
|
247
|
+
},
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
## Resources
|
|
253
|
+
|
|
254
|
+
- **[Quikturn website](https://getquikturn.io)** -- sign up, manage keys, explore the API
|
|
255
|
+
- **[Dashboard](https://getquikturn.io/dashboard)** -- usage analytics, key management, plan upgrades
|
|
256
|
+
- **[Pricing](https://getquikturn.io/pricing)** -- free tier, pro, and enterprise plans
|
|
257
|
+
- **[Core SDK docs](https://www.npmjs.com/package/@quikturn/logos)** -- `@quikturn/logos` URL builder, browser client, server client
|
|
258
|
+
- **[React SDK docs](https://www.npmjs.com/package/@quikturn/logos-react)** -- `@quikturn/logos-react` components and hooks
|
|
259
|
+
|
|
260
|
+
## License
|
|
261
|
+
|
|
262
|
+
MIT -- built by [Quikturn](https://getquikturn.io)
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var Image2 = require('next/image');
|
|
4
|
+
var logos = require('@quikturn/logos');
|
|
5
|
+
var react = require('react');
|
|
6
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
7
|
+
var logosReact = require('@quikturn/logos-react');
|
|
8
|
+
|
|
9
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
+
|
|
11
|
+
var Image2__default = /*#__PURE__*/_interopDefault(Image2);
|
|
12
|
+
|
|
13
|
+
var fired = /* @__PURE__ */ new Set();
|
|
14
|
+
function fireBeacon(token) {
|
|
15
|
+
if (typeof window === "undefined") return;
|
|
16
|
+
if (!token || token.startsWith("sk_")) return;
|
|
17
|
+
if (fired.has(token)) return;
|
|
18
|
+
fired.add(token);
|
|
19
|
+
const img = new Image();
|
|
20
|
+
img.src = `${logos.BASE_URL}/_beacon?token=${token}&page=${encodeURIComponent(location.href)}`;
|
|
21
|
+
}
|
|
22
|
+
var QuikturnContext = react.createContext(null);
|
|
23
|
+
function useQuikturnContext() {
|
|
24
|
+
return react.useContext(QuikturnContext);
|
|
25
|
+
}
|
|
26
|
+
function QuikturnProvider({
|
|
27
|
+
token,
|
|
28
|
+
baseUrl,
|
|
29
|
+
children
|
|
30
|
+
}) {
|
|
31
|
+
return /* @__PURE__ */ jsxRuntime.jsx(QuikturnContext.Provider, { value: { token, baseUrl }, children });
|
|
32
|
+
}
|
|
33
|
+
function QuikturnImage({
|
|
34
|
+
domain,
|
|
35
|
+
token,
|
|
36
|
+
format,
|
|
37
|
+
greyscale,
|
|
38
|
+
theme,
|
|
39
|
+
alt,
|
|
40
|
+
...imageProps
|
|
41
|
+
}) {
|
|
42
|
+
const ctx = useQuikturnContext();
|
|
43
|
+
const effectiveToken = token ?? ctx?.token ?? "";
|
|
44
|
+
const loader = react.useMemo(
|
|
45
|
+
() => ({ src, width }) => logos.logoUrl(src, {
|
|
46
|
+
token: effectiveToken || void 0,
|
|
47
|
+
size: width,
|
|
48
|
+
format,
|
|
49
|
+
greyscale,
|
|
50
|
+
theme
|
|
51
|
+
}),
|
|
52
|
+
[effectiveToken, format, greyscale, theme]
|
|
53
|
+
);
|
|
54
|
+
react.useEffect(() => {
|
|
55
|
+
if (effectiveToken) fireBeacon(effectiveToken);
|
|
56
|
+
}, [effectiveToken]);
|
|
57
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
58
|
+
Image2__default.default,
|
|
59
|
+
{
|
|
60
|
+
...imageProps,
|
|
61
|
+
src: domain,
|
|
62
|
+
loader,
|
|
63
|
+
alt: alt ?? `${domain} logo`
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
function quikturnImageLoader({ src, width }) {
|
|
68
|
+
return logos.logoUrl(src, { size: width });
|
|
69
|
+
}
|
|
70
|
+
function createQuikturnImageLoader(options) {
|
|
71
|
+
return ({ src, width }) => logos.logoUrl(src, {
|
|
72
|
+
token: options.token,
|
|
73
|
+
size: width,
|
|
74
|
+
format: options.format,
|
|
75
|
+
greyscale: options.greyscale,
|
|
76
|
+
theme: options.theme,
|
|
77
|
+
baseUrl: options.baseUrl
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
Object.defineProperty(exports, "QuikturnLogo", {
|
|
82
|
+
enumerable: true,
|
|
83
|
+
get: function () { return logosReact.QuikturnLogo; }
|
|
84
|
+
});
|
|
85
|
+
Object.defineProperty(exports, "QuikturnLogoCarousel", {
|
|
86
|
+
enumerable: true,
|
|
87
|
+
get: function () { return logosReact.QuikturnLogoCarousel; }
|
|
88
|
+
});
|
|
89
|
+
Object.defineProperty(exports, "QuikturnLogoGrid", {
|
|
90
|
+
enumerable: true,
|
|
91
|
+
get: function () { return logosReact.QuikturnLogoGrid; }
|
|
92
|
+
});
|
|
93
|
+
Object.defineProperty(exports, "useLogoUrl", {
|
|
94
|
+
enumerable: true,
|
|
95
|
+
get: function () { return logosReact.useLogoUrl; }
|
|
96
|
+
});
|
|
97
|
+
exports.QuikturnImage = QuikturnImage;
|
|
98
|
+
exports.QuikturnProvider = QuikturnProvider;
|
|
99
|
+
exports.createQuikturnImageLoader = createQuikturnImageLoader;
|
|
100
|
+
exports.quikturnImageLoader = quikturnImageLoader;
|
|
101
|
+
exports.useQuikturnContext = useQuikturnContext;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ImageProps } from 'next/image';
|
|
3
|
+
import { LogoRequestOptions } from '@quikturn/logos';
|
|
4
|
+
export { LogoConfig, LogoOptions, QuikturnLogo, QuikturnLogoCarousel, QuikturnLogoCarouselProps, QuikturnLogoGrid, QuikturnLogoGridProps, QuikturnLogoProps, ResolvedLogo, useLogoUrl } from '@quikturn/logos-react';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Props accepted by the `QuikturnImage` component.
|
|
8
|
+
*
|
|
9
|
+
* Extends all `next/image` props except `src` and `loader` (which are
|
|
10
|
+
* derived from the `domain` and logo-specific options).
|
|
11
|
+
*/
|
|
12
|
+
interface QuikturnImageProps extends Omit<ImageProps, "src" | "loader"> {
|
|
13
|
+
/** The domain to fetch a logo for (e.g. "github.com"). */
|
|
14
|
+
domain: string;
|
|
15
|
+
/** Publishable API token (qt_ / pk_ prefix). Overrides context token. */
|
|
16
|
+
token?: string;
|
|
17
|
+
/** Output image format. */
|
|
18
|
+
format?: LogoRequestOptions["format"];
|
|
19
|
+
/** When true, returns a greyscale logo. */
|
|
20
|
+
greyscale?: boolean;
|
|
21
|
+
/** Theme adjustment ("light" or "dark"). */
|
|
22
|
+
theme?: LogoRequestOptions["theme"];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Next.js `<Image>` wrapper that renders a Quikturn logo for the given domain.
|
|
26
|
+
*
|
|
27
|
+
* Automatically constructs a custom `loader` using `logoUrl()` from
|
|
28
|
+
* `@quikturn/logos`, fires an attribution beacon on mount, and supports
|
|
29
|
+
* reading a token from `<QuikturnProvider>` context.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```tsx
|
|
33
|
+
* <QuikturnImage domain="github.com" token="qt_abc" width={128} height={128} alt="GitHub" />
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
declare function QuikturnImage({ domain, token, format, greyscale, theme, alt, ...imageProps }: QuikturnImageProps): react_jsx_runtime.JSX.Element;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Props matching the Next.js `ImageLoaderProps` interface from `next/image`.
|
|
40
|
+
*
|
|
41
|
+
* - `src` - The domain string (or image source) passed by Next.js.
|
|
42
|
+
* - `width` - The resolved width in pixels requested by Next.js.
|
|
43
|
+
* - `quality` - Optional quality hint (unused by the Logos API, included for compatibility).
|
|
44
|
+
*/
|
|
45
|
+
interface ImageLoaderProps {
|
|
46
|
+
src: string;
|
|
47
|
+
width: number;
|
|
48
|
+
quality?: number;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Options for configuring a Quikturn image loader factory.
|
|
52
|
+
*
|
|
53
|
+
* These options are "baked in" to the returned loader function so they
|
|
54
|
+
* don't need to be supplied on every call.
|
|
55
|
+
*/
|
|
56
|
+
interface QuikturnImageLoaderOptions {
|
|
57
|
+
token?: string;
|
|
58
|
+
format?: LogoRequestOptions["format"];
|
|
59
|
+
greyscale?: boolean;
|
|
60
|
+
theme?: LogoRequestOptions["theme"];
|
|
61
|
+
baseUrl?: string;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Basic Quikturn image loader compatible with Next.js `next/image`.
|
|
65
|
+
*
|
|
66
|
+
* Converts a domain + width into a Logos API URL. Does not inject a token
|
|
67
|
+
* or any additional options -- use {@link createQuikturnImageLoader} for that.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```tsx
|
|
71
|
+
* import Image from "next/image";
|
|
72
|
+
* import { quikturnImageLoader } from "@quikturn/logos-next";
|
|
73
|
+
*
|
|
74
|
+
* <Image loader={quikturnImageLoader} src="github.com" width={256} height={256} alt="GitHub" />
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
declare function quikturnImageLoader({ src, width }: ImageLoaderProps): string;
|
|
78
|
+
/**
|
|
79
|
+
* Factory that creates a Quikturn image loader with pre-configured options.
|
|
80
|
+
*
|
|
81
|
+
* The returned function is compatible with Next.js `next/image`'s `loader` prop.
|
|
82
|
+
* Options such as `token`, `format`, `greyscale`, `theme`, and `baseUrl` are
|
|
83
|
+
* captured in the closure so they apply to every call automatically.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```tsx
|
|
87
|
+
* import Image from "next/image";
|
|
88
|
+
* import { createQuikturnImageLoader } from "@quikturn/logos-next";
|
|
89
|
+
*
|
|
90
|
+
* const loader = createQuikturnImageLoader({ token: "qt_abc123", format: "webp" });
|
|
91
|
+
*
|
|
92
|
+
* <Image loader={loader} src="github.com" width={256} height={256} alt="GitHub" />
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
declare function createQuikturnImageLoader(options: QuikturnImageLoaderOptions): (props: ImageLoaderProps) => string;
|
|
96
|
+
|
|
97
|
+
interface QuikturnContextValue {
|
|
98
|
+
token: string;
|
|
99
|
+
baseUrl?: string;
|
|
100
|
+
}
|
|
101
|
+
/** Read the current Quikturn context (token + optional baseUrl). */
|
|
102
|
+
declare function useQuikturnContext(): QuikturnContextValue | null;
|
|
103
|
+
/** Props for the QuikturnProvider component. */
|
|
104
|
+
interface QuikturnProviderProps {
|
|
105
|
+
token: string;
|
|
106
|
+
baseUrl?: string;
|
|
107
|
+
children: React.ReactNode;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Provides a Quikturn token (and optional baseUrl) to all descendant
|
|
111
|
+
* `QuikturnImage` components so they don't need an explicit `token` prop.
|
|
112
|
+
*/
|
|
113
|
+
declare function QuikturnProvider({ token, baseUrl, children, }: QuikturnProviderProps): react_jsx_runtime.JSX.Element;
|
|
114
|
+
|
|
115
|
+
export { type ImageLoaderProps, QuikturnImage, type QuikturnImageLoaderOptions, type QuikturnImageProps, QuikturnProvider, createQuikturnImageLoader, quikturnImageLoader, useQuikturnContext };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ImageProps } from 'next/image';
|
|
3
|
+
import { LogoRequestOptions } from '@quikturn/logos';
|
|
4
|
+
export { LogoConfig, LogoOptions, QuikturnLogo, QuikturnLogoCarousel, QuikturnLogoCarouselProps, QuikturnLogoGrid, QuikturnLogoGridProps, QuikturnLogoProps, ResolvedLogo, useLogoUrl } from '@quikturn/logos-react';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Props accepted by the `QuikturnImage` component.
|
|
8
|
+
*
|
|
9
|
+
* Extends all `next/image` props except `src` and `loader` (which are
|
|
10
|
+
* derived from the `domain` and logo-specific options).
|
|
11
|
+
*/
|
|
12
|
+
interface QuikturnImageProps extends Omit<ImageProps, "src" | "loader"> {
|
|
13
|
+
/** The domain to fetch a logo for (e.g. "github.com"). */
|
|
14
|
+
domain: string;
|
|
15
|
+
/** Publishable API token (qt_ / pk_ prefix). Overrides context token. */
|
|
16
|
+
token?: string;
|
|
17
|
+
/** Output image format. */
|
|
18
|
+
format?: LogoRequestOptions["format"];
|
|
19
|
+
/** When true, returns a greyscale logo. */
|
|
20
|
+
greyscale?: boolean;
|
|
21
|
+
/** Theme adjustment ("light" or "dark"). */
|
|
22
|
+
theme?: LogoRequestOptions["theme"];
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Next.js `<Image>` wrapper that renders a Quikturn logo for the given domain.
|
|
26
|
+
*
|
|
27
|
+
* Automatically constructs a custom `loader` using `logoUrl()` from
|
|
28
|
+
* `@quikturn/logos`, fires an attribution beacon on mount, and supports
|
|
29
|
+
* reading a token from `<QuikturnProvider>` context.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```tsx
|
|
33
|
+
* <QuikturnImage domain="github.com" token="qt_abc" width={128} height={128} alt="GitHub" />
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
declare function QuikturnImage({ domain, token, format, greyscale, theme, alt, ...imageProps }: QuikturnImageProps): react_jsx_runtime.JSX.Element;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Props matching the Next.js `ImageLoaderProps` interface from `next/image`.
|
|
40
|
+
*
|
|
41
|
+
* - `src` - The domain string (or image source) passed by Next.js.
|
|
42
|
+
* - `width` - The resolved width in pixels requested by Next.js.
|
|
43
|
+
* - `quality` - Optional quality hint (unused by the Logos API, included for compatibility).
|
|
44
|
+
*/
|
|
45
|
+
interface ImageLoaderProps {
|
|
46
|
+
src: string;
|
|
47
|
+
width: number;
|
|
48
|
+
quality?: number;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Options for configuring a Quikturn image loader factory.
|
|
52
|
+
*
|
|
53
|
+
* These options are "baked in" to the returned loader function so they
|
|
54
|
+
* don't need to be supplied on every call.
|
|
55
|
+
*/
|
|
56
|
+
interface QuikturnImageLoaderOptions {
|
|
57
|
+
token?: string;
|
|
58
|
+
format?: LogoRequestOptions["format"];
|
|
59
|
+
greyscale?: boolean;
|
|
60
|
+
theme?: LogoRequestOptions["theme"];
|
|
61
|
+
baseUrl?: string;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Basic Quikturn image loader compatible with Next.js `next/image`.
|
|
65
|
+
*
|
|
66
|
+
* Converts a domain + width into a Logos API URL. Does not inject a token
|
|
67
|
+
* or any additional options -- use {@link createQuikturnImageLoader} for that.
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```tsx
|
|
71
|
+
* import Image from "next/image";
|
|
72
|
+
* import { quikturnImageLoader } from "@quikturn/logos-next";
|
|
73
|
+
*
|
|
74
|
+
* <Image loader={quikturnImageLoader} src="github.com" width={256} height={256} alt="GitHub" />
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
declare function quikturnImageLoader({ src, width }: ImageLoaderProps): string;
|
|
78
|
+
/**
|
|
79
|
+
* Factory that creates a Quikturn image loader with pre-configured options.
|
|
80
|
+
*
|
|
81
|
+
* The returned function is compatible with Next.js `next/image`'s `loader` prop.
|
|
82
|
+
* Options such as `token`, `format`, `greyscale`, `theme`, and `baseUrl` are
|
|
83
|
+
* captured in the closure so they apply to every call automatically.
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```tsx
|
|
87
|
+
* import Image from "next/image";
|
|
88
|
+
* import { createQuikturnImageLoader } from "@quikturn/logos-next";
|
|
89
|
+
*
|
|
90
|
+
* const loader = createQuikturnImageLoader({ token: "qt_abc123", format: "webp" });
|
|
91
|
+
*
|
|
92
|
+
* <Image loader={loader} src="github.com" width={256} height={256} alt="GitHub" />
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
declare function createQuikturnImageLoader(options: QuikturnImageLoaderOptions): (props: ImageLoaderProps) => string;
|
|
96
|
+
|
|
97
|
+
interface QuikturnContextValue {
|
|
98
|
+
token: string;
|
|
99
|
+
baseUrl?: string;
|
|
100
|
+
}
|
|
101
|
+
/** Read the current Quikturn context (token + optional baseUrl). */
|
|
102
|
+
declare function useQuikturnContext(): QuikturnContextValue | null;
|
|
103
|
+
/** Props for the QuikturnProvider component. */
|
|
104
|
+
interface QuikturnProviderProps {
|
|
105
|
+
token: string;
|
|
106
|
+
baseUrl?: string;
|
|
107
|
+
children: React.ReactNode;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Provides a Quikturn token (and optional baseUrl) to all descendant
|
|
111
|
+
* `QuikturnImage` components so they don't need an explicit `token` prop.
|
|
112
|
+
*/
|
|
113
|
+
declare function QuikturnProvider({ token, baseUrl, children, }: QuikturnProviderProps): react_jsx_runtime.JSX.Element;
|
|
114
|
+
|
|
115
|
+
export { type ImageLoaderProps, QuikturnImage, type QuikturnImageLoaderOptions, type QuikturnImageProps, QuikturnProvider, createQuikturnImageLoader, quikturnImageLoader, useQuikturnContext };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import Image2 from 'next/image';
|
|
2
|
+
import { logoUrl, BASE_URL } from '@quikturn/logos';
|
|
3
|
+
import { createContext, useContext, useMemo, useEffect } from 'react';
|
|
4
|
+
import { jsx } from 'react/jsx-runtime';
|
|
5
|
+
export { QuikturnLogo, QuikturnLogoCarousel, QuikturnLogoGrid, useLogoUrl } from '@quikturn/logos-react';
|
|
6
|
+
|
|
7
|
+
var fired = /* @__PURE__ */ new Set();
|
|
8
|
+
function fireBeacon(token) {
|
|
9
|
+
if (typeof window === "undefined") return;
|
|
10
|
+
if (!token || token.startsWith("sk_")) return;
|
|
11
|
+
if (fired.has(token)) return;
|
|
12
|
+
fired.add(token);
|
|
13
|
+
const img = new Image();
|
|
14
|
+
img.src = `${BASE_URL}/_beacon?token=${token}&page=${encodeURIComponent(location.href)}`;
|
|
15
|
+
}
|
|
16
|
+
var QuikturnContext = createContext(null);
|
|
17
|
+
function useQuikturnContext() {
|
|
18
|
+
return useContext(QuikturnContext);
|
|
19
|
+
}
|
|
20
|
+
function QuikturnProvider({
|
|
21
|
+
token,
|
|
22
|
+
baseUrl,
|
|
23
|
+
children
|
|
24
|
+
}) {
|
|
25
|
+
return /* @__PURE__ */ jsx(QuikturnContext.Provider, { value: { token, baseUrl }, children });
|
|
26
|
+
}
|
|
27
|
+
function QuikturnImage({
|
|
28
|
+
domain,
|
|
29
|
+
token,
|
|
30
|
+
format,
|
|
31
|
+
greyscale,
|
|
32
|
+
theme,
|
|
33
|
+
alt,
|
|
34
|
+
...imageProps
|
|
35
|
+
}) {
|
|
36
|
+
const ctx = useQuikturnContext();
|
|
37
|
+
const effectiveToken = token ?? ctx?.token ?? "";
|
|
38
|
+
const loader = useMemo(
|
|
39
|
+
() => ({ src, width }) => logoUrl(src, {
|
|
40
|
+
token: effectiveToken || void 0,
|
|
41
|
+
size: width,
|
|
42
|
+
format,
|
|
43
|
+
greyscale,
|
|
44
|
+
theme
|
|
45
|
+
}),
|
|
46
|
+
[effectiveToken, format, greyscale, theme]
|
|
47
|
+
);
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
if (effectiveToken) fireBeacon(effectiveToken);
|
|
50
|
+
}, [effectiveToken]);
|
|
51
|
+
return /* @__PURE__ */ jsx(
|
|
52
|
+
Image2,
|
|
53
|
+
{
|
|
54
|
+
...imageProps,
|
|
55
|
+
src: domain,
|
|
56
|
+
loader,
|
|
57
|
+
alt: alt ?? `${domain} logo`
|
|
58
|
+
}
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
function quikturnImageLoader({ src, width }) {
|
|
62
|
+
return logoUrl(src, { size: width });
|
|
63
|
+
}
|
|
64
|
+
function createQuikturnImageLoader(options) {
|
|
65
|
+
return ({ src, width }) => logoUrl(src, {
|
|
66
|
+
token: options.token,
|
|
67
|
+
size: width,
|
|
68
|
+
format: options.format,
|
|
69
|
+
greyscale: options.greyscale,
|
|
70
|
+
theme: options.theme,
|
|
71
|
+
baseUrl: options.baseUrl
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export { QuikturnImage, QuikturnProvider, createQuikturnImageLoader, quikturnImageLoader, useQuikturnContext };
|
package/dist/server.cjs
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
require('server-only');
|
|
4
|
+
var server = require('@quikturn/logos/server');
|
|
5
|
+
|
|
6
|
+
// src/server.ts
|
|
7
|
+
var cached = null;
|
|
8
|
+
function getServerClient() {
|
|
9
|
+
if (!cached) {
|
|
10
|
+
const key = process.env.QUIKTURN_SECRET_KEY;
|
|
11
|
+
if (!key) {
|
|
12
|
+
throw new Error(
|
|
13
|
+
"QUIKTURN_SECRET_KEY environment variable is not set. Set it in your .env.local file or deployment environment."
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
cached = new server.QuikturnLogos({ secretKey: key });
|
|
17
|
+
}
|
|
18
|
+
return cached;
|
|
19
|
+
}
|
|
20
|
+
async function getLogoBuffer(domain, options) {
|
|
21
|
+
return getServerClient().get(domain, options);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
Object.defineProperty(exports, "QuikturnLogos", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () { return server.QuikturnLogos; }
|
|
27
|
+
});
|
|
28
|
+
exports.getLogoBuffer = getLogoBuffer;
|
|
29
|
+
exports.getServerClient = getServerClient;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ServerGetOptions, QuikturnLogos } from '@quikturn/logos/server';
|
|
2
|
+
export { QuikturnLogos } from '@quikturn/logos/server';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Returns a singleton {@link QuikturnLogos} server client.
|
|
6
|
+
*
|
|
7
|
+
* Reads the `QUIKTURN_SECRET_KEY` environment variable on first call and
|
|
8
|
+
* caches the client instance for subsequent calls.
|
|
9
|
+
*
|
|
10
|
+
* @throws {Error} If `QUIKTURN_SECRET_KEY` is not set.
|
|
11
|
+
*/
|
|
12
|
+
declare function getServerClient(): QuikturnLogos;
|
|
13
|
+
/**
|
|
14
|
+
* Convenience wrapper that fetches a logo buffer for a domain using the
|
|
15
|
+
* cached server client.
|
|
16
|
+
*
|
|
17
|
+
* @param domain - The domain to fetch a logo for (e.g. "github.com").
|
|
18
|
+
* @param options - Optional request options forwarded to `client.get()`.
|
|
19
|
+
* @returns The server logo response containing a Buffer, content type, and metadata.
|
|
20
|
+
*/
|
|
21
|
+
declare function getLogoBuffer(domain: string, options?: ServerGetOptions): Promise<ReturnType<QuikturnLogos["get"]>>;
|
|
22
|
+
|
|
23
|
+
export { getLogoBuffer, getServerClient };
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ServerGetOptions, QuikturnLogos } from '@quikturn/logos/server';
|
|
2
|
+
export { QuikturnLogos } from '@quikturn/logos/server';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Returns a singleton {@link QuikturnLogos} server client.
|
|
6
|
+
*
|
|
7
|
+
* Reads the `QUIKTURN_SECRET_KEY` environment variable on first call and
|
|
8
|
+
* caches the client instance for subsequent calls.
|
|
9
|
+
*
|
|
10
|
+
* @throws {Error} If `QUIKTURN_SECRET_KEY` is not set.
|
|
11
|
+
*/
|
|
12
|
+
declare function getServerClient(): QuikturnLogos;
|
|
13
|
+
/**
|
|
14
|
+
* Convenience wrapper that fetches a logo buffer for a domain using the
|
|
15
|
+
* cached server client.
|
|
16
|
+
*
|
|
17
|
+
* @param domain - The domain to fetch a logo for (e.g. "github.com").
|
|
18
|
+
* @param options - Optional request options forwarded to `client.get()`.
|
|
19
|
+
* @returns The server logo response containing a Buffer, content type, and metadata.
|
|
20
|
+
*/
|
|
21
|
+
declare function getLogoBuffer(domain: string, options?: ServerGetOptions): Promise<ReturnType<QuikturnLogos["get"]>>;
|
|
22
|
+
|
|
23
|
+
export { getLogoBuffer, getServerClient };
|
package/dist/server.mjs
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import 'server-only';
|
|
2
|
+
import { QuikturnLogos } from '@quikturn/logos/server';
|
|
3
|
+
export { QuikturnLogos } from '@quikturn/logos/server';
|
|
4
|
+
|
|
5
|
+
// src/server.ts
|
|
6
|
+
var cached = null;
|
|
7
|
+
function getServerClient() {
|
|
8
|
+
if (!cached) {
|
|
9
|
+
const key = process.env.QUIKTURN_SECRET_KEY;
|
|
10
|
+
if (!key) {
|
|
11
|
+
throw new Error(
|
|
12
|
+
"QUIKTURN_SECRET_KEY environment variable is not set. Set it in your .env.local file or deployment environment."
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
cached = new QuikturnLogos({ secretKey: key });
|
|
16
|
+
}
|
|
17
|
+
return cached;
|
|
18
|
+
}
|
|
19
|
+
async function getLogoBuffer(domain, options) {
|
|
20
|
+
return getServerClient().get(domain, options);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export { getLogoBuffer, getServerClient };
|
package/package.json
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@quikturn/logos-next",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Next.js components for the Quikturn Logos API — QuikturnImage with next/image integration, server helpers",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Quikturn",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"sideEffects": false,
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": {
|
|
12
|
+
"import": "./dist/index.d.ts",
|
|
13
|
+
"require": "./dist/index.d.cts"
|
|
14
|
+
},
|
|
15
|
+
"import": "./dist/index.mjs",
|
|
16
|
+
"require": "./dist/index.cjs"
|
|
17
|
+
},
|
|
18
|
+
"./server": {
|
|
19
|
+
"types": {
|
|
20
|
+
"import": "./dist/server.d.ts",
|
|
21
|
+
"require": "./dist/server.d.cts"
|
|
22
|
+
},
|
|
23
|
+
"import": "./dist/server.mjs",
|
|
24
|
+
"require": "./dist/server.cjs"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"main": "./dist/index.cjs",
|
|
28
|
+
"module": "./dist/index.mjs",
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
32
|
+
},
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "https://github.com/Quikturn-PowerPoint-Add-In/Logo-SDK.git",
|
|
36
|
+
"directory": "packages/next"
|
|
37
|
+
},
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/Quikturn-PowerPoint-Add-In/Logo-SDK/issues"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/Quikturn-PowerPoint-Add-In/Logo-SDK/tree/main/packages/next#readme",
|
|
42
|
+
"keywords": [
|
|
43
|
+
"quikturn",
|
|
44
|
+
"logos",
|
|
45
|
+
"next",
|
|
46
|
+
"company-logos",
|
|
47
|
+
"brand-assets"
|
|
48
|
+
],
|
|
49
|
+
"engines": {
|
|
50
|
+
"node": ">=20"
|
|
51
|
+
},
|
|
52
|
+
"files": [
|
|
53
|
+
"dist",
|
|
54
|
+
"LICENSE",
|
|
55
|
+
"README.md"
|
|
56
|
+
],
|
|
57
|
+
"scripts": {
|
|
58
|
+
"build": "tsup",
|
|
59
|
+
"test": "vitest run",
|
|
60
|
+
"test:watch": "vitest",
|
|
61
|
+
"typecheck": "tsc --noEmit",
|
|
62
|
+
"lint": "eslint src/ tests/"
|
|
63
|
+
},
|
|
64
|
+
"dependencies": {
|
|
65
|
+
"@quikturn/logos": "workspace:^",
|
|
66
|
+
"@quikturn/logos-react": "workspace:^",
|
|
67
|
+
"server-only": "^0.0.1"
|
|
68
|
+
},
|
|
69
|
+
"peerDependencies": {
|
|
70
|
+
"next": "^14 || ^15",
|
|
71
|
+
"react": ">=18",
|
|
72
|
+
"react-dom": ">=18"
|
|
73
|
+
},
|
|
74
|
+
"devDependencies": {
|
|
75
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
76
|
+
"@semantic-release/git": "^10.0.1",
|
|
77
|
+
"@testing-library/jest-dom": "^6.6.3",
|
|
78
|
+
"@testing-library/react": "^16.3.0",
|
|
79
|
+
"@types/react": "^19.0.0",
|
|
80
|
+
"@types/react-dom": "^19.0.0",
|
|
81
|
+
"jsdom": "^28.0.0",
|
|
82
|
+
"next": "^15.0.0",
|
|
83
|
+
"react": "^19.0.0",
|
|
84
|
+
"react-dom": "^19.0.0",
|
|
85
|
+
"semantic-release": "^25.0.3",
|
|
86
|
+
"tsup": "^8.5.1",
|
|
87
|
+
"typescript": "^5.9.3",
|
|
88
|
+
"vitest": "^4.0.18"
|
|
89
|
+
}
|
|
90
|
+
}
|