@lightdash/cli 2.13.2 → 2.14.0

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/dist/index.js CHANGED
@@ -39,6 +39,7 @@ const sql_1 = require("./handlers/sql");
39
39
  const upgradeCheck_1 = require("./handlers/upgradeCheck");
40
40
  const validate_2 = require("./handlers/validate");
41
41
  const warehouseCatalog_1 = require("./handlers/warehouseCatalog");
42
+ const refsArgument_1 = require("./refsArgument");
42
43
  const styles = tslib_1.__importStar(require("./styles"));
43
44
  // Trigger CLI tests
44
45
  // Suppress AWS SDK V2 warning, imported by snowflake SDK
@@ -360,15 +361,15 @@ const downloadCommand = commander_1.program
360
361
  .command('download')
361
362
  .description('Downloads project or organization content as code')
362
363
  .option('--verbose', undefined, false)
363
- .option('-c, --charts <charts...>', 'specify chart slugs, uuids, or urls to download', [])
364
- .option('-d, --dashboards <dashboards...>', 'specify dashboard slugs, uuids or urls to download', [])
365
- .option('--agents <slugs...>', 'specify AI agent slugs to download', [])
364
+ .option('-c, --charts <charts...>', 'specify chart slugs, uuids, or urls to download', refsArgument_1.parseRefsArgument, [])
365
+ .option('-d, --dashboards <dashboards...>', 'specify dashboard slugs, uuids or urls to download', refsArgument_1.parseRefsArgument, [])
366
+ .option('--agents <slugs...>', 'specify AI agent slugs to download', refsArgument_1.parseRefsArgument, [])
366
367
  .option('--include-agents', "include all of the project's AI agents (enterprise)", false)
367
- .option('--alerts <slugs...>', 'specify alert slugs to download', [])
368
- .option('--virtual-views <slugs...>', 'specify virtual view slugs to download', [])
369
- .option('--google-sheets <slugs...>', 'specify Google Sheets sync slugs to download', [])
370
- .option('--scheduled-deliveries <slugs...>', 'specify scheduled delivery slugs to download', [])
371
- .option('--external-connections <slugs...>', 'specify external connection slugs to download (enterprise)', [])
368
+ .option('--alerts <slugs...>', 'specify alert slugs to download', refsArgument_1.parseRefsArgument, [])
369
+ .option('--virtual-views <slugs...>', 'specify virtual view slugs to download', refsArgument_1.parseRefsArgument, [])
370
+ .option('--google-sheets <slugs...>', 'specify Google Sheets sync slugs to download', refsArgument_1.parseRefsArgument, [])
371
+ .option('--scheduled-deliveries <slugs...>', 'specify scheduled delivery slugs to download', refsArgument_1.parseRefsArgument, [])
372
+ .option('--external-connections <slugs...>', 'specify external connection slugs to download (enterprise)', refsArgument_1.parseRefsArgument, [])
372
373
  .option('--include-external-connections', "include all of the project's data-app external connections (enterprise)", false)
373
374
  .option('-l, --language-map', 'generate a language maps for the downloaded charts and dashboards', false)
374
375
  .option('-p, --path <path>', 'specify a custom path to download content', undefined)
@@ -385,11 +386,11 @@ const downloadCommand = commander_1.program
385
386
  .option('--include-scheduled-deliveries', 'include all scheduled deliveries in the download', false)
386
387
  .option('--include-all', 'include all optional content in the download', false)
387
388
  .option('--strip-pivot-series', 'strip per-value pivot series config from chart YAML for portable downloads', false)
388
- .option('--apps <appReferences...>', 'Download only the specified data apps, by slug, app URL, or UUID (enterprise). Works for apps not added to a space.')
389
+ .option('--apps <appReferences...>', 'Download only the specified data apps, by slug, app URL, or UUID (enterprise). Works for apps not added to a space.', refsArgument_1.parseRefsArgument)
389
390
  .option('--include-apps', "Include all of the project's data apps (enterprise), capped at --apps-limit (default: 50)", false)
390
391
  .option('--apps-limit <number>', 'Maximum number of data apps downloaded by --include-apps or --include-all (default: 50)', undefined)
391
392
  .option('--apps-only', "Download only data apps (implies --skip-charts --skip-dashboards --skip-spaces). Bare --apps-only downloads all the project's apps; pass --apps <appReferences...> to select.", false)
392
- .option('--chart-types <chartTypeReferences...>', 'Download only the specified custom chart types, by slug, URL, or UUID (enterprise).')
393
+ .option('--chart-types <chartTypeReferences...>', 'Download only the specified custom chart types, by slug, URL, or UUID (enterprise).', refsArgument_1.parseRefsArgument)
393
394
  .option('--include-chart-types', "Include all of the project's custom chart types (enterprise), capped at --chart-types-limit (default: 50)", false)
394
395
  .option('--chart-types-limit <number>', 'Maximum number of custom chart types downloaded by --include-chart-types or --include-all (default: 50)', undefined)
395
396
  .option('--chart-types-only', "Download only custom chart types (implies --skip-charts --skip-dashboards --skip-spaces). Bare --chart-types-only downloads all the project's chart types; pass --chart-types <chartTypeReferences...> to select.", false)
@@ -399,14 +400,14 @@ const uploadCommand = commander_1.program
399
400
  .command('upload')
400
401
  .description('Uploads project or organization content as code')
401
402
  .option('--verbose', undefined, false)
402
- .option('-c, --charts <charts...>', 'specify chart slugs to force upload', [])
403
- .option('-d, --dashboards <dashboards...>', 'specify dashboard slugs to force upload', [])
404
- .option('--agents <slugs...>', 'specify AI agent slugs to upload', [])
405
- .option('--alerts <slugs...>', 'specify alert slugs to upload', [])
406
- .option('--virtual-views <slugs...>', 'specify virtual view slugs to upload', [])
407
- .option('--google-sheets <slugs...>', 'specify Google Sheets sync slugs to upload', [])
408
- .option('--scheduled-deliveries <slugs...>', 'specify scheduled delivery slugs to upload', [])
409
- .option('--external-connections <slugs...>', 'specify external connection slugs to upload (enterprise)', [])
403
+ .option('-c, --charts <charts...>', 'specify chart slugs to force upload', refsArgument_1.parseRefsArgument, [])
404
+ .option('-d, --dashboards <dashboards...>', 'specify dashboard slugs to force upload', refsArgument_1.parseRefsArgument, [])
405
+ .option('--agents <slugs...>', 'specify AI agent slugs to upload', refsArgument_1.parseRefsArgument, [])
406
+ .option('--alerts <slugs...>', 'specify alert slugs to upload', refsArgument_1.parseRefsArgument, [])
407
+ .option('--virtual-views <slugs...>', 'specify virtual view slugs to upload', refsArgument_1.parseRefsArgument, [])
408
+ .option('--google-sheets <slugs...>', 'specify Google Sheets sync slugs to upload', refsArgument_1.parseRefsArgument, [])
409
+ .option('--scheduled-deliveries <slugs...>', 'specify scheduled delivery slugs to upload', refsArgument_1.parseRefsArgument, [])
410
+ .option('--external-connections <slugs...>', 'specify external connection slugs to upload (enterprise)', refsArgument_1.parseRefsArgument, [])
410
411
  .option('--force', 'Force upload unchanged files and allow destructive virtual-view column changes', false)
411
412
  .option('-p, --path <path>', 'specify a custom path to upload content from', undefined)
412
413
  .option('--project <project uuid>', 'specify a project UUID to upload', parseProjectArgument, undefined)
@@ -426,10 +427,10 @@ const uploadCommand = commander_1.program
426
427
  .option('--include-virtual-views', 'Include the virtual views used by the charts and dashboards being uploaded', false)
427
428
  .option('--validate', 'Validate charts and dashboards after upload', false)
428
429
  .option('--gzip', 'Enable gzip compression for request bodies', false)
429
- .option('--apps <appReferences...>', 'Upload only the specified data apps, by slug (the app folder name), app URL, or UUID (enterprise). URL and UUID refs are resolved against the target project.')
430
+ .option('--apps <appReferences...>', 'Upload only the specified data apps, by slug (the app folder name), app URL, or UUID (enterprise). URL and UUID refs are resolved against the target project.', refsArgument_1.parseRefsArgument)
430
431
  .option('--include-apps', 'Upload all app folders on disk (enterprise).', false)
431
432
  .option('--apps-only', 'Upload only data apps, skipping charts, dashboards, and space reconciliation. Bare --apps-only uploads every app folder; pass --apps <appReferences...> to select.', false)
432
- .option('--chart-types <chartTypeReferences...>', 'Upload only the specified custom chart types, by slug (the chart type folder name), URL, or UUID (enterprise). URL and UUID refs are resolved against the target project.')
433
+ .option('--chart-types <chartTypeReferences...>', 'Upload only the specified custom chart types, by slug (the chart type folder name), URL, or UUID (enterprise). URL and UUID refs are resolved against the target project.', refsArgument_1.parseRefsArgument)
433
434
  .option('--include-chart-types', 'Upload all chart type folders on disk (enterprise).', false)
434
435
  .option('--chart-types-only', 'Upload only custom chart types, skipping charts, dashboards, and space reconciliation. Bare --chart-types-only uploads every chart type folder; pass --chart-types <chartTypeReferences...> to select.', false)
435
436
  .option('--allow-custom-dependencies', 'Approve uploading apps that declare custom dependencies without prompting. Required for non-interactive runs of such uploads.', false)
@@ -464,7 +465,7 @@ appsProgram
464
465
  .action(preview_1.appsPreviewHandler);
465
466
  appsProgram
466
467
  .command('validate [paths...]')
467
- .description('Validate data app source, manifests, dependencies, and semantic-layer references locally.')
468
+ .description('Validate data app and custom chart type source, manifests, dependencies, and semantic-layer references locally.')
468
469
  .option('--live', 'Validate against fresh explores from each app project instead of its downloaded semantic-layer snapshot.', false)
469
470
  .option('--build', 'Run the same Vite production build as Lightdash Cloud.', false)
470
471
  .addOption(new commander_1.Option('--format <format>', 'Output format: human or json')
@@ -811,6 +812,8 @@ const successHandler = () => {
811
812
  process.exit(0);
812
813
  }
813
814
  console.error(`Done 🕶`);
814
- process.exit(0);
815
+ // Handlers report partial failures (e.g. some uploads failed) via
816
+ // process.exitCode; an unconditional exit(0) would wipe it.
817
+ process.exit(process.exitCode ?? 0);
815
818
  };
816
819
  commander_1.program.parseAsync().then(successHandler).catch(errorHandler);
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Coercion for variadic reference options (--charts, --chart-types, --apps, ...).
3
+ * Commander's required-value parsing consumes the next argv token even when it
4
+ * is another option (e.g. `--chart-types --force` reads "--force" as a ref),
5
+ * so reject option-like values with a clear missing-value error.
6
+ */
7
+ export declare function parseRefsArgument(value: string, previous?: string[]): string[];
8
+ //# sourceMappingURL=refsArgument.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refsArgument.d.ts","sourceRoot":"","sources":["../src/refsArgument.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC7B,KAAK,EAAE,MAAM,EACb,QAAQ,GAAE,MAAM,EAAO,GACxB,MAAM,EAAE,CAOV"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseRefsArgument = parseRefsArgument;
4
+ const commander_1 = require("commander");
5
+ /**
6
+ * Coercion for variadic reference options (--charts, --chart-types, --apps, ...).
7
+ * Commander's required-value parsing consumes the next argv token even when it
8
+ * is another option (e.g. `--chart-types --force` reads "--force" as a ref),
9
+ * so reject option-like values with a clear missing-value error.
10
+ */
11
+ function parseRefsArgument(value, previous = []) {
12
+ if (value.startsWith('-')) {
13
+ throw new commander_1.InvalidArgumentError('Expected a reference value but got another option. Pass one or more references after this flag, or use the matching --include-* flag to select all.');
14
+ }
15
+ return [...previous, value];
16
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=refsArgument.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refsArgument.test.d.ts","sourceRoot":"","sources":["../src/refsArgument.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const commander_1 = require("commander");
4
+ const refsArgument_1 = require("./refsArgument");
5
+ const buildCommand = () => {
6
+ const command = new commander_1.Command('upload')
7
+ .exitOverride()
8
+ .configureOutput({ writeErr: () => { } })
9
+ .option('--force', 'force upload', false)
10
+ .option('-c, --charts <charts...>', 'chart refs', refsArgument_1.parseRefsArgument, [])
11
+ .option('--chart-types <chartTypeReferences...>', 'chart type refs', refsArgument_1.parseRefsArgument);
12
+ return command;
13
+ };
14
+ describe('parseRefsArgument', () => {
15
+ it('rejects a bare flag followed by another option', () => {
16
+ const command = buildCommand();
17
+ expect(() => command.parse(['--chart-types', '--force'], { from: 'user' })).toThrow(/argument '--force' is invalid/);
18
+ });
19
+ it('does not consume the following boolean flag as a value', () => {
20
+ const command = buildCommand();
21
+ command.parse(['--chart-types', 'one', 'two', '--force'], {
22
+ from: 'user',
23
+ });
24
+ expect(command.opts().chartTypes).toEqual(['one', 'two']);
25
+ expect(command.opts().force).toBe(true);
26
+ });
27
+ it('rejects option-like values on options with array defaults', () => {
28
+ const command = buildCommand();
29
+ expect(() => command.parse(['--charts', '--force'], { from: 'user' })).toThrow(/argument '--force' is invalid/);
30
+ });
31
+ it('accumulates values onto the default array', () => {
32
+ const command = buildCommand();
33
+ command.parse(['-c', 'a', '-c', 'b'], { from: 'user' });
34
+ expect(command.opts().charts).toEqual(['a', 'b']);
35
+ });
36
+ it('leaves unset options at their defaults', () => {
37
+ const command = buildCommand();
38
+ command.parse([], { from: 'user' });
39
+ expect(command.opts().charts).toEqual([]);
40
+ expect(command.opts().chartTypes).toBeUndefined();
41
+ });
42
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightdash/cli",
3
- "version": "2.13.2",
3
+ "version": "2.14.0",
4
4
  "description": "Lightdash CLI tool",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -45,8 +45,8 @@
45
45
  "unique-names-generator": "4.7.1",
46
46
  "uuid": "11.1.1",
47
47
  "yaml": "2.8.3",
48
- "@lightdash/warehouses": "2.13.2",
49
- "@lightdash/common": "2.13.2"
48
+ "@lightdash/warehouses": "2.14.0",
49
+ "@lightdash/common": "2.14.0"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@types/inquirer": "8.2.4",