Skip to content

Commit afd59ad

Browse files
committed
cleanup
1 parent 02e8894 commit afd59ad

10 files changed

Lines changed: 53 additions & 32 deletions

File tree

.github/workflows/codeql.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727

2828
steps:
2929
- name: Checkout repository
30-
uses: actions/checkout@v4
30+
uses: actions/checkout@v5
3131

3232
- name: Initialize CodeQL
3333
uses: github/codeql-action/init@v4

.github/workflows/publish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525

2626
steps:
2727
- name: Checkout code
28-
uses: actions/checkout@v4
28+
uses: actions/checkout@v5
2929

3030
- name: Setup pnpm
3131
uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ pnpm build
1111

1212
## Architecture
1313

14-
The CLI is a thin layer over the `[@iterable/api](https://github.com/Iterable/api-client)` client. Each command maps a Zod schema from the client package to CLI arguments and calls one client method.
14+
The CLI is a thin layer over the [@iterable/api](https://github.com/Iterable/api-client) client. Each command maps a Zod schema from the client package to CLI arguments and calls one client method.
1515

1616
### Request flow
1717

src/index.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ import {
1717
} from "./router.js";
1818
import { COMMAND_NAME } from "./utils/command-info.js";
1919

20+
const CLI_PAGINATION_DEFAULTS: Record<string, number> = {
21+
page: 1,
22+
pageSize: 10,
23+
};
24+
2025
async function main(): Promise<void> {
2126
const parsed = parseArgs(process.argv.slice(2));
2227

@@ -95,10 +100,6 @@ async function main(): Promise<void> {
95100
command.cliTransforms
96101
);
97102

98-
const CLI_PAGINATION_DEFAULTS: Record<string, number> = {
99-
page: 1,
100-
pageSize: 10,
101-
};
102103
const schemaKeys =
103104
command.schema instanceof z.ZodObject
104105
? new Set(Object.keys(command.schema.shape))

src/key-manager.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1112,6 +1112,9 @@ export class KeyManager {
11121112

11131113
/** Deactivate all keys (no key will be active). */
11141114
async deactivateAllKeys(): Promise<void> {
1115+
if (!this.store) {
1116+
await this.initialize();
1117+
}
11151118
if (!this.store) {
11161119
throw new Error("Key store not initialized");
11171120
}

src/keys-cli.ts

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -73,17 +73,16 @@ async function saveKeyInteractive(
7373
return key;
7474
}
7575

76-
const { activateNow } = await inquirer.prompt([
76+
const { activateNow } = await inquirer.prompt<{ activateNow: boolean }>([
7777
{
7878
type: "confirm",
7979
name: "activateNow",
8080
message: `Set "${key.name}" as your active API key now?`,
8181
default: !isUpdate,
8282
},
8383
]);
84-
const shouldActivate = activateNow as boolean;
8584

86-
if (shouldActivate) {
85+
if (activateNow) {
8786
await keyManager.setActiveKey(key.id);
8887
showSuccess(`"${key.name}" is now your active API key`);
8988
const updatedKey = await keyManager.getKeyMetadata(key.id);
@@ -194,7 +193,7 @@ async function saveKeyInteractive(
194193
return true;
195194
};
196195

197-
const { name } = await inquirer.prompt([
196+
const { name } = await inquirer.prompt<{ name: string }>([
198197
{
199198
type: "input",
200199
name: "name",
@@ -213,13 +212,8 @@ async function saveKeyInteractive(
213212
try {
214213
const id =
215214
isUpdate && existingKey
216-
? await keyManager.updateKey(
217-
existingKey.id,
218-
name as string,
219-
apiKey,
220-
baseUrl
221-
)
222-
: await keyManager.addKey(name as string, apiKey, baseUrl);
215+
? await keyManager.updateKey(existingKey.id, name, apiKey, baseUrl)
216+
: await keyManager.addKey(name, apiKey, baseUrl);
223217

224218
spinner.succeed(
225219
isUpdate
@@ -229,7 +223,7 @@ async function saveKeyInteractive(
229223

230224
const w = 12;
231225
console.log();
232-
console.log(` ${"Name:".padEnd(w)} ${chalk.white.bold(name as string)}`);
226+
console.log(` ${"Name:".padEnd(w)} ${chalk.white.bold(name)}`);
233227
console.log(` ${"ID:".padEnd(w)} ${chalk.gray(id)}`);
234228
console.log(` ${"Endpoint:".padEnd(w)} ${linkColor()(baseUrl)}`);
235229
console.log();
@@ -442,7 +436,9 @@ export async function handleKeysCommand(args: string[]): Promise<void> {
442436
}
443437

444438
if (keyToDelete.isActive && otherKeys.length > 0) {
445-
const { newActiveKey } = await inquirer.prompt([
439+
const { newActiveKey } = await inquirer.prompt<{
440+
newActiveKey: string;
441+
}>([
446442
{
447443
type: "list" as const,
448444
name: "newActiveKey",
@@ -457,7 +453,7 @@ export async function handleKeysCommand(args: string[]): Promise<void> {
457453
},
458454
]);
459455
if (newActiveKey !== "none") {
460-
await keyManager.setActiveKey(newActiveKey as string);
456+
await keyManager.setActiveKey(newActiveKey);
461457
const activated = otherKeys.find((k) => k.id === newActiveKey);
462458
if (activated) {
463459
showSuccess(`Switched to "${activated.name}"`);

src/output.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,18 @@ interface TableData {
6464
metadata: Record<string, unknown>;
6565
}
6666

67+
function isObjectArray(value: unknown): value is Record<string, unknown>[] {
68+
return (
69+
Array.isArray(value) &&
70+
value.length > 0 &&
71+
typeof value[0] === "object" &&
72+
value[0] !== null
73+
);
74+
}
75+
6776
function findTableData(data: unknown): TableData | null {
68-
if (Array.isArray(data)) return { rows: data, metadata: {} };
69-
if (data && typeof data === "object") {
77+
if (isObjectArray(data)) return { rows: data, metadata: {} };
78+
if (data && typeof data === "object" && !Array.isArray(data)) {
7079
const entries = Object.entries(data as Record<string, unknown>);
7180
for (const [arrayKey, value] of entries) {
7281
if (Array.isArray(value)) {

src/router.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,8 @@ export function parseArgs(argv: string[]): ParsedArgs {
9090
return { category, action, rest, globalFlags };
9191
}
9292

93-
function getVersion(): string {
94-
return PACKAGE_VERSION;
95-
}
96-
9793
export function showVersion(): void {
98-
console.log(`${COMMAND_NAME} ${getVersion()}`);
94+
console.log(`${COMMAND_NAME} ${PACKAGE_VERSION}`);
9995
}
10096

10197
interface KeyInfo {
@@ -125,7 +121,7 @@ async function getKeyInfo(): Promise<KeyInfo> {
125121
}
126122

127123
export async function showGlobalHelp(): Promise<void> {
128-
const version = getVersion();
124+
const version = PACKAGE_VERSION;
129125
const categories = getCategories();
130126
const keyInfo = await getKeyInfo();
131127

@@ -193,7 +189,7 @@ export async function showGlobalHelp(): Promise<void> {
193189
theme.bold("GLOBAL OPTIONS"),
194190
` ${theme.accent("--help, -h")} Show help`,
195191
` ${theme.accent("--version, -V")} Show version`,
196-
` ${theme.accent("--output")} <fmt> Output format: ${OUTPUT_FORMATS.join(", ")} (default: pretty)`,
192+
` ${theme.accent("--output")} <fmt> Output format: ${OUTPUT_FORMATS.join(", ")} (default: pretty in TTY, json when piped)`,
197193
` ${theme.accent("--columns")} <cols> Columns to show in table output (comma-separated)`,
198194
` ${theme.accent("--json")} <data> Pass raw JSON — bypasses all other flags (use '-' for stdin)`,
199195
` ${theme.accent("--file")} <path> Read JSON input from a file`,

src/utils/theme.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ import { detectBackground } from "./detect-background.js";
55
const mode = detectBackground();
66

77
export const theme = {
8-
mode,
9-
108
key: mode === "dark" ? chalk.hex("#7DD3FC") : chalk.hex("#0369A1"),
119
value: mode === "dark" ? chalk.hex("#86EFAC") : chalk.green,
1210
number: mode === "dark" ? chalk.hex("#FDE68A") : chalk.yellow,

tests/unit/router.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,22 @@ describe("parseArgs", () => {
9090
expect(result.globalFlags.help).toBe(true);
9191
expect(result.action).toBeNull();
9292
});
93+
94+
it("extracts --force flag", () => {
95+
const result = parseArgs(["--force", "lists", "delete", "123"]);
96+
expect(result.globalFlags.force).toBe(true);
97+
expect(result.category).toBe("lists");
98+
});
99+
100+
it("extracts -f shorthand", () => {
101+
const result = parseArgs(["-f", "lists", "delete"]);
102+
expect(result.globalFlags.force).toBe(true);
103+
});
104+
105+
it("extracts --file flag", () => {
106+
const result = parseArgs(["--file", "data.json", "users", "bulk-update"]);
107+
expect(result.globalFlags.file).toBe("data.json");
108+
expect(result.category).toBe("users");
109+
expect(result.action).toBe("bulk-update");
110+
});
93111
});

0 commit comments

Comments
 (0)