@lightdash/cli 0.1419.1 → 0.1420.1
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.
@@ -52,9 +52,13 @@ export declare const lightdashApi: <T extends string | boolean | unknown[] | imp
|
|
52
52
|
} | {
|
53
53
|
charts: import("@lightdash/common").ChartAsCode[];
|
54
54
|
missingIds: string[];
|
55
|
+
total: number;
|
56
|
+
offset: number;
|
55
57
|
} | {
|
56
58
|
dashboards: import("@lightdash/common").DashboardAsCode[];
|
57
59
|
missingIds: string[];
|
60
|
+
total: number;
|
61
|
+
offset: number;
|
58
62
|
} | {
|
59
63
|
edges: import("@lightdash/common").CatalogMetricsTreeEdge[];
|
60
64
|
} | import("@lightdash/common").MetricTotalResults | null | undefined>({ method, url, body, }: LightdashApiProps) => Promise<T>;
|
@@ -29,7 +29,7 @@ const parseContentFilters = (items) => {
|
|
29
29
|
};
|
30
30
|
const dumpIntoFiles = async (folder, items) => {
|
31
31
|
const outputDir = path.join(process.cwd(), DOWNLOAD_FOLDER, folder);
|
32
|
-
|
32
|
+
globalState_1.default.debug(`Writing ${items.length} ${folder} into ${outputDir}`);
|
33
33
|
// Make directory
|
34
34
|
const created = await fs_1.promises.mkdir(outputDir, { recursive: true });
|
35
35
|
if (created)
|
@@ -103,45 +103,80 @@ const downloadHandler = async (options) => {
|
|
103
103
|
console.info(styles.warning(`No charts filters provided, skipping`));
|
104
104
|
}
|
105
105
|
else {
|
106
|
-
globalState_1.default.
|
106
|
+
const spinner = globalState_1.default.startSpinner(`Downloading charts`);
|
107
107
|
const chartFilters = parseContentFilters(options.charts);
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
108
|
+
let chartsAsCode;
|
109
|
+
let offset = 0;
|
110
|
+
do {
|
111
|
+
globalState_1.default.debug(`Downloading charts with offset "${offset}" and filters "${chartFilters}"`);
|
112
|
+
const queryParams = chartFilters
|
113
|
+
? `${chartFilters}&offset=${offset}`
|
114
|
+
: `?offset=${offset}`;
|
115
|
+
chartsAsCode = await (0, apiClient_1.lightdashApi)({
|
116
|
+
method: 'GET',
|
117
|
+
url: `/api/v1/projects/${projectId}/charts/code${queryParams}`,
|
118
|
+
body: undefined,
|
119
|
+
});
|
120
|
+
spinner.start(`Downloaded ${chartsAsCode.offset} of ${chartsAsCode.total} charts`);
|
121
|
+
chartsAsCode.missingIds.forEach((missingId) => {
|
122
|
+
console.warn(styles.warning(`\nNo chart with id "${missingId}"`));
|
123
|
+
});
|
124
|
+
await dumpIntoFiles('charts', chartsAsCode.charts);
|
125
|
+
offset = chartsAsCode.offset;
|
126
|
+
} while (chartsAsCode.offset < chartsAsCode.total);
|
127
|
+
spinner.succeed(`Downloaded ${chartsAsCode.total} charts`);
|
117
128
|
}
|
118
129
|
// Download dashboards
|
119
130
|
if (hasFilters && options.dashboards.length === 0) {
|
120
131
|
console.info(styles.warning(`No dashboards filters provided, skipping`));
|
121
132
|
}
|
122
133
|
else {
|
123
|
-
globalState_1.default.
|
134
|
+
const spinner = globalState_1.default.startSpinner(`Downloading dashboards`);
|
124
135
|
const dashboardFilters = parseContentFilters(options.dashboards);
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
136
|
+
let offset = 0;
|
137
|
+
let dashboardsAsCode;
|
138
|
+
do {
|
139
|
+
globalState_1.default.debug(`Downloading dashboards with offset "${offset}" and filters "${dashboardFilters}"`);
|
140
|
+
const queryParams = dashboardFilters
|
141
|
+
? `${dashboardFilters}&offset=${offset}`
|
142
|
+
: `?offset=${offset}`;
|
143
|
+
dashboardsAsCode = await (0, apiClient_1.lightdashApi)({
|
144
|
+
method: 'GET',
|
145
|
+
url: `/api/v1/projects/${projectId}/dashboards/code${queryParams}`,
|
146
|
+
body: undefined,
|
147
|
+
});
|
148
|
+
dashboardsAsCode.missingIds.forEach((missingId) => {
|
149
|
+
console.warn(styles.warning(`\nNo dashboard with id "${missingId}"`));
|
150
|
+
});
|
151
|
+
spinner?.start(`Downloaded ${dashboardsAsCode.offset} of ${dashboardsAsCode.total} dashboards`);
|
152
|
+
await dumpIntoFiles('dashboards', dashboardsAsCode.dashboards);
|
153
|
+
offset = dashboardsAsCode.offset;
|
154
|
+
} while (dashboardsAsCode.offset < dashboardsAsCode.total);
|
155
|
+
spinner.succeed(`Downloaded ${dashboardsAsCode.total} dashboards`);
|
134
156
|
}
|
135
157
|
// TODO delete files if chart don't exist ?*/
|
136
158
|
};
|
137
159
|
exports.downloadHandler = downloadHandler;
|
160
|
+
const getPromoteAction = (action) => {
|
161
|
+
switch (action) {
|
162
|
+
case common_1.PromotionAction.CREATE:
|
163
|
+
return 'created';
|
164
|
+
case common_1.PromotionAction.UPDATE:
|
165
|
+
return 'updated';
|
166
|
+
case common_1.PromotionAction.DELETE:
|
167
|
+
return 'deleted';
|
168
|
+
case common_1.PromotionAction.NO_CHANGES:
|
169
|
+
return 'skipped';
|
170
|
+
default:
|
171
|
+
(0, common_1.assertUnreachable)(action, `Unknown promotion action: ${action}`);
|
172
|
+
}
|
173
|
+
return 'skipped';
|
174
|
+
};
|
138
175
|
const storeUploadChanges = (changes, promoteChanges) => {
|
139
176
|
const getPromoteChanges = (resource) => {
|
140
177
|
const promotions = promoteChanges[resource];
|
141
178
|
return promotions.reduce((acc, promoteChange) => {
|
142
|
-
const action = promoteChange.action
|
143
|
-
? 'skipped'
|
144
|
-
: promoteChange.action;
|
179
|
+
const action = getPromoteAction(promoteChange.action);
|
145
180
|
const key = `${resource} ${action}`;
|
146
181
|
acc[key] = (acc[key] ?? 0) + 1;
|
147
182
|
return acc;
|
@@ -223,8 +258,21 @@ const uploadHandler = async (options) => {
|
|
223
258
|
throw new Error('No project selected. Run lightdash config set-project');
|
224
259
|
}
|
225
260
|
let changes = {};
|
226
|
-
|
227
|
-
|
261
|
+
// If any filter is provided, we skip those items without filters
|
262
|
+
// eg: if a --charts filter is provided, we skip dashboards if no --dashboards filter is provided
|
263
|
+
const hasFilters = options.charts.length > 0 || options.dashboards.length > 0;
|
264
|
+
if (hasFilters && options.charts.length === 0) {
|
265
|
+
console.info(styles.warning(`No charts filters provided, skipping`));
|
266
|
+
}
|
267
|
+
else {
|
268
|
+
changes = await upsertResources('charts', projectId, changes, options.force, options.charts);
|
269
|
+
}
|
270
|
+
if (hasFilters && options.dashboards.length === 0) {
|
271
|
+
console.info(styles.warning(`No dashboard filters provided, skipping`));
|
272
|
+
}
|
273
|
+
else {
|
274
|
+
changes = await upsertResources('dashboards', projectId, changes, options.force, options.dashboards);
|
275
|
+
}
|
228
276
|
logUploadChanges(changes);
|
229
277
|
};
|
230
278
|
exports.uploadHandler = uploadHandler;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@lightdash/cli",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.1420.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.
|
15
|
-
"@lightdash/warehouses": "^0.
|
14
|
+
"@lightdash/common": "^0.1420.1",
|
15
|
+
"@lightdash/warehouses": "^0.1420.1",
|
16
16
|
"@types/columnify": "^1.5.1",
|
17
17
|
"ajv": "^8.11.0",
|
18
18
|
"ajv-formats": "^2.1.1",
|