@scalemule/nextjs 0.1.7 → 0.1.8
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 +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +104 -2
- package/dist/index.mjs +104 -2
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { ApiError, RealtimeService, StorageService, PhotoService, VideoService, FileStatus } from '@scalemule/sdk';
|
|
2
|
+
import { ApiError, RealtimeService, StorageService, PhotoService, VideoService, AudioService, FileStatus } from '@scalemule/sdk';
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { ReactNode, ReactElement } from 'react';
|
|
5
5
|
import { MoneyClient } from '@scalemule/money';
|
|
@@ -164,6 +164,8 @@ interface ScaleMuleContextValue {
|
|
|
164
164
|
photo: PhotoService;
|
|
165
165
|
/** Base SDK video service — exposed for `useMedia()` and `video.uploadViaStorage()` */
|
|
166
166
|
video: VideoService;
|
|
167
|
+
/** Base SDK audio service — exposed for `useMedia()` and `audio.uploadViaStorage()` */
|
|
168
|
+
audio: AudioService;
|
|
167
169
|
/**
|
|
168
170
|
* Default media policy for `useMedia()` calls. Set via
|
|
169
171
|
* `<ScaleMuleProvider mediaPolicy="…">`; per-call overrides win.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { ApiError, RealtimeService, StorageService, PhotoService, VideoService, FileStatus } from '@scalemule/sdk';
|
|
2
|
+
import { ApiError, RealtimeService, StorageService, PhotoService, VideoService, AudioService, FileStatus } from '@scalemule/sdk';
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { ReactNode, ReactElement } from 'react';
|
|
5
5
|
import { MoneyClient } from '@scalemule/money';
|
|
@@ -164,6 +164,8 @@ interface ScaleMuleContextValue {
|
|
|
164
164
|
photo: PhotoService;
|
|
165
165
|
/** Base SDK video service — exposed for `useMedia()` and `video.uploadViaStorage()` */
|
|
166
166
|
video: VideoService;
|
|
167
|
+
/** Base SDK audio service — exposed for `useMedia()` and `audio.uploadViaStorage()` */
|
|
168
|
+
audio: AudioService;
|
|
167
169
|
/**
|
|
168
170
|
* Default media policy for `useMedia()` calls. Set via
|
|
169
171
|
* `<ScaleMuleProvider mediaPolicy="…">`; per-call overrides win.
|
package/dist/index.js
CHANGED
|
@@ -2727,6 +2727,25 @@ var StorageService = class extends ServiceModule {
|
|
|
2727
2727
|
async getInfo(fileId, options) {
|
|
2728
2728
|
return this._get(`/files/${fileId}/info`, options);
|
|
2729
2729
|
}
|
|
2730
|
+
/**
|
|
2731
|
+
* Get the calling app's storage + media settings — content policy,
|
|
2732
|
+
* retention, max upload size, and the per-app `media_policy`.
|
|
2733
|
+
*
|
|
2734
|
+
* `media_policy` drives release-gating in the SDK upload helpers:
|
|
2735
|
+
* `fast_trusted` / `safe_visible` resolve immediately on upload; the
|
|
2736
|
+
* `safe_public` / `moderated` / `compliance` modes await pipeline
|
|
2737
|
+
* completion before resolving the upload promise.
|
|
2738
|
+
*/
|
|
2739
|
+
async getSettings(options) {
|
|
2740
|
+
return this._get("/settings", options);
|
|
2741
|
+
}
|
|
2742
|
+
/**
|
|
2743
|
+
* Update the calling app's storage + media settings. Admin-only on the
|
|
2744
|
+
* platform side (callers without the right role get 403).
|
|
2745
|
+
*/
|
|
2746
|
+
async updateSettings(settings, options) {
|
|
2747
|
+
return this.put("/settings", settings, options);
|
|
2748
|
+
}
|
|
2730
2749
|
/**
|
|
2731
2750
|
* Aggregate status for a file — single call returns scan + reserved
|
|
2732
2751
|
* optimize/transcode slots + the canonical view URL paths for image
|
|
@@ -5678,6 +5697,72 @@ var PhotoService = class extends ServiceModule {
|
|
|
5678
5697
|
return this.get(id);
|
|
5679
5698
|
}
|
|
5680
5699
|
};
|
|
5700
|
+
var AudioService = class extends ServiceModule {
|
|
5701
|
+
/**
|
|
5702
|
+
* @param storage Required for {@link uploadViaStorage}. Wired up by the
|
|
5703
|
+
* top-level {@link ScaleMule} constructor — most call sites should not
|
|
5704
|
+
* instantiate `AudioService` directly.
|
|
5705
|
+
*/
|
|
5706
|
+
constructor(client, storage) {
|
|
5707
|
+
super(client);
|
|
5708
|
+
this.storage = storage;
|
|
5709
|
+
this.basePath = "/v1/audios";
|
|
5710
|
+
}
|
|
5711
|
+
/**
|
|
5712
|
+
* Register a storage-uploaded audio asset with the audio service.
|
|
5713
|
+
* Idempotent — re-calling with the same `file_id` returns the existing
|
|
5714
|
+
* record.
|
|
5715
|
+
*/
|
|
5716
|
+
async register(args, options) {
|
|
5717
|
+
return this.post("/register", { file_id: args.fileId, sm_user_id: args.userId }, options);
|
|
5718
|
+
}
|
|
5719
|
+
/**
|
|
5720
|
+
* Upload a file to storage (browser → S3 direct, private, uncompressed)
|
|
5721
|
+
* and register it with the audio service.
|
|
5722
|
+
*
|
|
5723
|
+
* Mirrors `photo.uploadViaStorage()` / `video.uploadViaStorage()`. If
|
|
5724
|
+
* `register()` fails after a successful storage upload, the file is *not*
|
|
5725
|
+
* lost — the returned `file_id` is still valid as a generic private storage
|
|
5726
|
+
* file. The SDK logs a warning and returns `audio_id: null`.
|
|
5727
|
+
*/
|
|
5728
|
+
async uploadViaStorage(file, uploadOptions, requestOptions) {
|
|
5729
|
+
const uploadResult = await this.storage.uploadPrivate(file, {
|
|
5730
|
+
filename: uploadOptions?.filename,
|
|
5731
|
+
metadata: uploadOptions?.metadata,
|
|
5732
|
+
onProgress: uploadOptions?.onProgress,
|
|
5733
|
+
signal: uploadOptions?.signal
|
|
5734
|
+
});
|
|
5735
|
+
if (uploadResult.error || !uploadResult.data) {
|
|
5736
|
+
return { data: null, error: uploadResult.error };
|
|
5737
|
+
}
|
|
5738
|
+
const fileInfo = uploadResult.data;
|
|
5739
|
+
const fileId = fileInfo.id;
|
|
5740
|
+
const originalViewUrl = fileInfo.url ?? null;
|
|
5741
|
+
const registerResult = await this.register({ fileId, userId: uploadOptions?.userId }, requestOptions);
|
|
5742
|
+
if (registerResult.error || !registerResult.data) {
|
|
5743
|
+
console.warn(
|
|
5744
|
+
"[scalemule-sdk] audio.register() failed after storage upload; typed audio metadata unavailable.",
|
|
5745
|
+
registerResult.error
|
|
5746
|
+
);
|
|
5747
|
+
return {
|
|
5748
|
+
data: {
|
|
5749
|
+
file_id: fileId,
|
|
5750
|
+
audio_id: null,
|
|
5751
|
+
original_view_url: originalViewUrl
|
|
5752
|
+
},
|
|
5753
|
+
error: null
|
|
5754
|
+
};
|
|
5755
|
+
}
|
|
5756
|
+
return {
|
|
5757
|
+
data: {
|
|
5758
|
+
file_id: fileId,
|
|
5759
|
+
audio_id: registerResult.data.audio_id,
|
|
5760
|
+
original_view_url: originalViewUrl
|
|
5761
|
+
},
|
|
5762
|
+
error: null
|
|
5763
|
+
};
|
|
5764
|
+
}
|
|
5765
|
+
};
|
|
5681
5766
|
var DeadLetterApi = class extends ServiceModule {
|
|
5682
5767
|
constructor() {
|
|
5683
5768
|
super(...arguments);
|
|
@@ -6497,6 +6582,7 @@ var ScaleMule = class {
|
|
|
6497
6582
|
this.graph = new GraphService(this._client);
|
|
6498
6583
|
this.functions = new FunctionsService(this._client);
|
|
6499
6584
|
this.photo = new PhotoService(this._client, this.storage);
|
|
6585
|
+
this.audio = new AudioService(this._client, this.storage);
|
|
6500
6586
|
this.flagContent = new FlagContentService(this._client);
|
|
6501
6587
|
this.creatorMaker = new CreatorMakerService(this._client);
|
|
6502
6588
|
this.compliance = new ComplianceService(this._client);
|
|
@@ -7585,6 +7671,7 @@ function ScaleMuleProvider({
|
|
|
7585
7671
|
storage: baseClient.storage,
|
|
7586
7672
|
photo: baseClient.photo,
|
|
7587
7673
|
video: baseClient.video,
|
|
7674
|
+
audio: baseClient.audio,
|
|
7588
7675
|
mediaPolicy,
|
|
7589
7676
|
user,
|
|
7590
7677
|
setUser: handleSetUser,
|
|
@@ -8899,7 +8986,7 @@ function useContent(options = {}) {
|
|
|
8899
8986
|
);
|
|
8900
8987
|
}
|
|
8901
8988
|
function useMedia() {
|
|
8902
|
-
const { storage, photo, video, mediaPolicy: providerDefaultPolicy } = useScaleMule();
|
|
8989
|
+
const { storage, photo, video, audio, mediaPolicy: providerDefaultPolicy } = useScaleMule();
|
|
8903
8990
|
const [uploading, setUploading] = React.useState(false);
|
|
8904
8991
|
const [error, setError] = React.useState(null);
|
|
8905
8992
|
const upload = React.useCallback(
|
|
@@ -8953,6 +9040,21 @@ function useMedia() {
|
|
|
8953
9040
|
is_public: false
|
|
8954
9041
|
};
|
|
8955
9042
|
}
|
|
9043
|
+
if (mimeType.startsWith("audio/") && !isPublic) {
|
|
9044
|
+
const r2 = await audio.uploadViaStorage(file, sharedOpts);
|
|
9045
|
+
if (r2.error || !r2.data) {
|
|
9046
|
+
throw r2.error ?? { code: "upload_error", message: "Upload failed", status: 0 };
|
|
9047
|
+
}
|
|
9048
|
+
return {
|
|
9049
|
+
file_id: r2.data.file_id,
|
|
9050
|
+
photo_id: null,
|
|
9051
|
+
original_view_url: r2.data.original_view_url,
|
|
9052
|
+
optimized_url_promise: Promise.resolve(null),
|
|
9053
|
+
hls_url_promise: Promise.resolve(null),
|
|
9054
|
+
mime_type: mimeType,
|
|
9055
|
+
is_public: false
|
|
9056
|
+
};
|
|
9057
|
+
}
|
|
8956
9058
|
if (mimeType.startsWith("image/") && isPublic) {
|
|
8957
9059
|
const r2 = await storage.upload(file, {
|
|
8958
9060
|
...sharedOpts,
|
|
@@ -8995,7 +9097,7 @@ function useMedia() {
|
|
|
8995
9097
|
setUploading(false);
|
|
8996
9098
|
}
|
|
8997
9099
|
},
|
|
8998
|
-
[storage, photo, video, providerDefaultPolicy]
|
|
9100
|
+
[storage, photo, video, audio, providerDefaultPolicy]
|
|
8999
9101
|
);
|
|
9000
9102
|
const cancelUpload = React.useCallback(
|
|
9001
9103
|
async (fileId) => {
|
package/dist/index.mjs
CHANGED
|
@@ -2707,6 +2707,25 @@ var StorageService = class extends ServiceModule {
|
|
|
2707
2707
|
async getInfo(fileId, options) {
|
|
2708
2708
|
return this._get(`/files/${fileId}/info`, options);
|
|
2709
2709
|
}
|
|
2710
|
+
/**
|
|
2711
|
+
* Get the calling app's storage + media settings — content policy,
|
|
2712
|
+
* retention, max upload size, and the per-app `media_policy`.
|
|
2713
|
+
*
|
|
2714
|
+
* `media_policy` drives release-gating in the SDK upload helpers:
|
|
2715
|
+
* `fast_trusted` / `safe_visible` resolve immediately on upload; the
|
|
2716
|
+
* `safe_public` / `moderated` / `compliance` modes await pipeline
|
|
2717
|
+
* completion before resolving the upload promise.
|
|
2718
|
+
*/
|
|
2719
|
+
async getSettings(options) {
|
|
2720
|
+
return this._get("/settings", options);
|
|
2721
|
+
}
|
|
2722
|
+
/**
|
|
2723
|
+
* Update the calling app's storage + media settings. Admin-only on the
|
|
2724
|
+
* platform side (callers without the right role get 403).
|
|
2725
|
+
*/
|
|
2726
|
+
async updateSettings(settings, options) {
|
|
2727
|
+
return this.put("/settings", settings, options);
|
|
2728
|
+
}
|
|
2710
2729
|
/**
|
|
2711
2730
|
* Aggregate status for a file — single call returns scan + reserved
|
|
2712
2731
|
* optimize/transcode slots + the canonical view URL paths for image
|
|
@@ -5658,6 +5677,72 @@ var PhotoService = class extends ServiceModule {
|
|
|
5658
5677
|
return this.get(id);
|
|
5659
5678
|
}
|
|
5660
5679
|
};
|
|
5680
|
+
var AudioService = class extends ServiceModule {
|
|
5681
|
+
/**
|
|
5682
|
+
* @param storage Required for {@link uploadViaStorage}. Wired up by the
|
|
5683
|
+
* top-level {@link ScaleMule} constructor — most call sites should not
|
|
5684
|
+
* instantiate `AudioService` directly.
|
|
5685
|
+
*/
|
|
5686
|
+
constructor(client, storage) {
|
|
5687
|
+
super(client);
|
|
5688
|
+
this.storage = storage;
|
|
5689
|
+
this.basePath = "/v1/audios";
|
|
5690
|
+
}
|
|
5691
|
+
/**
|
|
5692
|
+
* Register a storage-uploaded audio asset with the audio service.
|
|
5693
|
+
* Idempotent — re-calling with the same `file_id` returns the existing
|
|
5694
|
+
* record.
|
|
5695
|
+
*/
|
|
5696
|
+
async register(args, options) {
|
|
5697
|
+
return this.post("/register", { file_id: args.fileId, sm_user_id: args.userId }, options);
|
|
5698
|
+
}
|
|
5699
|
+
/**
|
|
5700
|
+
* Upload a file to storage (browser → S3 direct, private, uncompressed)
|
|
5701
|
+
* and register it with the audio service.
|
|
5702
|
+
*
|
|
5703
|
+
* Mirrors `photo.uploadViaStorage()` / `video.uploadViaStorage()`. If
|
|
5704
|
+
* `register()` fails after a successful storage upload, the file is *not*
|
|
5705
|
+
* lost — the returned `file_id` is still valid as a generic private storage
|
|
5706
|
+
* file. The SDK logs a warning and returns `audio_id: null`.
|
|
5707
|
+
*/
|
|
5708
|
+
async uploadViaStorage(file, uploadOptions, requestOptions) {
|
|
5709
|
+
const uploadResult = await this.storage.uploadPrivate(file, {
|
|
5710
|
+
filename: uploadOptions?.filename,
|
|
5711
|
+
metadata: uploadOptions?.metadata,
|
|
5712
|
+
onProgress: uploadOptions?.onProgress,
|
|
5713
|
+
signal: uploadOptions?.signal
|
|
5714
|
+
});
|
|
5715
|
+
if (uploadResult.error || !uploadResult.data) {
|
|
5716
|
+
return { data: null, error: uploadResult.error };
|
|
5717
|
+
}
|
|
5718
|
+
const fileInfo = uploadResult.data;
|
|
5719
|
+
const fileId = fileInfo.id;
|
|
5720
|
+
const originalViewUrl = fileInfo.url ?? null;
|
|
5721
|
+
const registerResult = await this.register({ fileId, userId: uploadOptions?.userId }, requestOptions);
|
|
5722
|
+
if (registerResult.error || !registerResult.data) {
|
|
5723
|
+
console.warn(
|
|
5724
|
+
"[scalemule-sdk] audio.register() failed after storage upload; typed audio metadata unavailable.",
|
|
5725
|
+
registerResult.error
|
|
5726
|
+
);
|
|
5727
|
+
return {
|
|
5728
|
+
data: {
|
|
5729
|
+
file_id: fileId,
|
|
5730
|
+
audio_id: null,
|
|
5731
|
+
original_view_url: originalViewUrl
|
|
5732
|
+
},
|
|
5733
|
+
error: null
|
|
5734
|
+
};
|
|
5735
|
+
}
|
|
5736
|
+
return {
|
|
5737
|
+
data: {
|
|
5738
|
+
file_id: fileId,
|
|
5739
|
+
audio_id: registerResult.data.audio_id,
|
|
5740
|
+
original_view_url: originalViewUrl
|
|
5741
|
+
},
|
|
5742
|
+
error: null
|
|
5743
|
+
};
|
|
5744
|
+
}
|
|
5745
|
+
};
|
|
5661
5746
|
var DeadLetterApi = class extends ServiceModule {
|
|
5662
5747
|
constructor() {
|
|
5663
5748
|
super(...arguments);
|
|
@@ -6477,6 +6562,7 @@ var ScaleMule = class {
|
|
|
6477
6562
|
this.graph = new GraphService(this._client);
|
|
6478
6563
|
this.functions = new FunctionsService(this._client);
|
|
6479
6564
|
this.photo = new PhotoService(this._client, this.storage);
|
|
6565
|
+
this.audio = new AudioService(this._client, this.storage);
|
|
6480
6566
|
this.flagContent = new FlagContentService(this._client);
|
|
6481
6567
|
this.creatorMaker = new CreatorMakerService(this._client);
|
|
6482
6568
|
this.compliance = new ComplianceService(this._client);
|
|
@@ -7565,6 +7651,7 @@ function ScaleMuleProvider({
|
|
|
7565
7651
|
storage: baseClient.storage,
|
|
7566
7652
|
photo: baseClient.photo,
|
|
7567
7653
|
video: baseClient.video,
|
|
7654
|
+
audio: baseClient.audio,
|
|
7568
7655
|
mediaPolicy,
|
|
7569
7656
|
user,
|
|
7570
7657
|
setUser: handleSetUser,
|
|
@@ -8879,7 +8966,7 @@ function useContent(options = {}) {
|
|
|
8879
8966
|
);
|
|
8880
8967
|
}
|
|
8881
8968
|
function useMedia() {
|
|
8882
|
-
const { storage, photo, video, mediaPolicy: providerDefaultPolicy } = useScaleMule();
|
|
8969
|
+
const { storage, photo, video, audio, mediaPolicy: providerDefaultPolicy } = useScaleMule();
|
|
8883
8970
|
const [uploading, setUploading] = useState(false);
|
|
8884
8971
|
const [error, setError] = useState(null);
|
|
8885
8972
|
const upload = useCallback(
|
|
@@ -8933,6 +9020,21 @@ function useMedia() {
|
|
|
8933
9020
|
is_public: false
|
|
8934
9021
|
};
|
|
8935
9022
|
}
|
|
9023
|
+
if (mimeType.startsWith("audio/") && !isPublic) {
|
|
9024
|
+
const r2 = await audio.uploadViaStorage(file, sharedOpts);
|
|
9025
|
+
if (r2.error || !r2.data) {
|
|
9026
|
+
throw r2.error ?? { code: "upload_error", message: "Upload failed", status: 0 };
|
|
9027
|
+
}
|
|
9028
|
+
return {
|
|
9029
|
+
file_id: r2.data.file_id,
|
|
9030
|
+
photo_id: null,
|
|
9031
|
+
original_view_url: r2.data.original_view_url,
|
|
9032
|
+
optimized_url_promise: Promise.resolve(null),
|
|
9033
|
+
hls_url_promise: Promise.resolve(null),
|
|
9034
|
+
mime_type: mimeType,
|
|
9035
|
+
is_public: false
|
|
9036
|
+
};
|
|
9037
|
+
}
|
|
8936
9038
|
if (mimeType.startsWith("image/") && isPublic) {
|
|
8937
9039
|
const r2 = await storage.upload(file, {
|
|
8938
9040
|
...sharedOpts,
|
|
@@ -8975,7 +9077,7 @@ function useMedia() {
|
|
|
8975
9077
|
setUploading(false);
|
|
8976
9078
|
}
|
|
8977
9079
|
},
|
|
8978
|
-
[storage, photo, video, providerDefaultPolicy]
|
|
9080
|
+
[storage, photo, video, audio, providerDefaultPolicy]
|
|
8979
9081
|
);
|
|
8980
9082
|
const cancelUpload = useCallback(
|
|
8981
9083
|
async (fileId) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scalemule/nextjs",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
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",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
56
|
"@scalemule/money": "^0.0.1",
|
|
57
|
-
"@scalemule/sdk": "^0.0.
|
|
57
|
+
"@scalemule/sdk": "^0.0.43"
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
60
|
"next": ">=14.0.0",
|