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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
- The `error:` line is coloured only when stderr is a terminal (and `NO_COLOR` / `--no-color` are not set, or `FORCE_COLOR` asks for it). The decision followed stdout, so `oura-cli sync 2>err.log` on a terminal wrote ANSI codes into the file. (#150)
- `--help` fits an 80-column terminal again, bar the root USAGE line that lists every command. citty padded each OPTIONS row with trailing spaces to column 87, so every row wrapped though its text fitted; the padding is gone. A `db` subcommand's screen names it in full (`USAGE oura-cli db rows …`, banner `(oura-cli db rows v…)`) where it said `db rows`; `db stats` and `db rows` have shorter descriptions so the longer banner still fits. (#147)
- The progress line on a terminal names the collection, as the summary under it does: `syncing sleep` is the sleep collection and `syncing sleep-periods` the sleep periods, where it printed the API endpoint (`daily_sleep`, `sleep`, `vO2_max`, `ring_battery_level`). Its page counter starts again with each request, so a 61-day `fetch hr`, three 30-day requests, counts up to each request's own pages instead of running to page 87; the row count still runs across them. (#129)
- `db rows hr` and `db rows battery` end the table with `day is the UTC date of each sample; rows are selected by the local day in <tz>.` Rows were already bounded on the local day, like `fetch`, while `day` holds the UTC date of the sample, so `db rows battery --day 2026-09-10` in Asia/Dubai listed rows dated 2026-09-09 with nothing on screen to say why. JSON is unchanged. (#131)

## [0.9.1] - 2026-09-15

Expand Down
20 changes: 20 additions & 0 deletions src/commands/db.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,4 +201,24 @@ describe('db rows (#73)', () => {
expect(text.stdout).toContain('No cached ring rows.');
expect(text.stdout).toContain('oura-cli fetch ring');
});

it('says under a timeseries table that day is the UTC date while rows follow the local day (#131)', async () => {
const path = join(tmpdir(), `oura-db-rows-utc-${process.pid}.db`);
const db = new Database(path);
ensureSchema(db);
db.query('INSERT INTO ring_battery_level (timestamp, level, charging, in_charger, day) VALUES (?,?,?,?,?)').run('2026-09-09T22:00:00+00:00', 80, 0, 0, '2026-09-09');
db.close();
const rows = (...collection: string[]) => Bun.spawn(['bun', 'run', 'src/index.ts', '--db', path, '--tz', 'Asia/Dubai', 'db', 'rows', ...collection, '--day', '2026-09-10', '--format', 'table'], { stdout: 'pipe', stderr: 'pipe' });
try {
const battery = rows('battery');
const lines = (await new Response(battery.stdout).text()).trimEnd().split('\n');
expect(await battery.exited).toBe(0);
expect(lines.at(-2)).toBe(' 2026-09-09T22:00:00+00:00 80 0 0 2026-09-09');
expect(lines.at(-1)).toBe(' day is the UTC date of each sample; rows are selected by the local day in Asia/Dubai.');
const tags = rows('tags');
expect(await new Response(tags.stdout).text()).not.toContain('UTC');
Comment on lines +218 to +219

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Daily-table check can pass incorrectly

The tags check reads an empty collection, so it passes even if the note is wrongly added to every nonempty daily table. It also passes if the command fails and writes nothing to stdout. Insert a daily row inside the requested range, assert a successful exit, and then check that its table has no note.

} finally {
for (const suffix of ['', '-wal', '-shm']) rmSync(path + suffix, { force: true });
}
});
});
7 changes: 6 additions & 1 deletion src/commands/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { formatDaySummary, formatWeekTable, formatTrends, formatStats, PUBLISH_D
import { formatRows } from '../render/format-rows.js';
import { CliError } from '../lib/errors.js';
import { daysBack } from '../lib/time.js';
import { screenWidth } from '../lib/terminal.js';
import { wrap } from '../lib/wrap.js';
import { assertCalendarDate, assertPositiveInt } from '../lib/validate.js';
import { assertRangeAllowed, resolveRange } from './fetch.js';
import { dataCommand } from './run-command.js';
Expand Down Expand Up @@ -122,7 +124,10 @@ export const dbCommand = defineCommand({
const hint = range === null
? `Run \`oura-cli sync\` to fill the cache, or \`oura-cli fetch ${c.name}\` to read the API.`
: `Run \`oura-cli sync\` (\`sync --from <day>\` for older days), or \`oura-cli fetch ${c.name}\` to read the API.`;
return { json: rows, text: () => formatRows(c, rows, scope, 'table', hint, undefined, all.length) };
const utcNote = range !== null && c.rangeParams === 'datetime' && rows.length > 0
? wrap(`day is the UTC date of each sample; rows are selected by the local day in ${ctx.tz}.`, screenWidth(), ' ')
: [];
return { json: rows, text: () => [formatRows(c, rows, scope, 'table', hint, undefined, all.length), ...utcNote].join('\n') };
},
}),
},
Expand Down
Loading