@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/.tsbuildinfo +1 -1
- package/dist/handlers/apps/appsDownload.d.ts +1 -1
- package/dist/handlers/apps/appsDownload.d.ts.map +1 -1
- package/dist/handlers/apps/appsDownload.js +2 -2
- package/dist/handlers/apps/validate.d.ts +6 -1
- package/dist/handlers/apps/validate.d.ts.map +1 -1
- package/dist/handlers/apps/validate.js +28 -5
- package/dist/handlers/apps/validate.test.js +42 -0
- package/dist/handlers/download.d.ts.map +1 -1
- package/dist/handlers/download.js +85 -27
- package/dist/handlers/metadataFile.d.ts.map +1 -1
- package/dist/handlers/metadataFile.js +3 -0
- package/dist/handlers/metadataFile.test.d.ts +2 -0
- package/dist/handlers/metadataFile.test.d.ts.map +1 -0
- package/dist/handlers/metadataFile.test.js +46 -0
- package/dist/index.js +25 -22
- package/dist/refsArgument.d.ts +8 -0
- package/dist/refsArgument.d.ts.map +1 -0
- package/dist/refsArgument.js +16 -0
- package/dist/refsArgument.test.d.ts +2 -0
- package/dist/refsArgument.test.d.ts.map +1 -0
- package/dist/refsArgument.test.js +42 -0
- package/package.json +3 -3
|
@@ -33,7 +33,7 @@ export declare const resolveUploadFilterUuids: (filter: Set<string>, listedApps:
|
|
|
33
33
|
* refs (including refs parsed out of app URLs) get the slug-identity
|
|
34
34
|
* explanation: id-free bundles can only be selected by slug.
|
|
35
35
|
*/
|
|
36
|
-
export declare const unmatchedUploadRefsWarning: (unmatched: string[]) => string | null;
|
|
36
|
+
export declare const unmatchedUploadRefsWarning: (unmatched: string[], noun?: string) => string | null;
|
|
37
37
|
/**
|
|
38
38
|
* Shown when the upload response carries no slug even though the bundle sent
|
|
39
39
|
* one — the server predates slug identity, so it ignored the slug and matched
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appsDownload.d.ts","sourceRoot":"","sources":["../../../src/handlers/apps/appsDownload.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACvB,MAAM,mBAAmB,CAAC;AAc3B,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC,eAAO,MAAM,mBAAmB,cAAe,MAAM,KAAG,MAoBvD,CAAC;AAEF,eAAO,MAAM,sBAAsB,eACnB,MAAM,EAAE,eACP,OAAO,KACrB,GAAG,CAAC,MAAM,CAAC,GAAG,IACoD,CAAC;AAEtE;;;GAGG;AACH,eAAO,MAAM,mBAAmB,WACpB,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI,YAChB,eAAe,KAC1B,OAG2D,CAAC;AAE/D,gFAAgF;AAChF,eAAO,MAAM,iBAAiB,WAClB,GAAG,CAAC,MAAM,CAAC,YACT,eAAe,KAC1B,MAAM,EAGJ,CAAC;AAEN;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,QACvB,MAAM,UACH;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,KACzC,MAWF,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,WACzB,GAAG,CAAC,MAAM,CAAC,cACP;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,KACjD,GAAG,CAAC,MAAM,CAcZ,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,cACxB,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"appsDownload.d.ts","sourceRoot":"","sources":["../../../src/handlers/apps/appsDownload.ts"],"names":[],"mappings":"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"}
|
|
@@ -73,10 +73,10 @@ exports.resolveUploadFilterUuids = resolveUploadFilterUuids;
|
|
|
73
73
|
* refs (including refs parsed out of app URLs) get the slug-identity
|
|
74
74
|
* explanation: id-free bundles can only be selected by slug.
|
|
75
75
|
*/
|
|
76
|
-
const unmatchedUploadRefsWarning = (unmatched) => {
|
|
76
|
+
const unmatchedUploadRefsWarning = (unmatched, noun = 'app') => {
|
|
77
77
|
if (unmatched.length === 0)
|
|
78
78
|
return null;
|
|
79
|
-
const base = `No local
|
|
79
|
+
const base = `No local ${noun} folder matched: ${unmatched.join(', ')}.`;
|
|
80
80
|
return unmatched.some((ref) => (0, uuid_1.validate)(ref))
|
|
81
81
|
? `${base} Bundles downloaded with slug identity carry no uuid — select them by slug (the folder name) instead of a UUID or app URL.`
|
|
82
82
|
: base;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type DataAppCode, type DataAppDataReferences, type DataAppExploreIndex, type DataReferenceLocation } from '@lightdash/common';
|
|
1
|
+
import { type DataAppCode, type DataAppDataReferences, type DataAppExploreIndex, type DataAppManifest, type DataReferenceLocation } from '@lightdash/common';
|
|
2
2
|
export type AppsValidateFormat = 'human' | 'json';
|
|
3
3
|
export type AppsValidateOptions = {
|
|
4
4
|
build: boolean;
|
|
@@ -24,6 +24,7 @@ export type AppValidationResult = {
|
|
|
24
24
|
path: string;
|
|
25
25
|
name: string | null;
|
|
26
26
|
projectUuid: string | null;
|
|
27
|
+
template: DataAppManifest['template'] | null;
|
|
27
28
|
valid: boolean;
|
|
28
29
|
errors: AppsValidationIssue[];
|
|
29
30
|
warnings: AppsValidationIssue[];
|
|
@@ -36,6 +37,8 @@ export type AppsValidationReport = {
|
|
|
36
37
|
mode: 'live' | 'offline';
|
|
37
38
|
summary: {
|
|
38
39
|
apps: number;
|
|
40
|
+
dataApps: number;
|
|
41
|
+
chartTypes: number;
|
|
39
42
|
errors: number;
|
|
40
43
|
warnings: number;
|
|
41
44
|
callSites: number;
|
|
@@ -70,6 +73,8 @@ export declare const validateDataAppBuild: (args: {
|
|
|
70
73
|
export declare const fetchLiveDataAppExploreIndex: (projectUuid: string) => Promise<DataAppExploreIndex>;
|
|
71
74
|
export declare const validateLocalDataApp: (appPath: string, options: ValidateAppOptions) => Promise<AppValidationResult>;
|
|
72
75
|
export declare const buildAppsValidationReport: (apps: AppValidationResult[], live: boolean, build?: boolean) => AppsValidationReport;
|
|
76
|
+
/** "2 data app(s)", "1 custom chart type(s)", or both — driven by manifest templates. */
|
|
77
|
+
export declare const describeValidatedBundles: (summary: AppsValidationReport['summary']) => string;
|
|
73
78
|
export declare const renderAppsValidationHuman: (report: AppsValidationReport, verbose?: boolean) => string;
|
|
74
79
|
export declare const renderAppsValidationJson: (report: AppsValidationReport) => string;
|
|
75
80
|
export declare const appsValidateHandler: (pathArgs: string[] | undefined, options: AppsValidateOptions) => Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/handlers/apps/validate.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/handlers/apps/validate.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.appsValidateHandler = exports.renderAppsValidationJson = exports.renderAppsValidationHuman = exports.buildAppsValidationReport = exports.validateLocalDataApp = exports.fetchLiveDataAppExploreIndex = exports.validateDataAppBuild = void 0;
|
|
3
|
+
exports.appsValidateHandler = exports.renderAppsValidationJson = exports.renderAppsValidationHuman = exports.describeValidatedBundles = exports.buildAppsValidationReport = exports.validateLocalDataApp = exports.fetchLiveDataAppExploreIndex = exports.validateDataAppBuild = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const common_1 = require("@lightdash/common");
|
|
6
6
|
const execa_1 = tslib_1.__importDefault(require("execa"));
|
|
@@ -289,6 +289,7 @@ const validateLocalDataApp = async (appPath, options) => {
|
|
|
289
289
|
path: appDir,
|
|
290
290
|
name: null,
|
|
291
291
|
projectUuid: null,
|
|
292
|
+
template: null,
|
|
292
293
|
valid: false,
|
|
293
294
|
errors: [issue('bundle', (0, common_1.getErrorMessage)(error))],
|
|
294
295
|
warnings,
|
|
@@ -374,6 +375,7 @@ const validateLocalDataApp = async (appPath, options) => {
|
|
|
374
375
|
path: appDir,
|
|
375
376
|
name: typeof manifest.name === 'string' ? manifest.name : null,
|
|
376
377
|
projectUuid,
|
|
378
|
+
template: manifest.template ?? null,
|
|
377
379
|
valid: errors.length === 0,
|
|
378
380
|
errors,
|
|
379
381
|
warnings,
|
|
@@ -385,12 +387,15 @@ exports.validateLocalDataApp = validateLocalDataApp;
|
|
|
385
387
|
const buildAppsValidationReport = (apps, live, build = false) => {
|
|
386
388
|
const errors = apps.reduce((count, app) => count + app.errors.length, 0);
|
|
387
389
|
const warnings = apps.reduce((count, app) => count + app.warnings.length, 0);
|
|
390
|
+
const chartTypes = apps.filter((app) => app.template === common_1.DATA_APP_VIZ_TEMPLATE).length;
|
|
388
391
|
return {
|
|
389
392
|
build,
|
|
390
393
|
valid: errors === 0,
|
|
391
394
|
mode: live ? 'live' : 'offline',
|
|
392
395
|
summary: {
|
|
393
396
|
apps: apps.length,
|
|
397
|
+
dataApps: apps.length - chartTypes,
|
|
398
|
+
chartTypes,
|
|
394
399
|
errors,
|
|
395
400
|
warnings,
|
|
396
401
|
callSites: apps.reduce((count, app) => count + app.coverage.callSites, 0),
|
|
@@ -422,9 +427,27 @@ const referenceKindLabels = {
|
|
|
422
427
|
globalFilter: 'global filter',
|
|
423
428
|
};
|
|
424
429
|
const formatUnanalyzedReference = (reference) => `${reference.location.path}:${reference.location.line}:${reference.location.column} — ${referenceKindLabels[reference.kind]} (unresolved: ${reference.unresolved.join(', ')})`;
|
|
430
|
+
/** "2 data app(s)", "1 custom chart type(s)", or both — driven by manifest templates. */
|
|
431
|
+
const describeValidatedBundles = (summary) => {
|
|
432
|
+
if (summary.chartTypes > 0 && summary.dataApps > 0) {
|
|
433
|
+
return `${summary.dataApps} data app(s) and ${summary.chartTypes} custom chart type(s)`;
|
|
434
|
+
}
|
|
435
|
+
if (summary.chartTypes > 0) {
|
|
436
|
+
return `${summary.chartTypes} custom chart type(s)`;
|
|
437
|
+
}
|
|
438
|
+
return `${summary.dataApps} data app(s)`;
|
|
439
|
+
};
|
|
440
|
+
exports.describeValidatedBundles = describeValidatedBundles;
|
|
441
|
+
const bundleKindLabel = (summary) => {
|
|
442
|
+
if (summary.chartTypes > 0 && summary.dataApps > 0)
|
|
443
|
+
return 'App bundle';
|
|
444
|
+
if (summary.chartTypes > 0)
|
|
445
|
+
return 'Custom chart type';
|
|
446
|
+
return 'Data app';
|
|
447
|
+
};
|
|
425
448
|
const renderAppsValidationHuman = (report, verbose = false) => {
|
|
426
449
|
const lines = [
|
|
427
|
-
`Validating ${report.summary
|
|
450
|
+
`Validating ${(0, exports.describeValidatedBundles)(report.summary)} using ${report.mode === 'live'
|
|
428
451
|
? 'the live project semantic layer'
|
|
429
452
|
: 'local semantic layer snapshots'}${report.build ? ' and running Vite production builds' : ''}.`,
|
|
430
453
|
];
|
|
@@ -451,8 +474,8 @@ const renderAppsValidationHuman = (report, verbose = false) => {
|
|
|
451
474
|
}
|
|
452
475
|
lines.push('');
|
|
453
476
|
lines.push(report.valid
|
|
454
|
-
? styles.success(`Validation passed for ${report.summary
|
|
455
|
-
: styles.error(`Validation failed with ${report.summary.errors} error(s) across ${report.summary
|
|
477
|
+
? styles.success(`Validation passed for ${(0, exports.describeValidatedBundles)(report.summary)} with ${report.summary.warnings} warning(s).`)
|
|
478
|
+
: styles.error(`Validation failed with ${report.summary.errors} error(s) across ${(0, exports.describeValidatedBundles)(report.summary)}.`));
|
|
456
479
|
return `${lines.join('\n')}\n`;
|
|
457
480
|
};
|
|
458
481
|
exports.renderAppsValidationHuman = renderAppsValidationHuman;
|
|
@@ -487,7 +510,7 @@ const appsValidateHandler = async (pathArgs, options) => {
|
|
|
487
510
|
? (0, exports.renderAppsValidationJson)(report)
|
|
488
511
|
: (0, exports.renderAppsValidationHuman)(report, options.verbose));
|
|
489
512
|
if (!report.valid) {
|
|
490
|
-
throw new common_1.ParameterError(
|
|
513
|
+
throw new common_1.ParameterError(`${bundleKindLabel(report.summary)} validation failed with ${report.summary.errors} error(s).`);
|
|
491
514
|
}
|
|
492
515
|
};
|
|
493
516
|
exports.appsValidateHandler = appsValidateHandler;
|
|
@@ -397,6 +397,7 @@ describe('renderAppsValidationHuman', () => {
|
|
|
397
397
|
path: '/tmp/orders-app',
|
|
398
398
|
name: 'Orders app',
|
|
399
399
|
projectUuid: 'project-uuid',
|
|
400
|
+
template: null,
|
|
400
401
|
valid: true,
|
|
401
402
|
errors: [],
|
|
402
403
|
warnings: [],
|
|
@@ -457,4 +458,45 @@ describe('renderAppsValidationHuman', () => {
|
|
|
457
458
|
const output = (0, validate_1.renderAppsValidationJson)(report);
|
|
458
459
|
expect(JSON.parse(output)).not.toHaveProperty('apps.0.unanalyzedReferences');
|
|
459
460
|
});
|
|
461
|
+
const buildResult = (template, overrides = {}) => ({
|
|
462
|
+
path: '/tmp/bundle',
|
|
463
|
+
name: 'Bundle',
|
|
464
|
+
projectUuid: null,
|
|
465
|
+
template,
|
|
466
|
+
valid: true,
|
|
467
|
+
errors: [],
|
|
468
|
+
warnings: [],
|
|
469
|
+
coverage: {
|
|
470
|
+
callSites: 0,
|
|
471
|
+
fullyResolved: 0,
|
|
472
|
+
partiallyResolved: 0,
|
|
473
|
+
unresolved: 0,
|
|
474
|
+
unanalyzed: 0,
|
|
475
|
+
},
|
|
476
|
+
unanalyzedReferences: [],
|
|
477
|
+
...overrides,
|
|
478
|
+
});
|
|
479
|
+
it('describes an all-chart-type run as custom chart types', () => {
|
|
480
|
+
const vizReport = (0, validate_1.buildAppsValidationReport)([buildResult(common_1.DATA_APP_VIZ_TEMPLATE)], false);
|
|
481
|
+
const output = (0, validate_1.renderAppsValidationHuman)(vizReport);
|
|
482
|
+
expect(output).toContain('Validating 1 custom chart type(s)');
|
|
483
|
+
expect(output).toContain('Validation passed for 1 custom chart type(s)');
|
|
484
|
+
expect(output).not.toContain('data app(s)');
|
|
485
|
+
expect(vizReport.summary.chartTypes).toBe(1);
|
|
486
|
+
expect(vizReport.summary.dataApps).toBe(0);
|
|
487
|
+
});
|
|
488
|
+
it('describes a mixed run with both nouns', () => {
|
|
489
|
+
const mixedReport = (0, validate_1.buildAppsValidationReport)([
|
|
490
|
+
buildResult(common_1.DATA_APP_VIZ_TEMPLATE, {
|
|
491
|
+
valid: false,
|
|
492
|
+
errors: [
|
|
493
|
+
{ code: 'manifest', message: 'bad', location: null },
|
|
494
|
+
],
|
|
495
|
+
}),
|
|
496
|
+
buildResult(null),
|
|
497
|
+
], false);
|
|
498
|
+
const output = (0, validate_1.renderAppsValidationHuman)(mixedReport);
|
|
499
|
+
expect(output).toContain('Validating 1 data app(s) and 1 custom chart type(s)');
|
|
500
|
+
expect(output).toContain('Validation failed with 1 error(s) across 1 data app(s) and 1 custom chart type(s).');
|
|
501
|
+
});
|
|
460
502
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/handlers/download.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/handlers/download.ts"],"names":[],"mappings":"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"}
|
|
@@ -1108,6 +1108,9 @@ const downloadHandler = async (options) => {
|
|
|
1108
1108
|
});
|
|
1109
1109
|
const projectName = (0, common_1.generateSlug)(project.name);
|
|
1110
1110
|
const counts = {};
|
|
1111
|
+
// Per-resource app/chart-type failures are reported inline and tallied
|
|
1112
|
+
// here so the process can exit non-zero without aborting the download.
|
|
1113
|
+
let downloadFailures = 0;
|
|
1111
1114
|
const start = Date.now();
|
|
1112
1115
|
await analytics_1.LightdashAnalytics.track({
|
|
1113
1116
|
event: 'download.started',
|
|
@@ -1419,6 +1422,7 @@ const downloadHandler = async (options) => {
|
|
|
1419
1422
|
});
|
|
1420
1423
|
const summary = (0, appsDownload_1.appsDownloadSummary)(successCount, appRefsToDownload.length, failures, appsDir, skippedNotBuiltCount + skippedWrongKindCount);
|
|
1421
1424
|
counts.appsNum = successCount;
|
|
1425
|
+
downloadFailures += failures.length;
|
|
1422
1426
|
output.completeItem(`${successCount} downloaded${skippedNotBuiltCount + skippedWrongKindCount > 0
|
|
1423
1427
|
? `, ${skippedNotBuiltCount + skippedWrongKindCount} skipped`
|
|
1424
1428
|
: ''}${failures.length > 0 ? `, ${failures.length} failed` : ''}`, summary.ok ? undefined : 'warning');
|
|
@@ -1525,6 +1529,7 @@ const downloadHandler = async (options) => {
|
|
|
1525
1529
|
const chartTypesSummary = (0, appsDownload_1.appsDownloadSummary)(chartTypesOutcome.successCount, chartTypeRefsToDownload.length, chartTypesOutcome.failures, chartTypesDir, chartTypesOutcome.skippedNotBuiltCount +
|
|
1526
1530
|
chartTypesOutcome.skippedWrongKindCount, 'custom chart type');
|
|
1527
1531
|
counts.chartTypesNum = chartTypesOutcome.successCount;
|
|
1532
|
+
downloadFailures += chartTypesOutcome.failures.length;
|
|
1528
1533
|
const chartTypesSkipped = chartTypesOutcome.skippedNotBuiltCount +
|
|
1529
1534
|
chartTypesOutcome.skippedWrongKindCount;
|
|
1530
1535
|
output.completeItem(`${chartTypesOutcome.successCount} downloaded${chartTypesSkipped > 0
|
|
@@ -1568,6 +1573,7 @@ const downloadHandler = async (options) => {
|
|
|
1568
1573
|
const linkedSkipped = outcome.skippedNotBuiltCount + outcome.skippedWrongKindCount;
|
|
1569
1574
|
const linkedSummary = (0, appsDownload_1.appsDownloadSummary)(outcome.successCount, linkedAppSlugs.length, outcome.failures, appsDir, linkedSkipped);
|
|
1570
1575
|
counts.appsNum = (counts.appsNum ?? 0) + outcome.successCount;
|
|
1576
|
+
downloadFailures += outcome.failures.length;
|
|
1571
1577
|
output.completeItem(`${outcome.successCount} downloaded${linkedSkipped > 0 ? `, ${linkedSkipped} skipped` : ''}${outcome.failures.length > 0
|
|
1572
1578
|
? `, ${outcome.failures.length} failed`
|
|
1573
1579
|
: ''}`, linkedSummary.ok ? undefined : 'warning');
|
|
@@ -1611,6 +1617,7 @@ const downloadHandler = async (options) => {
|
|
|
1611
1617
|
counts.chartTypesNum =
|
|
1612
1618
|
(counts.chartTypesNum ?? 0) +
|
|
1613
1619
|
linkedChartTypesOutcome.successCount;
|
|
1620
|
+
downloadFailures += linkedChartTypesOutcome.failures.length;
|
|
1614
1621
|
output.completeItem(`${linkedChartTypesOutcome.successCount} downloaded${linkedChartTypesSkipped > 0
|
|
1615
1622
|
? `, ${linkedChartTypesSkipped} skipped`
|
|
1616
1623
|
: ''}${linkedChartTypesOutcome.failures.length > 0
|
|
@@ -1645,6 +1652,10 @@ const downloadHandler = async (options) => {
|
|
|
1645
1652
|
if (!renderedSummary) {
|
|
1646
1653
|
globalState_1.default.log(styles.success(`Downloaded content saved to ${downloadRoot}`));
|
|
1647
1654
|
}
|
|
1655
|
+
if (downloadFailures > 0) {
|
|
1656
|
+
globalState_1.default.log(styles.error(`${downloadFailures} resource(s) failed to download — see errors above.`));
|
|
1657
|
+
process.exitCode = 1;
|
|
1658
|
+
}
|
|
1648
1659
|
await analytics_1.LightdashAnalytics.track({
|
|
1649
1660
|
event: 'download.completed',
|
|
1650
1661
|
properties: {
|
|
@@ -1724,6 +1735,8 @@ const summarizeUploadChanges = (before, after) => {
|
|
|
1724
1735
|
const hasFailures = [...totals.keys()].some((label) => label === 'with errors' || label === 'failed');
|
|
1725
1736
|
return { detail, variant: hasFailures ? 'warning' : undefined };
|
|
1726
1737
|
};
|
|
1738
|
+
const hasUploadFailures = (changes) => Object.entries(changes).some(([key, value]) => value > 0 &&
|
|
1739
|
+
(key.endsWith('with errors') || key.endsWith('failed')));
|
|
1727
1740
|
const runUploadChangesPhase = async ({ output, label, changes, action, onCount, }) => {
|
|
1728
1741
|
const before = { ...changes };
|
|
1729
1742
|
output.startItem(label);
|
|
@@ -1738,7 +1751,7 @@ const upsertSingleItem = async (item, type, projectId, changes, force, config, s
|
|
|
1738
1751
|
if (!force && !item.needsUpdating) {
|
|
1739
1752
|
globalState_1.default.debug(`Skipping ${type} "${item.slug}" with no local changes`);
|
|
1740
1753
|
changes[`${type} skipped`] = (changes[`${type} skipped`] ?? 0) + 1;
|
|
1741
|
-
return;
|
|
1754
|
+
return 'skipped';
|
|
1742
1755
|
}
|
|
1743
1756
|
globalState_1.default.debug(`Upserting ${type} ${item.slug}`);
|
|
1744
1757
|
// SQL charts use a different endpoint
|
|
@@ -1806,36 +1819,41 @@ const upsertSingleItem = async (item, type, projectId, changes, force, config, s
|
|
|
1806
1819
|
}
|
|
1807
1820
|
}
|
|
1808
1821
|
}
|
|
1822
|
+
return 'upserted';
|
|
1809
1823
|
}
|
|
1810
1824
|
catch (error) {
|
|
1811
1825
|
if (error instanceof common_1.LightdashError &&
|
|
1812
1826
|
error.name === 'NotFoundError' &&
|
|
1827
|
+
// Only the missing-space NotFoundError counts as a space skip;
|
|
1828
|
+
// other NotFoundErrors (e.g. a missing custom chart type) are
|
|
1829
|
+
// real failures even with --skip-space-create.
|
|
1830
|
+
error.message.startsWith('Space ') &&
|
|
1813
1831
|
skipSpaceCreate) {
|
|
1814
1832
|
globalState_1.default.log(styles.warning(`Skipping ${type} "${item.slug}" because space "${item.spaceSlug}" does not exist and --skip-space-create is true`));
|
|
1815
1833
|
changes[`${type} skipped`] = (changes[`${type} skipped`] ?? 0) + 1;
|
|
1834
|
+
return 'skipped';
|
|
1816
1835
|
}
|
|
1817
|
-
|
|
1818
|
-
changes[`${type} with errors`]
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
|
|
1828
|
-
|
|
1829
|
-
|
|
1830
|
-
|
|
1831
|
-
}
|
|
1836
|
+
changes[`${type} with errors`] =
|
|
1837
|
+
(changes[`${type} with errors`] ?? 0) + 1;
|
|
1838
|
+
globalState_1.default.log(styles.error(`Error upserting ${type}:\n\t"${item.name}" (slug: "${item.slug}")\n\t${(0, common_1.getErrorMessage)(error)}`));
|
|
1839
|
+
await analytics_1.LightdashAnalytics.track({
|
|
1840
|
+
event: 'download.error',
|
|
1841
|
+
properties: {
|
|
1842
|
+
userId: config.user?.userUuid,
|
|
1843
|
+
organizationId: config.user?.organizationUuid,
|
|
1844
|
+
projectId,
|
|
1845
|
+
type,
|
|
1846
|
+
error: (0, common_1.getErrorMessage)(error),
|
|
1847
|
+
},
|
|
1848
|
+
});
|
|
1849
|
+
return 'failed';
|
|
1832
1850
|
}
|
|
1833
1851
|
};
|
|
1834
1852
|
/**
|
|
1835
1853
|
*
|
|
1836
1854
|
* @param slugs if slugs are provided, we only force upsert the charts/dashboards that match the slugs, if slugs are empty, we upload files that were locally updated
|
|
1837
1855
|
*/
|
|
1838
|
-
const upsertResources = async (type, projectId, changes, force, slugs, canUpload, customPath, skipSpaceCreate, publicSpaceCreate, validate, concurrency = 1, extraItems = [], spaceNames) => {
|
|
1856
|
+
const upsertResources = async (type, projectId, changes, force, slugs, canUpload, customPath, skipSpaceCreate, publicSpaceCreate, validate, concurrency = 1, extraItems = [], spaceNames, skipSlugs) => {
|
|
1839
1857
|
const config = await (0, config_1.getConfig)();
|
|
1840
1858
|
const folderItems = await readCodeFiles(type, customPath);
|
|
1841
1859
|
const items = [...folderItems, ...extraItems];
|
|
@@ -1854,17 +1872,37 @@ const upsertResources = async (type, projectId, changes, force, slugs, canUpload
|
|
|
1854
1872
|
if (filteredItems.length > 0 && !canUpload) {
|
|
1855
1873
|
const requiredPermission = type === 'charts' ? 'manage:SavedChart' : 'manage:Dashboard';
|
|
1856
1874
|
globalState_1.default.log(styles.error(`Error uploading ${type}: the ${requiredPermission} permission is required`));
|
|
1857
|
-
return { changes, total: filteredItems.length };
|
|
1858
|
-
}
|
|
1875
|
+
return { changes, total: filteredItems.length, failedSlugs: [] };
|
|
1876
|
+
}
|
|
1877
|
+
// Items whose dependencies failed earlier in the upload are held back so
|
|
1878
|
+
// they are not created in a broken state (e.g. dashboards with null
|
|
1879
|
+
// chart tiles).
|
|
1880
|
+
const uploadableItems = skipSlugs
|
|
1881
|
+
? filteredItems.filter((item) => !skipSlugs.has(item.slug))
|
|
1882
|
+
: filteredItems;
|
|
1883
|
+
filteredItems
|
|
1884
|
+
.filter((item) => !uploadableItems.includes(item))
|
|
1885
|
+
.forEach((item) => {
|
|
1886
|
+
changes[`${type} dependency skipped`] =
|
|
1887
|
+
(changes[`${type} dependency skipped`] ?? 0) + 1;
|
|
1888
|
+
globalState_1.default.log(styles.warning(`Skipped ${type.slice(0, -1)} "${item.slug}" because a chart it references failed to upload`));
|
|
1889
|
+
});
|
|
1890
|
+
const failedSlugs = [];
|
|
1891
|
+
const trackOutcome = (item, outcome) => {
|
|
1892
|
+
if (outcome === 'failed') {
|
|
1893
|
+
failedSlugs.push(item.slug);
|
|
1894
|
+
}
|
|
1895
|
+
};
|
|
1859
1896
|
if (concurrency <= 1) {
|
|
1860
1897
|
// Sequential path — preserves original behavior exactly
|
|
1861
|
-
for (const item of
|
|
1898
|
+
for (const item of uploadableItems) {
|
|
1862
1899
|
// eslint-disable-next-line no-await-in-loop
|
|
1863
|
-
await upsertSingleItem(item, type, projectId, changes, force, config, skipSpaceCreate, publicSpaceCreate, validate, spaceNames);
|
|
1900
|
+
const outcome = await upsertSingleItem(item, type, projectId, changes, force, config, skipSpaceCreate, publicSpaceCreate, validate, spaceNames);
|
|
1901
|
+
trackOutcome(item, outcome);
|
|
1864
1902
|
}
|
|
1865
1903
|
}
|
|
1866
1904
|
else {
|
|
1867
|
-
const grouped = (0, groupBy_1.default)(
|
|
1905
|
+
const grouped = (0, groupBy_1.default)(uploadableItems, (item) => item.spaceSlug);
|
|
1868
1906
|
const seedItems = new Set();
|
|
1869
1907
|
const remainingItems = [];
|
|
1870
1908
|
Object.values(grouped).forEach((spaceItems) => {
|
|
@@ -1910,15 +1948,17 @@ const upsertResources = async (type, projectId, changes, force, slugs, canUpload
|
|
|
1910
1948
|
// Phase 1: Sequential seeding (spaces + dashboard placeholders)
|
|
1911
1949
|
for (const item of seedItems) {
|
|
1912
1950
|
// eslint-disable-next-line no-await-in-loop
|
|
1913
|
-
await upsertSingleItem(item, type, projectId, changes, force, config, skipSpaceCreate, publicSpaceCreate, validate, spaceNames);
|
|
1951
|
+
const outcome = await upsertSingleItem(item, type, projectId, changes, force, config, skipSpaceCreate, publicSpaceCreate, validate, spaceNames);
|
|
1952
|
+
trackOutcome(item, outcome);
|
|
1914
1953
|
}
|
|
1915
1954
|
// Phase 2: Parallel bulk upload of remaining items
|
|
1916
1955
|
const limit = (0, p_limit_1.default)(concurrency);
|
|
1917
1956
|
await Promise.all(remainingItems.map((item) => limit(async () => {
|
|
1918
|
-
await upsertSingleItem(item, type, projectId, changes, force, config, skipSpaceCreate, publicSpaceCreate, validate, spaceNames);
|
|
1957
|
+
const outcome = await upsertSingleItem(item, type, projectId, changes, force, config, skipSpaceCreate, publicSpaceCreate, validate, spaceNames);
|
|
1958
|
+
trackOutcome(item, outcome);
|
|
1919
1959
|
})));
|
|
1920
1960
|
}
|
|
1921
|
-
return { changes, total: filteredItems.length };
|
|
1961
|
+
return { changes, total: filteredItems.length, failedSlugs };
|
|
1922
1962
|
};
|
|
1923
1963
|
// readCodeFiles walks the whole download folder recursively, so callers that
|
|
1924
1964
|
// need both chart and app slugs should read once and reuse the result.
|
|
@@ -2069,6 +2109,10 @@ const uploadHandler = async (options) => {
|
|
|
2069
2109
|
(0, spacesAsCode_1.logUploadChanges)(changes);
|
|
2070
2110
|
globalState_1.default.log(styles.success(`Uploaded content from ${uploadRoot}`));
|
|
2071
2111
|
}
|
|
2112
|
+
if (hasUploadFailures(changes)) {
|
|
2113
|
+
globalState_1.default.log(styles.error('Upload completed with failures — see errors above.'));
|
|
2114
|
+
process.exitCode = 1;
|
|
2115
|
+
}
|
|
2072
2116
|
};
|
|
2073
2117
|
try {
|
|
2074
2118
|
const spaceFiles = preflightSpaceFiles;
|
|
@@ -2533,7 +2577,7 @@ const uploadHandler = async (options) => {
|
|
|
2533
2577
|
}
|
|
2534
2578
|
}
|
|
2535
2579
|
if (uploadFilter) {
|
|
2536
|
-
const unmatchedWarning = (0, appsDownload_1.unmatchedUploadRefsWarning)([...uploadFilter].filter((ref) => !matchedRefs.has(ref)));
|
|
2580
|
+
const unmatchedWarning = (0, appsDownload_1.unmatchedUploadRefsWarning)([...uploadFilter].filter((ref) => !matchedRefs.has(ref)), phase.noun);
|
|
2537
2581
|
if (unmatchedWarning) {
|
|
2538
2582
|
globalState_1.default.log(styles.warning(unmatchedWarning));
|
|
2539
2583
|
}
|
|
@@ -2574,6 +2618,10 @@ const uploadHandler = async (options) => {
|
|
|
2574
2618
|
process.exitCode = 1;
|
|
2575
2619
|
}
|
|
2576
2620
|
}
|
|
2621
|
+
// Chart slugs that failed to upload in the Charts phase; dashboards
|
|
2622
|
+
// referencing them are held back so they are not created with broken
|
|
2623
|
+
// (null chart) tiles.
|
|
2624
|
+
const failedChartSlugs = new Set();
|
|
2577
2625
|
changes = await runUploadChangesPhase({
|
|
2578
2626
|
output,
|
|
2579
2627
|
label: 'Charts',
|
|
@@ -2590,6 +2638,7 @@ const uploadHandler = async (options) => {
|
|
|
2590
2638
|
return changes;
|
|
2591
2639
|
}
|
|
2592
2640
|
const result = await upsertResources('charts', projectId, changes, options.force, chartSlugs, uploadPermissions.charts, options.path, options.skipSpaceCreate, options.public, options.validate, concurrency, looseFiles.charts, spaceNames);
|
|
2641
|
+
result.failedSlugs.forEach((slug) => failedChartSlugs.add(slug));
|
|
2593
2642
|
counts.chartsNum = result.total;
|
|
2594
2643
|
return result.changes;
|
|
2595
2644
|
},
|
|
@@ -2603,7 +2652,16 @@ const uploadHandler = async (options) => {
|
|
|
2603
2652
|
globalState_1.default.log(styles.warning(`No dashboard filters provided, skipping`));
|
|
2604
2653
|
return changes;
|
|
2605
2654
|
}
|
|
2606
|
-
|
|
2655
|
+
let dashboardsToSkip;
|
|
2656
|
+
if (failedChartSlugs.size > 0) {
|
|
2657
|
+
dashboardsToSkip = new Set((await loadDashboardItems())
|
|
2658
|
+
.filter((dashboard) => dashboard.tiles.some((tile) => 'chartSlug' in tile.properties &&
|
|
2659
|
+
typeof tile.properties.chartSlug ===
|
|
2660
|
+
'string' &&
|
|
2661
|
+
failedChartSlugs.has(tile.properties.chartSlug)))
|
|
2662
|
+
.map((dashboard) => dashboard.slug));
|
|
2663
|
+
}
|
|
2664
|
+
const result = await upsertResources('dashboards', projectId, changes, options.force, options.dashboards, uploadPermissions.dashboards, options.path, options.skipSpaceCreate, options.public, options.validate, concurrency, looseFiles.dashboards, spaceNames, dashboardsToSkip);
|
|
2607
2665
|
counts.dashboardsNum = result.total;
|
|
2608
2666
|
return result.changes;
|
|
2609
2667
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metadataFile.d.ts","sourceRoot":"","sources":["../../src/handlers/metadataFile.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,iBAAiB,6BAA6B,CAAC;AAE5D,MAAM,MAAM,iBAAiB,GAAG;IAC5B,OAAO,EAAE,CAAC,CAAC;IACX,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC,CAAC;AAQF,eAAO,MAAM,gBAAgB,YAChB,MAAM,KAChB,OAAO,CAAC,iBAAiB,CAQ3B,CAAC;AAEF,eAAO,MAAM,iBAAiB,YACjB,MAAM,YACL,iBAAiB,KAC5B,OAAO,CAAC,IAAI,
|
|
1
|
+
{"version":3,"file":"metadataFile.d.ts","sourceRoot":"","sources":["../../src/handlers/metadataFile.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,iBAAiB,6BAA6B,CAAC;AAE5D,MAAM,MAAM,iBAAiB,GAAG;IAC5B,OAAO,EAAE,CAAC,CAAC;IACX,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC,CAAC;AAQF,eAAO,MAAM,gBAAgB,YAChB,MAAM,KAChB,OAAO,CAAC,iBAAiB,CAQ3B,CAAC;AAEF,eAAO,MAAM,iBAAiB,YACjB,MAAM,YACL,iBAAiB,KAC5B,OAAO,CAAC,IAAI,CAYd,CAAC"}
|
|
@@ -29,6 +29,9 @@ const writeMetadataFile = async (baseDir, metadata) => {
|
|
|
29
29
|
dashboards: { ...existing.dashboards, ...metadata.dashboards },
|
|
30
30
|
};
|
|
31
31
|
const filePath = path.join(baseDir, exports.METADATA_FILENAME);
|
|
32
|
+
// An all-skipped download creates no bundle folders, so the output root
|
|
33
|
+
// may not exist yet when the metadata file is written.
|
|
34
|
+
await fs_1.promises.mkdir(baseDir, { recursive: true });
|
|
32
35
|
await fs_1.promises.writeFile(filePath, JSON.stringify(merged, null, 2));
|
|
33
36
|
};
|
|
34
37
|
exports.writeMetadataFile = writeMetadataFile;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metadataFile.test.d.ts","sourceRoot":"","sources":["../../src/handlers/metadataFile.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const os = tslib_1.__importStar(require("os"));
|
|
6
|
+
const path = tslib_1.__importStar(require("path"));
|
|
7
|
+
const metadataFile_1 = require("./metadataFile");
|
|
8
|
+
describe('writeMetadataFile', () => {
|
|
9
|
+
let tmpDir;
|
|
10
|
+
beforeEach(async () => {
|
|
11
|
+
tmpDir = await fs_1.promises.mkdtemp(path.join(os.tmpdir(), 'ld-metadata-'));
|
|
12
|
+
});
|
|
13
|
+
afterEach(async () => {
|
|
14
|
+
await fs_1.promises.rm(tmpDir, { recursive: true, force: true });
|
|
15
|
+
});
|
|
16
|
+
it('creates the output root when it does not exist yet', async () => {
|
|
17
|
+
const baseDir = path.join(tmpDir, 'brand-new-dir');
|
|
18
|
+
await (0, metadataFile_1.writeMetadataFile)(baseDir, {
|
|
19
|
+
version: 1,
|
|
20
|
+
charts: {},
|
|
21
|
+
dashboards: {},
|
|
22
|
+
});
|
|
23
|
+
const written = JSON.parse(await fs_1.promises.readFile(path.join(baseDir, metadataFile_1.METADATA_FILENAME), 'utf-8'));
|
|
24
|
+
expect(written).toEqual({ version: 1, charts: {}, dashboards: {} });
|
|
25
|
+
});
|
|
26
|
+
it('merges with existing metadata', async () => {
|
|
27
|
+
await (0, metadataFile_1.writeMetadataFile)(tmpDir, {
|
|
28
|
+
version: 1,
|
|
29
|
+
charts: { 'chart-a': '2026-01-01T00:00:00Z' },
|
|
30
|
+
dashboards: {},
|
|
31
|
+
});
|
|
32
|
+
await (0, metadataFile_1.writeMetadataFile)(tmpDir, {
|
|
33
|
+
version: 1,
|
|
34
|
+
charts: { 'chart-b': '2026-02-02T00:00:00Z' },
|
|
35
|
+
dashboards: { 'dash-a': '2026-02-02T00:00:00Z' },
|
|
36
|
+
});
|
|
37
|
+
expect(await (0, metadataFile_1.readMetadataFile)(tmpDir)).toEqual({
|
|
38
|
+
version: 1,
|
|
39
|
+
charts: {
|
|
40
|
+
'chart-a': '2026-01-01T00:00:00Z',
|
|
41
|
+
'chart-b': '2026-02-02T00:00:00Z',
|
|
42
|
+
},
|
|
43
|
+
dashboards: { 'dash-a': '2026-02-02T00:00:00Z' },
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
});
|