@devultur/convex 1.3.2 → 1.4.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 +426 -9
- package/dist/bin/init.js +44 -23
- package/dist/chunk-EX3W77VY.js +245 -0
- package/dist/chunk-HOFTKJWT.js +58 -0
- package/dist/chunk-KAIVI7RB.js +21 -0
- package/dist/chunk-QBHIZBOQ.js +139 -0
- package/dist/{chunk-GKLFRSGI.js → chunk-YIPZZDGD.js} +8 -1
- package/dist/component/_generated/api.d.ts +6 -0
- package/dist/component/_generated/api.d.ts.map +1 -1
- package/dist/component/_generated/api.js.map +1 -1
- package/dist/component/_generated/component.d.ts +27 -0
- package/dist/component/_generated/component.d.ts.map +1 -1
- package/dist/component/library.d.ts +93 -0
- package/dist/component/library.d.ts.map +1 -0
- package/dist/component/library.js +74 -0
- package/dist/component/library.js.map +1 -0
- package/dist/component/mediaMeta.d.ts +46 -0
- package/dist/component/mediaMeta.d.ts.map +1 -0
- package/dist/component/mediaMeta.js +82 -0
- package/dist/component/mediaMeta.js.map +1 -0
- package/dist/component/metadata.d.ts +59 -0
- package/dist/component/metadata.d.ts.map +1 -0
- package/dist/component/metadata.js +32 -0
- package/dist/component/metadata.js.map +1 -0
- package/dist/component/public.d.ts +17 -1
- package/dist/component/public.d.ts.map +1 -1
- package/dist/component/public.js +20 -11
- package/dist/component/public.js.map +1 -1
- package/dist/component/schema.d.ts +17 -2
- package/dist/component/schema.d.ts.map +1 -1
- package/dist/component/schema.js +13 -1
- package/dist/component/schema.js.map +1 -1
- package/dist/component/uploads.d.ts +13 -0
- package/dist/component/uploads.d.ts.map +1 -1
- package/dist/component/uploads.js +24 -5
- package/dist/component/uploads.js.map +1 -1
- package/dist/error-labels-BfqcFh2R.d.ts +19 -0
- package/dist/index.d.ts +204 -93
- package/dist/index.js +200 -128
- package/dist/locales/es.d.ts +11 -0
- package/dist/locales/es.js +162 -0
- package/dist/media-picker-labels-CiVcNUZo.d.ts +114 -0
- package/dist/{pdf-render-CiCK6V1X.d.ts → pdf-render-BwJGagvz.d.ts} +1 -1
- package/dist/pdfjs.d.ts +13 -2
- package/dist/pdfjs.js +9 -0
- package/dist/react.d.ts +441 -66
- package/dist/react.js +1663 -550
- package/dist/types-LrusGVDf.d.ts +62 -0
- package/dist/validators.d.ts +17 -5
- package/dist/validators.js +1 -1
- package/package.json +8 -4
package/dist/pdfjs.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { P as PdfjsModule } from './pdf-render-
|
|
1
|
+
import { P as PdfjsLoader, a as PdfjsModule } from './pdf-render-BwJGagvz.js';
|
|
2
2
|
|
|
3
3
|
/** The worker next to the legacy build, resolved by your bundler from this package. */
|
|
4
4
|
declare const defaultPdfWorkerSrc: () => string;
|
|
@@ -7,5 +7,16 @@ declare const defaultPdfWorkerSrc: () => string;
|
|
|
7
7
|
* already, points `GlobalWorkerOptions.workerSrc` at `defaultPdfWorkerSrc()`.
|
|
8
8
|
*/
|
|
9
9
|
declare function loadPdfjs(): Promise<PdfjsModule>;
|
|
10
|
+
/**
|
|
11
|
+
* A PDF's page count, read in the browser with pdf.js (imported on the first call), or `null` when the file isn't a
|
|
12
|
+
* PDF pdf.js can open. Pass it as `pageCount` to `upload()` or `confirmUpload`: it's recorded as the client's hint.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* const pageCount = (await countPdfPages(file)) ?? undefined;
|
|
16
|
+
* await upload(file, { pageCount });
|
|
17
|
+
*/
|
|
18
|
+
declare function countPdfPages(file: Blob, options?: {
|
|
19
|
+
loadPdfjs?: PdfjsLoader;
|
|
20
|
+
}): Promise<number | null>;
|
|
10
21
|
|
|
11
|
-
export { defaultPdfWorkerSrc, loadPdfjs };
|
|
22
|
+
export { countPdfPages, defaultPdfWorkerSrc, loadPdfjs };
|
package/dist/pdfjs.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
countPages
|
|
3
|
+
} from "./chunk-HOFTKJWT.js";
|
|
4
|
+
|
|
1
5
|
// src/pdfjs.ts
|
|
2
6
|
var defaultPdfWorkerSrc = () => new URL("pdfjs-dist/legacy/build/pdf.worker.min.mjs", import.meta.url).href;
|
|
3
7
|
async function loadPdfjs() {
|
|
@@ -5,7 +9,12 @@ async function loadPdfjs() {
|
|
|
5
9
|
if (!pdfjs.GlobalWorkerOptions.workerSrc) pdfjs.GlobalWorkerOptions.workerSrc = defaultPdfWorkerSrc();
|
|
6
10
|
return pdfjs;
|
|
7
11
|
}
|
|
12
|
+
async function countPdfPages(file, options) {
|
|
13
|
+
const pdfjs = await (options?.loadPdfjs ?? loadPdfjs)();
|
|
14
|
+
return countPages(pdfjs, file);
|
|
15
|
+
}
|
|
8
16
|
export {
|
|
17
|
+
countPdfPages,
|
|
9
18
|
defaultPdfWorkerSrc,
|
|
10
19
|
loadPdfjs
|
|
11
20
|
};
|
package/dist/react.d.ts
CHANGED
|
@@ -1,11 +1,35 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { DevulturMedia, MediaUrlOptions, Visibility, ProcessingPhase, FailureReason, MediaStatusValue } from '@devultur/core';
|
|
3
3
|
import { BakeOutputFormat, MediaUploadState, MediaUploadError, UploadProgress } from '@devultur/react';
|
|
4
4
|
export { MediaUploadError, MediaUploadState, UploadProgress } from '@devultur/react';
|
|
5
5
|
import { FunctionReference } from 'convex/server';
|
|
6
6
|
import { Value } from 'convex/values';
|
|
7
|
-
import { a as
|
|
8
|
-
export {
|
|
7
|
+
import { A as AttachmentLabels, M as MediaLibraryLabels, a as MediaPickerLabels } from './media-picker-labels-CiVcNUZo.js';
|
|
8
|
+
export { b as AttachmentKind, d as defaultAttachmentLabels, c as defaultMediaLibraryLabels, e as defaultMediaPickerLabels, f as formatDuration, g as formatFileSize } from './media-picker-labels-CiVcNUZo.js';
|
|
9
|
+
import { M as MediaRecord } from './types-LrusGVDf.js';
|
|
10
|
+
import { P as PdfjsLoader } from './pdf-render-BwJGagvz.js';
|
|
11
|
+
export { a as PdfjsModule } from './pdf-render-BwJGagvz.js';
|
|
12
|
+
|
|
13
|
+
/** Why a media fetch was refused. Stable: match on it, not on `message`. */
|
|
14
|
+
type MediaFetchErrorCode =
|
|
15
|
+
/** The delivery answered with a non-2xx status (`status` has it). */
|
|
16
|
+
"http_error"
|
|
17
|
+
/** `Content-Length`, or the streamed body, exceeds `maxBytes`. */
|
|
18
|
+
| "too_large"
|
|
19
|
+
/** The expected content type isn't one that can be previewed inline. */
|
|
20
|
+
| "unsupported_type"
|
|
21
|
+
/** The response's `Content-Type` doesn't agree with the expected one. */
|
|
22
|
+
| "type_mismatch"
|
|
23
|
+
/** No viewer token for private media: its issuance failed (`useDevultur().tokenError` has why) or was refused. */
|
|
24
|
+
| "token_unavailable"
|
|
25
|
+
/** The delivery refused the token for this browser session, also after a re-issue (video playback). */
|
|
26
|
+
| "session_mismatch";
|
|
27
|
+
declare class MediaFetchError extends Error {
|
|
28
|
+
readonly code: MediaFetchErrorCode;
|
|
29
|
+
/** HTTP status, for `http_error`. */
|
|
30
|
+
readonly status?: number;
|
|
31
|
+
constructor(code: MediaFetchErrorCode, message: string, status?: number, options?: ErrorOptions);
|
|
32
|
+
}
|
|
9
33
|
|
|
10
34
|
/** What a viewer token action returns: the token with its lifetime, or the bare token (default lifetime). */
|
|
11
35
|
type ViewerTokenResult = {
|
|
@@ -14,6 +38,52 @@ type ViewerTokenResult = {
|
|
|
14
38
|
} | string;
|
|
15
39
|
/** Extra arguments sent with `sessionSecret` to the viewer token action. */
|
|
16
40
|
type ViewerTokenArgs = Record<string, Value>;
|
|
41
|
+
/**
|
|
42
|
+
* Where the viewer token for the current `tokenArgs` stands: not requested yet, being issued (no token yet), held, or
|
|
43
|
+
* failed (the action threw or returned no token). A renewal in flight, or one that failed, keeps `"ready"`.
|
|
44
|
+
*/
|
|
45
|
+
type TokenStatus = "idle" | "loading" | "ready" | "error";
|
|
46
|
+
|
|
47
|
+
/** Transform/delivery options for media URLs (without `token`, which the context injects). */
|
|
48
|
+
type MediaRenderOptions = Omit<MediaUrlOptions, "token">;
|
|
49
|
+
type ViewerTokenAction = FunctionReference<"action", "public", {
|
|
50
|
+
sessionSecret: string;
|
|
51
|
+
}>;
|
|
52
|
+
interface MediaSession {
|
|
53
|
+
token: string | null;
|
|
54
|
+
/** Where the viewer token stands; `"error"` makes private previews fail fast with `token_unavailable`. */
|
|
55
|
+
tokenStatus: TokenStatus;
|
|
56
|
+
/** Why the last issuance failed (the action threw or returned no token), while `tokenStatus` is `"error"`. */
|
|
57
|
+
tokenError: Error | null;
|
|
58
|
+
/** Issues the viewer token again (after a failure, for example). Resolves to the new token, or `null`. */
|
|
59
|
+
retryToken: () => Promise<string | null>;
|
|
60
|
+
baseUrl: string | null;
|
|
61
|
+
/** Browser session secret → sent in `${SESSION_HEADER}` on every private delivery. */
|
|
62
|
+
sessionSecret: string;
|
|
63
|
+
/** Delivery URL from a reference (non-hook → usable in handlers and `.map`). Token-transparent. */
|
|
64
|
+
url: (media: DevulturMedia, options?: MediaRenderOptions) => string;
|
|
65
|
+
/** Downloads a video's subtitle text for a locale (auth-transparent). */
|
|
66
|
+
getCaptionsText: (media: DevulturMedia, locale: string) => Promise<string>;
|
|
67
|
+
/**
|
|
68
|
+
* Re-issues the viewer token (new session fingerprint with the current UA/IP) and updates the context.
|
|
69
|
+
* Single-flight: concurrent calls share the same issuance. Returns the new token (or null if it
|
|
70
|
+
* failed). The render uses it to transparently recover from a 401 `session_mismatch`.
|
|
71
|
+
*/
|
|
72
|
+
reissueToken: () => Promise<string | null>;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** What `useDevultur()` can do only under a `<DevulturProvider>` given the matching actions. */
|
|
76
|
+
type DevulturCapability = "upload" | "uploadUrl" | "deleteMedia" | "api";
|
|
77
|
+
/**
|
|
78
|
+
* Thrown (or rejected) when an app calls something its provider wasn't given: `upload`, `uploadUrl` or `deleteMedia`
|
|
79
|
+
* under a `<DevulturViewerProvider>`, or a hook that needs the `api` (`useMediaUpload`, `<MediaLibrary>`, ...).
|
|
80
|
+
* Stable `code`: `capability_unavailable`.
|
|
81
|
+
*/
|
|
82
|
+
declare class DevulturCapabilityError extends Error {
|
|
83
|
+
readonly code = "capability_unavailable";
|
|
84
|
+
readonly capability: DevulturCapability;
|
|
85
|
+
constructor(capability: DevulturCapability);
|
|
86
|
+
}
|
|
17
87
|
|
|
18
88
|
interface CropUploadRenderProps {
|
|
19
89
|
/** The state machine of the full cycle (idle → uploading → ready / failed). */
|
|
@@ -62,22 +132,147 @@ interface CropUploadProps {
|
|
|
62
132
|
*/
|
|
63
133
|
declare function CropUpload({ aspectRatio, visibility, outputFormat, maxWidth, minSourceWidth, replaces, onComplete, onReject, accept, cropperClassName, labels, children, }: CropUploadProps): React.JSX.Element;
|
|
64
134
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
135
|
+
interface DocumentLinkProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, "href" | "download" | "media"> {
|
|
136
|
+
/** Typed reference. `null`/`undefined` → renders nothing. */
|
|
137
|
+
media: DevulturMedia | null | undefined;
|
|
138
|
+
/** `true` → the link downloads the file instead of opening it. Private media always downloads. Default `false`. */
|
|
139
|
+
download?: boolean;
|
|
140
|
+
/** Text of the link. Default: the media's `title`, else its filename, else `labels.untitled`. */
|
|
141
|
+
children?: React.ReactNode;
|
|
142
|
+
labels?: Partial<AttachmentLabels>;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* A link to a media's file, named after it. Public: a plain link to the delivery URL (it opens in the browser, or
|
|
146
|
+
* downloads with `download`). Private: a navigation can't send the session header, so the click fetches the file
|
|
147
|
+
* with it and downloads it, as `<DownloadLink>` does.
|
|
148
|
+
*
|
|
149
|
+
* @example
|
|
150
|
+
* <DocumentLink media={invoice.file} target="_blank" rel="noopener" />
|
|
151
|
+
*/
|
|
152
|
+
declare function DocumentLink({ media, download, children, labels, ...anchorProps }: DocumentLinkProps): React.JSX.Element | null;
|
|
153
|
+
type HeadingLevel = 2 | 3 | 4 | 5 | 6;
|
|
154
|
+
interface AttachmentCardProps extends Omit<React.HTMLAttributes<HTMLElement>, "children"> {
|
|
155
|
+
/** Typed reference. `null`/`undefined` → renders nothing. */
|
|
156
|
+
media: DevulturMedia | null | undefined;
|
|
157
|
+
/** The type you know the media has. Default: inferred from `media.filename`'s extension (picks the icon). */
|
|
158
|
+
contentType?: string;
|
|
159
|
+
/** Shows an "Open preview" button that calls this, e.g. to render `<Preview>` in a dialog. */
|
|
160
|
+
onOpen?: (media: DevulturMedia) => void;
|
|
161
|
+
/** Shown in place of the type icon, e.g. a `<PdfThumbnail>` or an `<Image>`. */
|
|
162
|
+
preview?: React.ReactNode;
|
|
163
|
+
/** Level of the name's heading. Default `3`. */
|
|
164
|
+
headingLevel?: HeadingLevel;
|
|
165
|
+
/** Locale for the size. Default: `labels.locale` (`en`). */
|
|
166
|
+
locale?: string;
|
|
167
|
+
labels?: Partial<AttachmentLabels>;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* A card for an attachment: an icon by type (or your `preview`), its name, its type and size, its page count (PDF)
|
|
171
|
+
* or duration (audio, video), a download link and, with `onOpen`, an "Open preview" button. Unstyled: target its
|
|
172
|
+
* parts with `data-part` (`icon`, `name`, `details`, `actions`, `download`, `open`).
|
|
173
|
+
*
|
|
174
|
+
* @example
|
|
175
|
+
* <AttachmentCard media={file} onOpen={setPreviewed} />
|
|
176
|
+
*/
|
|
177
|
+
declare function AttachmentCard({ media, contentType, onOpen, preview, headingLevel, locale, labels, ...articleProps }: AttachmentCardProps): React.JSX.Element | null;
|
|
178
|
+
|
|
179
|
+
/** An explicit `srcSet` is passed through to the `<img>` as is, and wins over the one `widths` builds. */
|
|
180
|
+
interface ImageProps extends Omit<React.ImgHTMLAttributes<HTMLImageElement>, "src" | "width" | "height"> {
|
|
181
|
+
/** Typed reference. `null`/`undefined` → renders `fallback` (or `externalFallback`). Its `alt` is the default `alt`. */
|
|
182
|
+
media: DevulturMedia | null | undefined;
|
|
183
|
+
/** Resize width (px). With `widths`, the width a private image is picked for when `sizes` can't tell. */
|
|
184
|
+
width?: number;
|
|
185
|
+
/** Resize height (px). With `widths` and `width`, it sets the ratio every variant keeps. */
|
|
186
|
+
height?: number;
|
|
187
|
+
fit?: MediaUrlOptions["fit"];
|
|
188
|
+
format?: MediaUrlOptions["format"];
|
|
189
|
+
quality?: number;
|
|
190
|
+
/**
|
|
191
|
+
* Responsive widths (px). Public images get a `srcset` with one transformed variant per width, and default to
|
|
192
|
+
* `loading="lazy"` and `decoding="async"`. Private images are fetched once, at the largest width up to twice the
|
|
193
|
+
* width `sizes` (or `width`) gives them: a `blob:` URL can't be a `srcset` candidate.
|
|
194
|
+
*/
|
|
195
|
+
widths?: readonly number[];
|
|
196
|
+
/** What to show when there's no media (or it's loading). */
|
|
197
|
+
fallback?: React.ReactNode;
|
|
198
|
+
/** Explicit external URL (e.g. Unsplash) when `media` is null or the load fails. */
|
|
199
|
+
externalFallback?: string;
|
|
200
|
+
/** background-image mode: composes the URL as this element's `background-image` (doesn't force `<img>`). */
|
|
201
|
+
render?: React.ReactElement<{
|
|
202
|
+
style?: React.CSSProperties;
|
|
203
|
+
}>;
|
|
204
|
+
/**
|
|
205
|
+
* A private image that can't be shown: a `MediaFetchError` (`token_unavailable` right away when the viewer token
|
|
206
|
+
* couldn't be issued, `http_error` when the delivery refused it) or a network error. `fallback` shows meanwhile.
|
|
207
|
+
*/
|
|
208
|
+
onLoadError?: (error: Error) => void;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Renders any media declaratively: token-transparent, with typed transforms, and works inside a
|
|
212
|
+
* `.map()` (no wrappers or hooks rules on the consumer's side).
|
|
213
|
+
*
|
|
214
|
+
* @example
|
|
215
|
+
* <Image media={course.thumbnail} alt={course.title} width={512} format="webp" fallback={<Placeholder />} />
|
|
216
|
+
* <Image media={post.cover} widths={[480, 960, 1440]} sizes="(min-width: 768px) 50vw, 100vw" format="webp" />
|
|
217
|
+
*/
|
|
218
|
+
declare function Image({ media, width, height, fit, format, quality, widths, sizes, fallback, externalFallback, render, alt, onLoadError, ...imgProps }: ImageProps): React.JSX.Element;
|
|
219
|
+
|
|
220
|
+
/** What `renderItem` gets besides the record. */
|
|
221
|
+
interface MediaLibraryItemState {
|
|
222
|
+
/** The record's reference (`mediaFromRecord`), `null` for a record without a visibility. */
|
|
223
|
+
media: DevulturMedia | null;
|
|
224
|
+
/** Chosen (only with `selectable`). */
|
|
225
|
+
isSelected: boolean;
|
|
226
|
+
/** The item the arrow keys move from (the one in the tab order). */
|
|
227
|
+
isActive: boolean;
|
|
228
|
+
}
|
|
229
|
+
/** The parts of `<MediaLibrary>` that have a class name (`devultur-media-library__{part}`, `root`'s without the suffix). */
|
|
230
|
+
type MediaLibraryPart = "root" | "search" | "filter" | "list" | "item" | "thumbnail" | "name" | "size" | "status" | "more";
|
|
231
|
+
type MediaLibraryClassNames = Partial<Record<MediaLibraryPart, string>>;
|
|
232
|
+
|
|
233
|
+
type MediaType$1 = MediaRecord["type"];
|
|
234
|
+
interface MediaLibraryProps {
|
|
235
|
+
/** Called when an item is chosen (click, Enter or Space), with its reference (`null` for a record without one). */
|
|
236
|
+
onSelect: (record: MediaRecord, media: DevulturMedia | null) => void;
|
|
237
|
+
/** Overrides any of the strings; the rest stay English. */
|
|
238
|
+
labels?: Partial<MediaLibraryLabels>;
|
|
239
|
+
/** Only this kind of media; the type filter is then hidden. */
|
|
240
|
+
type?: MediaType$1;
|
|
241
|
+
/** Keeps the chosen item selected (`aria-selected`, `data-selected`), as a picker. Default `false`. */
|
|
242
|
+
selectable?: boolean;
|
|
243
|
+
/**
|
|
244
|
+
* The selected records' keys (the media ids), controlled by the app: with it, the library shows these as selected
|
|
245
|
+
* instead of the last one chosen. Implies `selectable`.
|
|
246
|
+
*/
|
|
247
|
+
selectedKeys?: readonly string[];
|
|
248
|
+
/** Several items can be selected at once (`aria-multiselectable`), for `selectedKeys`. Default `false`. */
|
|
249
|
+
multiple?: boolean;
|
|
250
|
+
/** Shows only the records it returns `true` for, of each loaded page (a page can then show fewer items). */
|
|
251
|
+
filter?: (record: MediaRecord) => boolean;
|
|
252
|
+
/** Replaces an item's content (thumbnail, name and size). The item itself stays the focusable option. */
|
|
253
|
+
renderItem?: (record: MediaRecord, state: MediaLibraryItemState) => React.ReactNode;
|
|
254
|
+
/** Records per page. Default 24. */
|
|
255
|
+
pageSize?: number;
|
|
256
|
+
/**
|
|
257
|
+
* Draws page 1 of PDFs (`<PdfThumbnail>`, inside a `PdfPreviewProvider`). Each one downloads its PDF as it nears the
|
|
258
|
+
* viewport, so it's off by default: PDFs show an icon.
|
|
259
|
+
*/
|
|
260
|
+
pdfThumbnails?: boolean;
|
|
261
|
+
/** Added to the root's `devultur-media-library` class. */
|
|
262
|
+
className?: string;
|
|
263
|
+
/** Added to each part's `devultur-media-library__{part}` class. */
|
|
264
|
+
classNames?: MediaLibraryClassNames;
|
|
80
265
|
}
|
|
266
|
+
/**
|
|
267
|
+
* A searchable grid of the media library: a search box, a type filter and the items (a thumbnail for images, an icon,
|
|
268
|
+
* the name and the size), a page at a time. Arrow keys, Home and End move between items. Needs `listMediaPage` and
|
|
269
|
+
* `searchMedia` in `<DevulturProvider api>`. Unstyled but for the layout; style it through the class names and the
|
|
270
|
+
* `--devultur-library-*` custom properties.
|
|
271
|
+
*
|
|
272
|
+
* @example
|
|
273
|
+
* <MediaLibrary type="image" selectable onSelect={(record, media) => setCover(media)} />
|
|
274
|
+
*/
|
|
275
|
+
declare function MediaLibrary(props: MediaLibraryProps): React.JSX.Element;
|
|
81
276
|
|
|
82
277
|
interface UseMediaObjectUrlOptions {
|
|
83
278
|
/** `false` → nothing is fetched (e.g. a list row that isn't selected). Default `true`. */
|
|
@@ -165,6 +360,153 @@ declare function PdfPreviewProvider({ pdfjs, workerSrc, labels, children, }: Pdf
|
|
|
165
360
|
children: React.ReactNode;
|
|
166
361
|
}): React.JSX.Element;
|
|
167
362
|
|
|
363
|
+
/** A file the picker is uploading, or one that failed (a finished upload leaves the list for the selection). */
|
|
364
|
+
interface MediaPickerUpload$1 {
|
|
365
|
+
/** Stable for the upload's lifetime, for React keys and `cancel(id)`. */
|
|
366
|
+
id: string;
|
|
367
|
+
file: File;
|
|
368
|
+
/** Bytes sent over the file's size, 0 to 1. */
|
|
369
|
+
fraction: number;
|
|
370
|
+
status: "uploading" | "failed";
|
|
371
|
+
/** Why it failed (`labels.uploadError` or `labels.notAccepted`), `null` while uploading. */
|
|
372
|
+
error: string | null;
|
|
373
|
+
/** A failed upload `accept` let through can be retried; a rejected file can't. */
|
|
374
|
+
canRetry: boolean;
|
|
375
|
+
}
|
|
376
|
+
interface MediaPickerUploads {
|
|
377
|
+
uploads: MediaPickerUpload$1[];
|
|
378
|
+
/** Uploads the files `accept` lets through (only the first one without `multiple`) and lists the rest as failed. */
|
|
379
|
+
start: (files: Iterable<File>) => void;
|
|
380
|
+
cancel: (id: string) => void;
|
|
381
|
+
retry: (id: string) => void;
|
|
382
|
+
dismiss: (id: string) => void;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/** What every part of a `<MediaPicker>` (and its render prop, and `useMediaPicker()`) gets. */
|
|
386
|
+
interface MediaPickerState extends MediaPickerUploads {
|
|
387
|
+
/** The selection, in order (one item at most without `multiple`). */
|
|
388
|
+
selected: readonly DevulturMedia[];
|
|
389
|
+
multiple: boolean;
|
|
390
|
+
/** The upload `accept`: the picker's own, else the one its `type` implies. */
|
|
391
|
+
accept: readonly string[] | undefined;
|
|
392
|
+
/** The library's type filter: the picker's `type`, else the one `accept` implies. */
|
|
393
|
+
libraryType: MediaRecord["type"] | undefined;
|
|
394
|
+
labels: MediaPickerLabels;
|
|
395
|
+
libraryLabels: Partial<MediaLibraryLabels> | undefined;
|
|
396
|
+
attachmentLabels: Partial<AttachmentLabels> | undefined;
|
|
397
|
+
/** Selects a media (replaces the selection without `multiple`). */
|
|
398
|
+
select: (media: DevulturMedia) => void;
|
|
399
|
+
/** Selects a media, or removes it when it's selected already (with `multiple`). */
|
|
400
|
+
toggle: (media: DevulturMedia) => void;
|
|
401
|
+
remove: (media: DevulturMedia) => void;
|
|
402
|
+
clear: () => void;
|
|
403
|
+
/** Opens the browser's file chooser. */
|
|
404
|
+
openFileDialog: () => void;
|
|
405
|
+
/** Says `message` in the picker's polite live region. */
|
|
406
|
+
announce: (message: string) => void;
|
|
407
|
+
/** The selection's region, focused after an upload and a removal (the `<MediaPicker.Selection>` sets it). */
|
|
408
|
+
selectionRef: React.RefObject<HTMLElement | null>;
|
|
409
|
+
}
|
|
410
|
+
/** The state of the nearest `<MediaPicker>`, to build a part of your own. */
|
|
411
|
+
declare function useMediaPicker(): MediaPickerState;
|
|
412
|
+
|
|
413
|
+
/** What `<MediaPicker.Library>` passes through to `<MediaLibrary>`; the picker sets the rest. */
|
|
414
|
+
type MediaPickerLibraryProps = Pick<MediaLibraryProps, "renderItem" | "pageSize" | "pdfThumbnails" | "className" | "classNames">;
|
|
415
|
+
/**
|
|
416
|
+
* The picker's `<MediaLibrary>`: shows the selection as selected, picks (and, with `multiple`, unpicks) an item on
|
|
417
|
+
* click, Enter or Space, and lists only what `accept` lets through.
|
|
418
|
+
*/
|
|
419
|
+
declare function MediaPickerLibrary(props: MediaPickerLibraryProps): React.JSX.Element;
|
|
420
|
+
|
|
421
|
+
interface MediaPickerSelectionProps {
|
|
422
|
+
/** Replaces an item's card. The remove button stays below it. */
|
|
423
|
+
renderItem?: (media: DevulturMedia) => React.ReactNode;
|
|
424
|
+
/** Level of the selection's heading (the cards' are one below). Default `3`. */
|
|
425
|
+
headingLevel?: 2 | 3 | 4 | 5;
|
|
426
|
+
/** Added to the region's `devultur-media-picker__selection` class. */
|
|
427
|
+
className?: string;
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* The picker's selection: a card per item (a thumbnail for images, the name, type, size and a download link) with
|
|
431
|
+
* "Open preview" (an inline `<Preview>`) and remove, plus clear, and replace without `multiple`. Focused after an
|
|
432
|
+
* upload and a removal, so a keyboard user lands on the result.
|
|
433
|
+
*/
|
|
434
|
+
declare function MediaPickerSelection({ renderItem, headingLevel, className }: MediaPickerSelectionProps): React.JSX.Element;
|
|
435
|
+
|
|
436
|
+
interface MediaPickerUploadProps {
|
|
437
|
+
/** Added to the drop zone's `devultur-media-picker__upload` class. */
|
|
438
|
+
className?: string;
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* The picker's upload area: a button that opens the file chooser, a drop target for files, and each upload's
|
|
442
|
+
* progress with a cancel button (or its error, with retry and dismiss).
|
|
443
|
+
*/
|
|
444
|
+
declare function MediaPickerUpload({ className }: MediaPickerUploadProps): React.JSX.Element;
|
|
445
|
+
|
|
446
|
+
interface SingleValueProps {
|
|
447
|
+
multiple?: false;
|
|
448
|
+
/** The selected media, controlled. Omitted → the picker keeps its own. */
|
|
449
|
+
value?: DevulturMedia | null;
|
|
450
|
+
/** Called with the new selection: on an upload, a pick from the library, a removal or a clear. */
|
|
451
|
+
onChange: (value: DevulturMedia | null) => void;
|
|
452
|
+
}
|
|
453
|
+
interface MultipleValueProps {
|
|
454
|
+
/** Several media can be selected; `value` and `onChange` take arrays. */
|
|
455
|
+
multiple: true;
|
|
456
|
+
value?: readonly DevulturMedia[];
|
|
457
|
+
onChange: (value: DevulturMedia[]) => void;
|
|
458
|
+
}
|
|
459
|
+
interface CommonProps {
|
|
460
|
+
/**
|
|
461
|
+
* File types to pick, as an `<input accept>` takes them (`image/*`, `application/pdf`, `.pdf`). Filters the files to
|
|
462
|
+
* upload and the library's records, and sets the library's type filter when they're all of one type.
|
|
463
|
+
*/
|
|
464
|
+
accept?: readonly string[];
|
|
465
|
+
/** Only this kind of media in the library; without `accept`, also what can be uploaded (`image/*`, `video/*`). */
|
|
466
|
+
type?: MediaRecord["type"];
|
|
467
|
+
/** Overrides any of the picker's strings; the rest stay English. */
|
|
468
|
+
labels?: Partial<MediaPickerLabels>;
|
|
469
|
+
/** Labels for the library (`<MediaPicker.Library>`). */
|
|
470
|
+
libraryLabels?: Partial<MediaLibraryLabels>;
|
|
471
|
+
/** Labels for the selection's cards (`<AttachmentCard>`). */
|
|
472
|
+
attachmentLabels?: Partial<AttachmentLabels>;
|
|
473
|
+
/** Added to the root's `devultur-media-picker` class. */
|
|
474
|
+
className?: string;
|
|
475
|
+
/**
|
|
476
|
+
* The picker's layout: the parts (`<MediaPicker.Upload>`, `.Library`, `.Selection`) in any order and markup, or a
|
|
477
|
+
* function of the picker's state. Default: the upload, the library and the selection, in that order.
|
|
478
|
+
*/
|
|
479
|
+
children?: React.ReactNode | ((picker: MediaPickerState) => React.ReactNode);
|
|
480
|
+
}
|
|
481
|
+
type MediaPickerProps = CommonProps & (SingleValueProps | MultipleValueProps);
|
|
482
|
+
/**
|
|
483
|
+
* Lets an editor pick media: upload new files (progress, cancel, retry), browse and search the library, and review
|
|
484
|
+
* the selection. Returns `DevulturMedia` references through `onChange`; a new upload is selected. It renders inline,
|
|
485
|
+
* with no dialog of its own: put it in yours. Needs `createUploadUrl`, `listMediaPage` and `searchMedia` in
|
|
486
|
+
* `<DevulturProvider api>` (and `confirmUpload` to record uploads). Under a `PdfPreviewProvider` with pdf.js, a PDF's
|
|
487
|
+
* page count is read before it uploads.
|
|
488
|
+
*
|
|
489
|
+
* @example
|
|
490
|
+
* <MediaPicker accept={["image/*"]} value={cover} onChange={setCover} />
|
|
491
|
+
*/
|
|
492
|
+
declare function MediaPicker(props: MediaPickerProps): React.JSX.Element;
|
|
493
|
+
declare namespace MediaPicker {
|
|
494
|
+
var Upload: typeof MediaPickerUpload;
|
|
495
|
+
var Library: typeof MediaPickerLibrary;
|
|
496
|
+
var Selection: typeof MediaPickerSelection;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
/** A file's name and type, or a record's filename and content type. */
|
|
500
|
+
interface Candidate {
|
|
501
|
+
name: string;
|
|
502
|
+
type: string;
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Whether `candidate` matches one of the `accept` patterns, as an `<input accept>` does: a MIME type
|
|
506
|
+
* (`application/pdf`), a wildcard (`image/*`) or an extension (`.pdf`). No `accept` (or an empty one) accepts all.
|
|
507
|
+
*/
|
|
508
|
+
declare function matchesAccept(candidate: Candidate, accept: readonly string[] | undefined): boolean;
|
|
509
|
+
|
|
168
510
|
interface PdfThumbnailProps {
|
|
169
511
|
/** Typed reference. `null`/`undefined` → renders nothing. */
|
|
170
512
|
media: DevulturMedia | null | undefined;
|
|
@@ -207,7 +549,8 @@ interface PreviewProps {
|
|
|
207
549
|
/**
|
|
208
550
|
* Shown for types that don't preview inline and when the fetch fails. Default: a `<DownloadLink>`.
|
|
209
551
|
* As a function it receives why: a `MediaFetchError` when the fetch was refused (`http_error`, `too_large`,
|
|
210
|
-
* `type_mismatch`)
|
|
552
|
+
* `type_mismatch`), the viewer token couldn't be issued (`token_unavailable`, nothing fetched), a video's session
|
|
553
|
+
* was refused (`session_mismatch`) or the type doesn't preview inline (`unsupported_type`), `null` otherwise
|
|
211
554
|
* (a network failure, a PDF pdf.js can't open, or the link after the `maxPages` note).
|
|
212
555
|
*/
|
|
213
556
|
fallback?: React.ReactNode | ((error: MediaFetchError | null) => React.ReactNode);
|
|
@@ -240,8 +583,40 @@ declare function Preview({ media, contentType, fallback, loading, labels, ...vie
|
|
|
240
583
|
/** How a content type renders inline: `<img>`, a PDF view (pdf.js canvases or `<iframe>`), `<audio>` or `<pre>`. */
|
|
241
584
|
type PreviewKind = "image" | "pdf" | "audio" | "text";
|
|
242
585
|
|
|
243
|
-
|
|
244
|
-
|
|
586
|
+
type MediaType = MediaRecord["type"];
|
|
587
|
+
interface UseMediaLibraryOptions {
|
|
588
|
+
/** Only this kind of media. Default: every kind. */
|
|
589
|
+
type?: MediaType;
|
|
590
|
+
/** Matches the title and filename. Debounced 250 ms; clearing it applies at once. Blank → newest first. */
|
|
591
|
+
search?: string;
|
|
592
|
+
/** Records in the first page and in each `loadMore()`. Default 24. */
|
|
593
|
+
pageSize?: number;
|
|
594
|
+
}
|
|
595
|
+
/** Convex's pagination status. */
|
|
596
|
+
type MediaLibraryStatus = "LoadingFirstPage" | "CanLoadMore" | "LoadingMore" | "Exhausted";
|
|
597
|
+
interface MediaLibraryState {
|
|
598
|
+
/** The records loaded so far: newest first, or best match first while searching. */
|
|
599
|
+
items: MediaRecord[];
|
|
600
|
+
status: MediaLibraryStatus;
|
|
601
|
+
/** Loads `numItems` more (default `pageSize`). Does nothing unless `status` is `"CanLoadMore"`. */
|
|
602
|
+
loadMore: (numItems?: number) => void;
|
|
603
|
+
/** The first page or a further one is loading. */
|
|
604
|
+
isLoading: boolean;
|
|
605
|
+
/** The search the items are for (the debounced `search`, trimmed). */
|
|
606
|
+
search: string;
|
|
607
|
+
/** `search` changed and the debounce hasn't applied it yet. */
|
|
608
|
+
isSearchPending: boolean;
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* The media library a page at a time, from the `listMediaPage` and `searchMedia` your `<DevulturProvider api>`
|
|
612
|
+
* passes. A new search or type starts again from the first page. Like Convex's `usePaginatedQuery`, a failed query
|
|
613
|
+
* throws to the nearest error boundary (`<MediaLibrary>` has its own).
|
|
614
|
+
*
|
|
615
|
+
* @example
|
|
616
|
+
* const { items, status, loadMore } = useMediaLibrary({ type: "image", search });
|
|
617
|
+
*/
|
|
618
|
+
declare function useMediaLibrary(options?: UseMediaLibraryOptions): MediaLibraryState;
|
|
619
|
+
|
|
245
620
|
type AnyAction = FunctionReference<"action">;
|
|
246
621
|
type AnyMutation = FunctionReference<"mutation">;
|
|
247
622
|
type AnyQuery = FunctionReference<"query">;
|
|
@@ -256,6 +631,10 @@ interface DevulturApi {
|
|
|
256
631
|
/** Requests the transcode of an uploaded video. Required by `useMediaUpload` for auto-process. */
|
|
257
632
|
processVideo?: AnyAction;
|
|
258
633
|
getMedia?: AnyQuery;
|
|
634
|
+
/** The library, newest first. Required by `useMediaLibrary` and `<MediaLibrary>`. */
|
|
635
|
+
listMediaPage?: AnyQuery;
|
|
636
|
+
/** The library matching a search. Required by `useMediaLibrary` and `<MediaLibrary>` to search. */
|
|
637
|
+
searchMedia?: AnyQuery;
|
|
259
638
|
saveProgress?: AnyMutation;
|
|
260
639
|
loadProgress?: AnyQuery;
|
|
261
640
|
markComplete?: AnyMutation;
|
|
@@ -268,6 +647,8 @@ interface UploadOptions {
|
|
|
268
647
|
onProgress?: (progress: UploadProgress) => void;
|
|
269
648
|
/** Aborts the PUT → `upload()` rejects with an `AbortError`. */
|
|
270
649
|
signal?: AbortSignal;
|
|
650
|
+
/** A PDF's page count to record with it, a hint (`countPdfPages` from `@devultur/convex/pdfjs` counts it). */
|
|
651
|
+
pageCount?: number;
|
|
271
652
|
}
|
|
272
653
|
/**
|
|
273
654
|
* The reference `upload()` resolves to: a `DevulturMedia` whose `key` is always set (the uploaded object's key; a
|
|
@@ -276,29 +657,19 @@ interface UploadOptions {
|
|
|
276
657
|
type UploadedMedia = DevulturMedia & {
|
|
277
658
|
readonly key: string;
|
|
278
659
|
};
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
660
|
+
/**
|
|
661
|
+
* What `useDevultur()` returns. Under a `<DevulturViewerProvider>`, `uploadUrl`, `upload` and `deleteMedia` throw a
|
|
662
|
+
* `DevulturCapabilityError` (`capability_unavailable`).
|
|
663
|
+
*/
|
|
664
|
+
interface DevulturContextValue extends MediaSession {
|
|
284
665
|
uploadUrl: (file: File) => Promise<{
|
|
285
666
|
url: string;
|
|
286
667
|
key: string;
|
|
287
668
|
}>;
|
|
288
669
|
/** Uploads a file (reporting progress), records it in the component, and returns the reference ready to save. */
|
|
289
670
|
upload: (file: File, options?: UploadOptions) => Promise<UploadedMedia>;
|
|
290
|
-
/** Delivery URL from a reference (non-hook → usable in handlers and `.map`). Token-transparent. */
|
|
291
|
-
url: (media: DevulturMedia, options?: MediaRenderOptions) => string;
|
|
292
|
-
/** Downloads a video's subtitle text for a locale (auth-transparent). */
|
|
293
|
-
getCaptionsText: (media: DevulturMedia, locale: string) => Promise<string>;
|
|
294
671
|
/** Deletes a media by reference: video → full folder; image/file → the object. */
|
|
295
672
|
deleteMedia: (media: DevulturMedia) => void;
|
|
296
|
-
/**
|
|
297
|
-
* Re-issues the viewer token (new session fingerprint with the current UA/IP) and updates the context.
|
|
298
|
-
* Single-flight: concurrent calls share the same issuance. Returns the new token (or null if it
|
|
299
|
-
* failed). The render uses it to transparently recover from a 401 `session_mismatch`.
|
|
300
|
-
*/
|
|
301
|
-
reissueToken: () => Promise<string | null>;
|
|
302
673
|
}
|
|
303
674
|
interface ProgressContextValue {
|
|
304
675
|
save: (videoId: string, position: number) => Promise<void>;
|
|
@@ -324,13 +695,37 @@ interface DevulturProviderProps {
|
|
|
324
695
|
* Your own viewer token action, used instead of `api.issueViewerToken`. It receives `{ sessionSecret, ...tokenArgs }`
|
|
325
696
|
* and returns what the component's `issueViewerToken` returns.
|
|
326
697
|
*/
|
|
327
|
-
issueViewerToken?:
|
|
328
|
-
sessionSecret: string;
|
|
329
|
-
}>;
|
|
698
|
+
issueViewerToken?: ViewerTokenAction;
|
|
330
699
|
children: React.ReactNode;
|
|
331
700
|
}
|
|
332
701
|
declare function DevulturProvider({ api, baseUrl, tokenArgs, issueViewerToken, children }: DevulturProviderProps): React.JSX.Element;
|
|
333
702
|
declare function useDevultur(): DevulturContextValue;
|
|
703
|
+
/**
|
|
704
|
+
* The `api` passed to `<DevulturProvider>`: your app's exported Devultur functions. Under a `<DevulturViewerProvider>`
|
|
705
|
+
* it throws a `DevulturCapabilityError`.
|
|
706
|
+
*/
|
|
707
|
+
declare function useDevulturApi(): DevulturApi;
|
|
708
|
+
interface DevulturViewerProviderProps {
|
|
709
|
+
/** Media worker base (e.g. `https://media.your-domain.com`). */
|
|
710
|
+
baseUrl: string;
|
|
711
|
+
/** Your viewer token action. It receives `{ sessionSecret, ...tokenArgs }`, like `<DevulturProvider>`'s. */
|
|
712
|
+
issueViewerToken: ViewerTokenAction;
|
|
713
|
+
/** Extra arguments for `issueViewerToken`, compared by value (see `<DevulturProvider tokenArgs>`). */
|
|
714
|
+
tokenArgs?: ViewerTokenArgs;
|
|
715
|
+
children: React.ReactNode;
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* A provider for apps that only display media: it issues and renews the viewer token, so `<Image>`, `<Preview>`,
|
|
719
|
+
* `<DownloadLink>`, `useMediaObjectUrl` and the video hooks work, and it needs no upload or delete actions. `upload`,
|
|
720
|
+
* `uploadUrl` and `deleteMedia` throw a `DevulturCapabilityError`, as do the hooks that need the `api`
|
|
721
|
+
* (`useMediaUpload`, `useDevulturApi`, `<MediaLibrary>`, `<MediaPicker>`).
|
|
722
|
+
*
|
|
723
|
+
* @example
|
|
724
|
+
* <DevulturViewerProvider baseUrl={MEDIA_URL} issueViewerToken={api.admin.issueViewerToken} tokenArgs={{ workspaceId }}>
|
|
725
|
+
* <Preview media={document.file} />
|
|
726
|
+
* </DevulturViewerProvider>
|
|
727
|
+
*/
|
|
728
|
+
declare function DevulturViewerProvider({ baseUrl, issueViewerToken, tokenArgs, children, }: DevulturViewerProviderProps): React.JSX.Element;
|
|
334
729
|
declare function useDevulturProgress(): ProgressContextValue;
|
|
335
730
|
/**
|
|
336
731
|
* Ready-to-use delivery URL for a key, with the context's viewer token already injected. The consumer
|
|
@@ -361,35 +756,15 @@ interface VideoProps {
|
|
|
361
756
|
declare function useVideoProps(media: DevulturMedia | null | undefined, options?: {
|
|
362
757
|
locales?: string[];
|
|
363
758
|
}): VideoProps | null;
|
|
364
|
-
interface ImageProps extends Omit<React.ImgHTMLAttributes<HTMLImageElement>, "src" | "width" | "height"> {
|
|
365
|
-
/** Typed reference. `null`/`undefined` → renders `fallback` (or `externalFallback`). */
|
|
366
|
-
media: DevulturMedia | null | undefined;
|
|
367
|
-
width?: number;
|
|
368
|
-
height?: number;
|
|
369
|
-
fit?: MediaUrlOptions["fit"];
|
|
370
|
-
format?: MediaUrlOptions["format"];
|
|
371
|
-
quality?: number;
|
|
372
|
-
/** What to show when there's no media (or it's loading). */
|
|
373
|
-
fallback?: React.ReactNode;
|
|
374
|
-
/** Explicit external URL (e.g. Unsplash) when `media` is null or the load fails. */
|
|
375
|
-
externalFallback?: string;
|
|
376
|
-
/** background-image mode: composes the URL as this element's `background-image` (doesn't force `<img>`). */
|
|
377
|
-
render?: React.ReactElement<{
|
|
378
|
-
style?: React.CSSProperties;
|
|
379
|
-
}>;
|
|
380
|
-
}
|
|
381
|
-
/**
|
|
382
|
-
* Renders any media declaratively: token-transparent, with typed transforms, and works inside a
|
|
383
|
-
* `.map()` (no wrappers or hooks rules on the consumer's side).
|
|
384
|
-
*
|
|
385
|
-
* @example
|
|
386
|
-
* <Image media={course.thumbnail} alt={course.title} width={512} format="webp" fallback={<Placeholder />} />
|
|
387
|
-
*/
|
|
388
|
-
declare function Image({ media, width, height, fit, format, quality, fallback, externalFallback, render, alt, ...imgProps }: ImageProps): React.JSX.Element;
|
|
389
759
|
interface DownloadLinkProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, "href" | "download" | "media"> {
|
|
390
760
|
media: DevulturMedia | null | undefined;
|
|
391
761
|
/** Name it downloads as. Without this it uses the upload's original name. */
|
|
392
762
|
filename?: string;
|
|
763
|
+
/**
|
|
764
|
+
* A private download that failed: `token_unavailable` right away when the viewer token couldn't be issued
|
|
765
|
+
* (`useDevultur().retryToken()` tries again), `http_error` when the delivery refused it.
|
|
766
|
+
*/
|
|
767
|
+
onDownloadError?: (error: MediaFetchError) => void;
|
|
393
768
|
children: React.ReactNode;
|
|
394
769
|
}
|
|
395
770
|
/**
|
|
@@ -400,7 +775,7 @@ interface DownloadLinkProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorEl
|
|
|
400
775
|
* binding the gate gives a 401. So, for private media, we intercept the click, blob-fetch with the header
|
|
401
776
|
* (like private `<Image>`) and trigger the download from the object URL. Public keeps native navigation.
|
|
402
777
|
*/
|
|
403
|
-
declare function DownloadLink({ media, filename, children, ...anchorProps }: DownloadLinkProps): React.JSX.Element | null;
|
|
778
|
+
declare function DownloadLink({ media, filename, onDownloadError, children, ...anchorProps }: DownloadLinkProps): React.JSX.Element | null;
|
|
404
779
|
interface MediaStatusReturn {
|
|
405
780
|
status: MediaStatusValue;
|
|
406
781
|
/** Typed progress: `phase` is the pipeline step (no `as any`). */
|
|
@@ -494,4 +869,4 @@ interface UseMediaUploadReturn {
|
|
|
494
869
|
*/
|
|
495
870
|
declare function useMediaUpload(options?: UseMediaUploadOptions): UseMediaUploadReturn;
|
|
496
871
|
|
|
497
|
-
export { type CaptionTrack, CropUpload, type CropUploadLabels, type CropUploadProps, type CropUploadRenderProps, DevulturProvider, DownloadLink, Image, MediaFetchError, type MediaFetchErrorCode, type MediaObjectUrl, type PdfPreviewConfig, PdfPreviewProvider, PdfThumbnail, type PdfThumbnailProps, PdfjsLoader, Preview, type PreviewKind, type PreviewLabels, type PreviewProps, type UploadedMedia, type UseMediaObjectUrlOptions, type UseMediaUploadOptions, type UseMediaUploadReturn, type VideoProps, type VideoState, type ViewerTokenArgs, type ViewerTokenResult, defaultPreviewLabels, useDevultur, useDevulturMedia, useDevulturProgress, useMediaObjectUrl, useMediaUpload, useMediaUrl, useVideoProps, useVideoState };
|
|
872
|
+
export { AttachmentCard, type AttachmentCardProps, AttachmentLabels, type CaptionTrack, CropUpload, type CropUploadLabels, type CropUploadProps, type CropUploadRenderProps, type DevulturApi, type DevulturCapability, DevulturCapabilityError, DevulturProvider, DevulturViewerProvider, DocumentLink, type DocumentLinkProps, DownloadLink, Image, type ImageProps, MediaFetchError, type MediaFetchErrorCode, MediaLibrary, type MediaLibraryItemState, MediaLibraryLabels, type MediaLibraryPart, type MediaLibraryProps, type MediaLibraryState, type MediaLibraryStatus, type MediaObjectUrl, MediaPicker, MediaPickerLabels, type MediaPickerLibraryProps, type MediaPickerProps, type MediaPickerSelectionProps, type MediaPickerState, type MediaPickerUpload$1 as MediaPickerUpload, type MediaPickerUploadProps, type MediaPickerUploads, type PdfPreviewConfig, PdfPreviewProvider, PdfThumbnail, type PdfThumbnailProps, PdfjsLoader, Preview, type PreviewKind, type PreviewLabels, type PreviewProps, type TokenStatus, type UploadedMedia, type UseMediaLibraryOptions, type UseMediaObjectUrlOptions, type UseMediaUploadOptions, type UseMediaUploadReturn, type VideoProps, type VideoState, type ViewerTokenArgs, type ViewerTokenResult, defaultPreviewLabels, matchesAccept, useDevultur, useDevulturApi, useDevulturMedia, useDevulturProgress, useMediaLibrary, useMediaObjectUrl, useMediaPicker, useMediaUpload, useMediaUrl, useVideoProps, useVideoState };
|