@nocoo/zhe 1.11.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 (54) hide show
  1. package/README.md +57 -0
  2. package/dist/api/client.d.ts +45 -0
  3. package/dist/api/client.d.ts.map +1 -0
  4. package/dist/api/client.js +145 -0
  5. package/dist/api/client.js.map +1 -0
  6. package/dist/api/types.d.ts +45 -0
  7. package/dist/api/types.d.ts.map +1 -0
  8. package/dist/api/types.js +5 -0
  9. package/dist/api/types.js.map +1 -0
  10. package/dist/commands/create.d.ts +43 -0
  11. package/dist/commands/create.d.ts.map +1 -0
  12. package/dist/commands/create.js +173 -0
  13. package/dist/commands/create.js.map +1 -0
  14. package/dist/commands/delete.d.ts +20 -0
  15. package/dist/commands/delete.d.ts.map +1 -0
  16. package/dist/commands/delete.js +93 -0
  17. package/dist/commands/delete.js.map +1 -0
  18. package/dist/commands/get.d.ts +15 -0
  19. package/dist/commands/get.d.ts.map +1 -0
  20. package/dist/commands/get.js +67 -0
  21. package/dist/commands/get.js.map +1 -0
  22. package/dist/commands/list.d.ts +29 -0
  23. package/dist/commands/list.d.ts.map +1 -0
  24. package/dist/commands/list.js +90 -0
  25. package/dist/commands/list.js.map +1 -0
  26. package/dist/commands/login.d.ts +5 -0
  27. package/dist/commands/login.d.ts.map +1 -0
  28. package/dist/commands/login.js +112 -0
  29. package/dist/commands/login.js.map +1 -0
  30. package/dist/commands/logout.d.ts +5 -0
  31. package/dist/commands/logout.d.ts.map +1 -0
  32. package/dist/commands/logout.js +21 -0
  33. package/dist/commands/logout.js.map +1 -0
  34. package/dist/commands/open.d.ts +11 -0
  35. package/dist/commands/open.d.ts.map +1 -0
  36. package/dist/commands/open.js +53 -0
  37. package/dist/commands/open.js.map +1 -0
  38. package/dist/commands/update.d.ts +40 -0
  39. package/dist/commands/update.d.ts.map +1 -0
  40. package/dist/commands/update.js +134 -0
  41. package/dist/commands/update.js.map +1 -0
  42. package/dist/config.d.ts +38 -0
  43. package/dist/config.d.ts.map +1 -0
  44. package/dist/config.js +66 -0
  45. package/dist/config.js.map +1 -0
  46. package/dist/index.d.ts +6 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +32 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/utils.d.ts +41 -0
  51. package/dist/utils.d.ts.map +1 -0
  52. package/dist/utils.js +105 -0
  53. package/dist/utils.js.map +1 -0
  54. package/package.json +47 -0
@@ -0,0 +1,15 @@
1
+ /**
2
+ * zhe get <id> — Get link details
3
+ */
4
+ export declare const getCommand: import("citty").CommandDef<{
5
+ readonly id: {
6
+ readonly type: "positional";
7
+ readonly description: "Link ID (numeric)";
8
+ readonly required: true;
9
+ };
10
+ readonly json: {
11
+ readonly type: "boolean";
12
+ readonly description: "Output as JSON";
13
+ };
14
+ }>;
15
+ //# sourceMappingURL=get.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../src/commands/get.ts"],"names":[],"mappings":"AAAA;;GAEG;AAeH,eAAO,MAAM,UAAU;;;;;;;;;;EA4CrB,CAAC"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * zhe get <id> — Get link details
3
+ */
4
+ import { defineCommand, pc } from "@nocoo/cli-base";
5
+ import { ApiClient, ApiClientError, EXIT_AUTH_REQUIRED, EXIT_ERROR, EXIT_INVALID_ARGS, EXIT_NOT_FOUND, EXIT_RATE_LIMITED, } from "../api/client.js";
6
+ import { getApiKey } from "../config.js";
7
+ import { formatLinkDetail, parseLinkId } from "../utils.js";
8
+ export const getCommand = defineCommand({
9
+ meta: {
10
+ name: "get",
11
+ description: "Get link details",
12
+ },
13
+ args: {
14
+ id: {
15
+ type: "positional",
16
+ description: "Link ID (numeric)",
17
+ required: true,
18
+ },
19
+ json: {
20
+ type: "boolean",
21
+ description: "Output as JSON",
22
+ },
23
+ },
24
+ async run({ args }) {
25
+ const apiKey = getApiKey();
26
+ if (!apiKey) {
27
+ console.log(pc.red("Not authenticated. Run `zhe login` first."));
28
+ process.exit(EXIT_AUTH_REQUIRED);
29
+ }
30
+ const idStr = args.id;
31
+ const id = parseLinkId(idStr);
32
+ if (id === null) {
33
+ console.log(pc.red("Invalid link ID. Must be a number."));
34
+ process.exit(EXIT_INVALID_ARGS);
35
+ }
36
+ const client = new ApiClient(apiKey);
37
+ try {
38
+ const response = await client.getLink(id);
39
+ if (args.json) {
40
+ console.log(JSON.stringify(response, null, 2));
41
+ }
42
+ else {
43
+ console.log(formatLinkDetail(response.link));
44
+ }
45
+ }
46
+ catch (error) {
47
+ handleApiError(error);
48
+ }
49
+ },
50
+ });
51
+ function handleApiError(error) {
52
+ if (error instanceof ApiClientError) {
53
+ console.log(pc.red(`Error: ${error.message}`));
54
+ if (error.status === 401) {
55
+ process.exit(EXIT_AUTH_REQUIRED);
56
+ }
57
+ if (error.status === 404) {
58
+ process.exit(EXIT_NOT_FOUND);
59
+ }
60
+ if (error.status === 429) {
61
+ process.exit(EXIT_RATE_LIMITED);
62
+ }
63
+ process.exit(EXIT_ERROR);
64
+ }
65
+ throw error;
66
+ }
67
+ //# sourceMappingURL=get.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get.js","sourceRoot":"","sources":["../../src/commands/get.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EACN,SAAS,EACT,cAAc,EACd,kBAAkB,EAClB,UAAU,EACV,iBAAiB,EACjB,cAAc,EACd,iBAAiB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE5D,MAAM,CAAC,MAAM,UAAU,GAAG,aAAa,CAAC;IACvC,IAAI,EAAE;QACL,IAAI,EAAE,KAAK;QACX,WAAW,EAAE,kBAAkB;KAC/B;IACD,IAAI,EAAE;QACL,EAAE,EAAE;YACH,IAAI,EAAE,YAAY;YAClB,WAAW,EAAE,mBAAmB;YAChC,QAAQ,EAAE,IAAI;SACd;QACD,IAAI,EAAE;YACL,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,gBAAgB;SAC7B;KACD;IACD,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE;QACjB,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;QAC3B,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC,CAAC;YACjE,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAClC,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,EAAY,CAAC;QAChC,MAAM,EAAE,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC,CAAC;YAC1D,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACjC,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,MAAM,CAAC,CAAC;QAErC,IAAI,CAAC;YACJ,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAE1C,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACf,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAChD,CAAC;iBAAM,CAAC;gBACP,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;YAC9C,CAAC;QACF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,cAAc,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;IACF,CAAC;CACD,CAAC,CAAC;AAEH,SAAS,cAAc,CAAC,KAAc;IACrC,IAAI,KAAK,YAAY,cAAc,EAAE,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAE/C,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAClC,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC9B,CAAC;QACD,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACjC,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC1B,CAAC;IACD,MAAM,KAAK,CAAC;AACb,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * zhe list — List all links
3
+ */
4
+ export declare const listCommand: import("citty").CommandDef<{
5
+ readonly folder: {
6
+ readonly type: "string";
7
+ readonly alias: "f";
8
+ readonly description: "Filter by folder ID";
9
+ };
10
+ readonly limit: {
11
+ readonly type: "string";
12
+ readonly alias: "l";
13
+ readonly description: "Max results (default: 50, max: 500)";
14
+ };
15
+ readonly offset: {
16
+ readonly type: "string";
17
+ readonly alias: "o";
18
+ readonly description: "Pagination offset (default: 0)";
19
+ };
20
+ readonly json: {
21
+ readonly type: "boolean";
22
+ readonly description: "Output as JSON";
23
+ };
24
+ readonly minimal: {
25
+ readonly type: "boolean";
26
+ readonly description: "Output short URLs only";
27
+ };
28
+ }>;
29
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;EAmEtB,CAAC"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * zhe list — List all links
3
+ */
4
+ import { defineCommand, pc } from "@nocoo/cli-base";
5
+ import { ApiClient, ApiClientError, EXIT_AUTH_REQUIRED, EXIT_ERROR, EXIT_RATE_LIMITED, } from "../api/client.js";
6
+ import { getApiKey, getOutputFormat } from "../config.js";
7
+ import { formatLinksMinimal, formatLinksTable } from "../utils.js";
8
+ export const listCommand = defineCommand({
9
+ meta: {
10
+ name: "list",
11
+ description: "List all links",
12
+ },
13
+ args: {
14
+ folder: {
15
+ type: "string",
16
+ alias: "f",
17
+ description: "Filter by folder ID",
18
+ },
19
+ limit: {
20
+ type: "string",
21
+ alias: "l",
22
+ description: "Max results (default: 50, max: 500)",
23
+ },
24
+ offset: {
25
+ type: "string",
26
+ alias: "o",
27
+ description: "Pagination offset (default: 0)",
28
+ },
29
+ json: {
30
+ type: "boolean",
31
+ description: "Output as JSON",
32
+ },
33
+ minimal: {
34
+ type: "boolean",
35
+ description: "Output short URLs only",
36
+ },
37
+ },
38
+ async run({ args }) {
39
+ const apiKey = getApiKey();
40
+ if (!apiKey) {
41
+ console.log(pc.red("Not authenticated. Run `zhe login` first."));
42
+ process.exit(EXIT_AUTH_REQUIRED);
43
+ }
44
+ const client = new ApiClient(apiKey);
45
+ try {
46
+ // Build params object, only including defined fields
47
+ const params = {};
48
+ if (args.limit)
49
+ params.limit = Number.parseInt(args.limit, 10);
50
+ if (args.offset)
51
+ params.offset = Number.parseInt(args.offset, 10);
52
+ if (args.folder)
53
+ params.folderId = args.folder;
54
+ const response = await client.listLinks(params);
55
+ // Determine output format
56
+ let format = getOutputFormat();
57
+ if (args.json)
58
+ format = "json";
59
+ if (args.minimal)
60
+ format = "minimal";
61
+ switch (format) {
62
+ case "json":
63
+ console.log(JSON.stringify(response, null, 2));
64
+ break;
65
+ case "minimal":
66
+ console.log(formatLinksMinimal(response.links));
67
+ break;
68
+ default:
69
+ console.log(formatLinksTable(response.links));
70
+ }
71
+ }
72
+ catch (error) {
73
+ handleApiError(error);
74
+ }
75
+ },
76
+ });
77
+ function handleApiError(error) {
78
+ if (error instanceof ApiClientError) {
79
+ console.log(pc.red(`Error: ${error.message}`));
80
+ if (error.status === 401) {
81
+ process.exit(EXIT_AUTH_REQUIRED);
82
+ }
83
+ if (error.status === 429) {
84
+ process.exit(EXIT_RATE_LIMITED);
85
+ }
86
+ process.exit(EXIT_ERROR);
87
+ }
88
+ throw error;
89
+ }
90
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * zhe login — Authenticate with API Key
3
+ */
4
+ export declare const loginCommand: import("citty").CommandDef<import("citty").ArgsDef>;
5
+ //# sourceMappingURL=login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,eAAO,MAAM,YAAY,qDAgEvB,CAAC"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * zhe login — Authenticate with API Key
3
+ */
4
+ import * as readline from "node:readline";
5
+ import { defineCommand, pc } from "@nocoo/cli-base";
6
+ import { ApiClient, EXIT_AUTH_REQUIRED, EXIT_ERROR } from "../api/client.js";
7
+ import { getApiKey, saveApiKey } from "../config.js";
8
+ import { isValidApiKeyFormat, maskApiKey } from "../utils.js";
9
+ export const loginCommand = defineCommand({
10
+ meta: {
11
+ name: "login",
12
+ description: "Authenticate with API Key",
13
+ },
14
+ async run() {
15
+ // Check if already logged in
16
+ const existingKey = getApiKey();
17
+ if (existingKey) {
18
+ console.log(pc.yellow(`Already logged in with API Key: ${maskApiKey(existingKey)}`));
19
+ console.log(pc.dim("Run `zhe logout` first to switch accounts."));
20
+ return;
21
+ }
22
+ // Prompt for API key
23
+ const apiKey = await promptForApiKey();
24
+ if (!apiKey) {
25
+ console.log(pc.red("No API Key provided."));
26
+ process.exit(EXIT_AUTH_REQUIRED);
27
+ }
28
+ // Validate format
29
+ if (!isValidApiKeyFormat(apiKey)) {
30
+ console.log(pc.red("✗ Invalid API Key format"));
31
+ console.log(pc.dim("API Key must start with 'zhe_'"));
32
+ process.exit(EXIT_AUTH_REQUIRED);
33
+ }
34
+ // Test the key
35
+ console.log(pc.dim("Verifying API Key..."));
36
+ const client = new ApiClient(apiKey);
37
+ try {
38
+ const valid = await client.verifyKey();
39
+ if (!valid) {
40
+ console.log(pc.red("✗ Invalid API Key"));
41
+ console.log();
42
+ console.log(`To create an API Key, visit: ${pc.cyan("https://zhe.to/dashboard/api-keys")}`);
43
+ process.exit(EXIT_AUTH_REQUIRED);
44
+ }
45
+ }
46
+ catch (error) {
47
+ console.log(pc.red("✗ Failed to verify API Key"));
48
+ if (error instanceof Error) {
49
+ console.log(pc.dim(error.message));
50
+ }
51
+ process.exit(EXIT_ERROR);
52
+ }
53
+ // Save the key
54
+ saveApiKey(apiKey);
55
+ console.log(pc.green("✓ API Key saved (read access verified)"));
56
+ console.log(` API Key: ${pc.cyan(maskApiKey(apiKey))}`);
57
+ console.log();
58
+ console.log(pc.dim("Note: Write operations require `links:write` scope."));
59
+ console.log(`To create an API Key, visit: ${pc.cyan("https://zhe.to/dashboard/api-keys")}`);
60
+ },
61
+ });
62
+ async function promptForApiKey() {
63
+ return new Promise((resolve) => {
64
+ const rl = readline.createInterface({
65
+ input: process.stdin,
66
+ output: process.stdout,
67
+ });
68
+ // Hide input for security
69
+ const stdin = process.stdin;
70
+ const originalRawMode = stdin.isRaw;
71
+ process.stdout.write("Enter your API Key: ");
72
+ if (stdin.isTTY) {
73
+ stdin.setRawMode(true);
74
+ }
75
+ let input = "";
76
+ const onData = (char) => {
77
+ const c = char.toString();
78
+ if (c === "\n" || c === "\r") {
79
+ // Enter pressed
80
+ if (stdin.isTTY) {
81
+ stdin.setRawMode(originalRawMode ?? false);
82
+ }
83
+ stdin.removeListener("data", onData);
84
+ process.stdout.write("\n");
85
+ rl.close();
86
+ resolve(input.trim());
87
+ }
88
+ else if (c === "\u0003") {
89
+ // Ctrl+C
90
+ if (stdin.isTTY) {
91
+ stdin.setRawMode(originalRawMode ?? false);
92
+ }
93
+ process.stdout.write("\n");
94
+ process.exit(0);
95
+ }
96
+ else if (c === "\u007F" || c === "\b") {
97
+ // Backspace
98
+ if (input.length > 0) {
99
+ input = input.slice(0, -1);
100
+ }
101
+ }
102
+ else if (c.charCodeAt(0) >= 32) {
103
+ // Printable character
104
+ input += c;
105
+ process.stdout.write("*");
106
+ }
107
+ };
108
+ stdin.on("data", onData);
109
+ stdin.resume();
110
+ });
111
+ }
112
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * zhe logout — Clear stored credentials
3
+ */
4
+ export declare const logoutCommand: import("citty").CommandDef<import("citty").ArgsDef>;
5
+ //# sourceMappingURL=logout.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,eAAO,MAAM,aAAa,qDAgBxB,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * zhe logout — Clear stored credentials
3
+ */
4
+ import { defineCommand, pc } from "@nocoo/cli-base";
5
+ import { clearApiKey, getApiKey } from "../config.js";
6
+ export const logoutCommand = defineCommand({
7
+ meta: {
8
+ name: "logout",
9
+ description: "Clear stored credentials",
10
+ },
11
+ run() {
12
+ const existingKey = getApiKey();
13
+ if (!existingKey) {
14
+ console.log(pc.dim("Not logged in."));
15
+ return;
16
+ }
17
+ clearApiKey();
18
+ console.log(pc.green("✓ Logged out"));
19
+ },
20
+ });
21
+ //# sourceMappingURL=logout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEtD,MAAM,CAAC,MAAM,aAAa,GAAG,aAAa,CAAC;IAC1C,IAAI,EAAE;QACL,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,0BAA0B;KACvC;IACD,GAAG;QACF,MAAM,WAAW,GAAG,SAAS,EAAE,CAAC;QAEhC,IAAI,CAAC,WAAW,EAAE,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC;YACtC,OAAO;QACR,CAAC;QAED,WAAW,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;IACvC,CAAC;CACD,CAAC,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * zhe open <slug> — Open short URL in browser
3
+ */
4
+ export declare const openCommand: import("citty").CommandDef<{
5
+ readonly slug: {
6
+ readonly type: "positional";
7
+ readonly description: "The slug to open";
8
+ readonly required: true;
9
+ };
10
+ }>;
11
+ //# sourceMappingURL=open.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open.d.ts","sourceRoot":"","sources":["../../src/commands/open.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,eAAO,MAAM,WAAW;;;;;;EAyBtB,CAAC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * zhe open <slug> — Open short URL in browser
3
+ */
4
+ import { exec } from "node:child_process";
5
+ import { defineCommand, pc } from "@nocoo/cli-base";
6
+ import { EXIT_INVALID_ARGS } from "../api/client.js";
7
+ const BASE_URL = "https://zhe.to";
8
+ export const openCommand = defineCommand({
9
+ meta: {
10
+ name: "open",
11
+ description: "Open short URL in browser",
12
+ },
13
+ args: {
14
+ slug: {
15
+ type: "positional",
16
+ description: "The slug to open",
17
+ required: true,
18
+ },
19
+ },
20
+ run({ args }) {
21
+ const slug = args.slug;
22
+ if (!slug || slug.length === 0) {
23
+ console.log(pc.red("Slug is required."));
24
+ process.exit(EXIT_INVALID_ARGS);
25
+ }
26
+ const url = `${BASE_URL}/${slug}`;
27
+ console.log(`Opening ${pc.cyan(url)}...`);
28
+ openInBrowser(url);
29
+ },
30
+ });
31
+ function openInBrowser(url) {
32
+ const platform = process.platform;
33
+ let command;
34
+ if (platform === "darwin") {
35
+ command = `open "${url}"`;
36
+ }
37
+ else if (platform === "linux") {
38
+ command = `xdg-open "${url}"`;
39
+ }
40
+ else if (platform === "win32") {
41
+ command = `start "" "${url}"`;
42
+ }
43
+ else {
44
+ console.log(pc.dim(`Unable to open browser on ${platform}. Visit: ${url}`));
45
+ return;
46
+ }
47
+ exec(command, (error) => {
48
+ if (error) {
49
+ console.log(pc.dim(`Failed to open browser. Visit: ${url}`));
50
+ }
51
+ });
52
+ }
53
+ //# sourceMappingURL=open.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open.js","sourceRoot":"","sources":["../../src/commands/open.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,QAAQ,GAAG,gBAAgB,CAAC;AAElC,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAC;IACxC,IAAI,EAAE;QACL,IAAI,EAAE,MAAM;QACZ,WAAW,EAAE,2BAA2B;KACxC;IACD,IAAI,EAAE;QACL,IAAI,EAAE;YACL,IAAI,EAAE,YAAY;YAClB,WAAW,EAAE,kBAAkB;YAC/B,QAAQ,EAAE,IAAI;SACd;KACD;IACD,GAAG,CAAC,EAAE,IAAI,EAAE;QACX,MAAM,IAAI,GAAG,IAAI,CAAC,IAAc,CAAC;QAEjC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,CAAC;YACzC,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QACjC,CAAC;QAED,MAAM,GAAG,GAAG,GAAG,QAAQ,IAAI,IAAI,EAAE,CAAC;QAElC,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC1C,aAAa,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC;CACD,CAAC,CAAC;AAEH,SAAS,aAAa,CAAC,GAAW;IACjC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAClC,IAAI,OAAe,CAAC;IAEpB,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC3B,OAAO,GAAG,SAAS,GAAG,GAAG,CAAC;IAC3B,CAAC;SAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,GAAG,aAAa,GAAG,GAAG,CAAC;IAC/B,CAAC;SAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,GAAG,aAAa,GAAG,GAAG,CAAC;IAC/B,CAAC;SAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,6BAA6B,QAAQ,YAAY,GAAG,EAAE,CAAC,CAAC,CAAC;QAC5E,OAAO;IACR,CAAC;IAED,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;QACvB,IAAI,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,kCAAkC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC9D,CAAC;IACF,CAAC,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * zhe update <id> — Update an existing link
3
+ */
4
+ export declare const updateCommand: import("citty").CommandDef<{
5
+ readonly id: {
6
+ readonly type: "positional";
7
+ readonly description: "Link ID (numeric)";
8
+ readonly required: true;
9
+ };
10
+ readonly url: {
11
+ readonly type: "string";
12
+ readonly alias: "u";
13
+ readonly description: "New destination URL";
14
+ };
15
+ readonly slug: {
16
+ readonly type: "string";
17
+ readonly alias: "s";
18
+ readonly description: "New slug";
19
+ };
20
+ readonly folder: {
21
+ readonly type: "string";
22
+ readonly alias: "f";
23
+ readonly description: "New folder ID (use \"none\" to remove)";
24
+ };
25
+ readonly note: {
26
+ readonly type: "string";
27
+ readonly alias: "n";
28
+ readonly description: "New note (use \"\" to clear)";
29
+ };
30
+ readonly expires: {
31
+ readonly type: "string";
32
+ readonly alias: "e";
33
+ readonly description: "New expiration (use \"never\" to remove)";
34
+ };
35
+ readonly json: {
36
+ readonly type: "boolean";
37
+ readonly description: "Output as JSON";
38
+ };
39
+ }>;
40
+ //# sourceMappingURL=update.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA;;GAEG;AAgBH,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwGxB,CAAC"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * zhe update <id> — Update an existing link
3
+ */
4
+ import { defineCommand, pc } from "@nocoo/cli-base";
5
+ import { ApiClient, ApiClientError, EXIT_AUTH_REQUIRED, EXIT_ERROR, EXIT_INVALID_ARGS, EXIT_NOT_FOUND, EXIT_RATE_LIMITED, } from "../api/client.js";
6
+ import { getApiKey } from "../config.js";
7
+ import { parseLinkId } from "../utils.js";
8
+ export const updateCommand = defineCommand({
9
+ meta: {
10
+ name: "update",
11
+ description: "Update an existing link",
12
+ },
13
+ args: {
14
+ id: {
15
+ type: "positional",
16
+ description: "Link ID (numeric)",
17
+ required: true,
18
+ },
19
+ url: {
20
+ type: "string",
21
+ alias: "u",
22
+ description: "New destination URL",
23
+ },
24
+ slug: {
25
+ type: "string",
26
+ alias: "s",
27
+ description: "New slug",
28
+ },
29
+ folder: {
30
+ type: "string",
31
+ alias: "f",
32
+ description: 'New folder ID (use "none" to remove)',
33
+ },
34
+ note: {
35
+ type: "string",
36
+ alias: "n",
37
+ description: 'New note (use "" to clear)',
38
+ },
39
+ expires: {
40
+ type: "string",
41
+ alias: "e",
42
+ description: 'New expiration (use "never" to remove)',
43
+ },
44
+ json: {
45
+ type: "boolean",
46
+ description: "Output as JSON",
47
+ },
48
+ },
49
+ async run({ args }) {
50
+ const apiKey = getApiKey();
51
+ if (!apiKey) {
52
+ console.log(pc.red("Not authenticated. Run `zhe login` first."));
53
+ process.exit(EXIT_AUTH_REQUIRED);
54
+ }
55
+ const idStr = args.id;
56
+ const id = parseLinkId(idStr);
57
+ if (id === null) {
58
+ console.log(pc.red("Invalid link ID. Must be a number."));
59
+ process.exit(EXIT_INVALID_ARGS);
60
+ }
61
+ // Build update payload
62
+ const data = {};
63
+ if (args.url !== undefined) {
64
+ // Validate URL
65
+ if (!isValidUrl(args.url)) {
66
+ console.log(pc.red("Invalid URL format. Include protocol (https://)."));
67
+ process.exit(EXIT_INVALID_ARGS);
68
+ }
69
+ data.originalUrl = args.url;
70
+ }
71
+ if (args.slug !== undefined) {
72
+ data.slug = args.slug;
73
+ }
74
+ if (args.folder !== undefined) {
75
+ data.folderId = args.folder === "none" ? null : args.folder;
76
+ }
77
+ if (args.note !== undefined) {
78
+ data.note = args.note === "" ? null : args.note;
79
+ }
80
+ if (args.expires !== undefined) {
81
+ data.expiresAt = args.expires === "never" ? null : args.expires;
82
+ }
83
+ // Check if there's anything to update
84
+ if (Object.keys(data).length === 0) {
85
+ console.log(pc.yellow("No changes specified."));
86
+ console.log(pc.dim("Use --url, --slug, --folder, --note, or --expires"));
87
+ process.exit(EXIT_INVALID_ARGS);
88
+ }
89
+ const client = new ApiClient(apiKey);
90
+ try {
91
+ const response = await client.updateLink(id, data);
92
+ if (args.json) {
93
+ console.log(JSON.stringify(response, null, 2));
94
+ }
95
+ else {
96
+ console.log(pc.green(`✓ Updated link #${id}`));
97
+ }
98
+ }
99
+ catch (error) {
100
+ handleApiError(error);
101
+ }
102
+ },
103
+ });
104
+ function isValidUrl(url) {
105
+ try {
106
+ const parsed = new URL(url);
107
+ return parsed.protocol === "http:" || parsed.protocol === "https:";
108
+ }
109
+ catch {
110
+ return false;
111
+ }
112
+ }
113
+ function handleApiError(error) {
114
+ if (error instanceof ApiClientError) {
115
+ if (error.status === 409) {
116
+ console.log(pc.red("Slug is already in use."));
117
+ }
118
+ else {
119
+ console.log(pc.red(`Error: ${error.message}`));
120
+ }
121
+ if (error.status === 401) {
122
+ process.exit(EXIT_AUTH_REQUIRED);
123
+ }
124
+ if (error.status === 404) {
125
+ process.exit(EXIT_NOT_FOUND);
126
+ }
127
+ if (error.status === 429) {
128
+ process.exit(EXIT_RATE_LIMITED);
129
+ }
130
+ process.exit(EXIT_ERROR);
131
+ }
132
+ throw error;
133
+ }
134
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"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"}