Skip to content

Commit db1c51d

Browse files
authored
feat: support snapshot version in object commands (#37)
1 parent d97089f commit db1c51d

6 files changed

Lines changed: 54 additions & 15 deletions

File tree

src/cli-core.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,9 @@ export function formatArgumentHelp(arg: Argument): string {
5959
optionPart = ` ${arg.name}`;
6060
} else {
6161
optionPart = ` --${arg.name}`;
62-
if (arg.alias && typeof arg.alias === 'string' && arg.alias.length === 1) {
63-
optionPart += `, -${arg.alias}`;
62+
if (arg.alias && typeof arg.alias === 'string') {
63+
optionPart +=
64+
arg.alias.length === 1 ? `, -${arg.alias}` : `, --${arg.alias}`;
6465
}
6566
}
6667

@@ -222,11 +223,15 @@ export function addArgumentsToCommand(
222223
const argumentName = arg.required ? `<${arg.name}>` : `[${arg.name}]`;
223224
cmd.argument(argumentName, arg.description);
224225
} else {
225-
const hasValidShortOption =
226+
const isShortAlias =
226227
arg.alias && typeof arg.alias === 'string' && arg.alias.length === 1;
227-
let optionString = hasValidShortOption
228+
const isLongAlias =
229+
arg.alias && typeof arg.alias === 'string' && arg.alias.length > 1;
230+
let optionString = isShortAlias
228231
? `-${arg.alias}, --${arg.name}`
229-
: `--${arg.name}`;
232+
: isLongAlias
233+
? `--${arg.alias}, --${arg.name}`
234+
: `--${arg.name}`;
230235

231236
if (arg.type === 'flag') {
232237
// Flags don't take values

src/lib/ls.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ import { list, listBuckets } from '@tigrisdata/storage';
66

77
export default async function ls(options: Record<string, unknown>) {
88
const pathString = getOption<string>(options, ['path']);
9+
const snapshotVersion = getOption<string>(options, [
10+
'snapshot-version',
11+
'snapshotVersion',
12+
'snapshot',
13+
]);
914

1015
if (!pathString) {
1116
// No path provided, list all buckets
@@ -45,6 +50,7 @@ export default async function ls(options: Record<string, unknown>) {
4550

4651
const { data, error } = await list({
4752
prefix,
53+
...(snapshotVersion ? { snapshotVersion } : {}),
4854
config: {
4955
...config,
5056
bucket,

src/lib/objects/get.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,11 @@ export default async function getObject(options: Record<string, unknown>) {
112112
const key = getOption<string>(options, ['key']);
113113
const output = getOption<string>(options, ['output', 'o', 'O']);
114114
const modeOption = getOption<string>(options, ['mode', 'm', 'M']);
115+
const snapshotVersion = getOption<string>(options, [
116+
'snapshot-version',
117+
'snapshotVersion',
118+
'snapshot',
119+
]);
115120

116121
if (!bucket) {
117122
printFailure(context, 'Bucket name is required');
@@ -130,6 +135,7 @@ export default async function getObject(options: Record<string, unknown>) {
130135

131136
if (mode === 'stream') {
132137
const { data, error } = await get(key, 'stream', {
138+
...(snapshotVersion ? { snapshotVersion } : {}),
133139
config: {
134140
...config,
135141
bucket,
@@ -152,6 +158,7 @@ export default async function getObject(options: Record<string, unknown>) {
152158
}
153159
} else {
154160
const { data, error } = await get(key, 'string', {
161+
...(snapshotVersion ? { snapshotVersion } : {}),
155162
config: {
156163
...config,
157164
bucket,

src/lib/objects/list.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ export default async function listObjects(options: Record<string, unknown>) {
1818
const bucket = getOption<string>(options, ['bucket']);
1919
const prefix = getOption<string>(options, ['prefix', 'p', 'P']);
2020
const format = getOption<string>(options, ['format', 'f', 'F'], 'table');
21+
const snapshotVersion = getOption<string>(options, [
22+
'snapshot-version',
23+
'snapshotVersion',
24+
'snapshot',
25+
]);
2126

2227
if (!bucket) {
2328
printFailure(context, 'Bucket name is required');
@@ -28,6 +33,7 @@ export default async function listObjects(options: Record<string, unknown>) {
2833

2934
const { data, error } = await list({
3035
prefix: prefix || undefined,
36+
...(snapshotVersion ? { snapshotVersion } : {}),
3137
config: {
3238
...config,
3339
bucket,

src/lib/stat.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { parseAnyPath } from '../utils/path.js';
2+
import { getOption } from '../utils/options.js';
23
import { formatOutput, formatSize } from '../utils/format.js';
34
import { getStorageConfig } from '../auth/s3-client.js';
45
import { getStats, getBucketInfo, head } from '@tigrisdata/storage';
@@ -12,15 +13,16 @@ import { buildBucketInfo } from '../utils/bucket-info.js';
1213

1314
const context = msg('stat');
1415

15-
export default async function stat(options: {
16-
path?: string;
17-
format?: string;
18-
_positional?: string[];
19-
}) {
16+
export default async function stat(options: Record<string, unknown>) {
2017
printStart(context);
2118

22-
const pathString = options.path || options._positional?.[0];
23-
const format = options.format || 'table';
19+
const pathString = getOption<string>(options, ['path']);
20+
const format = getOption<string>(options, ['format'], 'table');
21+
const snapshotVersion = getOption<string>(options, [
22+
'snapshot-version',
23+
'snapshotVersion',
24+
'snapshot',
25+
]);
2426
const config = await getStorageConfig();
2527

2628
// No path: show overall stats
@@ -45,7 +47,7 @@ export default async function stat(options: {
4547
},
4648
];
4749

48-
const output = formatOutput(stats, format, 'stats', 'stat', [
50+
const output = formatOutput(stats, format!, 'stats', 'stat', [
4951
{ key: 'metric', header: 'Metric' },
5052
{ key: 'value', header: 'Value' },
5153
]);
@@ -76,7 +78,7 @@ export default async function stat(options: {
7678
value,
7779
}));
7880

79-
const output = formatOutput(info, format, 'bucket-info', 'info', [
81+
const output = formatOutput(info, format!, 'bucket-info', 'info', [
8082
{ key: 'metric', header: 'Metric' },
8183
{ key: 'value', header: 'Value' },
8284
]);
@@ -88,6 +90,7 @@ export default async function stat(options: {
8890

8991
// Object path: show object metadata
9092
const { data, error } = await head(path, {
93+
...(snapshotVersion ? { snapshotVersion } : {}),
9194
config: {
9295
...config,
9396
bucket,
@@ -112,7 +115,7 @@ export default async function stat(options: {
112115
{ metric: 'Modified', value: data.modified.toISOString() },
113116
];
114117

115-
const output = formatOutput(info, format, 'object-info', 'info', [
118+
const output = formatOutput(info, format!, 'object-info', 'info', [
116119
{ key: 'metric', header: 'Metric' },
117120
{ key: 'value', header: 'Value' },
118121
]);

src/specs.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,9 @@ commands:
249249
- my-bucket/my-path
250250
- t3://my-bucket
251251
- t3://my-bucket/my-path
252+
- name: snapshot-version
253+
description: Read from a specific bucket snapshot. Accepts a snapshot version string or any UNIX nanosecond-precision timestamp (e.g. 1765889000501544464)
254+
alias: snapshot
252255

253256
# mk
254257
- name: mk
@@ -347,6 +350,9 @@ commands:
347350
alias: f
348351
options: [json, table, xml]
349352
default: table
353+
- name: snapshot-version
354+
description: Read from a specific bucket snapshot. Accepts a snapshot version string or any UNIX nanosecond-precision timestamp (e.g. 1765889000501544464)
355+
alias: snapshot
350356

351357
# presign
352358
- name: presign
@@ -1086,6 +1092,9 @@ commands:
10861092
alias: f
10871093
options: [json, table, xml]
10881094
default: table
1095+
- name: snapshot-version
1096+
description: Read from a specific bucket snapshot. Accepts a snapshot version string or any UNIX nanosecond-precision timestamp (e.g. 1765889000501544464)
1097+
alias: snapshot
10891098
# get
10901099
- name: get
10911100
description: Download an object by key. Prints to stdout by default, or saves to a file with --output
@@ -1117,6 +1126,9 @@ commands:
11171126
description: 'Response mode: "string" loads into memory, "stream" writes in chunks (auto-detected from extension if not specified)'
11181127
alias: m
11191128
options: [string, stream]
1129+
- name: snapshot-version
1130+
description: Read from a specific bucket snapshot. Accepts a snapshot version string or any UNIX nanosecond-precision timestamp (e.g. 1765889000501544464)
1131+
alias: snapshot
11201132
# put
11211133
- name: put
11221134
description: Upload a local file as an object. Content-type is auto-detected from extension unless overridden

0 commit comments

Comments
 (0)