@editframe/cli 0.10.0-beta.3 → 0.10.0-beta.5

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 CHANGED
@@ -1 +1 @@
1
- export declare const VERSION = "0.10.0-beta.3";
1
+ export declare const VERSION = "0.10.0-beta.5";
package/dist/VERSION.js CHANGED
@@ -1,4 +1,4 @@
1
- const VERSION = "0.10.0-beta.3";
1
+ const VERSION = "0.10.0-beta.5";
2
2
  export {
3
3
  VERSION
4
4
  };
@@ -10,26 +10,32 @@ program.command("process-file <file>").description("Upload a audio/video to Edit
10
10
  const client = getClient();
11
11
  const md5 = await md5FilePath(path);
12
12
  const byte_size = (await stat(path)).size;
13
- await withSpinner("Creating unprocessed file record", async () => {
14
- await createUnprocessedFile(client, {
13
+ const unprocessedFile = await withSpinner(
14
+ "Creating unprocessed file record",
15
+ async () => await createUnprocessedFile(client, {
15
16
  md5,
16
17
  processes: [],
17
18
  filename: basename(path),
18
19
  byte_size
19
- });
20
- });
20
+ })
21
+ );
21
22
  const readStream = createReadStream(path);
22
23
  await withSpinner("Uploading file", async () => {
23
- await uploadUnprocessedFile(client, md5, readStream, byte_size);
24
+ await uploadUnprocessedFile(
25
+ client,
26
+ unprocessedFile.id,
27
+ readStream,
28
+ byte_size
29
+ );
24
30
  });
25
- const unprocessedFile = await withSpinner(
31
+ const updatedUnprocessedFile = await withSpinner(
26
32
  "Marking for processing",
27
33
  async () => {
28
- return await updateUnprocessedFile(client, md5, {
34
+ return await updateUnprocessedFile(client, unprocessedFile.id, {
29
35
  processes: ["isobmff"]
30
36
  });
31
37
  }
32
38
  );
33
39
  process.stderr.write("File uploaded and marked for processing.\n");
34
- console.log(JSON.stringify(unprocessedFile, null, 2));
40
+ console.log(JSON.stringify(updatedUnprocessedFile, null, 2));
35
41
  });
@@ -5,7 +5,6 @@ import { PassThrough } from "node:stream";
5
5
  import * as tar from "tar";
6
6
  import { program, Option } from "commander";
7
7
  import { parse } from "node-html-parser";
8
- import { build } from "vite";
9
8
  import { md5Directory, md5FilePath } from "@editframe/assets";
10
9
  import { withSpinner } from "../utils/withSpinner.js";
11
10
  import { syncAssetDirectory } from "../operations/syncAssetsDirectory.js";
@@ -13,10 +12,11 @@ import { createRender, uploadRender } from "@editframe/api";
13
12
  import { launchBrowserAndWaitForSDK } from "../utils/launchBrowserAndWaitForSDK.js";
14
13
  import { PreviewServer } from "../utils/startPreviewServer.js";
15
14
  import { getClient } from "../utils/index.js";
16
- import { getRenderInfo } from "../operations/getRenderInfo.js";
15
+ import { RenderInfo, getRenderInfo } from "../operations/getRenderInfo.js";
17
16
  import { processRenderInfo } from "../operations/processRenderInfo.js";
18
17
  import { validateVideoResolution } from "../utils/validateVideoResolution.js";
19
18
  import { getFolderSize } from "../utils/getFolderSize.js";
19
+ import { spawnSync } from "node:child_process";
20
20
  const buildAssetId = async (assetPath) => {
21
21
  const md5Sum = await md5FilePath(assetPath);
22
22
  const basename = path.basename(assetPath);
@@ -52,12 +52,23 @@ program.command("render [directory]").description(
52
52
  }
53
53
  await withSpinner("Building\n", async () => {
54
54
  try {
55
- await build({
56
- root: directory,
57
- logLevel: "info",
58
- // Optional: adjust log level as needed
59
- clearScreen: false
60
- // Optional: keep console output clean
55
+ await withSpinner("Building\n", async () => {
56
+ spawnSync(
57
+ "npx",
58
+ // biome-ignore format: Grouping CLI arguments
59
+ [
60
+ "vite",
61
+ "build",
62
+ directory,
63
+ "--clearScreen",
64
+ "false",
65
+ "--logLevel",
66
+ "debug"
67
+ ],
68
+ {
69
+ stdio: "inherit"
70
+ }
71
+ );
61
72
  });
62
73
  } catch (error) {
63
74
  console.error("Build failed:", error);
@@ -75,7 +86,7 @@ program.command("render [directory]").description(
75
86
  headless: true
76
87
  },
77
88
  async (page) => {
78
- const renderInfo = await page.evaluate(getRenderInfo);
89
+ const renderInfo = RenderInfo.parse(await page.evaluate(getRenderInfo));
79
90
  validateVideoResolution({
80
91
  width: renderInfo.width,
81
92
  height: renderInfo.height
@@ -88,6 +99,9 @@ program.command("render [directory]").description(
88
99
  "ef-audio, ef-video, ef-image, ef-captions"
89
100
  );
90
101
  for (const element of elements) {
102
+ if (element.hasAttribute("asset-id")) {
103
+ continue;
104
+ }
91
105
  const src = element.getAttribute("src");
92
106
  if (!src) {
93
107
  continue;
@@ -126,7 +140,7 @@ program.command("render [directory]").description(
126
140
  const readable = new PassThrough();
127
141
  tarStream.pipe(readable);
128
142
  const folderSize = await getFolderSize(distDir);
129
- await uploadRender(getClient(), md5, readable, folderSize);
143
+ await uploadRender(getClient(), render.id, readable, folderSize);
130
144
  process.stderr.write("Render assets uploaded\n");
131
145
  process.stderr.write(inspect(render));
132
146
  process.stderr.write("\n");
@@ -1,7 +1,43 @@
1
- /**
2
- * THIS MODULE DOESNT USE THE DEBUG LOGGER BECAUSE IT IS
3
- * RUN IN A WEB BROWSER. LOGS ARE CAPTURED AND RE-LOGGED.
4
- */
1
+ import { z } from 'zod';
2
+ export declare const RenderInfo: z.ZodObject<{
3
+ width: z.ZodNumber;
4
+ height: z.ZodNumber;
5
+ fps: z.ZodNumber;
6
+ durationMs: z.ZodNumber;
7
+ assets: z.ZodObject<{
8
+ efMedia: z.ZodRecord<z.ZodString, z.ZodAny>;
9
+ efCaptions: z.ZodArray<z.ZodString, "many">;
10
+ efImage: z.ZodArray<z.ZodString, "many">;
11
+ }, "strip", z.ZodTypeAny, {
12
+ efMedia: Record<string, any>;
13
+ efCaptions: string[];
14
+ efImage: string[];
15
+ }, {
16
+ efMedia: Record<string, any>;
17
+ efCaptions: string[];
18
+ efImage: string[];
19
+ }>;
20
+ }, "strip", z.ZodTypeAny, {
21
+ height: number;
22
+ width: number;
23
+ fps: number;
24
+ assets: {
25
+ efMedia: Record<string, any>;
26
+ efCaptions: string[];
27
+ efImage: string[];
28
+ };
29
+ durationMs: number;
30
+ }, {
31
+ height: number;
32
+ width: number;
33
+ fps: number;
34
+ assets: {
35
+ efMedia: Record<string, any>;
36
+ efCaptions: string[];
37
+ efImage: string[];
38
+ };
39
+ durationMs: number;
40
+ }>;
5
41
  export declare const getRenderInfo: () => Promise<{
6
42
  width: number;
7
43
  height: number;
@@ -1,3 +1,15 @@
1
+ import { z } from "zod";
2
+ const RenderInfo = z.object({
3
+ width: z.number().positive(),
4
+ height: z.number().positive(),
5
+ fps: z.number().positive(),
6
+ durationMs: z.number().positive(),
7
+ assets: z.object({
8
+ efMedia: z.record(z.any()),
9
+ efCaptions: z.array(z.string()),
10
+ efImage: z.array(z.string())
11
+ })
12
+ });
1
13
  const getRenderInfo = async () => {
2
14
  const rootTimeGroup = document.querySelector("ef-timegroup");
3
15
  if (!rootTimeGroup) {
@@ -55,5 +67,6 @@ const getRenderInfo = async () => {
55
67
  return renderInfo;
56
68
  };
57
69
  export {
70
+ RenderInfo,
58
71
  getRenderInfo
59
72
  };
@@ -5,6 +5,9 @@ const processRenderInfo = async (renderInfo) => {
5
5
  process.stderr.write(src);
6
6
  process.stderr.write("\n");
7
7
  for (const trackId in tracks) {
8
+ process.stderr.write("Generating track: ");
9
+ process.stderr.write(trackId);
10
+ process.stderr.write("\n");
8
11
  await generateTrack(
9
12
  "./src/assets",
10
13
  `./src${src}`,
@@ -219,7 +219,7 @@ const syncAssetDirectory = async (projectDirectory) => {
219
219
  const readStream = createReadStream(subAssetPath);
220
220
  await uploadFragmentIndex(
221
221
  getClient(),
222
- assetMd5,
222
+ createdFile.id,
223
223
  readStream,
224
224
  stats.size
225
225
  ).then(() => {
@@ -257,7 +257,7 @@ const syncAssetDirectory = async (projectDirectory) => {
257
257
  const stats = statSync(subAssetPath);
258
258
  await uploadCaptionFile(
259
259
  getClient(),
260
- assetMd5,
260
+ createdFile.id,
261
261
  readStream,
262
262
  stats.size
263
263
  ).then(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@editframe/cli",
3
- "version": "0.10.0-beta.3",
3
+ "version": "0.10.0-beta.5",
4
4
  "description": "Command line interface for EditFrame",
5
5
  "bin": {
6
6
  "editframe": "./dist/index.js"
@@ -23,10 +23,10 @@
23
23
  "vite-tsconfig-paths": "^4.3.2"
24
24
  },
25
25
  "dependencies": {
26
- "@editframe/api": "0.10.0-beta.3",
27
- "@editframe/assets": "0.10.0-beta.3",
28
- "@editframe/elements": "0.10.0-beta.3",
29
- "@editframe/vite-plugin": "0.10.0-beta.3",
26
+ "@editframe/api": "0.10.0-beta.5",
27
+ "@editframe/assets": "0.10.0-beta.5",
28
+ "@editframe/elements": "0.10.0-beta.5",
29
+ "@editframe/vite-plugin": "0.10.0-beta.5",
30
30
  "@inquirer/prompts": "^5.3.8",
31
31
  "axios": "^1.6.8",
32
32
  "chalk": "^5.3.0",
@@ -24,25 +24,32 @@ program
24
24
 
25
25
  const byte_size = (await stat(path)).size;
26
26
 
27
- await withSpinner("Creating unprocessed file record", async () => {
28
- await createUnprocessedFile(client, {
29
- md5,
30
- processes: [],
31
- filename: basename(path),
32
- byte_size,
33
- });
34
- });
27
+ const unprocessedFile = await withSpinner(
28
+ "Creating unprocessed file record",
29
+ async () =>
30
+ await createUnprocessedFile(client, {
31
+ md5,
32
+ processes: [],
33
+ filename: basename(path),
34
+ byte_size,
35
+ }),
36
+ );
35
37
 
36
38
  const readStream = createReadStream(path);
37
39
 
38
40
  await withSpinner("Uploading file", async () => {
39
- await uploadUnprocessedFile(client, md5, readStream, byte_size);
41
+ await uploadUnprocessedFile(
42
+ client,
43
+ unprocessedFile.id,
44
+ readStream,
45
+ byte_size,
46
+ );
40
47
  });
41
48
 
42
- const unprocessedFile = await withSpinner(
49
+ const updatedUnprocessedFile = await withSpinner(
43
50
  "Marking for processing",
44
51
  async () => {
45
- return await updateUnprocessedFile(client, md5, {
52
+ return await updateUnprocessedFile(client, unprocessedFile.id, {
46
53
  processes: ["isobmff"],
47
54
  });
48
55
  },
@@ -50,5 +57,5 @@ program
50
57
 
51
58
  process.stderr.write("File uploaded and marked for processing.\n");
52
59
 
53
- console.log(JSON.stringify(unprocessedFile, null, 2));
60
+ console.log(JSON.stringify(updatedUnprocessedFile, null, 2));
54
61
  });
@@ -17,7 +17,6 @@ program
17
17
  .action(async (directory) => {
18
18
  directory ??= ".";
19
19
 
20
- // const srcDir = path.join(directory, "src");
21
20
  const distDir = path.join(directory, "dist");
22
21
  await withSpinner("Building\n", async () => {
23
22
  spawnSync("npx", ["vite", "build", directory], {
@@ -6,7 +6,6 @@ import { PassThrough } from "node:stream";
6
6
  import * as tar from "tar";
7
7
  import { program, Option } from "commander";
8
8
  import { parse as parseHTML } from "node-html-parser";
9
- import { build } from "vite";
10
9
 
11
10
  import { md5Directory, md5FilePath } from "@editframe/assets";
12
11
 
@@ -16,10 +15,11 @@ import { createRender, uploadRender } from "@editframe/api";
16
15
  import { launchBrowserAndWaitForSDK } from "../utils/launchBrowserAndWaitForSDK.ts";
17
16
  import { PreviewServer } from "../utils/startPreviewServer.ts";
18
17
  import { getClient } from "../utils/index.ts";
19
- import { getRenderInfo } from "../operations/getRenderInfo.ts";
18
+ import { RenderInfo, getRenderInfo } from "../operations/getRenderInfo.ts";
20
19
  import { processRenderInfo } from "../operations/processRenderInfo.ts";
21
20
  import { validateVideoResolution } from "../utils/validateVideoResolution.ts";
22
21
  import { getFolderSize } from "../utils/getFolderSize.ts";
22
+ import { spawnSync } from "node:child_process";
23
23
 
24
24
  interface StrategyBuilder {
25
25
  buildAssetId: (assetPath: string) => Promise<string>;
@@ -74,10 +74,19 @@ program
74
74
  }
75
75
  await withSpinner("Building\n", async () => {
76
76
  try {
77
- await build({
78
- root: directory,
79
- logLevel: "info", // Optional: adjust log level as needed
80
- clearScreen: false, // Optional: keep console output clean
77
+ await withSpinner("Building\n", async () => {
78
+ spawnSync(
79
+ "npx",
80
+ // biome-ignore format: Grouping CLI arguments
81
+ [
82
+ "vite", "build", directory,
83
+ "--clearScreen", "false",
84
+ "--logLevel", "debug",
85
+ ],
86
+ {
87
+ stdio: "inherit",
88
+ },
89
+ );
81
90
  });
82
91
  } catch (error) {
83
92
  console.error("Build failed:", error);
@@ -96,7 +105,7 @@ program
96
105
  headless: true,
97
106
  },
98
107
  async (page) => {
99
- const renderInfo = await page.evaluate(getRenderInfo);
108
+ const renderInfo = RenderInfo.parse(await page.evaluate(getRenderInfo));
100
109
 
101
110
  validateVideoResolution({
102
111
  width: renderInfo.width,
@@ -112,6 +121,9 @@ program
112
121
  "ef-audio, ef-video, ef-image, ef-captions",
113
122
  );
114
123
  for (const element of elements) {
124
+ if (element.hasAttribute("asset-id")) {
125
+ continue;
126
+ }
115
127
  const src = element.getAttribute("src");
116
128
  if (!src) {
117
129
  continue;
@@ -159,7 +171,7 @@ program
159
171
  const readable = new PassThrough();
160
172
  tarStream.pipe(readable);
161
173
  const folderSize = await getFolderSize(distDir);
162
- await uploadRender(getClient(), md5, readable, folderSize);
174
+ await uploadRender(getClient(), render.id, readable, folderSize);
163
175
  process.stderr.write("Render assets uploaded\n");
164
176
  process.stderr.write(inspect(render));
165
177
  process.stderr.write("\n");
@@ -3,6 +3,8 @@
3
3
  * RUN IN A WEB BROWSER. LOGS ARE CAPTURED AND RE-LOGGED.
4
4
  */
5
5
 
6
+ import { z } from "zod";
7
+
6
8
  import type {
7
9
  EFCaptions,
8
10
  EFImage,
@@ -10,6 +12,18 @@ import type {
10
12
  EFTimegroup,
11
13
  } from "@editframe/elements";
12
14
 
15
+ export const RenderInfo = z.object({
16
+ width: z.number().positive(),
17
+ height: z.number().positive(),
18
+ fps: z.number().positive(),
19
+ durationMs: z.number().positive(),
20
+ assets: z.object({
21
+ efMedia: z.record(z.any()),
22
+ efCaptions: z.array(z.string()),
23
+ efImage: z.array(z.string()),
24
+ }),
25
+ });
26
+
13
27
  export const getRenderInfo = async () => {
14
28
  const rootTimeGroup = document.querySelector("ef-timegroup") as
15
29
  | EFTimegroup
@@ -13,6 +13,9 @@ export const processRenderInfo = async (
13
13
  process.stderr.write(src);
14
14
  process.stderr.write("\n");
15
15
  for (const trackId in tracks) {
16
+ process.stderr.write("Generating track: ");
17
+ process.stderr.write(trackId);
18
+ process.stderr.write("\n");
16
19
  await generateTrack(
17
20
  "./src/assets",
18
21
  `./src${src}`,
@@ -269,7 +269,7 @@ export const syncAssetDirectory = async (
269
269
  const readStream = createReadStream(subAssetPath);
270
270
  await uploadFragmentIndex(
271
271
  getClient(),
272
- assetMd5,
272
+ createdFile.id,
273
273
  readStream,
274
274
  stats.size,
275
275
  )
@@ -309,7 +309,7 @@ export const syncAssetDirectory = async (
309
309
  const stats = statSync(subAssetPath);
310
310
  await uploadCaptionFile(
311
311
  getClient(),
312
- assetMd5,
312
+ createdFile.id,
313
313
  readStream,
314
314
  stats.size,
315
315
  )