diffusr 0.1.0 → 0.2.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/README.md +42 -1
- package/dist/cli/account.d.ts +19 -0
- package/dist/cli/account.js +250 -0
- package/dist/cli/account.js.map +1 -0
- package/dist/cli/args.d.ts +28 -0
- package/dist/cli/args.js +204 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/format.d.ts +10 -0
- package/dist/cli/format.js +80 -0
- package/dist/cli/format.js.map +1 -0
- package/dist/cli/io.d.ts +32 -0
- package/dist/cli/io.js +56 -0
- package/dist/cli/io.js.map +1 -0
- package/dist/cli/main.d.ts +3 -0
- package/dist/cli/main.js +176 -0
- package/dist/cli/main.js.map +1 -0
- package/dist/cli/ops.d.ts +22 -0
- package/dist/cli/ops.js +367 -0
- package/dist/cli/ops.js.map +1 -0
- package/dist/cli/spec.d.ts +37 -0
- package/dist/cli/spec.js +117 -0
- package/dist/cli/spec.js.map +1 -0
- package/dist/cli/spec.json +4207 -0
- package/dist/cli/test-helpers.d.ts +32 -0
- package/dist/cli/test-helpers.js +70 -0
- package/dist/cli/test-helpers.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +9 -0
- package/dist/cli.js.map +1 -0
- package/dist/client.d.ts +19 -1
- package/dist/client.js +25 -7
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +30 -0
- package/dist/config.js +71 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +10 -5
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@ Mint keys on the Developers page in the app.
|
|
|
17
17
|
```ts
|
|
18
18
|
import { Diffusr } from "diffusr";
|
|
19
19
|
|
|
20
|
-
const diffusr = new Diffusr(); // reads DIFFUSR_KEY
|
|
20
|
+
const diffusr = new Diffusr(); // reads DIFFUSR_KEY, else the key `npx diffusr login` saved
|
|
21
21
|
|
|
22
22
|
// 1. Ask the price. Free: nothing is made, nothing is spent.
|
|
23
23
|
const quote = await diffusr.makeVideo({
|
|
@@ -63,6 +63,47 @@ app.post("/diffusr", express.text({ type: "*/*" }), (req, res) => {
|
|
|
63
63
|
constant-time compare, two signatures after a secret rotation, a 5-minute
|
|
64
64
|
timestamp window, `whsec_` prefix handled.
|
|
65
65
|
|
|
66
|
+
## Command line
|
|
67
|
+
|
|
68
|
+
The package also installs a `diffusr` command. No install needed:
|
|
69
|
+
|
|
70
|
+
```sh
|
|
71
|
+
npx diffusr login # shows a code, opens your browser, saves a key
|
|
72
|
+
npx diffusr make_image "a mug on a sunlit table"
|
|
73
|
+
npx diffusr whoami # who you are, and your balance
|
|
74
|
+
npx diffusr help # every command
|
|
75
|
+
npx diffusr make_video --help # every flag of one command
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Anything that costs credits shows the price first and asks `Make it? [y/N]`.
|
|
79
|
+
It never spends without a yes. A local file works wherever a link is
|
|
80
|
+
expected (`--image-urls ./mug.jpg`): it is uploaded first.
|
|
81
|
+
|
|
82
|
+
For scripts and agents:
|
|
83
|
+
|
|
84
|
+
```sh
|
|
85
|
+
diffusr price make_video "a can of sparkling water" --json # free: just the price
|
|
86
|
+
diffusr make_video "a can of sparkling water" --yes --json # spend, wait, print the result
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
- `--json` prints only the JSON answer on stdout. Errors go to stderr.
|
|
90
|
+
- `--yes` allows spending. Without it, and with no terminal, the command
|
|
91
|
+
exits with code `2` and makes nothing.
|
|
92
|
+
- `--no-wait` starts the job and prints its id. Check it with `diffusr get_result <id>`.
|
|
93
|
+
- `diffusr logout` revokes the saved key and deletes the file.
|
|
94
|
+
|
|
95
|
+
The commands come from the API's own description, so a new API tool shows up
|
|
96
|
+
by itself.
|
|
97
|
+
|
|
98
|
+
**Where the key is saved.** `~/.config/diffusr/config.json` (or
|
|
99
|
+
`$XDG_CONFIG_HOME/diffusr/config.json`; on Windows `%APPDATA%\diffusr\config.json`).
|
|
100
|
+
Only you can read it (mode 0600). The `Diffusr` class and the Python package
|
|
101
|
+
read the same file.
|
|
102
|
+
|
|
103
|
+
**Which key wins.** The `--key` flag or the constructor argument, then the
|
|
104
|
+
`DIFFUSR_KEY` variable, then the saved file. The API address: `--base-url` or
|
|
105
|
+
the `baseUrl` option, then `DIFFUSR_BASE_URL`, then the saved file.
|
|
106
|
+
|
|
66
107
|
## Methods
|
|
67
108
|
|
|
68
109
|
| Method | REST |
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Diffusr } from "../client.js";
|
|
2
|
+
import type { SavedConfig } from "../config.js";
|
|
3
|
+
import type { FlagDef, ParsedArgs } from "./args.js";
|
|
4
|
+
import type { Io } from "./io.js";
|
|
5
|
+
export declare const LOGIN_FLAGS: Map<string, FlagDef>;
|
|
6
|
+
export declare const LOGOUT_FLAGS: Map<string, FlagDef>;
|
|
7
|
+
export declare const WHOAMI_FLAGS: Map<string, FlagDef>;
|
|
8
|
+
export interface Auth {
|
|
9
|
+
key: string | undefined;
|
|
10
|
+
source: "argument" | "env" | "file" | undefined;
|
|
11
|
+
config: SavedConfig | undefined;
|
|
12
|
+
baseUrl: string;
|
|
13
|
+
}
|
|
14
|
+
/** The key (argument, DIFFUSR_KEY, saved file) and the base URL that goes with it. */
|
|
15
|
+
export declare function resolveAuth(io: Io, args: ParsedArgs): Auth;
|
|
16
|
+
export declare function makeClient(io: Io, auth: Auth): Diffusr;
|
|
17
|
+
export declare function login(io: Io, args: ParsedArgs): Promise<number>;
|
|
18
|
+
export declare function whoami(io: Io, args: ParsedArgs): Promise<number>;
|
|
19
|
+
export declare function logout(io: Io, args: ParsedArgs): Promise<number>;
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import { DEFAULT_BASE_URL, Diffusr } from "../client.js";
|
|
2
|
+
import { configPath, deleteConfig, readConfig, resolveKey, writeConfig } from "../config.js";
|
|
3
|
+
import { DiffusrError } from "../errors.js";
|
|
4
|
+
import { flagBool, flagStr } from "./args.js";
|
|
5
|
+
import { credits, formatMe } from "./format.js";
|
|
6
|
+
import { CliError, shouldOpenBrowser } from "./io.js";
|
|
7
|
+
export const LOGIN_FLAGS = new Map([
|
|
8
|
+
["test", true],
|
|
9
|
+
["name", false],
|
|
10
|
+
["force", true],
|
|
11
|
+
["json", true],
|
|
12
|
+
["help", true],
|
|
13
|
+
["version", true],
|
|
14
|
+
["yes", true],
|
|
15
|
+
["base_url", false],
|
|
16
|
+
["key", false],
|
|
17
|
+
].map(([name, boolean]) => [name, { name: name, boolean: boolean }]));
|
|
18
|
+
export const LOGOUT_FLAGS = new Map([
|
|
19
|
+
["revoke_env_key", true],
|
|
20
|
+
["json", true],
|
|
21
|
+
["help", true],
|
|
22
|
+
["version", true],
|
|
23
|
+
["yes", true],
|
|
24
|
+
["base_url", false],
|
|
25
|
+
["key", false],
|
|
26
|
+
].map(([name, boolean]) => [name, { name: name, boolean: boolean }]));
|
|
27
|
+
export const WHOAMI_FLAGS = LOGOUT_FLAGS;
|
|
28
|
+
const MISSING_KEY = "Pass an API key, set DIFFUSR_KEY, or run `npx diffusr login`.";
|
|
29
|
+
const trim = (u) => u.replace(/\/+$/, "");
|
|
30
|
+
/** The key (argument, DIFFUSR_KEY, saved file) and the base URL that goes with it. */
|
|
31
|
+
export function resolveAuth(io, args) {
|
|
32
|
+
const found = resolveKey(flagStr(args, "key"), io.env, io.platform);
|
|
33
|
+
const fileBase = found?.source === "file" ? found.config?.base_url : undefined;
|
|
34
|
+
const baseUrl = trim(flagStr(args, "base_url") || io.env.DIFFUSR_BASE_URL || fileBase || DEFAULT_BASE_URL);
|
|
35
|
+
return { key: found?.key, source: found?.source, config: found?.config, baseUrl };
|
|
36
|
+
}
|
|
37
|
+
export function makeClient(io, auth) {
|
|
38
|
+
if (!auth.key)
|
|
39
|
+
throw new DiffusrError({ status: 0, code: "MISSING_API_KEY", message: MISSING_KEY });
|
|
40
|
+
return new Diffusr(auth.key, { baseUrl: auth.baseUrl, fetch: io.fetch });
|
|
41
|
+
}
|
|
42
|
+
function describeSource(io, auth) {
|
|
43
|
+
if (auth.source === "argument")
|
|
44
|
+
return "the --key flag";
|
|
45
|
+
if (auth.source === "env")
|
|
46
|
+
return "DIFFUSR_KEY";
|
|
47
|
+
return `the saved file ${configPath(io.env, io.platform)}`;
|
|
48
|
+
}
|
|
49
|
+
// ——— plain JSON calls with no key (login) ———
|
|
50
|
+
async function postJson(io, url, body) {
|
|
51
|
+
let res;
|
|
52
|
+
try {
|
|
53
|
+
res = await io.fetch(url, {
|
|
54
|
+
method: "POST",
|
|
55
|
+
headers: { "Content-Type": "application/json", Accept: "application/json", "User-Agent": "diffusr-cli" },
|
|
56
|
+
body: JSON.stringify(body),
|
|
57
|
+
signal: AbortSignal.timeout(20_000),
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
catch (cause) {
|
|
61
|
+
throw new DiffusrError({ status: 0, code: "NETWORK_ERROR", message: `Could not reach diffusr: ${cause.message}` });
|
|
62
|
+
}
|
|
63
|
+
const text = await res.text().catch(() => "");
|
|
64
|
+
let parsed = {};
|
|
65
|
+
try {
|
|
66
|
+
const p = JSON.parse(text);
|
|
67
|
+
if (p && typeof p === "object")
|
|
68
|
+
parsed = p;
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
/* not JSON */
|
|
72
|
+
}
|
|
73
|
+
if (!text || Object.keys(parsed).length === 0)
|
|
74
|
+
parsed = { error: text.slice(0, 300) || `HTTP ${res.status}` };
|
|
75
|
+
return { status: res.status, body: parsed };
|
|
76
|
+
}
|
|
77
|
+
function toDiffusrError(status, body) {
|
|
78
|
+
return new DiffusrError({
|
|
79
|
+
status,
|
|
80
|
+
code: typeof body.code === "string" ? body.code : `HTTP_${status}`,
|
|
81
|
+
message: typeof body.error === "string" ? body.error : `HTTP ${status}`,
|
|
82
|
+
requestId: typeof body.request_id === "string" ? body.request_id : undefined,
|
|
83
|
+
retryAfter: typeof body.retry_after_seconds === "number" ? body.retry_after_seconds : undefined,
|
|
84
|
+
body,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
// ——— login ———
|
|
88
|
+
function limitWords(a) {
|
|
89
|
+
if (typeof a.monthly_limit_credits === "number")
|
|
90
|
+
return `limit ${credits(a.monthly_limit_credits)} a month`;
|
|
91
|
+
if (typeof a.daily_limit_credits === "number")
|
|
92
|
+
return `limit ${credits(a.daily_limit_credits)} a day`;
|
|
93
|
+
return "no limit";
|
|
94
|
+
}
|
|
95
|
+
export async function login(io, args) {
|
|
96
|
+
const json = flagBool(args, "json");
|
|
97
|
+
const say = (l) => (json ? io.err(l) : io.out(l));
|
|
98
|
+
const existing = readConfig(io.env, io.platform);
|
|
99
|
+
if (existing && !flagBool(args, "force")) {
|
|
100
|
+
io.err(`Already signed in as ${existing.email ?? "this account"}${existing.key_name ? ` (${existing.mode ?? "live"} key "${existing.key_name}")` : ""}. Run diffusr logout first, or diffusr login --force.`);
|
|
101
|
+
return 1;
|
|
102
|
+
}
|
|
103
|
+
const base = trim(flagStr(args, "base_url") || io.env.DIFFUSR_BASE_URL || DEFAULT_BASE_URL);
|
|
104
|
+
const mode = flagBool(args, "test") ? "test" : "live";
|
|
105
|
+
const started = await postJson(io, `${base}/cli/logins`, { device_name: flagStr(args, "name") || io.hostname, mode });
|
|
106
|
+
if (started.status < 200 || started.status >= 300)
|
|
107
|
+
throw toDiffusrError(started.status, started.body);
|
|
108
|
+
const s = started.body;
|
|
109
|
+
const loginId = String(s.login_id ?? "");
|
|
110
|
+
const pollToken = String(s.poll_token ?? "");
|
|
111
|
+
const code = String(s.code ?? "");
|
|
112
|
+
const verifyUrl = String(s.verify_url ?? "");
|
|
113
|
+
if (!loginId || !pollToken)
|
|
114
|
+
throw new CliError("diffusr sent back an answer this version does not understand. Update with: npm i -g diffusr");
|
|
115
|
+
say(`Your code: ${code.replace(/^(\d{3})(\d+)$/, "$1 $2")}`);
|
|
116
|
+
say(`Open ${verifyUrl}`);
|
|
117
|
+
say("and press Yes, connect.");
|
|
118
|
+
say("");
|
|
119
|
+
say("Waiting…");
|
|
120
|
+
if (shouldOpenBrowser(io.env, io.platform) && verifyUrl)
|
|
121
|
+
io.openUrl(verifyUrl);
|
|
122
|
+
const expiresAt = io.now() + (typeof s.expires_in === "number" ? s.expires_in : 600) * 1000;
|
|
123
|
+
const intervalMs = Math.max(1, typeof s.interval === "number" ? s.interval : 3) * 1000;
|
|
124
|
+
while (io.now() < expiresAt) {
|
|
125
|
+
await io.sleep(intervalMs);
|
|
126
|
+
const r = await postJson(io, `${base}/cli/logins/${encodeURIComponent(loginId)}/token`, { poll_token: pollToken });
|
|
127
|
+
if (r.status === 429) {
|
|
128
|
+
const wait = typeof r.body.retry_after_seconds === "number" ? r.body.retry_after_seconds * 1000 : intervalMs;
|
|
129
|
+
await io.sleep(wait);
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (r.status === 404)
|
|
133
|
+
throw new CliError("This login was not found. Run diffusr login again.");
|
|
134
|
+
if (r.status >= 500)
|
|
135
|
+
continue;
|
|
136
|
+
if (r.status >= 400)
|
|
137
|
+
throw toDiffusrError(r.status, r.body);
|
|
138
|
+
const a = r.body;
|
|
139
|
+
switch (a.status) {
|
|
140
|
+
case "approved": {
|
|
141
|
+
const cfg = {
|
|
142
|
+
key: String(a.key),
|
|
143
|
+
key_id: String(a.key_id ?? ""),
|
|
144
|
+
key_name: String(a.key_name ?? ""),
|
|
145
|
+
mode: a.mode === "test" ? "test" : "live",
|
|
146
|
+
email: String(a.email ?? ""),
|
|
147
|
+
...(base !== DEFAULT_BASE_URL ? { base_url: base } : {}),
|
|
148
|
+
saved_at: new Date(io.now()).toISOString(),
|
|
149
|
+
};
|
|
150
|
+
const file = writeConfig(cfg, io.env, io.platform);
|
|
151
|
+
// --force replaced a saved key: revoke it so no live key is left behind.
|
|
152
|
+
if (existing && existing.key !== cfg.key)
|
|
153
|
+
await revokeQuietly(io, existing);
|
|
154
|
+
if (json) {
|
|
155
|
+
io.out(JSON.stringify({ connected: true, email: cfg.email, key_id: cfg.key_id, key_name: cfg.key_name, mode: cfg.mode, config_path: file }, null, 2));
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
io.out(`✓ Connected as ${cfg.email} (${cfg.mode} key "${cfg.key_name}", ${limitWords(a)})`);
|
|
159
|
+
io.out("");
|
|
160
|
+
io.out('Try: diffusr make_image "a mug on a sunlit table"');
|
|
161
|
+
}
|
|
162
|
+
if (io.env.DIFFUSR_KEY)
|
|
163
|
+
io.err("Note: DIFFUSR_KEY is set in this shell, and it wins over the saved key.");
|
|
164
|
+
return 0;
|
|
165
|
+
}
|
|
166
|
+
case "denied":
|
|
167
|
+
throw new CliError("Cancelled in the browser.");
|
|
168
|
+
case "expired":
|
|
169
|
+
throw new CliError("The code expired. Run diffusr login again.");
|
|
170
|
+
case "failed":
|
|
171
|
+
throw new CliError(typeof a.error === "string" ? a.error : "The login failed. Run diffusr login again.");
|
|
172
|
+
default:
|
|
173
|
+
break; // pending
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
throw new CliError("The code expired. Run diffusr login again.");
|
|
177
|
+
}
|
|
178
|
+
/** Best effort: revoke a key we no longer keep. A failure only warns. */
|
|
179
|
+
async function revokeQuietly(io, old) {
|
|
180
|
+
try {
|
|
181
|
+
await new Diffusr(old.key, { baseUrl: trim(old.base_url || DEFAULT_BASE_URL), fetch: io.fetch, maxRetries: 1 }).call("POST", "/cli/logout", { body: {} });
|
|
182
|
+
}
|
|
183
|
+
catch (e) {
|
|
184
|
+
if (e instanceof DiffusrError && e.status === 401)
|
|
185
|
+
return; // already gone
|
|
186
|
+
io.err(`Note: the old key "${old.key_name ?? "CLI"}" could not be revoked. Revoke it on the Developers page.`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// ——— whoami ———
|
|
190
|
+
export async function whoami(io, args) {
|
|
191
|
+
const auth = resolveAuth(io, args);
|
|
192
|
+
const client = makeClient(io, auth);
|
|
193
|
+
const me = await client.call("GET", "/me");
|
|
194
|
+
if (flagBool(args, "json")) {
|
|
195
|
+
io.out(JSON.stringify(me, null, 2));
|
|
196
|
+
return 0;
|
|
197
|
+
}
|
|
198
|
+
for (const l of formatMe(me))
|
|
199
|
+
io.out(l);
|
|
200
|
+
io.out(`Key from ${describeSource(io, auth)}`);
|
|
201
|
+
return 0;
|
|
202
|
+
}
|
|
203
|
+
// ——— logout ———
|
|
204
|
+
export async function logout(io, args) {
|
|
205
|
+
const json = flagBool(args, "json");
|
|
206
|
+
const auth = resolveAuth(io, args);
|
|
207
|
+
const saved = readConfig(io.env, io.platform);
|
|
208
|
+
const revokeEnv = flagBool(args, "revoke_env_key");
|
|
209
|
+
const envSet = Boolean(io.env.DIFFUSR_KEY);
|
|
210
|
+
let key;
|
|
211
|
+
let name;
|
|
212
|
+
let base = auth.baseUrl;
|
|
213
|
+
if (saved) {
|
|
214
|
+
key = saved.key;
|
|
215
|
+
name = saved.key_name;
|
|
216
|
+
base = trim(flagStr(args, "base_url") || io.env.DIFFUSR_BASE_URL || saved.base_url || DEFAULT_BASE_URL);
|
|
217
|
+
}
|
|
218
|
+
else if (revokeEnv && auth.key) {
|
|
219
|
+
key = auth.key;
|
|
220
|
+
}
|
|
221
|
+
if (!key) {
|
|
222
|
+
const msg = auth.key ? `Nothing saved to sign out of. The key from ${describeSource(io, auth)} was left alone (add --revoke-env-key to revoke it).` : "You are not signed in. Nothing is saved.";
|
|
223
|
+
if (json)
|
|
224
|
+
io.out(JSON.stringify({ revoked: false, message: msg }));
|
|
225
|
+
else
|
|
226
|
+
io.out(msg);
|
|
227
|
+
return 0;
|
|
228
|
+
}
|
|
229
|
+
try {
|
|
230
|
+
await new Diffusr(key, { baseUrl: base, fetch: io.fetch }).call("POST", "/cli/logout", { body: {} });
|
|
231
|
+
}
|
|
232
|
+
catch (e) {
|
|
233
|
+
// A 401 means the key is already gone: that is what we wanted.
|
|
234
|
+
if (!(e instanceof DiffusrError && e.status === 401))
|
|
235
|
+
throw e;
|
|
236
|
+
}
|
|
237
|
+
if (saved)
|
|
238
|
+
deleteConfig(io.env, io.platform);
|
|
239
|
+
const label = name ? `The key "${name}"` : "The key";
|
|
240
|
+
if (json)
|
|
241
|
+
io.out(JSON.stringify({ revoked: true, key_name: name ?? null }));
|
|
242
|
+
else
|
|
243
|
+
io.out(`Signed out. ${label} is revoked.`);
|
|
244
|
+
if (envSet && io.env.DIFFUSR_KEY !== key)
|
|
245
|
+
io.err("Note: DIFFUSR_KEY is still set in this shell.");
|
|
246
|
+
else if (envSet)
|
|
247
|
+
io.err("Note: DIFFUSR_KEY is still set in this shell, but that key no longer works.");
|
|
248
|
+
return 0;
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=account.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account.js","sourceRoot":"","sources":["../../src/cli/account.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Json } from "./spec.js";
|
|
2
|
+
export declare function schemaType(s: Json): string | undefined;
|
|
3
|
+
export declare const flagName: (prop: string) => string;
|
|
4
|
+
/** "string", "integer", "a|b", "string[]", "json". */
|
|
5
|
+
export declare function describeType(s: Json): string;
|
|
6
|
+
export declare function readAt(path: string, flag: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* Turn the raw values of one flag into the JSON value its schema wants.
|
|
9
|
+
* `raws` has one entry per time the flag was given.
|
|
10
|
+
*/
|
|
11
|
+
export declare function coerceFlag(s: Json, raws: string[], flag: string): unknown;
|
|
12
|
+
export interface FlagDef {
|
|
13
|
+
/** Property name, snake_case. */
|
|
14
|
+
name: string;
|
|
15
|
+
boolean: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface ParsedArgs {
|
|
18
|
+
positionals: string[];
|
|
19
|
+
/** Flag (snake_case) -> every value given. Booleans hold "true"/"false". */
|
|
20
|
+
flags: Map<string, string[]>;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Split argv into positionals and flags. `known` says which flags exist and
|
|
24
|
+
* whether they take a value; anything else is an error.
|
|
25
|
+
*/
|
|
26
|
+
export declare function parseArgs(argv: string[], known: Map<string, FlagDef>, helpHint: string): ParsedArgs;
|
|
27
|
+
export declare function flagBool(p: ParsedArgs, name: string): boolean;
|
|
28
|
+
export declare function flagStr(p: ParsedArgs, name: string): string | undefined;
|
package/dist/cli/args.js
ADDED
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { CliError } from "./io.js";
|
|
3
|
+
export function schemaType(s) {
|
|
4
|
+
if (typeof s.type === "string")
|
|
5
|
+
return s.type;
|
|
6
|
+
if (Array.isArray(s.type))
|
|
7
|
+
return s.type.find((t) => t !== "null");
|
|
8
|
+
for (const k of ["anyOf", "oneOf"]) {
|
|
9
|
+
const list = s[k];
|
|
10
|
+
if (Array.isArray(list)) {
|
|
11
|
+
for (const sub of list) {
|
|
12
|
+
const t = schemaType(sub);
|
|
13
|
+
if (t && t !== "null")
|
|
14
|
+
return t;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
if (Array.isArray(s.enum))
|
|
19
|
+
return "string";
|
|
20
|
+
if ("const" in s)
|
|
21
|
+
return typeof s.const;
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
export const flagName = (prop) => "--" + prop.replace(/_/g, "-");
|
|
25
|
+
/** "string", "integer", "a|b", "string[]", "json". */
|
|
26
|
+
export function describeType(s) {
|
|
27
|
+
if (Array.isArray(s.enum))
|
|
28
|
+
return s.enum.join("|");
|
|
29
|
+
const t = schemaType(s);
|
|
30
|
+
if (t === "array") {
|
|
31
|
+
const items = (s.items ?? {});
|
|
32
|
+
return schemaType(items) === "object" ? "json[]" : `${describeType(items)}[]`;
|
|
33
|
+
}
|
|
34
|
+
if (t === "object")
|
|
35
|
+
return "json";
|
|
36
|
+
return t ?? "value";
|
|
37
|
+
}
|
|
38
|
+
function fromJsonArg(raw, flag) {
|
|
39
|
+
const text = raw.startsWith("@") ? readAt(raw.slice(1), flag) : raw;
|
|
40
|
+
try {
|
|
41
|
+
return JSON.parse(text);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
throw new CliError(`${flag} needs JSON${raw.startsWith("@") ? ` (the file ${raw.slice(1)} is not valid JSON)` : ""}.`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export function readAt(path, flag) {
|
|
48
|
+
try {
|
|
49
|
+
return readFileSync(path, "utf8");
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
throw new CliError(`${flag}: cannot read the file ${path}.`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function scalar(s, raw, flag) {
|
|
56
|
+
const t = schemaType(s);
|
|
57
|
+
let v = raw;
|
|
58
|
+
if (t === "integer") {
|
|
59
|
+
if (!/^-?\d+$/.test(raw.trim()))
|
|
60
|
+
throw new CliError(`${flag} needs a whole number, not "${raw}".`);
|
|
61
|
+
v = Number(raw);
|
|
62
|
+
}
|
|
63
|
+
else if (t === "number") {
|
|
64
|
+
if (raw.trim() === "" || !Number.isFinite(Number(raw)))
|
|
65
|
+
throw new CliError(`${flag} needs a number, not "${raw}".`);
|
|
66
|
+
v = Number(raw);
|
|
67
|
+
}
|
|
68
|
+
else if (t === "boolean") {
|
|
69
|
+
if (/^(true|yes|1)$/i.test(raw))
|
|
70
|
+
v = true;
|
|
71
|
+
else if (/^(false|no|0)$/i.test(raw))
|
|
72
|
+
v = false;
|
|
73
|
+
else
|
|
74
|
+
throw new CliError(`${flag} needs true or false, not "${raw}".`);
|
|
75
|
+
}
|
|
76
|
+
if (Array.isArray(s.enum) && !s.enum.includes(v)) {
|
|
77
|
+
throw new CliError(`${flag} must be one of: ${s.enum.join(", ")} (not "${raw}").`);
|
|
78
|
+
}
|
|
79
|
+
return v;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Turn the raw values of one flag into the JSON value its schema wants.
|
|
83
|
+
* `raws` has one entry per time the flag was given.
|
|
84
|
+
*/
|
|
85
|
+
export function coerceFlag(s, raws, flag) {
|
|
86
|
+
const t = schemaType(s);
|
|
87
|
+
if (t === "array") {
|
|
88
|
+
const items = (s.items ?? {});
|
|
89
|
+
const out = [];
|
|
90
|
+
for (const raw of raws) {
|
|
91
|
+
const trimmed = raw.trim();
|
|
92
|
+
if (trimmed.startsWith("[") || trimmed.startsWith("@")) {
|
|
93
|
+
const v = fromJsonArg(trimmed, flag);
|
|
94
|
+
if (!Array.isArray(v))
|
|
95
|
+
throw new CliError(`${flag} needs a JSON list.`);
|
|
96
|
+
out.push(...v);
|
|
97
|
+
}
|
|
98
|
+
else if (schemaType(items) === "object") {
|
|
99
|
+
out.push(fromJsonArg(trimmed, flag));
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
for (const part of trimmed.split(","))
|
|
103
|
+
if (part.trim() !== "")
|
|
104
|
+
out.push(scalar(items, part.trim(), flag));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return out;
|
|
108
|
+
}
|
|
109
|
+
const raw = raws[raws.length - 1] ?? "";
|
|
110
|
+
if (t === "object") {
|
|
111
|
+
const trimmed = raw.trim();
|
|
112
|
+
if (trimmed.startsWith("{") || trimmed.startsWith("@"))
|
|
113
|
+
return fromJsonArg(trimmed, flag);
|
|
114
|
+
// name=value pairs for a map of strings, e.g. --pictures him=./a.jpg
|
|
115
|
+
const obj = {};
|
|
116
|
+
for (const r of raws) {
|
|
117
|
+
const i = r.indexOf("=");
|
|
118
|
+
if (i <= 0)
|
|
119
|
+
throw new CliError(`${flag} needs JSON, or name=value pairs.`);
|
|
120
|
+
obj[r.slice(0, i)] = r.slice(i + 1);
|
|
121
|
+
}
|
|
122
|
+
return obj;
|
|
123
|
+
}
|
|
124
|
+
if (t === undefined) {
|
|
125
|
+
try {
|
|
126
|
+
return JSON.parse(raw);
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return raw;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return scalar(s, raw, flag);
|
|
133
|
+
}
|
|
134
|
+
const SHORT = { y: "yes", h: "help", v: "version" };
|
|
135
|
+
/**
|
|
136
|
+
* Split argv into positionals and flags. `known` says which flags exist and
|
|
137
|
+
* whether they take a value; anything else is an error.
|
|
138
|
+
*/
|
|
139
|
+
export function parseArgs(argv, known, helpHint) {
|
|
140
|
+
const positionals = [];
|
|
141
|
+
const flags = new Map();
|
|
142
|
+
const add = (k, v) => flags.set(k, [...(flags.get(k) ?? []), v]);
|
|
143
|
+
for (let i = 0; i < argv.length; i++) {
|
|
144
|
+
const tok = argv[i];
|
|
145
|
+
if (tok === "--") {
|
|
146
|
+
positionals.push(...argv.slice(i + 1));
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
let name;
|
|
150
|
+
let inline;
|
|
151
|
+
if (tok.startsWith("--")) {
|
|
152
|
+
const eq = tok.indexOf("=");
|
|
153
|
+
name = (eq === -1 ? tok.slice(2) : tok.slice(2, eq)).replace(/-/g, "_");
|
|
154
|
+
if (eq !== -1)
|
|
155
|
+
inline = tok.slice(eq + 1);
|
|
156
|
+
}
|
|
157
|
+
else if (/^-[a-z]$/i.test(tok) && SHORT[tok[1].toLowerCase()]) {
|
|
158
|
+
name = SHORT[tok[1].toLowerCase()];
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
positionals.push(tok);
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
let def = known.get(name);
|
|
165
|
+
let negated = false;
|
|
166
|
+
if (!def && name.startsWith("no_")) {
|
|
167
|
+
const base = known.get(name.slice(3));
|
|
168
|
+
if (base?.boolean) {
|
|
169
|
+
def = base;
|
|
170
|
+
negated = true;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
if (!def)
|
|
174
|
+
throw new CliError(`Unknown flag --${name.replace(/_/g, "-")}. ${helpHint}`);
|
|
175
|
+
if (def.boolean) {
|
|
176
|
+
let v = negated ? "false" : "true";
|
|
177
|
+
if (inline !== undefined)
|
|
178
|
+
v = inline;
|
|
179
|
+
else if (!negated && argv[i + 1] !== undefined && /^(true|false)$/i.test(argv[i + 1]))
|
|
180
|
+
v = argv[++i];
|
|
181
|
+
add(def.name, v);
|
|
182
|
+
}
|
|
183
|
+
else if (inline !== undefined) {
|
|
184
|
+
add(def.name, inline);
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
const next = argv[i + 1];
|
|
188
|
+
if (next === undefined)
|
|
189
|
+
throw new CliError(`${flagName(def.name)} needs a value.`);
|
|
190
|
+
add(def.name, next);
|
|
191
|
+
i++;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return { positionals, flags };
|
|
195
|
+
}
|
|
196
|
+
export function flagBool(p, name) {
|
|
197
|
+
const v = p.flags.get(name);
|
|
198
|
+
return v !== undefined && /^(true|1|yes)$/i.test(v[v.length - 1]);
|
|
199
|
+
}
|
|
200
|
+
export function flagStr(p, name) {
|
|
201
|
+
const v = p.flags.get(name);
|
|
202
|
+
return v?.[v.length - 1];
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=args.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** "✦ 1,240.00": always two decimals, like the app. */
|
|
2
|
+
export declare function credits(n: number | string): string;
|
|
3
|
+
export declare function errorLine(e: unknown): string;
|
|
4
|
+
export declare function wrap(text: string, width: number, indent: string): string;
|
|
5
|
+
/** Quote in credits from a make or dry-run answer. */
|
|
6
|
+
export declare function priceCredits(answer: unknown): number | undefined;
|
|
7
|
+
export declare function outputUrls(result: unknown): string[];
|
|
8
|
+
export declare function chargedCredits(result: unknown): number | undefined;
|
|
9
|
+
export declare function formatMe(me: unknown): string[];
|
|
10
|
+
export declare function formatResult(r: unknown): string[];
|