@wuapidev/cli 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.
Files changed (95) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +84 -0
  3. package/dist/args.d.ts +17 -0
  4. package/dist/args.d.ts.map +1 -0
  5. package/dist/args.js +96 -0
  6. package/dist/args.js.map +1 -0
  7. package/dist/cli.d.ts +3 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +7 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/context.d.ts +45 -0
  12. package/dist/context.d.ts.map +1 -0
  13. package/dist/context.js +120 -0
  14. package/dist/context.js.map +1 -0
  15. package/dist/credentials.d.ts +31 -0
  16. package/dist/credentials.d.ts.map +1 -0
  17. package/dist/credentials.js +90 -0
  18. package/dist/credentials.js.map +1 -0
  19. package/dist/dialcodes.d.ts +5 -0
  20. package/dist/dialcodes.d.ts.map +1 -0
  21. package/dist/dialcodes.js +51 -0
  22. package/dist/dialcodes.js.map +1 -0
  23. package/dist/dispatch.d.ts +37 -0
  24. package/dist/dispatch.d.ts.map +1 -0
  25. package/dist/dispatch.js +225 -0
  26. package/dist/dispatch.js.map +1 -0
  27. package/dist/dotenv.d.ts +7 -0
  28. package/dist/dotenv.d.ts.map +1 -0
  29. package/dist/dotenv.js +67 -0
  30. package/dist/dotenv.js.map +1 -0
  31. package/dist/errors.d.ts +24 -0
  32. package/dist/errors.d.ts.map +1 -0
  33. package/dist/errors.js +41 -0
  34. package/dist/errors.js.map +1 -0
  35. package/dist/files.d.ts +4 -0
  36. package/dist/files.d.ts.map +1 -0
  37. package/dist/files.js +35 -0
  38. package/dist/files.js.map +1 -0
  39. package/dist/generated/operations.d.ts +3 -0
  40. package/dist/generated/operations.d.ts.map +1 -0
  41. package/dist/generated/operations.js +4462 -0
  42. package/dist/generated/operations.js.map +1 -0
  43. package/dist/help.d.ts +13 -0
  44. package/dist/help.d.ts.map +1 -0
  45. package/dist/help.js +176 -0
  46. package/dist/help.js.map +1 -0
  47. package/dist/index.d.ts +8 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +8 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/io.d.ts +35 -0
  52. package/dist/io.d.ts.map +1 -0
  53. package/dist/io.js +103 -0
  54. package/dist/io.js.map +1 -0
  55. package/dist/link.d.ts +26 -0
  56. package/dist/link.d.ts.map +1 -0
  57. package/dist/link.js +226 -0
  58. package/dist/link.js.map +1 -0
  59. package/dist/login.d.ts +30 -0
  60. package/dist/login.d.ts.map +1 -0
  61. package/dist/login.js +224 -0
  62. package/dist/login.js.map +1 -0
  63. package/dist/main.d.ts +3 -0
  64. package/dist/main.d.ts.map +1 -0
  65. package/dist/main.js +88 -0
  66. package/dist/main.js.map +1 -0
  67. package/dist/mcp.d.ts +3 -0
  68. package/dist/mcp.d.ts.map +1 -0
  69. package/dist/mcp.js +127 -0
  70. package/dist/mcp.js.map +1 -0
  71. package/dist/operation.d.ts +32 -0
  72. package/dist/operation.d.ts.map +1 -0
  73. package/dist/operation.js +3 -0
  74. package/dist/operation.js.map +1 -0
  75. package/dist/paths.d.ts +12 -0
  76. package/dist/paths.d.ts.map +1 -0
  77. package/dist/paths.js +27 -0
  78. package/dist/paths.js.map +1 -0
  79. package/dist/profiles.d.ts +6 -0
  80. package/dist/profiles.d.ts.map +1 -0
  81. package/dist/profiles.js +119 -0
  82. package/dist/profiles.js.map +1 -0
  83. package/dist/qr.d.ts +19 -0
  84. package/dist/qr.d.ts.map +1 -0
  85. package/dist/qr.js +198 -0
  86. package/dist/qr.js.map +1 -0
  87. package/dist/send.d.ts +3 -0
  88. package/dist/send.d.ts.map +1 -0
  89. package/dist/send.js +73 -0
  90. package/dist/send.js.map +1 -0
  91. package/dist/version.d.ts +3 -0
  92. package/dist/version.d.ts.map +1 -0
  93. package/dist/version.js +3 -0
  94. package/dist/version.js.map +1 -0
  95. package/package.json +61 -0
package/dist/send.js ADDED
@@ -0,0 +1,73 @@
1
+ // `wuapi send <to> <text>`: queue a text message. One idempotency key per
2
+ // command, reused on every retry (the SDK's and ours), so a request cut off
3
+ // midway is replayed by the API instead of sent twice.
4
+ import { randomUUID } from "node:crypto";
5
+ import { allowOnly, boolFlag, numberFlag, stringFlag } from "./args.js";
6
+ import { emit, log, makeClient } from "./context.js";
7
+ import { CliError, usage } from "./errors.js";
8
+ import { isTransient } from "./link.js";
9
+ const POLL_MS = 2_000;
10
+ const SEND_ATTEMPTS = 3;
11
+ const DONE = new Set(["sent", "delivered", "read", "played"]);
12
+ async function pickAccount(ctx, client) {
13
+ const { items } = await client.accounts.list({ limit: 100 }).page();
14
+ const ready = items.filter((a) => a.status === "ready");
15
+ if (ready.length === 1) {
16
+ log(ctx, `wuapi: sending from ${ready[0].id}${ready[0].phone ? ` (${ready[0].phone})` : ""}`);
17
+ return ready[0].id;
18
+ }
19
+ if (ready.length === 0) {
20
+ throw new CliError("no_ready_account", items.length ? "No account is ready to send. Check `wuapi accounts list`." : "No linked number yet. Run `wuapi link` first.");
21
+ }
22
+ throw new CliError("account_required", `Several accounts are ready: pass --account <id> (${ready.map((a) => a.id).join(", ")}).`, {
23
+ exitCode: 2,
24
+ details: { accounts: ready.map((a) => ({ id: a.id, phone: a.phone, name: a.name })) },
25
+ });
26
+ }
27
+ export async function send(ctx) {
28
+ allowOnly(ctx.args, ["account", "accountId", "wait", "timeout", "idempotency-key"]);
29
+ const [, to, text, ...rest] = ctx.args.positionals;
30
+ if (!to || text === undefined || rest.length)
31
+ throw usage('Usage: wuapi send <to> <text> [--account <id>] [--wait] (quote the text: "Hello there")');
32
+ const client = makeClient(ctx);
33
+ const accountId = stringFlag(ctx.args, "account") ?? stringFlag(ctx.args, "accountId") ?? (await pickAccount(ctx, client));
34
+ const idempotencyKey = stringFlag(ctx.args, "idempotency-key") ?? randomUUID();
35
+ let message;
36
+ for (let attempt = 1; !message; attempt++) {
37
+ try {
38
+ message = await client.messages.send({ accountId, to, text }, { idempotencyKey });
39
+ }
40
+ catch (e) {
41
+ if (!isTransient(e) || attempt >= SEND_ATTEMPTS)
42
+ throw e;
43
+ log(ctx, `wuapi: ${e.message} Retrying with the same idempotency key...`);
44
+ await ctx.io.sleep(1000 * attempt);
45
+ }
46
+ }
47
+ if (boolFlag(ctx.args, "wait")) {
48
+ const deadline = ctx.io.now() + numberFlag(ctx.args, "timeout", 120) * 1000;
49
+ while (!DONE.has(message.status) && message.status !== "failed") {
50
+ if (ctx.io.now() + POLL_MS > deadline) {
51
+ throw new CliError("wait_timeout", `Message ${message.id} is still ${message.status}. Check it later: wuapi messages get ${message.id}`, {
52
+ details: { messageId: message.id, status: message.status },
53
+ });
54
+ }
55
+ await ctx.io.sleep(POLL_MS);
56
+ try {
57
+ message = await client.messages.get(message.id);
58
+ }
59
+ catch (e) {
60
+ if (!isTransient(e))
61
+ throw e;
62
+ }
63
+ }
64
+ if (message.status === "failed") {
65
+ const err = message.error;
66
+ throw new CliError(err?.code ?? "message_failed", `Message ${message.id} failed${err?.message ? `: ${err.message}` : "."}`, {
67
+ details: { messageId: message.id, status: message.status, ...(err ? { error: err } : {}) },
68
+ });
69
+ }
70
+ }
71
+ emit(ctx, { id: message.id, status: message.status, accountId: message.accountId, chatId: message.chatId, idempotencyKey, message }, () => `${message.id} ${message.status}`);
72
+ }
73
+ //# sourceMappingURL=send.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send.js","sourceRoot":"","sources":["../src/send.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** The package version. Bump it together with package.json (test/version.test.ts checks). */
2
+ export declare const VERSION = "0.1.0";
3
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,eAAO,MAAM,OAAO,UAAU,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** The package version. Bump it together with package.json (test/version.test.ts checks). */
2
+ export const VERSION = "0.1.0";
3
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@wuapidev/cli",
3
+ "version": "0.1.0",
4
+ "description": "The wuapi command line: log in from the browser, link a WhatsApp number by QR or pairing code, send messages, set up the MCP server and call every endpoint of the wuapi API from your terminal or your agent.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "bin": {
10
+ "wuapi": "./dist/cli.js"
11
+ },
12
+ "exports": {
13
+ ".": {
14
+ "types": "./dist/index.d.ts",
15
+ "import": "./dist/index.js"
16
+ },
17
+ "./package.json": "./package.json"
18
+ },
19
+ "files": [
20
+ "dist",
21
+ "README.md",
22
+ "LICENSE"
23
+ ],
24
+ "engines": {
25
+ "node": ">=20"
26
+ },
27
+ "keywords": [
28
+ "wuapi",
29
+ "whatsapp",
30
+ "whatsapp-api",
31
+ "cli",
32
+ "ai-agents",
33
+ "mcp"
34
+ ],
35
+ "homepage": "https://wuapi.dev/docs#cli",
36
+ "repository": {
37
+ "type": "git",
38
+ "url": "git+https://github.com/wuapidev/wuapi-cli.git"
39
+ },
40
+ "bugs": {
41
+ "url": "https://github.com/wuapidev/wuapi-cli/issues"
42
+ },
43
+ "scripts": {
44
+ "gen": "node scripts/gen-operations.mjs",
45
+ "build": "rm -rf dist && tsc -p tsconfig.build.json && chmod +x dist/cli.js",
46
+ "typecheck": "tsc -p tsconfig.json --noEmit",
47
+ "test": "vitest run",
48
+ "prepublishOnly": "npm run typecheck && npm run test && npm run build"
49
+ },
50
+ "dependencies": {
51
+ "@wuapidev/sdk": "^0.5.0"
52
+ },
53
+ "devDependencies": {
54
+ "@types/node": "^22.10.0",
55
+ "typescript": "^5.6.0",
56
+ "vitest": "^4.0.14"
57
+ },
58
+ "publishConfig": {
59
+ "access": "public"
60
+ }
61
+ }