@editframe/cli 0.10.0-beta.7 → 0.11.0-beta.10
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/auth.d.ts +2 -2
- package/dist/commands/auth.js +8 -8
- package/dist/operations/syncAssetsDirectory/SubAssetSync.js +3 -0
- package/dist/operations/syncAssetsDirectory/SyncCaption.d.ts +1 -1
- package/dist/operations/syncAssetsDirectory/SyncCaption.js +2 -1
- package/dist/operations/syncAssetsDirectory/SyncFragmentIndex.d.ts +1 -1
- package/dist/operations/syncAssetsDirectory/SyncFragmentIndex.js +3 -5
- package/dist/operations/syncAssetsDirectory/SyncImage.d.ts +2 -2
- package/dist/operations/syncAssetsDirectory/SyncImage.js +3 -3
- package/dist/operations/syncAssetsDirectory/SyncStatus.d.ts +1 -1
- package/dist/operations/syncAssetsDirectory/SyncStatus.js +1 -0
- package/dist/operations/syncAssetsDirectory/SyncTrack.d.ts +2 -2
- package/dist/operations/syncAssetsDirectory/SyncTrack.js +5 -7
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.js +10 -4
- package/package.json +5 -5
- package/src/commands/auth.ts +9 -9
- package/src/operations/syncAssetsDirectory/SubAssetSync.ts +4 -0
- package/src/operations/syncAssetsDirectory/SyncCaption.ts +3 -2
- package/src/operations/syncAssetsDirectory/SyncFragmentIndex.ts +4 -6
- package/src/operations/syncAssetsDirectory/SyncImage.test.ts +1 -3
- package/src/operations/syncAssetsDirectory/SyncImage.ts +3 -3
- package/src/operations/syncAssetsDirectory/SyncStatus.ts +3 -2
- package/src/operations/syncAssetsDirectory/SyncTrack.ts +6 -8
- package/src/utils/index.ts +10 -4
- package/dist/test-fixtures/fixture.d.ts +0 -26
package/dist/VERSION.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "0.
|
|
1
|
+
export declare const VERSION = "0.11.0-beta.10";
|
package/dist/VERSION.js
CHANGED
package/dist/commands/auth.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
export interface APIOrgResult {
|
|
2
|
-
|
|
2
|
+
apiKeyName: string;
|
|
3
3
|
id: string;
|
|
4
4
|
org_id: string;
|
|
5
5
|
created_at: unknown;
|
|
6
6
|
updated_at: unknown;
|
|
7
|
-
|
|
7
|
+
displayName: string;
|
|
8
8
|
}
|
|
9
9
|
export declare const getApiData: () => Promise<APIOrgResult>;
|
package/dist/commands/auth.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { program } from "commander";
|
|
2
|
-
import ora from "ora";
|
|
3
1
|
import chalk from "chalk";
|
|
2
|
+
import { program } from "commander";
|
|
4
3
|
import debug from "debug";
|
|
4
|
+
import ora from "ora";
|
|
5
5
|
import { getClient } from "../utils/index.js";
|
|
6
6
|
const log = debug("ef:cli:auth");
|
|
7
7
|
const getApiData = async () => {
|
|
8
|
-
const response = await getClient().authenticatedFetch("/api/
|
|
8
|
+
const response = await getClient().authenticatedFetch("/api/v1/organization");
|
|
9
9
|
return response.json();
|
|
10
10
|
};
|
|
11
11
|
const authCommand = program.command("auth").description("Fetch organization data using API token").action(async () => {
|
|
@@ -15,16 +15,16 @@ const authCommand = program.command("auth").description("Fetch organization data
|
|
|
15
15
|
try {
|
|
16
16
|
const apiData = await getApiData();
|
|
17
17
|
spinner.succeed("You are authenticated! 🎉");
|
|
18
|
-
process.stderr.write(chalk.green(`Name: ${apiData.name}
|
|
19
|
-
`));
|
|
20
18
|
process.stderr.write(
|
|
21
|
-
chalk.green(`
|
|
19
|
+
chalk.green(`You're using ${apiData.apiKeyName} API key 🚀
|
|
20
|
+
`)
|
|
21
|
+
);
|
|
22
|
+
process.stderr.write(
|
|
23
|
+
chalk.blue(`Welcome to ${apiData.displayName} organization 🎉
|
|
22
24
|
`)
|
|
23
25
|
);
|
|
24
26
|
} catch (error) {
|
|
25
27
|
spinner.fail("Authentication failed!");
|
|
26
|
-
process.stderr.write(error?.message);
|
|
27
|
-
process.stderr.write("\n");
|
|
28
28
|
log("Error:", error);
|
|
29
29
|
}
|
|
30
30
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import debug from "debug";
|
|
1
2
|
import { SyncCaption } from "./SyncCaption.js";
|
|
2
3
|
import { SyncFragmentIndex } from "./SyncFragmentIndex.js";
|
|
3
4
|
import { SyncImage } from "./SyncImage.js";
|
|
@@ -6,7 +7,9 @@ const trackMatch = /\.track-[\d]+.mp4$/i;
|
|
|
6
7
|
const fragmentIndexMatch = /\.tracks.json$/i;
|
|
7
8
|
const captionsMatch = /\.captions.json$/i;
|
|
8
9
|
const imageMatch = /\.(png|jpe?g|gif|webp)$/i;
|
|
10
|
+
const log = debug("ef:SubAssetSync");
|
|
9
11
|
const getAssetSync = (subAssetPath, md5) => {
|
|
12
|
+
log("getAssetSync", { subAssetPath, md5 });
|
|
10
13
|
if (imageMatch.test(subAssetPath)) {
|
|
11
14
|
return new SyncImage(subAssetPath, md5);
|
|
12
15
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CreateCaptionFileResult } from '../../../../api/src';
|
|
1
|
+
import { CreateCaptionFileResult } from '../../../../api/src/index.ts';
|
|
2
2
|
import { SubAssetSync } from './SubAssetSync.ts';
|
|
3
3
|
import { SyncStatus } from './SyncStatus.ts';
|
|
4
4
|
export declare class SyncCaption implements SubAssetSync<CreateCaptionFileResult> {
|
|
@@ -2,6 +2,7 @@ import fs from "node:fs/promises";
|
|
|
2
2
|
import { createCaptionFile, uploadCaptionFile } from "@editframe/api";
|
|
3
3
|
import { Readable } from "node:stream";
|
|
4
4
|
import { getClient } from "../../utils/index.js";
|
|
5
|
+
import { basename } from "node:path";
|
|
5
6
|
import { SyncStatus } from "./SyncStatus.js";
|
|
6
7
|
class SyncCaption {
|
|
7
8
|
constructor(path, md5) {
|
|
@@ -22,7 +23,7 @@ class SyncCaption {
|
|
|
22
23
|
async create() {
|
|
23
24
|
this.created = await createCaptionFile(getClient(), {
|
|
24
25
|
md5: this.md5,
|
|
25
|
-
filename: this.path.replace(/\.captions.json$/, ""),
|
|
26
|
+
filename: basename(this.path).replace(/\.captions.json$/, ""),
|
|
26
27
|
byte_size: await this.byteSize()
|
|
27
28
|
});
|
|
28
29
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CreateISOBMFFFileResult } from '../../../../api/src';
|
|
1
|
+
import { CreateISOBMFFFileResult } from '../../../../api/src/index.ts';
|
|
2
2
|
import { SubAssetSync } from './SubAssetSync.ts';
|
|
3
3
|
import { SyncStatus } from './SyncStatus.ts';
|
|
4
4
|
export declare class SyncFragmentIndex implements SubAssetSync<CreateISOBMFFFileResult> {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
|
-
import { join, dirname } from "node:path";
|
|
2
|
+
import { join, dirname, basename } from "node:path";
|
|
3
3
|
import { Readable } from "node:stream";
|
|
4
4
|
import { createISOBMFFFile, uploadFragmentIndex } from "@editframe/api";
|
|
5
5
|
import { getClient } from "../../utils/index.js";
|
|
@@ -11,9 +11,7 @@ class SyncFragmentIndex {
|
|
|
11
11
|
this.icon = "📋";
|
|
12
12
|
this.label = "fragment index";
|
|
13
13
|
this.syncStatus = new SyncStatus(this.path);
|
|
14
|
-
this.fileSyncStatus = new SyncStatus(
|
|
15
|
-
join(dirname(this.path), "isobmff")
|
|
16
|
-
);
|
|
14
|
+
this.fileSyncStatus = new SyncStatus(join(dirname(this.path), "isobmff"));
|
|
17
15
|
this.created = null;
|
|
18
16
|
}
|
|
19
17
|
async byteSize() {
|
|
@@ -26,7 +24,7 @@ class SyncFragmentIndex {
|
|
|
26
24
|
async create() {
|
|
27
25
|
this.created = await createISOBMFFFile(getClient(), {
|
|
28
26
|
md5: this.md5,
|
|
29
|
-
filename: this.path.replace(/\.tracks.json$/, "")
|
|
27
|
+
filename: basename(this.path).replace(/\.tracks.json$/, "")
|
|
30
28
|
});
|
|
31
29
|
}
|
|
32
30
|
isComplete() {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CreateImageFileResult } from '../../../../api/src';
|
|
2
|
-
import { Probe } from '../../../../assets/src';
|
|
1
|
+
import { CreateImageFileResult } from '../../../../api/src/index.ts';
|
|
2
|
+
import { Probe } from '../../../../assets/src/index.ts';
|
|
3
3
|
import { SubAssetSync } from './SubAssetSync.ts';
|
|
4
4
|
import { SyncStatus } from './SyncStatus.ts';
|
|
5
5
|
export declare class SyncImage implements SubAssetSync<CreateImageFileResult> {
|
|
@@ -60,18 +60,18 @@ class SyncImage {
|
|
|
60
60
|
isComplete() {
|
|
61
61
|
return !!this.created?.complete;
|
|
62
62
|
}
|
|
63
|
-
upload() {
|
|
63
|
+
async upload() {
|
|
64
64
|
if (!this.created) {
|
|
65
65
|
throw new Error(
|
|
66
66
|
"Image not created. Should have been prevented by .isComplete()"
|
|
67
67
|
);
|
|
68
68
|
}
|
|
69
|
-
|
|
69
|
+
await uploadImageFile(
|
|
70
70
|
getClient(),
|
|
71
71
|
this.created.id,
|
|
72
72
|
createReadStream(this.path),
|
|
73
73
|
Number.parseInt(this.probeResult.format.size || "0")
|
|
74
|
-
);
|
|
74
|
+
).whenUploaded();
|
|
75
75
|
}
|
|
76
76
|
async markSynced() {
|
|
77
77
|
if (!this.created) {
|
|
@@ -25,8 +25,8 @@ export interface SyncStatusInfo extends z.infer<typeof SyncStatusSchema> {
|
|
|
25
25
|
}
|
|
26
26
|
export declare class SyncStatus {
|
|
27
27
|
private basePath;
|
|
28
|
-
constructor(basePath: string);
|
|
29
28
|
infoPath: string;
|
|
29
|
+
constructor(basePath: string);
|
|
30
30
|
isSynced(): Promise<boolean>;
|
|
31
31
|
readInfo(): Promise<{
|
|
32
32
|
md5: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CreateISOBMFFFileResult, CreateISOBMFFTrackResult } from '../../../../api/src';
|
|
2
|
-
import { Probe } from '../../../../assets/src';
|
|
1
|
+
import { CreateISOBMFFFileResult, CreateISOBMFFTrackResult } from '../../../../api/src/index.ts';
|
|
2
|
+
import { Probe } from '../../../../assets/src/index.ts';
|
|
3
3
|
import { SubAssetSync } from './SubAssetSync.ts';
|
|
4
4
|
import { SyncStatus } from './SyncStatus.ts';
|
|
5
5
|
export declare class SyncTrack implements SubAssetSync<CreateISOBMFFTrackResult> {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createReadStream } from "node:fs";
|
|
2
2
|
import fs from "node:fs/promises";
|
|
3
|
-
import { join, dirname } from "node:path";
|
|
3
|
+
import { join, dirname, basename } from "node:path";
|
|
4
4
|
import { createISOBMFFFile, createISOBMFFTrack, uploadISOBMFFTrack } from "@editframe/api";
|
|
5
5
|
import { Probe } from "@editframe/assets";
|
|
6
6
|
import { getClient } from "../../utils/index.js";
|
|
@@ -12,9 +12,7 @@ class SyncTrack {
|
|
|
12
12
|
this.icon = "📼";
|
|
13
13
|
this.label = "track";
|
|
14
14
|
this.syncStatus = new SyncStatus(this.path);
|
|
15
|
-
this.fileSyncStatus = new SyncStatus(
|
|
16
|
-
join(dirname(this.path), "isobmff")
|
|
17
|
-
);
|
|
15
|
+
this.fileSyncStatus = new SyncStatus(join(dirname(this.path), "isobmff"));
|
|
18
16
|
this.created = null;
|
|
19
17
|
this._isoFile = null;
|
|
20
18
|
this._probeResult = null;
|
|
@@ -44,7 +42,7 @@ class SyncTrack {
|
|
|
44
42
|
async prepare() {
|
|
45
43
|
this._isoFile = await createISOBMFFFile(getClient(), {
|
|
46
44
|
md5: this.md5,
|
|
47
|
-
filename: this.path.replace(/\.track-[\d]+.mp4$/, "")
|
|
45
|
+
filename: basename(this.path).replace(/\.track-[\d]+.mp4$/, "")
|
|
48
46
|
});
|
|
49
47
|
this._probeResult = await Probe.probePath(this.path);
|
|
50
48
|
}
|
|
@@ -98,13 +96,13 @@ class SyncTrack {
|
|
|
98
96
|
"Track not created. Should have been prevented by .isComplete()"
|
|
99
97
|
);
|
|
100
98
|
}
|
|
101
|
-
|
|
99
|
+
await uploadISOBMFFTrack(
|
|
102
100
|
getClient(),
|
|
103
101
|
this.isoFile.id,
|
|
104
102
|
Number(this.trackId),
|
|
105
103
|
createReadStream(this.path),
|
|
106
104
|
this.created?.byte_size
|
|
107
|
-
);
|
|
105
|
+
).whenUploaded();
|
|
108
106
|
}
|
|
109
107
|
async markSynced() {
|
|
110
108
|
if (!this.created) {
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Client } from '../../../api/src';
|
|
1
|
+
import { Client } from '../../../api/src/index.ts';
|
|
2
2
|
export declare const getClient: () => Client;
|
package/dist/utils/index.js
CHANGED
|
@@ -5,10 +5,16 @@ let client;
|
|
|
5
5
|
const getClient = () => {
|
|
6
6
|
if (!client) {
|
|
7
7
|
const programOpts = program.opts();
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
);
|
|
8
|
+
const token = programOpts.token || process.env.EF_TOKEN;
|
|
9
|
+
const efHost = programOpts.efHost || process.env.EF_HOST;
|
|
10
|
+
console.log("token", token);
|
|
11
|
+
console.log("efHost", efHost);
|
|
12
|
+
if (!token) {
|
|
13
|
+
throw new Error(
|
|
14
|
+
"EF_TOKEN must be set or supplied as command line argument"
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
client = new Client(token, efHost);
|
|
12
18
|
}
|
|
13
19
|
return client;
|
|
14
20
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@editframe/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0-beta.10",
|
|
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.
|
|
27
|
-
"@editframe/assets": "0.
|
|
28
|
-
"@editframe/elements": "0.
|
|
29
|
-
"@editframe/vite-plugin": "0.
|
|
26
|
+
"@editframe/api": "0.11.0-beta.10",
|
|
27
|
+
"@editframe/assets": "0.11.0-beta.10",
|
|
28
|
+
"@editframe/elements": "0.11.0-beta.10",
|
|
29
|
+
"@editframe/vite-plugin": "0.11.0-beta.10",
|
|
30
30
|
"@inquirer/prompts": "^5.3.8",
|
|
31
31
|
"axios": "^1.6.8",
|
|
32
32
|
"chalk": "^5.3.0",
|
package/src/commands/auth.ts
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { program } from "commander";
|
|
2
|
-
import ora from "ora";
|
|
3
1
|
import chalk from "chalk";
|
|
2
|
+
import { program } from "commander";
|
|
4
3
|
import debug from "debug";
|
|
4
|
+
import ora from "ora";
|
|
5
5
|
|
|
6
6
|
import { getClient } from "../utils/index.ts";
|
|
7
7
|
|
|
8
8
|
const log = debug("ef:cli:auth");
|
|
9
9
|
|
|
10
10
|
export interface APIOrgResult {
|
|
11
|
-
|
|
11
|
+
apiKeyName: string;
|
|
12
12
|
id: string;
|
|
13
13
|
org_id: string;
|
|
14
14
|
created_at: unknown;
|
|
15
15
|
updated_at: unknown;
|
|
16
|
-
|
|
16
|
+
displayName: string;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
export const getApiData = async () => {
|
|
20
|
-
const response = await getClient().authenticatedFetch("/api/
|
|
20
|
+
const response = await getClient().authenticatedFetch("/api/v1/organization");
|
|
21
21
|
return response.json() as Promise<APIOrgResult>;
|
|
22
22
|
};
|
|
23
23
|
|
|
@@ -33,14 +33,14 @@ const authCommand = program
|
|
|
33
33
|
try {
|
|
34
34
|
const apiData = await getApiData();
|
|
35
35
|
spinner.succeed("You are authenticated! 🎉");
|
|
36
|
-
process.stderr.write(chalk.green(`Name: ${apiData.name}\n`));
|
|
37
36
|
process.stderr.write(
|
|
38
|
-
chalk.green(`
|
|
37
|
+
chalk.green(`You're using ${apiData.apiKeyName} API key 🚀\n`),
|
|
38
|
+
);
|
|
39
|
+
process.stderr.write(
|
|
40
|
+
chalk.blue(`Welcome to ${apiData.displayName} organization 🎉\n`),
|
|
39
41
|
);
|
|
40
42
|
} catch (error: any) {
|
|
41
43
|
spinner.fail("Authentication failed!");
|
|
42
|
-
process.stderr.write(error?.message);
|
|
43
|
-
process.stderr.write("\n");
|
|
44
44
|
log("Error:", error);
|
|
45
45
|
}
|
|
46
46
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import debug from "debug";
|
|
1
2
|
import type { SyncStatus } from "./SyncStatus.ts";
|
|
2
3
|
|
|
3
4
|
import { SyncCaption } from "./SyncCaption.ts";
|
|
@@ -25,7 +26,10 @@ const fragmentIndexMatch = /\.tracks.json$/i;
|
|
|
25
26
|
const captionsMatch = /\.captions.json$/i;
|
|
26
27
|
const imageMatch = /\.(png|jpe?g|gif|webp)$/i;
|
|
27
28
|
|
|
29
|
+
const log = debug("ef:SubAssetSync");
|
|
30
|
+
|
|
28
31
|
export const getAssetSync = (subAssetPath: string, md5: string) => {
|
|
32
|
+
log("getAssetSync", { subAssetPath, md5 });
|
|
29
33
|
if (imageMatch.test(subAssetPath)) {
|
|
30
34
|
return new SyncImage(subAssetPath, md5);
|
|
31
35
|
}
|
|
@@ -8,9 +8,10 @@ import {
|
|
|
8
8
|
|
|
9
9
|
import { Readable } from "node:stream";
|
|
10
10
|
import { getClient } from "../../utils/index.ts";
|
|
11
|
+
|
|
12
|
+
import { basename } from "node:path";
|
|
11
13
|
import type { SubAssetSync } from "./SubAssetSync.ts";
|
|
12
14
|
import { SyncStatus } from "./SyncStatus.ts";
|
|
13
|
-
|
|
14
15
|
export class SyncCaption implements SubAssetSync<CreateCaptionFileResult> {
|
|
15
16
|
icon = "📝";
|
|
16
17
|
label = "captions";
|
|
@@ -32,7 +33,7 @@ export class SyncCaption implements SubAssetSync<CreateCaptionFileResult> {
|
|
|
32
33
|
async create() {
|
|
33
34
|
this.created = await createCaptionFile(getClient(), {
|
|
34
35
|
md5: this.md5,
|
|
35
|
-
filename: this.path.replace(/\.captions.json$/, ""),
|
|
36
|
+
filename: basename(this.path).replace(/\.captions.json$/, ""),
|
|
36
37
|
byte_size: await this.byteSize(),
|
|
37
38
|
});
|
|
38
39
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
|
-
import { dirname, join } from "node:path";
|
|
2
|
+
import { basename, dirname, join } from "node:path";
|
|
3
3
|
import { Readable } from "node:stream";
|
|
4
4
|
|
|
5
5
|
import {
|
|
@@ -17,10 +17,8 @@ export class SyncFragmentIndex
|
|
|
17
17
|
{
|
|
18
18
|
icon = "📋";
|
|
19
19
|
label = "fragment index";
|
|
20
|
-
syncStatus
|
|
21
|
-
fileSyncStatus
|
|
22
|
-
join(dirname(this.path), "isobmff"),
|
|
23
|
-
);
|
|
20
|
+
syncStatus = new SyncStatus(this.path);
|
|
21
|
+
fileSyncStatus = new SyncStatus(join(dirname(this.path), "isobmff"));
|
|
24
22
|
created: CreateISOBMFFFileResult | null = null;
|
|
25
23
|
|
|
26
24
|
constructor(
|
|
@@ -39,7 +37,7 @@ export class SyncFragmentIndex
|
|
|
39
37
|
async create() {
|
|
40
38
|
this.created = await createISOBMFFFile(getClient(), {
|
|
41
39
|
md5: this.md5,
|
|
42
|
-
filename: this.path.replace(/\.tracks.json$/, ""),
|
|
40
|
+
filename: basename(this.path).replace(/\.tracks.json$/, ""),
|
|
43
41
|
});
|
|
44
42
|
}
|
|
45
43
|
|
|
@@ -70,9 +70,7 @@ describe("SyncImage", async () => {
|
|
|
70
70
|
test("throws when not created", async () => {
|
|
71
71
|
const syncImage = new SyncImage(await cacheImage(image!), image!.md5);
|
|
72
72
|
await syncImage.prepare();
|
|
73
|
-
|
|
74
|
-
// any async operations are awaited.
|
|
75
|
-
expect(() => syncImage.upload()).toThrow();
|
|
73
|
+
await expect(() => syncImage.upload()).rejects.toThrow();
|
|
76
74
|
});
|
|
77
75
|
test("uploads image", async () => {
|
|
78
76
|
server.use(
|
|
@@ -80,18 +80,18 @@ export class SyncImage implements SubAssetSync<CreateImageFileResult> {
|
|
|
80
80
|
isComplete() {
|
|
81
81
|
return !!this.created?.complete;
|
|
82
82
|
}
|
|
83
|
-
upload() {
|
|
83
|
+
async upload() {
|
|
84
84
|
if (!this.created) {
|
|
85
85
|
throw new Error(
|
|
86
86
|
"Image not created. Should have been prevented by .isComplete()",
|
|
87
87
|
);
|
|
88
88
|
}
|
|
89
|
-
|
|
89
|
+
await uploadImageFile(
|
|
90
90
|
getClient(),
|
|
91
91
|
this.created.id,
|
|
92
92
|
createReadStream(this.path),
|
|
93
93
|
Number.parseInt(this.probeResult.format.size || "0"),
|
|
94
|
-
);
|
|
94
|
+
).whenUploaded();
|
|
95
95
|
}
|
|
96
96
|
async markSynced() {
|
|
97
97
|
if (!this.created) {
|
|
@@ -16,15 +16,16 @@ const SyncStatusSchema = z.object({
|
|
|
16
16
|
export interface SyncStatusInfo extends z.infer<typeof SyncStatusSchema> {}
|
|
17
17
|
|
|
18
18
|
export class SyncStatus {
|
|
19
|
-
constructor(private basePath: string) {}
|
|
20
|
-
|
|
21
19
|
infoPath = `${this.basePath}.info`;
|
|
22
20
|
|
|
21
|
+
constructor(private basePath: string) {}
|
|
22
|
+
|
|
23
23
|
async isSynced() {
|
|
24
24
|
const syncInfo = await this.readInfo();
|
|
25
25
|
if (!syncInfo) {
|
|
26
26
|
return false;
|
|
27
27
|
}
|
|
28
|
+
console.log("syncInfo.infoPath", this.infoPath);
|
|
28
29
|
return syncInfo.version === SYNC_VERSION && syncInfo.complete;
|
|
29
30
|
}
|
|
30
31
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createReadStream } from "node:fs";
|
|
2
2
|
import fs from "node:fs/promises";
|
|
3
|
-
import { dirname, join } from "node:path";
|
|
3
|
+
import { basename, dirname, join } from "node:path";
|
|
4
4
|
|
|
5
5
|
import type { z } from "zod";
|
|
6
6
|
|
|
@@ -21,10 +21,8 @@ import { SyncStatus } from "./SyncStatus.ts";
|
|
|
21
21
|
export class SyncTrack implements SubAssetSync<CreateISOBMFFTrackResult> {
|
|
22
22
|
icon = "📼";
|
|
23
23
|
label = "track";
|
|
24
|
-
syncStatus
|
|
25
|
-
fileSyncStatus
|
|
26
|
-
join(dirname(this.path), "isobmff"),
|
|
27
|
-
);
|
|
24
|
+
syncStatus = new SyncStatus(this.path);
|
|
25
|
+
fileSyncStatus = new SyncStatus(join(dirname(this.path), "isobmff"));
|
|
28
26
|
created: CreateISOBMFFTrackResult | null = null;
|
|
29
27
|
|
|
30
28
|
constructor(
|
|
@@ -64,7 +62,7 @@ export class SyncTrack implements SubAssetSync<CreateISOBMFFTrackResult> {
|
|
|
64
62
|
async prepare() {
|
|
65
63
|
this._isoFile = await createISOBMFFFile(getClient(), {
|
|
66
64
|
md5: this.md5,
|
|
67
|
-
filename: this.path.replace(/\.track-[\d]+.mp4$/, ""),
|
|
65
|
+
filename: basename(this.path).replace(/\.track-[\d]+.mp4$/, ""),
|
|
68
66
|
});
|
|
69
67
|
this._probeResult = await Probe.probePath(this.path);
|
|
70
68
|
}
|
|
@@ -127,13 +125,13 @@ export class SyncTrack implements SubAssetSync<CreateISOBMFFTrackResult> {
|
|
|
127
125
|
"Track not created. Should have been prevented by .isComplete()",
|
|
128
126
|
);
|
|
129
127
|
}
|
|
130
|
-
|
|
128
|
+
await uploadISOBMFFTrack(
|
|
131
129
|
getClient(),
|
|
132
130
|
this.isoFile.id,
|
|
133
131
|
Number(this.trackId),
|
|
134
132
|
createReadStream(this.path),
|
|
135
133
|
this.created?.byte_size,
|
|
136
|
-
);
|
|
134
|
+
).whenUploaded();
|
|
137
135
|
}
|
|
138
136
|
async markSynced() {
|
|
139
137
|
if (!this.created) {
|
package/src/utils/index.ts
CHANGED
|
@@ -7,10 +7,16 @@ let client: Client;
|
|
|
7
7
|
export const getClient = () => {
|
|
8
8
|
if (!client) {
|
|
9
9
|
const programOpts = program.opts();
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
);
|
|
10
|
+
const token = programOpts.token || process.env.EF_TOKEN;
|
|
11
|
+
const efHost = programOpts.efHost || process.env.EF_HOST;
|
|
12
|
+
console.log("token", token);
|
|
13
|
+
console.log("efHost", efHost);
|
|
14
|
+
if (!token) {
|
|
15
|
+
throw new Error(
|
|
16
|
+
"EF_TOKEN must be set or supplied as command line argument",
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
client = new Client(token, efHost);
|
|
14
20
|
}
|
|
15
21
|
return client;
|
|
16
22
|
};
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { SyncStatusInfo } from '../src/operations/syncAssetsDirectory/SyncStatus.ts';
|
|
2
|
-
export declare const fixture: (fixture: string, name: string) => Promise<Fixture>;
|
|
3
|
-
export interface Fixture {
|
|
4
|
-
name: string;
|
|
5
|
-
fixture: string;
|
|
6
|
-
md5: string;
|
|
7
|
-
content: Buffer;
|
|
8
|
-
originalPath: string;
|
|
9
|
-
write: (dir: string) => Promise<void>;
|
|
10
|
-
}
|
|
11
|
-
export declare const withFixtures: (fixtures: Promise<Fixture>[], fn: (props: {
|
|
12
|
-
files: Fixture[];
|
|
13
|
-
rootDir: string;
|
|
14
|
-
srcDir: string;
|
|
15
|
-
assetsDir: string;
|
|
16
|
-
cacheDir: string;
|
|
17
|
-
expectCacheFiles: (fixture: Fixture, files: string[]) => Promise<void>;
|
|
18
|
-
expectInfoFileContent: (fileName: string, fixture: Fixture, expectedContent: Pick<SyncStatusInfo, "complete" | "id"> & {
|
|
19
|
-
byte_size?: number;
|
|
20
|
-
}) => Promise<void>;
|
|
21
|
-
syncAssetsDirectory: () => Promise<void>;
|
|
22
|
-
cacheImage: (fixture: Fixture) => Promise<string>;
|
|
23
|
-
generateTrack: (fixture: Fixture, trackId: number) => Promise<string>;
|
|
24
|
-
generateTrackFragmentIndex: (fixture: Fixture) => Promise<string>;
|
|
25
|
-
generateCaptions: (fixture: Fixture) => Promise<string>;
|
|
26
|
-
}) => Promise<void>) => Promise<void>;
|