@scalepad/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.
package/dist/index.js ADDED
@@ -0,0 +1,437 @@
1
+ #!/usr/bin/env node
2
+ import { readFile } from "node:fs/promises";
3
+ import { confirm, password } from "@inquirer/prompts";
4
+ import { coreOperations, createCoreClient, GeneratedCoreClient, ScalepadApiError } from "@scalepad/sdk-core";
5
+ import { GeneratedLifecycleManagerClient, lifecycleManagerOperations, ScalepadLmApiError } from "@scalepad/sdk-lm";
6
+ import { Command } from "commander";
7
+ import { loadConfig } from "./config.js";
8
+ import { deleteStoredApiKey, readStoredApiKey, resolveApiKey, storeApiKey } from "./credentials.js";
9
+ import { buildSort, parseFilterArgs } from "./filters.js";
10
+ import { formatApiError, parseFields, printList, printObject, resolveOutputFormat } from "./format.js";
11
+ function collect(value, previous) {
12
+ previous.push(value);
13
+ return previous;
14
+ }
15
+ function humanizeSegment(segment) {
16
+ return segment.replaceAll("-", " ");
17
+ }
18
+ function listSubcommands(command, prefix = "") {
19
+ const lines = [];
20
+ for (const subcommand of command.commands) {
21
+ if (subcommand.name() === "help") {
22
+ continue;
23
+ }
24
+ const fullName = [prefix, subcommand.name()].filter(Boolean).join(" ");
25
+ const description = subcommand.description();
26
+ const paddedName = fullName.padEnd(40, " ");
27
+ lines.push(` ${paddedName} ${description}`);
28
+ lines.push(...listSubcommands(subcommand, fullName));
29
+ }
30
+ return lines;
31
+ }
32
+ function addExpandedHelp(command, prefix = command.name()) {
33
+ const lines = listSubcommands(command, prefix);
34
+ if (lines.length === 0) {
35
+ return;
36
+ }
37
+ command.addHelpText("after", `\nAvailable Commands:\n${lines.join("\n")}`);
38
+ }
39
+ async function resolveProfile(profile) {
40
+ if (profile) {
41
+ return profile;
42
+ }
43
+ const config = await loadConfig();
44
+ return config.currentProfile || "default";
45
+ }
46
+ async function getApiKeyForCommand(options) {
47
+ const profile = await resolveProfile(options.profile);
48
+ const apiKey = await resolveApiKey({
49
+ explicitApiKey: options.apiKey,
50
+ envApiKey: process.env.SCALEPAD_API_KEY,
51
+ profile
52
+ });
53
+ if (!apiKey) {
54
+ throw new Error(`No API key configured for profile '${profile}'. Run 'scalepad auth login'.`);
55
+ }
56
+ return { apiKey, profile };
57
+ }
58
+ async function probeCoreAccess(coreClient) {
59
+ try {
60
+ await coreClient.listClients({ pageSize: 1 });
61
+ return true;
62
+ }
63
+ catch {
64
+ return false;
65
+ }
66
+ }
67
+ async function probeLifecycleManagerAccess(apiKey) {
68
+ const response = await fetch("https://api.scalepad.com/lifecycle-manager/v1/meeting-types", {
69
+ headers: {
70
+ accept: "application/json",
71
+ "x-api-key": apiKey,
72
+ "user-agent": "@scalepad/cli"
73
+ }
74
+ });
75
+ return response.ok;
76
+ }
77
+ function addSharedAuthOptions(command) {
78
+ return command
79
+ .option("--profile <name>", "credential profile name")
80
+ .option("--api-key <key>", "override API key for this command");
81
+ }
82
+ function addOutputOptions(command) {
83
+ return command
84
+ .option("--json", "print JSON")
85
+ .option("--jsonl", "print newline-delimited JSON")
86
+ .option("--csv", "print CSV")
87
+ .option("--table", "print a table")
88
+ .option("--fields <fields>", "comma-separated output fields");
89
+ }
90
+ function addOperationOptions(command, operation) {
91
+ const configured = addOutputOptions(addSharedAuthOptions(command))
92
+ .option("--query <name=value>", "raw query parameter", collect, []);
93
+ if (operation.queryParams.length > 0) {
94
+ configured
95
+ .option("--all", "walk cursor pagination until exhaustion")
96
+ .option("--limit <count>", "page size for list requests")
97
+ .option("--cursor <cursor>", "starting cursor")
98
+ .option("--filter <field=expr>", "filter expression", collect, [])
99
+ .option("--sort <field>", "sortable field")
100
+ .option("--desc", "sort descending");
101
+ }
102
+ if (operation.hasBody) {
103
+ configured
104
+ .option("--body <json-or-@file>", "inline JSON body or @path/to/file.json")
105
+ .option("--body-file <path>", "path to a JSON body file");
106
+ }
107
+ if (operation.method !== "get") {
108
+ configured.option("--yes", "skip interactive confirmation");
109
+ }
110
+ return configured;
111
+ }
112
+ function hasAdvancedQueryFlags(options) {
113
+ return Boolean(options.limit
114
+ || options.cursor
115
+ || (options.filter?.length ?? 0) > 0
116
+ || options.sort
117
+ || options.desc);
118
+ }
119
+ function parseKeyValueArgs(values) {
120
+ const entries = {};
121
+ for (const value of values) {
122
+ const separatorIndex = value.indexOf("=");
123
+ if (separatorIndex <= 0 || separatorIndex === value.length - 1) {
124
+ throw new Error(`Invalid key/value argument '${value}'. Expected name=value.`);
125
+ }
126
+ const key = value.slice(0, separatorIndex).trim();
127
+ const entryValue = value.slice(separatorIndex + 1).trim();
128
+ if (!key || !entryValue) {
129
+ throw new Error(`Invalid key/value argument '${value}'. Expected name=value.`);
130
+ }
131
+ entries[key] = entryValue;
132
+ }
133
+ return entries;
134
+ }
135
+ function buildQueryFromOptions(operation, options) {
136
+ const rawQuery = parseKeyValueArgs(options.query ?? []);
137
+ const hasFriendlyQueryFlags = hasAdvancedQueryFlags(options);
138
+ if (operation.queryParams.length === 0) {
139
+ if (Object.keys(rawQuery).length > 0 || hasFriendlyQueryFlags) {
140
+ throw new Error(`Command '${[...operation.commandPath, operation.action].join(" ")}' does not accept query parameters.`);
141
+ }
142
+ return undefined;
143
+ }
144
+ const query = { ...rawQuery };
145
+ if (options.limit) {
146
+ const pageSize = Number(options.limit);
147
+ if (!Number.isInteger(pageSize) || pageSize <= 0) {
148
+ throw new Error(`Invalid --limit value '${options.limit}'. Expected a positive integer.`);
149
+ }
150
+ query.page_size = String(pageSize);
151
+ }
152
+ if (options.cursor) {
153
+ query.cursor = options.cursor;
154
+ }
155
+ const sort = buildSort(options.sort, Boolean(options.desc));
156
+ if (sort) {
157
+ query.sort = sort;
158
+ }
159
+ for (const [field, expression] of Object.entries(parseFilterArgs(options.filter ?? []))) {
160
+ query[`filter[${field}]`] = expression;
161
+ }
162
+ return Object.keys(query).length === 0 ? undefined : query;
163
+ }
164
+ async function loadBodyFromOptions(operation, options) {
165
+ if (!operation.hasBody) {
166
+ if (options.body || options.bodyFile) {
167
+ throw new Error(`Command '${[...operation.commandPath, operation.action].join(" ")}' does not accept a request body.`);
168
+ }
169
+ return undefined;
170
+ }
171
+ if (options.body && options.bodyFile) {
172
+ throw new Error("Use either --body or --body-file, not both.");
173
+ }
174
+ let rawInput;
175
+ if (options.bodyFile) {
176
+ rawInput = await readFile(options.bodyFile, "utf8");
177
+ }
178
+ else if (options.body) {
179
+ if (options.body.startsWith("@")) {
180
+ rawInput = await readFile(options.body.slice(1), "utf8");
181
+ }
182
+ else {
183
+ rawInput = options.body;
184
+ }
185
+ }
186
+ if (rawInput == null) {
187
+ throw new Error(`Command '${[...operation.commandPath, operation.action].join(" ")}' requires --body or --body-file.`);
188
+ }
189
+ try {
190
+ return JSON.parse(rawInput);
191
+ }
192
+ catch (error) {
193
+ throw new Error(`Invalid JSON body: ${formatApiError(error)}`);
194
+ }
195
+ }
196
+ async function confirmMutation(operation, options) {
197
+ if (operation.method === "get" || options.yes) {
198
+ return true;
199
+ }
200
+ return confirm({
201
+ message: `${operation.method.toUpperCase()} ${operation.path}?`,
202
+ default: false
203
+ });
204
+ }
205
+ function buildPathParams(operation, pathValues) {
206
+ return Object.fromEntries(operation.pathParams.map((name, index) => [name, pathValues[index] ?? ""]));
207
+ }
208
+ function createGeneratedClient(family, apiKey) {
209
+ return family === "core"
210
+ ? new GeneratedCoreClient({ apiKey })
211
+ : new GeneratedLifecycleManagerClient({ apiKey });
212
+ }
213
+ async function invokeOperation(family, operation, options, pathValues, queryOverride) {
214
+ const { apiKey } = await getApiKeyForCommand(options);
215
+ const client = createGeneratedClient(family, apiKey);
216
+ const method = client[operation.methodName];
217
+ if (typeof method !== "function") {
218
+ throw new Error(`Generated client is missing method '${operation.methodName}'. Re-run 'pnpm generate:sdk'.`);
219
+ }
220
+ const query = queryOverride ?? buildQueryFromOptions(operation, options);
221
+ const body = await loadBodyFromOptions(operation, options);
222
+ const args = [];
223
+ if (operation.pathParams.length > 0) {
224
+ args.push(buildPathParams(operation, pathValues));
225
+ }
226
+ if (operation.queryParams.length > 0) {
227
+ args.push(query);
228
+ }
229
+ if (operation.hasBody) {
230
+ args.push(body);
231
+ }
232
+ return method.apply(client, args);
233
+ }
234
+ async function executeOperation(family, operation, options, pathValues) {
235
+ const format = resolveOutputFormat(options);
236
+ const fields = parseFields(options.fields);
237
+ if (!(await confirmMutation(operation, options))) {
238
+ console.log("Aborted.");
239
+ return;
240
+ }
241
+ if (operation.output === "list") {
242
+ const initialQuery = buildQueryFromOptions(operation, options) ?? {};
243
+ let nextCursor = initialQuery.cursor;
244
+ while (true) {
245
+ const query = nextCursor ? { ...initialQuery, cursor: nextCursor } : initialQuery;
246
+ const payload = await invokeOperation(family, operation, options, pathValues, query);
247
+ printList(payload, format, fields);
248
+ if (!options.all) {
249
+ return;
250
+ }
251
+ const cursor = payload?.next_cursor;
252
+ if (typeof cursor !== "string" || cursor.length === 0) {
253
+ return;
254
+ }
255
+ nextCursor = cursor;
256
+ }
257
+ }
258
+ const payload = await invokeOperation(family, operation, options, pathValues);
259
+ printObject(payload, format, fields);
260
+ }
261
+ function getOperationSortKey(operation) {
262
+ const actionOrder = ["list", "get", "create", "update", "delete"];
263
+ return `${operation.commandPath.join("/")}:${actionOrder.indexOf(operation.action).toString().padStart(2, "0")}:${operation.pathParams.length}`;
264
+ }
265
+ function extractApiVersion(path) {
266
+ const match = path.match(/\/v(\d+)\//);
267
+ return match ? Number(match[1]) : 0;
268
+ }
269
+ function stripLeadingVersion(commandPath) {
270
+ if (commandPath.length > 0 && /^v\d+$/i.test(commandPath[0] ?? "")) {
271
+ return commandPath.slice(1);
272
+ }
273
+ return [...commandPath];
274
+ }
275
+ function operationIdentity(operation) {
276
+ return [
277
+ operation.commandPath.join("/"),
278
+ operation.action,
279
+ operation.pathParams.join(",")
280
+ ].join("|");
281
+ }
282
+ function buildLatestLifecycleManagerOperations() {
283
+ const preferred = new Map();
284
+ for (const operation of lifecycleManagerOperations) {
285
+ const normalized = {
286
+ ...operation,
287
+ commandPath: stripLeadingVersion(operation.commandPath)
288
+ };
289
+ const key = operationIdentity(normalized);
290
+ const existing = preferred.get(key);
291
+ if (!existing || extractApiVersion(normalized.path) > extractApiVersion(existing.path)) {
292
+ preferred.set(key, normalized);
293
+ }
294
+ }
295
+ return [...preferred.values()];
296
+ }
297
+ function registerOperations(root, family, operations) {
298
+ const commandCache = new Map([["", root]]);
299
+ for (const operation of [...operations].sort((left, right) => getOperationSortKey(left).localeCompare(getOperationSortKey(right)))) {
300
+ let current = root;
301
+ const pathSoFar = [];
302
+ for (const segment of operation.commandPath) {
303
+ pathSoFar.push(segment);
304
+ const key = pathSoFar.join("/");
305
+ const existing = commandCache.get(key);
306
+ if (existing) {
307
+ current = existing;
308
+ continue;
309
+ }
310
+ const group = current.command(segment).description(`${humanizeSegment(segment)} commands`);
311
+ commandCache.set(key, group);
312
+ current = group;
313
+ }
314
+ const leaf = current.command(operation.action).description(operation.summary);
315
+ for (const pathParam of operation.pathParams) {
316
+ leaf.argument(`<${pathParam}>`, `${pathParam} path parameter`);
317
+ }
318
+ addOperationOptions(leaf, operation).action(async (...actionArgs) => {
319
+ const options = actionArgs[actionArgs.length - 1];
320
+ const pathValues = actionArgs.slice(0, -1).map((value) => String(value));
321
+ await executeOperation(family, operation, options, pathValues);
322
+ });
323
+ }
324
+ }
325
+ function findOperation(operations, path, method) {
326
+ const operation = operations.find((entry) => entry.path === path && entry.method === method);
327
+ if (!operation) {
328
+ throw new Error(`Missing generated operation for ${method.toUpperCase()} ${path}.`);
329
+ }
330
+ return operation;
331
+ }
332
+ function buildCoreAliasOperations() {
333
+ return [
334
+ { ...findOperation(coreOperations, "/core/v1/assets/hardware", "get"), commandPath: ["hardware-assets"] },
335
+ { ...findOperation(coreOperations, "/core/v1/assets/hardware/{id}", "get"), commandPath: ["hardware-assets"] },
336
+ { ...findOperation(coreOperations, "/core/v1/service/tickets", "get"), commandPath: ["tickets"] },
337
+ { ...findOperation(coreOperations, "/core/v1/service/tickets/{id}", "get"), commandPath: ["tickets"] },
338
+ { ...findOperation(coreOperations, "/core/v1/service/contracts", "get"), commandPath: ["contracts"] },
339
+ { ...findOperation(coreOperations, "/core/v1/service/contracts/{id}", "get"), commandPath: ["contracts"] },
340
+ { ...findOperation(coreOperations, "/core/v1/assets/saas", "get"), commandPath: ["saas-assets"] },
341
+ { ...findOperation(coreOperations, "/core/v1/assets/saas/{id}", "get"), commandPath: ["saas-assets"] }
342
+ ];
343
+ }
344
+ async function run() {
345
+ const program = new Command();
346
+ program
347
+ .name("scalepad")
348
+ .description("ScalePad public CLI for Core API and Lifecycle Manager")
349
+ .version("0.1.0");
350
+ const auth = program.command("auth").description("manage API credentials");
351
+ addSharedAuthOptions(auth.command("login")
352
+ .description("authenticate with an API key and store it under a profile")
353
+ .action(async (options) => {
354
+ const profile = await resolveProfile(options.profile);
355
+ const suppliedApiKey = options.apiKey ?? await password({
356
+ message: "Enter your ScalePad API key",
357
+ mask: "*"
358
+ });
359
+ const coreClient = createCoreClient({ apiKey: suppliedApiKey });
360
+ const coreAccess = await probeCoreAccess(coreClient);
361
+ const lmAccess = await probeLifecycleManagerAccess(suppliedApiKey);
362
+ if (!coreAccess && !lmAccess) {
363
+ throw new Error("Unable to validate the API key against Core API or Lifecycle Manager.");
364
+ }
365
+ const storage = await storeApiKey(profile, suppliedApiKey);
366
+ console.log(`Authenticated profile '${profile}'.`);
367
+ console.log(`Stored credential using ${storage}.`);
368
+ console.log(`Core access: ${coreAccess ? "yes" : "no"}`);
369
+ console.log(`Lifecycle Manager access: ${lmAccess ? "yes" : "no"}`);
370
+ }));
371
+ addSharedAuthOptions(auth.command("whoami")
372
+ .description("show the current profile and accessible API families")
373
+ .action(async (options) => {
374
+ const profile = await resolveProfile(options.profile);
375
+ const apiKey = await resolveApiKey({
376
+ explicitApiKey: options.apiKey,
377
+ envApiKey: process.env.SCALEPAD_API_KEY,
378
+ profile
379
+ });
380
+ if (!apiKey) {
381
+ throw new Error(`No API key configured for profile '${profile}'.`);
382
+ }
383
+ const stored = !options.apiKey && !process.env.SCALEPAD_API_KEY ? await readStoredApiKey(profile) : null;
384
+ const coreClient = createCoreClient({ apiKey });
385
+ const result = {
386
+ profile,
387
+ credential_source: options.apiKey ? "flag" : process.env.SCALEPAD_API_KEY ? "env" : stored ? "stored" : "unknown",
388
+ core_access: false,
389
+ lifecycle_manager_access: false
390
+ };
391
+ result.core_access = await probeCoreAccess(coreClient);
392
+ result.lifecycle_manager_access = await probeLifecycleManagerAccess(apiKey);
393
+ console.log(JSON.stringify(result, null, 2));
394
+ }));
395
+ addSharedAuthOptions(auth.command("logout")
396
+ .description("remove the stored credential for a profile")
397
+ .action(async (options) => {
398
+ const profile = await resolveProfile(options.profile);
399
+ const confirmed = await confirm({
400
+ message: `Remove the stored API key for profile '${profile}'?`,
401
+ default: true
402
+ });
403
+ if (!confirmed) {
404
+ console.log("Aborted.");
405
+ return;
406
+ }
407
+ const removed = await deleteStoredApiKey(profile);
408
+ if (!removed) {
409
+ console.log(`No stored credential found for profile '${profile}'.`);
410
+ return;
411
+ }
412
+ console.log(`Removed stored credential for profile '${profile}'.`);
413
+ }));
414
+ const core = program.command("core").description("ScalePad Core API commands");
415
+ const lm = program.command("lm").description("Lifecycle Manager API commands");
416
+ registerOperations(core, "core", [...coreOperations, ...buildCoreAliasOperations()]);
417
+ registerOperations(lm, "lm", buildLatestLifecycleManagerOperations());
418
+ addExpandedHelp(program, "");
419
+ addExpandedHelp(auth);
420
+ addExpandedHelp(core);
421
+ addExpandedHelp(lm);
422
+ try {
423
+ await program.parseAsync(process.argv);
424
+ }
425
+ catch (error) {
426
+ if (error instanceof ScalepadApiError || error instanceof ScalepadLmApiError) {
427
+ console.error(formatApiError(error));
428
+ console.error(JSON.stringify(error.payload, null, 2));
429
+ process.exitCode = 1;
430
+ return;
431
+ }
432
+ console.error(formatApiError(error));
433
+ process.exitCode = 1;
434
+ }
435
+ }
436
+ void run();
437
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "@scalepad/cli",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "scalepad": "dist/index.js"
9
+ },
10
+ "dependencies": {
11
+ "@inquirer/prompts": "^7.8.4",
12
+ "commander": "^14.0.1",
13
+ "@scalepad/sdk-lm": "0.1.0",
14
+ "@scalepad/sdk-core": "0.1.0"
15
+ },
16
+ "optionalDependencies": {
17
+ "keytar": "^7.9.0"
18
+ },
19
+ "scripts": {
20
+ "build": "tsc -p tsconfig.json",
21
+ "typecheck": "tsc -p tsconfig.json --noEmit",
22
+ "test": "vitest run"
23
+ }
24
+ }
package/src/config.ts ADDED
@@ -0,0 +1,66 @@
1
+ import { chmod, mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { homedir } from "node:os";
3
+ import { dirname, join } from "node:path";
4
+
5
+ export interface ProfileMetadata {
6
+ storage?: "keytar" | "file";
7
+ }
8
+
9
+ export interface CliConfig {
10
+ currentProfile: string;
11
+ profiles: Record<string, ProfileMetadata>;
12
+ }
13
+
14
+ const DEFAULT_CONFIG: CliConfig = {
15
+ currentProfile: "default",
16
+ profiles: {}
17
+ };
18
+
19
+ function configRoot(): string {
20
+ const xdg = process.env.XDG_CONFIG_HOME;
21
+ if (xdg) {
22
+ return join(xdg, "scalepad-cli");
23
+ }
24
+
25
+ return join(homedir(), ".config", "scalepad-cli");
26
+ }
27
+
28
+ export function getConfigPath(): string {
29
+ return join(configRoot(), "config.json");
30
+ }
31
+
32
+ export function getFallbackCredentialsPath(): string {
33
+ return join(configRoot(), "credentials.json");
34
+ }
35
+
36
+ export async function ensureConfigDir(): Promise<void> {
37
+ await mkdir(configRoot(), { recursive: true });
38
+ }
39
+
40
+ export async function loadConfig(): Promise<CliConfig> {
41
+ try {
42
+ const raw = await readFile(getConfigPath(), "utf8");
43
+ const parsed = JSON.parse(raw) as Partial<CliConfig>;
44
+ return {
45
+ currentProfile: parsed.currentProfile ?? "default",
46
+ profiles: parsed.profiles ?? {}
47
+ };
48
+ } catch {
49
+ return structuredClone(DEFAULT_CONFIG);
50
+ }
51
+ }
52
+
53
+ export async function saveConfig(config: CliConfig): Promise<void> {
54
+ await ensureConfigDir();
55
+ const path = getConfigPath();
56
+ await writeFile(path, `${JSON.stringify(config, null, 2)}\n`, "utf8");
57
+ await chmod(path, 0o600);
58
+ }
59
+
60
+ export async function writePrivateJson(path: string, value: unknown): Promise<void> {
61
+ await ensureConfigDir();
62
+ await mkdir(dirname(path), { recursive: true });
63
+ await writeFile(path, `${JSON.stringify(value, null, 2)}\n`, "utf8");
64
+ await chmod(path, 0o600);
65
+ }
66
+