Skip to content

Commit bab11ae

Browse files
committed
Update @open-audio-stack/core, use shared spinner/json method to format cli output
1 parent 8861678 commit bab11ae

15 files changed

Lines changed: 299 additions & 99 deletions

package-lock.json

Lines changed: 30 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
"node": ">=18"
4040
},
4141
"dependencies": {
42-
"@open-audio-stack/core": "^0.1.45",
42+
"@open-audio-stack/core": "^0.1.47",
4343
"cli-table3": "^0.6.5",
4444
"commander": "^12.1.0",
4545
"ora": "^9.0.0"

src/commands/config.ts

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Command } from 'commander';
22
import { CliOptions } from '../types/options.js';
33
import { ConfigInterface, ConfigLocal, isTests } from '@open-audio-stack/core';
44
import { CONFIG_LOCAL_TEST } from '../data/Config.js';
5+
import { withSpinner } from '../utils.js';
56

67
const config: ConfigLocal = new ConfigLocal(isTests() ? CONFIG_LOCAL_TEST : undefined);
78
const program = new Command();
@@ -13,14 +14,23 @@ configCmd
1314
.option('-l, --log', 'Enable logging')
1415
.description('Get a config setting by key')
1516
.action((key: keyof ConfigInterface, options: CliOptions) => {
16-
if (options.log) config.logEnable();
17-
if (options.json) {
18-
const obj: any = {};
19-
obj[key] = config.get(key);
20-
console.log({ key });
21-
} else {
22-
console.log(config.get(key));
23-
}
17+
return withSpinner(
18+
options,
19+
config as any,
20+
`Get config ${String(key)}`,
21+
async () => {
22+
return { key, value: config.get(key) };
23+
},
24+
(result: any, useJson: boolean) => {
25+
if (useJson) {
26+
const obj: any = {};
27+
obj[result.key] = result.value;
28+
console.log(JSON.stringify(obj, null, 2));
29+
} else {
30+
console.log(result.value);
31+
}
32+
},
33+
);
2434
});
2535

2636
configCmd
@@ -29,12 +39,22 @@ configCmd
2939
.option('-l, --log', 'Enable logging')
3040
.description('Set a config setting by key and value')
3141
.action((key: keyof ConfigInterface, val: any, options: CliOptions) => {
32-
// if (options.log) config.logEnable();
33-
if (options.json) {
34-
const obj: any = {};
35-
obj[key] = config.set(key, val);
36-
console.log(obj);
37-
} else {
38-
console.log(config.set(key, val));
39-
}
42+
return withSpinner(
43+
options,
44+
config as any,
45+
`Set config ${String(key)}`,
46+
async () => {
47+
const res = config.set(key, val);
48+
return { key, value: res };
49+
},
50+
(result: any, useJson: boolean) => {
51+
if (useJson) {
52+
const obj: any = {};
53+
obj[result.key] = result.value;
54+
console.log(JSON.stringify(obj, null, 2));
55+
} else {
56+
console.log(result.value);
57+
}
58+
},
59+
);
4060
});

src/commands/create.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,27 @@
11
import { Command } from 'commander';
22
import { CliOptions } from '../types/options.js';
33
import { ManagerLocal } from '@open-audio-stack/core';
4+
import { withSpinner } from '../utils.js';
45

56
export function create(command: Command, manager: ManagerLocal) {
67
command
7-
.command('create <path>')
8+
.command('create')
9+
.option('-j, --json', 'Output results as json')
810
.option('-l, --log', 'Enable logging')
911
.description('Create a new package locally')
1012
.action(async (path: string, options: CliOptions) => {
11-
if (options.log) manager.logEnable();
12-
else manager.logDisable();
13-
console.log(await manager.create());
14-
console.log(path);
13+
await withSpinner(
14+
options,
15+
manager,
16+
`Create package at ${path}`,
17+
async () => {
18+
const result = await manager.create();
19+
return result;
20+
},
21+
(result: any, useJson: boolean) => {
22+
if (useJson) console.log(JSON.stringify(result, null, 2));
23+
else console.log(result);
24+
},
25+
);
1526
});
1627
}

src/commands/filter.ts

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,37 @@
11
import { Command } from 'commander';
22
import { CliOptions } from '../types/options.js';
33
import { ManagerLocal, PackageVersion } from '@open-audio-stack/core';
4-
import { formatOutput } from '../utils.js';
4+
import { formatOutput, withSpinner } from '../utils.js';
55

66
export function filter(command: Command, manager: ManagerLocal) {
77
command
88
.command('filter <field> <value>')
9+
.option('-j, --json', 'Output results as json')
910
.option('-l, --log', 'Enable logging')
1011
.description('Filter the by field and matching value')
1112
.action((field: keyof PackageVersion, value: string, options: CliOptions) => {
12-
if (options.log) manager.logEnable();
13-
else manager.logDisable();
14-
console.log(formatOutput(manager.filter(pkgVersion => pkgVersion[field] === value)));
13+
return withSpinner(
14+
options,
15+
manager,
16+
`Filter ${manager.type} by ${String(field)}=${value}`,
17+
async () => {
18+
const predicate = (pkgVersion: PackageVersion) => {
19+
const fieldVal: any = (pkgVersion as any)[field];
20+
if (Array.isArray(fieldVal)) {
21+
return fieldVal.some((v: any) => String(v).toLowerCase() === value.toLowerCase());
22+
}
23+
if (typeof fieldVal === 'string') {
24+
return fieldVal.toLowerCase().includes(value.toLowerCase());
25+
}
26+
if (fieldVal === undefined || fieldVal === null) return false;
27+
return String(fieldVal) === value;
28+
};
29+
return manager.filter(predicate);
30+
},
31+
(result: any, useJson: boolean) => {
32+
if (useJson) console.log(JSON.stringify(result, null, 2));
33+
else console.log(formatOutput(result as any));
34+
},
35+
);
1536
});
1637
}

src/commands/get.ts

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,30 @@
11
import { Command } from 'commander';
22
import { CliOptions } from '../types/options.js';
33
import { inputGetParts, ManagerLocal } from '@open-audio-stack/core';
4-
import { formatOutput } from '../utils.js';
4+
import { formatOutput, withSpinner } from '../utils.js';
55

66
export function get(command: Command, manager: ManagerLocal) {
77
command
88
.command('get <input>')
9+
.option('-j, --json', 'Output results as json')
910
.option('-l, --log', 'Enable logging')
1011
.description('Get package metadata from registry')
1112
.action((input: string, options: CliOptions) => {
12-
if (options.log) manager.logEnable();
13-
else manager.logDisable();
14-
const [slug, version] = inputGetParts(input);
15-
const pkg = manager.getPackage(slug);
16-
const versions = version ? [version] : Array.from(pkg?.versions.keys() || new Map().keys());
17-
console.log(formatOutput(pkg, versions));
13+
return withSpinner(
14+
options,
15+
manager,
16+
`Get package ${input}`,
17+
async () => {
18+
const [slug, version] = inputGetParts(input);
19+
const pkg = manager.getPackage(slug);
20+
if (!pkg) throw new Error(`No package found with slug: ${slug}`);
21+
return { pkg, version };
22+
},
23+
(result: any, useJson: boolean) => {
24+
const { pkg, version } = result;
25+
const versions = version ? [version] : Array.from(pkg.versions.keys());
26+
console.log(formatOutput(pkg, versions, useJson));
27+
},
28+
);
1829
});
1930
}

src/commands/install.ts

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,29 @@
11
import { Command } from 'commander';
2-
import ora from 'ora';
32
import { CliOptions } from '../types/options.js';
43
import { inputGetParts, ManagerLocal, isTests } from '@open-audio-stack/core';
4+
import { withSpinner } from '../utils.js';
55

66
export function install(command: Command, manager: ManagerLocal) {
77
command
88
.command('install <input>')
9+
.option('-j, --json', 'Output results as json')
910
.option('-l, --log', 'Enable logging')
1011
.description('Install a package locally by slug/version')
1112
.action(async (input: string, options: CliOptions) => {
12-
if (options.log) manager.logEnable();
13-
else manager.logDisable();
1413
const [slug, version] = inputGetParts(input);
15-
const spinner = ora(`Installing ${slug}${version ? `@${version}` : ''}...`).start();
16-
try {
17-
await manager.install(slug, version);
18-
spinner.succeed(`Installed ${slug}${version ? `@${version}` : ''}`);
19-
if (isTests()) console.log(`Installed ${slug}${version ? `@${version}` : ''}`);
20-
} catch (error) {
21-
const errorMessage = error instanceof Error ? error.message : String(error);
22-
spinner.fail(errorMessage);
23-
if (isTests()) console.log(errorMessage);
24-
}
14+
await withSpinner(
15+
options,
16+
manager,
17+
`Install ${slug}${version ? `@${version}` : ''}`,
18+
async () => {
19+
await manager.install(slug, version);
20+
return { slug, version: version || null, installed: true, isTests: isTests() };
21+
},
22+
(result: any, useJson: boolean) => {
23+
if (useJson)
24+
console.log(JSON.stringify({ slug: result.slug, version: result.version, installed: true }, null, 2));
25+
else if (result.isTests) console.log(`Installed ${result.slug}${result.version ? `@${result.version}` : ''}`);
26+
},
27+
);
2528
});
2629
}

src/commands/list.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Command } from 'commander';
22
import { CliOptions } from '../types/options.js';
33
import { ManagerLocal } from '@open-audio-stack/core';
4-
import { formatOutput } from '../utils.js';
4+
import { formatOutput, withSpinner } from '../utils.js';
55

66
interface ListOptions extends CliOptions {
77
incompatible: boolean;
@@ -13,11 +13,21 @@ export function list(command: Command, manager: ManagerLocal) {
1313
.command('list')
1414
.option('-c, --incompatible', 'List incompatible packages')
1515
.option('-i, --installed', 'Only list installed packages')
16+
.option('-j, --json', 'Output results as json')
1617
.option('-l, --log', 'Enable logging')
1718
.description('List packages')
1819
.action(async (options: ListOptions) => {
19-
if (options.log) manager.logEnable();
20-
else manager.logDisable();
21-
console.log(formatOutput(manager.listPackages(options.installed, options.incompatible)));
20+
await withSpinner(
21+
options,
22+
manager,
23+
`List ${manager.type}`,
24+
async () => {
25+
return manager.listPackages(options.installed, options.incompatible);
26+
},
27+
(result: any, useJson: boolean) => {
28+
if (useJson) console.log(JSON.stringify(result, null, 2));
29+
else console.log(formatOutput(result as any));
30+
},
31+
);
2232
});
2333
}

src/commands/open.ts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,26 @@
11
import { Command } from 'commander';
22
import { CliOptions } from '../types/options.js';
33
import { inputGetParts, ManagerLocal } from '@open-audio-stack/core';
4+
import { withSpinner } from '../utils.js';
45

56
export function open(command: Command, manager: ManagerLocal) {
67
command
78
.command('open <input> [options...]')
89
.option('-l, --log', 'Enable logging')
910
.description('Open a package by slug/version')
1011
.action(async (input: string, options: string[], cliOptions: CliOptions) => {
11-
if (cliOptions.log) manager.logEnable();
12-
else manager.logDisable();
13-
const [slug, version] = inputGetParts(input);
14-
try {
15-
await manager.open(slug, version, options);
16-
} catch (error: any) {
17-
const errorMessage = error instanceof Error ? error.message : String(error);
18-
console.error(errorMessage);
19-
process.exit(1);
20-
}
12+
await withSpinner(
13+
cliOptions,
14+
manager,
15+
`Open ${input}`,
16+
async () => {
17+
const [slug, version] = inputGetParts(input);
18+
await manager.open(slug, version, options);
19+
return { slug, version };
20+
},
21+
() => {
22+
// open is an action side-effect; no additional output required
23+
},
24+
);
2125
});
2226
}

src/commands/scan.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,26 @@
11
import { Command } from 'commander';
22
import { CliOptions } from '../types/options.js';
33
import { ManagerLocal } from '@open-audio-stack/core';
4+
import { withSpinner } from '../utils.js';
45

56
export function scan(command: Command, manager: ManagerLocal) {
67
command
78
.command('scan')
9+
.option('-j, --json', 'Output results as json')
810
.option('-l, --log', 'Enable logging')
911
.description('Scan local packages into cache')
1012
.action(async (options: CliOptions) => {
11-
if (options.log) manager.logEnable();
12-
else manager.logDisable();
13-
manager.scan();
14-
console.log(`${manager.type} scan completed`);
13+
await withSpinner(
14+
options,
15+
manager,
16+
`Scan ${manager.type}`,
17+
async () => {
18+
await manager.scan();
19+
return { type: manager.type, status: 'scan completed' };
20+
},
21+
(result: any, useJson: boolean) => {
22+
if (useJson) console.log(JSON.stringify({ type: result.type, status: result.status }, null, 2));
23+
},
24+
);
1525
});
1626
}

0 commit comments

Comments
 (0)