@rawdash/cli 0.15.0 → 0.16.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/bin.js +59 -5
- package/dist/bin.js.map +1 -1
- package/package.json +2 -2
package/dist/bin.js
CHANGED
|
@@ -295,18 +295,72 @@ function exitCodeForStatus(status) {
|
|
|
295
295
|
// src/commands/secrets.ts
|
|
296
296
|
import { spinner as spinner2 } from "@clack/prompts";
|
|
297
297
|
import { Command as Command2 } from "commander";
|
|
298
|
+
import { readFile } from "fs/promises";
|
|
298
299
|
var secretsCommand = new Command2("secrets").description(
|
|
299
300
|
"Manage secrets"
|
|
300
301
|
);
|
|
301
|
-
secretsCommand.command("set <name> [value]").description(
|
|
302
|
+
secretsCommand.command("set <name> [value]").description(
|
|
303
|
+
"Set a secret. Pass value as argument, via stdin, or as structured JSON via --json / --from-file."
|
|
304
|
+
).option(
|
|
305
|
+
"--json <json>",
|
|
306
|
+
"Set the secret to a JSON-encoded value (object, array, etc.). Validated before sending."
|
|
307
|
+
).option(
|
|
308
|
+
"--from-file <path>",
|
|
309
|
+
"Read the secret value as JSON from a file. Validated before sending."
|
|
310
|
+
).action(async (name, value, opts) => {
|
|
302
311
|
requireApiKey();
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
312
|
+
const usingJson = opts.json !== void 0;
|
|
313
|
+
const usingFile = opts.fromFile !== void 0;
|
|
314
|
+
if (usingJson && usingFile) {
|
|
315
|
+
printError("Cannot use --json and --from-file together.");
|
|
316
|
+
process.exit(1);
|
|
317
|
+
}
|
|
318
|
+
if ((usingJson || usingFile) && value !== void 0) {
|
|
319
|
+
printError(
|
|
320
|
+
"Cannot combine a positional value with --json or --from-file."
|
|
321
|
+
);
|
|
322
|
+
process.exit(1);
|
|
323
|
+
}
|
|
324
|
+
let secretValue;
|
|
325
|
+
if (usingJson) {
|
|
326
|
+
const raw = opts.json;
|
|
327
|
+
try {
|
|
328
|
+
JSON.parse(raw);
|
|
329
|
+
} catch (err) {
|
|
330
|
+
printError(
|
|
331
|
+
`Invalid JSON passed to --json: ${err instanceof Error ? err.message : String(err)}`
|
|
332
|
+
);
|
|
333
|
+
process.exit(1);
|
|
334
|
+
}
|
|
335
|
+
secretValue = raw;
|
|
336
|
+
} else if (usingFile) {
|
|
337
|
+
let raw;
|
|
338
|
+
try {
|
|
339
|
+
raw = await readFile(opts.fromFile, "utf8");
|
|
340
|
+
} catch (err) {
|
|
341
|
+
printError(
|
|
342
|
+
`Failed to read file "${opts.fromFile}": ${err instanceof Error ? err.message : String(err)}`
|
|
343
|
+
);
|
|
344
|
+
process.exit(1);
|
|
345
|
+
}
|
|
346
|
+
try {
|
|
347
|
+
JSON.parse(raw);
|
|
348
|
+
} catch (err) {
|
|
349
|
+
printError(
|
|
350
|
+
`File "${opts.fromFile}" does not contain valid JSON: ${err instanceof Error ? err.message : String(err)}`
|
|
351
|
+
);
|
|
352
|
+
process.exit(1);
|
|
353
|
+
}
|
|
354
|
+
secretValue = raw;
|
|
355
|
+
} else if (value !== void 0) {
|
|
356
|
+
secretValue = value;
|
|
357
|
+
} else {
|
|
358
|
+
const stdin = await readStdin();
|
|
359
|
+
if (!stdin) {
|
|
307
360
|
printError("No value provided. Pass as argument or via stdin.");
|
|
308
361
|
process.exit(1);
|
|
309
362
|
}
|
|
363
|
+
secretValue = stdin;
|
|
310
364
|
}
|
|
311
365
|
const s = spinner2();
|
|
312
366
|
s.start(`Setting secret ${name}...`);
|
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/bin.ts","../src/commands/deploy.ts","../src/lib/api-client.ts","../src/lib/env.ts","../src/lib/config-loader.ts","../src/lib/output.ts","../src/commands/secrets.ts","../src/commands/validate.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { deployCommand } from './commands/deploy';\nimport { secretsCommand } from './commands/secrets';\nimport { validateCommand } from './commands/validate';\n\nconst pkg = JSON.parse(\n readFileSync(\n join(dirname(fileURLToPath(import.meta.url)), '../package.json'),\n 'utf8',\n ),\n) as { version: string };\n\nconst program = new Command();\n\nprogram\n .name('rawdash')\n .description('Rawdash CLI — deploy and manage your dashboard config')\n .version(pkg.version);\n\nprogram.addCommand(deployCommand);\nprogram.addCommand(secretsCommand);\nprogram.addCommand(validateCommand);\n\nprogram.parseAsync(process.argv).catch((err: unknown) => {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n});\n","import { confirm, isCancel, spinner } from '@clack/prompts';\nimport { Command } from 'commander';\n\nimport { postConfig } from '../lib/api-client';\nimport { findConfigFile, loadConfig } from '../lib/config-loader';\nimport { requireApiKey } from '../lib/env';\nimport { printDiff, printError, printSuccess } from '../lib/output';\n\nexport const deployCommand = new Command('deploy')\n .description('Deploy rawdash.config.ts to the server')\n .option('--config <path>', 'path to rawdash.config.ts')\n .option('--dry-run', 'validate and diff without persisting')\n .option('--yes', 'skip confirmation prompt (useful in CI)')\n .action(\n async (opts: { config?: string; dryRun?: boolean; yes?: boolean }) => {\n requireApiKey();\n\n const configPath = await findConfigFile(opts.config).catch(\n (err: unknown) => {\n printError(err instanceof Error ? err.message : String(err));\n process.exit(2);\n },\n );\n\n const s = spinner();\n s.start('Loading config...');\n\n const config = await loadConfig(configPath).catch((err: unknown) => {\n s.stop('Failed to load config');\n printError(err instanceof Error ? err.message : String(err));\n process.exit(2);\n });\n s.stop('Config loaded');\n\n s.start('Fetching diff...');\n const previewResult = await postConfig(config, true);\n s.stop('');\n\n if (!previewResult.ok) {\n printError(previewResult.error);\n process.exit(exitCodeForStatus(previewResult.status));\n }\n\n printDiff(previewResult.diff);\n\n if (opts.dryRun) {\n printSuccess('Dry run complete — no changes applied');\n return;\n }\n\n if (!opts.yes) {\n const confirmed = await confirm({ message: 'Apply this diff?' });\n if (isCancel(confirmed) || !confirmed) {\n console.log('Aborted.');\n process.exit(0);\n }\n }\n\n s.start('Deploying...');\n const deployResult = await postConfig(config, false);\n s.stop('');\n\n if (!deployResult.ok) {\n printError(deployResult.error);\n process.exit(exitCodeForStatus(deployResult.status));\n }\n\n printSuccess('Deployed');\n },\n );\n\nfunction exitCodeForStatus(status: number): number {\n if (status === 401 || status === 403) {\n return 3;\n }\n if (status === 409) {\n return 4;\n }\n if (status === 422) {\n return 2;\n }\n return 1;\n}\n","import { type DashboardConfig, toWireConfig } from '@rawdash/core';\n\nimport { getEnv } from './env';\n\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\nexport interface Diff<T> {\n added: T[];\n removed: T[];\n modified: T[];\n}\n\nexport interface CloudConnectorRecord {\n name: string;\n connectorId: string;\n displayName?: string | null;\n config: Record<string, unknown>;\n syncIntervalSeconds?: number;\n enabled?: boolean;\n}\n\nexport interface CloudDashboardRecord {\n id: string;\n name: string;\n slug: string;\n config: Record<string, unknown>;\n}\n\nexport interface ConfigDiff {\n connectors: Diff<CloudConnectorRecord>;\n dashboards: Diff<CloudDashboardRecord>;\n}\n\nexport interface DeploySuccess {\n ok: true;\n diff: ConfigDiff;\n}\n\nexport interface DeployFailure {\n ok: false;\n error: string;\n status: number;\n conflicts?: string[];\n}\n\nexport type DeployResult = DeploySuccess | DeployFailure;\n\nexport interface CloudSecret {\n name: string;\n lastRotatedAt: string | null;\n}\n\nexport class ApiError extends Error {\n constructor(\n message: string,\n public readonly status: number,\n ) {\n super(message);\n this.name = 'ApiError';\n }\n}\n\nexport async function postConfig(\n config: DashboardConfig,\n dryRun: boolean,\n): Promise<DeployResult> {\n const { url, apiKey } = getEnv();\n const endpoint = `${url}/config${dryRun ? '?dryRun=true' : ''}`;\n\n let res: Response;\n try {\n res = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey ?? ''}`,\n },\n body: JSON.stringify(toWireConfig(config)),\n signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS),\n });\n } catch (err) {\n const isTimeout =\n err instanceof Error &&\n (err.name === 'AbortError' || err.name === 'TimeoutError');\n return {\n ok: false,\n error: isTimeout\n ? 'Request timed out'\n : `Network error: ${err instanceof Error ? err.message : String(err)}`,\n status: 0,\n };\n }\n\n if (res.ok) {\n const diff = (await res.json()) as ConfigDiff;\n return { ok: true, diff };\n }\n\n return buildDeployFailure(res);\n}\n\nasync function buildDeployFailure(res: Response): Promise<DeployFailure> {\n const { body, text } = await readErrorBody(res);\n const rawMessage = body.error ?? body.message ?? (text || res.statusText);\n\n let error: string;\n if (res.status === 401) {\n error = `API key invalid or revoked. Check RAWDASH_API_KEY. (${rawMessage})`;\n } else if (res.status === 403) {\n error = `Key lacks config:write scope. Get a new key with broader scope. (${rawMessage})`;\n } else if (res.status === 409) {\n error = `Org is in ui source-of-truth mode. Switch to git mode in cloud settings, or push UI changes back into your config first.`;\n } else if (res.status === 422) {\n error = `Validation failed: ${rawMessage}`;\n } else {\n error = `Request failed (${res.status}): ${rawMessage}`;\n }\n\n return { ok: false, error, status: res.status, conflicts: body.conflicts };\n}\n\nexport async function setSecret(name: string, value: string): Promise<void> {\n const { url, apiKey } = getEnv();\n\n let res: Response;\n try {\n res = await fetch(`${url}/secrets`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey ?? ''}`,\n },\n body: JSON.stringify({ name, value }),\n signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS),\n });\n } catch (err) {\n throw new ApiError(wrapFetchError(err), 0);\n }\n\n if (!res.ok) {\n await throwApiError(res);\n }\n}\n\nexport async function listSecrets(): Promise<CloudSecret[]> {\n const { url, apiKey } = getEnv();\n\n let res: Response;\n try {\n res = await fetch(`${url}/secrets`, {\n headers: { Authorization: `Bearer ${apiKey ?? ''}` },\n signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS),\n });\n } catch (err) {\n throw new ApiError(wrapFetchError(err), 0);\n }\n\n if (!res.ok) {\n await throwApiError(res);\n }\n const body = (await res.json()) as { secrets: CloudSecret[] };\n return body.secrets;\n}\n\nexport async function removeSecret(name: string): Promise<void> {\n const { url, apiKey } = getEnv();\n\n let res: Response;\n try {\n res = await fetch(`${url}/secrets/${encodeURIComponent(name)}`, {\n method: 'DELETE',\n headers: { Authorization: `Bearer ${apiKey ?? ''}` },\n signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS),\n });\n } catch (err) {\n throw new ApiError(wrapFetchError(err), 0);\n }\n\n if (!res.ok) {\n await throwApiError(res);\n }\n}\n\nfunction wrapFetchError(err: unknown): string {\n if (\n err instanceof Error &&\n (err.name === 'AbortError' || err.name === 'TimeoutError')\n ) {\n return 'Request timed out';\n }\n return `Network error: ${err instanceof Error ? err.message : String(err)}`;\n}\n\nasync function throwApiError(res: Response): Promise<never> {\n const { body, text } = await readErrorBody(res);\n const message = body.error ?? body.message ?? (text || res.statusText);\n throw new ApiError(`API error (${res.status}): ${message}`, res.status);\n}\n\nasync function readErrorBody(res: Response): Promise<{\n body: { error?: string; message?: string; conflicts?: string[] };\n text: string;\n}> {\n const text = await res.text();\n const contentType = res.headers.get('content-type') ?? '';\n if (contentType.includes('application/json')) {\n try {\n return {\n body: JSON.parse(text) as {\n error?: string;\n message?: string;\n conflicts?: string[];\n },\n text,\n };\n } catch {\n // body claimed JSON but wasn't — fall through to text\n }\n }\n return { body: {}, text };\n}\n","export function getEnv(): { url: string; apiKey: string | undefined } {\n return {\n url: process.env['RAWDASH_URL'] ?? 'https://api.rawdash.dev',\n apiKey: process.env['RAWDASH_API_KEY'],\n };\n}\n\nexport function requireApiKey(): string {\n const { apiKey } = getEnv();\n if (!apiKey) {\n console.error('RAWDASH_API_KEY is not set. Set it in your environment.');\n process.exit(3);\n }\n return apiKey;\n}\n","import { type DashboardConfig, defineConfig } from '@rawdash/core';\nimport { existsSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport { tsImport } from 'tsx/esm/api';\n\nexport async function findConfigFile(explicitPath?: string): Promise<string> {\n if (explicitPath) {\n const abs = resolve(explicitPath);\n if (!existsSync(abs)) {\n throw new Error(`Config file not found: ${abs}`);\n }\n return abs;\n }\n\n let dir = process.cwd();\n for (;;) {\n const candidate = join(dir, 'rawdash.config.ts');\n if (existsSync(candidate)) {\n return candidate;\n }\n const parent = dirname(dir);\n if (parent === dir) {\n break;\n }\n dir = parent;\n }\n\n throw new Error(\n 'Could not find rawdash.config.ts. Pass --config <path> to specify it explicitly.',\n );\n}\n\nexport async function loadConfig(configPath: string): Promise<DashboardConfig> {\n const mod = await tsImport(configPath, import.meta.url);\n const config: unknown =\n (mod as { default?: unknown; config?: unknown }).default ??\n (mod as { config?: unknown }).config;\n if (!config || typeof config !== 'object') {\n throw new Error(\n `${configPath} must export a default config (result of defineConfig())`,\n );\n }\n return defineConfig(config as Parameters<typeof defineConfig>[0]);\n}\n","import pc from 'picocolors';\n\nimport type {\n CloudConnectorRecord,\n CloudDashboardRecord,\n ConfigDiff,\n Diff,\n} from './api-client';\n\nexport function printDiff(diff: ConfigDiff): void {\n printDiffSection('Connectors', diff.connectors, (c) => c.name);\n printDiffSection('Dashboards', diff.dashboards, (d) => d.slug);\n}\n\nfunction printDiffSection<\n T extends CloudConnectorRecord | CloudDashboardRecord,\n>(label: string, diff: Diff<T>, getName: (t: T) => string): void {\n if (\n diff.added.length === 0 &&\n diff.modified.length === 0 &&\n diff.removed.length === 0\n ) {\n console.log(pc.dim(` ${label}: no changes`));\n return;\n }\n console.log(pc.bold(` ${label}:`));\n for (const item of diff.added) {\n console.log(pc.green(` + ${getName(item)}`));\n }\n for (const item of diff.modified) {\n console.log(pc.yellow(` ~ ${getName(item)}`));\n }\n for (const item of diff.removed) {\n console.log(pc.red(` - ${getName(item)}`));\n }\n}\n\nexport function printError(message: string): void {\n console.error(pc.red(`✗ ${message}`));\n}\n\nexport function printSuccess(message: string): void {\n console.log(pc.green(`✓ ${message}`));\n}\n","import { spinner } from '@clack/prompts';\nimport { Command } from 'commander';\n\nimport {\n ApiError,\n listSecrets,\n removeSecret,\n setSecret,\n} from '../lib/api-client';\nimport { requireApiKey } from '../lib/env';\nimport { printError, printSuccess } from '../lib/output';\n\nexport const secretsCommand = new Command('secrets').description(\n 'Manage secrets',\n);\n\nsecretsCommand\n .command('set <name> [value]')\n .description('Set a secret (reads value from stdin if not provided)')\n .action(async (name: string, value?: string) => {\n requireApiKey();\n\n let secretValue = value;\n if (secretValue === undefined) {\n secretValue = await readStdin();\n if (!secretValue) {\n printError('No value provided. Pass as argument or via stdin.');\n process.exit(1);\n }\n }\n\n const s = spinner();\n s.start(`Setting secret ${name}...`);\n try {\n await setSecret(name, secretValue);\n s.stop('');\n printSuccess(`Secret ${name} set`);\n } catch (err) {\n s.stop('');\n printError(err instanceof Error ? err.message : String(err));\n process.exit(authExitCode(err));\n }\n });\n\nsecretsCommand\n .command('list')\n .description('List all secrets (names and last-rotated timestamps)')\n .action(async () => {\n requireApiKey();\n\n const s = spinner();\n s.start('Fetching secrets...');\n try {\n const secrets = await listSecrets();\n s.stop('');\n if (secrets.length === 0) {\n console.log('No secrets configured.');\n return;\n }\n for (const { name, lastRotatedAt } of secrets) {\n const ts = lastRotatedAt\n ? new Date(lastRotatedAt).toLocaleString()\n : 'never';\n console.log(` ${name} (last rotated: ${ts})`);\n }\n } catch (err) {\n s.stop('');\n printError(err instanceof Error ? err.message : String(err));\n process.exit(authExitCode(err));\n }\n });\n\nsecretsCommand\n .command('remove <name>')\n .description('Remove a secret')\n .action(async (name: string) => {\n requireApiKey();\n\n const s = spinner();\n s.start(`Removing secret ${name}...`);\n try {\n await removeSecret(name);\n s.stop('');\n printSuccess(`Secret ${name} removed`);\n } catch (err) {\n s.stop('');\n printError(err instanceof Error ? err.message : String(err));\n process.exit(authExitCode(err));\n }\n });\n\nasync function readStdin(): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n process.stdin.on('data', (chunk: Buffer) => chunks.push(chunk));\n process.stdin.on('end', () =>\n resolve(Buffer.concat(chunks).toString('utf8')),\n );\n process.stdin.on('error', reject);\n });\n}\n\nfunction authExitCode(err: unknown): number {\n if (err instanceof ApiError && (err.status === 401 || err.status === 403)) {\n return 3;\n }\n return 1;\n}\n","import { Command } from 'commander';\n\nimport { findConfigFile, loadConfig } from '../lib/config-loader';\nimport { printError, printSuccess } from '../lib/output';\n\nexport const validateCommand = new Command('validate')\n .description('Validate rawdash.config.ts locally without network access')\n .option('--config <path>', 'path to rawdash.config.ts')\n .action(async (opts: { config?: string }) => {\n const configPath = await findConfigFile(opts.config).catch(\n (err: unknown) => {\n printError(err instanceof Error ? err.message : String(err));\n process.exit(2);\n },\n );\n\n try {\n const config = await loadConfig(configPath);\n console.log(JSON.stringify(config, null, 2));\n printSuccess('Config is valid');\n } catch (err) {\n printError(err instanceof Error ? err.message : String(err));\n process.exit(2);\n }\n });\n"],"mappings":"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","names":["Command","dirname","join","spinner","Command","Command","spinner","resolve","Command","Command","join","dirname","Command"]}
|
|
1
|
+
{"version":3,"sources":["../src/bin.ts","../src/commands/deploy.ts","../src/lib/api-client.ts","../src/lib/env.ts","../src/lib/config-loader.ts","../src/lib/output.ts","../src/commands/secrets.ts","../src/commands/validate.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { deployCommand } from './commands/deploy';\nimport { secretsCommand } from './commands/secrets';\nimport { validateCommand } from './commands/validate';\n\nconst pkg = JSON.parse(\n readFileSync(\n join(dirname(fileURLToPath(import.meta.url)), '../package.json'),\n 'utf8',\n ),\n) as { version: string };\n\nconst program = new Command();\n\nprogram\n .name('rawdash')\n .description('Rawdash CLI — deploy and manage your dashboard config')\n .version(pkg.version);\n\nprogram.addCommand(deployCommand);\nprogram.addCommand(secretsCommand);\nprogram.addCommand(validateCommand);\n\nprogram.parseAsync(process.argv).catch((err: unknown) => {\n console.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n});\n","import { confirm, isCancel, spinner } from '@clack/prompts';\nimport { Command } from 'commander';\n\nimport { postConfig } from '../lib/api-client';\nimport { findConfigFile, loadConfig } from '../lib/config-loader';\nimport { requireApiKey } from '../lib/env';\nimport { printDiff, printError, printSuccess } from '../lib/output';\n\nexport const deployCommand = new Command('deploy')\n .description('Deploy rawdash.config.ts to the server')\n .option('--config <path>', 'path to rawdash.config.ts')\n .option('--dry-run', 'validate and diff without persisting')\n .option('--yes', 'skip confirmation prompt (useful in CI)')\n .action(\n async (opts: { config?: string; dryRun?: boolean; yes?: boolean }) => {\n requireApiKey();\n\n const configPath = await findConfigFile(opts.config).catch(\n (err: unknown) => {\n printError(err instanceof Error ? err.message : String(err));\n process.exit(2);\n },\n );\n\n const s = spinner();\n s.start('Loading config...');\n\n const config = await loadConfig(configPath).catch((err: unknown) => {\n s.stop('Failed to load config');\n printError(err instanceof Error ? err.message : String(err));\n process.exit(2);\n });\n s.stop('Config loaded');\n\n s.start('Fetching diff...');\n const previewResult = await postConfig(config, true);\n s.stop('');\n\n if (!previewResult.ok) {\n printError(previewResult.error);\n process.exit(exitCodeForStatus(previewResult.status));\n }\n\n printDiff(previewResult.diff);\n\n if (opts.dryRun) {\n printSuccess('Dry run complete — no changes applied');\n return;\n }\n\n if (!opts.yes) {\n const confirmed = await confirm({ message: 'Apply this diff?' });\n if (isCancel(confirmed) || !confirmed) {\n console.log('Aborted.');\n process.exit(0);\n }\n }\n\n s.start('Deploying...');\n const deployResult = await postConfig(config, false);\n s.stop('');\n\n if (!deployResult.ok) {\n printError(deployResult.error);\n process.exit(exitCodeForStatus(deployResult.status));\n }\n\n printSuccess('Deployed');\n },\n );\n\nfunction exitCodeForStatus(status: number): number {\n if (status === 401 || status === 403) {\n return 3;\n }\n if (status === 409) {\n return 4;\n }\n if (status === 422) {\n return 2;\n }\n return 1;\n}\n","import { type DashboardConfig, toWireConfig } from '@rawdash/core';\n\nimport { getEnv } from './env';\n\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\nexport interface Diff<T> {\n added: T[];\n removed: T[];\n modified: T[];\n}\n\nexport interface CloudConnectorRecord {\n name: string;\n connectorId: string;\n displayName?: string | null;\n config: Record<string, unknown>;\n syncIntervalSeconds?: number;\n enabled?: boolean;\n}\n\nexport interface CloudDashboardRecord {\n id: string;\n name: string;\n slug: string;\n config: Record<string, unknown>;\n}\n\nexport interface ConfigDiff {\n connectors: Diff<CloudConnectorRecord>;\n dashboards: Diff<CloudDashboardRecord>;\n}\n\nexport interface DeploySuccess {\n ok: true;\n diff: ConfigDiff;\n}\n\nexport interface DeployFailure {\n ok: false;\n error: string;\n status: number;\n conflicts?: string[];\n}\n\nexport type DeployResult = DeploySuccess | DeployFailure;\n\nexport interface CloudSecret {\n name: string;\n lastRotatedAt: string | null;\n}\n\nexport class ApiError extends Error {\n constructor(\n message: string,\n public readonly status: number,\n ) {\n super(message);\n this.name = 'ApiError';\n }\n}\n\nexport async function postConfig(\n config: DashboardConfig,\n dryRun: boolean,\n): Promise<DeployResult> {\n const { url, apiKey } = getEnv();\n const endpoint = `${url}/config${dryRun ? '?dryRun=true' : ''}`;\n\n let res: Response;\n try {\n res = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey ?? ''}`,\n },\n body: JSON.stringify(toWireConfig(config)),\n signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS),\n });\n } catch (err) {\n const isTimeout =\n err instanceof Error &&\n (err.name === 'AbortError' || err.name === 'TimeoutError');\n return {\n ok: false,\n error: isTimeout\n ? 'Request timed out'\n : `Network error: ${err instanceof Error ? err.message : String(err)}`,\n status: 0,\n };\n }\n\n if (res.ok) {\n const diff = (await res.json()) as ConfigDiff;\n return { ok: true, diff };\n }\n\n return buildDeployFailure(res);\n}\n\nasync function buildDeployFailure(res: Response): Promise<DeployFailure> {\n const { body, text } = await readErrorBody(res);\n const rawMessage = body.error ?? body.message ?? (text || res.statusText);\n\n let error: string;\n if (res.status === 401) {\n error = `API key invalid or revoked. Check RAWDASH_API_KEY. (${rawMessage})`;\n } else if (res.status === 403) {\n error = `Key lacks config:write scope. Get a new key with broader scope. (${rawMessage})`;\n } else if (res.status === 409) {\n error = `Org is in ui source-of-truth mode. Switch to git mode in cloud settings, or push UI changes back into your config first.`;\n } else if (res.status === 422) {\n error = `Validation failed: ${rawMessage}`;\n } else {\n error = `Request failed (${res.status}): ${rawMessage}`;\n }\n\n return { ok: false, error, status: res.status, conflicts: body.conflicts };\n}\n\nexport async function setSecret(name: string, value: string): Promise<void> {\n const { url, apiKey } = getEnv();\n\n let res: Response;\n try {\n res = await fetch(`${url}/secrets`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey ?? ''}`,\n },\n body: JSON.stringify({ name, value }),\n signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS),\n });\n } catch (err) {\n throw new ApiError(wrapFetchError(err), 0);\n }\n\n if (!res.ok) {\n await throwApiError(res);\n }\n}\n\nexport async function listSecrets(): Promise<CloudSecret[]> {\n const { url, apiKey } = getEnv();\n\n let res: Response;\n try {\n res = await fetch(`${url}/secrets`, {\n headers: { Authorization: `Bearer ${apiKey ?? ''}` },\n signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS),\n });\n } catch (err) {\n throw new ApiError(wrapFetchError(err), 0);\n }\n\n if (!res.ok) {\n await throwApiError(res);\n }\n const body = (await res.json()) as { secrets: CloudSecret[] };\n return body.secrets;\n}\n\nexport async function removeSecret(name: string): Promise<void> {\n const { url, apiKey } = getEnv();\n\n let res: Response;\n try {\n res = await fetch(`${url}/secrets/${encodeURIComponent(name)}`, {\n method: 'DELETE',\n headers: { Authorization: `Bearer ${apiKey ?? ''}` },\n signal: AbortSignal.timeout(DEFAULT_TIMEOUT_MS),\n });\n } catch (err) {\n throw new ApiError(wrapFetchError(err), 0);\n }\n\n if (!res.ok) {\n await throwApiError(res);\n }\n}\n\nfunction wrapFetchError(err: unknown): string {\n if (\n err instanceof Error &&\n (err.name === 'AbortError' || err.name === 'TimeoutError')\n ) {\n return 'Request timed out';\n }\n return `Network error: ${err instanceof Error ? err.message : String(err)}`;\n}\n\nasync function throwApiError(res: Response): Promise<never> {\n const { body, text } = await readErrorBody(res);\n const message = body.error ?? body.message ?? (text || res.statusText);\n throw new ApiError(`API error (${res.status}): ${message}`, res.status);\n}\n\nasync function readErrorBody(res: Response): Promise<{\n body: { error?: string; message?: string; conflicts?: string[] };\n text: string;\n}> {\n const text = await res.text();\n const contentType = res.headers.get('content-type') ?? '';\n if (contentType.includes('application/json')) {\n try {\n return {\n body: JSON.parse(text) as {\n error?: string;\n message?: string;\n conflicts?: string[];\n },\n text,\n };\n } catch {\n // body claimed JSON but wasn't — fall through to text\n }\n }\n return { body: {}, text };\n}\n","export function getEnv(): { url: string; apiKey: string | undefined } {\n return {\n url: process.env['RAWDASH_URL'] ?? 'https://api.rawdash.dev',\n apiKey: process.env['RAWDASH_API_KEY'],\n };\n}\n\nexport function requireApiKey(): string {\n const { apiKey } = getEnv();\n if (!apiKey) {\n console.error('RAWDASH_API_KEY is not set. Set it in your environment.');\n process.exit(3);\n }\n return apiKey;\n}\n","import { type DashboardConfig, defineConfig } from '@rawdash/core';\nimport { existsSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\nimport { tsImport } from 'tsx/esm/api';\n\nexport async function findConfigFile(explicitPath?: string): Promise<string> {\n if (explicitPath) {\n const abs = resolve(explicitPath);\n if (!existsSync(abs)) {\n throw new Error(`Config file not found: ${abs}`);\n }\n return abs;\n }\n\n let dir = process.cwd();\n for (;;) {\n const candidate = join(dir, 'rawdash.config.ts');\n if (existsSync(candidate)) {\n return candidate;\n }\n const parent = dirname(dir);\n if (parent === dir) {\n break;\n }\n dir = parent;\n }\n\n throw new Error(\n 'Could not find rawdash.config.ts. Pass --config <path> to specify it explicitly.',\n );\n}\n\nexport async function loadConfig(configPath: string): Promise<DashboardConfig> {\n const mod = await tsImport(configPath, import.meta.url);\n const config: unknown =\n (mod as { default?: unknown; config?: unknown }).default ??\n (mod as { config?: unknown }).config;\n if (!config || typeof config !== 'object') {\n throw new Error(\n `${configPath} must export a default config (result of defineConfig())`,\n );\n }\n return defineConfig(config as Parameters<typeof defineConfig>[0]);\n}\n","import pc from 'picocolors';\n\nimport type {\n CloudConnectorRecord,\n CloudDashboardRecord,\n ConfigDiff,\n Diff,\n} from './api-client';\n\nexport function printDiff(diff: ConfigDiff): void {\n printDiffSection('Connectors', diff.connectors, (c) => c.name);\n printDiffSection('Dashboards', diff.dashboards, (d) => d.slug);\n}\n\nfunction printDiffSection<\n T extends CloudConnectorRecord | CloudDashboardRecord,\n>(label: string, diff: Diff<T>, getName: (t: T) => string): void {\n if (\n diff.added.length === 0 &&\n diff.modified.length === 0 &&\n diff.removed.length === 0\n ) {\n console.log(pc.dim(` ${label}: no changes`));\n return;\n }\n console.log(pc.bold(` ${label}:`));\n for (const item of diff.added) {\n console.log(pc.green(` + ${getName(item)}`));\n }\n for (const item of diff.modified) {\n console.log(pc.yellow(` ~ ${getName(item)}`));\n }\n for (const item of diff.removed) {\n console.log(pc.red(` - ${getName(item)}`));\n }\n}\n\nexport function printError(message: string): void {\n console.error(pc.red(`✗ ${message}`));\n}\n\nexport function printSuccess(message: string): void {\n console.log(pc.green(`✓ ${message}`));\n}\n","import { spinner } from '@clack/prompts';\nimport { Command } from 'commander';\nimport { readFile } from 'node:fs/promises';\n\nimport {\n ApiError,\n listSecrets,\n removeSecret,\n setSecret,\n} from '../lib/api-client';\nimport { requireApiKey } from '../lib/env';\nimport { printError, printSuccess } from '../lib/output';\n\nexport const secretsCommand = new Command('secrets').description(\n 'Manage secrets',\n);\n\ninterface SetOptions {\n json?: string;\n fromFile?: string;\n}\n\nsecretsCommand\n .command('set <name> [value]')\n .description(\n 'Set a secret. Pass value as argument, via stdin, or as structured JSON via --json / --from-file.',\n )\n .option(\n '--json <json>',\n 'Set the secret to a JSON-encoded value (object, array, etc.). Validated before sending.',\n )\n .option(\n '--from-file <path>',\n 'Read the secret value as JSON from a file. Validated before sending.',\n )\n .action(async (name: string, value: string | undefined, opts: SetOptions) => {\n requireApiKey();\n\n const usingJson = opts.json !== undefined;\n const usingFile = opts.fromFile !== undefined;\n\n if (usingJson && usingFile) {\n printError('Cannot use --json and --from-file together.');\n process.exit(1);\n }\n if ((usingJson || usingFile) && value !== undefined) {\n printError(\n 'Cannot combine a positional value with --json or --from-file.',\n );\n process.exit(1);\n }\n\n let secretValue: string;\n if (usingJson) {\n const raw = opts.json!;\n try {\n JSON.parse(raw);\n } catch (err) {\n printError(\n `Invalid JSON passed to --json: ${err instanceof Error ? err.message : String(err)}`,\n );\n process.exit(1);\n }\n secretValue = raw;\n } else if (usingFile) {\n let raw: string;\n try {\n raw = await readFile(opts.fromFile!, 'utf8');\n } catch (err) {\n printError(\n `Failed to read file \"${opts.fromFile}\": ${err instanceof Error ? err.message : String(err)}`,\n );\n process.exit(1);\n }\n try {\n JSON.parse(raw);\n } catch (err) {\n printError(\n `File \"${opts.fromFile}\" does not contain valid JSON: ${err instanceof Error ? err.message : String(err)}`,\n );\n process.exit(1);\n }\n secretValue = raw;\n } else if (value !== undefined) {\n secretValue = value;\n } else {\n const stdin = await readStdin();\n if (!stdin) {\n printError('No value provided. Pass as argument or via stdin.');\n process.exit(1);\n }\n secretValue = stdin;\n }\n\n const s = spinner();\n s.start(`Setting secret ${name}...`);\n try {\n await setSecret(name, secretValue);\n s.stop('');\n printSuccess(`Secret ${name} set`);\n } catch (err) {\n s.stop('');\n printError(err instanceof Error ? err.message : String(err));\n process.exit(authExitCode(err));\n }\n });\n\nsecretsCommand\n .command('list')\n .description('List all secrets (names and last-rotated timestamps)')\n .action(async () => {\n requireApiKey();\n\n const s = spinner();\n s.start('Fetching secrets...');\n try {\n const secrets = await listSecrets();\n s.stop('');\n if (secrets.length === 0) {\n console.log('No secrets configured.');\n return;\n }\n for (const { name, lastRotatedAt } of secrets) {\n const ts = lastRotatedAt\n ? new Date(lastRotatedAt).toLocaleString()\n : 'never';\n console.log(` ${name} (last rotated: ${ts})`);\n }\n } catch (err) {\n s.stop('');\n printError(err instanceof Error ? err.message : String(err));\n process.exit(authExitCode(err));\n }\n });\n\nsecretsCommand\n .command('remove <name>')\n .description('Remove a secret')\n .action(async (name: string) => {\n requireApiKey();\n\n const s = spinner();\n s.start(`Removing secret ${name}...`);\n try {\n await removeSecret(name);\n s.stop('');\n printSuccess(`Secret ${name} removed`);\n } catch (err) {\n s.stop('');\n printError(err instanceof Error ? err.message : String(err));\n process.exit(authExitCode(err));\n }\n });\n\nasync function readStdin(): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n process.stdin.on('data', (chunk: Buffer) => chunks.push(chunk));\n process.stdin.on('end', () =>\n resolve(Buffer.concat(chunks).toString('utf8')),\n );\n process.stdin.on('error', reject);\n });\n}\n\nfunction authExitCode(err: unknown): number {\n if (err instanceof ApiError && (err.status === 401 || err.status === 403)) {\n return 3;\n }\n return 1;\n}\n","import { Command } from 'commander';\n\nimport { findConfigFile, loadConfig } from '../lib/config-loader';\nimport { printError, printSuccess } from '../lib/output';\n\nexport const validateCommand = new Command('validate')\n .description('Validate rawdash.config.ts locally without network access')\n .option('--config <path>', 'path to rawdash.config.ts')\n .action(async (opts: { config?: string }) => {\n const configPath = await findConfigFile(opts.config).catch(\n (err: unknown) => {\n printError(err instanceof Error ? err.message : String(err));\n process.exit(2);\n },\n );\n\n try {\n const config = await loadConfig(configPath);\n console.log(JSON.stringify(config, null, 2));\n printSuccess('Config is valid');\n } catch (err) {\n printError(err instanceof Error ? err.message : String(err));\n process.exit(2);\n }\n });\n"],"mappings":"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","names":["Command","dirname","join","spinner","Command","Command","spinner","resolve","Command","Command","join","dirname","Command"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rawdash/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "Rawdash CLI — deploy and manage your dashboard config",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"commander": "^13.0.0",
|
|
29
29
|
"picocolors": "^1.1.0",
|
|
30
30
|
"tsx": "^4.19.4",
|
|
31
|
-
"@rawdash/core": "0.
|
|
31
|
+
"@rawdash/core": "0.16.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@types/node": "^22.0.0",
|