@editframe/api 0.11.0-beta.9 → 0.12.0-beta.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/dist/CHUNK_SIZE_BYTES.js +1 -1
- package/dist/ProgressIterator.d.ts +25 -0
- package/dist/ProgressIterator.js +99 -0
- package/dist/ProgressIterator.test.d.ts +1 -0
- package/dist/StreamEventSource.d.ts +50 -0
- package/dist/StreamEventSource.js +130 -0
- package/dist/StreamEventSource.test.d.ts +1 -0
- package/dist/client.d.ts +6 -3
- package/dist/client.js +20 -6
- package/dist/index.d.ts +7 -5
- package/dist/index.js +20 -11
- package/dist/readableFromBuffers.d.ts +1 -2
- package/dist/resources/caption-file.d.ts +7 -3
- package/dist/resources/caption-file.js +22 -2
- package/dist/resources/image-file.d.ts +7 -3
- package/dist/resources/image-file.js +19 -0
- package/dist/resources/isobmff-file.d.ts +16 -3
- package/dist/resources/isobmff-file.js +37 -2
- package/dist/resources/isobmff-track.d.ts +5 -7
- package/dist/resources/isobmff-track.js +44 -1
- package/dist/resources/process-isobmff.d.ts +12 -0
- package/dist/resources/process-isobmff.js +22 -0
- package/dist/resources/process-isobmff.test.d.ts +1 -0
- package/dist/resources/renders.d.ts +10 -5
- package/dist/resources/renders.js +21 -2
- package/dist/resources/transcriptions.d.ts +24 -0
- package/dist/resources/transcriptions.js +45 -0
- package/dist/resources/transcriptions.test.d.ts +1 -0
- package/dist/resources/unprocessed-file.d.ts +12 -53
- package/dist/resources/unprocessed-file.js +31 -130
- package/dist/streamChunker.d.ts +1 -2
- package/dist/streamChunker.js +20 -9
- package/dist/uploadChunks.d.ts +1 -2
- package/dist/uploadChunks.js +1 -4
- package/package.json +3 -2
- package/src/resources/caption-file.test.ts +57 -6
- package/src/resources/caption-file.ts +34 -5
- package/src/resources/image-file.test.ts +56 -5
- package/src/resources/image-file.ts +32 -4
- package/src/resources/isobmff-file.test.ts +57 -6
- package/src/resources/isobmff-file.ts +64 -5
- package/src/resources/isobmff-track.test.ts +3 -3
- package/src/resources/isobmff-track.ts +50 -5
- package/src/resources/process-isobmff.test.ts +62 -0
- package/src/resources/process-isobmff.ts +33 -0
- package/src/resources/renders.test.ts +51 -6
- package/src/resources/renders.ts +34 -5
- package/src/resources/transcriptions.test.ts +49 -0
- package/src/resources/transcriptions.ts +64 -0
- package/src/resources/unprocessed-file.test.ts +19 -430
- package/src/resources/unprocessed-file.ts +45 -161
|
@@ -1,69 +1,37 @@
|
|
|
1
|
-
import { createReadStream } from "node:fs";
|
|
2
|
-
import { stat } from "node:fs/promises";
|
|
3
|
-
import { basename } from "node:path";
|
|
4
|
-
import { Readable } from "node:stream";
|
|
5
|
-
|
|
6
1
|
import debug from "debug";
|
|
7
2
|
import { z } from "zod";
|
|
8
3
|
|
|
9
|
-
import { md5Buffer, md5FilePath } from "@editframe/assets";
|
|
10
|
-
|
|
11
4
|
import type { Client } from "../client.ts";
|
|
12
|
-
import {
|
|
13
|
-
type IteratorWithPromise,
|
|
14
|
-
type UploadChunkEvent,
|
|
15
|
-
uploadChunks,
|
|
16
|
-
} from "../uploadChunks.ts";
|
|
5
|
+
import { uploadChunks } from "../uploadChunks.ts";
|
|
17
6
|
|
|
18
7
|
const log = debug("ef:api:unprocessed-file");
|
|
19
8
|
|
|
20
|
-
const FileProcessor = z.union([
|
|
21
|
-
z.literal("isobmff"),
|
|
22
|
-
z.literal("image"),
|
|
23
|
-
z.literal("captions"),
|
|
24
|
-
z.string(),
|
|
25
|
-
]);
|
|
26
|
-
|
|
27
|
-
const FileProcessors = z.array(FileProcessor).refine(
|
|
28
|
-
(value) => {
|
|
29
|
-
return new Set(value).size === value.length;
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
message: "Processors list must not include duplicates",
|
|
33
|
-
},
|
|
34
|
-
);
|
|
35
|
-
|
|
36
9
|
const MAX_FILE_SIZE = 1024 * 1024 * 1024; // 1GiB
|
|
37
10
|
|
|
38
11
|
export const CreateUnprocessedFilePayload = z.object({
|
|
39
12
|
md5: z.string(),
|
|
40
13
|
filename: z.string(),
|
|
41
|
-
processes: FileProcessors.optional(),
|
|
42
14
|
byte_size: z.number().int().max(MAX_FILE_SIZE),
|
|
43
15
|
});
|
|
44
16
|
|
|
45
|
-
export const UpdateUnprocessedFilePayload = z.object({
|
|
46
|
-
processes: FileProcessors.optional(),
|
|
47
|
-
});
|
|
17
|
+
export const UpdateUnprocessedFilePayload = z.object({});
|
|
48
18
|
|
|
49
|
-
|
|
19
|
+
interface UnprocessedFile {
|
|
50
20
|
byte_size: number;
|
|
51
21
|
next_byte: number;
|
|
52
22
|
complete: boolean;
|
|
53
23
|
id: string;
|
|
54
24
|
md5: string;
|
|
55
|
-
processes: z.infer<typeof FileProcessors> & string[];
|
|
56
|
-
asset_id: string;
|
|
57
25
|
}
|
|
58
26
|
|
|
59
|
-
export interface
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
27
|
+
export interface CreateUnprocessedFileResult extends UnprocessedFile {}
|
|
28
|
+
|
|
29
|
+
export interface LookupUnprocessedFileByMd5Result extends UnprocessedFile {}
|
|
30
|
+
|
|
31
|
+
export interface UpdateUnprocessedFileResult extends UnprocessedFile {}
|
|
32
|
+
|
|
33
|
+
export interface ProcessIsobmffFileResult {
|
|
63
34
|
id: string;
|
|
64
|
-
md5: string;
|
|
65
|
-
processes: z.infer<typeof FileProcessors>;
|
|
66
|
-
asset_id: string;
|
|
67
35
|
}
|
|
68
36
|
|
|
69
37
|
export const createUnprocessedFile = async (
|
|
@@ -96,36 +64,10 @@ export const createUnprocessedFile = async (
|
|
|
96
64
|
);
|
|
97
65
|
};
|
|
98
66
|
|
|
99
|
-
export const updateUnprocessedFile = async (
|
|
100
|
-
client: Client,
|
|
101
|
-
fileId: string,
|
|
102
|
-
payload: Partial<z.infer<typeof UpdateUnprocessedFilePayload>>,
|
|
103
|
-
) => {
|
|
104
|
-
log("Updating unprocessed file", fileId, payload);
|
|
105
|
-
UpdateUnprocessedFilePayload.parse(payload);
|
|
106
|
-
const response = await client.authenticatedFetch(
|
|
107
|
-
`/api/v1/unprocessed_files/${fileId}`,
|
|
108
|
-
{
|
|
109
|
-
method: "POST",
|
|
110
|
-
body: JSON.stringify(payload),
|
|
111
|
-
},
|
|
112
|
-
);
|
|
113
|
-
|
|
114
|
-
log("Unprocessed file updated", response);
|
|
115
|
-
|
|
116
|
-
if (response.ok) {
|
|
117
|
-
return (await response.json()) as UpdateUnprocessedFileResult;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
throw new Error(
|
|
121
|
-
`Failed to update unprocessed file ${response.status} ${response.statusText}`,
|
|
122
|
-
);
|
|
123
|
-
};
|
|
124
|
-
|
|
125
67
|
export const uploadUnprocessedFile = (
|
|
126
68
|
client: Client,
|
|
127
69
|
fileId: string,
|
|
128
|
-
fileStream:
|
|
70
|
+
fileStream: ReadableStream,
|
|
129
71
|
fileSize: number,
|
|
130
72
|
) => {
|
|
131
73
|
log("Uploading unprocessed file", fileId);
|
|
@@ -138,104 +80,46 @@ export const uploadUnprocessedFile = (
|
|
|
138
80
|
});
|
|
139
81
|
};
|
|
140
82
|
|
|
141
|
-
const
|
|
83
|
+
export const lookupUnprocessedFileByMd5 = async (
|
|
142
84
|
client: Client,
|
|
143
|
-
filename: string,
|
|
144
85
|
md5: string,
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
86
|
+
): Promise<LookupUnprocessedFileByMd5Result | null> => {
|
|
87
|
+
const response = await client.authenticatedFetch(
|
|
88
|
+
`/api/v1/unprocessed_files/md5/${md5}`,
|
|
89
|
+
{
|
|
90
|
+
method: "GET",
|
|
91
|
+
},
|
|
92
|
+
);
|
|
150
93
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
filename,
|
|
155
|
-
byte_size: byteSize,
|
|
156
|
-
});
|
|
94
|
+
if (response.ok) {
|
|
95
|
+
return (await response.json()) as LookupUnprocessedFileByMd5Result;
|
|
96
|
+
}
|
|
157
97
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
if (unprocessedFile.complete) {
|
|
162
|
-
yield { type: "progress", progress: 0 };
|
|
163
|
-
yield { type: "progress", progress: 1 };
|
|
164
|
-
}
|
|
165
|
-
yield* doUpload(unprocessedFile.id);
|
|
166
|
-
},
|
|
167
|
-
file: async () => {
|
|
168
|
-
const unprocessedFile = await createFilePromise;
|
|
169
|
-
if (unprocessedFile.complete) {
|
|
170
|
-
return unprocessedFile;
|
|
171
|
-
}
|
|
172
|
-
await doUpload(unprocessedFile.id).whenUploaded();
|
|
173
|
-
const fileInformation = await updateUnprocessedFile(
|
|
174
|
-
client,
|
|
175
|
-
unprocessedFile.id,
|
|
176
|
-
{
|
|
177
|
-
processes: [processor],
|
|
178
|
-
},
|
|
179
|
-
);
|
|
180
|
-
log("File processed", fileInformation);
|
|
181
|
-
return fileInformation;
|
|
182
|
-
},
|
|
183
|
-
};
|
|
184
|
-
};
|
|
98
|
+
if (response.status === 404) {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
185
101
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
const md5 = md5Buffer(buffer);
|
|
190
|
-
|
|
191
|
-
return processResource(
|
|
192
|
-
client,
|
|
193
|
-
filename,
|
|
194
|
-
md5,
|
|
195
|
-
buffer.byteLength,
|
|
196
|
-
processor,
|
|
197
|
-
(id: string) => {
|
|
198
|
-
const readStream = new Readable({
|
|
199
|
-
read() {
|
|
200
|
-
readStream.push(buffer);
|
|
201
|
-
readStream.push(null);
|
|
202
|
-
},
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
return uploadUnprocessedFile(client, id, readStream, buffer.byteLength);
|
|
206
|
-
},
|
|
207
|
-
);
|
|
208
|
-
};
|
|
102
|
+
throw new Error(
|
|
103
|
+
`Failed to lookup unprocessed file by md5 ${md5} ${response.status} ${response.statusText}`,
|
|
104
|
+
);
|
|
209
105
|
};
|
|
210
106
|
|
|
211
|
-
const
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
md5,
|
|
222
|
-
byteSize,
|
|
223
|
-
processor,
|
|
224
|
-
(id: string) => {
|
|
225
|
-
const readStream = createReadStream(filePath);
|
|
226
|
-
return uploadUnprocessedFile(client, id, readStream, byteSize);
|
|
227
|
-
},
|
|
228
|
-
);
|
|
229
|
-
};
|
|
230
|
-
return {
|
|
231
|
-
progress: async () => (await processPromise()).progress(),
|
|
232
|
-
file: async () => (await processPromise()).file(),
|
|
233
|
-
};
|
|
234
|
-
};
|
|
235
|
-
};
|
|
107
|
+
export const processIsobmffFile = async (
|
|
108
|
+
client: Client,
|
|
109
|
+
unprocessedFileId: LookupUnprocessedFileByMd5Result["id"],
|
|
110
|
+
) => {
|
|
111
|
+
const response = await client.authenticatedFetch(
|
|
112
|
+
`/api/v1/unprocessed_files/${unprocessedFileId}/isobmff`,
|
|
113
|
+
{
|
|
114
|
+
method: "POST",
|
|
115
|
+
},
|
|
116
|
+
);
|
|
236
117
|
|
|
237
|
-
|
|
238
|
-
|
|
118
|
+
if (response.ok) {
|
|
119
|
+
return (await response.json()) as ProcessIsobmffFileResult;
|
|
120
|
+
}
|
|
239
121
|
|
|
240
|
-
|
|
241
|
-
|
|
122
|
+
throw new Error(
|
|
123
|
+
`Failed to process isobmff file ${response.status} ${response.statusText}`,
|
|
124
|
+
);
|
|
125
|
+
};
|