@lightdash/cli 0.1385.1 → 0.1386.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -49,6 +49,9 @@ export declare const lightdashApi: <T extends string | boolean | unknown[] | imp
49
49
  owner: string;
50
50
  } | import("@lightdash/common").KnexPaginatedData<import("@lightdash/common").ApiMetricsCatalogResults> | import("@lightdash/common").MetricsExplorerQueryResults | import("@lightdash/common").KnexPaginatedData<import("@lightdash/common").Group[] | import("@lightdash/common").GroupWithMembers[]> | {
51
51
  tagUuid: string;
52
+ } | import("@lightdash/common").ChartAsCode[] | {
53
+ chart: import("@lightdash/common").ChartAsCode;
54
+ created: boolean;
52
55
  } | null | undefined>({ method, url, body, }: LightdashApiProps) => Promise<T>;
53
56
  export declare const checkLightdashVersion: () => Promise<void>;
54
57
  export {};
@@ -0,0 +1,5 @@
1
+ export type DownloadHandlerOptions = {
2
+ verbose: boolean;
3
+ };
4
+ export declare const downloadHandler: (options: DownloadHandlerOptions) => Promise<void>;
5
+ export declare const uploadHandler: (options: DownloadHandlerOptions) => Promise<void>;
@@ -0,0 +1,109 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.uploadHandler = exports.downloadHandler = void 0;
4
+ const tslib_1 = require("tslib");
5
+ /* eslint-disable no-await-in-loop */
6
+ const common_1 = require("@lightdash/common");
7
+ const fs_1 = require("fs");
8
+ const yaml = tslib_1.__importStar(require("js-yaml"));
9
+ const path = tslib_1.__importStar(require("path"));
10
+ const config_1 = require("../config");
11
+ const globalState_1 = tslib_1.__importDefault(require("../globalState"));
12
+ const apiClient_1 = require("./dbt/apiClient");
13
+ const DOWNLOAD_FOLDER = 'lightdash';
14
+ const downloadHandler = async (options) => {
15
+ globalState_1.default.setVerbose(options.verbose);
16
+ await (0, apiClient_1.checkLightdashVersion)();
17
+ const config = await (0, config_1.getConfig)();
18
+ if (!config.context?.apiKey || !config.context.serverUrl) {
19
+ throw new common_1.AuthorizationError(`Not logged in. Run 'lightdash login --help'`);
20
+ }
21
+ const projectId = config.context.project;
22
+ if (!projectId) {
23
+ throw new Error('No project selected. Run lightdash config set-project');
24
+ }
25
+ const chartsAsCode = await (0, apiClient_1.lightdashApi)({
26
+ method: 'GET',
27
+ url: `/api/v1/projects/${projectId}/charts/code`,
28
+ body: undefined,
29
+ });
30
+ console.info(`Downloading ${chartsAsCode.length} charts`);
31
+ const outputDir = path.join(process.cwd(), DOWNLOAD_FOLDER);
32
+ console.info(`Creating new path for files on ${outputDir} `);
33
+ try {
34
+ await fs_1.promises.mkdir(outputDir, { recursive: true });
35
+ }
36
+ catch (error) {
37
+ // Directory already exists
38
+ }
39
+ for (const chart of chartsAsCode) {
40
+ const chartPath = path.join(outputDir, `${chart.slug}.yml`);
41
+ globalState_1.default.debug(`> Writing chart to ${chartPath}`);
42
+ const chartYml = yaml.dump(chart, {
43
+ quotingType: '"',
44
+ });
45
+ await fs_1.promises.writeFile(chartPath, chartYml);
46
+ }
47
+ // TODO delete files if chart don't exist ?*/
48
+ };
49
+ exports.downloadHandler = downloadHandler;
50
+ const uploadHandler = async (options) => {
51
+ globalState_1.default.setVerbose(options.verbose);
52
+ await (0, apiClient_1.checkLightdashVersion)();
53
+ const config = await (0, config_1.getConfig)();
54
+ if (!config.context?.apiKey || !config.context.serverUrl) {
55
+ throw new common_1.AuthorizationError(`Not logged in. Run 'lightdash login --help'`);
56
+ }
57
+ const projectId = config.context.project;
58
+ if (!projectId) {
59
+ throw new Error('No project selected. Run lightdash config set-project');
60
+ }
61
+ const inputDir = path.join(process.cwd(), DOWNLOAD_FOLDER);
62
+ console.info(`Reading charts from ${inputDir}`);
63
+ const charts = [];
64
+ try {
65
+ // Read all files from the lightdash directory
66
+ const files = await fs_1.promises.readdir(inputDir);
67
+ const jsonFiles = files.filter((file) => file.endsWith('.yml'));
68
+ // Load each JSON file
69
+ for (const file of jsonFiles) {
70
+ const filePath = path.join(inputDir, file);
71
+ const fileContent = await fs_1.promises.readFile(filePath, 'utf-8');
72
+ const chart = yaml.load(fileContent);
73
+ charts.push(chart);
74
+ }
75
+ }
76
+ catch (error) {
77
+ if (error.code === 'ENOENT') {
78
+ throw new Error(`Directory ${inputDir} not found. Run download command first.`);
79
+ }
80
+ throw error;
81
+ }
82
+ console.info(`Found ${charts.length} chart files`);
83
+ let created = 0;
84
+ let updated = 0;
85
+ try {
86
+ for (const chart of charts) {
87
+ globalState_1.default.debug(`Upserting chart ${chart.slug}`);
88
+ const chartData = await (0, apiClient_1.lightdashApi)({
89
+ method: 'POST',
90
+ url: `/api/v1/projects/${projectId}/charts/${chart.slug}/code`,
91
+ body: JSON.stringify(chart),
92
+ });
93
+ if (chartData.created) {
94
+ created += 1;
95
+ globalState_1.default.debug(`Created chart: ${chart.name}`);
96
+ }
97
+ else {
98
+ updated += 1;
99
+ globalState_1.default.debug(`Updated chart: ${chart.name}`);
100
+ }
101
+ }
102
+ }
103
+ catch (error) {
104
+ console.error('Error upserting chart', error);
105
+ }
106
+ console.info(`Total charts created: ${created} `);
107
+ console.info(`Total charts updated: ${updated} `);
108
+ };
109
+ exports.uploadHandler = uploadHandler;
package/dist/index.js CHANGED
@@ -9,6 +9,7 @@ const compile_1 = require("./handlers/compile");
9
9
  const refresh_1 = require("./handlers/dbt/refresh");
10
10
  const run_1 = require("./handlers/dbt/run");
11
11
  const deploy_1 = require("./handlers/deploy");
12
+ const download_1 = require("./handlers/download");
12
13
  const generate_1 = require("./handlers/generate");
13
14
  const generateExposures_1 = require("./handlers/generateExposures");
14
15
  const login_1 = require("./handlers/login");
@@ -189,6 +190,16 @@ commander_1.program
189
190
  .option('--name [preview name]', '[required] Name for the preview project to be deleted')
190
191
  .option('--verbose', undefined, false)
191
192
  .action(preview_1.stopPreviewHandler);
193
+ commander_1.program
194
+ .command('download')
195
+ .description('Downloads charts and dashboards as code')
196
+ .option('--verbose', undefined, false)
197
+ .action(download_1.downloadHandler);
198
+ commander_1.program
199
+ .command('upload')
200
+ .description('Uploads charts and dashboards as code')
201
+ .option('--verbose', undefined, false)
202
+ .action(download_1.uploadHandler);
192
203
  commander_1.program
193
204
  .command('deploy')
194
205
  .description('Compiles and deploys a Lightdash project')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightdash/cli",
3
- "version": "0.1385.1",
3
+ "version": "0.1386.1",
4
4
  "license": "MIT",
5
5
  "bin": {
6
6
  "lightdash": "dist/index.js"
@@ -11,8 +11,8 @@
11
11
  ],
12
12
  "dependencies": {
13
13
  "@actions/core": "^1.11.1",
14
- "@lightdash/common": "^0.1385.1",
15
- "@lightdash/warehouses": "^0.1385.1",
14
+ "@lightdash/common": "^0.1386.1",
15
+ "@lightdash/warehouses": "^0.1386.1",
16
16
  "@types/columnify": "^1.5.1",
17
17
  "ajv": "^8.11.0",
18
18
  "ajv-formats": "^2.1.1",