@lightdash/cli 0.2629.1 → 0.2630.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.
@@ -5,6 +5,7 @@ type LightdashApiProps = {
5
5
  url: string;
6
6
  body: BodyInit | undefined;
7
7
  };
8
+ export declare const setGzipEnabled: (enabled: boolean) => void;
8
9
  export declare const lightdashApi: <T extends ApiResponse["results"]>({ method, url, body, }: LightdashApiProps) => Promise<T>;
9
10
  export declare const getUserContext: () => Promise<LightdashUserWithAbilityRules>;
10
11
  export declare const checkProjectCreationPermission: (upstreamProjectUuid: string | undefined, projectType: ProjectType) => Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"apiClient.d.ts","sourceRoot":"","sources":["../../../src/handlers/dbt/apiClient.ts"],"names":[],"mappings":"AACA,OAAO,EAGH,WAAW,EAIX,WAAW,EACX,KAAK,6BAA6B,EAErC,MAAM,mBAAmB,CAAC;AAC3B,OAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAQ7C,KAAK,iBAAiB,GAAG;IACrB,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IACpD,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;CAC9B,CAAC;AACF,eAAO,MAAM,YAAY,GAAU,CAAC,SAAS,WAAW,CAAC,SAAS,CAAC,EAAE,wBAIlE,iBAAiB,KAAG,OAAO,CAAC,CAAC,CA+C/B,CAAC;AAEF,eAAO,MAAM,cAAc,QACb,OAAO,CAAC,6BAA6B,CAKzC,CAAC;AAEX,eAAO,MAAM,8BAA8B,GACvC,qBAAqB,MAAM,GAAG,SAAS,EACvC,aAAa,WAAW,KACzB,OAAO,CAAC,IAAI,CAkGd,CAAC;AAEF,eAAO,MAAM,qBAAqB,QAAa,OAAO,CAAC,IAAI,CAwB1D,CAAC"}
1
+ {"version":3,"file":"apiClient.d.ts","sourceRoot":"","sources":["../../../src/handlers/dbt/apiClient.ts"],"names":[],"mappings":"AACA,OAAO,EAGH,WAAW,EAIX,WAAW,EACX,KAAK,6BAA6B,EAErC,MAAM,mBAAmB,CAAC;AAC3B,OAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAS7C,KAAK,iBAAiB,GAAG;IACrB,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;IACpD,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;CAC9B,CAAC;AAKF,eAAO,MAAM,cAAc,GAAI,SAAS,OAAO,SAE9C,CAAC;AAEF,eAAO,MAAM,YAAY,GAAU,CAAC,SAAS,WAAW,CAAC,SAAS,CAAC,EAAE,wBAIlE,iBAAiB,KAAG,OAAO,CAAC,CAAC,CAqE/B,CAAC;AAEF,eAAO,MAAM,cAAc,QACb,OAAO,CAAC,6BAA6B,CAKzC,CAAC;AAEX,eAAO,MAAM,8BAA8B,GACvC,qBAAqB,MAAM,GAAG,SAAS,EACvC,aAAa,WAAW,KACzB,OAAO,CAAC,IAAI,CAkGd,CAAC;AAEF,eAAO,MAAM,qBAAqB,QAAa,OAAO,CAAC,IAAI,CAyB1D,CAAC"}
@@ -1,16 +1,23 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.checkLightdashVersion = exports.checkProjectCreationPermission = exports.getUserContext = exports.lightdashApi = void 0;
3
+ exports.checkLightdashVersion = exports.checkProjectCreationPermission = exports.getUserContext = exports.lightdashApi = exports.setGzipEnabled = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const ability_1 = require("@casl/ability");
6
6
  const common_1 = require("@lightdash/common");
7
7
  const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
8
8
  const url_1 = require("url");
9
+ const zlib_1 = require("zlib");
9
10
  const config_1 = require("../../config");
10
11
  const env_1 = require("../../env");
11
12
  const globalState_1 = tslib_1.__importDefault(require("../../globalState"));
12
13
  const styles = tslib_1.__importStar(require("../../styles"));
13
14
  const utils_1 = require("../utils");
15
+ const MIN_GZIP_SIZE = 1024;
16
+ let gzipEnabled = false;
17
+ const setGzipEnabled = (enabled) => {
18
+ gzipEnabled = enabled;
19
+ };
20
+ exports.setGzipEnabled = setGzipEnabled;
14
21
  const lightdashApi = async ({ method, url, body, }) => {
15
22
  const config = await (0, config_1.getConfig)();
16
23
  if (!(config.context?.apiKey && config.context.serverUrl)) {
@@ -19,7 +26,23 @@ const lightdashApi = async ({ method, url, body, }) => {
19
26
  const headers = (0, utils_1.buildRequestHeaders)(config.context.apiKey);
20
27
  const fullUrl = new url_1.URL(url, config.context.serverUrl).href;
21
28
  globalState_1.default.debug(`> Making HTTP ${method} request to: ${fullUrl}`);
22
- return (0, node_fetch_1.default)(fullUrl, { method, headers, body })
29
+ let requestBody = body;
30
+ if (gzipEnabled &&
31
+ body &&
32
+ typeof body === 'string' &&
33
+ Buffer.byteLength(body) > MIN_GZIP_SIZE) {
34
+ try {
35
+ const uncompressedSize = Buffer.byteLength(body);
36
+ const compressed = (0, zlib_1.gzipSync)(body);
37
+ globalState_1.default.debug(`> Compressed request body: ${uncompressedSize} bytes → ${compressed.byteLength} bytes (${Math.round((1 - compressed.byteLength / uncompressedSize) * 100)}% reduction)`);
38
+ requestBody = compressed;
39
+ headers['Content-Encoding'] = 'gzip';
40
+ }
41
+ catch (err) {
42
+ globalState_1.default.debug(`> Gzip compression failed, sending uncompressed: ${err}`);
43
+ }
44
+ }
45
+ return (0, node_fetch_1.default)(fullUrl, { method, headers, body: requestBody })
23
46
  .then((r) => {
24
47
  globalState_1.default.debug(`> HTTP request returned status: ${r.status}`);
25
48
  if (!r.ok) {
@@ -138,7 +161,7 @@ const checkLightdashVersion = async () => {
138
161
  }
139
162
  }
140
163
  catch (err) {
141
- // do nothing
164
+ globalState_1.default.debug(`> Health check failed: ${err}`);
142
165
  }
143
166
  };
144
167
  exports.checkLightdashVersion = checkLightdashVersion;
@@ -15,6 +15,7 @@ type DeployHandlerOptions = DbtCompileOptions & {
15
15
  useBatchedDeploy?: boolean;
16
16
  batchSize?: string;
17
17
  parallelBatches?: string;
18
+ gzip?: boolean;
18
19
  };
19
20
  type DeployArgs = DeployHandlerOptions & {
20
21
  projectUuid: string;
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/handlers/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,OAAO,EACP,YAAY,EASf,MAAM,mBAAmB,CAAC;AAkB3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAIlD,KAAK,oBAAoB,GAAG,iBAAiB,GAAG;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAEF,KAAK,UAAU,GAAG,oBAAoB,GAAG;IACrC,WAAW,EAAE,MAAM,CAAC;CACvB,CAAC;AA8KF,eAAO,MAAM,MAAM,GACf,UAAU,CAAC,OAAO,GAAG,YAAY,CAAC,EAAE,EACpC,SAAS,UAAU,KACpB,OAAO,CAAC,IAAI,CAuHd,CAAC;AAiGF,eAAO,MAAM,aAAa,GAAU,iBAAiB,oBAAoB,kBA4GxE,CAAC"}
1
+ {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/handlers/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,OAAO,EACP,YAAY,EASf,MAAM,mBAAmB,CAAC;AAsB3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAIlD,KAAK,oBAAoB,GAAG,iBAAiB,GAAG;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF,KAAK,UAAU,GAAG,oBAAoB,GAAG;IACrC,WAAW,EAAE,MAAM,CAAC;CACvB,CAAC;AA8KF,eAAO,MAAM,MAAM,GACf,UAAU,CAAC,OAAO,GAAG,YAAY,CAAC,EAAE,EACpC,SAAS,UAAU,KACpB,OAAO,CAAC,IAAI,CAuHd,CAAC;AAiGF,eAAO,MAAM,aAAa,GAAU,iBAAiB,oBAAoB,kBA+GxE,CAAC"}
@@ -322,6 +322,9 @@ const deployHandler = async (originalOptions) => {
322
322
  const dbtVersionResult = projectTypeConfig.type === projectType_1.CliProjectType.Dbt
323
323
  ? await (0, getDbtVersion_1.tryGetDbtVersion)()
324
324
  : { success: false, error: null };
325
+ if (options.gzip) {
326
+ (0, apiClient_1.setGzipEnabled)(true);
327
+ }
325
328
  await (0, apiClient_1.checkLightdashVersion)();
326
329
  const executionId = (0, uuid_1.v4)();
327
330
  const explores = await (0, compile_1.compile)(options);
@@ -12,6 +12,7 @@ export type DownloadHandlerOptions = {
12
12
  nested: boolean;
13
13
  validate?: boolean;
14
14
  concurrency: number;
15
+ gzip?: boolean;
15
16
  };
16
17
  type DownloadContentType = 'charts' | 'dashboards' | 'sqlCharts';
17
18
  export declare const downloadContent: (ids: string[], type: DownloadContentType, projectId: string, projectName: string, customPath?: string, languageMap?: boolean, nested?: boolean) => Promise<[number, string[]]>;
@@ -1 +1 @@
1
- {"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/handlers/download.ts"],"names":[],"mappings":"AAiCA,MAAM,MAAM,sBAAsB,GAAG;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,EAAE,OAAO,CAAC;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACvB,CAAC;AAmQF,KAAK,mBAAmB,GAAG,QAAQ,GAAG,YAAY,GAAG,WAAW,CAAC;AAkDjE,eAAO,MAAM,eAAe,GACxB,KAAK,MAAM,EAAE,EACb,MAAM,mBAAmB,EACzB,WAAW,MAAM,EACjB,aAAa,MAAM,EACnB,aAAa,MAAM,EACnB,cAAa,OAAe,EAC5B,SAAQ,OAAe,KACxB,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CA2G5B,CAAC;AAEF,eAAO,MAAM,eAAe,GACxB,SAAS,sBAAsB,KAChC,OAAO,CAAC,IAAI,CAuKd,CAAC;AAuXF,eAAO,MAAM,aAAa,GACtB,SAAS,sBAAsB,KAChC,OAAO,CAAC,IAAI,CA4Id,CAAC"}
1
+ {"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/handlers/download.ts"],"names":[],"mappings":"AAqCA,MAAM,MAAM,sBAAsB,GAAG;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,eAAe,EAAE,OAAO,CAAC;IACzB,MAAM,EAAE,OAAO,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAmQF,KAAK,mBAAmB,GAAG,QAAQ,GAAG,YAAY,GAAG,WAAW,CAAC;AAkDjE,eAAO,MAAM,eAAe,GACxB,KAAK,MAAM,EAAE,EACb,MAAM,mBAAmB,EACzB,WAAW,MAAM,EACjB,aAAa,MAAM,EACnB,aAAa,MAAM,EACnB,cAAa,OAAe,EAC5B,SAAQ,OAAe,KACxB,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CA2G5B,CAAC;AAEF,eAAO,MAAM,eAAe,GACxB,SAAS,sBAAsB,KAChC,OAAO,CAAC,IAAI,CAuKd,CAAC;AA4ZF,eAAO,MAAM,aAAa,GACtB,SAAS,sBAAsB,KAChC,OAAO,CAAC,IAAI,CA+Id,CAAC"}
@@ -548,7 +548,32 @@ const upsertResources = async (type, projectId, changes, force, slugs, customPat
548
548
  remainingItems.push(...spaceItems);
549
549
  }
550
550
  });
551
- // Phase 1: Sequential space seeding
551
+ // For charts: also seed one item per unique dashboardSlug to avoid
552
+ // concurrent placeholder dashboard creation (duplicate slug bug)
553
+ if (type === 'charts') {
554
+ const chartsWithDashboard = remainingItems.filter((item) => 'dashboardSlug' in item &&
555
+ item.dashboardSlug);
556
+ const groupedByDashboard = (0, groupBy_1.default)(chartsWithDashboard, (item) => item.dashboardSlug);
557
+ Object.values(groupedByDashboard).forEach((dashboardItems) => {
558
+ // If no item for this dashboardSlug was already picked as a
559
+ // space seed, pick the first one as a dashboard seed
560
+ const alreadySeeded = dashboardItems.some((item) => seedItems.has(item));
561
+ if (!alreadySeeded) {
562
+ const seedIndex = force
563
+ ? 0
564
+ : dashboardItems.findIndex((i) => i.needsUpdating);
565
+ if (seedIndex >= 0) {
566
+ seedItems.add(dashboardItems[seedIndex]);
567
+ // Remove from remainingItems since it's now a seed
568
+ const idx = remainingItems.indexOf(dashboardItems[seedIndex]);
569
+ if (idx >= 0) {
570
+ remainingItems.splice(idx, 1);
571
+ }
572
+ }
573
+ }
574
+ });
575
+ }
576
+ // Phase 1: Sequential seeding (spaces + dashboard placeholders)
552
577
  for (const item of seedItems) {
553
578
  // eslint-disable-next-line no-await-in-loop
554
579
  await upsertSingleItem(item, type, projectId, changes, force, config, skipSpaceCreate, publicSpaceCreate, validate);
@@ -577,6 +602,9 @@ const getDashboardChartSlugs = async (dashboardSlugs, customPath) => {
577
602
  };
578
603
  const uploadHandler = async (options) => {
579
604
  globalState_1.default.setVerbose(options.verbose);
605
+ if (options.gzip) {
606
+ (0, apiClient_1.setGzipEnabled)(true);
607
+ }
580
608
  await (0, apiClient_1.checkLightdashVersion)();
581
609
  const config = await (0, config_1.getConfig)();
582
610
  if (!config.context?.apiKey || !config.context.serverUrl) {
@@ -1,6 +1,7 @@
1
1
  import { LightdashRequestMethodHeader, RequestMethod } from '@lightdash/common';
2
2
  type RequestHeader = {
3
3
  'Content-Type': 'application/json';
4
+ 'Content-Encoding'?: string;
4
5
  Authorization: string;
5
6
  'Proxy-Authorization'?: string;
6
7
  [LightdashRequestMethodHeader]: RequestMethod;
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/handlers/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,4BAA4B,EAC5B,aAAa,EAChB,MAAM,mBAAmB,CAAC;AAO3B,KAAK,aAAa,GAAG;IACjB,cAAc,EAAE,kBAAkB,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,CAAC,4BAA4B,CAAC,EAAE,aAAa,CAAC;CACjD,CAAC;AAgBF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,iBAgBhD"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/handlers/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,4BAA4B,EAC5B,aAAa,EAChB,MAAM,mBAAmB,CAAC;AAO3B,KAAK,aAAa,GAAG;IACjB,cAAc,EAAE,kBAAkB,CAAC;IACnC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,CAAC,4BAA4B,CAAC,EAAE,aAAa,CAAC;CACjD,CAAC;AAgBF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,iBAgBhD"}
package/dist/index.js CHANGED
@@ -304,6 +304,7 @@ commander_1.program
304
304
  .option('--concurrency <number>', 'Number of parallel uploads (default: 1)', '1')
305
305
  .option('--include-charts', 'Include charts updates when uploading dashboards', false)
306
306
  .option('--validate', 'Validate charts and dashboards after upload', false)
307
+ .option('--gzip', 'Enable gzip compression for request bodies', false)
307
308
  .action(download_1.uploadHandler);
308
309
  commander_1.program
309
310
  .command('deploy')
@@ -339,6 +340,7 @@ commander_1.program
339
340
  .option('--use-batched-deploy', 'Use batched deploy for large projects (sends explores in batches)', false)
340
341
  .option('--batch-size <number>', 'Number of explores per batch (default: 50)', '50')
341
342
  .option('--parallel-batches <number>', 'Number of batches to send in parallel (default: 1, use higher values with caution)', '1')
343
+ .option('--gzip', 'Enable gzip compression for request bodies', false)
342
344
  .action(deploy_1.deployHandler);
343
345
  commander_1.program
344
346
  .command('refresh')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightdash/cli",
3
- "version": "0.2629.1",
3
+ "version": "0.2630.0",
4
4
  "description": "Lightdash CLI tool",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -40,8 +40,8 @@
40
40
  "unique-names-generator": "^4.7.1",
41
41
  "uuid": "^11.0.3",
42
42
  "yaml": "^2.7.0",
43
- "@lightdash/common": "0.2629.1",
44
- "@lightdash/warehouses": "0.2629.1"
43
+ "@lightdash/common": "0.2630.0",
44
+ "@lightdash/warehouses": "0.2630.0"
45
45
  },
46
46
  "devDependencies": {
47
47
  "@types/inquirer": "^8.2.1",