beatapi 0.1.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.
- package/LICENSE +21 -0
- package/README.md +27 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +23 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli.d.ts +48 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +282 -0
- package/dist/cli.js.map +1 -0
- package/dist/credentials.d.ts +28 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +44 -0
- package/dist/credentials.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/prompt.d.ts +2 -0
- package/dist/prompt.d.ts.map +1 -0
- package/dist/prompt.js +38 -0
- package/dist/prompt.js.map +1 -0
- package/dist/webhook-secrets.d.ts +4 -0
- package/dist/webhook-secrets.d.ts.map +1 -0
- package/dist/webhook-secrets.js +36 -0
- package/dist/webhook-secrets.js.map +1 -0
- package/package.json +50 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 BeatAPI
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# beatapi
|
|
2
|
+
|
|
3
|
+
Official BeatAPI command-line interface for people, scripts, and AI agents.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install --global beatapi
|
|
7
|
+
beatapi auth login
|
|
8
|
+
beatapi workflows list
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The login command validates the key before storing it in the operating
|
|
12
|
+
system's credential manager. For CI and short-lived shells, set
|
|
13
|
+
`BEATAPI_API_KEY` instead.
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
beatapi music-video create --file music-video.json
|
|
17
|
+
beatapi tasks wait task_123 --interval 7000
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Results are JSON on stdout. Progress and errors use stderr so the CLI composes
|
|
21
|
+
cleanly with shell scripts and automation tools.
|
|
22
|
+
|
|
23
|
+
Webhook creation writes the one-time signing secret to a mode-`0600` file and
|
|
24
|
+
returns its path as `secret_file`; it does not print the secret.
|
|
25
|
+
|
|
26
|
+
See the [repository](https://github.com/BeatAPI/beatapi-cli) for the complete
|
|
27
|
+
command reference and security model.
|
package/dist/bin.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":""}
|
package/dist/bin.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { BeatAPIError } from "beatapi-client";
|
|
3
|
+
import { run } from "./cli.js";
|
|
4
|
+
function exitCodeFor(error) {
|
|
5
|
+
if (!(error instanceof BeatAPIError))
|
|
6
|
+
return 1;
|
|
7
|
+
if (error.status === 401 || error.code === "missing_api_key")
|
|
8
|
+
return 2;
|
|
9
|
+
if (error.status === 402 || error.code === "insufficient_credits")
|
|
10
|
+
return 3;
|
|
11
|
+
if (error.status === 429)
|
|
12
|
+
return 4;
|
|
13
|
+
return 1;
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
process.exitCode = await run(process.argv.slice(2));
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
20
|
+
process.stderr.write(`beatapi: ${message}\n`);
|
|
21
|
+
process.exitCode = exitCodeFor(error);
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,SAAS,WAAW,CAAC,KAAc;IACjC,IAAI,CAAC,CAAC,KAAK,YAAY,YAAY,CAAC;QAAE,OAAO,CAAC,CAAC;IAC/C,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB;QAAE,OAAO,CAAC,CAAC;IACvE,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,IAAI,KAAK,sBAAsB;QAAE,OAAO,CAAC,CAAC;IAC5E,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG;QAAE,OAAO,CAAC,CAAC;IACnC,OAAO,CAAC,CAAC;AACX,CAAC;AAED,IAAI,CAAC;IACH,OAAO,CAAC,QAAQ,GAAG,MAAM,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AACtD,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,OAAO,IAAI,CAAC,CAAC;IAC9C,OAAO,CAAC,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;AACxC,CAAC"}
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type BeatAPITask, type CreateWebhookInput, type EcommerceVideoTaskInput, type MusicVideoTaskInput, type UpdateWebhookInput } from "beatapi-client";
|
|
2
|
+
import { type CredentialStore } from "./credentials.js";
|
|
3
|
+
export declare const VERSION = "0.1.0";
|
|
4
|
+
type Writable = (text: string) => void;
|
|
5
|
+
interface ClientLike {
|
|
6
|
+
listWorkflows(): Promise<unknown>;
|
|
7
|
+
getUsage(): Promise<unknown>;
|
|
8
|
+
getTask(taskId: string): Promise<unknown>;
|
|
9
|
+
waitForTask(taskId: string, options: {
|
|
10
|
+
intervalMs: number;
|
|
11
|
+
maxAttempts: number;
|
|
12
|
+
onUpdate: (task: BeatAPITask, attempt: number) => void;
|
|
13
|
+
}): Promise<unknown>;
|
|
14
|
+
uploadFile(content: Blob | Uint8Array, options: {
|
|
15
|
+
filename: string;
|
|
16
|
+
mimeType?: string;
|
|
17
|
+
purpose?: "input";
|
|
18
|
+
}): Promise<unknown>;
|
|
19
|
+
createMusicVideoTask(input: MusicVideoTaskInput): Promise<unknown>;
|
|
20
|
+
editMusicVideoShot(taskId: string, shotId: string, input: {
|
|
21
|
+
prompt: string;
|
|
22
|
+
duration?: number;
|
|
23
|
+
quality?: "standard" | "high";
|
|
24
|
+
resolution?: "540p" | "720p" | "1080p";
|
|
25
|
+
}): Promise<unknown>;
|
|
26
|
+
getMusicVideoShotMedia(taskId: string, shotId: string): Promise<unknown>;
|
|
27
|
+
composeMusicVideoTask(taskId: string, input: {
|
|
28
|
+
shot_ids: string[];
|
|
29
|
+
}): Promise<unknown>;
|
|
30
|
+
createEcommerceVideoTask(input: EcommerceVideoTaskInput): Promise<unknown>;
|
|
31
|
+
listWebhooks(): Promise<unknown>;
|
|
32
|
+
createWebhook(input: CreateWebhookInput): Promise<unknown>;
|
|
33
|
+
getWebhook(id: string): Promise<unknown>;
|
|
34
|
+
updateWebhook(id: string, input: UpdateWebhookInput): Promise<unknown>;
|
|
35
|
+
deleteWebhook(id: string): Promise<unknown>;
|
|
36
|
+
}
|
|
37
|
+
export interface RunOptions {
|
|
38
|
+
stdout?: Writable;
|
|
39
|
+
stderr?: Writable;
|
|
40
|
+
env?: Record<string, string | undefined>;
|
|
41
|
+
apiKey?: string;
|
|
42
|
+
credentialStore?: CredentialStore;
|
|
43
|
+
promptSecret?: (label?: string) => Promise<string>;
|
|
44
|
+
createClient?: (apiKey?: string) => ClientLike;
|
|
45
|
+
}
|
|
46
|
+
export declare function run(args: string[], options?: RunOptions): Promise<number>;
|
|
47
|
+
export {};
|
|
48
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { basename, extname } from "node:path";
|
|
3
|
+
import { BeatAPIClient, } from "beatapi-client";
|
|
4
|
+
import { createCredentialStore, resolveApiKey, } from "./credentials.js";
|
|
5
|
+
import { promptSecret as defaultPromptSecret } from "./prompt.js";
|
|
6
|
+
import { persistWebhookSecret } from "./webhook-secrets.js";
|
|
7
|
+
export const VERSION = "0.1.0";
|
|
8
|
+
const HELP = `BeatAPI CLI ${VERSION}
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
beatapi auth login|status|logout
|
|
12
|
+
beatapi workflows list
|
|
13
|
+
beatapi usage
|
|
14
|
+
beatapi files upload <path>
|
|
15
|
+
beatapi music-video create --file <input.json>
|
|
16
|
+
beatapi music-video shots edit <task-id> <shot-id> --prompt <text>
|
|
17
|
+
beatapi music-video shots media <task-id> <shot-id>
|
|
18
|
+
beatapi music-video compose <task-id> --shot <shot-id> [--shot <shot-id>]
|
|
19
|
+
beatapi ecommerce-video create --file <input.json>
|
|
20
|
+
beatapi tasks get <task-id>
|
|
21
|
+
beatapi tasks wait <task-id> [--interval <ms>] [--attempts <count>]
|
|
22
|
+
beatapi webhooks list
|
|
23
|
+
beatapi webhooks create --file <input.json>
|
|
24
|
+
beatapi webhooks get <webhook-id>
|
|
25
|
+
beatapi webhooks update <webhook-id> --file <input.json>
|
|
26
|
+
beatapi webhooks delete <webhook-id>
|
|
27
|
+
|
|
28
|
+
Authentication:
|
|
29
|
+
Run \`beatapi auth login\` to store the key in the operating-system
|
|
30
|
+
credential manager, or set BEATAPI_API_KEY for the current process.
|
|
31
|
+
|
|
32
|
+
Environment:
|
|
33
|
+
BEATAPI_API_KEY Overrides the saved credential
|
|
34
|
+
BEATAPI_BASE_URL Optional API origin; defaults to https://api.beatapi.io
|
|
35
|
+
`;
|
|
36
|
+
const MIME_TYPES = {
|
|
37
|
+
".aac": "audio/aac",
|
|
38
|
+
".jpeg": "image/jpeg",
|
|
39
|
+
".jpg": "image/jpeg",
|
|
40
|
+
".m4a": "audio/mp4",
|
|
41
|
+
".mp3": "audio/mpeg",
|
|
42
|
+
".png": "image/png",
|
|
43
|
+
".srt": "application/x-subrip",
|
|
44
|
+
".wav": "audio/wav",
|
|
45
|
+
".webp": "image/webp",
|
|
46
|
+
};
|
|
47
|
+
function flagValue(args, flag) {
|
|
48
|
+
const index = args.indexOf(flag);
|
|
49
|
+
if (index < 0)
|
|
50
|
+
return undefined;
|
|
51
|
+
const value = args[index + 1];
|
|
52
|
+
if (!value || value.startsWith("--")) {
|
|
53
|
+
throw new Error(`${flag} requires a value.`);
|
|
54
|
+
}
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
57
|
+
function repeatedFlagValues(args, flag) {
|
|
58
|
+
const values = [];
|
|
59
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
60
|
+
if (args[index] !== flag)
|
|
61
|
+
continue;
|
|
62
|
+
const value = args[index + 1];
|
|
63
|
+
if (!value || value.startsWith("--")) {
|
|
64
|
+
throw new Error(`${flag} requires a value.`);
|
|
65
|
+
}
|
|
66
|
+
values.push(value);
|
|
67
|
+
index += 1;
|
|
68
|
+
}
|
|
69
|
+
return values;
|
|
70
|
+
}
|
|
71
|
+
function positiveInteger(value, fallback, flag) {
|
|
72
|
+
if (value === undefined)
|
|
73
|
+
return fallback;
|
|
74
|
+
const parsed = Number(value);
|
|
75
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
76
|
+
throw new Error(`${flag} must be a positive integer.`);
|
|
77
|
+
}
|
|
78
|
+
return parsed;
|
|
79
|
+
}
|
|
80
|
+
async function readJson(path) {
|
|
81
|
+
if (!path)
|
|
82
|
+
throw new Error("--file <path> is required.");
|
|
83
|
+
let text;
|
|
84
|
+
try {
|
|
85
|
+
text = await readFile(path, "utf8");
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
throw new Error(`Unable to read ${path}.`, { cause: error });
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
return JSON.parse(text);
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
throw new Error(`${path} is not valid JSON.`, { cause: error });
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function inputFile(args) {
|
|
98
|
+
return flagValue(args, "--file") ?? flagValue(args, "--json");
|
|
99
|
+
}
|
|
100
|
+
function printJson(value, stdout) {
|
|
101
|
+
stdout(`${JSON.stringify(value, null, 2)}\n`);
|
|
102
|
+
}
|
|
103
|
+
function requireIdentifier(value, label) {
|
|
104
|
+
if (!value || value.startsWith("--"))
|
|
105
|
+
throw new Error(`${label} is required.`);
|
|
106
|
+
return value;
|
|
107
|
+
}
|
|
108
|
+
function defaultCreateClient(apiKey, env) {
|
|
109
|
+
return new BeatAPIClient({
|
|
110
|
+
apiKey,
|
|
111
|
+
baseUrl: env.BEATAPI_BASE_URL,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
export async function run(args, options = {}) {
|
|
115
|
+
const stdout = options.stdout ?? ((text) => process.stdout.write(text));
|
|
116
|
+
const stderr = options.stderr ?? ((text) => process.stderr.write(text));
|
|
117
|
+
const env = options.env ?? process.env;
|
|
118
|
+
const store = options.credentialStore ?? createCredentialStore();
|
|
119
|
+
const createClient = options.createClient ?? ((apiKey) => defaultCreateClient(apiKey, env));
|
|
120
|
+
const promptSecret = options.promptSecret ?? defaultPromptSecret;
|
|
121
|
+
if (args.length === 0 || args.includes("--help") || args.includes("-h")) {
|
|
122
|
+
stdout(HELP);
|
|
123
|
+
return 0;
|
|
124
|
+
}
|
|
125
|
+
if (args.includes("--version") || args.includes("-v")) {
|
|
126
|
+
stdout(`${VERSION}\n`);
|
|
127
|
+
return 0;
|
|
128
|
+
}
|
|
129
|
+
const [resource, action, firstIdentifier, secondIdentifier] = args;
|
|
130
|
+
if (resource === "auth" && action === "login") {
|
|
131
|
+
const apiKey = (await promptSecret()).trim();
|
|
132
|
+
if (!apiKey.startsWith("sk_") || apiKey.length < 8) {
|
|
133
|
+
throw new Error("The API key must be a BeatAPI key beginning with sk_.");
|
|
134
|
+
}
|
|
135
|
+
const usage = await createClient(apiKey).getUsage();
|
|
136
|
+
await store.set(apiKey);
|
|
137
|
+
stdout("Connected to BeatAPI. The API key was saved securely.\n");
|
|
138
|
+
printJson(usage, stdout);
|
|
139
|
+
return 0;
|
|
140
|
+
}
|
|
141
|
+
if (resource === "auth" && action === "logout") {
|
|
142
|
+
await store.delete();
|
|
143
|
+
stdout("Saved BeatAPI credentials removed.\n");
|
|
144
|
+
return 0;
|
|
145
|
+
}
|
|
146
|
+
if ((resource === "workflows" && (action === undefined || action === "list")) ||
|
|
147
|
+
(resource === "workflow" && action === "list")) {
|
|
148
|
+
printJson(await createClient(undefined).listWorkflows(), stdout);
|
|
149
|
+
return 0;
|
|
150
|
+
}
|
|
151
|
+
const resolved = options.apiKey?.trim()
|
|
152
|
+
? { apiKey: options.apiKey.trim(), source: "explicit" }
|
|
153
|
+
: await resolveApiKey({ env, store });
|
|
154
|
+
if (resource === "auth" && action === "status") {
|
|
155
|
+
if (!resolved) {
|
|
156
|
+
stdout("Not authenticated. Run `beatapi auth login`.\n");
|
|
157
|
+
return 1;
|
|
158
|
+
}
|
|
159
|
+
const usage = await createClient(resolved.apiKey).getUsage();
|
|
160
|
+
stdout(`Authenticated via ${resolved.source}.\n`);
|
|
161
|
+
printJson(usage, stdout);
|
|
162
|
+
return 0;
|
|
163
|
+
}
|
|
164
|
+
if (!resolved) {
|
|
165
|
+
throw new Error("Authentication required. Run `beatapi auth login` or set BEATAPI_API_KEY.");
|
|
166
|
+
}
|
|
167
|
+
const client = createClient(resolved.apiKey);
|
|
168
|
+
if (resource === "usage" && action === undefined) {
|
|
169
|
+
printJson(await client.getUsage(), stdout);
|
|
170
|
+
return 0;
|
|
171
|
+
}
|
|
172
|
+
if ((resource === "files" || resource === "file") &&
|
|
173
|
+
action === "upload") {
|
|
174
|
+
const path = requireIdentifier(firstIdentifier, "File path");
|
|
175
|
+
const extension = extname(path).toLowerCase();
|
|
176
|
+
const mimeType = MIME_TYPES[extension];
|
|
177
|
+
if (!mimeType) {
|
|
178
|
+
throw new Error(`Unsupported file extension: ${extension || "(none)"}.`);
|
|
179
|
+
}
|
|
180
|
+
const content = await readFile(path);
|
|
181
|
+
printJson(await client.uploadFile(content, {
|
|
182
|
+
filename: basename(path),
|
|
183
|
+
mimeType,
|
|
184
|
+
purpose: "input",
|
|
185
|
+
}), stdout);
|
|
186
|
+
return 0;
|
|
187
|
+
}
|
|
188
|
+
if (resource === "music-video" && action === "create") {
|
|
189
|
+
const input = await readJson(inputFile(args));
|
|
190
|
+
printJson(await client.createMusicVideoTask(input), stdout);
|
|
191
|
+
return 0;
|
|
192
|
+
}
|
|
193
|
+
if (resource === "music-video" &&
|
|
194
|
+
action === "shots" &&
|
|
195
|
+
firstIdentifier === "edit") {
|
|
196
|
+
const taskId = requireIdentifier(secondIdentifier, "Task ID");
|
|
197
|
+
const shotId = requireIdentifier(args[4], "Shot ID");
|
|
198
|
+
const prompt = flagValue(args, "--prompt");
|
|
199
|
+
const input = inputFile(args)
|
|
200
|
+
? await readJson(inputFile(args))
|
|
201
|
+
: { prompt: requireIdentifier(prompt, "--prompt") };
|
|
202
|
+
printJson(await client.editMusicVideoShot(taskId, shotId, input), stdout);
|
|
203
|
+
return 0;
|
|
204
|
+
}
|
|
205
|
+
if (resource === "music-video" &&
|
|
206
|
+
action === "shots" &&
|
|
207
|
+
firstIdentifier === "media") {
|
|
208
|
+
const taskId = requireIdentifier(secondIdentifier, "Task ID");
|
|
209
|
+
const shotId = requireIdentifier(args[4], "Shot ID");
|
|
210
|
+
printJson(await client.getMusicVideoShotMedia(taskId, shotId), stdout);
|
|
211
|
+
return 0;
|
|
212
|
+
}
|
|
213
|
+
if (resource === "music-video" && action === "compose") {
|
|
214
|
+
const taskId = requireIdentifier(firstIdentifier, "Task ID");
|
|
215
|
+
const shotIds = repeatedFlagValues(args, "--shot");
|
|
216
|
+
if (shotIds.length === 0) {
|
|
217
|
+
throw new Error("At least one --shot <shot-id> is required.");
|
|
218
|
+
}
|
|
219
|
+
printJson(await client.composeMusicVideoTask(taskId, { shot_ids: shotIds }), stdout);
|
|
220
|
+
return 0;
|
|
221
|
+
}
|
|
222
|
+
if (resource === "ecommerce-video" && action === "create") {
|
|
223
|
+
const input = await readJson(inputFile(args));
|
|
224
|
+
printJson(await client.createEcommerceVideoTask(input), stdout);
|
|
225
|
+
return 0;
|
|
226
|
+
}
|
|
227
|
+
if ((resource === "tasks" || resource === "task") &&
|
|
228
|
+
action === "get") {
|
|
229
|
+
printJson(await client.getTask(requireIdentifier(firstIdentifier, "Task ID")), stdout);
|
|
230
|
+
return 0;
|
|
231
|
+
}
|
|
232
|
+
if ((resource === "tasks" || resource === "task") &&
|
|
233
|
+
action === "wait") {
|
|
234
|
+
const taskId = requireIdentifier(firstIdentifier, "Task ID");
|
|
235
|
+
const intervalMs = positiveInteger(flagValue(args, "--interval"), 5_000, "--interval");
|
|
236
|
+
const maxAttempts = positiveInteger(flagValue(args, "--attempts"), 120, "--attempts");
|
|
237
|
+
const result = await client.waitForTask(taskId, {
|
|
238
|
+
intervalMs,
|
|
239
|
+
maxAttempts,
|
|
240
|
+
onUpdate: (task, attempt) => {
|
|
241
|
+
stderr(`[${attempt}/${maxAttempts}] ${task.id || taskId}: ${task.status}\n`);
|
|
242
|
+
},
|
|
243
|
+
});
|
|
244
|
+
printJson(result, stdout);
|
|
245
|
+
return 0;
|
|
246
|
+
}
|
|
247
|
+
if (resource === "webhooks" && action === "list") {
|
|
248
|
+
printJson(await client.listWebhooks(), stdout);
|
|
249
|
+
return 0;
|
|
250
|
+
}
|
|
251
|
+
if (resource === "webhooks" && action === "create") {
|
|
252
|
+
const input = await readJson(inputFile(args));
|
|
253
|
+
const endpoint = (await client.createWebhook(input));
|
|
254
|
+
try {
|
|
255
|
+
printJson(await persistWebhookSecret(endpoint, env), stdout);
|
|
256
|
+
}
|
|
257
|
+
catch (error) {
|
|
258
|
+
const endpointId = typeof endpoint.id === "string" ? endpoint.id : undefined;
|
|
259
|
+
if (endpointId) {
|
|
260
|
+
await client.deleteWebhook(endpointId).catch(() => undefined);
|
|
261
|
+
}
|
|
262
|
+
throw new Error("Unable to store the one-time webhook secret; the webhook was rolled back.", { cause: error });
|
|
263
|
+
}
|
|
264
|
+
return 0;
|
|
265
|
+
}
|
|
266
|
+
if (resource === "webhooks" && action === "get") {
|
|
267
|
+
printJson(await client.getWebhook(requireIdentifier(firstIdentifier, "Webhook ID")), stdout);
|
|
268
|
+
return 0;
|
|
269
|
+
}
|
|
270
|
+
if (resource === "webhooks" && action === "update") {
|
|
271
|
+
const id = requireIdentifier(firstIdentifier, "Webhook ID");
|
|
272
|
+
const input = await readJson(inputFile(args));
|
|
273
|
+
printJson(await client.updateWebhook(id, input), stdout);
|
|
274
|
+
return 0;
|
|
275
|
+
}
|
|
276
|
+
if (resource === "webhooks" && action === "delete") {
|
|
277
|
+
printJson(await client.deleteWebhook(requireIdentifier(firstIdentifier, "Webhook ID")), stdout);
|
|
278
|
+
return 0;
|
|
279
|
+
}
|
|
280
|
+
throw new Error(`Unknown command.\n\n${HELP}`);
|
|
281
|
+
}
|
|
282
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE9C,OAAO,EACL,aAAa,GAMd,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,qBAAqB,EACrB,aAAa,GAEd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,YAAY,IAAI,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE5D,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,MAAM,IAAI,GAAG,eAAe,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2BlC,CAAC;AAiDF,MAAM,UAAU,GAAqC;IACnD,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,YAAY;IACrB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,sBAAsB;IAC9B,MAAM,EAAE,WAAW;IACnB,OAAO,EAAE,YAAY;CACtB,CAAC;AAEF,SAAS,SAAS,CAAC,IAAc,EAAE,IAAY;IAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAChC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAC9B,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,oBAAoB,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAc,EAAE,IAAY;IACtD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACpD,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI;YAAE,SAAS;QACnC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAC9B,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACrC,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,oBAAoB,CAAC,CAAC;QAC/C,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnB,KAAK,IAAI,CAAC,CAAC;IACb,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,eAAe,CACtB,KAAyB,EACzB,QAAgB,EAChB,IAAY;IAEZ,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,QAAQ,CAAC;IACzC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,8BAA8B,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,QAAQ,CAAI,IAAwB;IACjD,IAAI,CAAC,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IACzD,IAAI,IAAY,CAAC;IACjB,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,kBAAkB,IAAI,GAAG,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAM,CAAC;IAC/B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,qBAAqB,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAClE,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,IAAc;IAC/B,OAAO,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,SAAS,CAAC,KAAc,EAAE,MAAgB;IACjD,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;AAChD,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAyB,EAAE,KAAa;IACjE,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,eAAe,CAAC,CAAC;IAC/E,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,mBAAmB,CAC1B,MAA0B,EAC1B,GAAuC;IAEvC,OAAO,IAAI,aAAa,CAAC;QACvB,MAAM;QACN,OAAO,EAAE,GAAG,CAAC,gBAAgB;KAC9B,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,GAAG,CACvB,IAAc,EACd,UAAsB,EAAE;IAExB,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IACxE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IACxE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;IACvC,MAAM,KAAK,GAAG,OAAO,CAAC,eAAe,IAAI,qBAAqB,EAAE,CAAC;IACjE,MAAM,YAAY,GAChB,OAAO,CAAC,YAAY,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,mBAAmB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;IACzE,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,mBAAmB,CAAC;IAEjE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACxE,MAAM,CAAC,IAAI,CAAC,CAAC;QACb,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACtD,MAAM,CAAC,GAAG,OAAO,IAAI,CAAC,CAAC;QACvB,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,eAAe,EAAE,gBAAgB,CAAC,GAAG,IAAI,CAAC;IAEnE,IAAI,QAAQ,KAAK,MAAM,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;QAC9C,MAAM,MAAM,GAAG,CAAC,MAAM,YAAY,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7C,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnD,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;QAC3E,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;QACpD,MAAM,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACxB,MAAM,CAAC,yDAAyD,CAAC,CAAC;QAClE,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACzB,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,QAAQ,KAAK,MAAM,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/C,MAAM,KAAK,CAAC,MAAM,EAAE,CAAC;QACrB,MAAM,CAAC,sCAAsC,CAAC,CAAC;QAC/C,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IACE,CAAC,QAAQ,KAAK,WAAW,IAAI,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,MAAM,CAAC,CAAC;QACzE,CAAC,QAAQ,KAAK,UAAU,IAAI,MAAM,KAAK,MAAM,CAAC,EAC9C,CAAC;QACD,SAAS,CAAC,MAAM,YAAY,CAAC,SAAS,CAAC,CAAC,aAAa,EAAE,EAAE,MAAM,CAAC,CAAC;QACjE,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,QAAQ,GACZ,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE;QACpB,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,UAAmB,EAAE;QAChE,CAAC,CAAC,MAAM,aAAa,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;IAE1C,IAAI,QAAQ,KAAK,MAAM,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,CAAC,gDAAgD,CAAC,CAAC;YACzD,OAAO,CAAC,CAAC;QACX,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC7D,MAAM,CAAC,qBAAqB,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC;QAClD,SAAS,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACzB,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CACb,2EAA2E,CAC5E,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;IAE7C,IAAI,QAAQ,KAAK,OAAO,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACjD,SAAS,CAAC,MAAM,MAAM,CAAC,QAAQ,EAAE,EAAE,MAAM,CAAC,CAAC;QAC3C,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IACE,CAAC,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,MAAM,CAAC;QAC7C,MAAM,KAAK,QAAQ,EACnB,CAAC;QACD,MAAM,IAAI,GAAG,iBAAiB,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC;QAC7D,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;QAC9C,MAAM,QAAQ,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;QACvC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,+BAA+B,SAAS,IAAI,QAAQ,GAAG,CAAC,CAAC;QAC3E,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;QACrC,SAAS,CACP,MAAM,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE;YAC/B,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC;YACxB,QAAQ;YACR,OAAO,EAAE,OAAO;SACjB,CAAC,EACF,MAAM,CACP,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,QAAQ,KAAK,aAAa,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACtD,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAsB,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QACnE,SAAS,CAAC,MAAM,MAAM,CAAC,oBAAoB,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC;QAC5D,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IACE,QAAQ,KAAK,aAAa;QAC1B,MAAM,KAAK,OAAO;QAClB,eAAe,KAAK,MAAM,EAC1B,CAAC;QACD,MAAM,MAAM,GAAG,iBAAiB,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;QAC9D,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QACrD,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;QAC3C,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC;YAC3B,CAAC,CAAC,MAAM,QAAQ,CAKX,SAAS,CAAC,IAAI,CAAC,CAAC;YACrB,CAAC,CAAC,EAAE,MAAM,EAAE,iBAAiB,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC;QACtD,SAAS,CAAC,MAAM,MAAM,CAAC,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC;QAC1E,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IACE,QAAQ,KAAK,aAAa;QAC1B,MAAM,KAAK,OAAO;QAClB,eAAe,KAAK,OAAO,EAC3B,CAAC;QACD,MAAM,MAAM,GAAG,iBAAiB,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;QAC9D,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QACrD,SAAS,CAAC,MAAM,MAAM,CAAC,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;QACvE,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,QAAQ,KAAK,aAAa,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACvD,MAAM,MAAM,GAAG,iBAAiB,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,OAAO,GAAG,kBAAkB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACnD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAChE,CAAC;QACD,SAAS,CACP,MAAM,MAAM,CAAC,qBAAqB,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,EACjE,MAAM,CACP,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,QAAQ,KAAK,iBAAiB,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC1D,MAAM,KAAK,GAAG,MAAM,QAAQ,CAA0B,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QACvE,SAAS,CAAC,MAAM,MAAM,CAAC,wBAAwB,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC;QAChE,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IACE,CAAC,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,MAAM,CAAC;QAC7C,MAAM,KAAK,KAAK,EAChB,CAAC;QACD,SAAS,CACP,MAAM,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC,EACnE,MAAM,CACP,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IACE,CAAC,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,MAAM,CAAC;QAC7C,MAAM,KAAK,MAAM,EACjB,CAAC;QACD,MAAM,MAAM,GAAG,iBAAiB,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;QAC7D,MAAM,UAAU,GAAG,eAAe,CAChC,SAAS,CAAC,IAAI,EAAE,YAAY,CAAC,EAC7B,KAAK,EACL,YAAY,CACb,CAAC;QACF,MAAM,WAAW,GAAG,eAAe,CACjC,SAAS,CAAC,IAAI,EAAE,YAAY,CAAC,EAC7B,GAAG,EACH,YAAY,CACb,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE;YAC9C,UAAU;YACV,WAAW;YACX,QAAQ,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE;gBAC1B,MAAM,CACJ,IAAI,OAAO,IAAI,WAAW,KAAK,IAAI,CAAC,EAAE,IAAI,MAAM,KAAK,IAAI,CAAC,MAAM,IAAI,CACrE,CAAC;YACJ,CAAC;SACF,CAAC,CAAC;QACH,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC1B,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,QAAQ,KAAK,UAAU,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACjD,SAAS,CAAC,MAAM,MAAM,CAAC,YAAY,EAAE,EAAE,MAAM,CAAC,CAAC;QAC/C,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,QAAQ,KAAK,UAAU,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACnD,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAqB,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAClE,MAAM,QAAQ,GAAG,CAAC,MAAM,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,CAGlD,CAAC;QACF,IAAI,CAAC;YACH,SAAS,CAAC,MAAM,oBAAoB,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QAC/D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,UAAU,GACd,OAAO,QAAQ,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;YAC5D,IAAI,UAAU,EAAE,CAAC;gBACf,MAAM,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YAChE,CAAC;YACD,MAAM,IAAI,KAAK,CACb,2EAA2E,EAC3E,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,QAAQ,KAAK,UAAU,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QAChD,SAAS,CACP,MAAM,MAAM,CAAC,UAAU,CAAC,iBAAiB,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC,EACzE,MAAM,CACP,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,QAAQ,KAAK,UAAU,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACnD,MAAM,EAAE,GAAG,iBAAiB,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC;QAC5D,MAAM,KAAK,GAAG,MAAM,QAAQ,CAAqB,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;QAClE,SAAS,CAAC,MAAM,MAAM,CAAC,aAAa,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC;QACzD,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,QAAQ,KAAK,UAAU,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACnD,SAAS,CACP,MAAM,MAAM,CAAC,aAAa,CACxB,iBAAiB,CAAC,eAAe,EAAE,YAAY,CAAC,CACjD,EACD,MAAM,CACP,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface CredentialStore {
|
|
2
|
+
get(): Promise<string | null>;
|
|
3
|
+
set(apiKey: string): Promise<void>;
|
|
4
|
+
delete(): Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
interface KeychainModule {
|
|
7
|
+
getPassword(service: string, account: string): Promise<string | null>;
|
|
8
|
+
setPassword(service: string, account: string, password: string): Promise<void>;
|
|
9
|
+
deletePassword(service: string, account: string): Promise<unknown>;
|
|
10
|
+
}
|
|
11
|
+
export interface CreateCredentialStoreOptions {
|
|
12
|
+
platform?: NodeJS.Platform | string;
|
|
13
|
+
service?: string;
|
|
14
|
+
account?: string;
|
|
15
|
+
loadKeychain?: (backend: string) => Promise<KeychainModule>;
|
|
16
|
+
}
|
|
17
|
+
export interface ResolveApiKeyOptions {
|
|
18
|
+
env?: Record<string, string | undefined>;
|
|
19
|
+
store: CredentialStore;
|
|
20
|
+
}
|
|
21
|
+
export interface ResolvedApiKey {
|
|
22
|
+
apiKey: string;
|
|
23
|
+
source: "environment" | "credential-store";
|
|
24
|
+
}
|
|
25
|
+
export declare function createCredentialStore(options?: CreateCredentialStoreOptions): CredentialStore;
|
|
26
|
+
export declare function resolveApiKey(options: ResolveApiKeyOptions): Promise<ResolvedApiKey | null>;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=credentials.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,GAAG,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAC9B,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACzB;AAED,UAAU,cAAc;IACtB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACtE,WAAW,CACT,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACpE;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC;CAC7D;AAED,MAAM,WAAW,oBAAoB;IACnC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,KAAK,EAAE,eAAe,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,aAAa,GAAG,kBAAkB,CAAC;CAC5C;AAcD,wBAAgB,qBAAqB,CACnC,OAAO,GAAE,4BAAiC,GACzC,eAAe,CA2BjB;AAED,wBAAsB,aAAa,CACjC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAOhC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const PLATFORM_BACKENDS = {
|
|
2
|
+
darwin: "native-macos",
|
|
3
|
+
linux: "secret-service",
|
|
4
|
+
win32: "windows",
|
|
5
|
+
};
|
|
6
|
+
async function loadNativeKeychain(backend) {
|
|
7
|
+
const keychain = await import("cross-keychain");
|
|
8
|
+
await keychain.useBackend(backend);
|
|
9
|
+
return keychain;
|
|
10
|
+
}
|
|
11
|
+
export function createCredentialStore(options = {}) {
|
|
12
|
+
const platform = options.platform ?? process.platform;
|
|
13
|
+
const backend = PLATFORM_BACKENDS[platform];
|
|
14
|
+
const service = options.service ?? "io.beatapi.cli";
|
|
15
|
+
const account = options.account ?? "default";
|
|
16
|
+
const loadKeychain = options.loadKeychain ?? loadNativeKeychain;
|
|
17
|
+
async function keychain() {
|
|
18
|
+
if (!backend) {
|
|
19
|
+
throw new Error(`Secure credential storage is not available on ${platform}. Set BEATAPI_API_KEY for this session instead.`);
|
|
20
|
+
}
|
|
21
|
+
return loadKeychain(backend);
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
async get() {
|
|
25
|
+
return (await keychain()).getPassword(service, account);
|
|
26
|
+
},
|
|
27
|
+
async set(apiKey) {
|
|
28
|
+
await (await keychain()).setPassword(service, account, apiKey);
|
|
29
|
+
},
|
|
30
|
+
async delete() {
|
|
31
|
+
await (await keychain()).deletePassword(service, account);
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export async function resolveApiKey(options) {
|
|
36
|
+
const envKey = options.env?.BEATAPI_API_KEY?.trim();
|
|
37
|
+
if (envKey)
|
|
38
|
+
return { apiKey: envKey, source: "environment" };
|
|
39
|
+
const storedKey = (await options.store.get())?.trim();
|
|
40
|
+
if (!storedKey)
|
|
41
|
+
return null;
|
|
42
|
+
return { apiKey: storedKey, source: "credential-store" };
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=credentials.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAiCA,MAAM,iBAAiB,GAAqC;IAC1D,MAAM,EAAE,cAAc;IACtB,KAAK,EAAE,gBAAgB;IACvB,KAAK,EAAE,SAAS;CACjB,CAAC;AAEF,KAAK,UAAU,kBAAkB,CAAC,OAAe;IAC/C,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;IAChD,MAAM,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IACnC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,UAAwC,EAAE;IAE1C,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,QAAQ,CAAC;IACtD,MAAM,OAAO,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,gBAAgB,CAAC;IACpD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,SAAS,CAAC;IAC7C,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,kBAAkB,CAAC;IAEhE,KAAK,UAAU,QAAQ;QACrB,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,iDAAiD,QAAQ,iDAAiD,CAC3G,CAAC;QACJ,CAAC;QACD,OAAO,YAAY,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO;QACL,KAAK,CAAC,GAAG;YACP,OAAO,CAAC,MAAM,QAAQ,EAAE,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC1D,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,MAAM;YACd,MAAM,CAAC,MAAM,QAAQ,EAAE,CAAC,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;QACjE,CAAC;QACD,KAAK,CAAC,MAAM;YACV,MAAM,CAAC,MAAM,QAAQ,EAAE,CAAC,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC5D,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,OAA6B;IAE7B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC;IACpD,IAAI,MAAM;QAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;IAE7D,MAAM,SAAS,GAAG,CAAC,MAAM,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC;IACtD,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAC5B,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;AAC3D,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,UAAU,CAAC;AACzD,OAAO,EACL,qBAAqB,EACrB,aAAa,EACb,KAAK,eAAe,EACpB,KAAK,cAAc,GACpB,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,OAAO,EAAmB,MAAM,UAAU,CAAC;AACzD,OAAO,EACL,qBAAqB,EACrB,aAAa,GAGd,MAAM,kBAAkB,CAAC"}
|
package/dist/prompt.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAAA,wBAAsB,YAAY,CAChC,KAAK,SAAsB,GAC1B,OAAO,CAAC,MAAM,CAAC,CA0CjB"}
|
package/dist/prompt.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export async function promptSecret(label = "BeatAPI API key: ") {
|
|
2
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
3
|
+
throw new Error("Interactive login requires a TTY. Set BEATAPI_API_KEY instead.");
|
|
4
|
+
}
|
|
5
|
+
process.stdout.write(label);
|
|
6
|
+
process.stdin.setRawMode(true);
|
|
7
|
+
process.stdin.resume();
|
|
8
|
+
process.stdin.setEncoding("utf8");
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
let value = "";
|
|
11
|
+
const cleanup = () => {
|
|
12
|
+
process.stdin.off("data", onData);
|
|
13
|
+
process.stdin.setRawMode(false);
|
|
14
|
+
process.stdin.pause();
|
|
15
|
+
process.stdout.write("\n");
|
|
16
|
+
};
|
|
17
|
+
const onData = (chunk) => {
|
|
18
|
+
if (chunk === "\u0003") {
|
|
19
|
+
cleanup();
|
|
20
|
+
reject(new Error("Login cancelled."));
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (chunk === "\r" || chunk === "\n") {
|
|
24
|
+
cleanup();
|
|
25
|
+
resolve(value);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (chunk === "\u007f" || chunk === "\b") {
|
|
29
|
+
value = value.slice(0, -1);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (chunk >= " ")
|
|
33
|
+
value += chunk;
|
|
34
|
+
};
|
|
35
|
+
process.stdin.on("data", onData);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=prompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt.js","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,KAAK,GAAG,mBAAmB;IAE3B,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CACb,gEAAgE,CACjE,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC5B,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IAC/B,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;IACvB,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAElC,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC7C,IAAI,KAAK,GAAG,EAAE,CAAC;QAEf,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAClC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YAChC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACtB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC7B,CAAC,CAAC;QAEF,MAAM,MAAM,GAAG,CAAC,KAAa,EAAE,EAAE;YAC/B,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACvB,OAAO,EAAE,CAAC;gBACV,MAAM,CAAC,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC;gBACtC,OAAO;YACT,CAAC;YACD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACrC,OAAO,EAAE,CAAC;gBACV,OAAO,CAAC,KAAK,CAAC,CAAC;gBACf,OAAO;YACT,CAAC;YACD,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACzC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC3B,OAAO;YACT,CAAC;YACD,IAAI,KAAK,IAAI,GAAG;gBAAE,KAAK,IAAI,KAAK,CAAC;QACnC,CAAC,CAAC;QAEF,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook-secrets.d.ts","sourceRoot":"","sources":["../src/webhook-secrets.ts"],"names":[],"mappings":"AAIA,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAuBtD,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,GAAG,GAAE,WAAyB,GAC7B,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAelC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { chmod, mkdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
function secretDirectory(env) {
|
|
5
|
+
if (env.BEATAPI_CONFIG_DIR?.trim()) {
|
|
6
|
+
return resolve(env.BEATAPI_CONFIG_DIR.trim(), "secrets");
|
|
7
|
+
}
|
|
8
|
+
if (process.platform === "win32" && env.APPDATA?.trim()) {
|
|
9
|
+
return resolve(env.APPDATA.trim(), "BeatAPI", "secrets");
|
|
10
|
+
}
|
|
11
|
+
if (env.XDG_CONFIG_HOME?.trim()) {
|
|
12
|
+
return resolve(env.XDG_CONFIG_HOME.trim(), "beatapi", "secrets");
|
|
13
|
+
}
|
|
14
|
+
return resolve(homedir(), ".config", "beatapi", "secrets");
|
|
15
|
+
}
|
|
16
|
+
function secretFilename(endpoint) {
|
|
17
|
+
const id = typeof endpoint.id === "string"
|
|
18
|
+
? endpoint.id.replace(/[^A-Za-z0-9._-]/g, "-")
|
|
19
|
+
: "";
|
|
20
|
+
return `${id || `webhook-${Date.now()}`}.secret`;
|
|
21
|
+
}
|
|
22
|
+
export async function persistWebhookSecret(endpoint, env = process.env) {
|
|
23
|
+
const secret = endpoint.secret;
|
|
24
|
+
if (typeof secret !== "string" || !secret || secret.includes("masked")) {
|
|
25
|
+
throw new Error("BeatAPI did not return a usable one-time webhook secret.");
|
|
26
|
+
}
|
|
27
|
+
const directory = secretDirectory(env);
|
|
28
|
+
await mkdir(directory, { recursive: true, mode: 0o700 });
|
|
29
|
+
await chmod(directory, 0o700);
|
|
30
|
+
const path = resolve(directory, secretFilename(endpoint));
|
|
31
|
+
await writeFile(path, `${secret}\n`, { mode: 0o600, flag: "wx" });
|
|
32
|
+
await chmod(path, 0o600);
|
|
33
|
+
const { secret: _secret, ...safeEndpoint } = endpoint;
|
|
34
|
+
return { ...safeEndpoint, secret_file: path };
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=webhook-secrets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook-secrets.js","sourceRoot":"","sources":["../src/webhook-secrets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,SAAS,eAAe,CAAC,GAAgB;IACvC,IAAI,GAAG,CAAC,kBAAkB,EAAE,IAAI,EAAE,EAAE,CAAC;QACnC,OAAO,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,EAAE,EAAE,SAAS,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;QACxD,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,EAAE,CAAC;QAChC,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,OAAO,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;AAC7D,CAAC;AAED,SAAS,cAAc,CAAC,QAAiC;IACvD,MAAM,EAAE,GACN,OAAO,QAAQ,CAAC,EAAE,KAAK,QAAQ;QAC7B,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC;QAC9C,CAAC,CAAC,EAAE,CAAC;IACT,OAAO,GAAG,EAAE,IAAI,WAAW,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC;AACnD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,QAAiC,EACjC,MAAmB,OAAO,CAAC,GAAG;IAE9B,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;IAC/B,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvE,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC9E,CAAC;IAED,MAAM,SAAS,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACzD,MAAM,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAC9B,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC1D,MAAM,SAAS,CAAC,IAAI,EAAE,GAAG,MAAM,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAClE,MAAM,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAEzB,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,YAAY,EAAE,GAAG,QAAQ,CAAC;IACtD,OAAO,EAAE,GAAG,YAAY,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;AAChD,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "beatapi",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Command-line interface for BeatAPI AI music video and ecommerce video workflows.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"beatapi": "./dist/bin.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"README.md",
|
|
14
|
+
"LICENSE"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "tsc -b",
|
|
18
|
+
"typecheck": "tsc -b --pretty false",
|
|
19
|
+
"test": "tsx --test test/*.test.ts"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"beatapi-client": "0.1.0",
|
|
23
|
+
"cross-keychain": "1.1.0"
|
|
24
|
+
},
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=20.19.0 <21 || >=22.12.0"
|
|
27
|
+
},
|
|
28
|
+
"publishConfig": {
|
|
29
|
+
"access": "public",
|
|
30
|
+
"provenance": true
|
|
31
|
+
},
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "git+https://github.com/BeatAPI/beatapi-cli.git",
|
|
35
|
+
"directory": "packages/cli"
|
|
36
|
+
},
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/BeatAPI/beatapi-cli/issues"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://docs.beatapi.io/",
|
|
41
|
+
"keywords": [
|
|
42
|
+
"beatapi",
|
|
43
|
+
"cli",
|
|
44
|
+
"ai-video",
|
|
45
|
+
"music-video",
|
|
46
|
+
"ecommerce-video",
|
|
47
|
+
"automation"
|
|
48
|
+
],
|
|
49
|
+
"license": "MIT"
|
|
50
|
+
}
|