Skip to content

Commit cef2f14

Browse files
thomasballingerConvex, Inc.
authored andcommitted
add --format jsonl to npx convex data (#40674)
GitOrigin-RevId: 1b615e20356a7244ada1876c7653e4471e147a51
1 parent f761e24 commit cef2f14

File tree

2 files changed

+49
-25
lines changed

2 files changed

+49
-25
lines changed

src/cli/lib/command.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ declare module "@commander-js/extra-typings" {
124124
limit: number;
125125
order: "asc" | "desc";
126126
component?: string;
127+
format?: "json" | "jsonArray" | "jsonLines" | "jsonl" | "pretty";
127128
}
128129
>;
129130

@@ -393,8 +394,7 @@ Command.prototype.addRunOptions = function () {
393394
.addOption(
394395
new Option(
395396
"--component <path>",
396-
"Path to the component in the component tree defined in convex.config.ts. " +
397-
"Components are a beta feature. This flag is unstable and may change in subsequent releases.",
397+
"Path to the component in the component tree defined in convex.config.ts.",
398398
),
399399
)
400400
.addOption(new Option("--live-component-sources").hideHelp())
@@ -449,7 +449,7 @@ Command.prototype.addImportOptions = function () {
449449
.addOption(
450450
new Option(
451451
"--component <path>",
452-
"Path to the component in the component tree defined in convex.config.ts",
452+
"Path to the component in the component tree defined in convex.config.ts.",
453453
),
454454
);
455455
};
@@ -486,9 +486,17 @@ Command.prototype.addDataOptions = function () {
486486
.addOption(
487487
new Option(
488488
"--component <path>",
489-
"Path to the component in the component tree defined in convex.config.ts.\n" +
490-
" By default, inspects data in the root component",
491-
).hideHelp(),
489+
"Path to the component in the component tree defined in convex.config.ts.",
490+
),
491+
)
492+
.addOption(
493+
new Option(
494+
"--format <format>",
495+
"Format to print the data in. This flag is only required if the filename is missing an extension.\n" +
496+
"- jsonArray (aka json): print the data as a JSON array of objects.\n" +
497+
"- jsonLines (aka jsonl): print the data as a JSON object per line.\n" +
498+
"- pretty: print the data in a human-readable format.",
499+
).choices(["jsonArray", "json", "jsonLines", "jsonl", "pretty"]),
492500
)
493501
.argument("[table]", "If specified, list documents in this table.");
494502
};

src/cli/lib/data.ts

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export async function dataInDeployment(
1515
limit: number;
1616
order: "asc" | "desc";
1717
component?: string;
18+
format?: "json" | "jsonArray" | "jsonLines" | "jsonl" | "pretty";
1819
},
1920
) {
2021
if (options.tableName !== undefined) {
@@ -27,6 +28,7 @@ export async function dataInDeployment(
2728
limit: options.limit,
2829
order: options.order as "asc" | "desc",
2930
componentPath: options.component ?? "",
31+
format: options.format,
3032
},
3133
);
3234
} else {
@@ -72,6 +74,7 @@ async function listDocuments(
7274
limit: number;
7375
order: "asc" | "desc";
7476
componentPath: string;
77+
format?: "json" | "jsonArray" | "jsonLines" | "jsonl" | "pretty";
7578
},
7679
) {
7780
const data = (await runSystemPaginatedQuery(ctx, {
@@ -91,26 +94,39 @@ async function listDocuments(
9194
return;
9295
}
9396

94-
logDocumentsTable(
95-
ctx,
96-
data.slice(0, options.limit).map((document) => {
97-
const printed: Record<string, string> = {};
98-
for (const key in document) {
99-
printed[key] = stringify(document[key]);
100-
}
101-
return printed;
102-
}),
103-
);
104-
if (data.length > options.limit) {
105-
logWarning(
106-
chalk.yellow(
107-
`Showing the ${options.limit} ${
108-
options.order === "desc" ? "most recently" : "oldest"
109-
} created document${
110-
options.limit > 1 ? "s" : ""
111-
}. Use the --limit option to see more.`,
112-
),
97+
if (options.format === "json" || options.format === "jsonArray") {
98+
logOutput(
99+
"[\n" + data.slice(0, options.limit).map(stringify).join(",\n") + "\n]",
100+
);
101+
} else if (options.format === "jsonLines" || options.format === "jsonl") {
102+
logOutput(
103+
data
104+
.slice(0, options.limit)
105+
.map((document) => stringify(document))
106+
.join("\n"),
107+
);
108+
} else {
109+
logDocumentsTable(
110+
ctx,
111+
data.slice(0, options.limit).map((document) => {
112+
const printed: Record<string, string> = {};
113+
for (const key in document) {
114+
printed[key] = stringify(document[key]);
115+
}
116+
return printed;
117+
}),
113118
);
119+
if (data.length > options.limit) {
120+
logWarning(
121+
chalk.yellow(
122+
`Showing the ${options.limit} ${
123+
options.order === "desc" ? "most recently" : "oldest"
124+
} created document${
125+
options.limit > 1 ? "s" : ""
126+
}. Use the --limit option to see more.`,
127+
),
128+
);
129+
}
114130
}
115131
}
116132

0 commit comments

Comments
 (0)