Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,12 @@ jobs:
cache: npm
- run: npm ci
- run: npm run build
- name: CLI --version matches package.json
run: |
PKG=$(node -p "require('./package.json').version")
CLI=$(node dist/index.js --version)
if [ "$PKG" != "$CLI" ]; then
echo "Version drift: package.json=$PKG, CLI=$CLI"
exit 1
fi
- run: npm test
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@switchbot/openapi-cli",
"version": "1.3.1",
"version": "1.3.2",
"description": "Command-line interface for SwitchBot API v1.1",
"keywords": [
"switchbot",
Expand Down
6 changes: 5 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/usr/bin/env node
import { Command, CommanderError } from 'commander';
import { createRequire } from 'node:module';
import { registerConfigCommand } from './commands/config.js';
import { registerDevicesCommand } from './commands/devices.js';
import { registerScenesCommand } from './commands/scenes.js';
Expand All @@ -16,12 +17,15 @@ import { registerHistoryCommand } from './commands/history.js';
import { registerPlanCommand } from './commands/plan.js';
import { registerCapabilitiesCommand } from './commands/capabilities.js';

const require = createRequire(import.meta.url);
const { version: pkgVersion } = require('../package.json') as { version: string };

const program = new Command();

program
.name('switchbot')
.description('Command-line tool for SwitchBot API v1.1')
.version('2.1.0')
.version(pkgVersion)
.option('--json', 'Output raw JSON response (disables tables; useful for pipes/scripts)')
.option('--format <type>', 'Output format: table (default), json, jsonl, tsv, yaml, id')
.option('--fields <csv>', 'Comma-separated list of columns to include (e.g. --fields=id,name,type)')
Expand Down
2 changes: 1 addition & 1 deletion tests/commands/capabilities.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { registerCapabilitiesCommand } from '../../src/commands/capabilities.js'
/** Build a representative program that mirrors the real CLI structure. */
function makeProgram(): Command {
const p = new Command();
p.name('switchbot').version('2.1.0');
p.name('switchbot').version('0.0.0-test');
p.option('--json', 'Output raw JSON response');
p.option('--format <type>', 'Output format');
p.option('--fields <csv>', 'Column filter');
Expand Down
8 changes: 8 additions & 0 deletions tests/globalSetup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { execSync } from 'node:child_process';

export default function setup(): void {
// Build once before the test run so tests that exercise the compiled CLI
// (e.g. version.test.ts spawning `node dist/index.js --version`) see the
// latest source. Runs once per vitest invocation, not per file.
execSync('npm run build', { stdio: 'inherit' });
}
26 changes: 26 additions & 0 deletions tests/version.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { describe, it, expect } from 'vitest';
import { execFileSync } from 'node:child_process';
import { readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import path from 'node:path';

// Read the real package.json (NOT an import — keeps this decoupled from tsc's
// JSON import assertion setup and mirrors what publish.yml does in CI).
const here = path.dirname(fileURLToPath(import.meta.url));
const pkg = JSON.parse(
readFileSync(path.join(here, '..', 'package.json'), 'utf-8'),
) as { version: string };

describe('CLI --version', () => {
it('matches package.json version', () => {
// Regression guard for the v1.3.1 bug where src/index.ts hardcoded a
// stale version string. execFileSync + process.execPath avoids shell
// quoting and PATH lookup issues on Windows/macOS/Linux.
const out = execFileSync(
process.execPath,
['dist/index.js', '--version'],
{ encoding: 'utf-8' },
).trim();
expect(out).toBe(pkg.version);
});
});
1 change: 1 addition & 0 deletions vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export default defineConfig({
test: {
environment: 'node',
include: ['tests/**/*.test.ts'],
globalSetup: ['./tests/globalSetup.ts'],
coverage: {
provider: 'v8',
include: ['src/**/*.ts'],
Expand Down
Loading