@editframe/cli 0.7.0-beta.8 → 0.8.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.
Files changed (51) hide show
  1. package/dist/VERSION.d.ts +1 -0
  2. package/dist/VERSION.js +1 -1
  3. package/dist/commands/auth.d.ts +9 -0
  4. package/dist/commands/check.d.ts +1 -0
  5. package/dist/commands/preview.d.ts +1 -0
  6. package/dist/commands/process-file.d.ts +1 -0
  7. package/dist/commands/process-file.js +32 -0
  8. package/dist/commands/process.d.ts +1 -0
  9. package/dist/commands/render.d.ts +1 -0
  10. package/dist/commands/render.js +8 -3
  11. package/dist/commands/sync.d.ts +1 -0
  12. package/dist/index.d.ts +1 -0
  13. package/dist/index.js +1 -0
  14. package/dist/operations/getRenderInfo.d.ts +15 -0
  15. package/dist/operations/processRenderInfo.d.ts +3 -0
  16. package/dist/operations/syncAssetsDirectory.d.ts +1 -0
  17. package/dist/utils/attachWorkbench.d.ts +3 -0
  18. package/dist/utils/index.d.ts +3 -0
  19. package/dist/utils/launchBrowserAndWaitForSDK.d.ts +10 -0
  20. package/dist/utils/startDevServer.d.ts +8 -0
  21. package/dist/utils/startPreviewServer.d.ts +8 -0
  22. package/dist/utils/validateVideoResolution.d.ts +9 -0
  23. package/dist/utils/validateVideoResolution.js +29 -0
  24. package/dist/utils/withSpinner.d.ts +1 -0
  25. package/package.json +7 -7
  26. package/src/commands/auth.ts +1 -1
  27. package/src/commands/process-file.ts +50 -0
  28. package/src/commands/process.ts +5 -5
  29. package/src/commands/render.ts +16 -9
  30. package/src/commands/sync.ts +1 -1
  31. package/src/operations/processRenderInfo.ts +1 -1
  32. package/src/operations/syncAssetsDirectory.ts +1 -1
  33. package/src/utils/launchBrowserAndWaitForSDK.ts +1 -1
  34. package/src/utils/startDevServer.ts +1 -1
  35. package/src/utils/startPreviewServer.ts +1 -1
  36. package/src/utils/validateVideoResolution.ts +36 -0
  37. package/dist/VERSION.cjs +0 -4
  38. package/dist/commands/auth.cjs +0 -33
  39. package/dist/commands/check.cjs +0 -115
  40. package/dist/commands/preview.cjs +0 -6
  41. package/dist/commands/process.cjs +0 -36
  42. package/dist/commands/render.cjs +0 -164
  43. package/dist/commands/sync.cjs +0 -6
  44. package/dist/index.cjs +0 -17
  45. package/dist/operations/getRenderInfo.cjs +0 -59
  46. package/dist/operations/processRenderInfo.cjs +0 -30
  47. package/dist/operations/syncAssetsDirectory.cjs +0 -250
  48. package/dist/utils/index.cjs +0 -14
  49. package/dist/utils/launchBrowserAndWaitForSDK.cjs +0 -49
  50. package/dist/utils/startPreviewServer.cjs +0 -38
  51. package/dist/utils/withSpinner.cjs +0 -15
@@ -0,0 +1 @@
1
+ export declare const VERSION = "0.8.0-beta.1";
package/dist/VERSION.js CHANGED
@@ -1,4 +1,4 @@
1
- const VERSION = "0.7.0-beta.8";
1
+ const VERSION = "0.8.0-beta.1";
2
2
  export {
3
3
  VERSION
4
4
  };
@@ -0,0 +1,9 @@
1
+ export interface APIOrgResult {
2
+ name: string;
3
+ id: string;
4
+ org_id: string;
5
+ created_at: unknown;
6
+ updated_at: unknown;
7
+ org_display_name: string;
8
+ }
9
+ export declare const getApiData: () => Promise<APIOrgResult>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,32 @@
1
+ import { basename } from "node:path";
2
+ import { program } from "commander";
3
+ import { withSpinner } from "../utils/withSpinner.js";
4
+ import { getClient } from "../utils/index.js";
5
+ import { createReadStream } from "node:fs";
6
+ import { createUnprocessedFile, uploadUnprocessedFile, updateUnprocessedFile } from "@editframe/api";
7
+ import { md5FilePath } from "@editframe/assets";
8
+ program.command("process-file <file>").description("Upload a audio/video to Editframe for processing.").action(async (path) => {
9
+ const client = getClient();
10
+ const fileId = await md5FilePath(path);
11
+ await withSpinner("Creating unprocessed file record", async () => {
12
+ await createUnprocessedFile(client, {
13
+ id: fileId,
14
+ processes: [],
15
+ filename: basename(path)
16
+ });
17
+ });
18
+ const readStream = createReadStream(path);
19
+ await withSpinner("Uploading file", async () => {
20
+ await uploadUnprocessedFile(client, fileId, readStream);
21
+ });
22
+ const unprocessedFile = await withSpinner(
23
+ "Marking for processing",
24
+ async () => {
25
+ return await updateUnprocessedFile(client, fileId, {
26
+ processes: ["isobmff"]
27
+ });
28
+ }
29
+ );
30
+ process.stderr.write("File uploaded and marked for processing.\n");
31
+ console.log(JSON.stringify(unprocessedFile, null, 2));
32
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -1,20 +1,21 @@
1
1
  import path from "node:path";
2
2
  import { readFile, writeFile } from "node:fs/promises";
3
+ import { inspect } from "node:util";
4
+ import { PassThrough } from "node:stream";
3
5
  import * as tar from "tar";
4
6
  import { program, Option } from "commander";
5
7
  import { parse } from "node-html-parser";
6
8
  import { build } from "vite";
7
9
  import { md5Directory, md5FilePath } from "@editframe/assets";
8
10
  import { withSpinner } from "../utils/withSpinner.js";
11
+ import { syncAssetDirectory } from "../operations/syncAssetsDirectory.js";
9
12
  import { createRender, uploadRender } from "@editframe/api";
10
13
  import { launchBrowserAndWaitForSDK } from "../utils/launchBrowserAndWaitForSDK.js";
11
14
  import { PreviewServer } from "../utils/startPreviewServer.js";
12
- import { PassThrough } from "node:stream";
13
- import { syncAssetDirectory } from "../operations/syncAssetsDirectory.js";
14
15
  import { getClient } from "../utils/index.js";
15
16
  import { getRenderInfo } from "../operations/getRenderInfo.js";
16
17
  import { processRenderInfo } from "../operations/processRenderInfo.js";
17
- import { inspect } from "node:util";
18
+ import { validateVideoResolution } from "../utils/validateVideoResolution.js";
18
19
  const buildProductionUrl = async (origin, tagName, assetPath) => {
19
20
  const md5Sum = await md5FilePath(assetPath);
20
21
  const basename = path.basename(assetPath);
@@ -89,6 +90,10 @@ program.command("render [directory]").description(
89
90
  },
90
91
  async (page) => {
91
92
  const renderInfo = await page.evaluate(getRenderInfo);
93
+ validateVideoResolution({
94
+ width: renderInfo.width,
95
+ height: renderInfo.height
96
+ });
92
97
  await processRenderInfo(renderInfo);
93
98
  const doc = parse(
94
99
  await readFile(path.join(distDir, "index.html"), "utf-8")
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+
package/dist/index.js CHANGED
@@ -7,6 +7,7 @@ import "./commands/sync.js";
7
7
  import "./commands/render.js";
8
8
  import "./commands/preview.js";
9
9
  import "./commands/process.js";
10
+ import "./commands/process-file.js";
10
11
  import "./commands/check.js";
11
12
  program.name("editframe").addOption(new Option("-t, --token <token>", "API Token").env("EF_TOKEN")).addOption(
12
13
  new Option("--ef-host <host>", "Editframe Host").env("EF_HOST").default("https://editframe.dev")
@@ -0,0 +1,15 @@
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
+ */
5
+ export declare const getRenderInfo: () => Promise<{
6
+ width: number;
7
+ height: number;
8
+ fps: number;
9
+ durationMs: number;
10
+ assets: {
11
+ efMedia: Record<string, any>;
12
+ efCaptions: string[];
13
+ efImage: string[];
14
+ };
15
+ }>;
@@ -0,0 +1,3 @@
1
+ import { getRenderInfo } from './getRenderInfo.ts';
2
+
3
+ export declare const processRenderInfo: (renderInfo: Awaited<ReturnType<typeof getRenderInfo>>) => Promise<void>;
@@ -0,0 +1 @@
1
+ export declare const syncAssetDirectory: (projectDirectory: string) => Promise<void>;
@@ -0,0 +1,3 @@
1
+ import { Page } from 'playwright';
2
+
3
+ export declare const attachWorkbench: (page: Page) => void;
@@ -0,0 +1,3 @@
1
+ import { Client } from '../../../api/src';
2
+
3
+ export declare const getClient: () => Client;
@@ -0,0 +1,10 @@
1
+ import { Page } from 'playwright';
2
+
3
+ interface LaunchOptions {
4
+ url: string;
5
+ headless?: boolean;
6
+ interactive?: boolean;
7
+ efInteractive?: boolean;
8
+ }
9
+ export declare function launchBrowserAndWaitForSDK(options: LaunchOptions, fn: (page: Page) => Promise<void>): Promise<void>;
10
+ export {};
@@ -0,0 +1,8 @@
1
+ import { ViteDevServer } from 'vite';
2
+
3
+ export declare class DevServer {
4
+ private devServer;
5
+ static start(directory: string): Promise<DevServer>;
6
+ constructor(devServer: ViteDevServer);
7
+ get url(): string;
8
+ }
@@ -0,0 +1,8 @@
1
+ import { ViteDevServer } from 'vite';
2
+
3
+ export declare class PreviewServer {
4
+ private previewServer;
5
+ static start(directory: string): Promise<PreviewServer>;
6
+ constructor(previewServer: ViteDevServer);
7
+ get url(): string;
8
+ }
@@ -0,0 +1,9 @@
1
+ type VideoPayload = {
2
+ width: number;
3
+ height: number;
4
+ };
5
+ export declare const validateVideoResolution: (rawPayload: VideoPayload) => Promise<{
6
+ width: number;
7
+ height: number;
8
+ }>;
9
+ export {};
@@ -0,0 +1,29 @@
1
+ import { z } from "zod";
2
+ import ora from "ora";
3
+ import debug from "debug";
4
+ const log = debug("ef:cli:validateVideoResolution");
5
+ const schema = z.object({
6
+ width: z.number().int(),
7
+ height: z.number().int()
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
+ });
14
+ 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
29
+ };
@@ -0,0 +1 @@
1
+ export declare const withSpinner: <T extends unknown>(label: string, fn: () => Promise<T>) => Promise<T>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@editframe/cli",
3
- "version": "0.7.0-beta.8",
3
+ "version": "0.8.0-beta.1",
4
4
  "description": "Command line interface for EditFrame",
5
5
  "bin": {
6
6
  "editframe": "./dist/index.js"
@@ -15,17 +15,18 @@
15
15
  "license": "UNLICENSED",
16
16
  "devDependencies": {
17
17
  "@types/dom-webcodecs": "^0.1.11",
18
- "@types/node": "^20.14.9",
18
+ "@types/node": "^20.14.13",
19
19
  "@types/promptly": "^3.0.5",
20
20
  "@types/tar": "^6.1.13",
21
+ "typescript": "^5.5.4",
21
22
  "vite-plugin-dts": "^3.9.1",
22
23
  "vite-tsconfig-paths": "^4.3.2"
23
24
  },
24
25
  "dependencies": {
25
- "@editframe/api": "0.7.0-beta.8",
26
- "@editframe/assets": "0.7.0-beta.8",
27
- "@editframe/elements": "0.7.0-beta.8",
28
- "@editframe/vite-plugin": "0.7.0-beta.8",
26
+ "@editframe/api": "0.8.0-beta.1",
27
+ "@editframe/assets": "0.8.0-beta.1",
28
+ "@editframe/elements": "0.8.0-beta.1",
29
+ "@editframe/vite-plugin": "0.8.0-beta.1",
29
30
  "axios": "^1.6.8",
30
31
  "chalk": "^5.3.0",
31
32
  "commander": "^12.0.0",
@@ -41,7 +42,6 @@
41
42
  "promptly": "^3.2.0",
42
43
  "tailwindcss": "^3.4.3",
43
44
  "tar": "^7.1.0",
44
- "typescript": "^5.2.2",
45
45
  "vite": "^5.2.11",
46
46
  "zod": "^3.23.8"
47
47
  }
@@ -3,7 +3,7 @@ import ora from "ora";
3
3
  import chalk from "chalk";
4
4
  import debug from "debug";
5
5
 
6
- import { getClient } from "../utils";
6
+ import { getClient } from "../utils/index.ts";
7
7
 
8
8
  const log = debug("ef:cli:auth");
9
9
 
@@ -0,0 +1,50 @@
1
+ import { basename } from "node:path";
2
+
3
+ import { program } from "commander";
4
+
5
+ import { withSpinner } from "../utils/withSpinner.ts";
6
+
7
+ import { getClient } from "../utils/index.ts";
8
+ import { createReadStream } from "node:fs";
9
+ import {
10
+ createUnprocessedFile,
11
+ updateUnprocessedFile,
12
+ uploadUnprocessedFile,
13
+ } from "@editframe/api";
14
+ import { md5FilePath } from "@editframe/assets";
15
+
16
+ program
17
+ .command("process-file <file>")
18
+ .description("Upload a audio/video to Editframe for processing.")
19
+ .action(async (path: string) => {
20
+ const client = getClient();
21
+
22
+ const fileId = await md5FilePath(path);
23
+
24
+ await withSpinner("Creating unprocessed file record", async () => {
25
+ await createUnprocessedFile(client, {
26
+ id: fileId,
27
+ processes: [],
28
+ filename: basename(path),
29
+ });
30
+ });
31
+
32
+ const readStream = createReadStream(path);
33
+
34
+ await withSpinner("Uploading file", async () => {
35
+ await uploadUnprocessedFile(client, fileId, readStream);
36
+ });
37
+
38
+ const unprocessedFile = await withSpinner(
39
+ "Marking for processing",
40
+ async () => {
41
+ return await updateUnprocessedFile(client, fileId, {
42
+ processes: ["isobmff"],
43
+ });
44
+ },
45
+ );
46
+
47
+ process.stderr.write("File uploaded and marked for processing.\n");
48
+
49
+ console.log(JSON.stringify(unprocessedFile, null, 2));
50
+ });
@@ -3,11 +3,11 @@ import path from "node:path";
3
3
 
4
4
  import { program } from "commander";
5
5
 
6
- import { withSpinner } from "../utils/withSpinner";
7
- import { launchBrowserAndWaitForSDK } from "../utils/launchBrowserAndWaitForSDK";
8
- import { PreviewServer } from "../utils/startPreviewServer";
9
- import { getRenderInfo } from "../operations/getRenderInfo";
10
- import { processRenderInfo } from "../operations/processRenderInfo";
6
+ import { withSpinner } from "../utils/withSpinner.ts";
7
+ import { launchBrowserAndWaitForSDK } from "../utils/launchBrowserAndWaitForSDK.ts";
8
+ import { PreviewServer } from "../utils/startPreviewServer.ts";
9
+ import { getRenderInfo } from "../operations/getRenderInfo.ts";
10
+ import { processRenderInfo } from "../operations/processRenderInfo.ts";
11
11
 
12
12
  program
13
13
  .command("process [directory]")
@@ -1,5 +1,7 @@
1
1
  import path from "node:path";
2
2
  import { readFile, writeFile } from "node:fs/promises";
3
+ import { inspect } from "node:util";
4
+ import { PassThrough } from "node:stream";
3
5
 
4
6
  import * as tar from "tar";
5
7
  import { program, Option } from "commander";
@@ -8,16 +10,15 @@ import { build } from "vite";
8
10
 
9
11
  import { md5Directory, md5FilePath } from "@editframe/assets";
10
12
 
11
- import { withSpinner } from "../utils/withSpinner";
13
+ import { withSpinner } from "../utils/withSpinner.ts";
14
+ import { syncAssetDirectory } from "../operations/syncAssetsDirectory.ts";
12
15
  import { createRender, uploadRender } from "@editframe/api";
13
- import { launchBrowserAndWaitForSDK } from "../utils/launchBrowserAndWaitForSDK";
14
- import { PreviewServer } from "../utils/startPreviewServer";
15
- import { PassThrough } from "node:stream";
16
- import { syncAssetDirectory } from "../operations/syncAssetsDirectory";
17
- import { getClient } from "../utils";
18
- import { getRenderInfo } from "../operations/getRenderInfo";
19
- import { processRenderInfo } from "../operations/processRenderInfo";
20
- import { inspect } from "node:util";
16
+ import { launchBrowserAndWaitForSDK } from "../utils/launchBrowserAndWaitForSDK.ts";
17
+ import { PreviewServer } from "../utils/startPreviewServer.ts";
18
+ import { getClient } from "../utils/index.ts";
19
+ import { getRenderInfo } from "../operations/getRenderInfo.ts";
20
+ import { processRenderInfo } from "../operations/processRenderInfo.ts";
21
+ import { validateVideoResolution } from "../utils/validateVideoResolution.ts";
21
22
 
22
23
  interface StrategyBuilder {
23
24
  buildProductionUrl: (tagName: string, assetPath: string) => Promise<string>;
@@ -114,6 +115,12 @@ program
114
115
  },
115
116
  async (page) => {
116
117
  const renderInfo = await page.evaluate(getRenderInfo);
118
+
119
+ validateVideoResolution({
120
+ width: renderInfo.width,
121
+ height: renderInfo.height,
122
+ });
123
+
117
124
  await processRenderInfo(renderInfo);
118
125
 
119
126
  const doc = parseHTML(
@@ -1,5 +1,5 @@
1
1
  import { program } from "commander";
2
- import { syncAssetDirectory } from "../operations/syncAssetsDirectory";
2
+ import { syncAssetDirectory } from "../operations/syncAssetsDirectory.ts";
3
3
 
4
4
  program
5
5
  .command("sync")
@@ -3,7 +3,7 @@ import {
3
3
  cacheImage,
4
4
  findOrCreateCaptions,
5
5
  } from "@editframe/assets";
6
- import type { getRenderInfo } from "./getRenderInfo";
6
+ import type { getRenderInfo } from "./getRenderInfo.ts";
7
7
 
8
8
  export const processRenderInfo = async (
9
9
  renderInfo: Awaited<ReturnType<typeof getRenderInfo>>,
@@ -15,7 +15,7 @@ import {
15
15
 
16
16
  import { createReadStream } from "node:fs";
17
17
  import type { z } from "zod";
18
- import { getClient } from "../utils";
18
+ import { getClient } from "../utils/index.ts";
19
19
 
20
20
  const imageMatch = /\.(png|jpe?g|gif|webp)$/i;
21
21
  const trackMatch = /\.track-[\d]+.mp4$/i;
@@ -2,7 +2,7 @@ import chalk from "chalk";
2
2
  import { type Browser, type Page, chromium } from "playwright";
3
3
  import debug from "debug";
4
4
 
5
- import { withSpinner } from "./withSpinner";
5
+ import { withSpinner } from "./withSpinner.ts";
6
6
 
7
7
  const browserLog = debug("ef:cli::browser");
8
8
 
@@ -5,7 +5,7 @@ import tailwindcss from "tailwindcss";
5
5
 
6
6
  import { vitePluginEditframe as editframe } from "@editframe/vite-plugin";
7
7
 
8
- import { withSpinner } from "./withSpinner";
8
+ import { withSpinner } from "./withSpinner.ts";
9
9
 
10
10
  export class DevServer {
11
11
  static async start(directory: string) {
@@ -3,7 +3,7 @@ import path from "node:path";
3
3
 
4
4
  import { vitePluginEditframe as editframe } from "@editframe/vite-plugin";
5
5
 
6
- import { withSpinner } from "./withSpinner";
6
+ import { withSpinner } from "./withSpinner.ts";
7
7
 
8
8
  export class PreviewServer {
9
9
  static async start(directory: string) {
@@ -0,0 +1,36 @@
1
+ import { z } from "zod";
2
+ import ora from "ora";
3
+ import debug from "debug";
4
+
5
+ const log = debug("ef:cli:validateVideoResolution");
6
+
7
+ type VideoPayload = {
8
+ width: number;
9
+ height: number;
10
+ };
11
+
12
+ const schema = z
13
+ .object({
14
+ width: z.number().int(),
15
+ height: z.number().int(),
16
+ })
17
+ .refine((data) => data.width % 2 === 0, {
18
+ message: "Width must be divisible by 2",
19
+ path: ["width"],
20
+ })
21
+ .refine((data) => data.height % 2 === 0, {
22
+ message: "Height must be divisible by 2",
23
+ });
24
+ export const validateVideoResolution = async (rawPayload: VideoPayload) => {
25
+ const spinner = ora("Validating video resolution").start();
26
+ const result = schema.safeParse(rawPayload);
27
+ if (result.success) {
28
+ spinner.succeed("Video resolution is valid");
29
+ return result.data;
30
+ }
31
+ spinner.fail("Invalid video resolution");
32
+ process.stderr.write(result.error?.errors.map((e) => e.message).join("\n"));
33
+ process.stderr.write("\n");
34
+ log("Error:", result.error?.errors.map((e) => e.message).join("\n"));
35
+ process.exit(1);
36
+ };
package/dist/VERSION.cjs DELETED
@@ -1,4 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const VERSION = "0.7.0-beta.8";
4
- exports.VERSION = VERSION;
@@ -1,33 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
- const commander = require("commander");
4
- const ora = require("ora");
5
- const chalk = require("chalk");
6
- const debug = require("debug");
7
- const index = require("../utils/index.cjs");
8
- const log = debug("ef:cli:auth");
9
- const getApiData = async () => {
10
- const response = await index.getClient().authenticatedFetch("/api/org");
11
- return response.json();
12
- };
13
- const authCommand = commander.program.command("auth").description("Fetch organization data using API token").action(async () => {
14
- const options = authCommand.opts();
15
- log("Options:", options);
16
- const spinner = ora("Loading...").start();
17
- try {
18
- const apiData = await getApiData();
19
- spinner.succeed("You are authenticated! 🎉");
20
- process.stderr.write(chalk.green(`Name: ${apiData.name}
21
- `));
22
- process.stderr.write(
23
- chalk.green(`Welcome to ${apiData.org_display_name}!
24
- `)
25
- );
26
- } catch (error) {
27
- spinner.fail("Authentication failed!");
28
- process.stderr.write(error?.message);
29
- process.stderr.write("\n");
30
- log("Error:", error);
31
- }
32
- });
33
- exports.getApiData = getApiData;
@@ -1,115 +0,0 @@
1
- "use strict";
2
- const node_child_process = require("node:child_process");
3
- const os = require("node:os");
4
- const commander = require("commander");
5
- const ora = require("ora");
6
- const chalk = require("chalk");
7
- const checks = {
8
- ffmpeg: {
9
- message: () => {
10
- const platform = os.platform();
11
- const message = [
12
- "Processing assets for <ef-video>, <ef-audio>, <ef-captions>, and <ef-waveform>\n elements requires ffmpeg to be installed."
13
- ];
14
- switch (platform) {
15
- case "darwin": {
16
- message.push(
17
- "On platform=darwin you can install ffmpeg using Homebrew:"
18
- );
19
- message.push(" - brew install ffmpeg");
20
- message.push(
21
- "Or you can download ffmpeg from https://ffmpeg.org/download.html"
22
- );
23
- break;
24
- }
25
- case "linux": {
26
- message.push(
27
- "You can install ffmpeg using your distribution's package manager."
28
- );
29
- break;
30
- }
31
- case "win32": {
32
- message.push(
33
- "You can download ffmpeg from https://ffmpeg.org/download.html"
34
- );
35
- message.push(
36
- "You can use package managers like Chocolatey or Scoop to install ffmpeg."
37
- );
38
- message.push(" - choco install ffmpeg-full");
39
- message.push(" - scoop install ffmpeg");
40
- message.push(" - winget install ffmpeg");
41
- break;
42
- }
43
- default: {
44
- message.push(`Unrecognized platform ${platform}`);
45
- message.push(
46
- "You can download ffmpeg from https://ffmpeg.org/download.html"
47
- );
48
- message.push(
49
- "Or try installing it from your operating system's package manager"
50
- );
51
- break;
52
- }
53
- }
54
- return message;
55
- },
56
- check: async () => {
57
- return new Promise((resolve, reject) => {
58
- node_child_process.exec("ffmpeg -version", (error, stdout, _stderr) => {
59
- if (error) {
60
- reject(error);
61
- return;
62
- }
63
- resolve(stdout);
64
- });
65
- });
66
- }
67
- },
68
- whisper_timestamped: {
69
- message: () => {
70
- const message = [
71
- "<ef-captions> Requires whisper_timestamped to be installed."
72
- ];
73
- message.push("whisper_timestamped depends on python3");
74
- message.push(" - pip3 install whisper_timestamped");
75
- message.push("Alternate installation instructions are availble at:");
76
- message.push(
77
- "https://github.com/linto-ai/whisper-timestamped#installation"
78
- );
79
- return message;
80
- },
81
- check: async () => {
82
- return new Promise((resolve, reject) => {
83
- node_child_process.exec(
84
- "whisper_timestamped --version",
85
- (error, stdout, _stderr) => {
86
- if (error) {
87
- reject(error);
88
- return;
89
- }
90
- resolve(stdout);
91
- }
92
- );
93
- });
94
- }
95
- }
96
- };
97
- commander.program.command("check").description("Check on dependencies and other requirements").action(async () => {
98
- for (const checkName in checks) {
99
- const check = checks[checkName];
100
- if (!check) {
101
- continue;
102
- }
103
- const spinner = ora(`Checking ${checkName}`).start();
104
- try {
105
- await check.check();
106
- spinner.succeed(
107
- chalk.white.bgGreen(` Check for ${checkName} passed `)
108
- );
109
- } catch (error) {
110
- spinner.fail(chalk.white.bgRed(` Check for ${checkName} failed `));
111
- process.stderr.write(chalk.red(check.message().join("\n\n")));
112
- process.stderr.write("\n");
113
- }
114
- }
115
- });