@lightdash/cli 1.79.1 → 1.80.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/appCodeFiles.d.ts +0 -5
- package/dist/handlers/apps/appCodeFiles.d.ts.map +1 -1
- package/dist/handlers/apps/appCodeFiles.js +1 -41
- package/dist/handlers/apps/appCodeFiles.test.js +0 -60
- package/dist/handlers/apps/appsDownload.d.ts +19 -19
- package/dist/handlers/apps/appsDownload.d.ts.map +1 -1
- package/dist/handlers/apps/appsDownload.js +29 -18
- package/dist/handlers/apps/appsDownload.test.js +32 -77
- package/dist/handlers/apps/preview.d.ts +1 -0
- package/dist/handlers/apps/preview.d.ts.map +1 -1
- package/dist/handlers/apps/preview.js +7 -3
- package/dist/handlers/apps/preview.test.js +13 -4
- package/dist/handlers/download.d.ts +2 -0
- package/dist/handlers/download.d.ts.map +1 -1
- package/dist/handlers/download.js +56 -35
- package/dist/index.js +4 -1
- package/package.json +3 -3
|
@@ -55,11 +55,6 @@ export declare const applySdkMirrorToTemplateDeps: (templateDependencies: Record
|
|
|
55
55
|
* deps (payload stays identical to today's format).
|
|
56
56
|
*/
|
|
57
57
|
export declare const attachDependenciesToCode: (code: DataAppCode, customDeps: Record<string, string>, deps: DataAppDependencies) => DataAppCode;
|
|
58
|
-
/**
|
|
59
|
-
* Mirrors the chart/dashboard rule: changed when a file that actually gets
|
|
60
|
-
* uploaded has drifted more than 30s from the manifest's downloadedAt.
|
|
61
|
-
*/
|
|
62
|
-
export declare const appFolderNeedsUpdating: (dir: string, manifest: DataAppManifest) => Promise<boolean>;
|
|
63
58
|
export declare const readManifestFromDir: (dir: string) => Promise<DataAppManifest>;
|
|
64
59
|
export declare const readBundleFromDir: (dir: string) => Promise<DataAppCode>;
|
|
65
60
|
//# sourceMappingURL=appCodeFiles.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"appCodeFiles.d.ts","sourceRoot":"","sources":["../../../src/handlers/apps/appCodeFiles.ts"],"names":[],"mappings":"AAAA,OAAO,EAKH,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,cAAc,EAEnB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,wBAAwB,EAChC,MAAM,mBAAmB,CAAC;AAO3B;;;;GAIG;AACH,eAAO,MAAM,aAAa,SAChB,MAAM,WACH,MAAM,gBACD,GAAG,CAAC,MAAM,CAAC,KAC1B,MAcF,CAAC;AAEF,eAAO,MAAM,eAAe,QACnB,MAAM,SACJ,eAAe,EAAE,KACzB,OAAO,CAAC,IAAI,CAsBd,CAAC;AAEF,eAAO,MAAM,iBAAiB,QACrB,MAAM,WACF,cAAc,KACxB,OAAO,CAAC,IAAI,CAiBd,CAAC;AAEF,eAAO,MAAM,gBAAgB,QACpB,MAAM,QACL,WAAW,KAClB,OAAO,CAAC,IAAI,CAWd,CAAC;AAmCF,eAAO,MAAM,eAAe,SAClB,WAAW,qBACE,MAAM,QACnB;IACF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB,KACF,wBAqBF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,aACnB,eAAe,gBACX,GAAG,CAAC,MAAM,CAAC,KAC1B,MAgBF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,QAC1B,MAAM,QACL,mBAAmB,KAC1B,OAAO,CAAC,IAAI,CAGd,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IAC/B,WAAW,EAAE,MAAM,CAAC;IAKpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAIxB,cAAc,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,QAC3B,MAAM,KACZ,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAmCrC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,eAClB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,wBACZ,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAC7C,MAAM,EAOH,CAAC;AAEP;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,yBACf,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,eAC/B,MAAM,KACpB,MAAM,CAAC,MAAM,EAAE,MAAM,CAgBvB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,SAC3B,WAAW,cACL,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,QAC5B,mBAAmB,KAC1B,WAC4E,CAAC;
|
|
1
|
+
{"version":3,"file":"appCodeFiles.d.ts","sourceRoot":"","sources":["../../../src/handlers/apps/appCodeFiles.ts"],"names":[],"mappings":"AAAA,OAAO,EAKH,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,cAAc,EAEnB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,wBAAwB,EAChC,MAAM,mBAAmB,CAAC;AAO3B;;;;GAIG;AACH,eAAO,MAAM,aAAa,SAChB,MAAM,WACH,MAAM,gBACD,GAAG,CAAC,MAAM,CAAC,KAC1B,MAcF,CAAC;AAEF,eAAO,MAAM,eAAe,QACnB,MAAM,SACJ,eAAe,EAAE,KACzB,OAAO,CAAC,IAAI,CAsBd,CAAC;AAEF,eAAO,MAAM,iBAAiB,QACrB,MAAM,WACF,cAAc,KACxB,OAAO,CAAC,IAAI,CAiBd,CAAC;AAEF,eAAO,MAAM,gBAAgB,QACpB,MAAM,QACL,WAAW,KAClB,OAAO,CAAC,IAAI,CAWd,CAAC;AAmCF,eAAO,MAAM,eAAe,SAClB,WAAW,qBACE,MAAM,QACnB;IACF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB,KACF,wBAqBF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,aACnB,eAAe,gBACX,GAAG,CAAC,MAAM,CAAC,KAC1B,MAgBF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,QAC1B,MAAM,QACL,mBAAmB,KAC1B,OAAO,CAAC,IAAI,CAGd,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IAC/B,WAAW,EAAE,MAAM,CAAC;IAKpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAIxB,cAAc,EAAE,OAAO,CAAC;CAC3B,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,QAC3B,MAAM,KACZ,OAAO,CAAC,oBAAoB,GAAG,IAAI,CAmCrC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,qBAAqB,eAClB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,wBACZ,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAC7C,MAAM,EAOH,CAAC;AAEP;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,yBACf,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,eAC/B,MAAM,KACpB,MAAM,CAAC,MAAM,EAAE,MAAM,CAgBvB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,SAC3B,WAAW,cACL,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,QAC5B,mBAAmB,KAC1B,WAC4E,CAAC;AAEhF,eAAO,MAAM,mBAAmB,QACvB,MAAM,KACZ,OAAO,CAAC,eAAe,CAYzB,CAAC;AAEF,eAAO,MAAM,iBAAiB,QAAe,MAAM,KAAG,OAAO,CAAC,WAAW,CAYxE,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.readBundleFromDir = exports.readManifestFromDir = exports.
|
|
3
|
+
exports.readBundleFromDir = exports.readManifestFromDir = exports.attachDependenciesToCode = exports.applySdkMirrorToTemplateDeps = exports.buildDepsWarningLines = exports.readDependenciesFromDir = exports.writeDependenciesToDir = exports.resolveAppFolderName = exports.buildImportBody = exports.writeBundleToDir = exports.writeContextToDir = exports.writeFilesToDir = exports.appFolderName = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const common_1 = require("@lightdash/common");
|
|
6
6
|
const fs_1 = require("fs");
|
|
@@ -223,46 +223,6 @@ exports.applySdkMirrorToTemplateDeps = applySdkMirrorToTemplateDeps;
|
|
|
223
223
|
*/
|
|
224
224
|
const attachDependenciesToCode = (code, customDeps, deps) => Object.keys(customDeps).length > 0 ? { ...code, dependencies: deps } : code;
|
|
225
225
|
exports.attachDependenciesToCode = attachDependenciesToCode;
|
|
226
|
-
const CHANGE_TOLERANCE_MS = 30_000;
|
|
227
|
-
const collectMtimes = async (dir) => {
|
|
228
|
-
const entries = await fs_1.promises.readdir(dir, { withFileTypes: true });
|
|
229
|
-
const nested = await Promise.all(entries.map(async (entry) => {
|
|
230
|
-
const entryPath = path.join(dir, entry.name);
|
|
231
|
-
if (entry.isDirectory())
|
|
232
|
-
return collectMtimes(entryPath);
|
|
233
|
-
const stats = await fs_1.promises.stat(entryPath);
|
|
234
|
-
return [stats.mtime.getTime()];
|
|
235
|
-
}));
|
|
236
|
-
return nested.flat();
|
|
237
|
-
};
|
|
238
|
-
const statMtime = async (file) => fs_1.promises
|
|
239
|
-
.stat(file)
|
|
240
|
-
.then((stats) => [stats.mtime.getTime()])
|
|
241
|
-
.catch(() => []);
|
|
242
|
-
/**
|
|
243
|
-
* Mirrors the chart/dashboard rule: changed when a file that actually gets
|
|
244
|
-
* uploaded has drifted more than 30s from the manifest's downloadedAt.
|
|
245
|
-
*/
|
|
246
|
-
const appFolderNeedsUpdating = async (dir, manifest) => {
|
|
247
|
-
if (!manifest.downloadedAt)
|
|
248
|
-
return true;
|
|
249
|
-
const downloadedAt = new Date(manifest.downloadedAt).getTime();
|
|
250
|
-
if (Number.isNaN(downloadedAt))
|
|
251
|
-
return true;
|
|
252
|
-
const srcDir = path.join(dir, 'src');
|
|
253
|
-
const srcExists = await fs_1.promises
|
|
254
|
-
.stat(srcDir)
|
|
255
|
-
.then((s) => s.isDirectory())
|
|
256
|
-
.catch(() => false);
|
|
257
|
-
const mtimes = [
|
|
258
|
-
...(srcExists ? await collectMtimes(srcDir) : []),
|
|
259
|
-
...(await statMtime(path.join(dir, 'package.json'))),
|
|
260
|
-
...(await statMtime(path.join(dir, 'pnpm-lock.yaml'))),
|
|
261
|
-
...(await statMtime(path.join(dir, MANIFEST_FILENAME))),
|
|
262
|
-
];
|
|
263
|
-
return mtimes.some((mtime) => Math.abs(mtime - downloadedAt) > CHANGE_TOLERANCE_MS);
|
|
264
|
-
};
|
|
265
|
-
exports.appFolderNeedsUpdating = appFolderNeedsUpdating;
|
|
266
226
|
const readManifestFromDir = async (dir) => {
|
|
267
227
|
const manifestRaw = await fs_1.promises.readFile(path.join(dir, MANIFEST_FILENAME), 'utf-8');
|
|
268
228
|
try {
|
|
@@ -389,63 +389,3 @@ describe('applySdkMirrorToTemplateDeps', () => {
|
|
|
389
389
|
expect((0, appCodeFiles_1.applySdkMirrorToTemplateDeps)(template, 'not-json')).toEqual(template);
|
|
390
390
|
});
|
|
391
391
|
});
|
|
392
|
-
// ─── appFolderNeedsUpdating ────────────────────────────────────────────────────
|
|
393
|
-
describe('appFolderNeedsUpdating', () => {
|
|
394
|
-
const DOWNLOADED_AT = '2026-07-30T12:00:00.000Z';
|
|
395
|
-
const manifest = { downloadedAt: DOWNLOADED_AT };
|
|
396
|
-
const buildFolder = () => {
|
|
397
|
-
const dir = (0, fs_1.mkdtempSync)(path.join(os.tmpdir(), 'ld-app-folder-'));
|
|
398
|
-
(0, fs_1.mkdirSync)(path.join(dir, 'src'), { recursive: true });
|
|
399
|
-
(0, fs_1.writeFileSync)(path.join(dir, 'src', 'App.tsx'), 'x');
|
|
400
|
-
(0, fs_1.writeFileSync)(path.join(dir, 'lightdash-app.yml'), 'slug: x');
|
|
401
|
-
(0, fs_1.mkdirSync)(path.join(dir, '.lightdash', 'context'), {
|
|
402
|
-
recursive: true,
|
|
403
|
-
});
|
|
404
|
-
(0, fs_1.writeFileSync)(path.join(dir, '.lightdash', 'context', 'semantic-layer.yml'), 'models: []');
|
|
405
|
-
const at = new Date(DOWNLOADED_AT);
|
|
406
|
-
[
|
|
407
|
-
path.join(dir, 'src', 'App.tsx'),
|
|
408
|
-
path.join(dir, 'lightdash-app.yml'),
|
|
409
|
-
path.join(dir, '.lightdash', 'context', 'semantic-layer.yml'),
|
|
410
|
-
].forEach((file) => (0, fs_1.utimesSync)(file, at, at));
|
|
411
|
-
return dir;
|
|
412
|
-
};
|
|
413
|
-
it('is false for a freshly downloaded folder', async () => {
|
|
414
|
-
await expect((0, appCodeFiles_1.appFolderNeedsUpdating)(buildFolder(), manifest)).resolves.toBe(false);
|
|
415
|
-
});
|
|
416
|
-
it('is true when a src file was edited', async () => {
|
|
417
|
-
const dir = buildFolder();
|
|
418
|
-
const later = new Date('2026-07-30T13:00:00.000Z');
|
|
419
|
-
(0, fs_1.utimesSync)(path.join(dir, 'src', 'App.tsx'), later, later);
|
|
420
|
-
await expect((0, appCodeFiles_1.appFolderNeedsUpdating)(dir, manifest)).resolves.toBe(true);
|
|
421
|
-
});
|
|
422
|
-
it('is true when the manifest was edited', async () => {
|
|
423
|
-
const dir = buildFolder();
|
|
424
|
-
const later = new Date('2026-07-30T13:00:00.000Z');
|
|
425
|
-
(0, fs_1.utimesSync)(path.join(dir, 'lightdash-app.yml'), later, later);
|
|
426
|
-
await expect((0, appCodeFiles_1.appFolderNeedsUpdating)(dir, manifest)).resolves.toBe(true);
|
|
427
|
-
});
|
|
428
|
-
it('ignores regenerated context files', async () => {
|
|
429
|
-
const dir = buildFolder();
|
|
430
|
-
const later = new Date('2026-07-30T13:00:00.000Z');
|
|
431
|
-
(0, fs_1.utimesSync)(path.join(dir, '.lightdash', 'context', 'semantic-layer.yml'), later, later);
|
|
432
|
-
await expect((0, appCodeFiles_1.appFolderNeedsUpdating)(dir, manifest)).resolves.toBe(false);
|
|
433
|
-
});
|
|
434
|
-
it('is true when downloadedAt is missing', async () => {
|
|
435
|
-
await expect((0, appCodeFiles_1.appFolderNeedsUpdating)(buildFolder(), {})).resolves.toBe(true);
|
|
436
|
-
});
|
|
437
|
-
it('is true when downloadedAt is unparseable', async () => {
|
|
438
|
-
await expect((0, appCodeFiles_1.appFolderNeedsUpdating)(buildFolder(), {
|
|
439
|
-
downloadedAt: 'not-a-date',
|
|
440
|
-
})).resolves.toBe(true);
|
|
441
|
-
});
|
|
442
|
-
it('is true when a nested src file was edited', async () => {
|
|
443
|
-
const dir = buildFolder();
|
|
444
|
-
(0, fs_1.mkdirSync)(path.join(dir, 'src', 'components'), { recursive: true });
|
|
445
|
-
const nested = path.join(dir, 'src', 'components', 'Chart.tsx');
|
|
446
|
-
(0, fs_1.writeFileSync)(nested, 'x');
|
|
447
|
-
const later = new Date('2026-07-30T13:00:00.000Z');
|
|
448
|
-
(0, fs_1.utimesSync)(nested, later, later);
|
|
449
|
-
await expect((0, appCodeFiles_1.appFolderNeedsUpdating)(dir, manifest)).resolves.toBe(true);
|
|
450
|
-
});
|
|
451
|
-
});
|
|
@@ -9,6 +9,25 @@ export declare const getDataAppUploadFilter: (references: string[], includeApps:
|
|
|
9
9
|
export declare const uploadFilterMatches: (filter: Set<string> | null, manifest: DataAppManifest) => boolean;
|
|
10
10
|
/** The filter entries this manifest satisfies (for unmatched-ref reporting). */
|
|
11
11
|
export declare const matchedUploadRefs: (filter: Set<string>, manifest: DataAppManifest) => string[];
|
|
12
|
+
/**
|
|
13
|
+
* Resolves a --app-space slug ref against the target project's spaces.
|
|
14
|
+
* UUID refs skip this (no listing needed); slug misses and ambiguity fail
|
|
15
|
+
* loudly — a space choice is explicit, so never guess.
|
|
16
|
+
*/
|
|
17
|
+
export declare const resolveAppSpaceUuid: (ref: string, spaces: {
|
|
18
|
+
uuid: string;
|
|
19
|
+
slug: string;
|
|
20
|
+
}[]) => string;
|
|
21
|
+
/**
|
|
22
|
+
* Slug-identity bundles carry no uuid, so a uuid/URL upload ref can't match
|
|
23
|
+
* a local folder directly. Translate refs the target project's app listing
|
|
24
|
+
* knows into their slugs; unknown refs keep their original form (and fall
|
|
25
|
+
* through to the unmatched warning).
|
|
26
|
+
*/
|
|
27
|
+
export declare const resolveUploadFilterUuids: (filter: Set<string>, listedApps: {
|
|
28
|
+
appUuid: string;
|
|
29
|
+
slug?: string;
|
|
30
|
+
}[]) => Set<string>;
|
|
12
31
|
/**
|
|
13
32
|
* Warning for --apps references that matched no local app folder. Uuid-shaped
|
|
14
33
|
* refs (including refs parsed out of app URLs) get the slug-identity
|
|
@@ -83,25 +102,6 @@ export declare const preSlugUploadHint: (args: {
|
|
|
83
102
|
folder: string;
|
|
84
103
|
slug: string | undefined;
|
|
85
104
|
}) => string;
|
|
86
|
-
export type AppPresence = {
|
|
87
|
-
kind: 'known';
|
|
88
|
-
slugs: Set<string>;
|
|
89
|
-
} | {
|
|
90
|
-
kind: 'unknown';
|
|
91
|
-
targetProjectUuid: string;
|
|
92
|
-
};
|
|
93
|
-
/**
|
|
94
|
-
* Auto-pushed apps normally upload only when the folder changed, because every
|
|
95
|
-
* upload triggers a sandbox rebuild. The exception is an app the target project
|
|
96
|
-
* does not have yet — without it a dashboard moved to a new project or instance
|
|
97
|
-
* lands with its tile skipped.
|
|
98
|
-
*/
|
|
99
|
-
export declare const shouldAutoPushApp: (args: {
|
|
100
|
-
manifest: Pick<DataAppManifest, 'slug' | 'projectUuid'>;
|
|
101
|
-
presence: AppPresence;
|
|
102
|
-
folderChanged: boolean;
|
|
103
|
-
force: boolean;
|
|
104
|
-
}) => boolean;
|
|
105
105
|
export type AppDownloadFailure = {
|
|
106
106
|
appRef: string;
|
|
107
107
|
message: string;
|
|
@@ -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,0BAA0B,cACxB,MAAM,EAAE,KACpB,MAAM,GAAG,IAMX,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,WAAY,MAAM,KAAG,MAC6K,CAAC;AAEjO;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,aACf,MAAM,GAAG,SAAS,eACf,OAAO,KACrB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;CAejD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kCAAkC,QAAS,OAAO,KAAG,OACP,CAAC;AAE5D,MAAM,MAAM,qBAAqB,GAC3B;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAEnD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,YAAa;IAC1C,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;CACzB,KAAG,qBASH,CAAC;AAEF,eAAO,MAAM,aAAa,gBACT,MAAM,EAAE,SACd,MAAM,KACd;IAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAG7C,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,qBAAqB,SAAU;IACxC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B,WAAW,EAAE,OAAO,CAAC;IACrB,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC/B,KAAG,MAAM,EAOT,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,0BAA0B,WAC3B,MAAM,QACR,mBAAmB,KAC1B,mBASF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,SAAU;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B,KAAG,MAKqD,CAAC;AAE1D,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"appsDownload.d.ts","sourceRoot":"","sources":["../../../src/handlers/apps/appsDownload.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.downloadAppsToDir = exports.appsDownloadSummary = exports.shouldWarnAllSkipped = exports.computeUpsertedTotal = exports.classifyAppDownloadError = exports.
|
|
3
|
+
exports.downloadAppsToDir = exports.appsDownloadSummary = exports.shouldWarnAllSkipped = exports.computeUpsertedTotal = exports.classifyAppDownloadError = exports.preSlugUploadHint = exports.ensureDownloadedAppContext = exports.computeLinkedAppSlugs = exports.capListedApps = exports.selectAppsToDownload = exports.shouldFallBackToSpaceScopedListing = exports.resolveAppsLimit = exports.preSlugServerHint = exports.unmatchedUploadRefsWarning = exports.resolveUploadFilterUuids = exports.resolveAppSpaceUuid = exports.matchedUploadRefs = exports.uploadFilterMatches = exports.getDataAppUploadFilter = exports.getDataAppReference = exports.DEFAULT_APPS_LIMIT = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const common_1 = require("@lightdash/common");
|
|
6
6
|
const path = tslib_1.__importStar(require("path"));
|
|
@@ -40,6 +40,34 @@ exports.uploadFilterMatches = uploadFilterMatches;
|
|
|
40
40
|
/** The filter entries this manifest satisfies (for unmatched-ref reporting). */
|
|
41
41
|
const matchedUploadRefs = (filter, manifest) => [manifest.appUuid, manifest.slug].filter((ref) => ref !== undefined && filter.has(ref));
|
|
42
42
|
exports.matchedUploadRefs = matchedUploadRefs;
|
|
43
|
+
/**
|
|
44
|
+
* Resolves a --app-space slug ref against the target project's spaces.
|
|
45
|
+
* UUID refs skip this (no listing needed); slug misses and ambiguity fail
|
|
46
|
+
* loudly — a space choice is explicit, so never guess.
|
|
47
|
+
*/
|
|
48
|
+
const resolveAppSpaceUuid = (ref, spaces) => {
|
|
49
|
+
const matches = spaces.filter((space) => space.slug === ref);
|
|
50
|
+
if (matches.length === 1)
|
|
51
|
+
return matches[0].uuid;
|
|
52
|
+
if (matches.length === 0) {
|
|
53
|
+
throw new common_1.ParameterError(`--app-space: no space with slug "${ref}" in the target project. Create it first or pass the space UUID.`);
|
|
54
|
+
}
|
|
55
|
+
throw new common_1.ParameterError(`--app-space: multiple spaces match slug "${ref}" — pass the space UUID instead.`);
|
|
56
|
+
};
|
|
57
|
+
exports.resolveAppSpaceUuid = resolveAppSpaceUuid;
|
|
58
|
+
/**
|
|
59
|
+
* Slug-identity bundles carry no uuid, so a uuid/URL upload ref can't match
|
|
60
|
+
* a local folder directly. Translate refs the target project's app listing
|
|
61
|
+
* knows into their slugs; unknown refs keep their original form (and fall
|
|
62
|
+
* through to the unmatched warning).
|
|
63
|
+
*/
|
|
64
|
+
const resolveUploadFilterUuids = (filter, listedApps) => {
|
|
65
|
+
const slugByUuid = new Map(listedApps
|
|
66
|
+
.filter((app) => app.slug !== undefined)
|
|
67
|
+
.map((app) => [app.appUuid, app.slug]));
|
|
68
|
+
return new Set([...filter].map((ref) => (0, uuid_1.validate)(ref) ? (slugByUuid.get(ref) ?? ref) : ref));
|
|
69
|
+
};
|
|
70
|
+
exports.resolveUploadFilterUuids = resolveUploadFilterUuids;
|
|
43
71
|
/**
|
|
44
72
|
* Warning for --apps references that matched no local app folder. Uuid-shaped
|
|
45
73
|
* refs (including refs parsed out of app URLs) get the slug-identity
|
|
@@ -140,23 +168,6 @@ const preSlugUploadHint = (args) => `${args.folder}/lightdash-app.yml predates s
|
|
|
140
168
|
? ` (or add \`slug: ${args.slug}\` to lightdash-app.yml)`
|
|
141
169
|
: ''}. Uploads keep working via uuid matching meanwhile.`;
|
|
142
170
|
exports.preSlugUploadHint = preSlugUploadHint;
|
|
143
|
-
/**
|
|
144
|
-
* Auto-pushed apps normally upload only when the folder changed, because every
|
|
145
|
-
* upload triggers a sandbox rebuild. The exception is an app the target project
|
|
146
|
-
* does not have yet — without it a dashboard moved to a new project or instance
|
|
147
|
-
* lands with its tile skipped.
|
|
148
|
-
*/
|
|
149
|
-
const shouldAutoPushApp = (args) => {
|
|
150
|
-
if (args.force || args.folderChanged)
|
|
151
|
-
return true;
|
|
152
|
-
if (args.manifest.slug === undefined)
|
|
153
|
-
return true;
|
|
154
|
-
if (args.presence.kind === 'known') {
|
|
155
|
-
return !args.presence.slugs.has(args.manifest.slug);
|
|
156
|
-
}
|
|
157
|
-
return args.manifest.projectUuid !== args.presence.targetProjectUuid;
|
|
158
|
-
};
|
|
159
|
-
exports.shouldAutoPushApp = shouldAutoPushApp;
|
|
160
171
|
/**
|
|
161
172
|
* A 404 saying the app has no ready version means it exists but never
|
|
162
173
|
* finished a successful build — nothing to download, so it's a skip, not a
|
|
@@ -550,84 +550,39 @@ describe('downloadAppsToDir', () => {
|
|
|
550
550
|
expect(outcome.failures).toEqual([]);
|
|
551
551
|
});
|
|
552
552
|
});
|
|
553
|
-
describe('
|
|
554
|
-
const
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
});
|
|
562
|
-
it('pushes when the target project does not have the app', () => {
|
|
563
|
-
expect((0, appsDownload_1.shouldAutoPushApp)({
|
|
564
|
-
manifest,
|
|
565
|
-
presence: known(),
|
|
566
|
-
folderChanged: false,
|
|
567
|
-
force: false,
|
|
568
|
-
})).toBe(true);
|
|
569
|
-
});
|
|
570
|
-
it('pushes when the app exists and the folder changed', () => {
|
|
571
|
-
expect((0, appsDownload_1.shouldAutoPushApp)({
|
|
572
|
-
manifest,
|
|
573
|
-
presence: known('revenue-explorer'),
|
|
574
|
-
folderChanged: true,
|
|
575
|
-
force: false,
|
|
576
|
-
})).toBe(true);
|
|
577
|
-
});
|
|
578
|
-
it('skips when the app exists and nothing changed', () => {
|
|
579
|
-
expect((0, appsDownload_1.shouldAutoPushApp)({
|
|
580
|
-
manifest,
|
|
581
|
-
presence: known('revenue-explorer'),
|
|
582
|
-
folderChanged: false,
|
|
583
|
-
force: false,
|
|
584
|
-
})).toBe(false);
|
|
553
|
+
describe('resolveUploadFilterUuids', () => {
|
|
554
|
+
const appUuid = 'd3afc44c-6f0f-4d9f-a267-fb739efa31dd';
|
|
555
|
+
const otherUuid = 'a1b2c3d4-0000-4000-8000-000000000000';
|
|
556
|
+
it('translates uuid refs the listing knows into slugs', () => {
|
|
557
|
+
const resolved = (0, appsDownload_1.resolveUploadFilterUuids)(new Set([appUuid]), [
|
|
558
|
+
{ appUuid, slug: 'my-app' },
|
|
559
|
+
]);
|
|
560
|
+
expect(resolved).toEqual(new Set(['my-app']));
|
|
585
561
|
});
|
|
586
|
-
it('
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
presence: known('revenue-explorer'),
|
|
590
|
-
folderChanged: false,
|
|
591
|
-
force: true,
|
|
592
|
-
})).toBe(true);
|
|
593
|
-
});
|
|
594
|
-
it('falls back to the project comparison when presence is unknown', () => {
|
|
595
|
-
expect((0, appsDownload_1.shouldAutoPushApp)({
|
|
596
|
-
manifest,
|
|
597
|
-
presence: {
|
|
598
|
-
kind: 'unknown',
|
|
599
|
-
targetProjectUuid: 'other-project',
|
|
600
|
-
},
|
|
601
|
-
folderChanged: false,
|
|
602
|
-
force: false,
|
|
603
|
-
})).toBe(true);
|
|
604
|
-
expect((0, appsDownload_1.shouldAutoPushApp)({
|
|
605
|
-
manifest,
|
|
606
|
-
presence: {
|
|
607
|
-
kind: 'unknown',
|
|
608
|
-
targetProjectUuid: 'source-project',
|
|
609
|
-
},
|
|
610
|
-
folderChanged: false,
|
|
611
|
-
force: false,
|
|
612
|
-
})).toBe(false);
|
|
562
|
+
it('keeps slug refs and unknown uuids untouched', () => {
|
|
563
|
+
const resolved = (0, appsDownload_1.resolveUploadFilterUuids)(new Set(['my-app', otherUuid]), [{ appUuid, slug: 'my-app' }]);
|
|
564
|
+
expect(resolved).toEqual(new Set(['my-app', otherUuid]));
|
|
613
565
|
});
|
|
614
|
-
it('
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
566
|
+
it('leaves uuid refs alone when the listing has no slugs (pre-slug server)', () => {
|
|
567
|
+
const resolved = (0, appsDownload_1.resolveUploadFilterUuids)(new Set([appUuid]), [
|
|
568
|
+
{ appUuid },
|
|
569
|
+
]);
|
|
570
|
+
expect(resolved).toEqual(new Set([appUuid]));
|
|
571
|
+
});
|
|
572
|
+
});
|
|
573
|
+
describe('resolveAppSpaceUuid', () => {
|
|
574
|
+
const spaces = [
|
|
575
|
+
{ uuid: 'space-1', slug: 'marketing' },
|
|
576
|
+
{ uuid: 'space-2', slug: 'finance' },
|
|
577
|
+
{ uuid: 'space-3', slug: 'finance' },
|
|
578
|
+
];
|
|
579
|
+
it('resolves a unique slug to its uuid', () => {
|
|
580
|
+
expect((0, appsDownload_1.resolveAppSpaceUuid)('marketing', spaces)).toBe('space-1');
|
|
581
|
+
});
|
|
582
|
+
it('fails loudly when no space matches the slug', () => {
|
|
583
|
+
expect(() => (0, appsDownload_1.resolveAppSpaceUuid)('missing', spaces)).toThrow(/no space with slug "missing"/);
|
|
584
|
+
});
|
|
585
|
+
it('fails loudly when the slug is ambiguous', () => {
|
|
586
|
+
expect(() => (0, appsDownload_1.resolveAppSpaceUuid)('finance', spaces)).toThrow(/multiple spaces match/);
|
|
632
587
|
});
|
|
633
588
|
});
|
|
@@ -21,6 +21,7 @@ export declare const assertScaffoldingSupportsPreviewProxy: (appDir: string) =>
|
|
|
21
21
|
export declare const resolvePreviewTarget: (args: {
|
|
22
22
|
pathArg?: string;
|
|
23
23
|
projectFlag?: string;
|
|
24
|
+
currentProjectUuid?: string;
|
|
24
25
|
cwd: string;
|
|
25
26
|
}) => Promise<{
|
|
26
27
|
appDir: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../../src/handlers/apps/preview.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../../src/handlers/apps/preview.ts"],"names":[],"mappings":"AAcA;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB,SAAU;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACjC,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CA2CxB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qCAAqC,WACtC,MAAM,KACf,OAAO,CAAC,IAAI,CAWd,CAAC;AAEF,eAAO,MAAM,oBAAoB,SAAgB;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC;CACf,KAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CA2BlD,CAAC;AAQF,eAAO,MAAM,wBAAwB,WACzB,MAAM,KACf,OAAO,CAAC,IAAI,CAMd,CAAC;AAyBF;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,SAAgB;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,OAAO,CAAC;CACtB,KAAG,OAAO,CAAC,IAAI,CAuEf,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,SAAU;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACrB,KAAG,MACgT,CAAC;AAErT,eAAO,MAAM,uBAAuB,SAAgB;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B,KAAG,OAAO,CAAC,OAAO,CAmBlB,CAAC;AAKF,eAAO,MAAM,6BAA6B,WAC9B,MAAM,KACf,OAAO,CAAC,OAAO,CAmBjB,CAAC;AAkBF,KAAK,kBAAkB,GAAG;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,kBAAkB,QACtB,MAAM,GAAG,SAAS,KACxB,MAAM,GAAG,SASX,CAAC;AAEF,eAAO,MAAM,kBAAkB,YAClB,MAAM,GAAG,SAAS,WAClB,kBAAkB,KAC5B,OAAO,CAAC,IAAI,CAkId,CAAC"}
|
|
@@ -85,9 +85,8 @@ const resolvePreviewTarget = async (args) => {
|
|
|
85
85
|
const appDir = args.pathArg
|
|
86
86
|
? path.resolve(args.cwd, args.pathArg)
|
|
87
87
|
: args.cwd;
|
|
88
|
-
let manifest;
|
|
89
88
|
try {
|
|
90
|
-
|
|
89
|
+
await (0, appCodeFiles_1.readManifestFromDir)(appDir);
|
|
91
90
|
}
|
|
92
91
|
catch (err) {
|
|
93
92
|
if (err.code === 'ENOENT') {
|
|
@@ -95,9 +94,13 @@ const resolvePreviewTarget = async (args) => {
|
|
|
95
94
|
}
|
|
96
95
|
throw err;
|
|
97
96
|
}
|
|
97
|
+
const projectUuid = args.projectFlag ?? args.currentProjectUuid;
|
|
98
|
+
if (projectUuid === undefined) {
|
|
99
|
+
throw new Error(`No project selected. Pass '--project <uuid>' or run 'lightdash config set-project' first.`);
|
|
100
|
+
}
|
|
98
101
|
return {
|
|
99
102
|
appDir,
|
|
100
|
-
projectUuid
|
|
103
|
+
projectUuid,
|
|
101
104
|
};
|
|
102
105
|
};
|
|
103
106
|
exports.resolvePreviewTarget = resolvePreviewTarget;
|
|
@@ -291,6 +294,7 @@ const appsPreviewHandler = async (pathArg, options) => {
|
|
|
291
294
|
const target = await (0, exports.resolvePreviewTarget)({
|
|
292
295
|
pathArg,
|
|
293
296
|
projectFlag: options.project,
|
|
297
|
+
currentProjectUuid: config.context?.project,
|
|
294
298
|
cwd: process.cwd(),
|
|
295
299
|
});
|
|
296
300
|
await (0, exports.ensureNodeModules)({
|
|
@@ -88,25 +88,34 @@ describe('assertScaffoldingSupportsPreviewProxy', () => {
|
|
|
88
88
|
});
|
|
89
89
|
});
|
|
90
90
|
describe('resolvePreviewTarget', () => {
|
|
91
|
-
it('defaults appDir to cwd and project to the
|
|
91
|
+
it('defaults appDir to cwd and project to the current CLI project', async () => {
|
|
92
92
|
const dir = await fs_1.promises.mkdtemp(path.join(os.tmpdir(), 'ld-prev-'));
|
|
93
93
|
await (0, appCodeFiles_1.writeBundleToDir)(dir, previewBundle);
|
|
94
|
-
const target = await (0, preview_1.resolvePreviewTarget)({
|
|
94
|
+
const target = await (0, preview_1.resolvePreviewTarget)({
|
|
95
|
+
cwd: dir,
|
|
96
|
+
currentProjectUuid: 'current-proj',
|
|
97
|
+
});
|
|
95
98
|
expect(target.appDir).toBe(dir);
|
|
96
|
-
expect(target.projectUuid).toBe('proj
|
|
99
|
+
expect(target.projectUuid).toBe('current-proj');
|
|
97
100
|
});
|
|
98
|
-
it('resolves a relative path arg
|
|
101
|
+
it('resolves a relative path arg and prefers --project over the current project', async () => {
|
|
99
102
|
const parent = await fs_1.promises.mkdtemp(path.join(os.tmpdir(), 'ld-prev-'));
|
|
100
103
|
const appDir = path.join(parent, 'apps', 'my-app');
|
|
101
104
|
await (0, appCodeFiles_1.writeBundleToDir)(appDir, previewBundle);
|
|
102
105
|
const target = await (0, preview_1.resolvePreviewTarget)({
|
|
103
106
|
pathArg: 'apps/my-app',
|
|
104
107
|
projectFlag: 'other-proj',
|
|
108
|
+
currentProjectUuid: 'current-proj',
|
|
105
109
|
cwd: parent,
|
|
106
110
|
});
|
|
107
111
|
expect(target.appDir).toBe(appDir);
|
|
108
112
|
expect(target.projectUuid).toBe('other-proj');
|
|
109
113
|
});
|
|
114
|
+
it('requires --project when the CLI has no current project', async () => {
|
|
115
|
+
const dir = await fs_1.promises.mkdtemp(path.join(os.tmpdir(), 'ld-prev-'));
|
|
116
|
+
await (0, appCodeFiles_1.writeBundleToDir)(dir, previewBundle);
|
|
117
|
+
await expect((0, preview_1.resolvePreviewTarget)({ cwd: dir })).rejects.toThrow(/Pass '--project <uuid>'/);
|
|
118
|
+
});
|
|
110
119
|
it('errors clearly when the folder has no manifest', async () => {
|
|
111
120
|
const dir = await fs_1.promises.mkdtemp(path.join(os.tmpdir(), 'ld-prev-'));
|
|
112
121
|
await expect((0, preview_1.resolvePreviewTarget)({ cwd: dir })).rejects.toThrow(/No lightdash-app\.yml found in/);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/handlers/download.ts"],"names":[],"mappings":"AAEA,OAAO,EACH,WAAW,
|
|
1
|
+
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../../src/handlers/download.ts"],"names":[],"mappings":"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"}
|