@sogni-ai/sogni-client 5.41.0 → 5.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -0
- package/CHANGELOG.md +7 -0
- package/README.md +28 -0
- package/dist/Projects/ReusableUploads.d.ts +47 -0
- package/dist/Projects/ReusableUploads.js +210 -0
- package/dist/Projects/ReusableUploads.js.map +1 -0
- package/dist/Projects/index.d.ts +4 -0
- package/dist/Projects/index.js +25 -0
- package/dist/Projects/index.js.map +1 -1
- package/dist/Projects/types/RawProject.d.ts +15 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/RestClient.d.ts +1 -0
- package/dist/lib/RestClient.js +3 -0
- package/dist/lib/RestClient.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist-esm/Projects/ReusableUploads.js +207 -0
- package/dist-esm/Projects/ReusableUploads.js.map +1 -0
- package/dist-esm/Projects/index.js +25 -0
- package/dist-esm/Projects/index.js.map +1 -1
- package/dist-esm/index.js.map +1 -1
- package/dist-esm/lib/RestClient.js +3 -0
- package/dist-esm/lib/RestClient.js.map +1 -1
- package/dist-esm/version.js +1 -1
- package/llms-full.txt +21 -0
- package/llms.txt +9 -0
- package/package.json +2 -1
- package/src/Projects/ReusableUploads.ts +239 -0
- package/src/Projects/index.ts +27 -0
- package/src/Projects/types/RawProject.ts +16 -0
- package/src/index.ts +2 -0
- package/src/lib/RestClient.ts +4 -0
- package/src/version.ts +1 -1
package/AGENTS.md
CHANGED
|
@@ -27,6 +27,7 @@ Current public API anchors:
|
|
|
27
27
|
- Socket-native LLM chat uses `sogni.chat.completions.create()`.
|
|
28
28
|
- Durable creative workflows use `sogni.workflows`.
|
|
29
29
|
- Project cost helpers are `sogni.projects.estimateCost()`, `estimateVideoCost()`, and `estimateAudioCost()`.
|
|
30
|
+
- `sogni.projects.assets` manages private subscriber uploads (`upload`, `list`, `remove`, `bind`). Supported servers automatically reuse matching files passed to `projects.create()`; saved IDs do not replace file parameters.
|
|
30
31
|
- `checkAuth()` is only for cookie-auth browser flows. API-key auth auto-authenticates during `createInstance()`, and token auth uses `login()` or `setTokens()`.
|
|
31
32
|
- `ChatCompletionResult` is SDK-shaped (`content`, `role`, `finishReason`, `tool_calls`, `usage`, `cost`). Streaming chunks expose `chunk.content` and optional `chunk.tool_calls`.
|
|
32
33
|
|
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
# [5.42.0](https://github.com/Sogni-AI/sogni-client/compare/v5.41.0...v5.42.0) (2026-09-11)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Features
|
|
5
|
+
|
|
6
|
+
* **projects:** reuse private subscriber uploads across projects ([938e8a4](https://github.com/Sogni-AI/sogni-client/commit/938e8a4d9716706530be4586ee324490f6374b01))
|
|
7
|
+
|
|
1
8
|
# [5.41.0](https://github.com/Sogni-AI/sogni-client/compare/v5.40.0...v5.41.0) (2026-09-11)
|
|
2
9
|
|
|
3
10
|
|
package/README.md
CHANGED
|
@@ -749,6 +749,34 @@ const project = await sogni.projects.create({
|
|
|
749
749
|
- Workers download a LoRA on first use, so the first render with an uncached one
|
|
750
750
|
takes longer to start.
|
|
751
751
|
|
|
752
|
+
### Reusable subscriber uploads
|
|
753
|
+
|
|
754
|
+
On servers that support saved uploads, eligible subscribers can reuse the same
|
|
755
|
+
image, video or audio file across projects. Pass files to `projects.create()` as
|
|
756
|
+
usual: the SDK checks for a previously saved copy before transferring bytes.
|
|
757
|
+
Uploads remain private to the signed-in account. Older servers and accounts
|
|
758
|
+
without this feature continue using ordinary project uploads.
|
|
759
|
+
|
|
760
|
+
```javascript
|
|
761
|
+
const saved = await sogni.projects.assets.upload(file, file.type, 'Product reference');
|
|
762
|
+
const { assets, limits } = await sogni.projects.assets.list();
|
|
763
|
+
console.log(saved.id, assets, limits);
|
|
764
|
+
// Reusing the same file in later projects needs no repeat upload.
|
|
765
|
+
// Removal does not remove inputs already copied into an existing project.
|
|
766
|
+
await sogni.projects.assets.remove(saved.id);
|
|
767
|
+
```
|
|
768
|
+
|
|
769
|
+
Use the returned limits and `expiresAt` to display remaining storage and expiry.
|
|
770
|
+
An expired entry can be removed even after the subscription ends. Explicit
|
|
771
|
+
`assets.upload()` calls report errors; automatic project uploads fall back only
|
|
772
|
+
when saved storage cannot be prepared. Transfer or verification failures stop
|
|
773
|
+
project submission. Saved-upload IDs are not accepted in place of files in
|
|
774
|
+
`projects.create()`; `assets.bind(id, { projectId, type, id? })` is available for
|
|
775
|
+
clients that manage project IDs and input slots directly.
|
|
776
|
+
|
|
777
|
+
Project history may include `byolUsed`, `personalLoras` public-source snapshots,
|
|
778
|
+
and `reusedAssetCount`. Missing fields on older projects mean unknown, not zero.
|
|
779
|
+
|
|
752
780
|
### ControlNets
|
|
753
781
|
|
|
754
782
|
**EXPERIMENTAL FEATURE:** This feature is still in development and may not work as expected. Use at your own risk.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type RestClient from '../lib/RestClient.js';
|
|
2
|
+
export interface SavedUpload {
|
|
3
|
+
id: string;
|
|
4
|
+
name: string;
|
|
5
|
+
bytes: number;
|
|
6
|
+
contentType: string;
|
|
7
|
+
state: 'uploading' | 'ready';
|
|
8
|
+
createdAt: number;
|
|
9
|
+
expiresAt: number;
|
|
10
|
+
}
|
|
11
|
+
export interface SavedUploadBinding {
|
|
12
|
+
projectId: string;
|
|
13
|
+
type: string;
|
|
14
|
+
id?: string;
|
|
15
|
+
}
|
|
16
|
+
/** Private subscriber uploads that can be reused across projects. */
|
|
17
|
+
export default class ReusableUploads {
|
|
18
|
+
private readonly rest;
|
|
19
|
+
private pending;
|
|
20
|
+
private lanes;
|
|
21
|
+
private nextLane;
|
|
22
|
+
private session;
|
|
23
|
+
private availability?;
|
|
24
|
+
private preparationFailures;
|
|
25
|
+
constructor(rest: RestClient);
|
|
26
|
+
private assertSession;
|
|
27
|
+
private canAutomaticallySave;
|
|
28
|
+
list(): Promise<{
|
|
29
|
+
assets: SavedUpload[];
|
|
30
|
+
limits: {
|
|
31
|
+
entries: number;
|
|
32
|
+
bytes: number;
|
|
33
|
+
fileBytes: number;
|
|
34
|
+
idleDays: number;
|
|
35
|
+
copyBytesPerDay: number;
|
|
36
|
+
bindingsPerDay: number;
|
|
37
|
+
};
|
|
38
|
+
}>;
|
|
39
|
+
remove(id: string): Promise<void>;
|
|
40
|
+
bind(id: string, binding: SavedUploadBinding): Promise<void>;
|
|
41
|
+
private retryBusy;
|
|
42
|
+
/** Upload once; the API verifies the file before making it reusable. */
|
|
43
|
+
upload(file: Blob | Buffer, contentType: string, name?: string): Promise<SavedUpload>;
|
|
44
|
+
private performUpload;
|
|
45
|
+
/** Existing project uploads remain available when saved uploads cannot be used. */
|
|
46
|
+
tryBindFile(file: Blob | Buffer, contentType: string | undefined, binding: SavedUploadBinding): Promise<boolean>;
|
|
47
|
+
}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const index_js_1 = require("../ApiClient/index.js");
|
|
13
|
+
const SUPPORTED_TYPES = new Set([
|
|
14
|
+
'image/png',
|
|
15
|
+
'image/jpeg',
|
|
16
|
+
'image/webp',
|
|
17
|
+
'video/mp4',
|
|
18
|
+
'video/quicktime',
|
|
19
|
+
'video/webm',
|
|
20
|
+
'audio/mp4',
|
|
21
|
+
'audio/mpeg',
|
|
22
|
+
'audio/flac',
|
|
23
|
+
'audio/wav',
|
|
24
|
+
'audio/x-wav',
|
|
25
|
+
'audio/wave'
|
|
26
|
+
]);
|
|
27
|
+
/** Private subscriber uploads that can be reused across projects. */
|
|
28
|
+
class ReusableUploads {
|
|
29
|
+
constructor(rest) {
|
|
30
|
+
var _a;
|
|
31
|
+
this.rest = rest;
|
|
32
|
+
this.pending = new Map();
|
|
33
|
+
// Bound hashing/upload memory even when a project has many reference files.
|
|
34
|
+
this.lanes = [Promise.resolve(), Promise.resolve()];
|
|
35
|
+
this.nextLane = 0;
|
|
36
|
+
this.session = 0;
|
|
37
|
+
this.preparationFailures = new WeakSet();
|
|
38
|
+
(_a = rest.auth) === null || _a === void 0 ? void 0 : _a.on('updated', () => {
|
|
39
|
+
this.session += 1;
|
|
40
|
+
this.pending.clear();
|
|
41
|
+
this.availability = undefined;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
assertSession(session) {
|
|
45
|
+
if (session !== this.session)
|
|
46
|
+
throw new Error('The account changed. Select the upload again.');
|
|
47
|
+
}
|
|
48
|
+
canAutomaticallySave() {
|
|
49
|
+
if (this.availability && this.availability.expiresAt > Date.now())
|
|
50
|
+
return this.availability.result;
|
|
51
|
+
const result = this.rest
|
|
52
|
+
.get('/v1/assets/capabilities')
|
|
53
|
+
.then((response) => response.data.enabled === true)
|
|
54
|
+
.catch((error) => {
|
|
55
|
+
if (error instanceof index_js_1.ApiError && [403, 404, 503].includes(error.status))
|
|
56
|
+
return false;
|
|
57
|
+
this.availability = undefined;
|
|
58
|
+
throw error;
|
|
59
|
+
});
|
|
60
|
+
this.availability = { expiresAt: Date.now() + 60000, result };
|
|
61
|
+
return result;
|
|
62
|
+
}
|
|
63
|
+
list() {
|
|
64
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
65
|
+
const result = yield this.rest.get('/v1/assets');
|
|
66
|
+
return result.data;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
remove(id) {
|
|
70
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
71
|
+
yield this.rest.delete(`/v1/assets/${encodeURIComponent(id)}`);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
bind(id, binding) {
|
|
75
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
76
|
+
const session = this.session;
|
|
77
|
+
yield this.retryBusy(() => {
|
|
78
|
+
this.assertSession(session);
|
|
79
|
+
return this.rest.post(`/v1/assets/${encodeURIComponent(id)}/bind`, Object.assign({}, binding));
|
|
80
|
+
});
|
|
81
|
+
this.assertSession(session);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
retryBusy(operation) {
|
|
85
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
86
|
+
for (let attempt = 0;; attempt += 1) {
|
|
87
|
+
try {
|
|
88
|
+
return yield operation();
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
if (!(error instanceof index_js_1.ApiError) || error.status !== 423 || attempt >= 4)
|
|
92
|
+
throw error;
|
|
93
|
+
yield new Promise((resolve) => setTimeout(resolve, 250 * Math.pow(2, attempt)));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
/** Upload once; the API verifies the file before making it reusable. */
|
|
99
|
+
upload(file, contentType, name = 'Saved upload') {
|
|
100
|
+
const session = this.session;
|
|
101
|
+
const size = file instanceof Blob ? file.size : file.byteLength;
|
|
102
|
+
if (!size || size > 100 * 1024 * 1024)
|
|
103
|
+
return Promise.reject(new index_js_1.ApiError(400, {
|
|
104
|
+
status: 'error',
|
|
105
|
+
errorCode: 0,
|
|
106
|
+
message: 'Choose a saved upload no larger than 100 MiB.'
|
|
107
|
+
}));
|
|
108
|
+
const lane = this.nextLane++ % this.lanes.length;
|
|
109
|
+
const run = this.lanes[lane].then(() => __awaiter(this, void 0, void 0, function* () {
|
|
110
|
+
this.assertSession(session);
|
|
111
|
+
const bytes = file instanceof Blob ? yield file.arrayBuffer() : file;
|
|
112
|
+
const digest = yield globalThis.crypto.subtle.digest('SHA-256', bytes);
|
|
113
|
+
this.assertSession(session);
|
|
114
|
+
const sha256 = Array.from(new Uint8Array(digest), (value) => value.toString(16).padStart(2, '0')).join('');
|
|
115
|
+
const key = `${sha256}:${contentType}`;
|
|
116
|
+
const existing = this.pending.get(key);
|
|
117
|
+
if (existing)
|
|
118
|
+
return existing;
|
|
119
|
+
const task = this.performUpload(file, bytes.byteLength, sha256, contentType, name, session);
|
|
120
|
+
this.pending.set(key, task);
|
|
121
|
+
try {
|
|
122
|
+
return yield task;
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
if (this.pending.get(key) === task)
|
|
126
|
+
this.pending.delete(key);
|
|
127
|
+
}
|
|
128
|
+
}));
|
|
129
|
+
this.lanes[lane] = run.catch(() => undefined);
|
|
130
|
+
return run;
|
|
131
|
+
}
|
|
132
|
+
performUpload(file, bytes, sha256, contentType, name, session) {
|
|
133
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
134
|
+
const result = yield this.retryBusy(() => {
|
|
135
|
+
this.assertSession(session);
|
|
136
|
+
return this.rest.post('/v1/assets/prepare', {
|
|
137
|
+
sha256,
|
|
138
|
+
bytes,
|
|
139
|
+
contentType,
|
|
140
|
+
name
|
|
141
|
+
});
|
|
142
|
+
}).catch((error) => {
|
|
143
|
+
if (error instanceof Error)
|
|
144
|
+
this.preparationFailures.add(error);
|
|
145
|
+
throw error;
|
|
146
|
+
});
|
|
147
|
+
this.assertSession(session);
|
|
148
|
+
const prepared = result.data;
|
|
149
|
+
if (prepared.state === 'ready')
|
|
150
|
+
return prepared;
|
|
151
|
+
if (!prepared.uploadUrl || !prepared.uploadHeaders)
|
|
152
|
+
throw new Error('The saved upload could not be prepared.');
|
|
153
|
+
const body = file instanceof Blob ? file : new Blob([new Uint8Array(file)]);
|
|
154
|
+
const response = yield fetch(prepared.uploadUrl, {
|
|
155
|
+
method: 'PUT',
|
|
156
|
+
body,
|
|
157
|
+
headers: prepared.uploadHeaders,
|
|
158
|
+
redirect: 'error',
|
|
159
|
+
credentials: 'omit',
|
|
160
|
+
signal: AbortSignal.timeout(300000)
|
|
161
|
+
});
|
|
162
|
+
this.assertSession(session);
|
|
163
|
+
// A concurrent/retried write-once upload may already have finished. The
|
|
164
|
+
// server still verifies the stored bytes before acknowledging completion.
|
|
165
|
+
if (!response.ok && response.status !== 412)
|
|
166
|
+
throw new index_js_1.ApiError(response.status, {
|
|
167
|
+
status: 'error',
|
|
168
|
+
errorCode: 0,
|
|
169
|
+
message: 'Could not upload the selected file.'
|
|
170
|
+
});
|
|
171
|
+
const finalized = yield this.retryBusy(() => {
|
|
172
|
+
this.assertSession(session);
|
|
173
|
+
return this.rest.post(`/v1/assets/${encodeURIComponent(prepared.id)}/finalize`);
|
|
174
|
+
});
|
|
175
|
+
this.assertSession(session);
|
|
176
|
+
return finalized.data;
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
/** Existing project uploads remain available when saved uploads cannot be used. */
|
|
180
|
+
tryBindFile(file, contentType, binding) {
|
|
181
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
182
|
+
const size = file instanceof Blob ? file.size : file.byteLength;
|
|
183
|
+
if (!contentType || !SUPPORTED_TYPES.has(contentType) || !size || size > 100 * 1024 * 1024)
|
|
184
|
+
return false;
|
|
185
|
+
const session = this.session;
|
|
186
|
+
if (!(yield this.canAutomaticallySave()))
|
|
187
|
+
return false;
|
|
188
|
+
this.assertSession(session);
|
|
189
|
+
try {
|
|
190
|
+
const saved = yield this.upload(file, contentType, file instanceof Blob && 'name' in file && typeof file.name === 'string'
|
|
191
|
+
? file.name
|
|
192
|
+
: 'Saved upload');
|
|
193
|
+
this.assertSession(session);
|
|
194
|
+
yield this.bind(saved.id, binding);
|
|
195
|
+
return true;
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
// Fallback is permitted only before a transfer was prepared. Checksum,
|
|
199
|
+
// storage-access and binding failures must surface before job submission.
|
|
200
|
+
if (error instanceof index_js_1.ApiError &&
|
|
201
|
+
this.preparationFailures.has(error) &&
|
|
202
|
+
[400, 403, 404, 409, 410, 503].includes(error.status))
|
|
203
|
+
return false;
|
|
204
|
+
throw error;
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
exports.default = ReusableUploads;
|
|
210
|
+
//# sourceMappingURL=ReusableUploads.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReusableUploads.js","sourceRoot":"","sources":["../../src/Projects/ReusableUploads.ts"],"names":[],"mappings":"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"}
|
package/dist/Projects/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import ApiGroup, { ApiConfig } from '../ApiGroup.js';
|
|
2
|
+
import ReusableUploads from './ReusableUploads.js';
|
|
2
3
|
import { AvailableModel, EnhancementStrength, EstimateRequest, ImageUrlParams, MediaUrlParams, CostEstimation, ProjectParams, SizePreset, SupportedModel, VideoEstimateRequest, AudioEstimateRequest } from './types/index.js';
|
|
3
4
|
import { type RecoveredProject } from '../ApiClient/WebSocketClient/events.js';
|
|
4
5
|
import Project from './Project.js';
|
|
@@ -52,6 +53,9 @@ export type ProjectStatusSnapshot = Partial<Omit<RawProject, 'status' | 'workerJ
|
|
|
52
53
|
completedWorkerJobs: RawProject['completedWorkerJobs'];
|
|
53
54
|
};
|
|
54
55
|
declare class ProjectsApi extends ApiGroup<ProjectApiEvents> {
|
|
56
|
+
private _assets?;
|
|
57
|
+
/** Manage subscriber uploads once and reuse them across projects. */
|
|
58
|
+
get assets(): ReusableUploads;
|
|
55
59
|
private _availableModels;
|
|
56
60
|
private _currentNetworkType;
|
|
57
61
|
private projects;
|
package/dist/Projects/index.js
CHANGED
|
@@ -13,6 +13,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
13
13
|
};
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
const ApiGroup_js_1 = __importDefault(require("../ApiGroup.js"));
|
|
16
|
+
const ReusableUploads_js_1 = __importDefault(require("./ReusableUploads.js"));
|
|
16
17
|
const Project_js_1 = __importDefault(require("./Project.js"));
|
|
17
18
|
const recovery_js_1 = require("./recovery.js");
|
|
18
19
|
const createJobRequestMessage_js_1 = __importDefault(require("./createJobRequestMessage.js"));
|
|
@@ -250,6 +251,11 @@ const MISSING_PROJECT_RETRY_MS = 2500;
|
|
|
250
251
|
const IN_FLIGHT_LOOKUP_STATUSES = new Set(['pending', 'queued', 'processing']);
|
|
251
252
|
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
252
253
|
class ProjectsApi extends ApiGroup_js_1.default {
|
|
254
|
+
/** Manage subscriber uploads once and reuse them across projects. */
|
|
255
|
+
get assets() {
|
|
256
|
+
var _a;
|
|
257
|
+
return ((_a = this._assets) !== null && _a !== void 0 ? _a : (this._assets = new ReusableUploads_js_1.default(this.client.rest)));
|
|
258
|
+
}
|
|
253
259
|
get availableModels() {
|
|
254
260
|
return this._availableModels;
|
|
255
261
|
}
|
|
@@ -1530,6 +1536,8 @@ class ProjectsApi extends ApiGroup_js_1.default {
|
|
|
1530
1536
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1531
1537
|
const imageId = (0, getUUID_js_1.default)();
|
|
1532
1538
|
const contentType = getFileContentType(file);
|
|
1539
|
+
if (yield this.assets.tryBindFile(file, contentType, { projectId, type: 'startingImage' }))
|
|
1540
|
+
return imageId;
|
|
1533
1541
|
const presignedUrl = yield this.uploadUrl({
|
|
1534
1542
|
imageId,
|
|
1535
1543
|
jobId: projectId,
|
|
@@ -1558,6 +1566,8 @@ class ProjectsApi extends ApiGroup_js_1.default {
|
|
|
1558
1566
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1559
1567
|
const imageId = (0, getUUID_js_1.default)();
|
|
1560
1568
|
const contentType = getFileContentType(file);
|
|
1569
|
+
if (yield this.assets.tryBindFile(file, contentType, { projectId, type: 'cnImage' }))
|
|
1570
|
+
return imageId;
|
|
1561
1571
|
const presignedUrl = yield this.uploadUrl({
|
|
1562
1572
|
imageId,
|
|
1563
1573
|
jobId: projectId,
|
|
@@ -1587,6 +1597,11 @@ class ProjectsApi extends ApiGroup_js_1.default {
|
|
|
1587
1597
|
const imageId = (0, getUUID_js_1.default)();
|
|
1588
1598
|
const imageIndex = (index + 1);
|
|
1589
1599
|
const contentType = getFileContentType(file);
|
|
1600
|
+
if (yield this.assets.tryBindFile(file, contentType, {
|
|
1601
|
+
projectId,
|
|
1602
|
+
type: `contextImage${imageIndex}`
|
|
1603
|
+
}))
|
|
1604
|
+
return imageId;
|
|
1590
1605
|
const presignedUrl = yield this.uploadUrl({
|
|
1591
1606
|
imageId,
|
|
1592
1607
|
jobId: projectId,
|
|
@@ -1623,6 +1638,8 @@ class ProjectsApi extends ApiGroup_js_1.default {
|
|
|
1623
1638
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1624
1639
|
const imageId = (0, getUUID_js_1.default)();
|
|
1625
1640
|
const contentType = getFileContentType(file);
|
|
1641
|
+
if (yield this.assets.tryBindFile(file, contentType, { projectId, type: 'referenceImage' }))
|
|
1642
|
+
return imageId;
|
|
1626
1643
|
const presignedUrl = yield this.uploadUrl({
|
|
1627
1644
|
imageId,
|
|
1628
1645
|
jobId: projectId,
|
|
@@ -1655,6 +1672,8 @@ class ProjectsApi extends ApiGroup_js_1.default {
|
|
|
1655
1672
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1656
1673
|
const imageId = (0, getUUID_js_1.default)();
|
|
1657
1674
|
const contentType = getFileContentType(file);
|
|
1675
|
+
if (yield this.assets.tryBindFile(file, contentType, { projectId, type: 'referenceMask' }))
|
|
1676
|
+
return imageId;
|
|
1658
1677
|
const presignedUrl = yield this.uploadUrl({
|
|
1659
1678
|
imageId,
|
|
1660
1679
|
jobId: projectId,
|
|
@@ -1687,6 +1706,8 @@ class ProjectsApi extends ApiGroup_js_1.default {
|
|
|
1687
1706
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1688
1707
|
const imageId = (0, getUUID_js_1.default)();
|
|
1689
1708
|
const contentType = getFileContentType(file);
|
|
1709
|
+
if (yield this.assets.tryBindFile(file, contentType, { projectId, type: 'referenceImageEnd' }))
|
|
1710
|
+
return imageId;
|
|
1690
1711
|
const presignedUrl = yield this.uploadUrl({
|
|
1691
1712
|
imageId,
|
|
1692
1713
|
jobId: projectId,
|
|
@@ -1720,6 +1741,8 @@ class ProjectsApi extends ApiGroup_js_1.default {
|
|
|
1720
1741
|
uploadReferenceAudio(projectId, file, id) {
|
|
1721
1742
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1722
1743
|
const contentType = getFileContentType(file);
|
|
1744
|
+
if (yield this.assets.tryBindFile(file, contentType, { projectId, type: 'referenceAudio', id }))
|
|
1745
|
+
return;
|
|
1723
1746
|
const presignedUrl = yield this.mediaUploadUrl({
|
|
1724
1747
|
jobId: projectId,
|
|
1725
1748
|
type: 'referenceAudio',
|
|
@@ -1752,6 +1775,8 @@ class ProjectsApi extends ApiGroup_js_1.default {
|
|
|
1752
1775
|
uploadReferenceVideo(projectId, file, id) {
|
|
1753
1776
|
return __awaiter(this, void 0, void 0, function* () {
|
|
1754
1777
|
const contentType = getFileContentType(file);
|
|
1778
|
+
if (yield this.assets.tryBindFile(file, contentType, { projectId, type: 'referenceVideo', id }))
|
|
1779
|
+
return;
|
|
1755
1780
|
const presignedUrl = yield this.mediaUploadUrl({
|
|
1756
1781
|
jobId: projectId,
|
|
1757
1782
|
type: 'referenceVideo',
|