twentythree-cli 1.0.1 → 1.0.2
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/commands/auth/credentials.cjs +2 -1
- package/dist/commands/autocomplete/index.cjs +79 -0
- package/dist/commands/video/list.cjs +2 -1
- package/dist/commands/video/replace.cjs +2 -1
- package/dist/commands/video/update.cjs +7 -4
- package/dist/commands/webinar/mail/preview.cjs +16 -3
- package/docs/guides/getting-started.md +17 -1
- package/oclif.manifest.json +2702 -2670
- package/package.json +10 -5
|
@@ -40,13 +40,14 @@ var Credentials = class Credentials extends _oclif_core.Command {
|
|
|
40
40
|
require_auth_workspace_config.setCredentialDomain(domain);
|
|
41
41
|
const s = _clack_prompts.spinner();
|
|
42
42
|
s.start("Discovering workspaces...");
|
|
43
|
-
let workspaces;
|
|
43
|
+
let workspaces = [];
|
|
44
44
|
try {
|
|
45
45
|
workspaces = await require_auth_token_refresh.fetchWorkspaceTokens(domain, trimmedToken);
|
|
46
46
|
s.stop("Workspaces discovered");
|
|
47
47
|
} catch (err) {
|
|
48
48
|
s.stop("Failed to discover workspaces");
|
|
49
49
|
this.error(`Could not discover workspaces: ${err instanceof Error ? err.message : String(err)}`, { exit: 1 });
|
|
50
|
+
return;
|
|
50
51
|
}
|
|
51
52
|
let selectedWorkspaces;
|
|
52
53
|
if (workspaces.length > 1) {
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const require_runtime = require("../../_virtual/_rolldown/runtime.cjs");
|
|
2
|
+
let _oclif_core = require("@oclif/core");
|
|
3
|
+
let _clack_prompts = require("@clack/prompts");
|
|
4
|
+
_clack_prompts = require_runtime.__toESM(_clack_prompts);
|
|
5
|
+
//#region src/commands/autocomplete/index.ts
|
|
6
|
+
var Autocomplete = class Autocomplete extends _oclif_core.Command {
|
|
7
|
+
static description = "Set up tab completion for your shell";
|
|
8
|
+
static agentMetadata = {
|
|
9
|
+
api_endpoint: "interactive",
|
|
10
|
+
auth_scope: "none",
|
|
11
|
+
output_shape: { type: "none" },
|
|
12
|
+
side_effects: "creates"
|
|
13
|
+
};
|
|
14
|
+
static examples = ["<%= config.bin %> autocomplete"];
|
|
15
|
+
async run() {
|
|
16
|
+
await this.parse(Autocomplete);
|
|
17
|
+
_clack_prompts.intro("Tab completion setup");
|
|
18
|
+
const rawShell = process.env.SHELL ?? "";
|
|
19
|
+
const detectedShell = rawShell.endsWith("zsh") ? "zsh" : rawShell.endsWith("bash") ? "bash" : null;
|
|
20
|
+
let shell;
|
|
21
|
+
if (detectedShell) {
|
|
22
|
+
const confirm = await _clack_prompts.confirm({ message: `Detected shell: ${detectedShell}. Set up completion for ${detectedShell}?` });
|
|
23
|
+
if (_clack_prompts.isCancel(confirm)) {
|
|
24
|
+
_clack_prompts.cancel("Cancelled");
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
if (confirm) shell = detectedShell;
|
|
28
|
+
else {
|
|
29
|
+
const chosen = await _clack_prompts.select({
|
|
30
|
+
message: "Select your shell",
|
|
31
|
+
options: [{
|
|
32
|
+
value: "zsh",
|
|
33
|
+
label: "zsh"
|
|
34
|
+
}, {
|
|
35
|
+
value: "bash",
|
|
36
|
+
label: "bash"
|
|
37
|
+
}]
|
|
38
|
+
});
|
|
39
|
+
if (_clack_prompts.isCancel(chosen)) {
|
|
40
|
+
_clack_prompts.cancel("Cancelled");
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
shell = chosen;
|
|
44
|
+
}
|
|
45
|
+
} else {
|
|
46
|
+
const chosen = await _clack_prompts.select({
|
|
47
|
+
message: "Select your shell",
|
|
48
|
+
options: [{
|
|
49
|
+
value: "zsh",
|
|
50
|
+
label: "zsh"
|
|
51
|
+
}, {
|
|
52
|
+
value: "bash",
|
|
53
|
+
label: "bash"
|
|
54
|
+
}]
|
|
55
|
+
});
|
|
56
|
+
if (_clack_prompts.isCancel(chosen)) {
|
|
57
|
+
_clack_prompts.cancel("Cancelled");
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
shell = chosen;
|
|
61
|
+
}
|
|
62
|
+
const s = _clack_prompts.spinner();
|
|
63
|
+
s.start("Building completion cache...");
|
|
64
|
+
try {
|
|
65
|
+
await this.config.runCommand("autocomplete:create", []);
|
|
66
|
+
s.stop("Completion cache built");
|
|
67
|
+
} catch (err) {
|
|
68
|
+
s.stop("Failed to build completion cache");
|
|
69
|
+
this.error(`Could not build completion cache: ${err instanceof Error ? err.message : String(err)}`, { exit: 1 });
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const rcFile = shell === "zsh" ? "~/.zshrc" : "~/.bashrc";
|
|
73
|
+
const evalLine = `printf "$(twentythree autocomplete script ${shell})" >> ${rcFile}; source ${rcFile}`;
|
|
74
|
+
_clack_prompts.note(`Add tab completion to your shell by running:\n\n ${evalLine}\n\nThen restart your terminal or run: source ${rcFile}`, "Setup instructions");
|
|
75
|
+
_clack_prompts.outro("After setup, try: twentythree video <TAB>");
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
//#endregion
|
|
79
|
+
module.exports = Autocomplete;
|
|
@@ -52,7 +52,7 @@ var VideoList = class VideoList extends require_lib_base_command.AuthenticatedCo
|
|
|
52
52
|
async run() {
|
|
53
53
|
const { flags } = await this.parse(VideoList);
|
|
54
54
|
this.printWorkspaceHeader();
|
|
55
|
-
const
|
|
55
|
+
const allVideos = await require_lib_pagination.fetchAllPages(async (page, size) => {
|
|
56
56
|
const { data, error } = await this.apiClient.GET("/photo/list", { params: { query: {
|
|
57
57
|
p: page,
|
|
58
58
|
size,
|
|
@@ -65,6 +65,7 @@ var VideoList = class VideoList extends require_lib_base_command.AuthenticatedCo
|
|
|
65
65
|
total_count: resp?.total_count
|
|
66
66
|
};
|
|
67
67
|
});
|
|
68
|
+
const videos = flags.limit !== void 0 ? allVideos.slice(0, flags.limit) : allVideos;
|
|
68
69
|
if (this.jsonEnabled()) return require_lib_output.formatJsonOutput({
|
|
69
70
|
ok: true,
|
|
70
71
|
data: videos,
|
|
@@ -81,7 +81,7 @@ var VideoReplace = class VideoReplace extends require_lib_base_command.Authentic
|
|
|
81
81
|
this.error(`File not found: ${args.file}`, { exit: 1 });
|
|
82
82
|
}
|
|
83
83
|
const { data: tokenData, error: tokenError } = await this.apiClient.GET("/photo/get-replace-token", { params: { query: { photo_id: Number(args.id) } } });
|
|
84
|
-
if (tokenError) this.error(require_lib_term_map.applyCliTerms(
|
|
84
|
+
if (tokenError) this.error(require_lib_term_map.applyCliTerms(require_lib_output.formatApiError(tokenError)), { exit: 1 });
|
|
85
85
|
const replaceToken = tokenData?.data?.replace_token;
|
|
86
86
|
if (!replaceToken) this.error("Failed to obtain replace token from API", { exit: 1 });
|
|
87
87
|
const totalBytes = (await (0, node_fs_promises.stat)(args.file)).size;
|
|
@@ -107,6 +107,7 @@ var VideoReplace = class VideoReplace extends require_lib_base_command.Authentic
|
|
|
107
107
|
} finally {
|
|
108
108
|
bar.finish();
|
|
109
109
|
}
|
|
110
|
+
if (!result) return;
|
|
110
111
|
const adminUrl = `https://${this.activeWorkspace.domain}/manage/video/${args.id}`;
|
|
111
112
|
this.log(chalk.default.green(`Video ${args.id} replaced successfully`));
|
|
112
113
|
this.log(`ID: ${args.id}`);
|
|
@@ -146,9 +146,12 @@ var VideoUpdate = class VideoUpdate extends require_lib_base_command.Authenticat
|
|
|
146
146
|
initialValue: current.published_p ? "yes" : "no"
|
|
147
147
|
});
|
|
148
148
|
if ((0, _clack_prompts.isCancel)(publishedResult)) process.exit(2);
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
149
|
+
const titleVal = titleResult;
|
|
150
|
+
const descriptionVal = descriptionResult;
|
|
151
|
+
const tagsVal = tagsResult;
|
|
152
|
+
if (titleVal !== "") body.title = titleVal;
|
|
153
|
+
if (descriptionVal !== "" || current.content_text === "") body.description = descriptionVal;
|
|
154
|
+
if (tagsVal !== "" || currentTags === "") body.tags = tagsVal;
|
|
152
155
|
body.published_p = publishedResult === "yes" ? 1 : 0;
|
|
153
156
|
} else {
|
|
154
157
|
if (flags.title !== void 0) body.title = flags.title;
|
|
@@ -167,7 +170,7 @@ var VideoUpdate = class VideoUpdate extends require_lib_base_command.Authenticat
|
|
|
167
170
|
body,
|
|
168
171
|
headers: { "Content-Type": "application/x-www-form-urlencoded" }
|
|
169
172
|
});
|
|
170
|
-
if (updateError) this.error(require_lib_term_map.applyCliTerms(
|
|
173
|
+
if (updateError) this.error(require_lib_term_map.applyCliTerms(require_lib_output.formatApiError(updateError)), { exit: 1 });
|
|
171
174
|
this.log(chalk.default.green(`Video ${args.id} updated`));
|
|
172
175
|
if (this.jsonEnabled()) return require_lib_output.formatJsonOutput({
|
|
173
176
|
ok: true,
|
|
@@ -49,7 +49,10 @@ var WebinarMailPreview = class WebinarMailPreview extends require_lib_base_comma
|
|
|
49
49
|
const { args, flags } = await this.parse(WebinarMailPreview);
|
|
50
50
|
this.printWorkspaceHeader();
|
|
51
51
|
const contextField = flags["webinar-id"] ? { live_id: Number(flags["webinar-id"]) } : flags["series-id"] ? { live_series_id: Number(flags["series-id"]) } : null;
|
|
52
|
-
if (!contextField)
|
|
52
|
+
if (!contextField) {
|
|
53
|
+
this.error(require_lib_term_map.applyCliTerms("Either --webinar-id or --series-id is required"), { exit: 1 });
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
53
56
|
const query = new URLSearchParams({
|
|
54
57
|
...Object.fromEntries(Object.entries(contextField).map(([k, v]) => [k, String(v)])),
|
|
55
58
|
live_mail_id: String(args.id)
|
|
@@ -57,8 +60,18 @@ var WebinarMailPreview = class WebinarMailPreview extends require_lib_base_comma
|
|
|
57
60
|
const headers = {};
|
|
58
61
|
if (this.activeWorkspace.bearer_token) headers["Authorization"] = `Bearer ${this.activeWorkspace.bearer_token}`;
|
|
59
62
|
const response = await fetch(`${this.apiBaseUrl}live/mail/preview?${query}`, { headers });
|
|
60
|
-
const
|
|
61
|
-
if (!response.ok)
|
|
63
|
+
const body = await response.text();
|
|
64
|
+
if (!response.ok) {
|
|
65
|
+
let errMsg;
|
|
66
|
+
try {
|
|
67
|
+
const parsed = JSON.parse(body);
|
|
68
|
+
errMsg = parsed?.message ?? parsed?.error ?? `status ${response.status}`;
|
|
69
|
+
} catch {
|
|
70
|
+
errMsg = body.slice(0, 200) || `status ${response.status}`;
|
|
71
|
+
}
|
|
72
|
+
this.error(require_lib_term_map.applyCliTerms(`API error: ${errMsg}`), { exit: 1 });
|
|
73
|
+
}
|
|
74
|
+
const html = body;
|
|
62
75
|
if (this.jsonEnabled()) return require_lib_output.formatJsonOutput({
|
|
63
76
|
ok: true,
|
|
64
77
|
data: html,
|
|
@@ -35,7 +35,21 @@ twentythree workspace list
|
|
|
35
35
|
twentythree workspace use company.video23.com
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
## Step 3:
|
|
38
|
+
## Step 3: Enable tab completion (optional)
|
|
39
|
+
|
|
40
|
+
Run this once to set up `<TAB>` completion for all commands and flags:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
twentythree autocomplete
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The command detects your shell (bash or zsh), builds the completion cache, and shows the eval line to paste into your RC file. After sourcing your RC file or restarting your terminal, try:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
twentythree video <TAB>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Step 4: Run your first command
|
|
39
53
|
|
|
40
54
|
List the videos in your active workspace.
|
|
41
55
|
|
|
@@ -64,3 +78,5 @@ Run `twentythree <topic> --help` for help on any topic. For example:
|
|
|
64
78
|
twentythree video --help
|
|
65
79
|
twentythree auth --help
|
|
66
80
|
```
|
|
81
|
+
|
|
82
|
+
Use `<TAB>` after any command to discover subcommands and flags.
|