@devultur/convex 1.3.1 → 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 +462 -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 +462 -64
- package/dist/react.js +1625 -493
- package/dist/types-LrusGVDf.d.ts +62 -0
- package/dist/validators.d.ts +13 -1
- package/dist/validators.js +1 -1
- package/package.json +8 -4
package/dist/react.d.ts
CHANGED
|
@@ -1,10 +1,89 @@
|
|
|
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
|
-
import {
|
|
7
|
-
|
|
6
|
+
import { Value } from 'convex/values';
|
|
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
|
+
}
|
|
33
|
+
|
|
34
|
+
/** What a viewer token action returns: the token with its lifetime, or the bare token (default lifetime). */
|
|
35
|
+
type ViewerTokenResult = {
|
|
36
|
+
token: string;
|
|
37
|
+
expiresIn: number;
|
|
38
|
+
} | string;
|
|
39
|
+
/** Extra arguments sent with `sessionSecret` to the viewer token action. */
|
|
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
|
+
}
|
|
8
87
|
|
|
9
88
|
interface CropUploadRenderProps {
|
|
10
89
|
/** The state machine of the full cycle (idle → uploading → ready / failed). */
|
|
@@ -53,22 +132,147 @@ interface CropUploadProps {
|
|
|
53
132
|
*/
|
|
54
133
|
declare function CropUpload({ aspectRatio, visibility, outputFormat, maxWidth, minSourceWidth, replaces, onComplete, onReject, accept, cropperClassName, labels, children, }: CropUploadProps): React.JSX.Element;
|
|
55
134
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
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;
|
|
71
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;
|
|
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;
|
|
72
276
|
|
|
73
277
|
interface UseMediaObjectUrlOptions {
|
|
74
278
|
/** `false` → nothing is fetched (e.g. a list row that isn't selected). Default `true`. */
|
|
@@ -156,6 +360,153 @@ declare function PdfPreviewProvider({ pdfjs, workerSrc, labels, children, }: Pdf
|
|
|
156
360
|
children: React.ReactNode;
|
|
157
361
|
}): React.JSX.Element;
|
|
158
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
|
+
|
|
159
510
|
interface PdfThumbnailProps {
|
|
160
511
|
/** Typed reference. `null`/`undefined` → renders nothing. */
|
|
161
512
|
media: DevulturMedia | null | undefined;
|
|
@@ -198,7 +549,8 @@ interface PreviewProps {
|
|
|
198
549
|
/**
|
|
199
550
|
* Shown for types that don't preview inline and when the fetch fails. Default: a `<DownloadLink>`.
|
|
200
551
|
* As a function it receives why: a `MediaFetchError` when the fetch was refused (`http_error`, `too_large`,
|
|
201
|
-
* `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
|
|
202
554
|
* (a network failure, a PDF pdf.js can't open, or the link after the `maxPages` note).
|
|
203
555
|
*/
|
|
204
556
|
fallback?: React.ReactNode | ((error: MediaFetchError | null) => React.ReactNode);
|
|
@@ -231,8 +583,40 @@ declare function Preview({ media, contentType, fallback, loading, labels, ...vie
|
|
|
231
583
|
/** How a content type renders inline: `<img>`, a PDF view (pdf.js canvases or `<iframe>`), `<audio>` or `<pre>`. */
|
|
232
584
|
type PreviewKind = "image" | "pdf" | "audio" | "text";
|
|
233
585
|
|
|
234
|
-
|
|
235
|
-
|
|
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
|
+
|
|
236
620
|
type AnyAction = FunctionReference<"action">;
|
|
237
621
|
type AnyMutation = FunctionReference<"mutation">;
|
|
238
622
|
type AnyQuery = FunctionReference<"query">;
|
|
@@ -247,6 +631,10 @@ interface DevulturApi {
|
|
|
247
631
|
/** Requests the transcode of an uploaded video. Required by `useMediaUpload` for auto-process. */
|
|
248
632
|
processVideo?: AnyAction;
|
|
249
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;
|
|
250
638
|
saveProgress?: AnyMutation;
|
|
251
639
|
loadProgress?: AnyQuery;
|
|
252
640
|
markComplete?: AnyMutation;
|
|
@@ -259,6 +647,8 @@ interface UploadOptions {
|
|
|
259
647
|
onProgress?: (progress: UploadProgress) => void;
|
|
260
648
|
/** Aborts the PUT → `upload()` rejects with an `AbortError`. */
|
|
261
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;
|
|
262
652
|
}
|
|
263
653
|
/**
|
|
264
654
|
* The reference `upload()` resolves to: a `DevulturMedia` whose `key` is always set (the uploaded object's key; a
|
|
@@ -267,29 +657,19 @@ interface UploadOptions {
|
|
|
267
657
|
type UploadedMedia = DevulturMedia & {
|
|
268
658
|
readonly key: string;
|
|
269
659
|
};
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
660
|
+
/**
|
|
661
|
+
* What `useDevultur()` returns. Under a `<DevulturViewerProvider>`, `uploadUrl`, `upload` and `deleteMedia` throw a
|
|
662
|
+
* `DevulturCapabilityError` (`capability_unavailable`).
|
|
663
|
+
*/
|
|
664
|
+
interface DevulturContextValue extends MediaSession {
|
|
275
665
|
uploadUrl: (file: File) => Promise<{
|
|
276
666
|
url: string;
|
|
277
667
|
key: string;
|
|
278
668
|
}>;
|
|
279
669
|
/** Uploads a file (reporting progress), records it in the component, and returns the reference ready to save. */
|
|
280
670
|
upload: (file: File, options?: UploadOptions) => Promise<UploadedMedia>;
|
|
281
|
-
/** Delivery URL from a reference (non-hook → usable in handlers and `.map`). Token-transparent. */
|
|
282
|
-
url: (media: DevulturMedia, options?: MediaRenderOptions) => string;
|
|
283
|
-
/** Downloads a video's subtitle text for a locale (auth-transparent). */
|
|
284
|
-
getCaptionsText: (media: DevulturMedia, locale: string) => Promise<string>;
|
|
285
671
|
/** Deletes a media by reference: video → full folder; image/file → the object. */
|
|
286
672
|
deleteMedia: (media: DevulturMedia) => void;
|
|
287
|
-
/**
|
|
288
|
-
* Re-issues the viewer token (new session fingerprint with the current UA/IP) and updates the context.
|
|
289
|
-
* Single-flight: concurrent calls share the same issuance. Returns the new token (or null if it
|
|
290
|
-
* failed). The render uses it to transparently recover from a 401 `session_mismatch`.
|
|
291
|
-
*/
|
|
292
|
-
reissueToken: () => Promise<string | null>;
|
|
293
673
|
}
|
|
294
674
|
interface ProgressContextValue {
|
|
295
675
|
save: (videoId: string, position: number) => Promise<void>;
|
|
@@ -304,10 +684,48 @@ interface DevulturProviderProps {
|
|
|
304
684
|
api: DevulturApi;
|
|
305
685
|
/** Media worker base (e.g. `https://media.your-domain.com`). Required for `useMediaUrl`. */
|
|
306
686
|
baseUrl?: string;
|
|
687
|
+
/**
|
|
688
|
+
* Extra arguments sent with `sessionSecret` on every viewer token issuance (first, renewal and re-issue), for
|
|
689
|
+
* example `{ workspaceId }`. Compared by value: when they change, the current token is dropped and a new one is
|
|
690
|
+
* issued. The component's own `issueViewerToken` accepts only `sessionSecret`, so pass your own action in
|
|
691
|
+
* `issueViewerToken` that takes these arguments.
|
|
692
|
+
*/
|
|
693
|
+
tokenArgs?: ViewerTokenArgs;
|
|
694
|
+
/**
|
|
695
|
+
* Your own viewer token action, used instead of `api.issueViewerToken`. It receives `{ sessionSecret, ...tokenArgs }`
|
|
696
|
+
* and returns what the component's `issueViewerToken` returns.
|
|
697
|
+
*/
|
|
698
|
+
issueViewerToken?: ViewerTokenAction;
|
|
307
699
|
children: React.ReactNode;
|
|
308
700
|
}
|
|
309
|
-
declare function DevulturProvider({ api, baseUrl, children }: DevulturProviderProps): React.JSX.Element;
|
|
701
|
+
declare function DevulturProvider({ api, baseUrl, tokenArgs, issueViewerToken, children }: DevulturProviderProps): React.JSX.Element;
|
|
310
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;
|
|
311
729
|
declare function useDevulturProgress(): ProgressContextValue;
|
|
312
730
|
/**
|
|
313
731
|
* Ready-to-use delivery URL for a key, with the context's viewer token already injected. The consumer
|
|
@@ -338,35 +756,15 @@ interface VideoProps {
|
|
|
338
756
|
declare function useVideoProps(media: DevulturMedia | null | undefined, options?: {
|
|
339
757
|
locales?: string[];
|
|
340
758
|
}): VideoProps | null;
|
|
341
|
-
interface ImageProps extends Omit<React.ImgHTMLAttributes<HTMLImageElement>, "src" | "width" | "height"> {
|
|
342
|
-
/** Typed reference. `null`/`undefined` → renders `fallback` (or `externalFallback`). */
|
|
343
|
-
media: DevulturMedia | null | undefined;
|
|
344
|
-
width?: number;
|
|
345
|
-
height?: number;
|
|
346
|
-
fit?: MediaUrlOptions["fit"];
|
|
347
|
-
format?: MediaUrlOptions["format"];
|
|
348
|
-
quality?: number;
|
|
349
|
-
/** What to show when there's no media (or it's loading). */
|
|
350
|
-
fallback?: React.ReactNode;
|
|
351
|
-
/** Explicit external URL (e.g. Unsplash) when `media` is null or the load fails. */
|
|
352
|
-
externalFallback?: string;
|
|
353
|
-
/** background-image mode: composes the URL as this element's `background-image` (doesn't force `<img>`). */
|
|
354
|
-
render?: React.ReactElement<{
|
|
355
|
-
style?: React.CSSProperties;
|
|
356
|
-
}>;
|
|
357
|
-
}
|
|
358
|
-
/**
|
|
359
|
-
* Renders any media declaratively: token-transparent, with typed transforms, and works inside a
|
|
360
|
-
* `.map()` (no wrappers or hooks rules on the consumer's side).
|
|
361
|
-
*
|
|
362
|
-
* @example
|
|
363
|
-
* <Image media={course.thumbnail} alt={course.title} width={512} format="webp" fallback={<Placeholder />} />
|
|
364
|
-
*/
|
|
365
|
-
declare function Image({ media, width, height, fit, format, quality, fallback, externalFallback, render, alt, ...imgProps }: ImageProps): React.JSX.Element;
|
|
366
759
|
interface DownloadLinkProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, "href" | "download" | "media"> {
|
|
367
760
|
media: DevulturMedia | null | undefined;
|
|
368
761
|
/** Name it downloads as. Without this it uses the upload's original name. */
|
|
369
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;
|
|
370
768
|
children: React.ReactNode;
|
|
371
769
|
}
|
|
372
770
|
/**
|
|
@@ -377,7 +775,7 @@ interface DownloadLinkProps extends Omit<React.AnchorHTMLAttributes<HTMLAnchorEl
|
|
|
377
775
|
* binding the gate gives a 401. So, for private media, we intercept the click, blob-fetch with the header
|
|
378
776
|
* (like private `<Image>`) and trigger the download from the object URL. Public keeps native navigation.
|
|
379
777
|
*/
|
|
380
|
-
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;
|
|
381
779
|
interface MediaStatusReturn {
|
|
382
780
|
status: MediaStatusValue;
|
|
383
781
|
/** Typed progress: `phase` is the pipeline step (no `as any`). */
|
|
@@ -471,4 +869,4 @@ interface UseMediaUploadReturn {
|
|
|
471
869
|
*/
|
|
472
870
|
declare function useMediaUpload(options?: UseMediaUploadOptions): UseMediaUploadReturn;
|
|
473
871
|
|
|
474
|
-
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, 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 };
|