@editframe/api 0.9.0-beta.1 → 0.10.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/index.d.ts CHANGED
@@ -4,5 +4,5 @@ export { createISOBMFFFile, CreateISOBMFFFilePayload, type CreateISOBMFFFileResu
4
4
  export { createISOBMFFTrack, CreateISOBMFFTrackPayload, type CreateISOBMFFTrackResult, uploadISOBMFFTrack, } from './resources/isobmff-track.ts';
5
5
  export { createRender, CreateRenderPayload, type CreateRenderResult, uploadRender, } from './resources/renders.ts';
6
6
  export { createURLToken, type URLTokenResult, } from './resources/url-token.ts';
7
- export { createUnprocessedFile, CreateUnprocessedFilePayload, type CreateUnprocessedFileResult, updateUnprocessedFile, UpdateUnprocessedFilePayload, type UpdateUnprocessedFileResult, uploadUnprocessedFile, processAVFile, processAVFileBuffer, } from './resources/unprocessed-file.ts';
7
+ export { createUnprocessedFile, CreateUnprocessedFilePayload, type CreateUnprocessedFileResult, updateUnprocessedFile, UpdateUnprocessedFilePayload, type UpdateUnprocessedFileResult, uploadUnprocessedFile, processAVFile, processAVFileBuffer, processImageFile, processImageFileBuffer, } from './resources/unprocessed-file.ts';
8
8
  export { Client } from './client.ts';
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import { CreateISOBMFFFilePayload, createISOBMFFFile, uploadFragmentIndex } from
4
4
  import { CreateISOBMFFTrackPayload, createISOBMFFTrack, uploadISOBMFFTrack } from "./resources/isobmff-track.js";
5
5
  import { CreateRenderPayload, createRender, uploadRender } from "./resources/renders.js";
6
6
  import { createURLToken } from "./resources/url-token.js";
7
- import { CreateUnprocessedFilePayload, UpdateUnprocessedFilePayload, createUnprocessedFile, processAVFile, processAVFileBuffer, updateUnprocessedFile, uploadUnprocessedFile } from "./resources/unprocessed-file.js";
7
+ import { CreateUnprocessedFilePayload, UpdateUnprocessedFilePayload, createUnprocessedFile, processAVFile, processAVFileBuffer, processImageFile, processImageFileBuffer, updateUnprocessedFile, uploadUnprocessedFile } from "./resources/unprocessed-file.js";
8
8
  import { Client } from "./client.js";
9
9
  export {
10
10
  Client,
@@ -24,6 +24,8 @@ export {
24
24
  createUnprocessedFile,
25
25
  processAVFile,
26
26
  processAVFileBuffer,
27
+ processImageFile,
28
+ processImageFileBuffer,
27
29
  updateUnprocessedFile,
28
30
  uploadCaptionFile,
29
31
  uploadFragmentIndex,
@@ -2,22 +2,23 @@ import { Readable } from 'node:stream';
2
2
  import { z } from 'zod';
3
3
  import { Client } from '../client.ts';
4
4
  export declare const CreateCaptionFilePayload: z.ZodObject<{
5
- id: z.ZodString;
5
+ md5: z.ZodString;
6
6
  filename: z.ZodString;
7
7
  byte_size: z.ZodNumber;
8
8
  }, "strip", z.ZodTypeAny, {
9
- id: string;
9
+ md5: string;
10
10
  filename: string;
11
11
  byte_size: number;
12
12
  }, {
13
- id: string;
13
+ md5: string;
14
14
  filename: string;
15
15
  byte_size: number;
16
16
  }>;
17
17
  export interface CreateCaptionFileResult {
18
18
  complete: boolean | null;
19
19
  id: string;
20
- assetId: string;
20
+ md5: string;
21
+ asset_id: string;
21
22
  }
22
23
  /**
23
24
  * Create a caption file
@@ -3,7 +3,7 @@ import debug from "debug";
3
3
  const log = debug("ef:api:caption-file");
4
4
  const MAX_CAPTION_SIZE = 1024 * 1024 * 2;
5
5
  const CreateCaptionFilePayload = z.object({
6
- id: z.string(),
6
+ md5: z.string(),
7
7
  filename: z.string(),
8
8
  byte_size: z.number().int().max(MAX_CAPTION_SIZE)
9
9
  });
@@ -18,13 +18,10 @@ const restrictSize = (size) => {
18
18
  const createCaptionFile = async (client, payload) => {
19
19
  log("Creating caption file", payload);
20
20
  restrictSize(payload.byte_size);
21
- const response = await client.authenticatedFetch(
22
- "/api/video2/caption_files",
23
- {
24
- method: "POST",
25
- body: JSON.stringify(payload)
26
- }
27
- );
21
+ const response = await client.authenticatedFetch("/api/v1/caption_files", {
22
+ method: "POST",
23
+ body: JSON.stringify(payload)
24
+ });
28
25
  log("Caption file created", response);
29
26
  if (response.ok) {
30
27
  return await response.json();
@@ -37,7 +34,7 @@ const uploadCaptionFile = async (client, fileId, fileStream, fileSize) => {
37
34
  log("Uploading caption file", fileId);
38
35
  restrictSize(fileSize);
39
36
  const response = await client.authenticatedFetch(
40
- `/api/video2/caption_files/${fileId}/upload`,
37
+ `/api/v1/caption_files/${fileId}/upload`,
41
38
  {
42
39
  method: "POST",
43
40
  body: fileStream
@@ -2,21 +2,21 @@ import { Readable } from 'node:stream';
2
2
  import { z } from 'zod';
3
3
  import { Client } from '../client.ts';
4
4
  export declare const CreateImageFilePayload: z.ZodObject<{
5
- id: z.ZodString;
5
+ md5: z.ZodString;
6
6
  height: z.ZodNumber;
7
7
  width: z.ZodNumber;
8
8
  mime_type: z.ZodEnum<["image/jpeg", "image/png", "image/jpg", "image/webp"]>;
9
9
  filename: z.ZodString;
10
10
  byte_size: z.ZodNumber;
11
11
  }, "strip", z.ZodTypeAny, {
12
- id: string;
12
+ md5: string;
13
13
  filename: string;
14
14
  byte_size: number;
15
15
  height: number;
16
16
  width: number;
17
17
  mime_type: "image/jpeg" | "image/png" | "image/jpg" | "image/webp";
18
18
  }, {
19
- id: string;
19
+ md5: string;
20
20
  filename: string;
21
21
  byte_size: number;
22
22
  height: number;
@@ -26,7 +26,8 @@ export declare const CreateImageFilePayload: z.ZodObject<{
26
26
  export interface CreateImageFileResult {
27
27
  complete: boolean | null;
28
28
  id: string;
29
- assetId: string;
29
+ md5: string;
30
+ asset_id: string;
30
31
  }
31
32
  export declare const createImageFile: (client: Client, payload: z.infer<typeof CreateImageFilePayload>) => Promise<CreateImageFileResult>;
32
33
  export declare const uploadImageFile: (client: Client, fileId: string, fileStream: Readable, fileSize: number) => Promise<void>;
@@ -4,7 +4,7 @@ import { uploadChunks } from "../uploadChunks.js";
4
4
  const log = debug("ef:api:image-file");
5
5
  const MAX_IMAGE_SIZE = 1024 * 1024 * 16;
6
6
  const CreateImageFilePayload = z.object({
7
- id: z.string(),
7
+ md5: z.string(),
8
8
  height: z.number().int(),
9
9
  width: z.number().int(),
10
10
  mime_type: z.enum(["image/jpeg", "image/png", "image/jpg", "image/webp"]),
@@ -14,7 +14,7 @@ const CreateImageFilePayload = z.object({
14
14
  const createImageFile = async (client, payload) => {
15
15
  log("Creating image file", payload);
16
16
  CreateImageFilePayload.parse(payload);
17
- const response = await client.authenticatedFetch("/api/video2/image_files", {
17
+ const response = await client.authenticatedFetch("/api/v1/image_files", {
18
18
  method: "POST",
19
19
  body: JSON.stringify(payload)
20
20
  });
@@ -34,7 +34,7 @@ const uploadImageFile = async (client, fileId, fileStream, fileSize) => {
34
34
  );
35
35
  }
36
36
  const result = await uploadChunks(client, {
37
- url: `/api/video2/image_files/${fileId}/upload`,
37
+ url: `/api/v1/image_files/${fileId}/upload`,
38
38
  fileSize,
39
39
  fileStream
40
40
  });
@@ -2,19 +2,21 @@ import { Readable } from 'node:stream';
2
2
  import { z } from 'zod';
3
3
  import { Client } from '../client.ts';
4
4
  export declare const CreateISOBMFFFilePayload: z.ZodObject<{
5
- id: z.ZodString;
5
+ md5: z.ZodString;
6
6
  filename: z.ZodString;
7
7
  }, "strip", z.ZodTypeAny, {
8
- id: string;
8
+ md5: string;
9
9
  filename: string;
10
10
  }, {
11
- id: string;
11
+ md5: string;
12
12
  filename: string;
13
13
  }>;
14
14
  export interface CreateISOBMFFFileResult {
15
15
  fragment_index_complete: boolean;
16
+ filename: string;
16
17
  id: string;
17
- assetId: string;
18
+ md5: string;
19
+ asset_id: string;
18
20
  }
19
21
  export declare const createISOBMFFFile: (client: Client, payload: z.infer<typeof CreateISOBMFFFilePayload>) => Promise<CreateISOBMFFFileResult>;
20
22
  export declare const uploadFragmentIndex: (client: Client, fileId: string, fileStream: Readable, fileSize: number) => Promise<unknown>;
@@ -3,18 +3,15 @@ import debug from "debug";
3
3
  const log = debug("ef:api:isobmff-file");
4
4
  const FILE_SIZE_LIMIT = 1024 * 1024 * 2;
5
5
  const CreateISOBMFFFilePayload = z.object({
6
- id: z.string(),
6
+ md5: z.string(),
7
7
  filename: z.string()
8
8
  });
9
9
  const createISOBMFFFile = async (client, payload) => {
10
10
  log("Creating isobmff file", payload);
11
- const response = await client.authenticatedFetch(
12
- "/api/video2/isobmff_files",
13
- {
14
- method: "POST",
15
- body: JSON.stringify(payload)
16
- }
17
- );
11
+ const response = await client.authenticatedFetch("/api/v1/isobmff_files", {
12
+ method: "POST",
13
+ body: JSON.stringify(payload)
14
+ });
18
15
  log("ISOBMFF file created", response);
19
16
  if (response.ok) {
20
17
  return await response.json();
@@ -29,7 +26,7 @@ const uploadFragmentIndex = async (client, fileId, fileStream, fileSize) => {
29
26
  throw new Error(`File size exceeds limit of ${FILE_SIZE_LIMIT} bytes`);
30
27
  }
31
28
  const response = await client.authenticatedFetch(
32
- `/api/video2/isobmff_files/${fileId}/index/upload`,
29
+ `/api/v1/isobmff_files/${fileId}/index/upload`,
33
30
  {
34
31
  method: "POST",
35
32
  body: fileStream
@@ -27,13 +27,10 @@ const CreateISOBMFFTrackPayload = z.discriminatedUnion("type", [
27
27
  const createISOBMFFTrack = async (client, payload) => {
28
28
  log("Creating isobmff track", payload);
29
29
  CreateISOBMFFTrackPayload.parse(payload);
30
- const response = await client.authenticatedFetch(
31
- "/api/video2/isobmff_tracks",
32
- {
33
- method: "POST",
34
- body: JSON.stringify(payload)
35
- }
36
- );
30
+ const response = await client.authenticatedFetch("/api/v1/isobmff_tracks", {
31
+ method: "POST",
32
+ body: JSON.stringify(payload)
33
+ });
37
34
  log("ISOBMFF track created", response);
38
35
  if (response.ok) {
39
36
  return await response.json();
@@ -45,7 +42,7 @@ const createISOBMFFTrack = async (client, payload) => {
45
42
  const uploadISOBMFFTrack = async (client, fileId, trackId, fileStream, trackSize) => {
46
43
  log("Uploading fragment track", fileId);
47
44
  await uploadChunks(client, {
48
- url: `/api/video2/isobmff_tracks/${fileId}/${trackId}/upload`,
45
+ url: `/api/v1/isobmff_tracks/${fileId}/${trackId}/upload`,
49
46
  fileStream,
50
47
  fileSize: trackSize
51
48
  });
@@ -2,7 +2,7 @@ import { Readable } from 'node:stream';
2
2
  import { z } from 'zod';
3
3
  import { Client } from '../client.ts';
4
4
  export declare const CreateRenderPayload: z.ZodObject<{
5
- id: z.ZodString;
5
+ md5: z.ZodString;
6
6
  fps: z.ZodNumber;
7
7
  width: z.ZodNumber;
8
8
  height: z.ZodNumber;
@@ -10,7 +10,7 @@ export declare const CreateRenderPayload: z.ZodObject<{
10
10
  duration_ms: z.ZodNumber;
11
11
  strategy: z.ZodEnum<["v1", "v2"]>;
12
12
  }, "strip", z.ZodTypeAny, {
13
- id: string;
13
+ md5: string;
14
14
  height: number;
15
15
  width: number;
16
16
  strategy: "v1" | "v2";
@@ -18,7 +18,7 @@ export declare const CreateRenderPayload: z.ZodObject<{
18
18
  fps: number;
19
19
  work_slice_ms: number;
20
20
  }, {
21
- id: string;
21
+ md5: string;
22
22
  height: number;
23
23
  width: number;
24
24
  strategy: "v1" | "v2";
@@ -27,8 +27,9 @@ export declare const CreateRenderPayload: z.ZodObject<{
27
27
  work_slice_ms: number;
28
28
  }>;
29
29
  export interface CreateRenderResult {
30
- status: "complete" | "created" | "failed" | "pending" | "rendering";
31
30
  id: string;
31
+ md5: string;
32
+ status: "complete" | "created" | "failed" | "pending" | "rendering";
32
33
  }
33
34
  export declare const createRender: (client: Client, payload: z.infer<typeof CreateRenderPayload>) => Promise<CreateRenderResult>;
34
35
  export declare const uploadRender: (client: Client, fileId: string, fileStream: Readable, folderSize: number) => Promise<unknown>;
@@ -3,7 +3,7 @@ import debug from "debug";
3
3
  const log = debug("ef:api:renders");
4
4
  const FILE_SIZE_LIMIT = 1024 * 1024 * 16;
5
5
  const CreateRenderPayload = z.object({
6
- id: z.string().uuid(),
6
+ md5: z.string(),
7
7
  fps: z.number(),
8
8
  width: z.number().int(),
9
9
  height: z.number().int(),
@@ -13,7 +13,7 @@ const CreateRenderPayload = z.object({
13
13
  });
14
14
  const createRender = async (client, payload) => {
15
15
  log("Creating render", payload);
16
- const response = await client.authenticatedFetch("/api/video2/renders", {
16
+ const response = await client.authenticatedFetch("/api/v1/renders", {
17
17
  method: "POST",
18
18
  body: JSON.stringify(payload)
19
19
  });
@@ -32,7 +32,7 @@ const uploadRender = async (client, fileId, fileStream, folderSize) => {
32
32
  throw new Error(`File size exceeds limit of ${FILE_SIZE_LIMIT} bytes`);
33
33
  }
34
34
  const response = await client.authenticatedFetch(
35
- `/api/video2/renders/${fileId}/upload`,
35
+ `/api/v1/renders/${fileId}/upload`,
36
36
  {
37
37
  method: "POST",
38
38
  body: fileStream
@@ -1,45 +1,53 @@
1
1
  import { Readable } from 'node:stream';
2
2
  import { z } from 'zod';
3
3
  import { Client } from '../client.ts';
4
- declare const FileProcessors: z.ZodEffects<z.ZodArray<z.ZodUnion<[z.ZodLiteral<"isobmff">, z.ZodLiteral<"captions">]>, "many">, ("captions" | "isobmff")[], ("captions" | "isobmff")[]>;
4
+ declare const FileProcessors: z.ZodEffects<z.ZodArray<z.ZodUnion<[z.ZodLiteral<"isobmff">, z.ZodLiteral<"image">, z.ZodLiteral<"captions">]>, "many">, ("captions" | "image" | "isobmff")[], ("captions" | "image" | "isobmff")[]>;
5
5
  export declare const CreateUnprocessedFilePayload: z.ZodObject<{
6
- id: z.ZodString;
6
+ md5: z.ZodString;
7
7
  filename: z.ZodString;
8
- processes: z.ZodOptional<z.ZodEffects<z.ZodArray<z.ZodUnion<[z.ZodLiteral<"isobmff">, z.ZodLiteral<"captions">]>, "many">, ("captions" | "isobmff")[], ("captions" | "isobmff")[]>>;
8
+ processes: z.ZodOptional<z.ZodEffects<z.ZodArray<z.ZodUnion<[z.ZodLiteral<"isobmff">, z.ZodLiteral<"image">, z.ZodLiteral<"captions">]>, "many">, ("captions" | "image" | "isobmff")[], ("captions" | "image" | "isobmff")[]>>;
9
9
  byte_size: z.ZodNumber;
10
10
  }, "strip", z.ZodTypeAny, {
11
- id: string;
11
+ md5: string;
12
12
  filename: string;
13
13
  byte_size: number;
14
- processes?: ("captions" | "isobmff")[] | undefined;
14
+ processes?: ("captions" | "image" | "isobmff")[] | undefined;
15
15
  }, {
16
- id: string;
16
+ md5: string;
17
17
  filename: string;
18
18
  byte_size: number;
19
- processes?: ("captions" | "isobmff")[] | undefined;
19
+ processes?: ("captions" | "image" | "isobmff")[] | undefined;
20
20
  }>;
21
21
  export declare const UpdateUnprocessedFilePayload: z.ZodObject<{
22
- processes: z.ZodOptional<z.ZodEffects<z.ZodArray<z.ZodUnion<[z.ZodLiteral<"isobmff">, z.ZodLiteral<"captions">]>, "many">, ("captions" | "isobmff")[], ("captions" | "isobmff")[]>>;
22
+ processes: z.ZodOptional<z.ZodEffects<z.ZodArray<z.ZodUnion<[z.ZodLiteral<"isobmff">, z.ZodLiteral<"image">, z.ZodLiteral<"captions">]>, "many">, ("captions" | "image" | "isobmff")[], ("captions" | "image" | "isobmff")[]>>;
23
23
  }, "strip", z.ZodTypeAny, {
24
- processes?: ("captions" | "isobmff")[] | undefined;
24
+ processes?: ("captions" | "image" | "isobmff")[] | undefined;
25
25
  }, {
26
- processes?: ("captions" | "isobmff")[] | undefined;
26
+ processes?: ("captions" | "image" | "isobmff")[] | undefined;
27
27
  }>;
28
28
  export interface CreateUnprocessedFileResult {
29
29
  byte_size: number;
30
30
  next_byte: number;
31
+ complete: boolean;
31
32
  id: string;
33
+ md5: string;
32
34
  processes: z.infer<typeof FileProcessors>;
35
+ asset_id: string;
33
36
  }
34
37
  export interface UpdateUnprocessedFileResult {
35
38
  byte_size?: number;
36
39
  next_byte: number;
40
+ complete: boolean;
37
41
  id: string;
42
+ md5: string;
38
43
  processes: z.infer<typeof FileProcessors>;
44
+ asset_id: string;
39
45
  }
40
46
  export declare const createUnprocessedFile: (client: Client, payload: z.infer<typeof CreateUnprocessedFilePayload>) => Promise<CreateUnprocessedFileResult>;
41
47
  export declare const updateUnprocessedFile: (client: Client, fileId: string, payload: Partial<z.infer<typeof UpdateUnprocessedFilePayload>>) => Promise<UpdateUnprocessedFileResult>;
42
48
  export declare const uploadUnprocessedFile: (client: Client, fileId: string, fileStream: Readable, fileSize: number) => Promise<void>;
43
49
  export declare const processAVFileBuffer: (client: Client, buffer: Buffer, filename?: string) => Promise<UpdateUnprocessedFileResult>;
44
50
  export declare const processAVFile: (client: Client, filePath: string) => Promise<UpdateUnprocessedFileResult>;
51
+ export declare const processImageFileBuffer: (client: Client, buffer: Buffer, filename?: string) => Promise<UpdateUnprocessedFileResult>;
52
+ export declare const processImageFile: (client: Client, filePath: string) => Promise<UpdateUnprocessedFileResult>;
45
53
  export {};
@@ -7,7 +7,12 @@ import debug from "debug";
7
7
  import { md5Buffer, md5FilePath } from "@editframe/assets";
8
8
  import { uploadChunks } from "../uploadChunks.js";
9
9
  const log = debug("ef:api:unprocessed-file");
10
- const FileProcessors = z.array(z.union([z.literal("isobmff"), z.literal("captions")])).refine(
10
+ const FileProcessor = z.union([
11
+ z.literal("isobmff"),
12
+ z.literal("image"),
13
+ z.literal("captions")
14
+ ]);
15
+ const FileProcessors = z.array(FileProcessor).refine(
11
16
  (value) => {
12
17
  return new Set(value).size === value.length;
13
18
  },
@@ -17,7 +22,7 @@ const FileProcessors = z.array(z.union([z.literal("isobmff"), z.literal("caption
17
22
  );
18
23
  const MAX_FILE_SIZE = 1024 * 1024 * 1024;
19
24
  const CreateUnprocessedFilePayload = z.object({
20
- id: z.string(),
25
+ md5: z.string(),
21
26
  filename: z.string(),
22
27
  processes: FileProcessors.optional(),
23
28
  byte_size: z.number().int().max(MAX_FILE_SIZE)
@@ -75,59 +80,83 @@ const uploadUnprocessedFile = async (client, fileId, fileStream, fileSize) => {
75
80
  });
76
81
  log("Unprocessed file upload complete");
77
82
  };
78
- const processAVFileBuffer = async (client, buffer, filename = "buffer") => {
79
- log("Processing AV file buffer");
80
- const fileId = md5Buffer(buffer);
81
- log("File ID", fileId);
82
- log(`File size: ${buffer.byteLength} bytes`);
83
- await createUnprocessedFile(client, {
84
- id: fileId,
83
+ const processResource = async (client, filename, md5, byteSize, processor, doUpload) => {
84
+ log("Processing", { filename, md5, byteSize, processor });
85
+ const unprocessedFile = await createUnprocessedFile(client, {
86
+ md5,
85
87
  processes: [],
86
88
  filename,
87
- byte_size: buffer.byteLength
89
+ byte_size: byteSize
88
90
  });
89
- const readStream = new Readable({
90
- read() {
91
- readStream.push(buffer);
92
- readStream.push(null);
93
- }
94
- });
95
- await uploadUnprocessedFile(client, fileId, readStream, buffer.byteLength);
96
- const fileInformation = await updateUnprocessedFile(client, fileId, {
97
- processes: ["isobmff"]
98
- });
99
- log("File processed", fileInformation);
100
- return fileInformation;
101
- };
102
- const processAVFile = async (client, filePath) => {
103
- log("Processing AV file", filePath);
104
- const fileId = await md5FilePath(filePath);
105
- log("File ID", fileId);
106
- await createUnprocessedFile(client, {
107
- id: fileId,
108
- processes: [],
109
- filename: basename(filePath),
110
- byte_size: (await stat(filePath)).size
111
- });
112
- const readStream = createReadStream(filePath);
113
- await uploadUnprocessedFile(
91
+ if (unprocessedFile.complete === false) {
92
+ await doUpload(unprocessedFile.id);
93
+ }
94
+ if (unprocessedFile.processes.includes(processor)) {
95
+ log("File already processed", unprocessedFile);
96
+ return unprocessedFile;
97
+ }
98
+ const fileInformation = await updateUnprocessedFile(
114
99
  client,
115
- fileId,
116
- readStream,
117
- (await stat(filePath)).size
100
+ unprocessedFile.id,
101
+ {
102
+ processes: [processor]
103
+ }
118
104
  );
119
- const fileInformation = await updateUnprocessedFile(client, fileId, {
120
- processes: ["isobmff"]
121
- });
122
105
  log("File processed", fileInformation);
123
106
  return fileInformation;
124
107
  };
108
+ const buildBufferProcessor = (processor) => {
109
+ return async (client, buffer, filename = "buffer") => {
110
+ log(`Processing file buffer: ${processor}`, filename);
111
+ const md5 = md5Buffer(buffer);
112
+ return await processResource(
113
+ client,
114
+ filename,
115
+ md5,
116
+ buffer.byteLength,
117
+ processor,
118
+ async (id) => {
119
+ const readStream = new Readable({
120
+ read() {
121
+ readStream.push(buffer);
122
+ readStream.push(null);
123
+ }
124
+ });
125
+ await uploadUnprocessedFile(client, id, readStream, buffer.byteLength);
126
+ }
127
+ );
128
+ };
129
+ };
130
+ const buildFileProcessor = (processor) => {
131
+ return async (client, filePath) => {
132
+ log(`Processing file ${processor}`, filePath);
133
+ const md5 = await md5FilePath(filePath);
134
+ const byteSize = (await stat(filePath)).size;
135
+ return await processResource(
136
+ client,
137
+ basename(filePath),
138
+ md5,
139
+ byteSize,
140
+ processor,
141
+ async (id) => {
142
+ const readStream = createReadStream(filePath);
143
+ return await uploadUnprocessedFile(client, id, readStream, byteSize);
144
+ }
145
+ );
146
+ };
147
+ };
148
+ const processAVFileBuffer = buildBufferProcessor("isobmff");
149
+ const processAVFile = buildFileProcessor("isobmff");
150
+ const processImageFileBuffer = buildBufferProcessor("image");
151
+ const processImageFile = buildFileProcessor("image");
125
152
  export {
126
153
  CreateUnprocessedFilePayload,
127
154
  UpdateUnprocessedFilePayload,
128
155
  createUnprocessedFile,
129
156
  processAVFile,
130
157
  processAVFileBuffer,
158
+ processImageFile,
159
+ processImageFileBuffer,
131
160
  updateUnprocessedFile,
132
161
  uploadUnprocessedFile
133
162
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@editframe/api",
3
- "version": "0.9.0-beta.1",
3
+ "version": "0.10.0-beta.2",
4
4
  "description": "API functions for EditFrame",
5
5
  "exports": {
6
6
  ".": {
@@ -28,7 +28,7 @@
28
28
  "vite-tsconfig-paths": "^4.3.2"
29
29
  },
30
30
  "dependencies": {
31
- "@editframe/assets": "0.9.0-beta.1",
31
+ "@editframe/assets": "0.10.0-beta.2",
32
32
  "debug": "^4.3.5",
33
33
  "jsonwebtoken": "^9.0.2",
34
34
  "node-fetch": "^3.3.2",
@@ -18,7 +18,7 @@ describe("CaptionFile", () => {
18
18
  test("Throws when file is too large", async () => {
19
19
  await expect(
20
20
  createCaptionFile(client, {
21
- id: "test-id",
21
+ md5: "test-md5",
22
22
  filename: "test",
23
23
  byte_size: 1024 * 1024 * 3,
24
24
  }),
@@ -29,14 +29,14 @@ describe("CaptionFile", () => {
29
29
 
30
30
  test("Throws when server returns an error", async () => {
31
31
  server.use(
32
- http.post("http://localhost/api/video2/caption_files", () =>
32
+ http.post("http://localhost/api/v1/caption_files", () =>
33
33
  HttpResponse.text("Internal Server Error", { status: 500 }),
34
34
  ),
35
35
  );
36
36
 
37
37
  await expect(
38
38
  createCaptionFile(client, {
39
- id: "test-id",
39
+ md5: "test-md5",
40
40
  filename: "test",
41
41
  byte_size: 4,
42
42
  }),
@@ -47,7 +47,7 @@ describe("CaptionFile", () => {
47
47
 
48
48
  test("Returns json data from the http response", async () => {
49
49
  server.use(
50
- http.post("http://localhost/api/video2/caption_files", () =>
50
+ http.post("http://localhost/api/v1/caption_files", () =>
51
51
  HttpResponse.json(
52
52
  { id: "test-id" },
53
53
  { status: 200, statusText: "OK" },
@@ -56,7 +56,7 @@ describe("CaptionFile", () => {
56
56
  );
57
57
 
58
58
  const response = await createCaptionFile(client, {
59
- id: "test-id",
59
+ md5: "test-md5",
60
60
  filename: "test",
61
61
  byte_size: 4,
62
62
  });
@@ -81,9 +81,8 @@ describe("CaptionFile", () => {
81
81
 
82
82
  test("Throws when server returns an error", async () => {
83
83
  server.use(
84
- http.post(
85
- "http://localhost/api/video2/caption_files/test-id/upload",
86
- () => HttpResponse.text("Internal Server Error", { status: 500 }),
84
+ http.post("http://localhost/api/v1/caption_files/test-id/upload", () =>
85
+ HttpResponse.text("Internal Server Error", { status: 500 }),
87
86
  ),
88
87
  );
89
88
 
@@ -101,13 +100,11 @@ describe("CaptionFile", () => {
101
100
 
102
101
  test("Returns json data from the http response", async () => {
103
102
  server.use(
104
- http.post(
105
- "http://localhost/api/video2/caption_files/test-id/upload",
106
- () =>
107
- HttpResponse.json(
108
- { id: "test-id" },
109
- { status: 200, statusText: "OK" },
110
- ),
103
+ http.post("http://localhost/api/v1/caption_files/test-id/upload", () =>
104
+ HttpResponse.json(
105
+ { id: "test-id" },
106
+ { status: 200, statusText: "OK" },
107
+ ),
111
108
  ),
112
109
  );
113
110
 
@@ -10,7 +10,7 @@ const log = debug("ef:api:caption-file");
10
10
  const MAX_CAPTION_SIZE = 1024 * 1024 * 2; // 2MB
11
11
 
12
12
  export const CreateCaptionFilePayload = z.object({
13
- id: z.string(),
13
+ md5: z.string(),
14
14
  filename: z.string(),
15
15
  byte_size: z.number().int().max(MAX_CAPTION_SIZE),
16
16
  });
@@ -18,7 +18,8 @@ export const CreateCaptionFilePayload = z.object({
18
18
  export interface CreateCaptionFileResult {
19
19
  complete: boolean | null;
20
20
  id: string;
21
- assetId: string;
21
+ md5: string;
22
+ asset_id: string;
22
23
  }
23
24
 
24
25
  const restrictSize = (size: number) => {
@@ -52,13 +53,10 @@ export const createCaptionFile = async (
52
53
  ) => {
53
54
  log("Creating caption file", payload);
54
55
  restrictSize(payload.byte_size);
55
- const response = await client.authenticatedFetch(
56
- "/api/video2/caption_files",
57
- {
58
- method: "POST",
59
- body: JSON.stringify(payload),
60
- },
61
- );
56
+ const response = await client.authenticatedFetch("/api/v1/caption_files", {
57
+ method: "POST",
58
+ body: JSON.stringify(payload),
59
+ });
62
60
  log("Caption file created", response);
63
61
 
64
62
  if (response.ok) {
@@ -80,7 +78,7 @@ export const uploadCaptionFile = async (
80
78
  restrictSize(fileSize);
81
79
 
82
80
  const response = await client.authenticatedFetch(
83
- `/api/video2/caption_files/${fileId}/upload`,
81
+ `/api/v1/caption_files/${fileId}/upload`,
84
82
  {
85
83
  method: "POST",
86
84
  body: fileStream,