@editframe/api 0.12.0-beta.6 → 0.13.0-beta.1
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/ProgressIterator.d.ts +1 -1
- package/dist/{api/src/ProgressIterator.js → ProgressIterator.js} +14 -2
- package/dist/StreamEventSource.d.ts +5 -3
- package/dist/{api/src/StreamEventSource.js → StreamEventSource.js} +0 -2
- package/dist/client.d.ts +1 -1
- package/dist/index.d.ts +14 -10
- package/dist/{api/src/index.js → index.js} +10 -7
- package/dist/node.d.ts +6 -0
- package/dist/node.js +98 -0
- package/dist/resources/caption-file.d.ts +32 -4
- package/dist/{api/src/resources → resources}/caption-file.js +9 -0
- package/dist/resources/image-file.d.ts +28 -10
- package/dist/{api/src/resources → resources}/image-file.js +18 -21
- package/dist/resources/isobmff-file.d.ts +25 -5
- package/dist/resources/isobmff-track.d.ts +497 -6
- package/dist/{api/src/resources → resources}/isobmff-track.js +24 -18
- package/dist/resources/process-isobmff.d.ts +2 -2
- package/dist/resources/renders.d.ts +27 -15
- package/dist/{api/src/resources → resources}/renders.js +21 -13
- package/dist/resources/transcriptions.d.ts +4 -3
- package/dist/resources/unprocessed-file.d.ts +11 -10
- package/dist/{api/src/resources → resources}/unprocessed-file.js +0 -25
- package/dist/resources/url-token.d.ts +1 -1
- package/dist/uploadChunks.d.ts +4 -1
- package/dist/utils/assertTypesMatch.d.ts +3 -0
- package/dist/utils/createReadableStreamFromReadable.d.ts +4 -0
- package/docs/packages/api/docs/.nojekyll +1 -0
- package/docs/packages/api/docs/assets/highlight.css +71 -0
- package/docs/packages/api/docs/assets/icons.js +18 -0
- package/docs/packages/api/docs/assets/icons.svg +1 -0
- package/docs/packages/api/docs/assets/main.js +60 -0
- package/docs/packages/api/docs/assets/navigation.js +1 -0
- package/docs/packages/api/docs/assets/search.js +1 -0
- package/docs/packages/api/docs/assets/style.css +1493 -0
- package/docs/packages/api/docs/classes/Client.html +4 -0
- package/docs/packages/api/docs/functions/createCaptionFile.html +8 -0
- package/docs/packages/api/docs/functions/createISOBMFFFile.html +1 -0
- package/docs/packages/api/docs/functions/createISOBMFFTrack.html +1 -0
- package/docs/packages/api/docs/functions/createImageFile.html +1 -0
- package/docs/packages/api/docs/functions/createRender.html +1 -0
- package/docs/packages/api/docs/functions/createTranscription.html +1 -0
- package/docs/packages/api/docs/functions/createURLToken.html +1 -0
- package/docs/packages/api/docs/functions/createUnprocessedFile.html +1 -0
- package/docs/packages/api/docs/functions/getISOBMFFFileTranscription.html +1 -0
- package/docs/packages/api/docs/functions/getIsobmffProcessInfo.html +1 -0
- package/docs/packages/api/docs/functions/getIsobmffProcessProgress.html +1 -0
- package/docs/packages/api/docs/functions/getTranscriptionInfo.html +1 -0
- package/docs/packages/api/docs/functions/getTranscriptionProgress.html +1 -0
- package/docs/packages/api/docs/functions/lookupCaptionFileByMd5.html +1 -0
- package/docs/packages/api/docs/functions/lookupISOBMFFFileByMd5.html +1 -0
- package/docs/packages/api/docs/functions/lookupImageFileByMd5.html +1 -0
- package/docs/packages/api/docs/functions/lookupRenderByMd5.html +1 -0
- package/docs/packages/api/docs/functions/lookupUnprocessedFileByMd5.html +1 -0
- package/docs/packages/api/docs/functions/processIsobmffFile.html +1 -0
- package/docs/packages/api/docs/functions/transcribeISOBMFFFile.html +1 -0
- package/docs/packages/api/docs/functions/uploadCaptionFile.html +1 -0
- package/docs/packages/api/docs/functions/uploadFragmentIndex.html +1 -0
- package/docs/packages/api/docs/functions/uploadISOBMFFTrack.html +1 -0
- package/docs/packages/api/docs/functions/uploadImageFile.html +1 -0
- package/docs/packages/api/docs/functions/uploadRender.html +1 -0
- package/docs/packages/api/docs/functions/uploadUnprocessedReadableStream.html +1 -0
- package/docs/packages/api/docs/index.html +39 -0
- package/docs/packages/api/docs/interfaces/CreateCaptionFileResult.html +4 -0
- package/docs/packages/api/docs/interfaces/CreateISOBMFFFileResult.html +5 -0
- package/docs/packages/api/docs/interfaces/CreateISOBMFFTrackResult.html +6 -0
- package/docs/packages/api/docs/interfaces/CreateImageFileResult.html +5 -0
- package/docs/packages/api/docs/interfaces/CreateRenderResult.html +4 -0
- package/docs/packages/api/docs/interfaces/CreateTranscriptionResult.html +3 -0
- package/docs/packages/api/docs/interfaces/CreateUnprocessedFileResult.html +6 -0
- package/docs/packages/api/docs/interfaces/GetISOBMFFFileTranscriptionResult.html +4 -0
- package/docs/packages/api/docs/interfaces/IsobmffProcessInfoResult.html +7 -0
- package/docs/packages/api/docs/interfaces/LookupCaptionFileByMd5Result.html +4 -0
- package/docs/packages/api/docs/interfaces/LookupISOBMFFFileByMd5Result.html +5 -0
- package/docs/packages/api/docs/interfaces/LookupImageFileByMd5Result.html +5 -0
- package/docs/packages/api/docs/interfaces/LookupRenderByMd5Result.html +4 -0
- package/docs/packages/api/docs/interfaces/LookupUnprocessedFileByMd5Result.html +6 -0
- package/docs/packages/api/docs/interfaces/ProcessIsobmffFileResult.html +2 -0
- package/docs/packages/api/docs/interfaces/TranscribeISOBMFFFileResult.html +4 -0
- package/docs/packages/api/docs/interfaces/TranscriptionInfoResult.html +3 -0
- package/docs/packages/api/docs/interfaces/URLTokenResult.html +2 -0
- package/docs/packages/api/docs/modules.html +54 -0
- package/docs/packages/api/docs/variables/CreateCaptionFilePayload.html +1 -0
- package/docs/packages/api/docs/variables/CreateISOBMFFFilePayload.html +1 -0
- package/docs/packages/api/docs/variables/CreateISOBMFFTrackPayload.html +1 -0
- package/docs/packages/api/docs/variables/CreateImageFilePayload.html +1 -0
- package/docs/packages/api/docs/variables/CreateRenderPayload.html +1 -0
- package/docs/packages/api/docs/variables/CreateTranscriptionPayload.html +1 -0
- package/docs/packages/api/docs/variables/CreateUnprocessedFilePayload.html +1 -0
- package/docs/packages/api/docs/variables/TranscribeISOBMFFFilePayload.html +1 -0
- package/package.json +12 -4
- package/src/resources/caption-file.test.ts +3 -3
- package/src/resources/caption-file.ts +31 -2
- package/src/resources/image-file.test.ts +3 -3
- package/src/resources/image-file.ts +23 -28
- package/src/resources/isobmff-file.test.ts +3 -3
- package/src/resources/isobmff-file.ts +27 -3
- package/src/resources/isobmff-track.test.ts +4 -4
- package/src/resources/isobmff-track.ts +147 -25
- package/src/resources/process-isobmff.test.ts +3 -3
- package/src/resources/process-isobmff.ts +2 -2
- package/src/resources/renders.test.ts +3 -18
- package/src/resources/renders.ts +44 -15
- package/src/resources/transcriptions.test.ts +2 -2
- package/src/resources/transcriptions.ts +7 -3
- package/src/resources/unprocessed-file.test.ts +3 -3
- package/src/resources/unprocessed-file.ts +20 -41
- package/src/resources/url-token.test.ts +3 -3
- package/src/resources/url-token.ts +1 -1
- package/src/utils/assertTypesMatch.ts +10 -0
- package/src/utils/createReadableStreamFromReadable.ts +117 -0
- /package/dist/{api/src/CHUNK_SIZE_BYTES.js → CHUNK_SIZE_BYTES.js} +0 -0
- /package/dist/{api/src/client.js → client.js} +0 -0
- /package/dist/{api/src/resources → resources}/isobmff-file.js +0 -0
- /package/dist/{api/src/resources → resources}/process-isobmff.js +0 -0
- /package/dist/{api/src/resources → resources}/transcriptions.js +0 -0
- /package/dist/{api/src/resources → resources}/url-token.js +0 -0
- /package/dist/{api/src/streamChunker.js → streamChunker.js} +0 -0
- /package/dist/{api/src/uploadChunks.js → uploadChunks.js} +0 -0
- /package/dist/{cli/src/utils → utils}/createReadableStreamFromReadable.js +0 -0
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import debug from "debug";
|
|
2
2
|
import { z } from "zod";
|
|
3
|
+
import type { Client } from "../client.js";
|
|
4
|
+
import { uploadChunks } from "../uploadChunks.js";
|
|
5
|
+
import { assertTypesMatch } from "../utils/assertTypesMatch.ts";
|
|
3
6
|
|
|
4
|
-
const AudioStreamSchema = z.object({
|
|
7
|
+
export const AudioStreamSchema = z.object({
|
|
5
8
|
index: z.number(),
|
|
6
9
|
codec_name: z.string(),
|
|
7
10
|
codec_long_name: z.string(),
|
|
@@ -25,9 +28,54 @@ const AudioStreamSchema = z.object({
|
|
|
25
28
|
disposition: z.record(z.unknown()),
|
|
26
29
|
});
|
|
27
30
|
|
|
28
|
-
|
|
31
|
+
export interface AudioStreamSchema {
|
|
32
|
+
/** The index of the stream in the file */
|
|
33
|
+
index: number;
|
|
34
|
+
/** The name of the codec */
|
|
35
|
+
codec_name: string;
|
|
36
|
+
/** The long name of the codec */
|
|
37
|
+
codec_long_name: string;
|
|
38
|
+
/** The type of the codec */
|
|
39
|
+
codec_type: "audio";
|
|
40
|
+
/** The tag string of the codec */
|
|
41
|
+
codec_tag_string: string;
|
|
42
|
+
/** The tag of the codec */
|
|
43
|
+
codec_tag: string;
|
|
44
|
+
/** The sample format */
|
|
45
|
+
sample_fmt: string;
|
|
46
|
+
/** The sample rate */
|
|
47
|
+
sample_rate: string;
|
|
48
|
+
/** The number of channels */
|
|
49
|
+
channels: number;
|
|
50
|
+
/** The channel layout */
|
|
51
|
+
channel_layout: string;
|
|
52
|
+
/** The number of bits per sample */
|
|
53
|
+
bits_per_sample: number;
|
|
54
|
+
/** The initial padding */
|
|
55
|
+
initial_padding?: number;
|
|
56
|
+
/** The frame rate */
|
|
57
|
+
r_frame_rate: string;
|
|
58
|
+
/** The average frame rate */
|
|
59
|
+
avg_frame_rate: string;
|
|
60
|
+
/** The time base */
|
|
61
|
+
time_base: string;
|
|
62
|
+
/** The start presentation timestamp */
|
|
63
|
+
start_pts: number;
|
|
64
|
+
/** The start time */
|
|
65
|
+
start_time: number;
|
|
66
|
+
/** The duration timestamp */
|
|
67
|
+
duration_ts: number;
|
|
68
|
+
/** The duration */
|
|
69
|
+
duration: number;
|
|
70
|
+
/** The bit rate */
|
|
71
|
+
bit_rate: string;
|
|
72
|
+
/** The disposition record. Subject to change, not documented. */
|
|
73
|
+
disposition: Record<string, unknown>;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
assertTypesMatch<z.infer<typeof AudioStreamSchema>, AudioStreamSchema>(true);
|
|
29
77
|
|
|
30
|
-
const VideoStreamSchema = z.object({
|
|
78
|
+
export const VideoStreamSchema = z.object({
|
|
31
79
|
index: z.number(),
|
|
32
80
|
codec_name: z.string(),
|
|
33
81
|
codec_long_name: z.string(),
|
|
@@ -49,36 +97,110 @@ const VideoStreamSchema = z.object({
|
|
|
49
97
|
disposition: z.record(z.unknown()),
|
|
50
98
|
});
|
|
51
99
|
|
|
52
|
-
|
|
100
|
+
export interface VideoStreamSchema {
|
|
101
|
+
/** The index of the stream in the file */
|
|
102
|
+
index: number;
|
|
103
|
+
/** The name of the codec */
|
|
104
|
+
codec_name: string;
|
|
105
|
+
/** The long name of the codec */
|
|
106
|
+
codec_long_name: string;
|
|
107
|
+
/** The type of the codec */
|
|
108
|
+
codec_type: "video";
|
|
109
|
+
/** The tag string of the codec */
|
|
110
|
+
codec_tag_string: string;
|
|
111
|
+
/** The tag of the codec */
|
|
112
|
+
codec_tag: string;
|
|
113
|
+
/** The width */
|
|
114
|
+
width: number;
|
|
115
|
+
/** The height */
|
|
116
|
+
height: number;
|
|
117
|
+
/** The coded width */
|
|
118
|
+
coded_width: number;
|
|
119
|
+
/** The coded height */
|
|
120
|
+
coded_height: number;
|
|
121
|
+
/** The frame rate */
|
|
122
|
+
r_frame_rate: string;
|
|
123
|
+
/** The average frame rate */
|
|
124
|
+
avg_frame_rate: string;
|
|
125
|
+
/** The time base */
|
|
126
|
+
time_base: string;
|
|
127
|
+
/** The start presentation timestamp */
|
|
128
|
+
start_pts?: number;
|
|
129
|
+
/** The start time */
|
|
130
|
+
start_time?: number;
|
|
131
|
+
/** The duration timestamp */
|
|
132
|
+
duration_ts?: number;
|
|
133
|
+
/** The duration */
|
|
134
|
+
duration?: number;
|
|
135
|
+
/** The bit rate */
|
|
136
|
+
bit_rate?: string;
|
|
137
|
+
/** The disposition record. Subject to change, not documented. */
|
|
138
|
+
disposition: Record<string, unknown>;
|
|
139
|
+
}
|
|
53
140
|
|
|
54
|
-
|
|
55
|
-
import { uploadChunks } from "../uploadChunks.ts";
|
|
141
|
+
assertTypesMatch<z.infer<typeof VideoStreamSchema>, VideoStreamSchema>(true);
|
|
56
142
|
|
|
57
143
|
const log = debug("ef:api:isobmff-track");
|
|
58
144
|
|
|
59
145
|
const MAX_TRACK_SIZE = 1024 * 1024 * 1024; // 1GB
|
|
60
146
|
|
|
147
|
+
export const AudioTrackPayload = z.object({
|
|
148
|
+
file_id: z.string(),
|
|
149
|
+
track_id: z.number().int(),
|
|
150
|
+
type: z.literal("audio"),
|
|
151
|
+
probe_info: AudioStreamSchema,
|
|
152
|
+
duration_ms: z.number().int(),
|
|
153
|
+
codec_name: z.string(),
|
|
154
|
+
byte_size: z.number().int().max(MAX_TRACK_SIZE),
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
export interface AudioTrackPayload {
|
|
158
|
+
file_id: string;
|
|
159
|
+
track_id: number;
|
|
160
|
+
type: "audio";
|
|
161
|
+
probe_info: AudioStreamSchema;
|
|
162
|
+
duration_ms: number;
|
|
163
|
+
codec_name: string;
|
|
164
|
+
byte_size: number;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// These will actually error if types don't match
|
|
168
|
+
assertTypesMatch<z.infer<typeof AudioTrackPayload>, AudioTrackPayload>(true);
|
|
169
|
+
|
|
170
|
+
export const VideoTrackPayload = z.object({
|
|
171
|
+
file_id: z.string(),
|
|
172
|
+
track_id: z.number().int(),
|
|
173
|
+
type: z.literal("video"),
|
|
174
|
+
probe_info: VideoStreamSchema,
|
|
175
|
+
duration_ms: z.number().int(),
|
|
176
|
+
codec_name: z.string(),
|
|
177
|
+
byte_size: z.number().int().max(MAX_TRACK_SIZE),
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
export interface VideoTrackPayload {
|
|
181
|
+
file_id: string;
|
|
182
|
+
track_id: number;
|
|
183
|
+
type: "video";
|
|
184
|
+
probe_info: VideoStreamSchema;
|
|
185
|
+
duration_ms: number;
|
|
186
|
+
codec_name: string;
|
|
187
|
+
byte_size: number;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
assertTypesMatch<z.infer<typeof VideoTrackPayload>, VideoTrackPayload>(true);
|
|
191
|
+
|
|
61
192
|
export const CreateISOBMFFTrackPayload = z.discriminatedUnion("type", [
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
track_id: z.number().int(),
|
|
65
|
-
type: z.literal("audio"),
|
|
66
|
-
probe_info: AudioStreamSchema,
|
|
67
|
-
duration_ms: z.number().int(),
|
|
68
|
-
codec_name: z.string(),
|
|
69
|
-
byte_size: z.number().int().max(MAX_TRACK_SIZE),
|
|
70
|
-
}),
|
|
71
|
-
z.object({
|
|
72
|
-
file_id: z.string(),
|
|
73
|
-
track_id: z.number().int(),
|
|
74
|
-
type: z.literal("video"),
|
|
75
|
-
probe_info: VideoStreamSchema,
|
|
76
|
-
duration_ms: z.number().int(),
|
|
77
|
-
codec_name: z.string(),
|
|
78
|
-
byte_size: z.number().int().max(MAX_TRACK_SIZE),
|
|
79
|
-
}),
|
|
193
|
+
AudioTrackPayload,
|
|
194
|
+
VideoTrackPayload,
|
|
80
195
|
]);
|
|
81
196
|
|
|
197
|
+
export type CreateISOBMFFTrackPayload = VideoTrackPayload | AudioTrackPayload;
|
|
198
|
+
|
|
199
|
+
assertTypesMatch<
|
|
200
|
+
z.infer<typeof CreateISOBMFFTrackPayload>,
|
|
201
|
+
CreateISOBMFFTrackPayload
|
|
202
|
+
>(true);
|
|
203
|
+
|
|
82
204
|
export interface CreateISOBMFFTrackResult {
|
|
83
205
|
next_byte: number;
|
|
84
206
|
byte_size: number;
|
|
@@ -89,7 +211,7 @@ export interface CreateISOBMFFTrackResult {
|
|
|
89
211
|
|
|
90
212
|
export const createISOBMFFTrack = async (
|
|
91
213
|
client: Client,
|
|
92
|
-
payload:
|
|
214
|
+
payload: CreateISOBMFFTrackPayload,
|
|
93
215
|
) => {
|
|
94
216
|
log("Creating isobmff track", payload);
|
|
95
217
|
CreateISOBMFFTrackPayload.parse(payload);
|
|
@@ -2,11 +2,11 @@ import { describe, expect, test } from "vitest";
|
|
|
2
2
|
import {
|
|
3
3
|
getIsobmffProcessInfo,
|
|
4
4
|
getIsobmffProcessProgress,
|
|
5
|
-
} from "./process-isobmff.
|
|
5
|
+
} from "./process-isobmff.js";
|
|
6
6
|
|
|
7
|
-
import { useMSW } from "TEST/useMSW.
|
|
7
|
+
import { useMSW } from "TEST/useMSW.js";
|
|
8
8
|
import { http, HttpResponse } from "msw";
|
|
9
|
-
import { Client } from "../client.
|
|
9
|
+
import { Client } from "../client.js";
|
|
10
10
|
|
|
11
11
|
const client = new Client("ef_TEST_TOKEN", "http://localhost");
|
|
12
12
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ProgressIterator } from "../ProgressIterator.
|
|
2
|
-
import type { Client } from "../client.
|
|
1
|
+
import { ProgressIterator } from "../ProgressIterator.js";
|
|
2
|
+
import type { Client } from "../client.js";
|
|
3
3
|
|
|
4
4
|
export interface IsobmffProcessInfoResult {
|
|
5
5
|
id: string;
|
|
@@ -2,9 +2,9 @@ import { http, HttpResponse } from "msw";
|
|
|
2
2
|
import { setupServer } from "msw/node";
|
|
3
3
|
import { afterAll, afterEach, beforeAll, describe, expect, test } from "vitest";
|
|
4
4
|
|
|
5
|
-
import { Client } from "../client.
|
|
6
|
-
import { webReadableFromBuffers } from "../readableFromBuffers.
|
|
7
|
-
import { createRender, lookupRenderByMd5, uploadRender } from "./renders.
|
|
5
|
+
import { Client } from "../client.js";
|
|
6
|
+
import { webReadableFromBuffers } from "../readableFromBuffers.js";
|
|
7
|
+
import { createRender, lookupRenderByMd5, uploadRender } from "./renders.js";
|
|
8
8
|
|
|
9
9
|
const server = setupServer();
|
|
10
10
|
const client = new Client("ef_TEST_TOKEN", "http://localhost");
|
|
@@ -46,19 +46,6 @@ describe("Renders", () => {
|
|
|
46
46
|
});
|
|
47
47
|
|
|
48
48
|
describe("uploadRender", () => {
|
|
49
|
-
test("throws if file size exceeds limit", async () => {
|
|
50
|
-
await expect(
|
|
51
|
-
uploadRender(
|
|
52
|
-
client,
|
|
53
|
-
"test-id",
|
|
54
|
-
webReadableFromBuffers(Buffer.from("test")),
|
|
55
|
-
1024 * 1024 * 17,
|
|
56
|
-
),
|
|
57
|
-
).rejects.toThrowError(
|
|
58
|
-
new Error("File size exceeds limit of 16777216 bytes"),
|
|
59
|
-
);
|
|
60
|
-
});
|
|
61
|
-
|
|
62
49
|
test("throws if server returns an error", async () => {
|
|
63
50
|
server.use(
|
|
64
51
|
http.post("http://localhost/api/v1/renders/test-id/upload", () =>
|
|
@@ -71,7 +58,6 @@ describe("Renders", () => {
|
|
|
71
58
|
client,
|
|
72
59
|
"test-id",
|
|
73
60
|
webReadableFromBuffers(Buffer.from("test")),
|
|
74
|
-
1024 * 1024 * 2,
|
|
75
61
|
),
|
|
76
62
|
).rejects.toThrowError(
|
|
77
63
|
"Failed to upload render 500 Internal Server Error",
|
|
@@ -92,7 +78,6 @@ describe("Renders", () => {
|
|
|
92
78
|
client,
|
|
93
79
|
"test-id",
|
|
94
80
|
webReadableFromBuffers(Buffer.from("test")),
|
|
95
|
-
1024 * 1024 * 2,
|
|
96
81
|
);
|
|
97
82
|
|
|
98
83
|
expect(response).toEqual({ testResponse: "test" });
|
package/src/resources/renders.ts
CHANGED
|
@@ -1,21 +1,42 @@
|
|
|
1
1
|
import debug from "debug";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
|
|
4
|
-
import
|
|
4
|
+
import { CompletionIterator } from "../ProgressIterator.js";
|
|
5
|
+
import type { Client } from "../client.js";
|
|
6
|
+
import { assertTypesMatch } from "../utils/assertTypesMatch.ts";
|
|
5
7
|
|
|
6
8
|
const log = debug("ef:api:renders");
|
|
7
|
-
const FILE_SIZE_LIMIT = 1024 * 1024 * 16; // 16MiB
|
|
8
9
|
|
|
9
10
|
export const CreateRenderPayload = z.object({
|
|
10
|
-
md5: z.string(),
|
|
11
|
-
fps: z.number(),
|
|
12
|
-
width: z.number().int(),
|
|
13
|
-
height: z.number().int(),
|
|
14
|
-
work_slice_ms: z
|
|
11
|
+
md5: z.string().optional(),
|
|
12
|
+
fps: z.number().int().min(1).max(120).default(30).optional(),
|
|
13
|
+
width: z.number().int().min(2),
|
|
14
|
+
height: z.number().int().min(2),
|
|
15
|
+
work_slice_ms: z
|
|
16
|
+
.number()
|
|
17
|
+
.int()
|
|
18
|
+
.min(1000)
|
|
19
|
+
.max(10_000)
|
|
20
|
+
.default(4_000)
|
|
21
|
+
.optional(),
|
|
15
22
|
duration_ms: z.number().int(),
|
|
16
|
-
strategy: z.enum(["v1", "v2"]),
|
|
23
|
+
strategy: z.enum(["v1", "v2"]).default("v1").optional(),
|
|
17
24
|
});
|
|
18
25
|
|
|
26
|
+
export interface CreateRenderPayload {
|
|
27
|
+
md5?: string;
|
|
28
|
+
fps?: number;
|
|
29
|
+
width: number;
|
|
30
|
+
height: number;
|
|
31
|
+
work_slice_ms?: number;
|
|
32
|
+
duration_ms: number;
|
|
33
|
+
strategy?: "v1" | "v2";
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
assertTypesMatch<CreateRenderPayload, z.infer<typeof CreateRenderPayload>>(
|
|
37
|
+
true,
|
|
38
|
+
);
|
|
39
|
+
|
|
19
40
|
export interface CreateRenderResult {
|
|
20
41
|
id: string;
|
|
21
42
|
md5: string;
|
|
@@ -30,7 +51,7 @@ export interface LookupRenderByMd5Result {
|
|
|
30
51
|
|
|
31
52
|
export const createRender = async (
|
|
32
53
|
client: Client,
|
|
33
|
-
payload:
|
|
54
|
+
payload: CreateRenderPayload,
|
|
34
55
|
) => {
|
|
35
56
|
log("Creating render", payload);
|
|
36
57
|
const response = await client.authenticatedFetch("/api/v1/renders", {
|
|
@@ -44,7 +65,7 @@ export const createRender = async (
|
|
|
44
65
|
}
|
|
45
66
|
|
|
46
67
|
throw new Error(
|
|
47
|
-
`Failed to create render ${response.status} ${response.statusText}`,
|
|
68
|
+
`Failed to create render ${response.status} ${response.statusText} ${await response.text()}`,
|
|
48
69
|
);
|
|
49
70
|
};
|
|
50
71
|
|
|
@@ -52,13 +73,8 @@ export const uploadRender = async (
|
|
|
52
73
|
client: Client,
|
|
53
74
|
fileId: string,
|
|
54
75
|
fileStream: ReadableStream,
|
|
55
|
-
folderSize: number,
|
|
56
76
|
) => {
|
|
57
77
|
log("Uploading render", fileId);
|
|
58
|
-
log("Folder size", folderSize, "bytes");
|
|
59
|
-
if (folderSize > FILE_SIZE_LIMIT) {
|
|
60
|
-
throw new Error(`File size exceeds limit of ${FILE_SIZE_LIMIT} bytes`);
|
|
61
|
-
}
|
|
62
78
|
const response = await client.authenticatedFetch(
|
|
63
79
|
`/api/v1/renders/${fileId}/upload`,
|
|
64
80
|
{
|
|
@@ -77,6 +93,11 @@ export const uploadRender = async (
|
|
|
77
93
|
);
|
|
78
94
|
};
|
|
79
95
|
|
|
96
|
+
export const getRenderInfo = async (client: Client, id: string) => {
|
|
97
|
+
const response = await client.authenticatedFetch(`/api/v1/renders/${id}`);
|
|
98
|
+
return response.json() as Promise<LookupRenderByMd5Result>;
|
|
99
|
+
};
|
|
100
|
+
|
|
80
101
|
export const lookupRenderByMd5 = async (
|
|
81
102
|
client: Client,
|
|
82
103
|
md5: string,
|
|
@@ -100,3 +121,11 @@ export const lookupRenderByMd5 = async (
|
|
|
100
121
|
`Failed to lookup render by md5 ${md5} ${response.status} ${response.statusText}`,
|
|
101
122
|
);
|
|
102
123
|
};
|
|
124
|
+
|
|
125
|
+
export const getRenderProgress = async (client: Client, id: string) => {
|
|
126
|
+
const eventSource = await client.authenticatedEventSource(
|
|
127
|
+
`/api/v1/renders/${id}/progress`,
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
return new CompletionIterator(eventSource);
|
|
131
|
+
};
|
|
@@ -2,8 +2,8 @@ import { http, HttpResponse } from "msw";
|
|
|
2
2
|
import { setupServer } from "msw/node";
|
|
3
3
|
import { afterAll, afterEach, beforeAll, describe, expect, test } from "vitest";
|
|
4
4
|
|
|
5
|
-
import { Client } from "../client.
|
|
6
|
-
import { createTranscription } from "./transcriptions.
|
|
5
|
+
import { Client } from "../client.js";
|
|
6
|
+
import { createTranscription } from "./transcriptions.js";
|
|
7
7
|
|
|
8
8
|
const server = setupServer();
|
|
9
9
|
const client = new Client("ef_TEST_TOKEN", "http://localhost");
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import debug from "debug";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
|
|
4
|
-
import { CompletionIterator } from "../ProgressIterator.
|
|
5
|
-
import type { Client } from "../client.
|
|
4
|
+
import { CompletionIterator } from "../ProgressIterator.js";
|
|
5
|
+
import type { Client } from "../client.js";
|
|
6
6
|
|
|
7
7
|
const log = debug("ef:api:transcriptions");
|
|
8
8
|
|
|
@@ -11,6 +11,10 @@ export const CreateTranscriptionPayload = z.object({
|
|
|
11
11
|
track_id: z.number().int(),
|
|
12
12
|
});
|
|
13
13
|
|
|
14
|
+
export type CreateTranscriptionPayload = z.infer<
|
|
15
|
+
typeof CreateTranscriptionPayload
|
|
16
|
+
>;
|
|
17
|
+
|
|
14
18
|
export interface CreateTranscriptionResult {
|
|
15
19
|
id: string;
|
|
16
20
|
status: "complete" | "created" | "failed" | "pending" | "transcribing";
|
|
@@ -23,7 +27,7 @@ export interface TranscriptionInfoResult {
|
|
|
23
27
|
|
|
24
28
|
export const createTranscription = async (
|
|
25
29
|
client: Client,
|
|
26
|
-
payload:
|
|
30
|
+
payload: CreateTranscriptionPayload,
|
|
27
31
|
) => {
|
|
28
32
|
log("Creating transcription", payload);
|
|
29
33
|
const response = await client.authenticatedFetch("/api/v1/transcriptions", {
|
|
@@ -3,13 +3,13 @@ import { setupServer } from "msw/node";
|
|
|
3
3
|
import { afterAll, afterEach, beforeAll, describe, expect, test } from "vitest";
|
|
4
4
|
import { ZodError } from "zod";
|
|
5
5
|
|
|
6
|
-
import { Client } from "../client.
|
|
7
|
-
import { webReadableFromBuffers } from "../readableFromBuffers.
|
|
6
|
+
import { Client } from "../client.js";
|
|
7
|
+
import { webReadableFromBuffers } from "../readableFromBuffers.js";
|
|
8
8
|
import {
|
|
9
9
|
createUnprocessedFile,
|
|
10
10
|
lookupUnprocessedFileByMd5,
|
|
11
11
|
uploadUnprocessedReadableStream,
|
|
12
|
-
} from "./unprocessed-file.
|
|
12
|
+
} from "./unprocessed-file.js";
|
|
13
13
|
|
|
14
14
|
const server = setupServer();
|
|
15
15
|
const client = new Client("ef_TEST_TOKEN", "http://localhost");
|
|
@@ -1,13 +1,9 @@
|
|
|
1
|
-
import { stat } from "node:fs/promises";
|
|
2
1
|
import debug from "debug";
|
|
3
2
|
import { z } from "zod";
|
|
4
3
|
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { createReadableStreamFromReadable } from "packages/cli/src/utils/createReadableStreamFromReadable.ts";
|
|
9
|
-
import type { Client } from "../client.ts";
|
|
10
|
-
import { uploadChunks } from "../uploadChunks.ts";
|
|
4
|
+
import type { Client } from "../client.js";
|
|
5
|
+
import { uploadChunks } from "../uploadChunks.js";
|
|
6
|
+
import { assertTypesMatch } from "../utils/assertTypesMatch.ts";
|
|
11
7
|
|
|
12
8
|
const log = debug("ef:api:unprocessed-file");
|
|
13
9
|
|
|
@@ -21,7 +17,11 @@ export const CreateUnprocessedFilePayload = z.object({
|
|
|
21
17
|
|
|
22
18
|
export const UpdateUnprocessedFilePayload = z.object({});
|
|
23
19
|
|
|
24
|
-
|
|
20
|
+
export type CreateUnprocessedFilePayload = z.infer<
|
|
21
|
+
typeof CreateUnprocessedFilePayload
|
|
22
|
+
>;
|
|
23
|
+
|
|
24
|
+
export interface UnprocessedFile {
|
|
25
25
|
byte_size: number;
|
|
26
26
|
next_byte: number;
|
|
27
27
|
complete: boolean;
|
|
@@ -29,7 +29,17 @@ interface UnprocessedFile {
|
|
|
29
29
|
md5: string;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
export interface UnprocessedFileUploadDetails {
|
|
33
|
+
id: string;
|
|
34
|
+
byte_size: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Ensure that the UnprocessedFileUploadDetails type matches the shape of the
|
|
38
|
+
// UnprocessedFile type, but without the optional fields.
|
|
39
|
+
assertTypesMatch<
|
|
40
|
+
Pick<UnprocessedFile, "id" | "byte_size">,
|
|
41
|
+
UnprocessedFileUploadDetails
|
|
42
|
+
>(true);
|
|
33
43
|
|
|
34
44
|
export interface CreateUnprocessedFileResult extends UnprocessedFile {}
|
|
35
45
|
|
|
@@ -41,26 +51,9 @@ export interface ProcessIsobmffFileResult {
|
|
|
41
51
|
id: string;
|
|
42
52
|
}
|
|
43
53
|
|
|
44
|
-
export const createUnprocessedFileFromPath = async (
|
|
45
|
-
client: Client,
|
|
46
|
-
path: string,
|
|
47
|
-
) => {
|
|
48
|
-
const fileInfo = await stat(path);
|
|
49
|
-
|
|
50
|
-
const byte_size = fileInfo.size;
|
|
51
|
-
|
|
52
|
-
const md5 = await md5FilePath(path);
|
|
53
|
-
|
|
54
|
-
return createUnprocessedFile(client, {
|
|
55
|
-
md5,
|
|
56
|
-
filename: basename(path),
|
|
57
|
-
byte_size,
|
|
58
|
-
});
|
|
59
|
-
};
|
|
60
|
-
|
|
61
54
|
export const createUnprocessedFile = async (
|
|
62
55
|
client: Client,
|
|
63
|
-
payload:
|
|
56
|
+
payload: CreateUnprocessedFilePayload,
|
|
64
57
|
) => {
|
|
65
58
|
log("Creating an unprocessed file", payload);
|
|
66
59
|
CreateUnprocessedFilePayload.parse(payload);
|
|
@@ -88,20 +81,6 @@ export const createUnprocessedFile = async (
|
|
|
88
81
|
);
|
|
89
82
|
};
|
|
90
83
|
|
|
91
|
-
export const uploadUnprocessedFile = async (
|
|
92
|
-
client: Client,
|
|
93
|
-
uploadDetails: UnprocessedFileUploadDetails,
|
|
94
|
-
path: string,
|
|
95
|
-
) => {
|
|
96
|
-
const readStream = createReadStream(path);
|
|
97
|
-
|
|
98
|
-
return uploadUnprocessedReadableStream(
|
|
99
|
-
client,
|
|
100
|
-
uploadDetails,
|
|
101
|
-
createReadableStreamFromReadable(readStream),
|
|
102
|
-
);
|
|
103
|
-
};
|
|
104
|
-
|
|
105
84
|
export const uploadUnprocessedReadableStream = (
|
|
106
85
|
client: Client,
|
|
107
86
|
uploadDetails: UnprocessedFileUploadDetails,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { afterAll, afterEach, beforeAll, describe, expect, test } from "vitest";
|
|
2
1
|
import { http, HttpResponse } from "msw";
|
|
3
2
|
import { setupServer } from "msw/node";
|
|
3
|
+
import { afterAll, afterEach, beforeAll, describe, expect, test } from "vitest";
|
|
4
4
|
|
|
5
|
-
import { Client } from "../client.
|
|
6
|
-
import { createURLToken } from "./url-token.
|
|
5
|
+
import { Client } from "../client.js";
|
|
6
|
+
import { createURLToken } from "./url-token.js";
|
|
7
7
|
|
|
8
8
|
const server = setupServer();
|
|
9
9
|
const client = new Client("ef_TEST_TOKEN", "http://localhost");
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// Type helper that will cause a compilation error
|
|
2
|
+
type Equals<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y
|
|
3
|
+
? 1
|
|
4
|
+
: 2
|
|
5
|
+
? true
|
|
6
|
+
: false;
|
|
7
|
+
// Force error with const assertion
|
|
8
|
+
export const assertTypesMatch = <T, U>(
|
|
9
|
+
value: Equals<T, U> extends true ? true : never,
|
|
10
|
+
) => value;
|