diff --git a/packages/cli/src/commands/artifacts/artifacts.list.ts b/packages/cli/src/commands/artifacts/artifacts.list.ts index 6c9f1f3..3d92276 100644 --- a/packages/cli/src/commands/artifacts/artifacts.list.ts +++ b/packages/cli/src/commands/artifacts/artifacts.list.ts @@ -2,6 +2,7 @@ import { Command } from 'commander'; import { createClient } from '../../client/client.js'; import { step } from '../../utils/step.js'; import { Context } from '../../context/context.js'; +import { Config } from '../../config/config.js'; const list = new Command('list'); @@ -21,7 +22,8 @@ list .option('-a, --limit ', 'Limit', '1000') .action(async () => { const { runId, loadId, offset, limit } = list.opts(); - const context = new Context(); + const config = new Config(); + const context = new Context(config.context); const client = await step('Connecting to server', async () => { return createClient(context); }); diff --git a/packages/cli/src/commands/artifacts/artifacts.pull.ts b/packages/cli/src/commands/artifacts/artifacts.pull.ts index 829d25a..df24f02 100644 --- a/packages/cli/src/commands/artifacts/artifacts.pull.ts +++ b/packages/cli/src/commands/artifacts/artifacts.pull.ts @@ -4,6 +4,7 @@ import { step } from '../../utils/step.js'; import { Context } from '../../context/context.js'; import { dirname, resolve } from 'path'; import { mkdir, writeFile } from 'fs/promises'; +import { Config } from '../../config/config.js'; const pull = new Command('pull'); @@ -12,7 +13,8 @@ pull .argument('', 'Artifact ID') .argument('', 'File to save') .action(async (id, file) => { - const context = new Context(); + const config = new Config(); + const context = new Context(config.context); const target = resolve(file); const client = await step('Connecting to server', async () => { return createClient(context); diff --git a/packages/cli/src/commands/artifacts/artifacts.remove.ts b/packages/cli/src/commands/artifacts/artifacts.remove.ts index 95a4f2c..ce0cae4 100644 --- a/packages/cli/src/commands/artifacts/artifacts.remove.ts +++ b/packages/cli/src/commands/artifacts/artifacts.remove.ts @@ -3,6 +3,7 @@ import { createClient } from '../../client/client.js'; import { step } from '../../utils/step.js'; import { Context } from '../../context/context.js'; import inquirer from 'inquirer'; +import { Config } from '../../config/config.js'; const remove = new Command('remove'); @@ -22,7 +23,8 @@ remove .option('-a, --limit ', 'Limit', '1000') .action(async () => { const { runId, loadId, offset, limit } = remove.opts(); - const context = new Context(); + const config = new Config(); + const context = new Context(config.context); const client = await step('Connecting to server', async () => { return createClient(context); }); diff --git a/packages/cli/src/commands/auth/auth.login.ts b/packages/cli/src/commands/auth/auth.login.ts index 401a7c5..dd29429 100644 --- a/packages/cli/src/commands/auth/auth.login.ts +++ b/packages/cli/src/commands/auth/auth.login.ts @@ -2,12 +2,14 @@ import { Command } from 'commander'; import inquerer from 'inquirer'; import { Context } from '../../context/context.js'; import { step } from '../../utils/step.js'; +import { Config } from '../../config/config.js'; const login = new Command('login'); login.description('Login to your account'); login.action(async () => { - const context = new Context(); + const config = new Config(); + const context = new Context(config.context); const { host, token } = await inquerer.prompt([ { type: 'input', diff --git a/packages/cli/src/commands/contexts/contexts.current.ts b/packages/cli/src/commands/contexts/contexts.current.ts new file mode 100644 index 0000000..8fbd140 --- /dev/null +++ b/packages/cli/src/commands/contexts/contexts.current.ts @@ -0,0 +1,10 @@ +import { Command } from 'commander'; +import { Config } from '../../config/config.js'; + +const current = new Command('current'); +current.action(async () => { + const config = new Config(); + console.log(config.context); +}); + +export { current }; diff --git a/packages/cli/src/commands/contexts/contexts.list.ts b/packages/cli/src/commands/contexts/contexts.list.ts new file mode 100644 index 0000000..ba9d461 --- /dev/null +++ b/packages/cli/src/commands/contexts/contexts.list.ts @@ -0,0 +1,11 @@ +import { Command } from 'commander'; +import { Context } from '../../context/context.js'; + +const list = new Command('list'); +list.alias('ls').description('List contexts'); +list.action(async () => { + const contexts = await Context.list(); + console.table(contexts); +}); + +export { list }; diff --git a/packages/cli/src/commands/contexts/contexts.ts b/packages/cli/src/commands/contexts/contexts.ts new file mode 100644 index 0000000..f4a207f --- /dev/null +++ b/packages/cli/src/commands/contexts/contexts.ts @@ -0,0 +1,12 @@ +import { Command } from 'commander'; +import { list } from './contexts.list.js'; +import { use } from './contexts.use.js'; +import { current } from './contexts.current.js'; + +const contexts = new Command('contexts'); +contexts.description('Manage contexts'); +contexts.addCommand(list); +contexts.addCommand(use); +contexts.addCommand(current); + +export { contexts }; diff --git a/packages/cli/src/commands/contexts/contexts.use.ts b/packages/cli/src/commands/contexts/contexts.use.ts new file mode 100644 index 0000000..56c1e22 --- /dev/null +++ b/packages/cli/src/commands/contexts/contexts.use.ts @@ -0,0 +1,11 @@ +import { Command } from 'commander'; +import { Config } from '../../config/config.js'; + +const use = new Command('use'); + +use.argument('').action(async (name) => { + const config = new Config(); + await config.setContext(name); +}); + +export { use }; diff --git a/packages/cli/src/commands/loads/loads.list.ts b/packages/cli/src/commands/loads/loads.list.ts index ba26373..0a7b4db 100644 --- a/packages/cli/src/commands/loads/loads.list.ts +++ b/packages/cli/src/commands/loads/loads.list.ts @@ -2,6 +2,7 @@ import { Command } from 'commander'; import { createClient } from '../../client/client.js'; import { step } from '../../utils/step.js'; import { Context } from '../../context/context.js'; +import { Config } from '../../config/config.js'; const list = new Command('list'); @@ -9,7 +10,8 @@ list .alias('ls') .description('List loads') .action(async () => { - const context = new Context(); + const config = new Config(); + const context = new Context(config.context); const client = await step('Connecting to server', async () => { return createClient(context); }); diff --git a/packages/cli/src/commands/loads/loads.push.ts b/packages/cli/src/commands/loads/loads.push.ts index dc21b2a..37bc406 100644 --- a/packages/cli/src/commands/loads/loads.push.ts +++ b/packages/cli/src/commands/loads/loads.push.ts @@ -4,6 +4,7 @@ import { createClient } from '../../client/client.js'; import { bundle } from '../../bundler/bundler.js'; import { step } from '../../utils/step.js'; import { Context } from '../../context/context.js'; +import { Config } from '../../config/config.js'; const push = new Command('push'); @@ -15,7 +16,8 @@ push .option('-ai, --auto-install', 'Auto install dependencies', false) .action(async (script) => { const opts = push.opts(); - const context = new Context(); + const config = new Config(); + const context = new Context(config.context); const location = resolve(script); const client = await step('Connecting to server', async () => { return createClient(context); diff --git a/packages/cli/src/commands/logs/logs.list.ts b/packages/cli/src/commands/logs/logs.list.ts index e1bfba2..a87e8c6 100644 --- a/packages/cli/src/commands/logs/logs.list.ts +++ b/packages/cli/src/commands/logs/logs.list.ts @@ -2,6 +2,7 @@ import { Command } from 'commander'; import { createClient } from '../../client/client.js'; import { step } from '../../utils/step.js'; import { Context } from '../../context/context.js'; +import { Config } from '../../config/config.js'; const list = new Command('list'); @@ -23,7 +24,8 @@ list .option('-s, --sort ', 'Sort', 'desc') .action(async () => { const { runId, loadId, severities, offset, limit, order } = list.opts(); - const context = new Context(); + const config = new Config(); + const context = new Context(config.context); const client = await step('Connecting to server', async () => { return createClient(context); }); diff --git a/packages/cli/src/commands/logs/logs.remove.ts b/packages/cli/src/commands/logs/logs.remove.ts index 1adbc48..544fa79 100644 --- a/packages/cli/src/commands/logs/logs.remove.ts +++ b/packages/cli/src/commands/logs/logs.remove.ts @@ -3,6 +3,7 @@ import { createClient } from '../../client/client.js'; import { step } from '../../utils/step.js'; import { Context } from '../../context/context.js'; import inquirer from 'inquirer'; +import { Config } from '../../config/config.js'; const remove = new Command('remove'); @@ -24,7 +25,8 @@ remove .option('-s, --sort ', 'Sort', 'desc') .action(async () => { const { runId, loadId, severities, offset, limit, order } = remove.opts(); - const context = new Context(); + const config = new Config(); + const context = new Context(config.context); const client = await step('Connecting to server', async () => { return createClient(context); }); diff --git a/packages/cli/src/commands/runs/runs.create.ts b/packages/cli/src/commands/runs/runs.create.ts index 2cc2279..076a22b 100644 --- a/packages/cli/src/commands/runs/runs.create.ts +++ b/packages/cli/src/commands/runs/runs.create.ts @@ -2,6 +2,7 @@ import { Command } from 'commander'; import { createClient } from '../../client/client.js'; import { step } from '../../utils/step.js'; import { Context } from '../../context/context.js'; +import { Config } from '../../config/config.js'; const create = new Command('create'); @@ -9,7 +10,8 @@ create .description('Create a new run') .argument('load-id', 'Load ID') .action(async (loadId) => { - const context = new Context(); + const config = new Config(); + const context = new Context(config.context); const client = await step('Connecting to server', async () => { return createClient(context); }); diff --git a/packages/cli/src/commands/runs/runs.list.ts b/packages/cli/src/commands/runs/runs.list.ts index dca5c20..7c973d8 100644 --- a/packages/cli/src/commands/runs/runs.list.ts +++ b/packages/cli/src/commands/runs/runs.list.ts @@ -2,6 +2,7 @@ import { Command } from 'commander'; import { createClient } from '../../client/client.js'; import { step } from '../../utils/step.js'; import { Context } from '../../context/context.js'; +import { Config } from '../../config/config.js'; const list = new Command('list'); @@ -10,7 +11,8 @@ list .description('Find a run') .argument('[load-id]', 'Load ID') .action(async (loadId) => { - const context = new Context(); + const config = new Config(); + const context = new Context(config.context); const client = await step('Connecting to server', async () => { return createClient(context); }); diff --git a/packages/cli/src/commands/secrets/secrets.list.ts b/packages/cli/src/commands/secrets/secrets.list.ts index 7cca018..c306dfd 100644 --- a/packages/cli/src/commands/secrets/secrets.list.ts +++ b/packages/cli/src/commands/secrets/secrets.list.ts @@ -2,6 +2,7 @@ import { Command } from 'commander'; import { createClient } from '../../client/client.js'; import { step } from '../../utils/step.js'; import { Context } from '../../context/context.js'; +import { Config } from '../../config/config.js'; const list = new Command('list'); @@ -19,7 +20,8 @@ list .option('-a, --limit ', 'Limit', '1000') .action(async () => { const { offset, limit } = list.opts(); - const context = new Context(); + const config = new Config(); + const context = new Context(config.context); const client = await step('Connecting to server', async () => { return createClient(context); }); diff --git a/packages/cli/src/commands/secrets/secrets.remove.ts b/packages/cli/src/commands/secrets/secrets.remove.ts index e3ba3ea..5b9376d 100644 --- a/packages/cli/src/commands/secrets/secrets.remove.ts +++ b/packages/cli/src/commands/secrets/secrets.remove.ts @@ -2,6 +2,7 @@ import { Command } from 'commander'; import { createClient } from '../../client/client.js'; import { step } from '../../utils/step.js'; import { Context } from '../../context/context.js'; +import { Config } from '../../config/config.js'; const remove = new Command('remove'); @@ -9,7 +10,8 @@ remove .alias('rm') .argument('') .action(async (id) => { - const context = new Context(); + const config = new Config(); + const context = new Context(config.context); const client = await step('Connecting to server', async () => { return createClient(context); }); diff --git a/packages/cli/src/commands/secrets/secrets.set.ts b/packages/cli/src/commands/secrets/secrets.set.ts index f4f2df3..1da167c 100644 --- a/packages/cli/src/commands/secrets/secrets.set.ts +++ b/packages/cli/src/commands/secrets/secrets.set.ts @@ -2,6 +2,7 @@ import { Command } from 'commander'; import { createClient } from '../../client/client.js'; import { step } from '../../utils/step.js'; import { Context } from '../../context/context.js'; +import { Config } from '../../config/config.js'; const set = new Command('set'); @@ -9,7 +10,8 @@ set .argument('') .argument('[value]') .action(async (id, value) => { - const context = new Context(); + const config = new Config(); + const context = new Context(config.context); const client = await step('Connecting to server', async () => { return createClient(context); }); diff --git a/packages/cli/src/config/config.ts b/packages/cli/src/config/config.ts new file mode 100644 index 0000000..5516d61 --- /dev/null +++ b/packages/cli/src/config/config.ts @@ -0,0 +1,44 @@ +import envPaths from 'env-paths'; +import { existsSync, readFileSync, writeFileSync } from 'fs'; +import { mkdir } from 'fs/promises'; +import { join, dirname } from 'path'; + +type ConfigValues = { + context?: string; +}; + +class Config { + #location: string; + #config?: ConfigValues; + + constructor() { + const paths = envPaths('mini-loader'); + this.#location = join(paths.config, 'config.json'); + if (existsSync(this.#location)) { + this.#config = JSON.parse(readFileSync(this.#location, 'utf-8')); + } + } + + public get context() { + return this.#config?.context || 'default'; + } + + public setContext = (context: string) => { + this.#config = { + ...(this.#config || {}), + context, + }; + this.save(); + }; + + public save = async () => { + if (!this.#config) { + return; + } + const json = JSON.stringify(this.#config); + mkdir(dirname(this.#location), { recursive: true }); + writeFileSync(this.#location, json); + }; +} + +export { Config }; diff --git a/packages/cli/src/context/context.ts b/packages/cli/src/context/context.ts index 4b056bf..aea7684 100644 --- a/packages/cli/src/context/context.ts +++ b/packages/cli/src/context/context.ts @@ -1,7 +1,7 @@ import envPaths from 'env-paths'; import { existsSync, readFileSync, writeFileSync } from 'fs'; -import { mkdir } from 'fs/promises'; -import { dirname } from 'path'; +import { mkdir, readdir } from 'fs/promises'; +import { dirname, join } from 'path'; type ContextValues = { host: string; @@ -12,9 +12,9 @@ class Context { #location: string; #config?: ContextValues; - constructor() { - const paths = envPaths('dws'); - this.#location = paths.config; + constructor(name: string) { + const paths = envPaths('mini-loader'); + this.#location = join(paths.config, 'contexts', name); if (existsSync(this.#location)) { this.#config = JSON.parse(readFileSync(this.#location, 'utf-8')); } @@ -45,6 +45,15 @@ class Context { mkdir(dirname(this.#location), { recursive: true }); writeFileSync(this.#location, json); }; + + public static list = async () => { + const paths = envPaths('mini-loader'); + const location = join(paths.config, 'contexts'); + if (!existsSync(location)) { + return []; + } + return await readdir(location); + }; } export { Context }; diff --git a/packages/cli/src/index.ts b/packages/cli/src/index.ts index ccbea29..c1483d2 100644 --- a/packages/cli/src/index.ts +++ b/packages/cli/src/index.ts @@ -6,6 +6,7 @@ import { artifacts } from './commands/artifacts/artifacts.js'; import { secrets } from './commands/secrets/secrets.js'; import { local } from './commands/local/local.js'; import { auth } from './commands/auth/auth.js'; +import { contexts } from './commands/contexts/contexts.js'; program.addCommand(loads); program.addCommand(runs); @@ -14,5 +15,6 @@ program.addCommand(artifacts); program.addCommand(secrets); program.addCommand(local); program.addCommand(auth); +program.addCommand(contexts); await program.parseAsync();