@editframe/cli 0.16.8-beta.0 → 0.17.6-beta.0

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.
Files changed (36) hide show
  1. package/dist/VERSION.d.ts +1 -1
  2. package/dist/VERSION.js +2 -4
  3. package/dist/commands/auth.js +16 -25
  4. package/dist/commands/check.js +81 -108
  5. package/dist/commands/mux.d.ts +1 -0
  6. package/dist/commands/preview.js +4 -1
  7. package/dist/commands/process-file.js +18 -34
  8. package/dist/commands/process.js +28 -31
  9. package/dist/commands/render.js +117 -157
  10. package/dist/commands/sync.js +3 -5
  11. package/dist/commands/webhook.js +48 -52
  12. package/dist/index.js +3 -7
  13. package/dist/operations/processRenderInfo.js +25 -31
  14. package/dist/operations/syncAssetsDirectory/SubAssetSync.js +11 -18
  15. package/dist/operations/syncAssetsDirectory/SyncCaption.js +46 -73
  16. package/dist/operations/syncAssetsDirectory/SyncFragmentIndex.js +53 -83
  17. package/dist/operations/syncAssetsDirectory/SyncImage.js +72 -99
  18. package/dist/operations/syncAssetsDirectory/SyncStatus.js +30 -37
  19. package/dist/operations/syncAssetsDirectory/SyncTrack.js +107 -143
  20. package/dist/operations/syncAssetsDirectory/doAssetSync.js +42 -46
  21. package/dist/operations/syncAssetsDirectory.js +55 -78
  22. package/dist/utils/createReadableStreamFromReadable.js +61 -78
  23. package/dist/utils/index.js +10 -16
  24. package/dist/utils/launchBrowserAndWaitForSDK.js +31 -43
  25. package/dist/utils/startDevServer.d.ts +1 -1
  26. package/dist/utils/startPreviewServer.d.ts +1 -1
  27. package/dist/utils/startPreviewServer.js +28 -34
  28. package/dist/utils/validateVideoResolution.js +19 -23
  29. package/dist/utils/withSpinner.js +10 -12
  30. package/package.json +8 -8
  31. package/src/commands/check.ts +2 -2
  32. package/src/commands/mux.ts +10 -0
  33. package/src/utils/createReadableStreamFromReadable.ts +3 -7
  34. package/src/utils/startDevServer.ts +5 -5
  35. package/src/utils/startPreviewServer.ts +1 -1
  36. package/test-fixtures/network.ts +38 -9
@@ -1,21 +1,15 @@
1
- import { program } from "commander";
2
1
  import "dotenv/config";
2
+ import { program } from "commander";
3
3
  import { Client } from "@editframe/api";
4
4
  let client;
5
5
  const getClient = () => {
6
- if (!client) {
7
- const programOpts = program.opts();
8
- const token = programOpts.token || process.env.EF_TOKEN;
9
- const efHost = programOpts.efHost || process.env.EF_HOST;
10
- if (!token) {
11
- throw new Error(
12
- "EF_TOKEN must be set or supplied as command line argument"
13
- );
14
- }
15
- client = new Client(token, efHost);
16
- }
17
- return client;
18
- };
19
- export {
20
- getClient
6
+ if (!client) {
7
+ const programOpts = program.opts();
8
+ const token = programOpts.token || process.env.EF_TOKEN;
9
+ const efHost = programOpts.efHost || process.env.EF_HOST;
10
+ if (!token) throw new Error("EF_TOKEN must be set or supplied as command line argument");
11
+ client = new Client(token, efHost);
12
+ }
13
+ return client;
21
14
  };
15
+ export { getClient };
@@ -1,49 +1,37 @@
1
+ import { withSpinner } from "./withSpinner.js";
1
2
  import chalk from "chalk";
2
3
  import debug from "debug";
3
4
  import { chromium } from "playwright";
4
- import { withSpinner } from "./withSpinner.js";
5
5
  const browserLog = debug("ef:cli::browser");
6
6
  async function launchBrowserAndWaitForSDK(options, fn) {
7
- const browser = await withSpinner("Launching chrome", async () => {
8
- return chromium.launch({
9
- channel: "chrome",
10
- headless: options.headless ?? true,
11
- // headless: false,
12
- devtools: options.interactive === true
13
- });
14
- });
15
- const page = await withSpinner("Loading Editframe SDK", async () => {
16
- const pageOptions = {};
17
- if (options.interactive === true) {
18
- pageOptions.viewport = null;
19
- }
20
- const page2 = await browser.newPage(pageOptions);
21
- page2.on("console", (msg) => {
22
- browserLog(chalk.blue(`browser (${msg.type()}) |`), msg.text());
23
- });
24
- const url = options.url + (options.efInteractive ? "" : "?EF_NONINTERACTIVE=1");
25
- process.stderr.write("\nLoading url: ");
26
- process.stderr.write(url);
27
- process.stderr.write("\n");
28
- await page2.goto(url);
29
- await page2.waitForFunction(
30
- () => {
31
- return (
32
- // @ts-expect-error
33
- window.EF_REGISTERED
34
- );
35
- },
36
- [],
37
- { timeout: 1e4 }
38
- );
39
- return page2;
40
- });
41
- await fn(page);
42
- if (options.interactive !== true) {
43
- await browser.close();
44
- process.exit(0);
45
- }
7
+ const browser = await withSpinner("Launching chrome", async () => {
8
+ return chromium.launch({
9
+ channel: "chrome",
10
+ headless: options.headless ?? true,
11
+ devtools: options.interactive === true
12
+ });
13
+ });
14
+ const page = await withSpinner("Loading Editframe SDK", async () => {
15
+ const pageOptions = {};
16
+ if (options.interactive === true) pageOptions.viewport = null;
17
+ const page$1 = await browser.newPage(pageOptions);
18
+ page$1.on("console", (msg) => {
19
+ browserLog(chalk.blue(`browser (${msg.type()}) |`), msg.text());
20
+ });
21
+ const url = options.url + (options.efInteractive ? "" : "?EF_NONINTERACTIVE=1");
22
+ process.stderr.write("\nLoading url: ");
23
+ process.stderr.write(url);
24
+ process.stderr.write("\n");
25
+ await page$1.goto(url);
26
+ await page$1.waitForFunction(() => {
27
+ return window.EF_REGISTERED;
28
+ }, [], { timeout: 1e4 });
29
+ return page$1;
30
+ });
31
+ await fn(page);
32
+ if (options.interactive !== true) {
33
+ await browser.close();
34
+ process.exit(0);
35
+ }
46
36
  }
47
- export {
48
- launchBrowserAndWaitForSDK
49
- };
37
+ export { launchBrowserAndWaitForSDK };
@@ -1,4 +1,4 @@
1
- import { ViteDevServer } from 'vite';
1
+ import { ViteDevServer } from 'rolldown-vite';
2
2
  export declare class DevServer {
3
3
  private devServer;
4
4
  static start(directory: string): Promise<DevServer>;
@@ -1,4 +1,4 @@
1
- import { ViteDevServer } from 'vite';
1
+ import { ViteDevServer } from 'rolldown-vite';
2
2
  export declare class PreviewServer {
3
3
  private previewServer;
4
4
  static start(directory: string): Promise<PreviewServer>;
@@ -1,38 +1,32 @@
1
+ import { withSpinner } from "./withSpinner.js";
1
2
  import path from "node:path";
2
- import { createServer } from "vite";
3
+ import { createServer } from "rolldown-vite";
3
4
  import { vitePluginEditframe } from "@editframe/vite-plugin";
4
- import { withSpinner } from "./withSpinner.js";
5
- class PreviewServer {
6
- constructor(previewServer) {
7
- this.previewServer = previewServer;
8
- }
9
- static async start(directory) {
10
- return new PreviewServer(await startPreviewServer(directory));
11
- }
12
- get url() {
13
- return `http://localhost:${this.previewServer.config.server.port}`;
14
- }
15
- }
16
- const startPreviewServer = async (directory) => {
17
- return await withSpinner("Starting vite...", async () => {
18
- const resolvedDirectory = path.resolve(process.cwd(), directory);
19
- const cacheRoot = path.join(resolvedDirectory, "assets");
20
- const devServer = await createServer({
21
- server: {
22
- watch: null
23
- },
24
- root: resolvedDirectory,
25
- plugins: [
26
- vitePluginEditframe({
27
- root: resolvedDirectory,
28
- cacheRoot
29
- })
30
- ]
31
- });
32
- await devServer.listen();
33
- return devServer;
34
- });
5
+ var PreviewServer = class PreviewServer {
6
+ static async start(directory) {
7
+ return new PreviewServer(await startPreviewServer(directory));
8
+ }
9
+ constructor(previewServer) {
10
+ this.previewServer = previewServer;
11
+ }
12
+ get url() {
13
+ return `http://localhost:${this.previewServer.config.server.port}`;
14
+ }
35
15
  };
36
- export {
37
- PreviewServer
16
+ const startPreviewServer = async (directory) => {
17
+ return await withSpinner("Starting vite...", async () => {
18
+ const resolvedDirectory = path.resolve(process.cwd(), directory);
19
+ const cacheRoot = path.join(resolvedDirectory, "assets");
20
+ const devServer = await createServer({
21
+ server: { watch: null },
22
+ root: resolvedDirectory,
23
+ plugins: [vitePluginEditframe({
24
+ root: resolvedDirectory,
25
+ cacheRoot
26
+ })]
27
+ });
28
+ await devServer.listen();
29
+ return devServer;
30
+ });
38
31
  };
32
+ export { PreviewServer };
@@ -1,29 +1,25 @@
1
- import { z } from "zod";
2
- import ora from "ora";
3
1
  import debug from "debug";
2
+ import ora from "ora";
3
+ import { z } from "zod";
4
4
  const log = debug("ef:cli:validateVideoResolution");
5
5
  const schema = z.object({
6
- width: z.number().int(),
7
- height: z.number().int()
6
+ width: z.number().int(),
7
+ height: z.number().int()
8
8
  }).refine((data) => data.width % 2 === 0, {
9
- message: "Width must be divisible by 2",
10
- path: ["width"]
11
- }).refine((data) => data.height % 2 === 0, {
12
- message: "Height must be divisible by 2"
13
- });
9
+ message: "Width must be divisible by 2",
10
+ path: ["width"]
11
+ }).refine((data) => data.height % 2 === 0, { message: "Height must be divisible by 2" });
14
12
  const validateVideoResolution = async (rawPayload) => {
15
- const spinner = ora("Validating video resolution").start();
16
- const result = schema.safeParse(rawPayload);
17
- if (result.success) {
18
- spinner.succeed("Video resolution is valid");
19
- return result.data;
20
- }
21
- spinner.fail("Invalid video resolution");
22
- process.stderr.write(result.error?.errors.map((e) => e.message).join("\n"));
23
- process.stderr.write("\n");
24
- log("Error:", result.error?.errors.map((e) => e.message).join("\n"));
25
- process.exit(1);
26
- };
27
- export {
28
- validateVideoResolution
13
+ const spinner = ora("Validating video resolution").start();
14
+ const result = schema.safeParse(rawPayload);
15
+ if (result.success) {
16
+ spinner.succeed("Video resolution is valid");
17
+ return result.data;
18
+ }
19
+ spinner.fail("Invalid video resolution");
20
+ process.stderr.write(result.error?.errors.map((e) => e.message).join("\n"));
21
+ process.stderr.write("\n");
22
+ log("Error:", result.error?.errors.map((e) => e.message).join("\n"));
23
+ process.exit(1);
29
24
  };
25
+ export { validateVideoResolution };
@@ -1,15 +1,13 @@
1
1
  import ora from "ora";
2
2
  const withSpinner = async (label, fn) => {
3
- const spinner = ora(label).start();
4
- try {
5
- const result = await fn();
6
- spinner.succeed();
7
- return result;
8
- } catch (error) {
9
- spinner.fail();
10
- throw error;
11
- }
12
- };
13
- export {
14
- withSpinner
3
+ const spinner = ora(label).start();
4
+ try {
5
+ const result = await fn();
6
+ spinner.succeed();
7
+ return result;
8
+ } catch (error) {
9
+ spinner.fail();
10
+ throw error;
11
+ }
15
12
  };
13
+ export { withSpinner };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@editframe/cli",
3
- "version": "0.16.8-beta.0",
3
+ "version": "0.17.6-beta.0",
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": "^4.0.3",
22
+ "vite-plugin-dts": "^4.5.4",
23
23
  "vite-tsconfig-paths": "^4.3.2"
24
24
  },
25
25
  "dependencies": {
26
- "@editframe/api": "0.16.8-beta.0",
27
- "@editframe/assets": "0.16.8-beta.0",
28
- "@editframe/elements": "0.16.8-beta.0",
29
- "@editframe/vite-plugin": "0.16.8-beta.0",
26
+ "@editframe/api": "0.17.6-beta.0",
27
+ "@editframe/assets": "0.17.6-beta.0",
28
+ "@editframe/elements": "0.17.6-beta.0",
29
+ "@editframe/vite-plugin": "0.17.6-beta.0",
30
30
  "@inquirer/prompts": "^5.3.8",
31
31
  "axios": "^1.6.8",
32
32
  "chalk": "^5.3.0",
@@ -39,11 +39,11 @@
39
39
  "node-html-parser": "^6.1.13",
40
40
  "ora": "^8.0.1",
41
41
  "parse5-html-rewriting-stream": "^7.0.0",
42
- "playwright": "^1.44.0",
42
+ "playwright": "^1.53.0",
43
43
  "promptly": "^3.2.0",
44
+ "rolldown-vite": "^6.3.21",
44
45
  "tailwindcss": "^3.4.3",
45
46
  "tar": "^7.1.0",
46
- "vite": "^6.3.5",
47
47
  "zod": "^3.23.8"
48
48
  }
49
49
  }
@@ -1,8 +1,8 @@
1
1
  import { exec } from "node:child_process";
2
2
  import os from "node:os";
3
+ import chalk from "chalk";
3
4
  import { program } from "commander";
4
5
  import ora from "ora";
5
- import chalk from "chalk";
6
6
 
7
7
  interface CheckDescriptor {
8
8
  check(): Promise<boolean>;
@@ -120,7 +120,7 @@ program
120
120
  spinner.succeed(
121
121
  chalk.white.bgGreen(` Check for ${checkName} passed `),
122
122
  );
123
- } catch (error) {
123
+ } catch (_error) {
124
124
  spinner.fail(chalk.white.bgRed(` Check for ${checkName} failed `));
125
125
  process.stderr.write(chalk.red(check.message().join("\n\n")));
126
126
  process.stderr.write("\n");
@@ -0,0 +1,10 @@
1
+ import { Probe } from "@editframe/assets";
2
+ import { program } from "commander";
3
+
4
+ program
5
+ .command("mux <path>")
6
+ .description("Mux a file into multiple audio/video tracks.")
7
+ .action(async (path: string) => {
8
+ const probe = await Probe.probePath(path);
9
+ console.log(probe);
10
+ });
@@ -69,14 +69,12 @@ class StreamPump {
69
69
  enqueue(chunk: Uint8Array | string) {
70
70
  if (this.controller) {
71
71
  try {
72
- const bytes = chunk instanceof Uint8Array ? chunk : Buffer.from(chunk);
73
-
74
- const available = (this.controller.desiredSize || 0) - bytes.byteLength;
75
- this.controller.enqueue(bytes);
72
+ const available = (this.controller.desiredSize || 0) - chunk.length;
73
+ this.controller.enqueue(chunk as Uint8Array);
76
74
  if (available <= 0) {
77
75
  this.pause();
78
76
  }
79
- } catch (error: any) {
77
+ } catch (_error: any) {
80
78
  this.controller.error(
81
79
  new Error(
82
80
  "Could not create Buffer, chunk must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object",
@@ -102,7 +100,6 @@ class StreamPump {
102
100
  close() {
103
101
  if (this.controller) {
104
102
  this.controller.close();
105
- // biome-ignore lint/performance/noDelete: infrequent use
106
103
  delete this.controller;
107
104
  }
108
105
  }
@@ -110,7 +107,6 @@ class StreamPump {
110
107
  error(error: Error) {
111
108
  if (this.controller) {
112
109
  this.controller.error(error);
113
- // biome-ignore lint/performance/noDelete: infrequent use
114
110
  delete this.controller;
115
111
  }
116
112
  }
@@ -1,9 +1,7 @@
1
1
  import path from "node:path";
2
-
3
- import tailwindcss from "tailwindcss";
4
- import { type ViteDevServer, createServer } from "vite";
5
-
6
2
  import { vitePluginEditframe as editframe } from "@editframe/vite-plugin";
3
+ import { createServer, type ViteDevServer } from "rolldown-vite";
4
+ import tailwindcss from "tailwindcss";
7
5
 
8
6
  import { withSpinner } from "./withSpinner.js";
9
7
 
@@ -51,7 +49,9 @@ const startDevServer = async (directory: string) => {
51
49
  build: {
52
50
  target: "es2022",
53
51
  rollupOptions: {
54
- treeshake: "recommended",
52
+ treeshake: {
53
+ moduleSideEffects: false,
54
+ },
55
55
  },
56
56
  },
57
57
  });
@@ -1,5 +1,5 @@
1
1
  import path from "node:path";
2
- import { type ViteDevServer, createServer } from "vite";
2
+ import { type ViteDevServer, createServer } from "rolldown-vite";
3
3
 
4
4
  import { vitePluginEditframe as editframe } from "@editframe/vite-plugin";
5
5
 
@@ -1,10 +1,15 @@
1
- import { http, HttpResponse } from "msw";
1
+ import { HttpResponse, http } from "msw";
2
2
  import type { Fixture } from "./fixture.js";
3
3
 
4
4
  export const mockCreateImageFile = ({
5
5
  complete = true,
6
6
  id = "123",
7
- }: { complete?: boolean; id?: string; filename?: string; fixture: Fixture }) =>
7
+ }: {
8
+ complete?: boolean;
9
+ id?: string;
10
+ filename?: string;
11
+ fixture: Fixture;
12
+ }) =>
8
13
  http.post(
9
14
  "http://localhost:3000/api/v1/image_files",
10
15
  async () => {
@@ -18,7 +23,12 @@ export const mockCreateImageFile = ({
18
23
 
19
24
  export const mockLookupImageFileByMd5 = ({
20
25
  md5 = "test-md5",
21
- }: { complete?: boolean; id?: string; md5?: string; fixture: Fixture }) =>
26
+ }: {
27
+ complete?: boolean;
28
+ id?: string;
29
+ md5?: string;
30
+ fixture: Fixture;
31
+ }) =>
22
32
  http.get(`http://localhost:3000/api/v1/image_files/md5/${md5}`, async () => {
23
33
  return HttpResponse.json({
24
34
  id: "123",
@@ -28,7 +38,9 @@ export const mockLookupImageFileByMd5 = ({
28
38
 
29
39
  export const mockLookupImageFileByMd5NotFound = ({
30
40
  md5 = "test-md5",
31
- }: { md5?: string }) =>
41
+ }: {
42
+ md5?: string;
43
+ }) =>
32
44
  http.get(`http://localhost:3000/api/v1/image_files/md5/${md5}`, async () => {
33
45
  return HttpResponse.json({}, { status: 404 });
34
46
  });
@@ -37,7 +49,12 @@ export const mockGetUploadImageFile = ({
37
49
  complete = true,
38
50
  id = "123",
39
51
  filename = "test.png",
40
- }: { complete?: boolean; id?: string; filename?: string; fixture: Fixture }) =>
52
+ }: {
53
+ complete?: boolean;
54
+ id?: string;
55
+ filename?: string;
56
+ fixture: Fixture;
57
+ }) =>
41
58
  http.get(
42
59
  `http://localhost:3000/api/v1/image_files/${id}/upload`,
43
60
  async () => {
@@ -91,7 +108,9 @@ export const mockLookupISOBMFFFileByMd5 = ({
91
108
 
92
109
  export const mockLookupISOBMFFFileByMd5NotFound = ({
93
110
  md5 = "test-md5",
94
- }: { md5?: string }) =>
111
+ }: {
112
+ md5?: string;
113
+ }) =>
95
114
  http.get(
96
115
  `http://localhost:3000/api/v1/isobmff_files/md5/${md5}`,
97
116
  async () => {
@@ -146,7 +165,10 @@ export const mockGetIsobmffTrackUpload = ({
146
165
  export const mockUploadIsobmffFileIndex = ({
147
166
  complete = true,
148
167
  id = "123",
149
- }: { complete?: boolean; id?: string }) =>
168
+ }: {
169
+ complete?: boolean;
170
+ id?: string;
171
+ }) =>
150
172
  http.post(
151
173
  "http://localhost:3000/api/v1/isobmff_files/123/index/upload",
152
174
  async () => {
@@ -162,7 +184,12 @@ export const mockLookupCaptionFileByMd5 = ({
162
184
  complete = true,
163
185
  id = "123",
164
186
  md5 = "test-md5",
165
- }: { complete?: boolean; id?: string; md5?: string; fixture: Fixture }) =>
187
+ }: {
188
+ complete?: boolean;
189
+ id?: string;
190
+ md5?: string;
191
+ fixture: Fixture;
192
+ }) =>
166
193
  http.get(
167
194
  `http://localhost:3000/api/v1/caption_files/md5/${md5}`,
168
195
  async () => {
@@ -175,7 +202,9 @@ export const mockLookupCaptionFileByMd5 = ({
175
202
 
176
203
  export const mockLookupCaptionFileByMd5NotFound = ({
177
204
  md5 = "test-md5",
178
- }: { md5?: string }) =>
205
+ }: {
206
+ md5?: string;
207
+ }) =>
179
208
  http.get(
180
209
  `http://localhost:3000/api/v1/caption_files/md5/${md5}`,
181
210
  async () => {