@editframe/cli 0.8.0-beta.5 → 0.8.0-beta.7
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/VERSION.d.ts +1 -1
- package/dist/VERSION.js +1 -1
- package/dist/commands/process-file.js +6 -3
- package/dist/commands/render.js +3 -1
- package/dist/commands/webhook.js +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/operations/processRenderInfo.d.ts +0 -1
- package/dist/operations/syncAssetsDirectory.js +32 -9
- package/dist/utils/attachWorkbench.d.ts +0 -1
- package/dist/utils/getFolderSize.d.ts +1 -0
- package/dist/utils/getFolderSize.js +22 -0
- package/dist/utils/index.d.ts +0 -1
- package/dist/utils/launchBrowserAndWaitForSDK.d.ts +0 -1
- package/dist/utils/startDevServer.d.ts +0 -1
- package/dist/utils/startPreviewServer.d.ts +0 -1
- package/dist/utils/validateVideoResolution.d.ts +1 -1
- package/package.json +6 -6
- package/src/commands/process-file.ts +6 -2
- package/src/commands/render.ts +3 -1
- package/src/commands/webhook.ts +0 -1
- package/src/operations/syncAssetsDirectory.ts +30 -8
- package/src/utils/getFolderSize.ts +24 -0
package/dist/VERSION.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "0.8.0-beta.
|
|
1
|
+
export declare const VERSION = "0.8.0-beta.7";
|
package/dist/VERSION.js
CHANGED
|
@@ -1,23 +1,26 @@
|
|
|
1
1
|
import { basename } from "node:path";
|
|
2
|
+
import { stat } from "node:fs/promises";
|
|
3
|
+
import { createReadStream } from "node:fs";
|
|
2
4
|
import { program } from "commander";
|
|
3
5
|
import { withSpinner } from "../utils/withSpinner.js";
|
|
4
6
|
import { getClient } from "../utils/index.js";
|
|
5
|
-
import { createReadStream } from "node:fs";
|
|
6
7
|
import { createUnprocessedFile, uploadUnprocessedFile, updateUnprocessedFile } from "@editframe/api";
|
|
7
8
|
import { md5FilePath } from "@editframe/assets";
|
|
8
9
|
program.command("process-file <file>").description("Upload a audio/video to Editframe for processing.").action(async (path) => {
|
|
9
10
|
const client = getClient();
|
|
10
11
|
const fileId = await md5FilePath(path);
|
|
12
|
+
const byte_size = (await stat(path)).size;
|
|
11
13
|
await withSpinner("Creating unprocessed file record", async () => {
|
|
12
14
|
await createUnprocessedFile(client, {
|
|
13
15
|
id: fileId,
|
|
14
16
|
processes: [],
|
|
15
|
-
filename: basename(path)
|
|
17
|
+
filename: basename(path),
|
|
18
|
+
byte_size
|
|
16
19
|
});
|
|
17
20
|
});
|
|
18
21
|
const readStream = createReadStream(path);
|
|
19
22
|
await withSpinner("Uploading file", async () => {
|
|
20
|
-
await uploadUnprocessedFile(client, fileId, readStream);
|
|
23
|
+
await uploadUnprocessedFile(client, fileId, readStream, byte_size);
|
|
21
24
|
});
|
|
22
25
|
const unprocessedFile = await withSpinner(
|
|
23
26
|
"Marking for processing",
|
package/dist/commands/render.js
CHANGED
|
@@ -16,6 +16,7 @@ import { getClient } from "../utils/index.js";
|
|
|
16
16
|
import { getRenderInfo } from "../operations/getRenderInfo.js";
|
|
17
17
|
import { processRenderInfo } from "../operations/processRenderInfo.js";
|
|
18
18
|
import { validateVideoResolution } from "../utils/validateVideoResolution.js";
|
|
19
|
+
import { getFolderSize } from "../utils/getFolderSize.js";
|
|
19
20
|
const buildProductionUrl = async (origin, tagName, assetPath) => {
|
|
20
21
|
const md5Sum = await md5FilePath(assetPath);
|
|
21
22
|
const basename = path.basename(assetPath);
|
|
@@ -142,7 +143,8 @@ program.command("render [directory]").description(
|
|
|
142
143
|
);
|
|
143
144
|
const readable = new PassThrough();
|
|
144
145
|
tarStream.pipe(readable);
|
|
145
|
-
await
|
|
146
|
+
const folderSize = await getFolderSize(distDir);
|
|
147
|
+
await uploadRender(getClient(), md5, readable, folderSize);
|
|
146
148
|
process.stderr.write("Render assets uploaded\n");
|
|
147
149
|
process.stderr.write(inspect(render));
|
|
148
150
|
process.stderr.write("\n");
|
package/dist/commands/webhook.js
CHANGED
|
@@ -26,7 +26,6 @@ const testWebhookURL = async ({
|
|
|
26
26
|
})
|
|
27
27
|
}
|
|
28
28
|
);
|
|
29
|
-
console.log(response);
|
|
30
29
|
return response.json();
|
|
31
30
|
};
|
|
32
31
|
const webhookCommand = program.command("webhook").description("Test webhook URL with a topic").option("-u, --webhookURL <webhookURL>", "Webhook URL").addOption(new Option("-t, --topic <topic>", "Topic").choices(topics)).action(async () => {
|
package/dist/index.d.ts
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
|
@@ -2,7 +2,7 @@ import { Probe } from "@editframe/assets";
|
|
|
2
2
|
import fs from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { createCaptionFile, uploadCaptionFile, createISOBMFFFile, uploadFragmentIndex, createISOBMFFTrack, uploadISOBMFFTrack, createImageFile, uploadImageFile } from "@editframe/api";
|
|
5
|
-
import { createReadStream } from "node:fs";
|
|
5
|
+
import { createReadStream, statSync } from "node:fs";
|
|
6
6
|
import { getClient } from "../utils/index.js";
|
|
7
7
|
const imageMatch = /\.(png|jpe?g|gif|webp)$/i;
|
|
8
8
|
const trackMatch = /\.track-[\d]+.mp4$/i;
|
|
@@ -76,6 +76,7 @@ const syncAssetDirectory = async (projectDirectory) => {
|
|
|
76
76
|
case imageMatch.test(subAsset): {
|
|
77
77
|
const probeResult = await Probe.probePath(subAssetPath);
|
|
78
78
|
const [videoProbe] = probeResult.videoStreams;
|
|
79
|
+
const { format } = probeResult;
|
|
79
80
|
if (!videoProbe) {
|
|
80
81
|
process.stderr.write(
|
|
81
82
|
`🚫 No video stream found in image: ${subAsset}
|
|
@@ -96,7 +97,8 @@ const syncAssetDirectory = async (projectDirectory) => {
|
|
|
96
97
|
filename: subAsset,
|
|
97
98
|
width: videoProbe.width,
|
|
98
99
|
height: videoProbe.height,
|
|
99
|
-
mime_type: `image/${ext}
|
|
100
|
+
mime_type: `image/${ext}`,
|
|
101
|
+
byte_size: (await fs.stat(subAssetPath)).size
|
|
100
102
|
});
|
|
101
103
|
if (created) {
|
|
102
104
|
if (created.complete) {
|
|
@@ -105,7 +107,8 @@ const syncAssetDirectory = async (projectDirectory) => {
|
|
|
105
107
|
await uploadImageFile(
|
|
106
108
|
getClient(),
|
|
107
109
|
created.id,
|
|
108
|
-
createReadStream(subAssetPath)
|
|
110
|
+
createReadStream(subAssetPath),
|
|
111
|
+
Number.parseInt(format.size || "0")
|
|
109
112
|
);
|
|
110
113
|
process.stderr.write(" ✅ Image has been synced.\n");
|
|
111
114
|
}
|
|
@@ -168,14 +171,15 @@ const syncAssetDirectory = async (projectDirectory) => {
|
|
|
168
171
|
createPayload
|
|
169
172
|
);
|
|
170
173
|
if (createdTrack) {
|
|
171
|
-
if (createdTrack.
|
|
174
|
+
if (createdTrack.next_byte === createdTrack.byte_size - 1) {
|
|
172
175
|
process.stderr.write(" ✔ Track has already been synced.\n");
|
|
173
176
|
} else {
|
|
174
177
|
await uploadISOBMFFTrack(
|
|
175
178
|
getClient(),
|
|
176
179
|
createdFile.id,
|
|
177
180
|
Number(trackId),
|
|
178
|
-
createReadStream(subAssetPath)
|
|
181
|
+
createReadStream(subAssetPath),
|
|
182
|
+
createdTrack.byte_size
|
|
179
183
|
);
|
|
180
184
|
process.stderr.write(" ✅ Track has been synced.\n");
|
|
181
185
|
}
|
|
@@ -197,8 +201,14 @@ const syncAssetDirectory = async (projectDirectory) => {
|
|
|
197
201
|
" ✔ Fragment index has already been synced.\n"
|
|
198
202
|
);
|
|
199
203
|
} else {
|
|
204
|
+
const stats = statSync(subAssetPath);
|
|
200
205
|
const readStream = createReadStream(subAssetPath);
|
|
201
|
-
await uploadFragmentIndex(
|
|
206
|
+
await uploadFragmentIndex(
|
|
207
|
+
getClient(),
|
|
208
|
+
asset,
|
|
209
|
+
readStream,
|
|
210
|
+
stats.size
|
|
211
|
+
);
|
|
202
212
|
process.stderr.write(" ✅ Fragment index has been synced.\n");
|
|
203
213
|
}
|
|
204
214
|
await syncStatus.markSynced();
|
|
@@ -216,15 +226,28 @@ const syncAssetDirectory = async (projectDirectory) => {
|
|
|
216
226
|
`);
|
|
217
227
|
const createdFile = await createCaptionFile(getClient(), {
|
|
218
228
|
id: asset,
|
|
219
|
-
filename: subAsset.replace(/\.captions.json$/, "")
|
|
229
|
+
filename: subAsset.replace(/\.captions.json$/, ""),
|
|
230
|
+
byte_size: (await fs.stat(subAsset)).size
|
|
220
231
|
});
|
|
221
232
|
if (createdFile) {
|
|
222
233
|
if (createdFile.complete) {
|
|
223
234
|
process.stderr.write(" ✔ Captions have already been synced.\n");
|
|
224
235
|
} else {
|
|
225
236
|
const readStream = createReadStream(subAssetPath);
|
|
226
|
-
|
|
227
|
-
|
|
237
|
+
const stats = statSync(subAssetPath);
|
|
238
|
+
await uploadCaptionFile(
|
|
239
|
+
getClient(),
|
|
240
|
+
asset,
|
|
241
|
+
readStream,
|
|
242
|
+
stats.size
|
|
243
|
+
).catch((error) => {
|
|
244
|
+
process.stderr.write(
|
|
245
|
+
`🚫 Error uploading captions: ${error.message}
|
|
246
|
+
`
|
|
247
|
+
);
|
|
248
|
+
}).then(() => {
|
|
249
|
+
process.stderr.write(" ✅ Captions have been synced.\n");
|
|
250
|
+
});
|
|
228
251
|
}
|
|
229
252
|
await syncStatus.markSynced();
|
|
230
253
|
} else {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const getFolderSize: (folderPath: string) => Promise<number>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { promises } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
const getFolderSize = async (folderPath) => {
|
|
4
|
+
let totalSize = 0;
|
|
5
|
+
async function calculateSize(dir) {
|
|
6
|
+
const files = await promises.readdir(dir);
|
|
7
|
+
for (const file of files) {
|
|
8
|
+
const filePath = path.join(dir, file);
|
|
9
|
+
const stats = await promises.stat(filePath);
|
|
10
|
+
if (stats.isDirectory()) {
|
|
11
|
+
await calculateSize(filePath);
|
|
12
|
+
} else {
|
|
13
|
+
totalSize += stats.size;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
await calculateSize(folderPath);
|
|
18
|
+
return totalSize;
|
|
19
|
+
};
|
|
20
|
+
export {
|
|
21
|
+
getFolderSize
|
|
22
|
+
};
|
package/dist/utils/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@editframe/cli",
|
|
3
|
-
"version": "0.8.0-beta.
|
|
3
|
+
"version": "0.8.0-beta.7",
|
|
4
4
|
"description": "Command line interface for EditFrame",
|
|
5
5
|
"bin": {
|
|
6
6
|
"editframe": "./dist/index.js"
|
|
@@ -19,14 +19,14 @@
|
|
|
19
19
|
"@types/promptly": "^3.0.5",
|
|
20
20
|
"@types/tar": "^6.1.13",
|
|
21
21
|
"typescript": "^5.5.4",
|
|
22
|
-
"vite-plugin-dts": "^
|
|
22
|
+
"vite-plugin-dts": "^4.0.3",
|
|
23
23
|
"vite-tsconfig-paths": "^4.3.2"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@editframe/api": "0.8.0-beta.
|
|
27
|
-
"@editframe/assets": "0.8.0-beta.
|
|
28
|
-
"@editframe/elements": "0.8.0-beta.
|
|
29
|
-
"@editframe/vite-plugin": "0.8.0-beta.
|
|
26
|
+
"@editframe/api": "0.8.0-beta.7",
|
|
27
|
+
"@editframe/assets": "0.8.0-beta.7",
|
|
28
|
+
"@editframe/elements": "0.8.0-beta.7",
|
|
29
|
+
"@editframe/vite-plugin": "0.8.0-beta.7",
|
|
30
30
|
"axios": "^1.6.8",
|
|
31
31
|
"chalk": "^5.3.0",
|
|
32
32
|
"commander": "^12.0.0",
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { basename } from "node:path";
|
|
2
|
+
import { stat } from "node:fs/promises";
|
|
3
|
+
import { createReadStream } from "node:fs";
|
|
2
4
|
|
|
3
5
|
import { program } from "commander";
|
|
4
6
|
|
|
5
7
|
import { withSpinner } from "../utils/withSpinner.ts";
|
|
6
8
|
|
|
7
9
|
import { getClient } from "../utils/index.ts";
|
|
8
|
-
import { createReadStream } from "node:fs";
|
|
9
10
|
import {
|
|
10
11
|
createUnprocessedFile,
|
|
11
12
|
updateUnprocessedFile,
|
|
@@ -21,18 +22,21 @@ program
|
|
|
21
22
|
|
|
22
23
|
const fileId = await md5FilePath(path);
|
|
23
24
|
|
|
25
|
+
const byte_size = (await stat(path)).size;
|
|
26
|
+
|
|
24
27
|
await withSpinner("Creating unprocessed file record", async () => {
|
|
25
28
|
await createUnprocessedFile(client, {
|
|
26
29
|
id: fileId,
|
|
27
30
|
processes: [],
|
|
28
31
|
filename: basename(path),
|
|
32
|
+
byte_size,
|
|
29
33
|
});
|
|
30
34
|
});
|
|
31
35
|
|
|
32
36
|
const readStream = createReadStream(path);
|
|
33
37
|
|
|
34
38
|
await withSpinner("Uploading file", async () => {
|
|
35
|
-
await uploadUnprocessedFile(client, fileId, readStream);
|
|
39
|
+
await uploadUnprocessedFile(client, fileId, readStream, byte_size);
|
|
36
40
|
});
|
|
37
41
|
|
|
38
42
|
const unprocessedFile = await withSpinner(
|
package/src/commands/render.ts
CHANGED
|
@@ -19,6 +19,7 @@ import { getClient } from "../utils/index.ts";
|
|
|
19
19
|
import { getRenderInfo } from "../operations/getRenderInfo.ts";
|
|
20
20
|
import { processRenderInfo } from "../operations/processRenderInfo.ts";
|
|
21
21
|
import { validateVideoResolution } from "../utils/validateVideoResolution.ts";
|
|
22
|
+
import { getFolderSize } from "../utils/getFolderSize.ts";
|
|
22
23
|
|
|
23
24
|
interface StrategyBuilder {
|
|
24
25
|
buildProductionUrl: (tagName: string, assetPath: string) => Promise<string>;
|
|
@@ -179,7 +180,8 @@ program
|
|
|
179
180
|
);
|
|
180
181
|
const readable = new PassThrough();
|
|
181
182
|
tarStream.pipe(readable);
|
|
182
|
-
await
|
|
183
|
+
const folderSize = await getFolderSize(distDir);
|
|
184
|
+
await uploadRender(getClient(), md5, readable, folderSize);
|
|
183
185
|
process.stderr.write("Render assets uploaded\n");
|
|
184
186
|
process.stderr.write(inspect(render));
|
|
185
187
|
process.stderr.write("\n");
|
package/src/commands/webhook.ts
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
uploadISOBMFFTrack,
|
|
13
13
|
type CreateISOBMFFTrackPayload,
|
|
14
14
|
} from "@editframe/api";
|
|
15
|
+
import { statSync } from "node:fs";
|
|
15
16
|
|
|
16
17
|
import { createReadStream } from "node:fs";
|
|
17
18
|
import type { z } from "zod";
|
|
@@ -97,6 +98,7 @@ export const syncAssetDirectory = async (
|
|
|
97
98
|
case imageMatch.test(subAsset): {
|
|
98
99
|
const probeResult = await Probe.probePath(subAssetPath);
|
|
99
100
|
const [videoProbe] = probeResult.videoStreams;
|
|
101
|
+
const { format } = probeResult;
|
|
100
102
|
if (!videoProbe) {
|
|
101
103
|
process.stderr.write(
|
|
102
104
|
`🚫 No video stream found in image: ${subAsset}\n`,
|
|
@@ -122,6 +124,7 @@ export const syncAssetDirectory = async (
|
|
|
122
124
|
width: videoProbe.width,
|
|
123
125
|
height: videoProbe.height,
|
|
124
126
|
mime_type: `image/${ext}`,
|
|
127
|
+
byte_size: (await fs.stat(subAssetPath)).size,
|
|
125
128
|
});
|
|
126
129
|
if (created) {
|
|
127
130
|
if (created.complete) {
|
|
@@ -131,6 +134,7 @@ export const syncAssetDirectory = async (
|
|
|
131
134
|
getClient(),
|
|
132
135
|
created.id,
|
|
133
136
|
createReadStream(subAssetPath),
|
|
137
|
+
Number.parseInt(format.size || "0"),
|
|
134
138
|
);
|
|
135
139
|
process.stderr.write(" ✅ Image has been synced.\n");
|
|
136
140
|
}
|
|
@@ -170,7 +174,7 @@ export const syncAssetDirectory = async (
|
|
|
170
174
|
const stat = await fs.stat(subAssetPath);
|
|
171
175
|
|
|
172
176
|
/**
|
|
173
|
-
* Because the payload is a discriminated union, we
|
|
177
|
+
* Because the payload is a discriminated union, we need to create these objects
|
|
174
178
|
* only after the value for type has been narrowed, otherwise the object will
|
|
175
179
|
* have type: "audio" | "video" which doesnt' match the payload type that
|
|
176
180
|
* looks more like { type: "audio", ... } | { type: "video", ... }
|
|
@@ -201,10 +205,7 @@ export const syncAssetDirectory = async (
|
|
|
201
205
|
);
|
|
202
206
|
|
|
203
207
|
if (createdTrack) {
|
|
204
|
-
if (
|
|
205
|
-
createdTrack.last_received_byte ===
|
|
206
|
-
createdTrack.byte_size - 1
|
|
207
|
-
) {
|
|
208
|
+
if (createdTrack.next_byte === createdTrack.byte_size - 1) {
|
|
208
209
|
process.stderr.write(" ✔ Track has already been synced.\n");
|
|
209
210
|
} else {
|
|
210
211
|
await uploadISOBMFFTrack(
|
|
@@ -212,6 +213,7 @@ export const syncAssetDirectory = async (
|
|
|
212
213
|
createdFile.id,
|
|
213
214
|
Number(trackId),
|
|
214
215
|
createReadStream(subAssetPath),
|
|
216
|
+
createdTrack.byte_size,
|
|
215
217
|
);
|
|
216
218
|
process.stderr.write(" ✅ Track has been synced.\n");
|
|
217
219
|
}
|
|
@@ -233,8 +235,14 @@ export const syncAssetDirectory = async (
|
|
|
233
235
|
" ✔ Fragment index has already been synced.\n",
|
|
234
236
|
);
|
|
235
237
|
} else {
|
|
238
|
+
const stats = statSync(subAssetPath);
|
|
236
239
|
const readStream = createReadStream(subAssetPath);
|
|
237
|
-
await uploadFragmentIndex(
|
|
240
|
+
await uploadFragmentIndex(
|
|
241
|
+
getClient(),
|
|
242
|
+
asset,
|
|
243
|
+
readStream,
|
|
244
|
+
stats.size,
|
|
245
|
+
);
|
|
238
246
|
process.stderr.write(" ✅ Fragment index has been synced.\n");
|
|
239
247
|
}
|
|
240
248
|
await syncStatus.markSynced();
|
|
@@ -251,14 +259,28 @@ export const syncAssetDirectory = async (
|
|
|
251
259
|
const createdFile = await createCaptionFile(getClient(), {
|
|
252
260
|
id: asset,
|
|
253
261
|
filename: subAsset.replace(/\.captions.json$/, ""),
|
|
262
|
+
byte_size: (await fs.stat(subAsset)).size,
|
|
254
263
|
});
|
|
255
264
|
if (createdFile) {
|
|
256
265
|
if (createdFile.complete) {
|
|
257
266
|
process.stderr.write(" ✔ Captions have already been synced.\n");
|
|
258
267
|
} else {
|
|
259
268
|
const readStream = createReadStream(subAssetPath);
|
|
260
|
-
|
|
261
|
-
|
|
269
|
+
const stats = statSync(subAssetPath);
|
|
270
|
+
await uploadCaptionFile(
|
|
271
|
+
getClient(),
|
|
272
|
+
asset,
|
|
273
|
+
readStream,
|
|
274
|
+
stats.size,
|
|
275
|
+
)
|
|
276
|
+
.catch((error) => {
|
|
277
|
+
process.stderr.write(
|
|
278
|
+
`🚫 Error uploading captions: ${error.message}\n`,
|
|
279
|
+
);
|
|
280
|
+
})
|
|
281
|
+
.then(() => {
|
|
282
|
+
process.stderr.write(" ✅ Captions have been synced.\n");
|
|
283
|
+
});
|
|
262
284
|
}
|
|
263
285
|
await syncStatus.markSynced();
|
|
264
286
|
} else {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
|
|
4
|
+
export const getFolderSize = async (folderPath: string): Promise<number> => {
|
|
5
|
+
let totalSize = 0;
|
|
6
|
+
|
|
7
|
+
async function calculateSize(dir: string): Promise<void> {
|
|
8
|
+
const files = await fs.readdir(dir);
|
|
9
|
+
|
|
10
|
+
for (const file of files) {
|
|
11
|
+
const filePath = path.join(dir, file);
|
|
12
|
+
const stats = await fs.stat(filePath);
|
|
13
|
+
|
|
14
|
+
if (stats.isDirectory()) {
|
|
15
|
+
await calculateSize(filePath);
|
|
16
|
+
} else {
|
|
17
|
+
totalSize += stats.size;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
await calculateSize(folderPath);
|
|
23
|
+
return totalSize;
|
|
24
|
+
};
|