@urbicon-ui/blocks 6.35.0 → 6.37.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.
Files changed (124) hide show
  1. package/dist/components/Chat/Chat/Chat.svelte +53 -0
  2. package/dist/components/Chat/Chat/Chat.svelte.d.ts +4 -0
  3. package/dist/components/Chat/Chat/chat.variants.d.ts +20 -0
  4. package/dist/components/Chat/Chat/chat.variants.js +15 -0
  5. package/dist/components/Chat/Chat/index.d.ts +47 -0
  6. package/dist/components/Chat/Chat/index.js +2 -0
  7. package/dist/components/Chat/ChatMessage/ChatMessage.svelte +342 -0
  8. package/dist/components/Chat/ChatMessage/ChatMessage.svelte.d.ts +4 -0
  9. package/dist/components/Chat/ChatMessage/chat-message.variants.d.ts +138 -0
  10. package/dist/components/Chat/ChatMessage/chat-message.variants.js +118 -0
  11. package/dist/components/Chat/ChatMessage/index.d.ts +102 -0
  12. package/dist/components/Chat/ChatMessage/index.js +2 -0
  13. package/dist/components/Chat/ChatMessageList/ChatMessageList.svelte +301 -0
  14. package/dist/components/Chat/ChatMessageList/ChatMessageList.svelte.d.ts +6 -0
  15. package/dist/components/Chat/ChatMessageList/chat-message-list.variants.d.ts +23 -0
  16. package/dist/components/Chat/ChatMessageList/chat-message-list.variants.js +32 -0
  17. package/dist/components/Chat/ChatMessageList/chat-scroll.d.ts +45 -0
  18. package/dist/components/Chat/ChatMessageList/chat-scroll.js +52 -0
  19. package/dist/components/Chat/ChatMessageList/index.d.ts +93 -0
  20. package/dist/components/Chat/ChatMessageList/index.js +3 -0
  21. package/dist/components/Chat/CitationChip/CitationChip.svelte +107 -0
  22. package/dist/components/Chat/CitationChip/CitationChip.svelte.d.ts +4 -0
  23. package/dist/components/Chat/CitationChip/citation-chip.variants.d.ts +40 -0
  24. package/dist/components/Chat/CitationChip/citation-chip.variants.js +42 -0
  25. package/dist/components/Chat/CitationChip/index.d.ts +69 -0
  26. package/dist/components/Chat/CitationChip/index.js +2 -0
  27. package/dist/components/Chat/CodeBlock/CodeBlock.svelte +120 -0
  28. package/dist/components/Chat/CodeBlock/CodeBlock.svelte.d.ts +4 -0
  29. package/dist/components/Chat/CodeBlock/code-block.variants.d.ts +40 -0
  30. package/dist/components/Chat/CodeBlock/code-block.variants.js +51 -0
  31. package/dist/components/Chat/CodeBlock/index.d.ts +55 -0
  32. package/dist/components/Chat/CodeBlock/index.js +2 -0
  33. package/dist/components/Chat/PromptInput/PromptInput.svelte +432 -0
  34. package/dist/components/Chat/PromptInput/PromptInput.svelte.d.ts +4 -0
  35. package/dist/components/Chat/PromptInput/index.d.ts +165 -0
  36. package/dist/components/Chat/PromptInput/index.js +2 -0
  37. package/dist/components/Chat/PromptInput/prompt-input.variants.d.ts +90 -0
  38. package/dist/components/Chat/PromptInput/prompt-input.variants.js +102 -0
  39. package/dist/components/Chat/ReasoningDisclosure/ReasoningDisclosure.svelte +107 -0
  40. package/dist/components/Chat/ReasoningDisclosure/ReasoningDisclosure.svelte.d.ts +4 -0
  41. package/dist/components/Chat/ReasoningDisclosure/index.d.ts +85 -0
  42. package/dist/components/Chat/ReasoningDisclosure/index.js +2 -0
  43. package/dist/components/Chat/ReasoningDisclosure/reasoning-disclosure.variants.d.ts +20 -0
  44. package/dist/components/Chat/ReasoningDisclosure/reasoning-disclosure.variants.js +31 -0
  45. package/dist/components/Chat/StreamingMarkdown/MdBlock.svelte +99 -0
  46. package/dist/components/Chat/StreamingMarkdown/MdBlock.svelte.d.ts +9 -0
  47. package/dist/components/Chat/StreamingMarkdown/MdInline.svelte +82 -0
  48. package/dist/components/Chat/StreamingMarkdown/MdInline.svelte.d.ts +9 -0
  49. package/dist/components/Chat/StreamingMarkdown/StreamingMarkdown.svelte +118 -0
  50. package/dist/components/Chat/StreamingMarkdown/StreamingMarkdown.svelte.d.ts +4 -0
  51. package/dist/components/Chat/StreamingMarkdown/index.d.ts +86 -0
  52. package/dist/components/Chat/StreamingMarkdown/index.js +2 -0
  53. package/dist/components/Chat/StreamingMarkdown/md-context.d.ts +58 -0
  54. package/dist/components/Chat/StreamingMarkdown/md-context.js +1 -0
  55. package/dist/components/Chat/StreamingMarkdown/streaming-markdown.variants.d.ts +145 -0
  56. package/dist/components/Chat/StreamingMarkdown/streaming-markdown.variants.js +73 -0
  57. package/dist/components/Chat/ToolCallCard/ToolCallCard.svelte +174 -0
  58. package/dist/components/Chat/ToolCallCard/ToolCallCard.svelte.d.ts +4 -0
  59. package/dist/components/Chat/ToolCallCard/index.d.ts +84 -0
  60. package/dist/components/Chat/ToolCallCard/index.js +2 -0
  61. package/dist/components/Chat/ToolCallCard/tool-call-card.variants.d.ts +38 -0
  62. package/dist/components/Chat/ToolCallCard/tool-call-card.variants.js +38 -0
  63. package/dist/components/Chat/chat.types.d.ts +82 -0
  64. package/dist/components/Chat/chat.types.js +7 -0
  65. package/dist/components/Chat/index.d.ts +22 -0
  66. package/dist/components/Chat/index.js +14 -0
  67. package/dist/components/Chat/markdown/blocks.d.ts +54 -0
  68. package/dist/components/Chat/markdown/blocks.js +462 -0
  69. package/dist/components/Chat/markdown/inline.d.ts +31 -0
  70. package/dist/components/Chat/markdown/inline.js +446 -0
  71. package/dist/components/Chat/markdown/repair.d.ts +23 -0
  72. package/dist/components/Chat/markdown/repair.js +337 -0
  73. package/dist/components/Chat/markdown/streaming-harness.d.ts +23 -0
  74. package/dist/components/Chat/markdown/streaming-harness.js +62 -0
  75. package/dist/components/Chat/markdown/types.d.ts +139 -0
  76. package/dist/components/Chat/markdown/types.js +13 -0
  77. package/dist/components/Chat/markdown/url-policy.d.ts +33 -0
  78. package/dist/components/Chat/markdown/url-policy.js +109 -0
  79. package/dist/components/FileUpload/FileUpload.svelte +35 -123
  80. package/dist/components/FileUpload/FileUpload.svelte.d.ts +1 -1
  81. package/dist/components/FileUpload/index.d.ts +2 -28
  82. package/dist/components/PinInput/PinInput.svelte +321 -0
  83. package/dist/components/PinInput/PinInput.svelte.d.ts +4 -0
  84. package/dist/components/PinInput/index.d.ts +98 -0
  85. package/dist/components/PinInput/index.js +2 -0
  86. package/dist/components/PinInput/pin-input.variants.d.ts +96 -0
  87. package/dist/components/PinInput/pin-input.variants.js +111 -0
  88. package/dist/components/QRCode/QRCode.svelte +107 -0
  89. package/dist/components/QRCode/QRCode.svelte.d.ts +4 -0
  90. package/dist/components/QRCode/index.d.ts +74 -0
  91. package/dist/components/QRCode/index.js +3 -0
  92. package/dist/components/QRCode/qr-code.variants.d.ts +25 -0
  93. package/dist/components/QRCode/qr-code.variants.js +24 -0
  94. package/dist/components/QRCode/qr-encode.d.ts +22 -0
  95. package/dist/components/QRCode/qr-encode.js +528 -0
  96. package/dist/components/TimeInput/TimeInput.svelte +521 -0
  97. package/dist/components/TimeInput/TimeInput.svelte.d.ts +4 -0
  98. package/dist/components/TimeInput/index.d.ts +93 -0
  99. package/dist/components/TimeInput/index.js +2 -0
  100. package/dist/components/TimeInput/time-input.variants.d.ts +131 -0
  101. package/dist/components/TimeInput/time-input.variants.js +120 -0
  102. package/dist/components/index.d.ts +7 -0
  103. package/dist/components/index.js +4 -0
  104. package/dist/i18n/index.d.ts +18 -0
  105. package/dist/primitives/Collapsible/Collapsible.svelte +5 -0
  106. package/dist/primitives/SplitPane/SplitPane.svelte +293 -0
  107. package/dist/primitives/SplitPane/SplitPane.svelte.d.ts +4 -0
  108. package/dist/primitives/SplitPane/index.d.ts +88 -0
  109. package/dist/primitives/SplitPane/index.js +2 -0
  110. package/dist/primitives/SplitPane/split-pane.utils.d.ts +73 -0
  111. package/dist/primitives/SplitPane/split-pane.utils.js +94 -0
  112. package/dist/primitives/SplitPane/split-pane.variants.d.ts +40 -0
  113. package/dist/primitives/SplitPane/split-pane.variants.js +56 -0
  114. package/dist/primitives/index.d.ts +2 -0
  115. package/dist/primitives/index.js +1 -0
  116. package/dist/translations/de.d.ts +6 -0
  117. package/dist/translations/de.js +6 -0
  118. package/dist/translations/en.d.ts +6 -0
  119. package/dist/translations/en.js +6 -0
  120. package/dist/utils/file-intake.d.ts +78 -0
  121. package/dist/utils/file-intake.js +144 -0
  122. package/dist/utils/index.d.ts +1 -0
  123. package/dist/utils/index.js +1 -0
  124. package/package.json +3 -3
@@ -0,0 +1,109 @@
1
+ /**
2
+ * URL policy enforcement (decision A4 — strict by default).
3
+ *
4
+ * LLM output is untrusted input: prompt-injected markdown links/images are a
5
+ * proven data-exfiltration channel (query-param payloads to attacker hosts)
6
+ * even without any script execution. Policy therefore runs on every URL the
7
+ * parser emits, and blocked URLs never reach the produced node tree — a
8
+ * blocked link/image carries `blocked: true` and an empty href/src.
9
+ *
10
+ * Checks run against the *normalized* absolute URL (WHATWG `URL`), so scheme
11
+ * tricks (`JaVaScRiPt:`, embedded tabs/newlines, `https:\\host`, `/../`
12
+ * path escapes against a prefix) are neutralized before matching.
13
+ */
14
+ export const DEFAULT_LINK_PROTOCOLS = ['http:', 'https:', 'mailto:', 'tel:'];
15
+ /** Placeholder base — only used to detect whether a URL is relative. */
16
+ const RELATIVE_PROBE_BASE = 'https://relative-probe.invalid/';
17
+ /**
18
+ * Strip ASCII tab/newline/CR and C0 controls anywhere in the string (the URL
19
+ * standard removes tab/NL/CR during parsing, so leaving them in would let
20
+ * `java\tscript:` sneak past a naive scheme check while browsers still
21
+ * execute it) and trim outer whitespace.
22
+ */
23
+ function cleanRawUrl(raw) {
24
+ let out = '';
25
+ for (const ch of raw.trim()) {
26
+ const code = ch.charCodeAt(0);
27
+ if (code > 0x1f)
28
+ out += ch;
29
+ }
30
+ return out;
31
+ }
32
+ function resolve(raw) {
33
+ const cleaned = cleanRawUrl(raw);
34
+ if (cleaned.length === 0)
35
+ return { invalid: true };
36
+ // Protocol-relative URLs (`//host/…`) are absolute in effect; resolving
37
+ // them against the probe base would otherwise mislabel them as relative.
38
+ const protocolRelative = cleaned.startsWith('//');
39
+ try {
40
+ const url = new URL(protocolRelative ? `https:${cleaned}` : cleaned);
41
+ return { absolute: true, url };
42
+ }
43
+ catch {
44
+ // Not parseable standalone → candidate for a relative reference.
45
+ }
46
+ try {
47
+ new URL(cleaned, RELATIVE_PROBE_BASE);
48
+ return { absolute: false, cleaned };
49
+ }
50
+ catch {
51
+ return { invalid: true };
52
+ }
53
+ }
54
+ const BLOCKED = { ok: false };
55
+ /**
56
+ * Check a link destination. Relative references are always allowed; absolute
57
+ * URLs must carry an allowed protocol.
58
+ */
59
+ export function checkLinkUrl(raw, policy) {
60
+ const resolved = resolve(raw);
61
+ if ('invalid' in resolved && resolved.invalid)
62
+ return blocked('link', raw, policy);
63
+ if (!resolved.absolute)
64
+ return { ok: true, href: resolved.cleaned };
65
+ const allowed = (policy?.allowedLinkProtocols ?? DEFAULT_LINK_PROTOCOLS).map((p) => p.toLowerCase());
66
+ if (allowed.includes(resolved.url.protocol))
67
+ return { ok: true, href: resolved.url.href };
68
+ return blocked('link', raw, policy);
69
+ }
70
+ /**
71
+ * Check an image source. Relative references are allowed (same-origin is not
72
+ * an exfiltration sink); absolute URLs must match an allowlisted prefix on
73
+ * the normalized href. The default empty allowlist blocks every external
74
+ * image — the CamoLeak lesson, and the posture ChatGPT/Copilot converged on.
75
+ */
76
+ export function checkImageUrl(raw, policy) {
77
+ const resolved = resolve(raw);
78
+ if ('invalid' in resolved && resolved.invalid)
79
+ return blocked('image', raw, policy);
80
+ if (!resolved.absolute)
81
+ return { ok: true, href: resolved.cleaned };
82
+ const prefixes = policy?.allowedImagePrefixes ?? [];
83
+ const href = resolved.url.href;
84
+ for (const prefix of prefixes) {
85
+ if (href.startsWith(normalizePrefix(prefix)))
86
+ return { ok: true, href };
87
+ }
88
+ return blocked('image', raw, policy);
89
+ }
90
+ /**
91
+ * Normalize an allowlist prefix the same way hrefs are normalized (lowercased
92
+ * scheme/host, resolved path) so `HTTPS://Example.com/img/` still matches.
93
+ * A bare-origin prefix gains its trailing slash (`https://cdn.example.com` →
94
+ * `…com/`), which pins it to that origin — without it, `startsWith` would
95
+ * also match `https://cdn.example.com.evil.com/…`. Prefixes that are not
96
+ * full URLs (e.g. `data:`) are kept verbatim.
97
+ */
98
+ function normalizePrefix(prefix) {
99
+ try {
100
+ return new URL(prefix).href;
101
+ }
102
+ catch {
103
+ return prefix;
104
+ }
105
+ }
106
+ function blocked(kind, raw, policy) {
107
+ policy?.onBlocked?.(kind, raw);
108
+ return BLOCKED;
109
+ }
@@ -1,12 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { useBlocksI18n } from '../..';
3
- import type {
4
- FileUploadProps,
5
- FileUploadFile,
6
- FileRejection,
7
- FileUploadError,
8
- FileUploadSlotName
9
- } from './index';
3
+ import type { FileUploadProps, FileUploadFile, FileUploadSlotName } from './index';
10
4
  import { fileUploadVariants, type FileUploadVariants } from './fileUpload.variants';
11
5
  import { getBlocksConfig, resolveSlotClasses } from '../../provider';
12
6
  import { resolveIcon } from '../../icons';
@@ -22,6 +16,15 @@
22
16
  import { fly } from 'svelte/transition';
23
17
  import { quintOut } from 'svelte/easing';
24
18
  import { onDestroy } from 'svelte';
19
+ import {
20
+ createIntakeEntry,
21
+ dragItemsMatchAccept,
22
+ formatFileSize,
23
+ partitionIntake,
24
+ revokeIntakePreviews,
25
+ type FileIntakeConstraints,
26
+ type FileIntakeMessages
27
+ } from '../../utils/file-intake';
25
28
 
26
29
  const bt = useBlocksI18n();
27
30
 
@@ -116,54 +119,27 @@
116
119
 
117
120
  // ── Validation ─────────────────────────────────────────────────────────────
118
121
 
119
- function validateFile(file: File): FileUploadError[] {
120
- const errors: FileUploadError[] = [];
121
-
122
- if (accept) {
123
- const types = Array.isArray(accept) ? accept : accept.split(',').map((t) => t.trim());
124
- const matches = types.some((type) => {
125
- if (type.startsWith('.')) return file.name.toLowerCase().endsWith(type.toLowerCase());
126
- if (type.endsWith('/*')) return file.type.startsWith(type.replace('/*', '/'));
127
- return file.type === type;
128
- });
129
- if (!matches) {
130
- errors.push({
131
- code: 'FILE_INVALID_TYPE',
132
- message: bt('fileUpload.invalidType', { type: file.type || 'unknown' })
133
- });
134
- }
135
- }
136
-
137
- if (file.size > maxFileSize) {
138
- errors.push({
139
- code: 'FILE_TOO_LARGE',
140
- message: bt('fileUpload.tooLarge', { size: formatFileSize(maxFileSize) })
141
- });
142
- }
143
-
144
- if (file.size < minFileSize) {
145
- errors.push({
146
- code: 'FILE_TOO_SMALL',
147
- message: bt('fileUpload.tooSmall', { size: formatFileSize(minFileSize) })
148
- });
149
- }
150
-
151
- if (files.some((f) => f.file.name === file.name && f.file.size === file.size)) {
152
- errors.push({ code: 'FILE_EXISTS', message: bt('fileUpload.exists') });
153
- }
154
-
155
- if (validate) {
156
- const custom = validate(file);
157
- if (custom) errors.push(...custom);
158
- }
159
-
160
- return errors;
161
- }
122
+ // Error texts wired from the component's i18n source; injected into the
123
+ // shared file-intake core so its pure functions stay label-agnostic. Texts
124
+ // are identical to the pre-refactor inline `bt('fileUpload.*')` calls.
125
+ const messages: FileIntakeMessages = {
126
+ invalidType: (type) => bt('fileUpload.invalidType', { type }),
127
+ tooLarge: (size) => bt('fileUpload.tooLarge', { size }),
128
+ tooSmall: (size) => bt('fileUpload.tooSmall', { size }),
129
+ exists: () => bt('fileUpload.exists'),
130
+ tooMany: (count) => bt('fileUpload.tooMany', { count: String(count) })
131
+ };
132
+
133
+ const constraints = $derived<FileIntakeConstraints>({
134
+ accept,
135
+ maxFiles,
136
+ maxFileSize,
137
+ minFileSize,
138
+ validate
139
+ });
162
140
 
163
141
  // ── File Processing ────────────────────────────────────────────────────────
164
142
 
165
- let idCounter = 0;
166
-
167
143
  // Two-way sync between `files[0]` and the convenience `file` binding.
168
144
  // `lastSyncedFile` is the snapshot we last wrote to `file` — comparing
169
145
  // against it lets us tell whether the change came from `files` (internal,
@@ -194,9 +170,7 @@
194
170
  if (file === lastSyncedFile) return;
195
171
 
196
172
  if (file === null) {
197
- for (const entry of files) {
198
- if (entry.preview) URL.revokeObjectURL(entry.preview);
199
- }
173
+ revokeIntakePreviews(files);
200
174
  files = [];
201
175
  lastSyncedFile = null;
202
176
  onFilesChange?.(files);
@@ -204,15 +178,8 @@
204
178
  }
205
179
 
206
180
  const old = files[0];
207
- if (old?.preview) URL.revokeObjectURL(old.preview);
208
- const replacement: FileUploadFile = {
209
- id: `file-${Date.now()}-${++idCounter}`,
210
- file,
211
- status: 'pending',
212
- errors: [],
213
- preview: isImageFile(file) ? URL.createObjectURL(file) : undefined
214
- };
215
- files = [replacement];
181
+ if (old) revokeIntakePreviews([old]);
182
+ files = [createIntakeEntry(file)];
216
183
  lastSyncedFile = file;
217
184
  onFilesChange?.(files);
218
185
  });
@@ -220,36 +187,7 @@
220
187
  function processFiles(incoming: File[]) {
221
188
  if (disabled) return;
222
189
 
223
- const accepted: FileUploadFile[] = [];
224
- const rejected: FileRejection[] = [];
225
-
226
- const remaining = maxFiles - files.length;
227
- const toProcess = incoming.slice(0, remaining);
228
- const excess = incoming.slice(remaining);
229
-
230
- for (const file of excess) {
231
- rejected.push({
232
- file,
233
- errors: [
234
- { code: 'TOO_MANY_FILES', message: bt('fileUpload.tooMany', { count: String(maxFiles) }) }
235
- ]
236
- });
237
- }
238
-
239
- for (const file of toProcess) {
240
- const errors = validateFile(file);
241
- if (errors.length > 0) {
242
- rejected.push({ file, errors });
243
- } else {
244
- accepted.push({
245
- id: `file-${Date.now()}-${++idCounter}`,
246
- file,
247
- status: 'pending',
248
- errors: [],
249
- preview: isImageFile(file) ? URL.createObjectURL(file) : undefined
250
- });
251
- }
252
- }
190
+ const { accepted, rejected } = partitionIntake(incoming, files, constraints, messages);
253
191
 
254
192
  if (accepted.length > 0) {
255
193
  files = [...files, ...accepted];
@@ -263,16 +201,14 @@
263
201
  }
264
202
 
265
203
  function removeFile(entry: FileUploadFile) {
266
- if (entry.preview) URL.revokeObjectURL(entry.preview);
204
+ revokeIntakePreviews([entry]);
267
205
  files = files.filter((f) => f.id !== entry.id);
268
206
  onFileRemove?.(entry);
269
207
  onFilesChange?.(files);
270
208
  }
271
209
 
272
210
  onDestroy(() => {
273
- for (const entry of files) {
274
- if (entry.preview) URL.revokeObjectURL(entry.preview);
275
- }
211
+ revokeIntakePreviews(files);
276
212
  });
277
213
 
278
214
  // ── Drag Handlers ──────────────────────────────────────────────────────────
@@ -285,16 +221,7 @@
285
221
  dragging = true;
286
222
 
287
223
  if (accept && e.dataTransfer?.items?.length) {
288
- const types = Array.isArray(accept) ? accept : accept.split(',').map((t) => t.trim());
289
- const hasInvalid = Array.from(e.dataTransfer.items).some((item) => {
290
- if (item.kind !== 'file') return true;
291
- return !types.some((type) => {
292
- if (type.endsWith('/*')) return item.type.startsWith(type.replace('/*', '/'));
293
- if (type.startsWith('.')) return true;
294
- return item.type === type;
295
- });
296
- });
297
- dragInvalid = hasInvalid;
224
+ dragInvalid = !dragItemsMatchAccept(e.dataTransfer.items, accept);
298
225
  }
299
226
  }
300
227
 
@@ -370,21 +297,6 @@
370
297
  };
371
298
  });
372
299
 
373
- // ── Helpers ────────────────────────────────────────────────────────────────
374
-
375
- function formatFileSize(bytes: number): string {
376
- if (bytes === 0) return '0 B';
377
- if (!isFinite(bytes)) return '';
378
- const k = 1024;
379
- const sizes = ['B', 'KB', 'MB', 'GB'];
380
- const i = Math.floor(Math.log(bytes) / Math.log(k));
381
- return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
382
- }
383
-
384
- function isImageFile(file: File): boolean {
385
- return file.type.startsWith('image/');
386
- }
387
-
388
300
  // ── Mint ─────────────────────────────────────────────────────────────────
389
301
 
390
302
  $effect(() => {
@@ -1,4 +1,4 @@
1
1
  import type { FileUploadProps } from './index.js';
2
- declare const FileUpload: import("svelte").Component<FileUploadProps, {}, "files" | "file">;
2
+ declare const FileUpload: import("svelte").Component<FileUploadProps, {}, "file" | "files">;
3
3
  type FileUpload = ReturnType<typeof FileUpload>;
4
4
  export default FileUpload;
@@ -2,34 +2,8 @@ import type { Snippet } from 'svelte';
2
2
  import type { HTMLAttributes } from 'svelte/elements';
3
3
  import type { MintProp } from '../../mint/index.js';
4
4
  import type { FileUploadSlots, FileUploadVariants } from './fileUpload.variants.js';
5
- export type FileUploadErrorCode = 'FILE_INVALID_TYPE' | 'FILE_TOO_LARGE' | 'FILE_TOO_SMALL' | 'TOO_MANY_FILES' | 'FILE_EXISTS' | 'CUSTOM';
6
- export interface FileUploadError {
7
- /** Machine-readable error code. */
8
- code: FileUploadErrorCode;
9
- /** Human-readable error message. */
10
- message: string;
11
- }
12
- export type FileUploadStatus = 'pending' | 'uploading' | 'complete' | 'error';
13
- export interface FileUploadFile {
14
- /** Unique identifier for this file entry. */
15
- id: string;
16
- /** The native File object. */
17
- file: File;
18
- /** Object URL for image previews (auto-generated, auto-revoked). */
19
- preview?: string;
20
- /** Upload progress 0–100. Undefined when not tracking. */
21
- progress?: number;
22
- /** Current lifecycle status. */
23
- status: FileUploadStatus;
24
- /** Validation or upload errors. */
25
- errors: FileUploadError[];
26
- }
27
- export interface FileRejection {
28
- /** The rejected file. */
29
- file: File;
30
- /** Why it was rejected. */
31
- errors: FileUploadError[];
32
- }
5
+ import type { FileIntakeRejection as FileRejection, FileIntakeError as FileUploadError, FileIntakeErrorCode as FileUploadErrorCode, FileIntakeEntry as FileUploadFile, FileIntakeStatus as FileUploadStatus } from '../../utils/file-intake.js';
6
+ export type { FileRejection, FileUploadError, FileUploadErrorCode, FileUploadFile, FileUploadStatus };
33
7
  export declare const IMAGE_MIME_TYPES: string[];
34
8
  export declare const PDF_MIME_TYPE: string[];
35
9
  export declare const VIDEO_MIME_TYPES: string[];