@quikturn/logos 0.4.0 → 0.4.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 +192 -309
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,61 +1,57 @@
|
|
|
1
1
|
# @quikturn/logos
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
TypeScript SDK for the [Quikturn Logos API](https://getquikturn.io) -- fetch any company's logo by domain name.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**[Get your API key](https://getquikturn.io)** -- free tier available, no credit card required.
|
|
6
6
|
|
|
7
|
-
| Package | Description |
|
|
8
|
-
|
|
7
|
+
| Package | Description | |
|
|
8
|
+
|---------|-------------|-|
|
|
9
9
|
| [`@quikturn/logos`](https://www.npmjs.com/package/@quikturn/logos) | Core SDK -- URL builder, browser client, server client, web component | `pnpm add @quikturn/logos` |
|
|
10
|
-
| [`@quikturn/logos-react`](https://www.npmjs.com/package/@quikturn/logos-react) | React components --
|
|
10
|
+
| [`@quikturn/logos-react`](https://www.npmjs.com/package/@quikturn/logos-react) | React components -- logo, carousel, grid | `pnpm add @quikturn/logos-react` |
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
- **Zero-dependency URL builder** -- universal, works in any JavaScript runtime
|
|
15
|
-
- **Browser client** -- blob URL management, retry/backoff, scrape polling, event emission
|
|
16
|
-
- **Server client** -- Buffer output, ReadableStream streaming, concurrent batch operations
|
|
17
|
-
- **`<quikturn-logo>` web component** -- zero-effort attribution element with shadow DOM
|
|
18
|
-
- **React components** -- see [`@quikturn/logos-react`](./packages/react/) for `<QuikturnLogo>`, `<QuikturnLogoCarousel>`, and `<QuikturnLogoGrid>`
|
|
19
|
-
- **Full TypeScript support** -- strict types, discriminated union error codes, generic response shapes
|
|
20
|
-
- **Tree-shakeable** -- ESM and CJS dual builds; import only what you need
|
|
12
|
+
---
|
|
21
13
|
|
|
22
|
-
##
|
|
14
|
+
## Install
|
|
23
15
|
|
|
24
16
|
```bash
|
|
25
|
-
# pnpm (recommended)
|
|
26
17
|
pnpm add @quikturn/logos
|
|
18
|
+
```
|
|
27
19
|
|
|
28
|
-
|
|
29
|
-
|
|
20
|
+
> Requires Node.js >= 18. Works with pnpm, npm, or yarn.
|
|
21
|
+
>
|
|
22
|
+
> Need an API key? **[Sign up at getquikturn.io](https://getquikturn.io)** -- takes 30 seconds.
|
|
30
23
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
24
|
+
## Pick Your Entry Point
|
|
25
|
+
|
|
26
|
+
| Entry Point | Import | Use Case |
|
|
27
|
+
|-------------|--------|----------|
|
|
28
|
+
| **Universal** | `@quikturn/logos` | URL builder, types, constants -- zero dependencies, any runtime |
|
|
29
|
+
| **Browser** | `@quikturn/logos/client` | Blob URLs, retry/backoff, scrape polling, events |
|
|
30
|
+
| **Server** | `@quikturn/logos/server` | Buffer output, streaming, batch operations |
|
|
31
|
+
| **Element** | `@quikturn/logos/element` | `<quikturn-logo>` web component with built-in attribution |
|
|
32
|
+
| **React** | `@quikturn/logos-react` | `<QuikturnLogo>`, `<QuikturnLogoCarousel>`, `<QuikturnLogoGrid>` |
|
|
34
33
|
|
|
35
|
-
|
|
34
|
+
---
|
|
36
35
|
|
|
37
36
|
## Quick Start
|
|
38
37
|
|
|
39
|
-
### URL Builder
|
|
38
|
+
### URL Builder
|
|
40
39
|
|
|
41
|
-
The URL
|
|
40
|
+
The simplest way to get a logo URL. Runs everywhere -- browsers, Node.js, edge runtimes -- with no network calls.
|
|
42
41
|
|
|
43
42
|
```ts
|
|
44
43
|
import { logoUrl } from "@quikturn/logos";
|
|
45
44
|
|
|
46
|
-
// Simple usage
|
|
47
45
|
const url = logoUrl("github.com");
|
|
48
46
|
// => "https://logos.getquikturn.io/github.com"
|
|
49
47
|
|
|
50
|
-
|
|
51
|
-
const customUrl = logoUrl("stripe.com", {
|
|
48
|
+
const url = logoUrl("stripe.com", {
|
|
52
49
|
token: "qt_abc123",
|
|
53
50
|
size: 256,
|
|
54
51
|
format: "webp",
|
|
55
52
|
greyscale: true,
|
|
56
53
|
theme: "dark",
|
|
57
54
|
});
|
|
58
|
-
// => "https://logos.getquikturn.io/stripe.com?token=qt_abc123&size=256&greyscale=1&theme=dark&format=webp"
|
|
59
55
|
```
|
|
60
56
|
|
|
61
57
|
### Browser Client
|
|
@@ -65,19 +61,13 @@ import { QuikturnLogos } from "@quikturn/logos/client";
|
|
|
65
61
|
|
|
66
62
|
const client = new QuikturnLogos({ token: "qt_your_publishable_key" });
|
|
67
63
|
|
|
68
|
-
|
|
69
|
-
const { url, blob, contentType, metadata } = await client.get("github.com", {
|
|
64
|
+
const { url, blob, contentType } = await client.get("github.com", {
|
|
70
65
|
size: 256,
|
|
71
66
|
format: "webp",
|
|
72
67
|
});
|
|
73
68
|
|
|
74
69
|
document.querySelector("img")!.src = url;
|
|
75
70
|
|
|
76
|
-
// Listen for rate limit warnings
|
|
77
|
-
client.on("rateLimitWarning", (remaining, limit) => {
|
|
78
|
-
console.warn(`Rate limit: ${remaining}/${limit} requests remaining`);
|
|
79
|
-
});
|
|
80
|
-
|
|
81
71
|
// Clean up blob URLs when done
|
|
82
72
|
client.destroy();
|
|
83
73
|
```
|
|
@@ -89,22 +79,15 @@ import { QuikturnLogos } from "@quikturn/logos/server";
|
|
|
89
79
|
|
|
90
80
|
const client = new QuikturnLogos({ secretKey: "sk_your_secret_key" });
|
|
91
81
|
|
|
92
|
-
//
|
|
93
|
-
const { buffer, contentType
|
|
94
|
-
size: 512,
|
|
95
|
-
format: "png",
|
|
96
|
-
});
|
|
82
|
+
// Single logo
|
|
83
|
+
const { buffer, contentType } = await client.get("github.com");
|
|
97
84
|
|
|
98
|
-
// Batch fetch
|
|
85
|
+
// Batch fetch
|
|
99
86
|
for await (const result of client.getMany(["github.com", "stripe.com", "vercel.com"])) {
|
|
100
|
-
if (result.success) {
|
|
101
|
-
console.log(`${result.domain}: ${result.buffer!.byteLength} bytes`);
|
|
102
|
-
} else {
|
|
103
|
-
console.error(`${result.domain}: ${result.error!.message}`);
|
|
104
|
-
}
|
|
87
|
+
if (result.success) console.log(`${result.domain}: ${result.buffer!.byteLength} bytes`);
|
|
105
88
|
}
|
|
106
89
|
|
|
107
|
-
// Stream
|
|
90
|
+
// Stream to file
|
|
108
91
|
import { createWriteStream } from "node:fs";
|
|
109
92
|
import { Readable } from "node:stream";
|
|
110
93
|
|
|
@@ -114,36 +97,19 @@ Readable.fromWeb(stream).pipe(createWriteStream("logo.png"));
|
|
|
114
97
|
|
|
115
98
|
### Web Component
|
|
116
99
|
|
|
117
|
-
|
|
100
|
+
No framework needed. Import the element entry and use it in plain HTML:
|
|
118
101
|
|
|
119
102
|
```html
|
|
120
103
|
<script type="module">
|
|
121
104
|
import "@quikturn/logos/element";
|
|
122
105
|
</script>
|
|
123
106
|
|
|
124
|
-
<quikturn-logo
|
|
125
|
-
domain="github.com"
|
|
126
|
-
token="qt_abc123"
|
|
127
|
-
size="64"
|
|
128
|
-
format="webp"
|
|
129
|
-
theme="dark"
|
|
130
|
-
></quikturn-logo>
|
|
107
|
+
<quikturn-logo domain="github.com" token="qt_abc123" size="64"></quikturn-logo>
|
|
131
108
|
```
|
|
132
109
|
|
|
133
|
-
|
|
134
|
-
|-----------|------|-------------|
|
|
135
|
-
| `domain` | `string` | Domain to fetch logo for (required for rendering) |
|
|
136
|
-
| `token` | `string` | Publishable API key |
|
|
137
|
-
| `size` | `string` | Image width in pixels |
|
|
138
|
-
| `format` | `string` | `"png"`, `"jpeg"`, `"webp"`, or `"avif"` |
|
|
139
|
-
| `greyscale` | presence | When present, applies greyscale transformation |
|
|
140
|
-
| `theme` | `string` | `"light"` or `"dark"` |
|
|
141
|
-
|
|
142
|
-
The element automatically registers as `quikturn-logo` on import and fires an attribution beacon on first render. Attribution styling uses `!important` rules inside the shadow DOM to prevent accidental removal.
|
|
110
|
+
Renders the logo with a "Powered by Quikturn" attribution badge protected by shadow DOM.
|
|
143
111
|
|
|
144
|
-
### React
|
|
145
|
-
|
|
146
|
-
For React applications, install the companion package:
|
|
112
|
+
### React
|
|
147
113
|
|
|
148
114
|
```bash
|
|
149
115
|
pnpm add @quikturn/logos-react
|
|
@@ -152,296 +118,228 @@ pnpm add @quikturn/logos-react
|
|
|
152
118
|
```tsx
|
|
153
119
|
import { QuikturnProvider, QuikturnLogo, QuikturnLogoCarousel } from "@quikturn/logos-react";
|
|
154
120
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
121
|
+
function App() {
|
|
122
|
+
return (
|
|
123
|
+
<QuikturnProvider token="qt_your_key">
|
|
124
|
+
<QuikturnLogo domain="github.com" size={64} />
|
|
125
|
+
|
|
126
|
+
<QuikturnLogoCarousel
|
|
127
|
+
domains={["github.com", "stripe.com", "vercel.com", "figma.com"]}
|
|
128
|
+
speed={120}
|
|
129
|
+
fadeOut
|
|
130
|
+
pauseOnHover
|
|
131
|
+
/>
|
|
132
|
+
</QuikturnProvider>
|
|
133
|
+
);
|
|
134
|
+
}
|
|
164
135
|
```
|
|
165
136
|
|
|
166
|
-
|
|
137
|
+
Full React API reference: [`@quikturn/logos-react` docs](./packages/react/README.md)
|
|
167
138
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
### Universal (`@quikturn/logos`)
|
|
171
|
-
|
|
172
|
-
The universal entry point exports the URL builder, types, constants, and error classes. No network calls are made from this module.
|
|
173
|
-
|
|
174
|
-
#### `logoUrl(domain, options?)`
|
|
175
|
-
|
|
176
|
-
Constructs a fully-qualified Logos API URL. Pure function with no side effects.
|
|
177
|
-
|
|
178
|
-
| Parameter | Type | Description |
|
|
179
|
-
|-----------|------|-------------|
|
|
180
|
-
| `domain` | `string` | Domain to fetch a logo for (e.g. `"github.com"`) |
|
|
181
|
-
| `options` | `LogoRequestOptions` | Optional request parameters |
|
|
182
|
-
|
|
183
|
-
**Returns:** `string` -- fully-qualified URL
|
|
184
|
-
|
|
185
|
-
**Throws:** `DomainValidationError` if the domain fails RFC 1035/1123 validation
|
|
139
|
+
---
|
|
186
140
|
|
|
187
|
-
|
|
141
|
+
## Authentication
|
|
188
142
|
|
|
189
|
-
|
|
|
190
|
-
|
|
191
|
-
| `
|
|
192
|
-
|
|
|
193
|
-
| `width` | `number` | `128` | Alias for `size` |
|
|
194
|
-
| `greyscale` | `boolean` | `false` | When `true`, applies saturation: 0 transformation |
|
|
195
|
-
| `theme` | `"light" \| "dark"` | -- | Optimize logo for light or dark backgrounds |
|
|
196
|
-
| `format` | `SupportedOutputFormat \| FormatShorthand` | `"image/png"` | Output image format |
|
|
197
|
-
| `baseUrl` | `string` | `"https://logos.getquikturn.io"` | Override the API base URL |
|
|
143
|
+
| Key Type | Prefix | Environment | Auth Method |
|
|
144
|
+
|----------|--------|-------------|-------------|
|
|
145
|
+
| **Publishable** | `qt_` / `pk_` | Browser | Query parameter (`?token=...`) |
|
|
146
|
+
| **Secret** | `sk_` | Server only | `Authorization: Bearer` header |
|
|
198
147
|
|
|
199
|
-
|
|
148
|
+
Publishable keys are safe to expose in client-side code (max 800px). Secret keys must never reach the browser (max 1200px). Manage your keys in the [Quikturn dashboard](https://getquikturn.io/dashboard).
|
|
200
149
|
|
|
201
150
|
```ts
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
SupportedOutputFormat, // "image/png" | "image/jpeg" | "image/webp" | "image/avif"
|
|
206
|
-
FormatShorthand, // "png" | "jpeg" | "webp" | "avif"
|
|
207
|
-
LogoRequestOptions,
|
|
208
|
-
|
|
209
|
-
// Response
|
|
210
|
-
LogoMetadata,
|
|
211
|
-
BrowserLogoResponse,
|
|
212
|
-
ServerLogoResponse,
|
|
213
|
-
|
|
214
|
-
// Scrape polling
|
|
215
|
-
ScrapeProgressEvent,
|
|
151
|
+
// Browser
|
|
152
|
+
import { QuikturnLogos } from "@quikturn/logos/client";
|
|
153
|
+
const client = new QuikturnLogos({ token: "qt_your_publishable_key" });
|
|
216
154
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
155
|
+
// Server
|
|
156
|
+
import { QuikturnLogos } from "@quikturn/logos/server";
|
|
157
|
+
const client = new QuikturnLogos({ secretKey: "sk_your_secret_key" });
|
|
220
158
|
```
|
|
221
159
|
|
|
222
|
-
#### Constants
|
|
223
|
-
|
|
224
|
-
| Constant | Value | Description |
|
|
225
|
-
|----------|-------|-------------|
|
|
226
|
-
| `BASE_URL` | `"https://logos.getquikturn.io"` | Root API endpoint |
|
|
227
|
-
| `DEFAULT_WIDTH` | `128` | Default logo width (px) |
|
|
228
|
-
| `DEFAULT_FORMAT` | `"image/png"` | Default output MIME type |
|
|
229
|
-
| `SUPPORTED_FORMATS` | `Set<SupportedOutputFormat>` | All supported MIME types |
|
|
230
|
-
| `FORMAT_ALIASES` | `Record<FormatShorthand, SupportedOutputFormat>` | Shorthand-to-MIME mapping |
|
|
231
|
-
|
|
232
160
|
---
|
|
233
161
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
#### `new QuikturnLogos(options)`
|
|
237
|
-
|
|
238
|
-
| Option | Type | Default | Description |
|
|
239
|
-
|--------|------|---------|-------------|
|
|
240
|
-
| `token` | `string` | **required** | Publishable key (`qt_`/`pk_` prefix). Server keys (`sk_`) are rejected. |
|
|
241
|
-
| `baseUrl` | `string` | `"https://logos.getquikturn.io"` | Override the API base URL |
|
|
242
|
-
| `maxRetries` | `number` | `2` | Max retry attempts for rate-limited/server-error responses |
|
|
243
|
-
|
|
244
|
-
#### `client.get(domain, options?)`
|
|
245
|
-
|
|
246
|
-
Fetches a logo and returns a `BrowserLogoResponse`.
|
|
162
|
+
## API Reference
|
|
247
163
|
|
|
248
|
-
|
|
249
|
-
|--------|------|---------|-------------|
|
|
250
|
-
| `size` | `number` | `128` | Output width in pixels |
|
|
251
|
-
| `width` | `number` | `128` | Alias for `size` |
|
|
252
|
-
| `greyscale` | `boolean` | `false` | Greyscale transformation |
|
|
253
|
-
| `theme` | `"light" \| "dark"` | -- | Gamma curve adjustment |
|
|
254
|
-
| `format` | `SupportedOutputFormat \| FormatShorthand` | `"image/png"` | Output format |
|
|
255
|
-
| `scrapeTimeout` | `number` | -- | Max time (ms) to wait for scrape completion |
|
|
256
|
-
| `onScrapeProgress` | `(event: ScrapeProgressEvent) => void` | -- | Callback for scrape progress |
|
|
257
|
-
| `signal` | `AbortSignal` | -- | Cancel the request |
|
|
164
|
+
### `logoUrl(domain, options?)`
|
|
258
165
|
|
|
259
|
-
|
|
166
|
+
Pure URL builder. No network calls, no side effects.
|
|
260
167
|
|
|
261
168
|
```ts
|
|
262
|
-
|
|
263
|
-
url: string; // blob: object URL for <img src>
|
|
264
|
-
blob: Blob; // Raw image Blob
|
|
265
|
-
contentType: string; // e.g. "image/webp"
|
|
266
|
-
metadata: LogoMetadata;
|
|
267
|
-
}
|
|
169
|
+
import { logoUrl } from "@quikturn/logos";
|
|
268
170
|
```
|
|
269
171
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
Returns a plain URL string without making a network request. Useful for `<img>` tags, CSS `background-image`, or preloading hints.
|
|
273
|
-
|
|
274
|
-
**Returns:** `string`
|
|
275
|
-
|
|
276
|
-
#### `client.on(event, handler)` / `client.off(event, handler)`
|
|
277
|
-
|
|
278
|
-
Register or remove event listeners.
|
|
279
|
-
|
|
280
|
-
| Event | Handler Signature | Description |
|
|
281
|
-
|-------|-------------------|-------------|
|
|
282
|
-
| `"rateLimitWarning"` | `(remaining: number, limit: number) => void` | Fires when rate limit is approaching |
|
|
283
|
-
| `"quotaWarning"` | `(remaining: number, limit: number) => void` | Fires when monthly quota is approaching |
|
|
172
|
+
**Options:**
|
|
284
173
|
|
|
285
|
-
|
|
174
|
+
| Property | Type | Default | Description |
|
|
175
|
+
|----------|------|---------|-------------|
|
|
176
|
+
| `token` | `string` | -- | API key appended as query parameter |
|
|
177
|
+
| `size` | `number` | `128` | Output width in pixels |
|
|
178
|
+
| `width` | `number` | `128` | Alias for `size` |
|
|
179
|
+
| `greyscale` | `boolean` | `false` | Desaturation filter |
|
|
180
|
+
| `theme` | `"light" \| "dark"` | -- | Background-optimized rendering |
|
|
181
|
+
| `format` | `string` | `"image/png"` | `"png"`, `"jpeg"`, `"webp"`, `"avif"` (or full MIME type) |
|
|
182
|
+
| `baseUrl` | `string` | `"https://logos.getquikturn.io"` | API base URL override |
|
|
286
183
|
|
|
287
|
-
|
|
184
|
+
**Returns:** `string` | **Throws:** `DomainValidationError`
|
|
288
185
|
|
|
289
186
|
---
|
|
290
187
|
|
|
291
|
-
###
|
|
188
|
+
### Browser Client
|
|
189
|
+
|
|
190
|
+
```ts
|
|
191
|
+
import { QuikturnLogos } from "@quikturn/logos/client";
|
|
192
|
+
```
|
|
292
193
|
|
|
293
|
-
####
|
|
194
|
+
#### Constructor
|
|
294
195
|
|
|
295
196
|
| Option | Type | Default | Description |
|
|
296
197
|
|--------|------|---------|-------------|
|
|
297
|
-
| `
|
|
298
|
-
| `baseUrl` | `string` | `"https://logos.getquikturn.io"` |
|
|
299
|
-
| `maxRetries` | `number` | `2` | Max
|
|
198
|
+
| `token` | `string` | **required** | Publishable key (`qt_`/`pk_` prefix) |
|
|
199
|
+
| `baseUrl` | `string` | `"https://logos.getquikturn.io"` | API base URL override |
|
|
200
|
+
| `maxRetries` | `number` | `2` | Max retries for 429/5xx responses |
|
|
300
201
|
|
|
301
|
-
####
|
|
202
|
+
#### Methods
|
|
302
203
|
|
|
303
|
-
Fetches a logo and returns a
|
|
204
|
+
**`client.get(domain, options?)`** -- Fetches a logo and returns a blob URL.
|
|
304
205
|
|
|
305
|
-
|
|
206
|
+
| Option | Type | Default |
|
|
207
|
+
|--------|------|---------|
|
|
208
|
+
| `size` | `number` | `128` |
|
|
209
|
+
| `format` | `string` | `"image/png"` |
|
|
210
|
+
| `greyscale` | `boolean` | `false` |
|
|
211
|
+
| `theme` | `"light" \| "dark"` | -- |
|
|
212
|
+
| `scrapeTimeout` | `number` | -- |
|
|
213
|
+
| `onScrapeProgress` | `(event) => void` | -- |
|
|
214
|
+
| `signal` | `AbortSignal` | -- |
|
|
306
215
|
|
|
307
|
-
|
|
216
|
+
Returns `Promise<{ url: string, blob: Blob, contentType: string, metadata: LogoMetadata }>`.
|
|
308
217
|
|
|
309
|
-
|
|
310
|
-
interface ServerLogoResponse {
|
|
311
|
-
buffer: Buffer; // Raw image bytes
|
|
312
|
-
contentType: string; // e.g. "image/png"
|
|
313
|
-
metadata: LogoMetadata;
|
|
314
|
-
}
|
|
315
|
-
```
|
|
218
|
+
**`client.getUrl(domain, options?)`** -- Returns a plain URL string without a network request.
|
|
316
219
|
|
|
317
|
-
|
|
220
|
+
**`client.on(event, handler)`** / **`client.off(event, handler)`** -- Listen for `"rateLimitWarning"` or `"quotaWarning"` events.
|
|
318
221
|
|
|
319
|
-
|
|
222
|
+
**`client.destroy()`** -- Revokes all tracked blob URLs and removes event listeners. Call this to prevent memory leaks.
|
|
320
223
|
|
|
321
|
-
|
|
322
|
-
|--------|------|---------|-------------|
|
|
323
|
-
| `concurrency` | `number` | `5` | Maximum parallel fetches |
|
|
324
|
-
| `size` | `number` | `128` | Output width in pixels |
|
|
325
|
-
| `greyscale` | `boolean` | `false` | Greyscale transformation |
|
|
326
|
-
| `theme` | `"light" \| "dark"` | -- | Gamma curve adjustment |
|
|
327
|
-
| `format` | `SupportedOutputFormat \| FormatShorthand` | `"image/png"` | Output format |
|
|
328
|
-
| `signal` | `AbortSignal` | -- | Cancel remaining batch items |
|
|
329
|
-
| `continueOnError` | `boolean` | `true` | Capture errors per-domain instead of aborting the batch |
|
|
224
|
+
---
|
|
330
225
|
|
|
331
|
-
|
|
226
|
+
### Server Client
|
|
332
227
|
|
|
333
228
|
```ts
|
|
334
|
-
|
|
335
|
-
domain: string;
|
|
336
|
-
success: boolean;
|
|
337
|
-
buffer?: Buffer;
|
|
338
|
-
contentType?: string;
|
|
339
|
-
metadata?: LogoMetadata;
|
|
340
|
-
error?: LogoError;
|
|
341
|
-
}
|
|
229
|
+
import { QuikturnLogos } from "@quikturn/logos/server";
|
|
342
230
|
```
|
|
343
231
|
|
|
344
|
-
####
|
|
232
|
+
#### Constructor
|
|
345
233
|
|
|
346
|
-
|
|
234
|
+
| Option | Type | Default | Description |
|
|
235
|
+
|--------|------|---------|-------------|
|
|
236
|
+
| `secretKey` | `string` | **required** | Secret key (`sk_` prefix) |
|
|
237
|
+
| `baseUrl` | `string` | `"https://logos.getquikturn.io"` | API base URL override |
|
|
238
|
+
| `maxRetries` | `number` | `2` | Max retries for 429/5xx responses |
|
|
347
239
|
|
|
348
|
-
|
|
240
|
+
#### Methods
|
|
349
241
|
|
|
350
|
-
|
|
242
|
+
**`client.get(domain, options?)`** -- Returns `Promise<{ buffer: Buffer, contentType: string, metadata: LogoMetadata }>`.
|
|
351
243
|
|
|
352
|
-
|
|
244
|
+
**`client.getMany(domains, options?)`** -- Batch fetch with concurrency control. Returns `AsyncGenerator<BatchResult>`.
|
|
353
245
|
|
|
354
|
-
|
|
246
|
+
| Option | Type | Default |
|
|
247
|
+
|--------|------|---------|
|
|
248
|
+
| `concurrency` | `number` | `5` |
|
|
249
|
+
| `continueOnError` | `boolean` | `true` |
|
|
250
|
+
| `signal` | `AbortSignal` | -- |
|
|
355
251
|
|
|
356
|
-
|
|
252
|
+
**`client.getStream(domain, options?)`** -- Returns `Promise<ReadableStream>` for zero-copy streaming.
|
|
357
253
|
|
|
358
|
-
|
|
254
|
+
**`client.getUrl(domain, options?)`** -- Returns a URL string (secret key NOT included -- use `Authorization` header).
|
|
359
255
|
|
|
360
|
-
|
|
256
|
+
**`client.on(event, handler)`** / **`client.off(event, handler)`** -- Same events as the browser client.
|
|
361
257
|
|
|
362
258
|
---
|
|
363
259
|
|
|
364
|
-
###
|
|
365
|
-
|
|
366
|
-
All SDK errors extend `LogoError`, which extends the native `Error` class with a machine-readable `code` and an optional HTTP `status`.
|
|
260
|
+
### Web Component
|
|
367
261
|
|
|
368
262
|
```ts
|
|
369
|
-
import
|
|
370
|
-
LogoError,
|
|
371
|
-
DomainValidationError,
|
|
372
|
-
RateLimitError,
|
|
373
|
-
QuotaExceededError,
|
|
374
|
-
AuthenticationError,
|
|
375
|
-
ForbiddenError,
|
|
376
|
-
NotFoundError,
|
|
377
|
-
ScrapeTimeoutError,
|
|
378
|
-
BadRequestError,
|
|
379
|
-
} from "@quikturn/logos";
|
|
263
|
+
import "@quikturn/logos/element";
|
|
380
264
|
```
|
|
381
265
|
|
|
382
|
-
|
|
|
383
|
-
|
|
384
|
-
| `
|
|
385
|
-
| `
|
|
386
|
-
| `
|
|
387
|
-
| `
|
|
388
|
-
| `
|
|
389
|
-
| `
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
266
|
+
| Attribute | Type | Description |
|
|
267
|
+
|-----------|------|-------------|
|
|
268
|
+
| `domain` | `string` | Domain to fetch logo for (required) |
|
|
269
|
+
| `token` | `string` | Publishable API key |
|
|
270
|
+
| `size` | `string` | Image width in pixels |
|
|
271
|
+
| `format` | `string` | `"png"`, `"jpeg"`, `"webp"`, or `"avif"` |
|
|
272
|
+
| `greyscale` | (presence) | Greyscale filter when attribute is present |
|
|
273
|
+
| `theme` | `string` | `"light"` or `"dark"` |
|
|
274
|
+
|
|
275
|
+
Auto-registers as `<quikturn-logo>` on import. Shadow DOM protects the attribution badge with `!important` CSS rules.
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
### Error Handling
|
|
393
280
|
|
|
394
|
-
All
|
|
281
|
+
All errors extend `LogoError` with a typed `code` property for exhaustive `switch` handling:
|
|
395
282
|
|
|
396
283
|
```ts
|
|
397
284
|
import { LogoError } from "@quikturn/logos";
|
|
398
|
-
import type { LogoErrorCode } from "@quikturn/logos";
|
|
399
285
|
|
|
400
286
|
try {
|
|
401
287
|
const { url } = await client.get("example.com");
|
|
402
288
|
} catch (err) {
|
|
403
289
|
if (err instanceof LogoError) {
|
|
404
290
|
switch (err.code) {
|
|
405
|
-
case "RATE_LIMIT_ERROR":
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
// show placeholder
|
|
410
|
-
break;
|
|
411
|
-
// ... handle other cases
|
|
291
|
+
case "RATE_LIMIT_ERROR": /* backoff */ break;
|
|
292
|
+
case "NOT_FOUND_ERROR": /* fallback */ break;
|
|
293
|
+
case "AUTHENTICATION_ERROR": /* check key */ break;
|
|
294
|
+
// ...
|
|
412
295
|
}
|
|
413
296
|
}
|
|
414
297
|
}
|
|
415
298
|
```
|
|
416
299
|
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
300
|
+
| Error | Code | Status | Extra Properties |
|
|
301
|
+
|-------|------|--------|------------------|
|
|
302
|
+
| `DomainValidationError` | `DOMAIN_VALIDATION_ERROR` | -- | `domain` |
|
|
303
|
+
| `AuthenticationError` | `AUTHENTICATION_ERROR` | 401 | -- |
|
|
304
|
+
| `ForbiddenError` | `FORBIDDEN_ERROR` | 403 | `reason` |
|
|
305
|
+
| `NotFoundError` | `NOT_FOUND_ERROR` | 404 | `domain` |
|
|
306
|
+
| `BadRequestError` | `BAD_REQUEST_ERROR` | 400 | -- |
|
|
307
|
+
| `RateLimitError` | `RATE_LIMIT_ERROR` | 429 | `retryAfter`, `remaining`, `resetAt` |
|
|
308
|
+
| `QuotaExceededError` | `QUOTA_EXCEEDED_ERROR` | 429 | `retryAfter`, `limit`, `used` |
|
|
309
|
+
| `ScrapeTimeoutError` | `SCRAPE_TIMEOUT_ERROR` | -- | `jobId`, `elapsed` |
|
|
420
310
|
|
|
421
|
-
|
|
422
|
-
|----------|--------|-------------|-------------|
|
|
423
|
-
| **Publishable** | `qt_` or `pk_` | Browser | Query parameter (`?token=...`) |
|
|
424
|
-
| **Secret** | `sk_` | Server only | `Authorization: Bearer` header |
|
|
311
|
+
---
|
|
425
312
|
|
|
426
|
-
|
|
427
|
-
- **Secret keys** must never be exposed to the browser. They are sent via the `Authorization` header and support a max image width of 1200px.
|
|
313
|
+
### Types & Constants
|
|
428
314
|
|
|
429
315
|
```ts
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
316
|
+
import type {
|
|
317
|
+
ThemeOption, // "light" | "dark"
|
|
318
|
+
SupportedOutputFormat, // "image/png" | "image/jpeg" | "image/webp" | "image/avif"
|
|
319
|
+
FormatShorthand, // "png" | "jpeg" | "webp" | "avif"
|
|
320
|
+
LogoRequestOptions,
|
|
321
|
+
LogoMetadata,
|
|
322
|
+
BrowserLogoResponse,
|
|
323
|
+
ServerLogoResponse,
|
|
324
|
+
ScrapeProgressEvent,
|
|
325
|
+
LogoErrorCode, // discriminated union of all error codes
|
|
326
|
+
} from "@quikturn/logos";
|
|
437
327
|
```
|
|
438
328
|
|
|
329
|
+
| Constant | Value |
|
|
330
|
+
|----------|-------|
|
|
331
|
+
| `BASE_URL` | `"https://logos.getquikturn.io"` |
|
|
332
|
+
| `DEFAULT_WIDTH` | `128` |
|
|
333
|
+
| `DEFAULT_FORMAT` | `"image/png"` |
|
|
334
|
+
| `SUPPORTED_FORMATS` | `Set` of 4 MIME types |
|
|
335
|
+
| `FORMAT_ALIASES` | `{ png, jpeg, webp, avif }` -> MIME mapping |
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
439
339
|
## Configuration
|
|
440
340
|
|
|
441
341
|
### Custom Base URL
|
|
442
342
|
|
|
443
|
-
Override the API endpoint for testing, proxied environments, or self-hosted deployments:
|
|
444
|
-
|
|
445
343
|
```ts
|
|
446
344
|
const client = new QuikturnLogos({
|
|
447
345
|
token: "qt_your_key",
|
|
@@ -449,48 +347,33 @@ const client = new QuikturnLogos({
|
|
|
449
347
|
});
|
|
450
348
|
```
|
|
451
349
|
|
|
452
|
-
###
|
|
350
|
+
### Formats
|
|
453
351
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
| Format | MIME Type | Shorthand |
|
|
352
|
+
| Format | Shorthand | MIME Type |
|
|
457
353
|
|--------|-----------|-----------|
|
|
458
|
-
| PNG | `
|
|
459
|
-
| JPEG | `
|
|
460
|
-
| WebP | `
|
|
461
|
-
| AVIF | `
|
|
354
|
+
| PNG | `"png"` | `image/png` |
|
|
355
|
+
| JPEG | `"jpeg"` | `image/jpeg` |
|
|
356
|
+
| WebP | `"webp"` | `image/webp` |
|
|
357
|
+
| AVIF | `"avif"` | `image/avif` |
|
|
462
358
|
|
|
463
|
-
Both
|
|
359
|
+
Both forms are accepted: `format: "webp"` and `format: "image/webp"` are equivalent.
|
|
464
360
|
|
|
465
|
-
|
|
466
|
-
// These are equivalent
|
|
467
|
-
client.get("github.com", { format: "image/webp" });
|
|
468
|
-
client.get("github.com", { format: "webp" });
|
|
469
|
-
```
|
|
361
|
+
### Themes
|
|
470
362
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
| Theme | Use Case |
|
|
474
|
-
|-------|----------|
|
|
475
|
-
| `"light"` | Optimized for light backgrounds |
|
|
476
|
-
| `"dark"` | Optimized for dark backgrounds |
|
|
363
|
+
Use `"light"` for light backgrounds and `"dark"` for dark backgrounds. The API adjusts the logo's color profile to maximize contrast.
|
|
477
364
|
|
|
478
365
|
## Rate Limits & Quotas
|
|
479
366
|
|
|
480
|
-
Rate limits and monthly quotas are enforced
|
|
481
|
-
|
|
482
|
-
## Related Packages
|
|
367
|
+
Rate limits and monthly quotas are enforced server-side and vary by plan. The SDK automatically retries with exponential backoff when limits are hit and emits `"rateLimitWarning"` / `"quotaWarning"` events so you can react in your UI. See [pricing & plan details](https://getquikturn.io/pricing).
|
|
483
368
|
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
Ready-made React components for displaying Quikturn logos. Includes an infinite scrolling carousel, responsive grid, single logo image, context provider for token propagation, and a `useLogoUrl()` hook. Zero CSS dependencies -- inline styles only.
|
|
487
|
-
|
|
488
|
-
```bash
|
|
489
|
-
pnpm add @quikturn/logos-react @quikturn/logos
|
|
490
|
-
```
|
|
369
|
+
## Resources
|
|
491
370
|
|
|
492
|
-
|
|
371
|
+
- **[Quikturn website](https://getquikturn.io)** -- sign up, manage keys, explore the API
|
|
372
|
+
- **[Dashboard](https://getquikturn.io/dashboard)** -- usage analytics, key management, plan upgrades
|
|
373
|
+
- **[Pricing](https://getquikturn.io/pricing)** -- free tier, pro, and enterprise plans
|
|
374
|
+
- **[React components](./packages/react/README.md)** -- `@quikturn/logos-react` docs
|
|
375
|
+
- **[GitHub](https://github.com/Quikturn-PowerPoint-Add-In/Logo-SDK)** -- source, issues, contributions
|
|
493
376
|
|
|
494
377
|
## License
|
|
495
378
|
|
|
496
|
-
MIT
|
|
379
|
+
MIT -- built by [Quikturn](https://getquikturn.io)
|