@getdial/cli 0.33.3 → 0.33.5

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/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { Command } from "commander";
2
+ import { Command, InvalidArgumentError } from "commander";
3
3
  import { VERSION } from "./lib/version.js";
4
4
  import { runDoctor } from "./commands/doctor.js";
5
5
  import { runBilling } from "./commands/billing.js";
@@ -35,6 +35,13 @@ import { isSandbox, SANDBOX_DISABLED_COMMANDS, sandboxDisabledMessage } from "./
35
35
  // keyless so the proxy injects auth. Computed once (memoized in lib/sandbox).
36
36
  const sandbox = isSandbox();
37
37
  const program = new Command();
38
+ function parsePositiveInteger(value) {
39
+ const parsed = Number(value);
40
+ if (!Number.isSafeInteger(parsed) || parsed <= 0 || String(parsed) !== value.trim()) {
41
+ throw new InvalidArgumentError(`must be a positive integer, got: ${value}`);
42
+ }
43
+ return parsed;
44
+ }
38
45
  program
39
46
  .name("dial")
40
47
  .description("Dial CLI — set up your account and run the listen service.")
@@ -327,7 +334,7 @@ if (!sandbox) {
327
334
  .option("--secret <value>", "HMAC-SHA256 key. The daemon signs each request body and sends the hex digest.")
328
335
  .option("--signature-header <name>", "HTTP header for the HMAC signature (defaults to X-Dial-Signature; only used with --secret)")
329
336
  .option("--bearer <token>", "static bearer token, sent as `Authorization: Bearer <token>`")
330
- .option("--timeout <seconds>", "per-attempt timeout (default 5)", (v) => parseInt(v, 10))
337
+ .option("--timeout <seconds>", "per-attempt timeout (default 5)", parsePositiveInteger)
331
338
  .option("--json", "machine-readable output")
332
339
  .action(async (url, opts) => process.exit(await runLocalTargetAddUrl({
333
340
  url,
@@ -340,7 +347,7 @@ if (!sandbox) {
340
347
  localTargetAdd
341
348
  .command("cmd <path> [args...]")
342
349
  .description("Register an executable. The daemon spawns it per event with the event JSON as the final positional argument.")
343
- .option("--timeout <seconds>", "per-attempt timeout (default 5)", (v) => parseInt(v, 10))
350
+ .option("--timeout <seconds>", "per-attempt timeout (default 5)", parsePositiveInteger)
344
351
  .option("--json", "machine-readable output")
345
352
  .passThroughOptions(true)
346
353
  .action(async (path, args, opts) => process.exit(await runLocalTargetAddCmd({
package/dist/lib/api.js CHANGED
@@ -89,7 +89,7 @@ async function apiRequest(method, path, body, apiKey, extraHeaders) {
89
89
  /** POST a multipart/form-data body (file uploads). fetch sets the boundary header itself. */
90
90
  export async function apiPostMultipart(path, form, apiKey) {
91
91
  const url = `${baseUrl()}${path}`;
92
- const headers = applyRefParamsHeader({});
92
+ const headers = applyRefParamsHeader({ "user-agent": USER_AGENT });
93
93
  if (apiKey)
94
94
  headers.authorization = `Bearer ${apiKey}`;
95
95
  try {
@@ -11,13 +11,23 @@ export const UrlTargetSchema = z.object({
11
11
  secret: z.string().optional(),
12
12
  signatureHeader: z.string().optional(),
13
13
  bearer: z.string().optional(),
14
- timeoutSeconds: z.number().int().positive().optional(),
14
+ timeoutSeconds: z
15
+ .number()
16
+ .int()
17
+ .positive()
18
+ .refine(Number.isSafeInteger, "timeout must be a safe integer")
19
+ .optional(),
15
20
  });
16
21
  export const CmdTargetSchema = z.object({
17
22
  kind: z.literal("cmd"),
18
23
  path: z.string(),
19
24
  args: z.array(z.string()).default([]),
20
- timeoutSeconds: z.number().int().positive().optional(),
25
+ timeoutSeconds: z
26
+ .number()
27
+ .int()
28
+ .positive()
29
+ .refine(Number.isSafeInteger, "timeout must be a safe integer")
30
+ .optional(),
21
31
  });
22
32
  export const LocalTargetSchema = z.discriminatedUnion("kind", [UrlTargetSchema, CmdTargetSchema]);
23
33
  const RegistrySchema = z.object({
@@ -66,19 +76,28 @@ export function listTargets() {
66
76
  return readRegistry().targets;
67
77
  }
68
78
  export function addTarget(t) {
69
- if (t.kind === "url") {
70
- assertLoopbackUrl(t.url);
79
+ const parsed = LocalTargetSchema.safeParse(t);
80
+ if (!parsed.success) {
81
+ const timeoutIssue = parsed.error.issues.find((issue) => issue.path[0] === "timeoutSeconds");
82
+ if (timeoutIssue) {
83
+ throw new LocalTargetError("invalid_timeout", "timeout must be a positive integer");
84
+ }
85
+ throw new LocalTargetError("invalid_target", parsed.error.issues[0]?.message ?? "invalid target");
86
+ }
87
+ const target = parsed.data;
88
+ if (target.kind === "url") {
89
+ assertLoopbackUrl(target.url);
71
90
  }
72
91
  else {
73
- if (!t.path)
92
+ if (!target.path)
74
93
  throw new LocalTargetError("invalid_path", "executable path is required");
75
94
  }
76
95
  const reg = readRegistry();
77
- const id = targetId(t);
78
- if (reg.targets.some((existing) => targetId(existing) === id && existing.kind === t.kind)) {
96
+ const id = targetId(target);
97
+ if (reg.targets.some((existing) => targetId(existing) === id && existing.kind === target.kind)) {
79
98
  return { added: false };
80
99
  }
81
- reg.targets.push(t);
100
+ reg.targets.push(target);
82
101
  writeRegistry(reg);
83
102
  return { added: true };
84
103
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getdial/cli",
3
- "version": "0.33.3",
3
+ "version": "0.33.5",
4
4
  "description": "Dial CLI — install, sign up, and run the local listen service.",
5
5
  "license": "MIT",
6
6
  "repository": {
package/skills.tar.gz CHANGED
Binary file