@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 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentio/cli",
3
- "version": "3.6.0-rc.1",
3
+ "version": "3.6.0-rc.2",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "exports": {
@@ -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') ||