@scalemule/nextjs 0.1.6 → 0.1.7

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/dist/index.d.mts CHANGED
@@ -1,14 +1,156 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ApiError, RealtimeService, StorageService, PhotoService, VideoService, FileStatus } from '@scalemule/sdk';
2
3
  import * as React from 'react';
3
4
  import { ReactNode, ReactElement } from 'react';
4
5
  import { MoneyClient } from '@scalemule/money';
5
6
  export { MoneyClient, MoneyClientConfig, createMoneyClient } from '@scalemule/money';
6
- import { RealtimeService, StorageService, PhotoService, VideoService, ApiError as ApiError$1, FileStatus } from '@scalemule/sdk';
7
7
  import { ScaleMuleClient } from './client.mjs';
8
8
  export { ClientConfig, RequestOptions, createClient } from './client.mjs';
9
- import { S as ScaleMuleConfig, U as User, L as LoginResponse, A as ApiError, a as UseAuthReturn, b as UseBillingReturn, c as ListFilesParams, d as UseContentReturn, e as UseUserReturn, f as UseAnalyticsOptions, g as UseAnalyticsReturn } from './index-BIIUrnPr.mjs';
9
+ import { S as ScaleMuleConfig, U as User, L as LoginResponse, A as ApiError$1, a as UseAuthReturn, b as UseBillingReturn, c as ListFilesParams, d as UseContentReturn, e as UseUserReturn, f as UseAnalyticsOptions, g as UseAnalyticsReturn } from './index-BIIUrnPr.mjs';
10
10
  export { h as AccountBalance, i as AnalyticsEvent, j as ApiResponse, B as BatchTrackRequest, k as BillingPayment, l as BillingPayout, m as BillingRefund, n as BillingTransaction, C as ChangeEmailRequest, o as ChangePasswordRequest, p as ClientContext, q as ConnectedAccount, D as DeviceFingerprint, r as DeviceInfo, E as EnhancedAnalyticsEvent, F as ForgotPasswordRequest, K as KnownAccountInfo, s as LinkedAccount, t as ListFilesResponse, u as LoginDeviceInfo, v as LoginRequest, w as LoginResponseWithMFA, x as LoginRiskInfo, M as MFAChallengeResponse, y as MFAMethod, z as MFASMSSetupResponse, G as MFASetupRequest, H as MFAStatus, I as MFATOTPSetupResponse, J as MFAVerifyRequest, O as OAuthCallbackRequest, N as OAuthCallbackResponse, P as OAuthConfig, Q as OAuthProvider, R as OAuthStartResponse, T as PageViewData, V as PayoutSchedule, W as PhoneLoginRequest, X as PhoneSendCodeRequest, Y as PhoneVerifyRequest, Z as Profile, _ as RefreshResponse, $ as RegisterRequest, a0 as ResetPasswordRequest, a1 as ScaleMuleApiError, a2 as ScaleMuleEnvironment, a3 as Session, a4 as SignedUploadCompleteRequest, a5 as SignedUploadRequest, a6 as SignedUploadResponse, a7 as SignedUploadUrl, a8 as StorageAdapter, a9 as StorageFile, aa as TrackEventResponse, ab as TransactionSummary, ac as UTMParams, ad as UpdateProfileRequest, ae as UploadOptions, af as UploadResponse, ag as VerifyEmailRequest } from './index-BIIUrnPr.mjs';
11
11
 
12
+ /**
13
+ * Result of a single {@link useMedia} upload call.
14
+ *
15
+ * The shape is normalized regardless of MIME type — `optimized_url_promise`
16
+ * resolves on image uploads after the photo optimizer finishes; for non-image
17
+ * uploads it resolves to `null` immediately. (Video / audio branches will
18
+ * populate `hls_url_promise` in later phases — today they fall through to
19
+ * generic storage and that field stays `null`.)
20
+ */
21
+ interface MediaUploadResult {
22
+ /** Storage file_id — store this in chat-attachment metadata. */
23
+ file_id: string;
24
+ /** Photo service id — null for non-image uploads or when register() failed. */
25
+ photo_id: string | null;
26
+ /** Short-lived signed URL to the original bytes (private uploads) or
27
+ * a public CDN URL (when caller passed `is_public: true`). */
28
+ original_view_url: string | null;
29
+ /** Resolves once the photo optimizer finishes. `null` for non-image
30
+ * MIME types or when register() failed. */
31
+ optimized_url_promise: Promise<string | null>;
32
+ /** Resolves once the video transcoder finishes (Phase 2 / S5b). `null` today. */
33
+ hls_url_promise: Promise<string | null>;
34
+ /** The file's MIME type — preserved from the input File / Blob. */
35
+ mime_type: string;
36
+ /** Whether the resulting storage object is public-readable. */
37
+ is_public: boolean;
38
+ }
39
+ /**
40
+ * Per-app media-pipeline policy. Drives release-gating + processing
41
+ * behavior. **Orthogonal to `is_public`.** See
42
+ * `docs/MEDIA-UPLOADS.md` and ADR-2026-04-26 for the full taxonomy.
43
+ *
44
+ * Today's behavior (Phase 4 v1):
45
+ * - `fast_trusted` / `safe_visible` (default): upload promise resolves
46
+ * as soon as the file is uploaded + registered. The post-processing
47
+ * (scan, optimize, transcode) runs async; callers can observe via
48
+ * `useFileStatus`.
49
+ * - `safe_public` / `moderated`: upload promise *waits* for the
50
+ * optimized image variant (image MIME) or HLS playlist (video MIME)
51
+ * to become ready before resolving. Acts as the release-gate for
52
+ * UGC-style apps that should not publish raw bytes.
53
+ * - `compliance`: today behaves as `safe_public`; Phase 4+ adds the
54
+ * audit-log + signed-with-purpose URL semantics.
55
+ */
56
+ type MediaPolicy = 'fast_trusted' | 'safe_visible' | 'safe_public' | 'moderated' | 'compliance';
57
+ interface UseMediaUploadOptions {
58
+ /** Whether the resulting storage object should be public-readable.
59
+ * Default: `false` (private). Public is opt-in for surfaces that
60
+ * genuinely need it (avatars, public listings). Chat / DM uploads
61
+ * should always be private. */
62
+ is_public?: boolean;
63
+ /**
64
+ * Per-call media-policy override. Defaults to `safe_visible` (visible
65
+ * immediately at original fidelity; optimized variants swap in async).
66
+ * Set to `safe_public` to make the upload promise *await* the optimized
67
+ * variant (image) or HLS playlist (video) before resolving — useful for
68
+ * broadcast / UGC apps that gate publication on processing complete.
69
+ *
70
+ * The per-app default lives in `application_storage_settings.media_policy`
71
+ * (Phase 4 / P3, live in prod 2026-04-26). Reading the per-app default
72
+ * into `useMedia` defaults lands in a follow-up; today the option is
73
+ * caller-provided per call.
74
+ */
75
+ policy?: MediaPolicy;
76
+ /** Display filename (sanitized server-side). */
77
+ filename?: string;
78
+ /** Custom metadata attached to the file. */
79
+ metadata?: Record<string, unknown>;
80
+ /** Upload progress callback (0-100). */
81
+ onProgress?: (percent: number) => void;
82
+ /** AbortSignal for cancellation. */
83
+ signal?: AbortSignal;
84
+ /** Force a non-photo path even for image MIME types — useful for
85
+ * generic file uploads where you don't want the photo optimizer
86
+ * to register the file. Default: `false`. */
87
+ skipPhotoRegister?: boolean;
88
+ }
89
+ interface UseMediaReturn {
90
+ /** Upload a file. MIME-aware: images go through photo register +
91
+ * optimization; everything else goes through generic storage. */
92
+ upload: (file: File | Blob, options?: UseMediaUploadOptions) => Promise<MediaUploadResult>;
93
+ /** Cancel an upload by its `file_id`. Deletes the storage object so
94
+ * it doesn't orphan in S3 — useful when a chat composer accepts a
95
+ * file but the user removes it before sending. Idempotent. */
96
+ cancelUpload: (fileId: string) => Promise<void>;
97
+ /** Last error from `upload` or `cancelUpload`. */
98
+ error: ApiError | null;
99
+ /** True while an upload is in progress. */
100
+ uploading: boolean;
101
+ }
102
+ /**
103
+ * Opinionated, MIME-aware media upload hook.
104
+ *
105
+ * `useMedia()` is the canonical upload primitive for chat / progressive
106
+ * media use. It branches by MIME type:
107
+ * - `image/*` → `client.photo.uploadViaStorage()` — upload to storage,
108
+ * then register with the photo service so the on-demand transform
109
+ * endpoint resolves to optimized variants. The returned
110
+ * `optimized_url_promise` resolves once the optimizer finishes.
111
+ * - everything else → `client.storage.uploadPrivate()` — a private,
112
+ * uncompressed, fail-closed upload to generic storage.
113
+ *
114
+ * **Default visibility is `is_public: false`.** Public is opt-in per call.
115
+ * `useMedia()` does not expose `is_public` via app-level config — visibility
116
+ * is always an explicit per-call surface choice.
117
+ *
118
+ * Compared to `useContent()`:
119
+ * - `useContent()` is a thin wrapper over generic storage and does not
120
+ * register photos / videos with their typed services. Use it for plain
121
+ * file uploads where you don't need optimization or transcoding.
122
+ * - `useMedia()` defaults to private + no compression, integrates with the
123
+ * typed media services automatically, and is the right primitive for
124
+ * anything chat- or media-shaped.
125
+ *
126
+ * @example
127
+ * ```tsx
128
+ * 'use client';
129
+ *
130
+ * import { useMedia, ScaleMuleMedia } from '@scalemule/nextjs';
131
+ *
132
+ * function ChatComposer({ onAttach }) {
133
+ * const { upload, uploading } = useMedia();
134
+ *
135
+ * async function handlePick(file: File) {
136
+ * const result = await upload(file);
137
+ * onAttach({
138
+ * file_id: result.file_id,
139
+ * mime_type: result.mime_type,
140
+ * optimized_url_promise: result.optimized_url_promise,
141
+ * });
142
+ * }
143
+ *
144
+ * return <input type="file" disabled={uploading}
145
+ * onChange={(e) => e.target.files?.[0] && handlePick(e.target.files[0])} />;
146
+ * }
147
+ * ```
148
+ *
149
+ * See `docs/MEDIA-UPLOADS.md` in the platform repo for the decision
150
+ * tree and the full anti-patterns list.
151
+ */
152
+ declare function useMedia(): UseMediaReturn;
153
+
12
154
  interface ScaleMuleContextValue {
13
155
  /** The API client instance */
14
156
  client: ScaleMuleClient;
@@ -22,6 +164,12 @@ interface ScaleMuleContextValue {
22
164
  photo: PhotoService;
23
165
  /** Base SDK video service — exposed for `useMedia()` and `video.uploadViaStorage()` */
24
166
  video: VideoService;
167
+ /**
168
+ * Default media policy for `useMedia()` calls. Set via
169
+ * `<ScaleMuleProvider mediaPolicy="…">`; per-call overrides win.
170
+ * Undefined falls back to `useMedia()`'s built-in `safe_visible` default.
171
+ */
172
+ mediaPolicy?: MediaPolicy;
25
173
  /** Current authenticated user */
26
174
  user: User | null;
27
175
  /** Set the current user */
@@ -29,9 +177,9 @@ interface ScaleMuleContextValue {
29
177
  /** Whether the SDK is initializing */
30
178
  initializing: boolean;
31
179
  /** Last error */
32
- error: ApiError | null;
180
+ error: ApiError$1 | null;
33
181
  /** Set error */
34
- setError: (error: ApiError | null) => void;
182
+ setError: (error: ApiError$1 | null) => void;
35
183
  /** Analytics proxy URL (when set, SDK sends events here instead of ScaleMule) */
36
184
  analyticsProxyUrl?: string;
37
185
  /** Auth proxy URL (when set, auth operations route through this proxy) */
@@ -56,11 +204,27 @@ interface ScaleMuleProviderProps extends ScaleMuleConfig {
56
204
  /** Called when user logs out */
57
205
  onLogout?: () => void;
58
206
  /** Called on authentication error */
59
- onAuthError?: (error: ApiError) => void;
207
+ onAuthError?: (error: ApiError$1) => void;
60
208
  /** Server-evaluated flag values to bootstrap the client (eliminates loading flash) */
61
209
  bootstrapFlags?: Record<string, unknown>;
210
+ /**
211
+ * Default media-pipeline policy applied to `useMedia()` calls when no
212
+ * per-call `policy` override is given. Five modes — see
213
+ * `docs/MEDIA-UPLOADS.md` and the {@link import('./hooks/useMedia').MediaPolicy} type.
214
+ *
215
+ * The platform stores the per-app policy in
216
+ * `application_storage_settings.media_policy` (Phase 4 / P3, live in
217
+ * prod). That endpoint is `MemberOnly` admin-auth, so end-user-context
218
+ * provider can't fetch it directly — apps that want policy-driven
219
+ * defaults should declare the value here, mirroring whatever the
220
+ * platform admin set.
221
+ *
222
+ * Default: undefined → `useMedia()` falls back to its built-in
223
+ * `safe_visible` default.
224
+ */
225
+ mediaPolicy?: MediaPolicy;
62
226
  }
63
- declare function ScaleMuleProvider({ apiKey, applicationId, environment, gatewayUrl, debug, storage, analyticsProxyUrl, authProxyUrl, publishableKey, enableAccountSwitcher, accountSwitcherPrivacy, children, onLogin, onLogout, onAuthError, bootstrapFlags, }: ScaleMuleProviderProps): react_jsx_runtime.JSX.Element;
227
+ declare function ScaleMuleProvider({ apiKey, applicationId, environment, gatewayUrl, debug, storage, analyticsProxyUrl, authProxyUrl, publishableKey, enableAccountSwitcher, accountSwitcherPrivacy, children, onLogin, onLogout, onAuthError, bootstrapFlags, mediaPolicy, }: ScaleMuleProviderProps): react_jsx_runtime.JSX.Element;
64
228
  declare function useScaleMule(): ScaleMuleContextValue;
65
229
  declare function useScaleMuleClient(): ScaleMuleClient;
66
230
  declare function useMoneyClient(): MoneyClient;
@@ -158,148 +322,6 @@ interface UseContentOptions {
158
322
  */
159
323
  declare function useContent(options?: UseContentOptions): UseContentReturn;
160
324
 
161
- /**
162
- * Result of a single {@link useMedia} upload call.
163
- *
164
- * The shape is normalized regardless of MIME type — `optimized_url_promise`
165
- * resolves on image uploads after the photo optimizer finishes; for non-image
166
- * uploads it resolves to `null` immediately. (Video / audio branches will
167
- * populate `hls_url_promise` in later phases — today they fall through to
168
- * generic storage and that field stays `null`.)
169
- */
170
- interface MediaUploadResult {
171
- /** Storage file_id — store this in chat-attachment metadata. */
172
- file_id: string;
173
- /** Photo service id — null for non-image uploads or when register() failed. */
174
- photo_id: string | null;
175
- /** Short-lived signed URL to the original bytes (private uploads) or
176
- * a public CDN URL (when caller passed `is_public: true`). */
177
- original_view_url: string | null;
178
- /** Resolves once the photo optimizer finishes. `null` for non-image
179
- * MIME types or when register() failed. */
180
- optimized_url_promise: Promise<string | null>;
181
- /** Resolves once the video transcoder finishes (Phase 2 / S5b). `null` today. */
182
- hls_url_promise: Promise<string | null>;
183
- /** The file's MIME type — preserved from the input File / Blob. */
184
- mime_type: string;
185
- /** Whether the resulting storage object is public-readable. */
186
- is_public: boolean;
187
- }
188
- /**
189
- * Per-app media-pipeline policy. Drives release-gating + processing
190
- * behavior. **Orthogonal to `is_public`.** See
191
- * `docs/MEDIA-UPLOADS.md` and ADR-2026-04-26 for the full taxonomy.
192
- *
193
- * Today's behavior (Phase 4 v1):
194
- * - `fast_trusted` / `safe_visible` (default): upload promise resolves
195
- * as soon as the file is uploaded + registered. The post-processing
196
- * (scan, optimize, transcode) runs async; callers can observe via
197
- * `useFileStatus`.
198
- * - `safe_public` / `moderated`: upload promise *waits* for the
199
- * optimized image variant (image MIME) or HLS playlist (video MIME)
200
- * to become ready before resolving. Acts as the release-gate for
201
- * UGC-style apps that should not publish raw bytes.
202
- * - `compliance`: today behaves as `safe_public`; Phase 4+ adds the
203
- * audit-log + signed-with-purpose URL semantics.
204
- */
205
- type MediaPolicy = 'fast_trusted' | 'safe_visible' | 'safe_public' | 'moderated' | 'compliance';
206
- interface UseMediaUploadOptions {
207
- /** Whether the resulting storage object should be public-readable.
208
- * Default: `false` (private). Public is opt-in for surfaces that
209
- * genuinely need it (avatars, public listings). Chat / DM uploads
210
- * should always be private. */
211
- is_public?: boolean;
212
- /**
213
- * Per-call media-policy override. Defaults to `safe_visible` (visible
214
- * immediately at original fidelity; optimized variants swap in async).
215
- * Set to `safe_public` to make the upload promise *await* the optimized
216
- * variant (image) or HLS playlist (video) before resolving — useful for
217
- * broadcast / UGC apps that gate publication on processing complete.
218
- *
219
- * The per-app default lives in `application_storage_settings.media_policy`
220
- * (Phase 4 / P3, live in prod 2026-04-26). Reading the per-app default
221
- * into `useMedia` defaults lands in a follow-up; today the option is
222
- * caller-provided per call.
223
- */
224
- policy?: MediaPolicy;
225
- /** Display filename (sanitized server-side). */
226
- filename?: string;
227
- /** Custom metadata attached to the file. */
228
- metadata?: Record<string, unknown>;
229
- /** Upload progress callback (0-100). */
230
- onProgress?: (percent: number) => void;
231
- /** AbortSignal for cancellation. */
232
- signal?: AbortSignal;
233
- /** Force a non-photo path even for image MIME types — useful for
234
- * generic file uploads where you don't want the photo optimizer
235
- * to register the file. Default: `false`. */
236
- skipPhotoRegister?: boolean;
237
- }
238
- interface UseMediaReturn {
239
- /** Upload a file. MIME-aware: images go through photo register +
240
- * optimization; everything else goes through generic storage. */
241
- upload: (file: File | Blob, options?: UseMediaUploadOptions) => Promise<MediaUploadResult>;
242
- /** Cancel an upload by its `file_id`. Deletes the storage object so
243
- * it doesn't orphan in S3 — useful when a chat composer accepts a
244
- * file but the user removes it before sending. Idempotent. */
245
- cancelUpload: (fileId: string) => Promise<void>;
246
- /** Last error from `upload` or `cancelUpload`. */
247
- error: ApiError$1 | null;
248
- /** True while an upload is in progress. */
249
- uploading: boolean;
250
- }
251
- /**
252
- * Opinionated, MIME-aware media upload hook.
253
- *
254
- * `useMedia()` is the canonical upload primitive for chat / progressive
255
- * media use. It branches by MIME type:
256
- * - `image/*` → `client.photo.uploadViaStorage()` — upload to storage,
257
- * then register with the photo service so the on-demand transform
258
- * endpoint resolves to optimized variants. The returned
259
- * `optimized_url_promise` resolves once the optimizer finishes.
260
- * - everything else → `client.storage.uploadPrivate()` — a private,
261
- * uncompressed, fail-closed upload to generic storage.
262
- *
263
- * **Default visibility is `is_public: false`.** Public is opt-in per call.
264
- * `useMedia()` does not expose `is_public` via app-level config — visibility
265
- * is always an explicit per-call surface choice.
266
- *
267
- * Compared to `useContent()`:
268
- * - `useContent()` is a thin wrapper over generic storage and does not
269
- * register photos / videos with their typed services. Use it for plain
270
- * file uploads where you don't need optimization or transcoding.
271
- * - `useMedia()` defaults to private + no compression, integrates with the
272
- * typed media services automatically, and is the right primitive for
273
- * anything chat- or media-shaped.
274
- *
275
- * @example
276
- * ```tsx
277
- * 'use client';
278
- *
279
- * import { useMedia, ScaleMuleMedia } from '@scalemule/nextjs';
280
- *
281
- * function ChatComposer({ onAttach }) {
282
- * const { upload, uploading } = useMedia();
283
- *
284
- * async function handlePick(file: File) {
285
- * const result = await upload(file);
286
- * onAttach({
287
- * file_id: result.file_id,
288
- * mime_type: result.mime_type,
289
- * optimized_url_promise: result.optimized_url_promise,
290
- * });
291
- * }
292
- *
293
- * return <input type="file" disabled={uploading}
294
- * onChange={(e) => e.target.files?.[0] && handlePick(e.target.files[0])} />;
295
- * }
296
- * ```
297
- *
298
- * See `docs/MEDIA-UPLOADS.md` in the platform repo for the decision
299
- * tree and the full anti-patterns list.
300
- */
301
- declare function useMedia(): UseMediaReturn;
302
-
303
325
  interface UseFileStatusOptions {
304
326
  /** Storage file_id to read status for. */
305
327
  fileId: string | null | undefined;
@@ -326,7 +348,7 @@ interface UseFileStatusReturn {
326
348
  /** True while a fetch is in flight. */
327
349
  loading: boolean;
328
350
  /** Last error, or null. */
329
- error: ApiError$1 | null;
351
+ error: ApiError | null;
330
352
  /**
331
353
  * Convenience: scan is clean. For images/videos, this means the file
332
354
  * is *safe to render*; the optimized / HLS variants may still be
@@ -586,7 +608,7 @@ interface UseFeatureFlagsOptions {
586
608
  interface UseFeatureFlagsReturn {
587
609
  flags: Record<string, FeatureFlagEvaluation>;
588
610
  loading: boolean;
589
- error: ApiError | null;
611
+ error: ApiError$1 | null;
590
612
  refresh: () => Promise<void>;
591
613
  isEnabled: (flagKey: string, fallback?: boolean) => boolean;
592
614
  getFlag: <T = unknown>(flagKey: string, fallback?: T) => T;
@@ -613,7 +635,7 @@ interface UsePushNotificationsReturn {
613
635
  /** Whether an operation is in progress */
614
636
  isLoading: boolean;
615
637
  /** Last error */
616
- error: ApiError | null;
638
+ error: ApiError$1 | null;
617
639
  /** Request permission and subscribe to push notifications */
618
640
  subscribe: () => Promise<void>;
619
641
  /** Unsubscribe from push notifications */
@@ -714,7 +736,7 @@ interface UseFeedbackResult {
714
736
  /** End-user's own feedback items for the current tenant. Empty when not signed in. */
715
737
  items: FeedbackItem[];
716
738
  loading: boolean;
717
- error: ApiError | null;
739
+ error: ApiError$1 | null;
718
740
  /** Submit a new feedback item. Returns the persisted item on success. */
719
741
  submit: (input: FeedbackItemInput) => Promise<FeedbackItem>;
720
742
  /** Re-fetch the list. */
@@ -926,4 +948,4 @@ declare function createSafeLogger(prefix: string): {
926
948
  error: (message: string, data?: unknown) => void;
927
949
  };
928
950
 
929
- export { ApiError, type FeatureFlagEvaluation, type FeatureFlagEvaluation as FeatureFlagResult, type FeedbackItem, type FeedbackItemInput, type FeedbackPriority, type FeedbackStatus, type FeedbackType, FeedbackWidget, type FeedbackWidgetConfig, type FeedbackWidgetProps, ListFilesParams, LoginResponse, type MediaPolicy, type MediaUploadResult, type PasswordValidationResult, type PhoneCountry, type PhoneValidationResult, type RealtimeEvent, type RealtimeMessage, type RealtimeStatus, ScaleMuleClient, ScaleMuleConfig, ScaleMuleMedia, type ScaleMuleMediaProps, ScaleMuleProvider, type ScaleMuleProviderProps, UseAnalyticsOptions, UseAnalyticsReturn, UseAuthReturn, UseBillingReturn, UseContentReturn, type UseFeatureFlagsOptions, type UseFeatureFlagsReturn, type UseFeedbackOptions, type UseFeedbackResult, type UseFileStatusOptions, type UseFileStatusReturn, type UseFeatureFlagsOptions as UseFlagsOptions, type UseFeatureFlagsReturn as UseFlagsReturn, type UseMediaReturn, type UseMediaUploadOptions, type UsePushNotificationsOptions, type UsePushNotificationsReturn, type UseRealtimeOptions, type UseRealtimeReturn, type UseShareOptions, type UseShareReturn, UseUserReturn, User, type UsernameValidationResult, composePhone, createSafeLogger, normalizePhone, phoneCountries, sanitizeForLog, useAnalytics, useAuth, useBilling, useContent, useFeatureFlags, useFeedback, useFileStatus, useMedia, useMoney, useMoneyClient, usePushNotifications, useRealtime, useScaleMule, useScaleMuleClient, useShare, useUser, validateForm, validators };
951
+ export { ApiError$1 as ApiError, type FeatureFlagEvaluation, type FeatureFlagEvaluation as FeatureFlagResult, type FeedbackItem, type FeedbackItemInput, type FeedbackPriority, type FeedbackStatus, type FeedbackType, FeedbackWidget, type FeedbackWidgetConfig, type FeedbackWidgetProps, ListFilesParams, LoginResponse, type MediaPolicy, type MediaUploadResult, type PasswordValidationResult, type PhoneCountry, type PhoneValidationResult, type RealtimeEvent, type RealtimeMessage, type RealtimeStatus, ScaleMuleClient, ScaleMuleConfig, ScaleMuleMedia, type ScaleMuleMediaProps, ScaleMuleProvider, type ScaleMuleProviderProps, UseAnalyticsOptions, UseAnalyticsReturn, UseAuthReturn, UseBillingReturn, UseContentReturn, type UseFeatureFlagsOptions, type UseFeatureFlagsReturn, type UseFeedbackOptions, type UseFeedbackResult, type UseFileStatusOptions, type UseFileStatusReturn, type UseFeatureFlagsOptions as UseFlagsOptions, type UseFeatureFlagsReturn as UseFlagsReturn, type UseMediaReturn, type UseMediaUploadOptions, type UsePushNotificationsOptions, type UsePushNotificationsReturn, type UseRealtimeOptions, type UseRealtimeReturn, type UseShareOptions, type UseShareReturn, UseUserReturn, User, type UsernameValidationResult, composePhone, createSafeLogger, normalizePhone, phoneCountries, sanitizeForLog, useAnalytics, useAuth, useBilling, useContent, useFeatureFlags, useFeedback, useFileStatus, useMedia, useMoney, useMoneyClient, usePushNotifications, useRealtime, useScaleMule, useScaleMuleClient, useShare, useUser, validateForm, validators };
package/dist/index.d.ts CHANGED
@@ -1,14 +1,156 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ApiError, RealtimeService, StorageService, PhotoService, VideoService, FileStatus } from '@scalemule/sdk';
2
3
  import * as React from 'react';
3
4
  import { ReactNode, ReactElement } from 'react';
4
5
  import { MoneyClient } from '@scalemule/money';
5
6
  export { MoneyClient, MoneyClientConfig, createMoneyClient } from '@scalemule/money';
6
- import { RealtimeService, StorageService, PhotoService, VideoService, ApiError as ApiError$1, FileStatus } from '@scalemule/sdk';
7
7
  import { ScaleMuleClient } from './client.js';
8
8
  export { ClientConfig, RequestOptions, createClient } from './client.js';
9
- import { S as ScaleMuleConfig, U as User, L as LoginResponse, A as ApiError, a as UseAuthReturn, b as UseBillingReturn, c as ListFilesParams, d as UseContentReturn, e as UseUserReturn, f as UseAnalyticsOptions, g as UseAnalyticsReturn } from './index-BIIUrnPr.js';
9
+ import { S as ScaleMuleConfig, U as User, L as LoginResponse, A as ApiError$1, a as UseAuthReturn, b as UseBillingReturn, c as ListFilesParams, d as UseContentReturn, e as UseUserReturn, f as UseAnalyticsOptions, g as UseAnalyticsReturn } from './index-BIIUrnPr.js';
10
10
  export { h as AccountBalance, i as AnalyticsEvent, j as ApiResponse, B as BatchTrackRequest, k as BillingPayment, l as BillingPayout, m as BillingRefund, n as BillingTransaction, C as ChangeEmailRequest, o as ChangePasswordRequest, p as ClientContext, q as ConnectedAccount, D as DeviceFingerprint, r as DeviceInfo, E as EnhancedAnalyticsEvent, F as ForgotPasswordRequest, K as KnownAccountInfo, s as LinkedAccount, t as ListFilesResponse, u as LoginDeviceInfo, v as LoginRequest, w as LoginResponseWithMFA, x as LoginRiskInfo, M as MFAChallengeResponse, y as MFAMethod, z as MFASMSSetupResponse, G as MFASetupRequest, H as MFAStatus, I as MFATOTPSetupResponse, J as MFAVerifyRequest, O as OAuthCallbackRequest, N as OAuthCallbackResponse, P as OAuthConfig, Q as OAuthProvider, R as OAuthStartResponse, T as PageViewData, V as PayoutSchedule, W as PhoneLoginRequest, X as PhoneSendCodeRequest, Y as PhoneVerifyRequest, Z as Profile, _ as RefreshResponse, $ as RegisterRequest, a0 as ResetPasswordRequest, a1 as ScaleMuleApiError, a2 as ScaleMuleEnvironment, a3 as Session, a4 as SignedUploadCompleteRequest, a5 as SignedUploadRequest, a6 as SignedUploadResponse, a7 as SignedUploadUrl, a8 as StorageAdapter, a9 as StorageFile, aa as TrackEventResponse, ab as TransactionSummary, ac as UTMParams, ad as UpdateProfileRequest, ae as UploadOptions, af as UploadResponse, ag as VerifyEmailRequest } from './index-BIIUrnPr.js';
11
11
 
12
+ /**
13
+ * Result of a single {@link useMedia} upload call.
14
+ *
15
+ * The shape is normalized regardless of MIME type — `optimized_url_promise`
16
+ * resolves on image uploads after the photo optimizer finishes; for non-image
17
+ * uploads it resolves to `null` immediately. (Video / audio branches will
18
+ * populate `hls_url_promise` in later phases — today they fall through to
19
+ * generic storage and that field stays `null`.)
20
+ */
21
+ interface MediaUploadResult {
22
+ /** Storage file_id — store this in chat-attachment metadata. */
23
+ file_id: string;
24
+ /** Photo service id — null for non-image uploads or when register() failed. */
25
+ photo_id: string | null;
26
+ /** Short-lived signed URL to the original bytes (private uploads) or
27
+ * a public CDN URL (when caller passed `is_public: true`). */
28
+ original_view_url: string | null;
29
+ /** Resolves once the photo optimizer finishes. `null` for non-image
30
+ * MIME types or when register() failed. */
31
+ optimized_url_promise: Promise<string | null>;
32
+ /** Resolves once the video transcoder finishes (Phase 2 / S5b). `null` today. */
33
+ hls_url_promise: Promise<string | null>;
34
+ /** The file's MIME type — preserved from the input File / Blob. */
35
+ mime_type: string;
36
+ /** Whether the resulting storage object is public-readable. */
37
+ is_public: boolean;
38
+ }
39
+ /**
40
+ * Per-app media-pipeline policy. Drives release-gating + processing
41
+ * behavior. **Orthogonal to `is_public`.** See
42
+ * `docs/MEDIA-UPLOADS.md` and ADR-2026-04-26 for the full taxonomy.
43
+ *
44
+ * Today's behavior (Phase 4 v1):
45
+ * - `fast_trusted` / `safe_visible` (default): upload promise resolves
46
+ * as soon as the file is uploaded + registered. The post-processing
47
+ * (scan, optimize, transcode) runs async; callers can observe via
48
+ * `useFileStatus`.
49
+ * - `safe_public` / `moderated`: upload promise *waits* for the
50
+ * optimized image variant (image MIME) or HLS playlist (video MIME)
51
+ * to become ready before resolving. Acts as the release-gate for
52
+ * UGC-style apps that should not publish raw bytes.
53
+ * - `compliance`: today behaves as `safe_public`; Phase 4+ adds the
54
+ * audit-log + signed-with-purpose URL semantics.
55
+ */
56
+ type MediaPolicy = 'fast_trusted' | 'safe_visible' | 'safe_public' | 'moderated' | 'compliance';
57
+ interface UseMediaUploadOptions {
58
+ /** Whether the resulting storage object should be public-readable.
59
+ * Default: `false` (private). Public is opt-in for surfaces that
60
+ * genuinely need it (avatars, public listings). Chat / DM uploads
61
+ * should always be private. */
62
+ is_public?: boolean;
63
+ /**
64
+ * Per-call media-policy override. Defaults to `safe_visible` (visible
65
+ * immediately at original fidelity; optimized variants swap in async).
66
+ * Set to `safe_public` to make the upload promise *await* the optimized
67
+ * variant (image) or HLS playlist (video) before resolving — useful for
68
+ * broadcast / UGC apps that gate publication on processing complete.
69
+ *
70
+ * The per-app default lives in `application_storage_settings.media_policy`
71
+ * (Phase 4 / P3, live in prod 2026-04-26). Reading the per-app default
72
+ * into `useMedia` defaults lands in a follow-up; today the option is
73
+ * caller-provided per call.
74
+ */
75
+ policy?: MediaPolicy;
76
+ /** Display filename (sanitized server-side). */
77
+ filename?: string;
78
+ /** Custom metadata attached to the file. */
79
+ metadata?: Record<string, unknown>;
80
+ /** Upload progress callback (0-100). */
81
+ onProgress?: (percent: number) => void;
82
+ /** AbortSignal for cancellation. */
83
+ signal?: AbortSignal;
84
+ /** Force a non-photo path even for image MIME types — useful for
85
+ * generic file uploads where you don't want the photo optimizer
86
+ * to register the file. Default: `false`. */
87
+ skipPhotoRegister?: boolean;
88
+ }
89
+ interface UseMediaReturn {
90
+ /** Upload a file. MIME-aware: images go through photo register +
91
+ * optimization; everything else goes through generic storage. */
92
+ upload: (file: File | Blob, options?: UseMediaUploadOptions) => Promise<MediaUploadResult>;
93
+ /** Cancel an upload by its `file_id`. Deletes the storage object so
94
+ * it doesn't orphan in S3 — useful when a chat composer accepts a
95
+ * file but the user removes it before sending. Idempotent. */
96
+ cancelUpload: (fileId: string) => Promise<void>;
97
+ /** Last error from `upload` or `cancelUpload`. */
98
+ error: ApiError | null;
99
+ /** True while an upload is in progress. */
100
+ uploading: boolean;
101
+ }
102
+ /**
103
+ * Opinionated, MIME-aware media upload hook.
104
+ *
105
+ * `useMedia()` is the canonical upload primitive for chat / progressive
106
+ * media use. It branches by MIME type:
107
+ * - `image/*` → `client.photo.uploadViaStorage()` — upload to storage,
108
+ * then register with the photo service so the on-demand transform
109
+ * endpoint resolves to optimized variants. The returned
110
+ * `optimized_url_promise` resolves once the optimizer finishes.
111
+ * - everything else → `client.storage.uploadPrivate()` — a private,
112
+ * uncompressed, fail-closed upload to generic storage.
113
+ *
114
+ * **Default visibility is `is_public: false`.** Public is opt-in per call.
115
+ * `useMedia()` does not expose `is_public` via app-level config — visibility
116
+ * is always an explicit per-call surface choice.
117
+ *
118
+ * Compared to `useContent()`:
119
+ * - `useContent()` is a thin wrapper over generic storage and does not
120
+ * register photos / videos with their typed services. Use it for plain
121
+ * file uploads where you don't need optimization or transcoding.
122
+ * - `useMedia()` defaults to private + no compression, integrates with the
123
+ * typed media services automatically, and is the right primitive for
124
+ * anything chat- or media-shaped.
125
+ *
126
+ * @example
127
+ * ```tsx
128
+ * 'use client';
129
+ *
130
+ * import { useMedia, ScaleMuleMedia } from '@scalemule/nextjs';
131
+ *
132
+ * function ChatComposer({ onAttach }) {
133
+ * const { upload, uploading } = useMedia();
134
+ *
135
+ * async function handlePick(file: File) {
136
+ * const result = await upload(file);
137
+ * onAttach({
138
+ * file_id: result.file_id,
139
+ * mime_type: result.mime_type,
140
+ * optimized_url_promise: result.optimized_url_promise,
141
+ * });
142
+ * }
143
+ *
144
+ * return <input type="file" disabled={uploading}
145
+ * onChange={(e) => e.target.files?.[0] && handlePick(e.target.files[0])} />;
146
+ * }
147
+ * ```
148
+ *
149
+ * See `docs/MEDIA-UPLOADS.md` in the platform repo for the decision
150
+ * tree and the full anti-patterns list.
151
+ */
152
+ declare function useMedia(): UseMediaReturn;
153
+
12
154
  interface ScaleMuleContextValue {
13
155
  /** The API client instance */
14
156
  client: ScaleMuleClient;
@@ -22,6 +164,12 @@ interface ScaleMuleContextValue {
22
164
  photo: PhotoService;
23
165
  /** Base SDK video service — exposed for `useMedia()` and `video.uploadViaStorage()` */
24
166
  video: VideoService;
167
+ /**
168
+ * Default media policy for `useMedia()` calls. Set via
169
+ * `<ScaleMuleProvider mediaPolicy="…">`; per-call overrides win.
170
+ * Undefined falls back to `useMedia()`'s built-in `safe_visible` default.
171
+ */
172
+ mediaPolicy?: MediaPolicy;
25
173
  /** Current authenticated user */
26
174
  user: User | null;
27
175
  /** Set the current user */
@@ -29,9 +177,9 @@ interface ScaleMuleContextValue {
29
177
  /** Whether the SDK is initializing */
30
178
  initializing: boolean;
31
179
  /** Last error */
32
- error: ApiError | null;
180
+ error: ApiError$1 | null;
33
181
  /** Set error */
34
- setError: (error: ApiError | null) => void;
182
+ setError: (error: ApiError$1 | null) => void;
35
183
  /** Analytics proxy URL (when set, SDK sends events here instead of ScaleMule) */
36
184
  analyticsProxyUrl?: string;
37
185
  /** Auth proxy URL (when set, auth operations route through this proxy) */
@@ -56,11 +204,27 @@ interface ScaleMuleProviderProps extends ScaleMuleConfig {
56
204
  /** Called when user logs out */
57
205
  onLogout?: () => void;
58
206
  /** Called on authentication error */
59
- onAuthError?: (error: ApiError) => void;
207
+ onAuthError?: (error: ApiError$1) => void;
60
208
  /** Server-evaluated flag values to bootstrap the client (eliminates loading flash) */
61
209
  bootstrapFlags?: Record<string, unknown>;
210
+ /**
211
+ * Default media-pipeline policy applied to `useMedia()` calls when no
212
+ * per-call `policy` override is given. Five modes — see
213
+ * `docs/MEDIA-UPLOADS.md` and the {@link import('./hooks/useMedia').MediaPolicy} type.
214
+ *
215
+ * The platform stores the per-app policy in
216
+ * `application_storage_settings.media_policy` (Phase 4 / P3, live in
217
+ * prod). That endpoint is `MemberOnly` admin-auth, so end-user-context
218
+ * provider can't fetch it directly — apps that want policy-driven
219
+ * defaults should declare the value here, mirroring whatever the
220
+ * platform admin set.
221
+ *
222
+ * Default: undefined → `useMedia()` falls back to its built-in
223
+ * `safe_visible` default.
224
+ */
225
+ mediaPolicy?: MediaPolicy;
62
226
  }
63
- declare function ScaleMuleProvider({ apiKey, applicationId, environment, gatewayUrl, debug, storage, analyticsProxyUrl, authProxyUrl, publishableKey, enableAccountSwitcher, accountSwitcherPrivacy, children, onLogin, onLogout, onAuthError, bootstrapFlags, }: ScaleMuleProviderProps): react_jsx_runtime.JSX.Element;
227
+ declare function ScaleMuleProvider({ apiKey, applicationId, environment, gatewayUrl, debug, storage, analyticsProxyUrl, authProxyUrl, publishableKey, enableAccountSwitcher, accountSwitcherPrivacy, children, onLogin, onLogout, onAuthError, bootstrapFlags, mediaPolicy, }: ScaleMuleProviderProps): react_jsx_runtime.JSX.Element;
64
228
  declare function useScaleMule(): ScaleMuleContextValue;
65
229
  declare function useScaleMuleClient(): ScaleMuleClient;
66
230
  declare function useMoneyClient(): MoneyClient;
@@ -158,148 +322,6 @@ interface UseContentOptions {
158
322
  */
159
323
  declare function useContent(options?: UseContentOptions): UseContentReturn;
160
324
 
161
- /**
162
- * Result of a single {@link useMedia} upload call.
163
- *
164
- * The shape is normalized regardless of MIME type — `optimized_url_promise`
165
- * resolves on image uploads after the photo optimizer finishes; for non-image
166
- * uploads it resolves to `null` immediately. (Video / audio branches will
167
- * populate `hls_url_promise` in later phases — today they fall through to
168
- * generic storage and that field stays `null`.)
169
- */
170
- interface MediaUploadResult {
171
- /** Storage file_id — store this in chat-attachment metadata. */
172
- file_id: string;
173
- /** Photo service id — null for non-image uploads or when register() failed. */
174
- photo_id: string | null;
175
- /** Short-lived signed URL to the original bytes (private uploads) or
176
- * a public CDN URL (when caller passed `is_public: true`). */
177
- original_view_url: string | null;
178
- /** Resolves once the photo optimizer finishes. `null` for non-image
179
- * MIME types or when register() failed. */
180
- optimized_url_promise: Promise<string | null>;
181
- /** Resolves once the video transcoder finishes (Phase 2 / S5b). `null` today. */
182
- hls_url_promise: Promise<string | null>;
183
- /** The file's MIME type — preserved from the input File / Blob. */
184
- mime_type: string;
185
- /** Whether the resulting storage object is public-readable. */
186
- is_public: boolean;
187
- }
188
- /**
189
- * Per-app media-pipeline policy. Drives release-gating + processing
190
- * behavior. **Orthogonal to `is_public`.** See
191
- * `docs/MEDIA-UPLOADS.md` and ADR-2026-04-26 for the full taxonomy.
192
- *
193
- * Today's behavior (Phase 4 v1):
194
- * - `fast_trusted` / `safe_visible` (default): upload promise resolves
195
- * as soon as the file is uploaded + registered. The post-processing
196
- * (scan, optimize, transcode) runs async; callers can observe via
197
- * `useFileStatus`.
198
- * - `safe_public` / `moderated`: upload promise *waits* for the
199
- * optimized image variant (image MIME) or HLS playlist (video MIME)
200
- * to become ready before resolving. Acts as the release-gate for
201
- * UGC-style apps that should not publish raw bytes.
202
- * - `compliance`: today behaves as `safe_public`; Phase 4+ adds the
203
- * audit-log + signed-with-purpose URL semantics.
204
- */
205
- type MediaPolicy = 'fast_trusted' | 'safe_visible' | 'safe_public' | 'moderated' | 'compliance';
206
- interface UseMediaUploadOptions {
207
- /** Whether the resulting storage object should be public-readable.
208
- * Default: `false` (private). Public is opt-in for surfaces that
209
- * genuinely need it (avatars, public listings). Chat / DM uploads
210
- * should always be private. */
211
- is_public?: boolean;
212
- /**
213
- * Per-call media-policy override. Defaults to `safe_visible` (visible
214
- * immediately at original fidelity; optimized variants swap in async).
215
- * Set to `safe_public` to make the upload promise *await* the optimized
216
- * variant (image) or HLS playlist (video) before resolving — useful for
217
- * broadcast / UGC apps that gate publication on processing complete.
218
- *
219
- * The per-app default lives in `application_storage_settings.media_policy`
220
- * (Phase 4 / P3, live in prod 2026-04-26). Reading the per-app default
221
- * into `useMedia` defaults lands in a follow-up; today the option is
222
- * caller-provided per call.
223
- */
224
- policy?: MediaPolicy;
225
- /** Display filename (sanitized server-side). */
226
- filename?: string;
227
- /** Custom metadata attached to the file. */
228
- metadata?: Record<string, unknown>;
229
- /** Upload progress callback (0-100). */
230
- onProgress?: (percent: number) => void;
231
- /** AbortSignal for cancellation. */
232
- signal?: AbortSignal;
233
- /** Force a non-photo path even for image MIME types — useful for
234
- * generic file uploads where you don't want the photo optimizer
235
- * to register the file. Default: `false`. */
236
- skipPhotoRegister?: boolean;
237
- }
238
- interface UseMediaReturn {
239
- /** Upload a file. MIME-aware: images go through photo register +
240
- * optimization; everything else goes through generic storage. */
241
- upload: (file: File | Blob, options?: UseMediaUploadOptions) => Promise<MediaUploadResult>;
242
- /** Cancel an upload by its `file_id`. Deletes the storage object so
243
- * it doesn't orphan in S3 — useful when a chat composer accepts a
244
- * file but the user removes it before sending. Idempotent. */
245
- cancelUpload: (fileId: string) => Promise<void>;
246
- /** Last error from `upload` or `cancelUpload`. */
247
- error: ApiError$1 | null;
248
- /** True while an upload is in progress. */
249
- uploading: boolean;
250
- }
251
- /**
252
- * Opinionated, MIME-aware media upload hook.
253
- *
254
- * `useMedia()` is the canonical upload primitive for chat / progressive
255
- * media use. It branches by MIME type:
256
- * - `image/*` → `client.photo.uploadViaStorage()` — upload to storage,
257
- * then register with the photo service so the on-demand transform
258
- * endpoint resolves to optimized variants. The returned
259
- * `optimized_url_promise` resolves once the optimizer finishes.
260
- * - everything else → `client.storage.uploadPrivate()` — a private,
261
- * uncompressed, fail-closed upload to generic storage.
262
- *
263
- * **Default visibility is `is_public: false`.** Public is opt-in per call.
264
- * `useMedia()` does not expose `is_public` via app-level config — visibility
265
- * is always an explicit per-call surface choice.
266
- *
267
- * Compared to `useContent()`:
268
- * - `useContent()` is a thin wrapper over generic storage and does not
269
- * register photos / videos with their typed services. Use it for plain
270
- * file uploads where you don't need optimization or transcoding.
271
- * - `useMedia()` defaults to private + no compression, integrates with the
272
- * typed media services automatically, and is the right primitive for
273
- * anything chat- or media-shaped.
274
- *
275
- * @example
276
- * ```tsx
277
- * 'use client';
278
- *
279
- * import { useMedia, ScaleMuleMedia } from '@scalemule/nextjs';
280
- *
281
- * function ChatComposer({ onAttach }) {
282
- * const { upload, uploading } = useMedia();
283
- *
284
- * async function handlePick(file: File) {
285
- * const result = await upload(file);
286
- * onAttach({
287
- * file_id: result.file_id,
288
- * mime_type: result.mime_type,
289
- * optimized_url_promise: result.optimized_url_promise,
290
- * });
291
- * }
292
- *
293
- * return <input type="file" disabled={uploading}
294
- * onChange={(e) => e.target.files?.[0] && handlePick(e.target.files[0])} />;
295
- * }
296
- * ```
297
- *
298
- * See `docs/MEDIA-UPLOADS.md` in the platform repo for the decision
299
- * tree and the full anti-patterns list.
300
- */
301
- declare function useMedia(): UseMediaReturn;
302
-
303
325
  interface UseFileStatusOptions {
304
326
  /** Storage file_id to read status for. */
305
327
  fileId: string | null | undefined;
@@ -326,7 +348,7 @@ interface UseFileStatusReturn {
326
348
  /** True while a fetch is in flight. */
327
349
  loading: boolean;
328
350
  /** Last error, or null. */
329
- error: ApiError$1 | null;
351
+ error: ApiError | null;
330
352
  /**
331
353
  * Convenience: scan is clean. For images/videos, this means the file
332
354
  * is *safe to render*; the optimized / HLS variants may still be
@@ -586,7 +608,7 @@ interface UseFeatureFlagsOptions {
586
608
  interface UseFeatureFlagsReturn {
587
609
  flags: Record<string, FeatureFlagEvaluation>;
588
610
  loading: boolean;
589
- error: ApiError | null;
611
+ error: ApiError$1 | null;
590
612
  refresh: () => Promise<void>;
591
613
  isEnabled: (flagKey: string, fallback?: boolean) => boolean;
592
614
  getFlag: <T = unknown>(flagKey: string, fallback?: T) => T;
@@ -613,7 +635,7 @@ interface UsePushNotificationsReturn {
613
635
  /** Whether an operation is in progress */
614
636
  isLoading: boolean;
615
637
  /** Last error */
616
- error: ApiError | null;
638
+ error: ApiError$1 | null;
617
639
  /** Request permission and subscribe to push notifications */
618
640
  subscribe: () => Promise<void>;
619
641
  /** Unsubscribe from push notifications */
@@ -714,7 +736,7 @@ interface UseFeedbackResult {
714
736
  /** End-user's own feedback items for the current tenant. Empty when not signed in. */
715
737
  items: FeedbackItem[];
716
738
  loading: boolean;
717
- error: ApiError | null;
739
+ error: ApiError$1 | null;
718
740
  /** Submit a new feedback item. Returns the persisted item on success. */
719
741
  submit: (input: FeedbackItemInput) => Promise<FeedbackItem>;
720
742
  /** Re-fetch the list. */
@@ -926,4 +948,4 @@ declare function createSafeLogger(prefix: string): {
926
948
  error: (message: string, data?: unknown) => void;
927
949
  };
928
950
 
929
- export { ApiError, type FeatureFlagEvaluation, type FeatureFlagEvaluation as FeatureFlagResult, type FeedbackItem, type FeedbackItemInput, type FeedbackPriority, type FeedbackStatus, type FeedbackType, FeedbackWidget, type FeedbackWidgetConfig, type FeedbackWidgetProps, ListFilesParams, LoginResponse, type MediaPolicy, type MediaUploadResult, type PasswordValidationResult, type PhoneCountry, type PhoneValidationResult, type RealtimeEvent, type RealtimeMessage, type RealtimeStatus, ScaleMuleClient, ScaleMuleConfig, ScaleMuleMedia, type ScaleMuleMediaProps, ScaleMuleProvider, type ScaleMuleProviderProps, UseAnalyticsOptions, UseAnalyticsReturn, UseAuthReturn, UseBillingReturn, UseContentReturn, type UseFeatureFlagsOptions, type UseFeatureFlagsReturn, type UseFeedbackOptions, type UseFeedbackResult, type UseFileStatusOptions, type UseFileStatusReturn, type UseFeatureFlagsOptions as UseFlagsOptions, type UseFeatureFlagsReturn as UseFlagsReturn, type UseMediaReturn, type UseMediaUploadOptions, type UsePushNotificationsOptions, type UsePushNotificationsReturn, type UseRealtimeOptions, type UseRealtimeReturn, type UseShareOptions, type UseShareReturn, UseUserReturn, User, type UsernameValidationResult, composePhone, createSafeLogger, normalizePhone, phoneCountries, sanitizeForLog, useAnalytics, useAuth, useBilling, useContent, useFeatureFlags, useFeedback, useFileStatus, useMedia, useMoney, useMoneyClient, usePushNotifications, useRealtime, useScaleMule, useScaleMuleClient, useShare, useUser, validateForm, validators };
951
+ export { ApiError$1 as ApiError, type FeatureFlagEvaluation, type FeatureFlagEvaluation as FeatureFlagResult, type FeedbackItem, type FeedbackItemInput, type FeedbackPriority, type FeedbackStatus, type FeedbackType, FeedbackWidget, type FeedbackWidgetConfig, type FeedbackWidgetProps, ListFilesParams, LoginResponse, type MediaPolicy, type MediaUploadResult, type PasswordValidationResult, type PhoneCountry, type PhoneValidationResult, type RealtimeEvent, type RealtimeMessage, type RealtimeStatus, ScaleMuleClient, ScaleMuleConfig, ScaleMuleMedia, type ScaleMuleMediaProps, ScaleMuleProvider, type ScaleMuleProviderProps, UseAnalyticsOptions, UseAnalyticsReturn, UseAuthReturn, UseBillingReturn, UseContentReturn, type UseFeatureFlagsOptions, type UseFeatureFlagsReturn, type UseFeedbackOptions, type UseFeedbackResult, type UseFileStatusOptions, type UseFileStatusReturn, type UseFeatureFlagsOptions as UseFlagsOptions, type UseFeatureFlagsReturn as UseFlagsReturn, type UseMediaReturn, type UseMediaUploadOptions, type UsePushNotificationsOptions, type UsePushNotificationsReturn, type UseRealtimeOptions, type UseRealtimeReturn, type UseShareOptions, type UseShareReturn, UseUserReturn, User, type UsernameValidationResult, composePhone, createSafeLogger, normalizePhone, phoneCountries, sanitizeForLog, useAnalytics, useAuth, useBilling, useContent, useFeatureFlags, useFeedback, useFileStatus, useMedia, useMoney, useMoneyClient, usePushNotifications, useRealtime, useScaleMule, useScaleMuleClient, useShare, useUser, validateForm, validators };
package/dist/index.js CHANGED
@@ -7445,7 +7445,8 @@ function ScaleMuleProvider({
7445
7445
  onLogin,
7446
7446
  onLogout,
7447
7447
  onAuthError,
7448
- bootstrapFlags
7448
+ bootstrapFlags,
7449
+ mediaPolicy
7449
7450
  }) {
7450
7451
  const [user, setUser] = React.useState(null);
7451
7452
  const [initializing, setInitializing] = React.useState(true);
@@ -7584,6 +7585,7 @@ function ScaleMuleProvider({
7584
7585
  storage: baseClient.storage,
7585
7586
  photo: baseClient.photo,
7586
7587
  video: baseClient.video,
7588
+ mediaPolicy,
7587
7589
  user,
7588
7590
  setUser: handleSetUser,
7589
7591
  initializing,
@@ -7598,7 +7600,7 @@ function ScaleMuleProvider({
7598
7600
  accountSwitcherPrivacy,
7599
7601
  bootstrapFlags
7600
7602
  }),
7601
- [client, money$1, baseClient, user, handleSetUser, initializing, error, analyticsProxyUrl, authProxyUrl, publishableKey, resolvedGatewayUrl, environment, enableAccountSwitcher, accountSwitcherPrivacy, bootstrapFlags]
7603
+ [client, money$1, baseClient, user, handleSetUser, initializing, error, analyticsProxyUrl, authProxyUrl, publishableKey, resolvedGatewayUrl, environment, enableAccountSwitcher, accountSwitcherPrivacy, bootstrapFlags, mediaPolicy]
7602
7604
  );
7603
7605
  return /* @__PURE__ */ jsxRuntime.jsx(ScaleMuleContext.Provider, { value, children });
7604
7606
  }
@@ -8897,7 +8899,7 @@ function useContent(options = {}) {
8897
8899
  );
8898
8900
  }
8899
8901
  function useMedia() {
8900
- const { storage, photo, video } = useScaleMule();
8902
+ const { storage, photo, video, mediaPolicy: providerDefaultPolicy } = useScaleMule();
8901
8903
  const [uploading, setUploading] = React.useState(false);
8902
8904
  const [error, setError] = React.useState(null);
8903
8905
  const upload = React.useCallback(
@@ -8906,7 +8908,7 @@ function useMedia() {
8906
8908
  setError(null);
8907
8909
  const isPublic = options?.is_public ?? false;
8908
8910
  const mimeType = file.type || "application/octet-stream";
8909
- const policy = options?.policy ?? "safe_visible";
8911
+ const policy = options?.policy ?? providerDefaultPolicy ?? "safe_visible";
8910
8912
  const gateOnPipeline = policy === "safe_public" || policy === "moderated" || policy === "compliance";
8911
8913
  const sharedOpts = {
8912
8914
  filename: options?.filename,
@@ -8993,7 +8995,7 @@ function useMedia() {
8993
8995
  setUploading(false);
8994
8996
  }
8995
8997
  },
8996
- [storage, photo]
8998
+ [storage, photo, video, providerDefaultPolicy]
8997
8999
  );
8998
9000
  const cancelUpload = React.useCallback(
8999
9001
  async (fileId) => {
package/dist/index.mjs CHANGED
@@ -7425,7 +7425,8 @@ function ScaleMuleProvider({
7425
7425
  onLogin,
7426
7426
  onLogout,
7427
7427
  onAuthError,
7428
- bootstrapFlags
7428
+ bootstrapFlags,
7429
+ mediaPolicy
7429
7430
  }) {
7430
7431
  const [user, setUser] = useState(null);
7431
7432
  const [initializing, setInitializing] = useState(true);
@@ -7564,6 +7565,7 @@ function ScaleMuleProvider({
7564
7565
  storage: baseClient.storage,
7565
7566
  photo: baseClient.photo,
7566
7567
  video: baseClient.video,
7568
+ mediaPolicy,
7567
7569
  user,
7568
7570
  setUser: handleSetUser,
7569
7571
  initializing,
@@ -7578,7 +7580,7 @@ function ScaleMuleProvider({
7578
7580
  accountSwitcherPrivacy,
7579
7581
  bootstrapFlags
7580
7582
  }),
7581
- [client, money, baseClient, user, handleSetUser, initializing, error, analyticsProxyUrl, authProxyUrl, publishableKey, resolvedGatewayUrl, environment, enableAccountSwitcher, accountSwitcherPrivacy, bootstrapFlags]
7583
+ [client, money, baseClient, user, handleSetUser, initializing, error, analyticsProxyUrl, authProxyUrl, publishableKey, resolvedGatewayUrl, environment, enableAccountSwitcher, accountSwitcherPrivacy, bootstrapFlags, mediaPolicy]
7582
7584
  );
7583
7585
  return /* @__PURE__ */ jsx(ScaleMuleContext.Provider, { value, children });
7584
7586
  }
@@ -8877,7 +8879,7 @@ function useContent(options = {}) {
8877
8879
  );
8878
8880
  }
8879
8881
  function useMedia() {
8880
- const { storage, photo, video } = useScaleMule();
8882
+ const { storage, photo, video, mediaPolicy: providerDefaultPolicy } = useScaleMule();
8881
8883
  const [uploading, setUploading] = useState(false);
8882
8884
  const [error, setError] = useState(null);
8883
8885
  const upload = useCallback(
@@ -8886,7 +8888,7 @@ function useMedia() {
8886
8888
  setError(null);
8887
8889
  const isPublic = options?.is_public ?? false;
8888
8890
  const mimeType = file.type || "application/octet-stream";
8889
- const policy = options?.policy ?? "safe_visible";
8891
+ const policy = options?.policy ?? providerDefaultPolicy ?? "safe_visible";
8890
8892
  const gateOnPipeline = policy === "safe_public" || policy === "moderated" || policy === "compliance";
8891
8893
  const sharedOpts = {
8892
8894
  filename: options?.filename,
@@ -8973,7 +8975,7 @@ function useMedia() {
8973
8975
  setUploading(false);
8974
8976
  }
8975
8977
  },
8976
- [storage, photo]
8978
+ [storage, photo, video, providerDefaultPolicy]
8977
8979
  );
8978
8980
  const cancelUpload = useCallback(
8979
8981
  async (fileId) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scalemule/nextjs",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "ScaleMule SDK for Next.js applications - authentication, storage, and user management",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -49,7 +49,8 @@
49
49
  "test:watch": "vitest",
50
50
  "type-check": "tsc --noEmit",
51
51
  "lint": "tsc --noEmit",
52
- "clean": "rm -rf dist"
52
+ "clean": "rm -rf dist",
53
+ "prepublishOnly": "node -e \"const v=require('./package.json').version; if(!/^0\\.(0|1)\\.\\d+$/.test(v)){console.error('ERR: SDK '+v+' violates patch-only policy (0.0.x or 0.1.x only). See CONTRIBUTING.md SDK versioning section.');process.exit(1)}\""
53
54
  },
54
55
  "dependencies": {
55
56
  "@scalemule/money": "^0.0.1",