@contello/uploader 8.21.0 → 8.21.2
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/README.md +88 -0
- package/dist/index.cjs +211 -0
- package/dist/index.d.cts +122 -0
- package/dist/index.d.ts +122 -132
- package/dist/index.js +155 -512
- package/package.json +18 -25
- package/dist/index.umd.cjs +0 -3
package/README.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# @contello/uploader
|
|
2
|
+
|
|
3
|
+
File uploader for Contello CMS with WebSocket (chunked) and HTTP (multipart) transports.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @contello/uploader rxjs
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Simple upload
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { ContelloUploader } from '@contello/uploader';
|
|
17
|
+
|
|
18
|
+
const uploader = new ContelloUploader({
|
|
19
|
+
url: 'https://example.com',
|
|
20
|
+
project: 'myProjectId',
|
|
21
|
+
token: 'app-a123b456c7890d123456789',
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const { id } = await uploader.upload(file);
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Upload with progress
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
uploader.uploadWithEvents(file).subscribe((event) => {
|
|
31
|
+
if ('progress' in event) {
|
|
32
|
+
console.log(`${event.progress.toFixed(1)}%`);
|
|
33
|
+
} else {
|
|
34
|
+
console.log(`uploaded: ${event.id}`);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Upload with metadata
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import { UploadAssetRetentionPolicy } from '@contello/uploader';
|
|
43
|
+
|
|
44
|
+
await uploader.upload(file, {
|
|
45
|
+
annotations: [{ key: 'category', value: 'photos' }],
|
|
46
|
+
collectionRefs: ['collection-id'],
|
|
47
|
+
retentionPolicy: UploadAssetRetentionPolicy.retain,
|
|
48
|
+
image: {
|
|
49
|
+
transformations: [
|
|
50
|
+
{ name: 'fit', options: { width: 1920, height: 1080 } },
|
|
51
|
+
{ name: 'convert', options: { format: 'avif', options: { quality: 80, lossless: false } } },
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Abort an upload
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
const controller = new AbortController();
|
|
61
|
+
|
|
62
|
+
uploader.upload(file, undefined, { abort: controller.signal });
|
|
63
|
+
|
|
64
|
+
controller.abort();
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## API
|
|
68
|
+
|
|
69
|
+
### `ContelloUploader`
|
|
70
|
+
|
|
71
|
+
| Option | Type | Default | Description |
|
|
72
|
+
| ----------- | ---------------- | ---------------- | -------------------------------- |
|
|
73
|
+
| `url` | `string` | — | Base URL of the Contello server |
|
|
74
|
+
| `project` | `string` | — | Project identifier |
|
|
75
|
+
| `token` | `string` | — | Authentication token |
|
|
76
|
+
| `transport` | `'ws' \| 'http'` | `'ws'` | Transport protocol |
|
|
77
|
+
| `chunkSize` | `number` | `4194304` (4 MB) | Chunk size for WebSocket uploads |
|
|
78
|
+
|
|
79
|
+
### Methods
|
|
80
|
+
|
|
81
|
+
| Method | Returns | Description |
|
|
82
|
+
| ----------------------------------------- | --------------------------------------------------- | ------------------------------------ |
|
|
83
|
+
| `upload(file, meta?, options?)` | `Promise<{ id: string }>` | Upload a file, resolve with asset ID |
|
|
84
|
+
| `uploadWithEvents(file, meta?, options?)` | `Observable<UploadAssetProgress \| { id: string }>` | Upload with progress events |
|
|
85
|
+
|
|
86
|
+
## License
|
|
87
|
+
|
|
88
|
+
MIT
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
ContelloUploader: () => ContelloUploader,
|
|
24
|
+
UploadAssetRetentionPolicy: () => UploadAssetRetentionPolicy
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(index_exports);
|
|
27
|
+
|
|
28
|
+
// src/upload-metadata.ts
|
|
29
|
+
var UploadAssetRetentionPolicy = /* @__PURE__ */ ((UploadAssetRetentionPolicy2) => {
|
|
30
|
+
UploadAssetRetentionPolicy2["retain"] = "retain";
|
|
31
|
+
UploadAssetRetentionPolicy2["deleteIfNotUsed"] = "deleteIfNotUsed";
|
|
32
|
+
return UploadAssetRetentionPolicy2;
|
|
33
|
+
})(UploadAssetRetentionPolicy || {});
|
|
34
|
+
|
|
35
|
+
// src/uploader.ts
|
|
36
|
+
var import_rxjs3 = require("rxjs");
|
|
37
|
+
|
|
38
|
+
// src/implementations/ws.ts
|
|
39
|
+
var import_rxjs = require("rxjs");
|
|
40
|
+
function uploadViaWebSocket({ url, project, token, chunkSize }, file, meta, options) {
|
|
41
|
+
const metadata = { ...meta ?? {}, projectRef: project };
|
|
42
|
+
return new import_rxjs.Observable((obs) => {
|
|
43
|
+
const parsedUrl = new URL(url);
|
|
44
|
+
const ws = new WebSocket(
|
|
45
|
+
`${parsedUrl.protocol === "https:" ? "wss" : "ws"}://${parsedUrl.host}/api/v1/assets/ws`,
|
|
46
|
+
"contello-file-upload-v1"
|
|
47
|
+
);
|
|
48
|
+
const reader = typeof FileReader !== "undefined" ? new FileReader() : null;
|
|
49
|
+
let offset = 0;
|
|
50
|
+
let done = false;
|
|
51
|
+
let ackReceived = false;
|
|
52
|
+
ws.onopen = async () => {
|
|
53
|
+
const initFrame = {
|
|
54
|
+
type: "init",
|
|
55
|
+
metadata: {
|
|
56
|
+
...metadata,
|
|
57
|
+
name: file.name,
|
|
58
|
+
mimeType: file.type,
|
|
59
|
+
size: file.size
|
|
60
|
+
},
|
|
61
|
+
token
|
|
62
|
+
};
|
|
63
|
+
ws.send(JSON.stringify(initFrame));
|
|
64
|
+
function readSlice() {
|
|
65
|
+
const slice = file.slice(offset, offset + chunkSize);
|
|
66
|
+
if (reader) {
|
|
67
|
+
reader.readAsArrayBuffer(slice);
|
|
68
|
+
} else {
|
|
69
|
+
slice.arrayBuffer().then((buffer) => {
|
|
70
|
+
handleArrayBuffer(buffer);
|
|
71
|
+
}).catch((err) => {
|
|
72
|
+
obs.error(err);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function markAsDone() {
|
|
77
|
+
reader?.abort();
|
|
78
|
+
ws.send(JSON.stringify({ type: "done" }));
|
|
79
|
+
}
|
|
80
|
+
function startUpload() {
|
|
81
|
+
if (ackReceived) {
|
|
82
|
+
readSlice();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function handleArrayBuffer(buffer) {
|
|
86
|
+
if (ws.readyState === WebSocket.OPEN) {
|
|
87
|
+
ws.send(buffer);
|
|
88
|
+
offset += buffer.byteLength;
|
|
89
|
+
if (offset < file.size) {
|
|
90
|
+
readSlice();
|
|
91
|
+
} else {
|
|
92
|
+
markAsDone();
|
|
93
|
+
}
|
|
94
|
+
} else {
|
|
95
|
+
obs.error(new Error("WebSocket is closed"));
|
|
96
|
+
reader?.abort();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (reader) {
|
|
100
|
+
reader.onload = () => {
|
|
101
|
+
if (reader.result && reader.result instanceof ArrayBuffer) {
|
|
102
|
+
handleArrayBuffer(reader.result);
|
|
103
|
+
} else {
|
|
104
|
+
markAsDone();
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
ws.onmessage = (event) => {
|
|
109
|
+
const message = JSON.parse(event.data);
|
|
110
|
+
if (message.type === "ack") {
|
|
111
|
+
ackReceived = true;
|
|
112
|
+
startUpload();
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (message.type === "progress") {
|
|
116
|
+
return obs.next({ progress: message.bytesReceived / file.size * 100 });
|
|
117
|
+
}
|
|
118
|
+
if (message.type === "done") {
|
|
119
|
+
if (message.id) {
|
|
120
|
+
done = true;
|
|
121
|
+
obs.next({ id: message.id });
|
|
122
|
+
obs.complete();
|
|
123
|
+
} else {
|
|
124
|
+
obs.error(new Error("No asset id received"));
|
|
125
|
+
}
|
|
126
|
+
return ws.close();
|
|
127
|
+
}
|
|
128
|
+
obs.error(new Error(`WebSocket message with unknown type ${JSON.stringify(message)}`));
|
|
129
|
+
ws.close();
|
|
130
|
+
};
|
|
131
|
+
};
|
|
132
|
+
ws.onerror = (error) => obs.error(error);
|
|
133
|
+
ws.onclose = () => {
|
|
134
|
+
if (!done) {
|
|
135
|
+
obs.error(new Error("Connection closed"));
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
const abortHandler = () => {
|
|
139
|
+
if (!done) {
|
|
140
|
+
reader?.abort();
|
|
141
|
+
ws.close();
|
|
142
|
+
obs.error(new Error("Upload aborted"));
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
options?.abort?.addEventListener("abort", abortHandler);
|
|
146
|
+
return () => {
|
|
147
|
+
options?.abort?.removeEventListener("abort", abortHandler);
|
|
148
|
+
ws.close();
|
|
149
|
+
};
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// src/implementations/xhr.ts
|
|
154
|
+
var import_rxjs2 = require("rxjs");
|
|
155
|
+
function uploadViaXhr({ url, project, token }, file, meta, options) {
|
|
156
|
+
return new import_rxjs2.Observable((obs) => {
|
|
157
|
+
const data = new FormData();
|
|
158
|
+
data.append("metadata", JSON.stringify({ ...meta ?? {}, projectRef: project }));
|
|
159
|
+
data.append("file", file);
|
|
160
|
+
const xhr = new XMLHttpRequest();
|
|
161
|
+
xhr.setRequestHeader("Authorization", `Bearer ${token}`);
|
|
162
|
+
xhr.open("POST", `${url}/api/v1/assets`, true);
|
|
163
|
+
xhr.upload.onprogress = async (event) => {
|
|
164
|
+
if (event.lengthComputable) {
|
|
165
|
+
obs.next({ progress: event.loaded / event.total * 100 });
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
xhr.onload = async () => {
|
|
169
|
+
if (xhr.status >= 200 && xhr.status < 300) {
|
|
170
|
+
const { id } = JSON.parse(xhr.responseText);
|
|
171
|
+
obs.next({ id });
|
|
172
|
+
return obs.complete();
|
|
173
|
+
}
|
|
174
|
+
obs.error(new Error(`${xhr.status}: ${xhr.statusText}`));
|
|
175
|
+
};
|
|
176
|
+
xhr.onerror = (error) => obs.error(error);
|
|
177
|
+
xhr.send(data);
|
|
178
|
+
options?.abort?.addEventListener("abort", () => xhr.abort());
|
|
179
|
+
return () => xhr.abort();
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// src/uploader.ts
|
|
184
|
+
var ContelloUploader = class {
|
|
185
|
+
params;
|
|
186
|
+
constructor(params) {
|
|
187
|
+
this.params = {
|
|
188
|
+
url: params.url,
|
|
189
|
+
project: params.project,
|
|
190
|
+
token: params.token,
|
|
191
|
+
transport: params.transport || "ws",
|
|
192
|
+
chunkSize: params.chunkSize || 4 * 1024 * 1024
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
/** Uploads a file and resolves with the asset ID once complete. */
|
|
196
|
+
async upload(file, meta, options) {
|
|
197
|
+
return (0, import_rxjs3.firstValueFrom)(this.uploadWithEvents(file, meta, options).pipe((0, import_rxjs3.filter)((r) => "id" in r)));
|
|
198
|
+
}
|
|
199
|
+
/** Uploads a file and returns an Observable emitting progress events and the final asset ID. */
|
|
200
|
+
uploadWithEvents(file, meta, options) {
|
|
201
|
+
if (this.params.transport === "http") {
|
|
202
|
+
return uploadViaXhr(this.params, file, meta, options);
|
|
203
|
+
}
|
|
204
|
+
return uploadViaWebSocket(this.params, file, meta, options);
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
208
|
+
0 && (module.exports = {
|
|
209
|
+
ContelloUploader,
|
|
210
|
+
UploadAssetRetentionPolicy
|
|
211
|
+
});
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import * as rxjs from 'rxjs';
|
|
2
|
+
|
|
3
|
+
type UploadAssetMetadata = {
|
|
4
|
+
name?: string | undefined;
|
|
5
|
+
mimeType?: string | undefined;
|
|
6
|
+
size?: number | undefined;
|
|
7
|
+
annotations?: UploadAssetAnnotation[] | undefined;
|
|
8
|
+
collectionRefs?: string[] | undefined;
|
|
9
|
+
image?: UploadAssetImageMetadata | undefined;
|
|
10
|
+
retentionPolicy?: UploadAssetRetentionPolicy | undefined;
|
|
11
|
+
generatePreview?: boolean | undefined;
|
|
12
|
+
createdAt?: string | undefined;
|
|
13
|
+
updatedAt?: string | undefined;
|
|
14
|
+
};
|
|
15
|
+
type UploadAssetAnnotation = {
|
|
16
|
+
key: string;
|
|
17
|
+
value: string;
|
|
18
|
+
};
|
|
19
|
+
type UploadAssetProgress = {
|
|
20
|
+
progress: number;
|
|
21
|
+
};
|
|
22
|
+
declare enum UploadAssetRetentionPolicy {
|
|
23
|
+
retain = "retain",
|
|
24
|
+
deleteIfNotUsed = "deleteIfNotUsed"
|
|
25
|
+
}
|
|
26
|
+
type UploadAssetImageMetadata = {
|
|
27
|
+
transformations: UploadAssetImageTransformation[];
|
|
28
|
+
};
|
|
29
|
+
type UploadAssetImageTransformation = UploadAssetExtractTransformation | UploadAssetFitTransformation | UploadAssetConvertTransformation;
|
|
30
|
+
type UploadAssetExtractTransformation = {
|
|
31
|
+
name: 'extract';
|
|
32
|
+
options: {
|
|
33
|
+
top: number;
|
|
34
|
+
left: number;
|
|
35
|
+
areaWidth: number;
|
|
36
|
+
areaHeight: number;
|
|
37
|
+
rotate?: 0 | 90 | 180 | 270 | undefined;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
type UploadAssetFitTransformation = {
|
|
41
|
+
name: 'fit';
|
|
42
|
+
options: {
|
|
43
|
+
width: number;
|
|
44
|
+
height: number;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
type UploadAssetConvertTransformation = {
|
|
48
|
+
name: 'convert';
|
|
49
|
+
options: UploadAssetConvertTransformationJpegOptions | UploadAssetConvertTransformationPngOptions | UploadAssetConvertTransformationAvifOptions;
|
|
50
|
+
};
|
|
51
|
+
type UploadAssetConvertTransformationJpegOptions = {
|
|
52
|
+
format: 'jpeg';
|
|
53
|
+
options: {
|
|
54
|
+
quality: number;
|
|
55
|
+
interlace: boolean;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
type UploadAssetConvertTransformationPngOptions = {
|
|
59
|
+
format: 'png';
|
|
60
|
+
options: {
|
|
61
|
+
compressionLevel: number;
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
type UploadAssetConvertTransformationAvifOptions = {
|
|
65
|
+
format: 'avif';
|
|
66
|
+
options: {
|
|
67
|
+
quality: number;
|
|
68
|
+
lossless: boolean;
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
type ContelloUploaderParams = {
|
|
73
|
+
/**
|
|
74
|
+
* Base URL of the Contello server.
|
|
75
|
+
* Example: 'https://example.com'
|
|
76
|
+
*/
|
|
77
|
+
url: string;
|
|
78
|
+
/**
|
|
79
|
+
* Project identifier for the Contello project.
|
|
80
|
+
* Example: 'myProjectId'
|
|
81
|
+
*/
|
|
82
|
+
project: string;
|
|
83
|
+
/**
|
|
84
|
+
* Authentication token for the Contello API.
|
|
85
|
+
* Example: 'app-a123b456c7890d123456789'
|
|
86
|
+
*/
|
|
87
|
+
token: string;
|
|
88
|
+
/**
|
|
89
|
+
* Transport protocol to use for uploading files.
|
|
90
|
+
* 'http' uses XMLHttpRequest, 'ws' uses WebSocket.
|
|
91
|
+
* @default 'ws'
|
|
92
|
+
*/
|
|
93
|
+
transport?: 'http' | 'ws';
|
|
94
|
+
/**
|
|
95
|
+
* Size of each chunk in bytes when uploading files.
|
|
96
|
+
* Default is 4MB.
|
|
97
|
+
* @default 4_194_304
|
|
98
|
+
*/
|
|
99
|
+
chunkSize?: number;
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* ContelloUploader is a class for uploading files to a Contello server.
|
|
103
|
+
* It supports both WebSocket and HTTP transports.
|
|
104
|
+
*/
|
|
105
|
+
declare class ContelloUploader {
|
|
106
|
+
private params;
|
|
107
|
+
constructor(params: ContelloUploaderParams);
|
|
108
|
+
/** Uploads a file and resolves with the asset ID once complete. */
|
|
109
|
+
upload(file: File, meta?: UploadAssetMetadata | undefined, options?: {
|
|
110
|
+
abort?: AbortSignal;
|
|
111
|
+
} | undefined): Promise<{
|
|
112
|
+
id: string;
|
|
113
|
+
}>;
|
|
114
|
+
/** Uploads a file and returns an Observable emitting progress events and the final asset ID. */
|
|
115
|
+
uploadWithEvents(file: File, meta?: UploadAssetMetadata | undefined, options?: {
|
|
116
|
+
abort?: AbortSignal;
|
|
117
|
+
} | undefined): rxjs.Observable<UploadAssetProgress | {
|
|
118
|
+
id: string;
|
|
119
|
+
}>;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export { ContelloUploader, type ContelloUploaderParams, type UploadAssetAnnotation, type UploadAssetConvertTransformation, type UploadAssetConvertTransformationAvifOptions, type UploadAssetConvertTransformationJpegOptions, type UploadAssetConvertTransformationPngOptions, type UploadAssetExtractTransformation, type UploadAssetFitTransformation, type UploadAssetImageMetadata, type UploadAssetImageTransformation, type UploadAssetMetadata, type UploadAssetProgress, UploadAssetRetentionPolicy };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,132 +1,122 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
export declare type UploadAssetProgress = {
|
|
124
|
-
progress: number;
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
export declare enum UploadAssetRetentionPolicy {
|
|
128
|
-
retain = "retain",
|
|
129
|
-
deleteIfNotUsed = "deleteIfNotUsed"
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
export { }
|
|
1
|
+
import * as rxjs from 'rxjs';
|
|
2
|
+
|
|
3
|
+
type UploadAssetMetadata = {
|
|
4
|
+
name?: string | undefined;
|
|
5
|
+
mimeType?: string | undefined;
|
|
6
|
+
size?: number | undefined;
|
|
7
|
+
annotations?: UploadAssetAnnotation[] | undefined;
|
|
8
|
+
collectionRefs?: string[] | undefined;
|
|
9
|
+
image?: UploadAssetImageMetadata | undefined;
|
|
10
|
+
retentionPolicy?: UploadAssetRetentionPolicy | undefined;
|
|
11
|
+
generatePreview?: boolean | undefined;
|
|
12
|
+
createdAt?: string | undefined;
|
|
13
|
+
updatedAt?: string | undefined;
|
|
14
|
+
};
|
|
15
|
+
type UploadAssetAnnotation = {
|
|
16
|
+
key: string;
|
|
17
|
+
value: string;
|
|
18
|
+
};
|
|
19
|
+
type UploadAssetProgress = {
|
|
20
|
+
progress: number;
|
|
21
|
+
};
|
|
22
|
+
declare enum UploadAssetRetentionPolicy {
|
|
23
|
+
retain = "retain",
|
|
24
|
+
deleteIfNotUsed = "deleteIfNotUsed"
|
|
25
|
+
}
|
|
26
|
+
type UploadAssetImageMetadata = {
|
|
27
|
+
transformations: UploadAssetImageTransformation[];
|
|
28
|
+
};
|
|
29
|
+
type UploadAssetImageTransformation = UploadAssetExtractTransformation | UploadAssetFitTransformation | UploadAssetConvertTransformation;
|
|
30
|
+
type UploadAssetExtractTransformation = {
|
|
31
|
+
name: 'extract';
|
|
32
|
+
options: {
|
|
33
|
+
top: number;
|
|
34
|
+
left: number;
|
|
35
|
+
areaWidth: number;
|
|
36
|
+
areaHeight: number;
|
|
37
|
+
rotate?: 0 | 90 | 180 | 270 | undefined;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
type UploadAssetFitTransformation = {
|
|
41
|
+
name: 'fit';
|
|
42
|
+
options: {
|
|
43
|
+
width: number;
|
|
44
|
+
height: number;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
type UploadAssetConvertTransformation = {
|
|
48
|
+
name: 'convert';
|
|
49
|
+
options: UploadAssetConvertTransformationJpegOptions | UploadAssetConvertTransformationPngOptions | UploadAssetConvertTransformationAvifOptions;
|
|
50
|
+
};
|
|
51
|
+
type UploadAssetConvertTransformationJpegOptions = {
|
|
52
|
+
format: 'jpeg';
|
|
53
|
+
options: {
|
|
54
|
+
quality: number;
|
|
55
|
+
interlace: boolean;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
type UploadAssetConvertTransformationPngOptions = {
|
|
59
|
+
format: 'png';
|
|
60
|
+
options: {
|
|
61
|
+
compressionLevel: number;
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
type UploadAssetConvertTransformationAvifOptions = {
|
|
65
|
+
format: 'avif';
|
|
66
|
+
options: {
|
|
67
|
+
quality: number;
|
|
68
|
+
lossless: boolean;
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
type ContelloUploaderParams = {
|
|
73
|
+
/**
|
|
74
|
+
* Base URL of the Contello server.
|
|
75
|
+
* Example: 'https://example.com'
|
|
76
|
+
*/
|
|
77
|
+
url: string;
|
|
78
|
+
/**
|
|
79
|
+
* Project identifier for the Contello project.
|
|
80
|
+
* Example: 'myProjectId'
|
|
81
|
+
*/
|
|
82
|
+
project: string;
|
|
83
|
+
/**
|
|
84
|
+
* Authentication token for the Contello API.
|
|
85
|
+
* Example: 'app-a123b456c7890d123456789'
|
|
86
|
+
*/
|
|
87
|
+
token: string;
|
|
88
|
+
/**
|
|
89
|
+
* Transport protocol to use for uploading files.
|
|
90
|
+
* 'http' uses XMLHttpRequest, 'ws' uses WebSocket.
|
|
91
|
+
* @default 'ws'
|
|
92
|
+
*/
|
|
93
|
+
transport?: 'http' | 'ws';
|
|
94
|
+
/**
|
|
95
|
+
* Size of each chunk in bytes when uploading files.
|
|
96
|
+
* Default is 4MB.
|
|
97
|
+
* @default 4_194_304
|
|
98
|
+
*/
|
|
99
|
+
chunkSize?: number;
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* ContelloUploader is a class for uploading files to a Contello server.
|
|
103
|
+
* It supports both WebSocket and HTTP transports.
|
|
104
|
+
*/
|
|
105
|
+
declare class ContelloUploader {
|
|
106
|
+
private params;
|
|
107
|
+
constructor(params: ContelloUploaderParams);
|
|
108
|
+
/** Uploads a file and resolves with the asset ID once complete. */
|
|
109
|
+
upload(file: File, meta?: UploadAssetMetadata | undefined, options?: {
|
|
110
|
+
abort?: AbortSignal;
|
|
111
|
+
} | undefined): Promise<{
|
|
112
|
+
id: string;
|
|
113
|
+
}>;
|
|
114
|
+
/** Uploads a file and returns an Observable emitting progress events and the final asset ID. */
|
|
115
|
+
uploadWithEvents(file: File, meta?: UploadAssetMetadata | undefined, options?: {
|
|
116
|
+
abort?: AbortSignal;
|
|
117
|
+
} | undefined): rxjs.Observable<UploadAssetProgress | {
|
|
118
|
+
id: string;
|
|
119
|
+
}>;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export { ContelloUploader, type ContelloUploaderParams, type UploadAssetAnnotation, type UploadAssetConvertTransformation, type UploadAssetConvertTransformationAvifOptions, type UploadAssetConvertTransformationJpegOptions, type UploadAssetConvertTransformationPngOptions, type UploadAssetExtractTransformation, type UploadAssetFitTransformation, type UploadAssetImageMetadata, type UploadAssetImageTransformation, type UploadAssetMetadata, type UploadAssetProgress, UploadAssetRetentionPolicy };
|