@calmlens/sdk 0.16.3 → 0.18.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 (114) hide show
  1. package/README.md +425 -181
  2. package/bin/calmlens.js +16016 -0
  3. package/bin/package.json +1 -0
  4. package/cjs/BrowserUpload-BT091eOB.d.ts +11 -0
  5. package/cjs/BrowserUpload-CQwXEGFv.js +10 -0
  6. package/cjs/CalmLensAppClient-CHQGu-Do.js +89 -0
  7. package/cjs/CalmLensAppClient-CV_K26Ce.d.ts +40 -0
  8. package/cjs/CalmLensConnection-B8Bu2j3y.js +659 -0
  9. package/cjs/CalmLensServerClient-C5o2A8MW.js +645 -0
  10. package/cjs/CalmLensServerClient-JtP687a3.d.ts +235 -0
  11. package/cjs/CalmLensTypes-9Vt16pc7.d.ts +40400 -0
  12. package/cjs/Classification-94kSYWZw-CMnQKW13.d.ts +5873 -0
  13. package/cjs/CryptoUtils-B_x8lMIx-YBW1-bvL.js +42 -0
  14. package/cjs/FileIcons-Ob003MdS.js +175 -0
  15. package/cjs/Jurisdiction-FusEXb4U-zVs21tDv.js +91 -0
  16. package/cjs/ModerationContext-9lGm-Mna-CcmbRnOy.d.ts +67 -0
  17. package/cjs/ModerationContextLimits-DelWfmiJ.js +1311 -0
  18. package/cjs/ReactUpload-CAyCsyG6.d.ts +17 -0
  19. package/cjs/ReactUpload-Cfg5JYUq.js +54 -0
  20. package/cjs/TestTriggers-By07LR31-CmK0yTyR.d.ts +271 -0
  21. package/cjs/TestTriggers-DTc_iMJF-BjMPq4_3.js +1327 -0
  22. package/cjs/UploadController-BGO1eyzb.js +618 -0
  23. package/{esm/index-C9Xw1aid.d.ts → cjs/WebhookPayload-2aL31v0J.d.ts} +131 -155
  24. package/cjs/app.d.ts +7 -44
  25. package/cjs/app.js +11 -89
  26. package/cjs/elements.d.ts +88 -0
  27. package/cjs/elements.js +555 -0
  28. package/cjs/file-icons.d.ts +67 -0
  29. package/cjs/file-icons.js +10 -0
  30. package/cjs/index-CI4BzN4W.d.ts +252 -0
  31. package/cjs/index.d.ts +6 -4
  32. package/cjs/index.js +9 -4
  33. package/cjs/react-native.d.ts +56 -0
  34. package/cjs/react-native.js +495 -0
  35. package/cjs/react.d.ts +30 -0
  36. package/cjs/react.js +370 -0
  37. package/cjs/server.d.ts +12 -191
  38. package/cjs/server.js +18 -378
  39. package/cjs/test-inputs.d.ts +2 -2
  40. package/cjs/test-inputs.js +9 -264
  41. package/cjs/testing.d.ts +285 -190
  42. package/cjs/testing.js +2393 -1203
  43. package/cjs/ui-CC1GOoMg.js +583 -0
  44. package/cjs/ui-wIiMfqMB.d.ts +526 -0
  45. package/cjs/ui.d.ts +2 -0
  46. package/cjs/ui.js +27 -0
  47. package/cjs/vue.d.ts +490 -0
  48. package/cjs/vue.js +419 -0
  49. package/esm/BrowserUpload-BT091eOB.d.ts +11 -0
  50. package/esm/BrowserUpload-D2xBWqhm.js +5 -0
  51. package/esm/CalmLensAppClient-CV_K26Ce.d.ts +40 -0
  52. package/esm/CalmLensAppClient-DuFas_dW.js +84 -0
  53. package/esm/CalmLensConnection-MxwwLXdl.js +582 -0
  54. package/esm/CalmLensServerClient-D80_mKpW.js +586 -0
  55. package/esm/CalmLensServerClient-JtP687a3.d.ts +235 -0
  56. package/esm/CalmLensTypes-9Vt16pc7.d.ts +40400 -0
  57. package/esm/Classification-94kSYWZw-CMnQKW13.d.ts +5873 -0
  58. package/esm/CryptoUtils-B_x8lMIx-DhuWGzqn.js +25 -0
  59. package/esm/FileIcons-M6dzjFxd.js +128 -0
  60. package/esm/Jurisdiction-FusEXb4U-1ov6m5yE.js +46 -0
  61. package/esm/ModerationContext-9lGm-Mna-CcmbRnOy.d.ts +67 -0
  62. package/esm/ModerationContextLimits-BaX2QnU8.js +1114 -0
  63. package/esm/ReactUpload-CAyCsyG6.d.ts +17 -0
  64. package/esm/ReactUpload-CL2XC8WS.js +37 -0
  65. package/esm/TestTriggers-By07LR31-CmK0yTyR.d.ts +271 -0
  66. package/esm/TestTriggers-DTc_iMJF-HfB533Gx.js +1267 -0
  67. package/esm/UploadController-qjoYGCwx.js +589 -0
  68. package/{cjs/index-C9Xw1aid.d.ts → esm/WebhookPayload-2aL31v0J.d.ts} +131 -155
  69. package/esm/app.d.ts +7 -44
  70. package/esm/app.js +3 -86
  71. package/esm/elements.d.ts +88 -0
  72. package/esm/elements.js +528 -0
  73. package/esm/file-icons.d.ts +67 -0
  74. package/esm/file-icons.js +1 -0
  75. package/esm/index-CI4BzN4W.d.ts +252 -0
  76. package/esm/index.d.ts +6 -4
  77. package/esm/index.js +1 -1
  78. package/esm/react-native.d.ts +56 -0
  79. package/esm/react-native.js +467 -0
  80. package/esm/react.d.ts +30 -0
  81. package/esm/react.js +343 -0
  82. package/esm/server.d.ts +12 -191
  83. package/esm/server.js +3 -369
  84. package/esm/styles.css +147 -0
  85. package/esm/svelte/CalmLensMedia.svelte +134 -0
  86. package/esm/svelte/CalmLensUploader.svelte +175 -0
  87. package/esm/svelte/Icon.svelte +7 -0
  88. package/esm/svelte/index.d.ts +37 -0
  89. package/esm/svelte/index.js +6 -0
  90. package/esm/test-inputs.d.ts +2 -2
  91. package/esm/test-inputs.js +1 -256
  92. package/esm/testing.d.ts +285 -190
  93. package/esm/testing.js +2329 -1122
  94. package/esm/ui-CCY3yXFn.js +458 -0
  95. package/esm/ui-wIiMfqMB.d.ts +526 -0
  96. package/esm/ui.d.ts +2 -0
  97. package/esm/ui.js +3 -0
  98. package/esm/vue.d.ts +490 -0
  99. package/esm/vue.js +392 -0
  100. package/package.json +118 -13
  101. package/cjs/CalmLensConnection-BNUHp_AQ.js +0 -234
  102. package/cjs/CalmLensUtils-o171ownK.js +0 -699
  103. package/cjs/CalmLensVersion-DwhgxQK5.js +0 -480
  104. package/cjs/CalmLensWebhooks-BKrq30Yp.js +0 -201
  105. package/cjs/Classification-BNhgwGEm-DmA9VEuE.d.ts +0 -4806
  106. package/cjs/TestTriggers-CRKtulyp-vrzEq2wm.d.ts +0 -44
  107. package/cjs/WebhookPayload-CJoIkGBD.d.ts +0 -11753
  108. package/esm/CalmLensConnection-XTqmlwzG.js +0 -193
  109. package/esm/CalmLensUtils-DsF8Aa_x.js +0 -574
  110. package/esm/CalmLensVersion-DcifRKsx.js +0 -415
  111. package/esm/CalmLensWebhooks-BvGyk5d3.js +0 -148
  112. package/esm/Classification-BNhgwGEm-DmA9VEuE.d.ts +0 -4806
  113. package/esm/TestTriggers-CRKtulyp-vrzEq2wm.d.ts +0 -44
  114. package/esm/WebhookPayload-CJoIkGBD.d.ts +0 -11753
@@ -0,0 +1,467 @@
1
+ import { _ as getMediaState, a as getMediaAspectRatio, b as ICONS, c as describeUploadItem, d as formatMessage, f as getDropzoneHint, g as resolveMessages, h as getUploadItemOutcome, i as resolveTheme, l as describeUploader, m as getUploadItemMessage, o as getMediaLoadKey, p as getMediaUnavailableMessage, r as CALMLENS_THEME, s as DEFAULT_MESSAGES, t as CALMLENS_STYLES, u as formatBytes, v as pickMediaSource, x as ICON_ATTRIBUTES, y as resolveMediaProps } from "./ui-CCY3yXFn.js";
2
+ import { i as createProgressFetch, n as createUploadController, r as isFileAccepted, t as UploadController } from "./UploadController-qjoYGCwx.js";
3
+ import { a as getFileIcon, o as getFileIconLabel, t as FILE_ICON_COLORS } from "./FileIcons-M6dzjFxd.js";
4
+ import { n as useOwnController, r as useUploadSnapshot, t as useCalmLensUpload } from "./ReactUpload-CL2XC8WS.js";
5
+ import { useMemo, useState } from "react";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { Image, PixelRatio, Pressable, StyleSheet, Text, View } from "react-native";
8
+ // src/react-native.tsx
9
+ const createUploaderStyles = (theme) => StyleSheet.create({
10
+ uploader: { gap: 12 },
11
+ picker: {
12
+ alignItems: "center",
13
+ gap: 12,
14
+ paddingVertical: 28,
15
+ paddingHorizontal: 20,
16
+ borderWidth: 1.5,
17
+ borderStyle: "dashed",
18
+ borderColor: theme.border,
19
+ borderRadius: theme.radius,
20
+ backgroundColor: theme.surface
21
+ },
22
+ hint: {
23
+ fontSize: 13,
24
+ color: theme.muted
25
+ },
26
+ button: {
27
+ paddingVertical: 8,
28
+ paddingHorizontal: 14,
29
+ borderRadius: 8,
30
+ borderWidth: 1,
31
+ borderColor: theme.accent,
32
+ backgroundColor: theme.accent
33
+ },
34
+ buttonText: {
35
+ fontSize: 14,
36
+ fontWeight: "500",
37
+ color: theme.accentText
38
+ },
39
+ outlineButton: {
40
+ backgroundColor: "transparent",
41
+ borderColor: theme.border
42
+ },
43
+ outlineButtonText: { color: theme.text },
44
+ smallButton: {
45
+ paddingVertical: 4,
46
+ paddingHorizontal: 10
47
+ },
48
+ disabledButton: {
49
+ backgroundColor: "transparent",
50
+ borderStyle: "dashed",
51
+ borderColor: theme.border
52
+ },
53
+ disabledButtonText: { color: theme.muted },
54
+ uploads: { gap: 8 },
55
+ upload: {
56
+ flexDirection: "row",
57
+ alignItems: "center",
58
+ gap: 12,
59
+ padding: 12,
60
+ borderWidth: 1,
61
+ borderColor: theme.border,
62
+ borderRadius: theme.radius,
63
+ backgroundColor: theme.background
64
+ },
65
+ messageRow: {
66
+ flexDirection: "row",
67
+ alignItems: "center",
68
+ gap: 8
69
+ },
70
+ outcomeDot: {
71
+ width: 8,
72
+ height: 8,
73
+ borderRadius: 4
74
+ },
75
+ accepted: { backgroundColor: theme.success },
76
+ restricted: { backgroundColor: theme.warning },
77
+ rejected: { backgroundColor: theme.danger },
78
+ thumb: {
79
+ width: 40,
80
+ height: 40,
81
+ borderRadius: 8,
82
+ overflow: "hidden"
83
+ },
84
+ fileIcon: {
85
+ alignItems: "center",
86
+ justifyContent: "center",
87
+ borderWidth: 1.5
88
+ },
89
+ fileIconLabel: {
90
+ fontSize: 9,
91
+ fontWeight: "700",
92
+ fontFamily: "monospace"
93
+ },
94
+ body: {
95
+ flex: 1,
96
+ minWidth: 0,
97
+ gap: 4
98
+ },
99
+ name: {
100
+ fontWeight: "500",
101
+ color: theme.text
102
+ },
103
+ size: {
104
+ fontSize: 13,
105
+ color: theme.muted
106
+ },
107
+ message: {
108
+ fontSize: 13,
109
+ color: theme.text
110
+ },
111
+ progress: {
112
+ height: 4,
113
+ borderRadius: 2,
114
+ overflow: "hidden",
115
+ backgroundColor: theme.border
116
+ },
117
+ progressBar: {
118
+ height: "100%",
119
+ borderRadius: 2,
120
+ backgroundColor: theme.accent
121
+ },
122
+ actions: {
123
+ flexDirection: "row",
124
+ alignItems: "center",
125
+ gap: 8
126
+ },
127
+ iconButton: {
128
+ width: 30,
129
+ height: 30,
130
+ alignItems: "center",
131
+ justifyContent: "center",
132
+ borderRadius: 8
133
+ },
134
+ iconButtonText: {
135
+ fontSize: 16,
136
+ color: theme.text
137
+ }
138
+ });
139
+ /** The `testID` of the uploader's pick buttons, for end-to-end tests such as Detox or Maestro. */
140
+ const CHOOSE_TEST_ID = "calmlens-choose";
141
+ const Button = ({ label, onPress, disabled, variant, size, styles, testID }) => /* @__PURE__ */ jsx(Pressable, {
142
+ role: "button",
143
+ "aria-label": label,
144
+ testID,
145
+ disabled,
146
+ onPress,
147
+ style: [
148
+ styles.button,
149
+ variant === "outline" && styles.outlineButton,
150
+ size === "small" && styles.smallButton,
151
+ disabled && styles.disabledButton
152
+ ],
153
+ children: /* @__PURE__ */ jsx(Text, {
154
+ style: [
155
+ styles.buttonText,
156
+ variant === "outline" && styles.outlineButtonText,
157
+ disabled && styles.disabledButtonText
158
+ ],
159
+ children: label
160
+ })
161
+ });
162
+ /** The file-type tile shown for files without an image preview, in the family's colour. */
163
+ const FileIcon = ({ file, styles }) => {
164
+ const { family, extension } = getFileIcon(file);
165
+ const tint = FILE_ICON_COLORS[family];
166
+ return /* @__PURE__ */ jsx(View, {
167
+ "aria-hidden": true,
168
+ style: [
169
+ styles.thumb,
170
+ styles.fileIcon,
171
+ { borderColor: tint }
172
+ ],
173
+ children: /* @__PURE__ */ jsx(Text, {
174
+ style: [styles.fileIconLabel, { color: tint }],
175
+ children: getFileIconLabel(extension).text
176
+ })
177
+ });
178
+ };
179
+ const UploadRow = ({ item, view, messages, styles, showChooseAnother, disabled, onChooseAnother, onRetry, onRemove }) => /* @__PURE__ */ jsxs(View, {
180
+ style: styles.upload,
181
+ children: [
182
+ item.previewUrl ? /* @__PURE__ */ jsx(Image, {
183
+ source: { uri: item.previewUrl },
184
+ "aria-hidden": true,
185
+ blurRadius: view.outcome === "rejected" ? 6 : void 0,
186
+ style: styles.thumb
187
+ }) : /* @__PURE__ */ jsx(FileIcon, {
188
+ file: item.file,
189
+ styles
190
+ }),
191
+ /* @__PURE__ */ jsxs(View, {
192
+ style: styles.body,
193
+ children: [
194
+ /* @__PURE__ */ jsx(Text, {
195
+ style: styles.name,
196
+ numberOfLines: 1,
197
+ children: item.file.name
198
+ }),
199
+ /* @__PURE__ */ jsx(Text, {
200
+ style: styles.size,
201
+ children: view.size
202
+ }),
203
+ view.busy && /* @__PURE__ */ jsx(View, {
204
+ role: "progressbar",
205
+ "aria-label": view.message,
206
+ "aria-valuemin": 0,
207
+ "aria-valuemax": 100,
208
+ "aria-valuenow": view.progressPercent,
209
+ style: styles.progress,
210
+ children: /* @__PURE__ */ jsx(View, { style: [styles.progressBar, { width: `${view.progressPercent ?? 100}%` }] })
211
+ }),
212
+ view.message ? /* @__PURE__ */ jsxs(View, {
213
+ style: styles.messageRow,
214
+ children: [view.outcome && /* @__PURE__ */ jsx(View, {
215
+ "aria-hidden": true,
216
+ style: [styles.outcomeDot, styles[view.outcome]]
217
+ }), /* @__PURE__ */ jsx(Text, {
218
+ role: "status",
219
+ style: styles.message,
220
+ children: view.message
221
+ })]
222
+ }) : null
223
+ ]
224
+ }),
225
+ /* @__PURE__ */ jsxs(View, {
226
+ style: styles.actions,
227
+ children: [
228
+ showChooseAnother && /* @__PURE__ */ jsx(Button, {
229
+ label: messages.chooseAnother,
230
+ testID: "calmlens-choose",
231
+ variant: "outline",
232
+ size: "small",
233
+ disabled,
234
+ onPress: onChooseAnother,
235
+ styles
236
+ }),
237
+ view.canRetry && /* @__PURE__ */ jsx(Pressable, {
238
+ role: "button",
239
+ "aria-label": messages.retry,
240
+ onPress: onRetry,
241
+ style: styles.iconButton,
242
+ children: /* @__PURE__ */ jsx(Text, {
243
+ "aria-hidden": true,
244
+ style: styles.iconButtonText,
245
+ children: "↻"
246
+ })
247
+ }),
248
+ /* @__PURE__ */ jsx(Pressable, {
249
+ role: "button",
250
+ "aria-label": view.removeLabel,
251
+ onPress: onRemove,
252
+ style: styles.iconButton,
253
+ children: /* @__PURE__ */ jsx(Text, {
254
+ "aria-hidden": true,
255
+ style: styles.iconButtonText,
256
+ children: "✕"
257
+ })
258
+ })
259
+ ]
260
+ })
261
+ ]
262
+ });
263
+ /**
264
+ * A pick button and file list that uploads through an upload preset, shows each file's progress
265
+ * and moderation decision, and reports finished uploads to `onUploaded`. `pick` opens your app's
266
+ * picker, such as `expo-image-picker`.
267
+ */
268
+ function CalmLensUploader({ pick, disabled, messages: overrides, controller: external, theme: themeOverrides, style, ...options }) {
269
+ const own = useOwnController(options, !external);
270
+ const upload = useUploadSnapshot(external ?? own);
271
+ const { accept, multiple = false } = upload.controller.options;
272
+ const messages = useMemo(() => resolveMessages(overrides), [overrides]);
273
+ const styles = useMemo(() => createUploaderStyles(resolveTheme(themeOverrides)), [themeOverrides]);
274
+ const view = describeUploader(upload, upload.controller.options, messages);
275
+ const openPicker = async () => {
276
+ if (disabled) return;
277
+ const files = await pick({
278
+ multiple,
279
+ accept
280
+ });
281
+ if (files?.length) upload.addFiles(files);
282
+ };
283
+ return /* @__PURE__ */ jsxs(View, {
284
+ style: [styles.uploader, style],
285
+ children: [view.showDropzone && /* @__PURE__ */ jsxs(View, {
286
+ style: styles.picker,
287
+ children: [/* @__PURE__ */ jsx(Button, {
288
+ label: view.chooseLabel,
289
+ testID: "calmlens-choose",
290
+ variant: "outline",
291
+ disabled,
292
+ onPress: () => void openPicker(),
293
+ styles
294
+ }), view.hint && /* @__PURE__ */ jsx(Text, {
295
+ style: styles.hint,
296
+ children: view.hint
297
+ })]
298
+ }), upload.items.length > 0 && /* @__PURE__ */ jsx(View, {
299
+ style: styles.uploads,
300
+ children: upload.items.map((item) => /* @__PURE__ */ jsx(UploadRow, {
301
+ item,
302
+ view: describeUploadItem(item, messages),
303
+ messages,
304
+ styles,
305
+ showChooseAnother: !view.showDropzone,
306
+ disabled,
307
+ onChooseAnother: () => void openPicker(),
308
+ onRetry: () => upload.retry(item.key),
309
+ onRemove: () => upload.remove(item.key)
310
+ }, item.key))
311
+ })]
312
+ });
313
+ }
314
+ const mediaStyles = StyleSheet.create({
315
+ media: {
316
+ position: "relative",
317
+ overflow: "hidden",
318
+ minHeight: 160
319
+ },
320
+ sized: { minHeight: 0 },
321
+ fill: { ...StyleSheet.absoluteFill },
322
+ notice: {
323
+ ...StyleSheet.absoluteFill,
324
+ alignItems: "center",
325
+ justifyContent: "center",
326
+ gap: 6,
327
+ padding: 12,
328
+ backgroundColor: "rgba(0, 0, 0, 0.45)"
329
+ },
330
+ noticeTitle: {
331
+ fontWeight: "600",
332
+ color: "#fff",
333
+ textAlign: "center"
334
+ },
335
+ noticeText: {
336
+ color: "#fff",
337
+ textAlign: "center"
338
+ },
339
+ revealButton: {
340
+ marginTop: 4,
341
+ paddingVertical: 7,
342
+ paddingHorizontal: 14,
343
+ borderRadius: 8,
344
+ backgroundColor: "#fff"
345
+ },
346
+ revealText: {
347
+ fontSize: 14,
348
+ fontWeight: "500",
349
+ color: "#111"
350
+ }
351
+ });
352
+ /**
353
+ * Shows an asset from the CalmLens CDN, at the width in `widths` that covers its measured size,
354
+ * with a blurred placeholder while it loads. Age-restricted assets stay behind the placeholder and
355
+ * a reveal button until `ageConfirmed` is set; blocked and purged assets show an unavailable notice.
356
+ */
357
+ function CalmLensMedia(input) {
358
+ const { asset: _asset, projectId, assetId, status, contentRemoved, type, resource, lens, transform, widths, url, placeholder, placeholderHash, placeholderUrl: customPlaceholderUrl, cdnBaseUrl, viewerClaims, alt = "", aspectRatio, width, height, averageColor, fit = "cover", messages: overrides, theme: themeOverrides, onReveal, renderPlayer, style } = resolveMediaProps(input);
359
+ const messages = useMemo(() => resolveMessages(overrides), [overrides]);
360
+ const theme = useMemo(() => resolveTheme(themeOverrides), [themeOverrides]);
361
+ const state = getMediaState({
362
+ asset: _asset,
363
+ projectId,
364
+ assetId,
365
+ status,
366
+ contentRemoved,
367
+ type,
368
+ resource,
369
+ lens,
370
+ transform,
371
+ widths,
372
+ url,
373
+ placeholder,
374
+ placeholderHash,
375
+ placeholderUrl: customPlaceholderUrl,
376
+ cdnBaseUrl,
377
+ viewerClaims
378
+ });
379
+ const [layoutWidth, setLayoutWidth] = useState();
380
+ const src = state.kind === "image" ? pickMediaSource(state, layoutWidth) : void 0;
381
+ const loadKey = src ?? getMediaLoadKey(state);
382
+ const [load, setLoad] = useState({
383
+ key: loadKey,
384
+ state: "loading"
385
+ });
386
+ const current = load.key === loadKey ? load.state : "loading";
387
+ const ratio = getMediaAspectRatio({
388
+ aspectRatio,
389
+ width,
390
+ height
391
+ });
392
+ const unavailable = state.kind === "unavailable" || current === "error";
393
+ const placeholderUrl = state.kind === "audio" || state.kind === "unavailable" ? void 0 : state.placeholderUrl;
394
+ const showPlaceholder = placeholderUrl && !unavailable && (state.kind !== "image" || current !== "loaded") && !(state.kind === "video" && renderPlayer);
395
+ const player = (state.kind === "video" || state.kind === "audio") && !unavailable ? renderPlayer?.({
396
+ kind: state.kind,
397
+ src: state.src,
398
+ alt
399
+ }) : void 0;
400
+ return /* @__PURE__ */ jsxs(View, {
401
+ onLayout: (event) => {
402
+ setLayoutWidth(PixelRatio.getPixelSizeForLayoutSize(event.nativeEvent.layout.width));
403
+ },
404
+ style: [
405
+ mediaStyles.media,
406
+ ratio !== void 0 && [mediaStyles.sized, { aspectRatio: ratio }],
407
+ { backgroundColor: averageColor ?? theme.surface },
408
+ style
409
+ ],
410
+ children: [
411
+ showPlaceholder && /* @__PURE__ */ jsx(Image, {
412
+ source: { uri: placeholderUrl },
413
+ "aria-hidden": true,
414
+ blurRadius: 12,
415
+ resizeMode: fit,
416
+ style: mediaStyles.fill
417
+ }),
418
+ src && !unavailable && /* @__PURE__ */ jsx(Image, {
419
+ source: { uri: src },
420
+ "aria-label": alt || void 0,
421
+ accessible: Boolean(alt),
422
+ resizeMode: fit,
423
+ onLoad: () => setLoad({
424
+ key: loadKey,
425
+ state: "loaded"
426
+ }),
427
+ onError: () => setLoad({
428
+ key: loadKey,
429
+ state: "error"
430
+ }),
431
+ style: [mediaStyles.fill, { opacity: current === "loaded" ? 1 : 0 }]
432
+ }, loadKey),
433
+ player,
434
+ state.kind === "gated" && /* @__PURE__ */ jsxs(View, {
435
+ style: mediaStyles.notice,
436
+ children: [
437
+ /* @__PURE__ */ jsx(Text, {
438
+ style: mediaStyles.noticeTitle,
439
+ children: messages.sensitiveTitle
440
+ }),
441
+ /* @__PURE__ */ jsx(Text, {
442
+ style: mediaStyles.noticeText,
443
+ children: messages.sensitiveBody
444
+ }),
445
+ onReveal && /* @__PURE__ */ jsx(Pressable, {
446
+ role: "button",
447
+ "aria-label": messages.reveal,
448
+ onPress: onReveal,
449
+ style: mediaStyles.revealButton,
450
+ children: /* @__PURE__ */ jsx(Text, {
451
+ style: mediaStyles.revealText,
452
+ children: messages.reveal
453
+ })
454
+ })
455
+ ]
456
+ }),
457
+ unavailable && /* @__PURE__ */ jsx(View, {
458
+ style: [mediaStyles.notice, { backgroundColor: theme.surface }],
459
+ children: /* @__PURE__ */ jsx(Text, {
460
+ style: { color: theme.text },
461
+ children: getMediaUnavailableMessage(state, messages)
462
+ })
463
+ })
464
+ ]
465
+ });
466
+ }
467
+ export { CALMLENS_STYLES, CALMLENS_THEME, CHOOSE_TEST_ID, CalmLensMedia, CalmLensUploader, DEFAULT_MESSAGES, ICONS, ICON_ATTRIBUTES, UploadController, createProgressFetch, createUploadController, describeUploadItem, describeUploader, formatBytes, formatMessage, getDropzoneHint, getMediaAspectRatio, getMediaLoadKey, getMediaState, getMediaUnavailableMessage, getUploadItemMessage, getUploadItemOutcome, isFileAccepted, pickMediaSource, resolveMediaProps, resolveMessages, resolveTheme, useCalmLensUpload };
package/esm/react.d.ts ADDED
@@ -0,0 +1,30 @@
1
+ import { A as CustomUploadResult, B as MediaAsset, C as getDropzoneHint, D as resolveMessages, E as getUploadItemOutcome, G as MediaState, H as MediaOptions, J as resolveMediaProps, K as getMediaState, L as UploadStage, M as UploadController, P as UploadFile, S as formatMessage, T as getUploadItemMessage, U as MediaSettings, V as MediaImageSource, W as MediaSource, _ as UploadItemView, a as createProgressFetch, b as describeUploader, c as IconName, d as UploaderDisplayOptions, g as DEFAULT_MESSAGES, h as CalmLensMessages, i as CALMLENS_STYLES, j as UploadClient, k as CustomUploadContext, l as MediaDisplayOptions, m as getMediaLoadKey, n as CalmLensTheme, o as ICONS, p as getMediaAspectRatio, q as pickMediaSource, r as resolveTheme, s as ICON_ATTRIBUTES, t as CALMLENS_THEME, u as MediaProps, v as UploaderView, w as getMediaUnavailableMessage, x as formatBytes, y as describeUploadItem, z as isFileAccepted } from "./ui-wIiMfqMB.js";
2
+ import { a as UploaderProps, i as UploadSnapshot, n as UploadControllerOptions, o as UseCalmLensUploadResult, r as UploadItem, s as createUploadController, t as CalmLensUpload } from "./BrowserUpload-BT091eOB.js";
3
+ import { CSSProperties, HTMLAttributes } from "react";
4
+ /**
5
+ * Uploads files through an upload preset and re-renders as each one uploads and is checked. Use
6
+ * it to build your own upload UI; `CalmLensUploader` is built on it. Uploads still running when
7
+ * the component unmounts are cancelled.
8
+ */
9
+ export declare const useCalmLensUpload: <F extends UploadFile = File>(options: UploadControllerOptions<F>) => UseCalmLensUploadResult<F>;
10
+ /** Leaves out the stylesheet the components render, so you can style the `calmlens-*` classes. */
11
+ type StyleOptions = {
12
+ unstyled?: boolean;
13
+ };
14
+ export type CalmLensUploaderProps = UploaderProps & StyleOptions & {
15
+ className?: string;
16
+ style?: CSSProperties;
17
+ };
18
+ /**
19
+ * A drop zone and file list that uploads through an upload preset, shows each file's progress
20
+ * and moderation decision, and reports finished uploads to `onUploaded`.
21
+ */
22
+ export declare function CalmLensUploader({ disabled, capture, messages: overrides, unstyled, controller: external, className, style, ...options }: CalmLensUploaderProps): import("react").JSX.Element;
23
+ export type CalmLensMediaProps = MediaProps & StyleOptions & Omit<HTMLAttributes<HTMLElement>, "children" | "placeholder">;
24
+ /**
25
+ * Shows an asset from the CalmLens CDN with responsive widths and a blurred placeholder while
26
+ * it loads. Age-restricted assets stay behind the placeholder and a reveal button until
27
+ * `ageConfirmed` is set; blocked and purged assets show an unavailable notice.
28
+ */
29
+ export declare function CalmLensMedia(input: CalmLensMediaProps): import("react").JSX.Element;
30
+ export { CALMLENS_STYLES, CALMLENS_THEME, type CalmLensMessages, type CalmLensTheme, type CalmLensUpload, type CustomUploadContext, type CustomUploadResult, DEFAULT_MESSAGES, ICONS, ICON_ATTRIBUTES, type IconName, type MediaAsset, type MediaDisplayOptions, type MediaImageSource, type MediaOptions, type MediaProps, type MediaSettings, type MediaSource, type MediaState, type UploadClient, UploadController, type UploadControllerOptions, type UploadFile, type UploadItem, type UploadItemView, type UploadSnapshot, type UploadStage, type UploaderDisplayOptions, type UploaderProps, type UploaderView, type UseCalmLensUploadResult, createProgressFetch, createUploadController, describeUploadItem, describeUploader, formatBytes, formatMessage, getDropzoneHint, getMediaAspectRatio, getMediaLoadKey, getMediaState, getMediaUnavailableMessage, getUploadItemMessage, getUploadItemOutcome, isFileAccepted, pickMediaSource, resolveMediaProps, resolveMessages, resolveTheme };