@sentio/cli 3.6.0-rc.1 → 3.6.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +60 -1
- package/package.json +1 -1
- package/src/commands/dashboard.ts +86 -0
package/lib/index.js
CHANGED
|
@@ -144804,6 +144804,7 @@ import process24 from "process";
|
|
|
144804
144804
|
function createDashboardCommand() {
|
|
144805
144805
|
const dashboardCommand = new Command("dashboard").description("Manage Sentio dashboards");
|
|
144806
144806
|
dashboardCommand.addCommand(createDashboardListCommand());
|
|
144807
|
+
dashboardCommand.addCommand(createDashboardCreateCommand());
|
|
144807
144808
|
dashboardCommand.addCommand(createDashboardExportCommand());
|
|
144808
144809
|
dashboardCommand.addCommand(createDashboardImportCommand());
|
|
144809
144810
|
dashboardCommand.addCommand(createDashboardAddPanelCommand());
|
|
@@ -144820,6 +144821,17 @@ function createDashboardListCommand() {
|
|
|
144820
144821
|
}
|
|
144821
144822
|
});
|
|
144822
144823
|
}
|
|
144824
|
+
function createDashboardCreateCommand() {
|
|
144825
|
+
return withOutputOptions8(
|
|
144826
|
+
withSharedProjectOptions7(withAuthOptions8(new Command("create").description("Create a dashboard for a project")))
|
|
144827
|
+
).showHelpAfterError().requiredOption("--title <name>", "Dashboard title").option("--file <path>", "Read initial dashboard JSON or YAML from file").option("--stdin", "Read initial dashboard JSON or YAML from stdin").action(async (options, command) => {
|
|
144828
|
+
try {
|
|
144829
|
+
await runDashboardCreate(options);
|
|
144830
|
+
} catch (error) {
|
|
144831
|
+
handleDashboardCommandError(error, command);
|
|
144832
|
+
}
|
|
144833
|
+
});
|
|
144834
|
+
}
|
|
144823
144835
|
function createDashboardExportCommand() {
|
|
144824
144836
|
return withOutputOptions8(
|
|
144825
144837
|
withSharedProjectOptions7(
|
|
@@ -144919,6 +144931,16 @@ async function runDashboardList(options) {
|
|
|
144919
144931
|
const data4 = unwrapApiResult(response);
|
|
144920
144932
|
printOutput8(options, data4);
|
|
144921
144933
|
}
|
|
144934
|
+
async function runDashboardCreate(options) {
|
|
144935
|
+
const context = createApiContext(options);
|
|
144936
|
+
const project = await resolveProjectRef(options, context, { ownerSlug: true });
|
|
144937
|
+
const body = buildDashboardCreateBody(options, project);
|
|
144938
|
+
const data4 = await postApiJson("/v1/dashboards", context, body);
|
|
144939
|
+
printOutput8(options, {
|
|
144940
|
+
message: `Dashboard "${options.title}" created`,
|
|
144941
|
+
dashboard: data4.dashboard ?? data4
|
|
144942
|
+
});
|
|
144943
|
+
}
|
|
144922
144944
|
async function runDashboardExport(dashboardId, options) {
|
|
144923
144945
|
const context = createApiContext(options);
|
|
144924
144946
|
const response = await import_api14.WebService.exportDashboard({
|
|
@@ -144946,6 +144968,40 @@ async function runDashboardImport(dashboardId, options) {
|
|
|
144946
144968
|
const data4 = unwrapApiResult(response);
|
|
144947
144969
|
printOutput8(options, { message: `Dashboard imported into ${dashboardId}`, dashboard: data4.dashboard });
|
|
144948
144970
|
}
|
|
144971
|
+
function buildDashboardCreateBody(options, project) {
|
|
144972
|
+
const input = loadJsonInput(options);
|
|
144973
|
+
const initialDashboard = normalizeDashboardInit(input);
|
|
144974
|
+
return {
|
|
144975
|
+
name: options.title,
|
|
144976
|
+
projectOwner: project.owner,
|
|
144977
|
+
projectSlug: project.slug,
|
|
144978
|
+
...initialDashboard
|
|
144979
|
+
};
|
|
144980
|
+
}
|
|
144981
|
+
function normalizeDashboardInit(input) {
|
|
144982
|
+
if (input === void 0) {
|
|
144983
|
+
return {
|
|
144984
|
+
panels: {},
|
|
144985
|
+
layouts: {
|
|
144986
|
+
responsiveLayouts: {
|
|
144987
|
+
lg: { layouts: [] }
|
|
144988
|
+
}
|
|
144989
|
+
}
|
|
144990
|
+
};
|
|
144991
|
+
}
|
|
144992
|
+
if (!input || typeof input !== "object" || Array.isArray(input)) {
|
|
144993
|
+
throw new CliError("Dashboard initialization data must be a JSON or YAML object.");
|
|
144994
|
+
}
|
|
144995
|
+
const dashboard = input;
|
|
144996
|
+
return {
|
|
144997
|
+
panels: isRecord(dashboard.panels) ? dashboard.panels : {},
|
|
144998
|
+
layouts: isRecord(dashboard.layouts) ? dashboard.layouts : {
|
|
144999
|
+
responsiveLayouts: {
|
|
145000
|
+
lg: { layouts: [] }
|
|
145001
|
+
}
|
|
145002
|
+
}
|
|
145003
|
+
};
|
|
145004
|
+
}
|
|
144949
145005
|
async function runDashboardAddPanel(dashboardId, options) {
|
|
144950
145006
|
const context = createApiContext(options);
|
|
144951
145007
|
const selectedSources = [Boolean(options.sql), Boolean(options.event), Boolean(options.metric)].filter(Boolean).length;
|
|
@@ -145072,6 +145128,9 @@ function collectOption3(value, previous = []) {
|
|
|
145072
145128
|
previous.push(value);
|
|
145073
145129
|
return previous;
|
|
145074
145130
|
}
|
|
145131
|
+
function isRecord(value) {
|
|
145132
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
145133
|
+
}
|
|
145075
145134
|
function withAuthOptions8(command) {
|
|
145076
145135
|
return command.option("--host <host>", "Override Sentio host").option("--api-key <key>", "Use an explicit API key instead of saved credentials").option("--token <token>", "Use an explicit bearer token instead of saved credentials");
|
|
145077
145136
|
}
|
|
@@ -145082,7 +145141,7 @@ function withOutputOptions8(command) {
|
|
|
145082
145141
|
return command.option("--json", "Print raw JSON response").option("--yaml", "Print raw YAML response");
|
|
145083
145142
|
}
|
|
145084
145143
|
function handleDashboardCommandError(error, command) {
|
|
145085
|
-
if (error instanceof CliError && (error.message.startsWith("Project is required.") || error.message.startsWith("Invalid project ") || error.message.startsWith("Dashboard ") || error.message.startsWith("Provide --file or --stdin") || error.message.startsWith("Provide exactly one data source") || error.message.startsWith("Use exactly one of --sql") || error.message.startsWith("Invalid chart type") || error.message.startsWith("Invalid aggregation") || error.message.startsWith("Invalid metric aggregation") || error.message.startsWith("Invalid filter") || error.message.startsWith("Invalid metric selector"))) {
|
|
145144
|
+
if (error instanceof CliError && (error.message.startsWith("Project is required.") || error.message.startsWith("Invalid project ") || error.message.startsWith("Dashboard ") || error.message.startsWith("Provide --file or --stdin") || error.message.startsWith("Use either --file or --stdin") || error.message.startsWith("Expected JSON or YAML") || error.message.startsWith("Invalid JSON or YAML") || error.message.startsWith("Dashboard initialization data") || error.message.startsWith("Provide exactly one data source") || error.message.startsWith("Use exactly one of --sql") || error.message.startsWith("Invalid chart type") || error.message.startsWith("Invalid aggregation") || error.message.startsWith("Invalid metric aggregation") || error.message.startsWith("Invalid filter") || error.message.startsWith("Invalid metric selector"))) {
|
|
145086
145145
|
console.error(error.message);
|
|
145087
145146
|
if (command) {
|
|
145088
145147
|
console.error();
|
package/package.json
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
createApiContext,
|
|
8
8
|
handleCommandError,
|
|
9
9
|
loadJsonInput,
|
|
10
|
+
postApiJson,
|
|
10
11
|
resolveProjectRef,
|
|
11
12
|
unwrapApiResult
|
|
12
13
|
} from '../api.js'
|
|
@@ -30,6 +31,12 @@ interface DashboardImportOptions extends DashboardOptions {
|
|
|
30
31
|
overrideLayouts?: boolean
|
|
31
32
|
}
|
|
32
33
|
|
|
34
|
+
interface DashboardCreateOptions extends DashboardOptions {
|
|
35
|
+
title?: string
|
|
36
|
+
file?: string
|
|
37
|
+
stdin?: boolean
|
|
38
|
+
}
|
|
39
|
+
|
|
33
40
|
interface AddPanelOptions extends DashboardOptions {
|
|
34
41
|
panelName?: string
|
|
35
42
|
type?: string
|
|
@@ -48,6 +55,7 @@ interface AddPanelOptions extends DashboardOptions {
|
|
|
48
55
|
export function createDashboardCommand() {
|
|
49
56
|
const dashboardCommand = new Command('dashboard').description('Manage Sentio dashboards')
|
|
50
57
|
dashboardCommand.addCommand(createDashboardListCommand())
|
|
58
|
+
dashboardCommand.addCommand(createDashboardCreateCommand())
|
|
51
59
|
dashboardCommand.addCommand(createDashboardExportCommand())
|
|
52
60
|
dashboardCommand.addCommand(createDashboardImportCommand())
|
|
53
61
|
dashboardCommand.addCommand(createDashboardAddPanelCommand())
|
|
@@ -68,6 +76,23 @@ function createDashboardListCommand() {
|
|
|
68
76
|
})
|
|
69
77
|
}
|
|
70
78
|
|
|
79
|
+
function createDashboardCreateCommand() {
|
|
80
|
+
return withOutputOptions(
|
|
81
|
+
withSharedProjectOptions(withAuthOptions(new Command('create').description('Create a dashboard for a project')))
|
|
82
|
+
)
|
|
83
|
+
.showHelpAfterError()
|
|
84
|
+
.requiredOption('--title <name>', 'Dashboard title')
|
|
85
|
+
.option('--file <path>', 'Read initial dashboard JSON or YAML from file')
|
|
86
|
+
.option('--stdin', 'Read initial dashboard JSON or YAML from stdin')
|
|
87
|
+
.action(async (options, command) => {
|
|
88
|
+
try {
|
|
89
|
+
await runDashboardCreate(options)
|
|
90
|
+
} catch (error) {
|
|
91
|
+
handleDashboardCommandError(error, command)
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
}
|
|
95
|
+
|
|
71
96
|
function createDashboardExportCommand() {
|
|
72
97
|
return withOutputOptions(
|
|
73
98
|
withSharedProjectOptions(
|
|
@@ -197,6 +222,18 @@ async function runDashboardList(options: DashboardOptions) {
|
|
|
197
222
|
printOutput(options, data)
|
|
198
223
|
}
|
|
199
224
|
|
|
225
|
+
async function runDashboardCreate(options: DashboardCreateOptions) {
|
|
226
|
+
const context = createApiContext(options)
|
|
227
|
+
const project = await resolveProjectRef(options, context, { ownerSlug: true })
|
|
228
|
+
const body = buildDashboardCreateBody(options, project)
|
|
229
|
+
const data = await postApiJson<{ dashboard?: Record<string, unknown> }>('/v1/dashboards', context, body)
|
|
230
|
+
|
|
231
|
+
printOutput(options, {
|
|
232
|
+
message: `Dashboard "${options.title}" created`,
|
|
233
|
+
dashboard: data.dashboard ?? data
|
|
234
|
+
})
|
|
235
|
+
}
|
|
236
|
+
|
|
200
237
|
async function runDashboardExport(dashboardId: string, options: DashboardOptions) {
|
|
201
238
|
const context = createApiContext(options)
|
|
202
239
|
const response = await WebService.exportDashboard({
|
|
@@ -229,6 +266,47 @@ async function runDashboardImport(dashboardId: string, options: DashboardImportO
|
|
|
229
266
|
printOutput(options, { message: `Dashboard imported into ${dashboardId}`, dashboard: data.dashboard })
|
|
230
267
|
}
|
|
231
268
|
|
|
269
|
+
function buildDashboardCreateBody(options: DashboardCreateOptions, project: { owner: string; slug: string }) {
|
|
270
|
+
const input = loadJsonInput(options)
|
|
271
|
+
const initialDashboard = normalizeDashboardInit(input)
|
|
272
|
+
|
|
273
|
+
return {
|
|
274
|
+
name: options.title,
|
|
275
|
+
projectOwner: project.owner,
|
|
276
|
+
projectSlug: project.slug,
|
|
277
|
+
...initialDashboard
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
function normalizeDashboardInit(input: unknown) {
|
|
282
|
+
if (input === undefined) {
|
|
283
|
+
return {
|
|
284
|
+
panels: {},
|
|
285
|
+
layouts: {
|
|
286
|
+
responsiveLayouts: {
|
|
287
|
+
lg: { layouts: [] }
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (!input || typeof input !== 'object' || Array.isArray(input)) {
|
|
294
|
+
throw new CliError('Dashboard initialization data must be a JSON or YAML object.')
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
const dashboard = input as Record<string, unknown>
|
|
298
|
+
return {
|
|
299
|
+
panels: isRecord(dashboard.panels) ? dashboard.panels : {},
|
|
300
|
+
layouts: isRecord(dashboard.layouts)
|
|
301
|
+
? dashboard.layouts
|
|
302
|
+
: {
|
|
303
|
+
responsiveLayouts: {
|
|
304
|
+
lg: { layouts: [] }
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
232
310
|
async function runDashboardAddPanel(dashboardId: string, options: AddPanelOptions) {
|
|
233
311
|
const context = createApiContext(options)
|
|
234
312
|
|
|
@@ -378,6 +456,10 @@ function collectOption(value: string, previous: string[] = []) {
|
|
|
378
456
|
return previous
|
|
379
457
|
}
|
|
380
458
|
|
|
459
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
460
|
+
return Boolean(value) && typeof value === 'object' && !Array.isArray(value)
|
|
461
|
+
}
|
|
462
|
+
|
|
381
463
|
function withAuthOptions<T extends Command<any, any, any>>(command: T) {
|
|
382
464
|
return command
|
|
383
465
|
.option('--host <host>', 'Override Sentio host')
|
|
@@ -404,6 +486,10 @@ function handleDashboardCommandError(error: unknown, command?: Command) {
|
|
|
404
486
|
error.message.startsWith('Invalid project ') ||
|
|
405
487
|
error.message.startsWith('Dashboard ') ||
|
|
406
488
|
error.message.startsWith('Provide --file or --stdin') ||
|
|
489
|
+
error.message.startsWith('Use either --file or --stdin') ||
|
|
490
|
+
error.message.startsWith('Expected JSON or YAML') ||
|
|
491
|
+
error.message.startsWith('Invalid JSON or YAML') ||
|
|
492
|
+
error.message.startsWith('Dashboard initialization data') ||
|
|
407
493
|
error.message.startsWith('Provide exactly one data source') ||
|
|
408
494
|
error.message.startsWith('Use exactly one of --sql') ||
|
|
409
495
|
error.message.startsWith('Invalid chart type') ||
|