@editframe/cli 0.26.3-beta.0 → 0.26.4-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 (37) hide show
  1. package/dist/VERSION.js +1 -1
  2. package/dist/VERSION.js.map +1 -1
  3. package/package.json +5 -5
  4. package/src/commands/auth.ts +0 -46
  5. package/src/commands/check.ts +0 -129
  6. package/src/commands/mux.ts +0 -10
  7. package/src/commands/preview.ts +0 -9
  8. package/src/commands/process-file.ts +0 -55
  9. package/src/commands/process.ts +0 -41
  10. package/src/commands/render.ts +0 -190
  11. package/src/commands/sync.ts +0 -13
  12. package/src/commands/test-asset.file +0 -0
  13. package/src/commands/webhook.ts +0 -76
  14. package/src/operations/processRenderInfo.ts +0 -40
  15. package/src/operations/syncAssetsDirectory/SubAssetSync.ts +0 -45
  16. package/src/operations/syncAssetsDirectory/SyncCaption.test.ts +0 -180
  17. package/src/operations/syncAssetsDirectory/SyncCaption.ts +0 -87
  18. package/src/operations/syncAssetsDirectory/SyncFragmentIndex.test.ts +0 -185
  19. package/src/operations/syncAssetsDirectory/SyncFragmentIndex.ts +0 -101
  20. package/src/operations/syncAssetsDirectory/SyncImage.test.ts +0 -162
  21. package/src/operations/syncAssetsDirectory/SyncImage.ts +0 -123
  22. package/src/operations/syncAssetsDirectory/SyncStatus.ts +0 -50
  23. package/src/operations/syncAssetsDirectory/SyncTrack.test.ts +0 -265
  24. package/src/operations/syncAssetsDirectory/SyncTrack.ts +0 -175
  25. package/src/operations/syncAssetsDirectory/doAssetSync.test.ts +0 -134
  26. package/src/operations/syncAssetsDirectory/doAssetSync.ts +0 -62
  27. package/src/operations/syncAssetsDirectory.test.ts +0 -510
  28. package/src/operations/syncAssetsDirectory.ts +0 -91
  29. package/src/utils/attachWorkbench.ts +0 -16
  30. package/src/utils/createReadableStreamFromReadable.ts +0 -113
  31. package/src/utils/getFolderSize.ts +0 -20
  32. package/src/utils/index.ts +0 -20
  33. package/src/utils/launchBrowserAndWaitForSDK.ts +0 -64
  34. package/src/utils/startDevServer.ts +0 -61
  35. package/src/utils/startPreviewServer.ts +0 -38
  36. package/src/utils/validateVideoResolution.ts +0 -36
  37. package/src/utils/withSpinner.ts +0 -16
@@ -1,175 +0,0 @@
1
- import { createReadStream } from "node:fs";
2
- import fs from "node:fs/promises";
3
- import { basename, dirname, join } from "node:path";
4
-
5
- import {
6
- type CreateISOBMFFFileResult,
7
- type CreateISOBMFFTrackPayload,
8
- type CreateISOBMFFTrackResult,
9
- createISOBMFFFile,
10
- createISOBMFFTrack,
11
- type LookupISOBMFFFileByMd5Result,
12
- lookupISOBMFFFileByMd5,
13
- uploadISOBMFFTrack,
14
- } from "@editframe/api";
15
- import { Probe } from "@editframe/assets";
16
-
17
- import { createReadableStreamFromReadable } from "../../utils/createReadableStreamFromReadable.js";
18
- import { getClient } from "../../utils/index.js";
19
- import type { SubAssetSync } from "./SubAssetSync.js";
20
- import { SyncStatus } from "./SyncStatus.js";
21
-
22
- export class SyncTrack implements SubAssetSync<CreateISOBMFFTrackResult> {
23
- icon = "📼";
24
- label = "track";
25
- syncStatus = new SyncStatus(this.path);
26
- fileSyncStatus = new SyncStatus(join(dirname(this.path), "isobmff"));
27
- created: CreateISOBMFFTrackResult | null = null;
28
-
29
- constructor(
30
- public path: string,
31
- public md5: string,
32
- ) {}
33
-
34
- private _isoFile:
35
- | CreateISOBMFFFileResult
36
- | LookupISOBMFFFileByMd5Result
37
- | null = null;
38
-
39
- get isoFile() {
40
- if (this._isoFile) {
41
- return this._isoFile;
42
- }
43
- throw new Error("ISOBMFF file not found. Call prepare() first.");
44
- }
45
-
46
- async byteSize() {
47
- return (await fs.stat(this.path)).size;
48
- }
49
-
50
- private _probeResult: Probe | null = null;
51
- get probeResult() {
52
- if (this._probeResult) {
53
- return this._probeResult;
54
- }
55
- throw new Error("Probe result not found. Call prepare() first.");
56
- }
57
-
58
- get track() {
59
- const [track] = this.probeResult.streams;
60
- if (track) {
61
- return track;
62
- }
63
- throw new Error(`No track found in track: ${this.path}`);
64
- }
65
-
66
- async prepare() {
67
- const maybeIsoFile = await lookupISOBMFFFileByMd5(getClient(), this.md5);
68
- if (maybeIsoFile) {
69
- this._isoFile = maybeIsoFile;
70
- } else {
71
- this._isoFile = await createISOBMFFFile(getClient(), {
72
- md5: this.md5,
73
- filename: basename(this.path).replace(/\.track-[\d]+.mp4$/, ""),
74
- });
75
- }
76
- this._probeResult = await Probe.probePath(this.path);
77
- }
78
-
79
- get trackId() {
80
- const trackId = this.path.match(/track-([\d]+).mp4/)?.[1];
81
- if (!trackId) {
82
- throw new Error(`No track ID found for track: ${this.path}`);
83
- }
84
- return trackId;
85
- }
86
-
87
- get trackDuration() {
88
- const track = this.track;
89
- if (!track.duration) {
90
- throw new Error(`No duration found in track: ${this.path}`);
91
- }
92
- if (typeof track.duration === "string") {
93
- return Number.parseFloat(track.duration);
94
- }
95
- return track.duration;
96
- }
97
-
98
- async validate() {
99
- this.trackId;
100
- this.isoFile;
101
- this.trackDuration;
102
- }
103
-
104
- async create(): Promise<void> {
105
- const track = this.track;
106
- const isoFile = this.isoFile;
107
-
108
- if (track.codec_type === "data") {
109
- throw new Error(`Unsupported codec type: ${track.codec_type}`);
110
- }
111
- const createPayload: CreateISOBMFFTrackPayload =
112
- track.codec_type === "audio"
113
- ? {
114
- type: track.codec_type,
115
- file_id: isoFile.id,
116
- track_id: Number(this.trackId),
117
- probe_info: track,
118
- duration_ms: Math.round(this.trackDuration * 1000),
119
- codec_name: track.codec_name,
120
- byte_size: await this.byteSize(),
121
- }
122
- : {
123
- type: track.codec_type,
124
- file_id: isoFile.id,
125
- track_id: Number(this.trackId),
126
- probe_info: track,
127
- duration_ms: Math.round(this.trackDuration * 1000),
128
- codec_name: track.codec_name,
129
- byte_size: await this.byteSize(),
130
- };
131
-
132
- this.created = await createISOBMFFTrack(getClient(), createPayload);
133
- }
134
- isComplete() {
135
- return !!this.created?.complete;
136
- }
137
- async upload() {
138
- if (!this.created) {
139
- throw new Error(
140
- "Track not created. Should have been prevented by .isComplete()",
141
- );
142
- }
143
- await uploadISOBMFFTrack(
144
- getClient(),
145
- this.isoFile.id,
146
- Number(this.trackId),
147
- createReadableStreamFromReadable(createReadStream(this.path)),
148
- this.created?.byte_size,
149
- ).whenUploaded();
150
- }
151
- async markSynced() {
152
- if (!this.created) {
153
- throw new Error(
154
- "Track not created. Should have been prevented by .isComplete()",
155
- );
156
- }
157
- const byteSize = await this.byteSize();
158
- await Promise.all([
159
- this.syncStatus.markSynced({
160
- version: "1",
161
- complete: true,
162
- id: `${this.created.file_id}:${this.created.track_id}`,
163
- md5: this.md5,
164
- byte_size: byteSize,
165
- }),
166
- this.fileSyncStatus.markSynced({
167
- version: "1",
168
- complete: true,
169
- id: this.created.file_id,
170
- md5: this.md5,
171
- byte_size: byteSize,
172
- }),
173
- ]);
174
- }
175
- }
@@ -1,134 +0,0 @@
1
- import { describe, expect, test, vi } from "vitest";
2
- import { doAssetSync } from "./doAssetSync.js";
3
- import type { SubAssetSync } from "./SubAssetSync.js";
4
- import type { SyncStatusInfo } from "./SyncStatus.js";
5
-
6
- const collectAsyncGenerator = async (
7
- generator: SubAssetSync<unknown>,
8
- ): Promise<
9
- {
10
- status: "info" | "success";
11
- message: string;
12
- }[]
13
- > => {
14
- const result = [];
15
- for await (const item of doAssetSync(generator)) {
16
- result.push(item);
17
- }
18
- return result;
19
- };
20
-
21
- const buildFakeSync = (): SubAssetSync<unknown> => {
22
- const fakeSyncStatus = {
23
- isSynced: vi.fn().mockReturnValue(false),
24
- } as unknown as SyncStatusInfo;
25
- const fakeSync = {
26
- label: "TEST_LABEL",
27
- icon: "🧪",
28
- path: "TEST_PATH",
29
- readInfo: vi.fn().mockReturnValue(Promise.resolve(null)),
30
- syncStatus: fakeSyncStatus,
31
- markSynced: vi.fn().mockReturnValue(Promise.resolve()),
32
- isComplete: vi.fn().mockReturnValue(false),
33
- prepare: vi.fn().mockReturnValue(Promise.resolve()),
34
- validate: vi.fn().mockReturnValue(Promise.resolve()),
35
- create: vi.fn().mockReturnValue(Promise.resolve()),
36
- upload: vi.fn().mockReturnValue(Promise.resolve()),
37
- } as unknown as SubAssetSync<unknown>;
38
- return fakeSync;
39
- };
40
-
41
- describe("doAssetSync", () => {
42
- test("Succeeds if all steps are executed without error", async () => {
43
- const fakeSync = buildFakeSync();
44
- const messages = await collectAsyncGenerator(fakeSync);
45
- expect(messages).toEqual([
46
- {
47
- status: "info",
48
- message: "🧪 Syncing TEST_LABEL: TEST_PATH",
49
- },
50
- {
51
- status: "success",
52
- message: "Synced TEST_LABEL: TEST_PATH",
53
- },
54
- ]);
55
- });
56
-
57
- test("Succeeds if asset is already synced", async () => {
58
- const fakeSync = buildFakeSync();
59
- fakeSync.syncStatus.isSynced = vi.fn().mockReturnValue(true);
60
- const messages = await collectAsyncGenerator(fakeSync);
61
- expect(messages).toEqual([
62
- {
63
- status: "info",
64
- message: "Sub-asset has already been synced: TEST_PATH",
65
- },
66
- ]);
67
- });
68
-
69
- test("Succeeds if asset is already uploaded", async () => {
70
- const fakeSync = buildFakeSync();
71
- fakeSync.isComplete = vi.fn().mockReturnValue(true);
72
- const messages = await collectAsyncGenerator(fakeSync);
73
- expect(messages).toEqual([
74
- {
75
- status: "info",
76
- message: "🧪 Syncing TEST_LABEL: TEST_PATH",
77
- },
78
- {
79
- status: "success",
80
- message: "Synced TEST_LABEL: TEST_PATH",
81
- },
82
- ]);
83
- });
84
-
85
- test("Throws if prepare fails", async () => {
86
- const fakeSync = buildFakeSync();
87
- fakeSync.prepare = vi
88
- .fn()
89
- .mockReturnValue(Promise.reject(new Error("TEST_ERROR")));
90
- await expect(collectAsyncGenerator(fakeSync)).rejects.toThrow(
91
- "Error validating TEST_LABEL: TEST_ERROR",
92
- );
93
- });
94
-
95
- test("Throws if validate fails", async () => {
96
- const fakeSync = buildFakeSync();
97
- fakeSync.validate = vi
98
- .fn()
99
- .mockReturnValue(Promise.reject(new Error("TEST_ERROR")));
100
- await expect(collectAsyncGenerator(fakeSync)).rejects.toThrow(
101
- "Error validating TEST_LABEL: TEST_ERROR",
102
- );
103
- });
104
-
105
- test("Throws if create fails", async () => {
106
- const fakeSync = buildFakeSync();
107
- fakeSync.create = vi
108
- .fn()
109
- .mockReturnValue(Promise.reject(new Error("TEST_ERROR")));
110
- await expect(collectAsyncGenerator(fakeSync)).rejects.toThrow(
111
- "Error creating TEST_LABEL: TEST_ERROR",
112
- );
113
- });
114
-
115
- test("Throws if upload fails", async () => {
116
- const fakeSync = buildFakeSync();
117
- fakeSync.upload = vi
118
- .fn()
119
- .mockReturnValue(Promise.reject(new Error("TEST_ERROR")));
120
- await expect(collectAsyncGenerator(fakeSync)).rejects.toThrow(
121
- "Error uploading TEST_LABEL: TEST_ERROR",
122
- );
123
- });
124
-
125
- test("Throws if markSynced fails", async () => {
126
- const fakeSync = buildFakeSync();
127
- fakeSync.markSynced = vi
128
- .fn()
129
- .mockReturnValue(Promise.reject(new Error("TEST_ERROR")));
130
- await expect(collectAsyncGenerator(fakeSync)).rejects.toThrow(
131
- "Error marking TEST_LABEL as synced: TEST_ERROR",
132
- );
133
- });
134
- });
@@ -1,62 +0,0 @@
1
- import type { SubAssetSync } from "./SubAssetSync.js";
2
-
3
- export const doAssetSync = async function* (
4
- assetSync: SubAssetSync<unknown>,
5
- ): AsyncGenerator<{
6
- status: "info" | "success";
7
- message: string;
8
- }> {
9
- if (await assetSync.syncStatus.isSynced()) {
10
- yield {
11
- status: "info",
12
- message: `Sub-asset has already been synced: ${assetSync.path}`,
13
- };
14
- return;
15
- }
16
-
17
- try {
18
- await assetSync.prepare();
19
- await assetSync.validate();
20
- } catch (error) {
21
- const message = error instanceof Error ? error.message : "Unknown error";
22
-
23
- throw new Error(`Error validating ${assetSync.label}: ${message}`);
24
- }
25
-
26
- yield {
27
- status: "info",
28
- message: `${assetSync.icon} Syncing ${assetSync.label}: ${assetSync.path}`,
29
- };
30
-
31
- try {
32
- await assetSync.create();
33
- } catch (error) {
34
- const message = error instanceof Error ? error.message : "Unknown error";
35
-
36
- throw new Error(`Error creating ${assetSync.label}: ${message}`);
37
- }
38
-
39
- if (!assetSync.isComplete()) {
40
- try {
41
- await assetSync.upload();
42
- } catch (error) {
43
- const message = error instanceof Error ? error.message : "Unknown error";
44
-
45
- throw new Error(`Error uploading ${assetSync.label}: ${message}`);
46
- }
47
- }
48
-
49
- try {
50
- await assetSync.markSynced();
51
- } catch (error) {
52
- const message = error instanceof Error ? error.message : "Unknown error";
53
-
54
- throw new Error(`Error marking ${assetSync.label} as synced: ${message}`);
55
- }
56
-
57
- yield {
58
- status: "success",
59
- message: `Synced ${assetSync.label}: ${assetSync.path}`,
60
- };
61
- return;
62
- };