@lightdash/cli 0.3465.1 → 0.3466.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.
@@ -1,5 +1,6 @@
1
1
  import { type DataAppCodeDownload } from '@lightdash/common';
2
2
  export declare const DEFAULT_APPS_LIMIT = 50;
3
+ export declare const getDataAppUuidFromReference: (reference: string) => string;
3
4
  /**
4
5
  * Resolves the --apps-limit flag. Commander passes the raw string (or
5
6
  * undefined when the flag was not given, so an explicit flag is
@@ -1 +1 @@
1
- {"version":3,"file":"appsDownload.d.ts","sourceRoot":"","sources":["../../../src/handlers/apps/appsDownload.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,KAAK,mBAAmB,EAC3B,MAAM,mBAAmB,CAAC;AAE3B,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GACzB,UAAU,MAAM,GAAG,SAAS,EAC5B,aAAa,OAAO,KACrB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;CAejD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kCAAkC,GAAI,KAAK,OAAO,KAAG,OACP,CAAC;AAE5D,MAAM,MAAM,qBAAqB,GAC3B;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,aAAa,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAEpD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAAI,SAAS;IAC1C,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;CACzB,KAAG,qBASH,CAAC;AAEF,eAAO,MAAM,aAAa,GACtB,aAAa,MAAM,EAAE,EACrB,OAAO,MAAM,KACd;IAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAG7C,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,0BAA0B,GACnC,SAAS,MAAM,EACf,MAAM,mBAAmB,KAC1B,mBAOF,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtE,MAAM,MAAM,uBAAuB,GAC7B;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC1B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,GACjC,KAAK,OAAO,KACb,uBAoBF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAAI,MAAM;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACvB,KAAG,MAC0O,CAAC;AAE/O;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAAI,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAG,MAGpB,CAAC;AAEpD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAC7B,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAChC,OAKF,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,GAC1B,qBAAqB,MAAM,EAC3B,mBAAmB,MAAM,EACzB,WAAW,OAAO,KACnB,SAAS,GAAG,oBAKd,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC5B,cAAc,MAAM,EACpB,OAAO,MAAM,EACb,UAAU,kBAAkB,EAAE,EAC9B,SAAS,MAAM,EACf,sBAAsB,MAAM,KAC7B;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAA;CAiBxD,CAAC"}
1
+ {"version":3,"file":"appsDownload.d.ts","sourceRoot":"","sources":["../../../src/handlers/apps/appsDownload.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,KAAK,mBAAmB,EAC3B,MAAM,mBAAmB,CAAC;AAG3B,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC,eAAO,MAAM,2BAA2B,GAAI,WAAW,MAAM,KAAG,MAoB/D,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,GACzB,UAAU,MAAM,GAAG,SAAS,EAC5B,aAAa,OAAO,KACrB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;CAejD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,kCAAkC,GAAI,KAAK,OAAO,KAAG,OACP,CAAC;AAE5D,MAAM,MAAM,qBAAqB,GAC3B;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,aAAa,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAEpD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAAI,SAAS;IAC1C,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;CACzB,KAAG,qBASH,CAAC;AAEF,eAAO,MAAM,aAAa,GACtB,aAAa,MAAM,EAAE,EACrB,OAAO,MAAM,KACd;IAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAG7C,CAAC;AAEH;;GAEG;AACH,eAAO,MAAM,0BAA0B,GACnC,SAAS,MAAM,EACf,MAAM,mBAAmB,KAC1B,mBAOF,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtE,MAAM,MAAM,uBAAuB,GAC7B;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,GAC1B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAExC;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,GACjC,KAAK,OAAO,KACb,uBAoBF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAAI,MAAM;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACvB,KAAG,MAC0O,CAAC;AAE/O;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAAI,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAG,MAGpB,CAAC;AAEpD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAC7B,SAAS,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAChC,OAKF,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,GAC1B,qBAAqB,MAAM,EAC3B,mBAAmB,MAAM,EACzB,WAAW,OAAO,KACnB,SAAS,GAAG,oBAKd,CAAC;AAEF,eAAO,MAAM,mBAAmB,GAC5B,cAAc,MAAM,EACpB,OAAO,MAAM,EACb,UAAU,kBAAkB,EAAE,EAC9B,SAAS,MAAM,EACf,sBAAsB,MAAM,KAC7B;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAA;CAiBxD,CAAC"}
@@ -1,8 +1,26 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.appsDownloadSummary = exports.classifyAppUpload = exports.shouldWarnAllSkipped = exports.computeUpsertedTotal = exports.manifestRetargetHint = exports.classifyAppDownloadError = exports.ensureDownloadedAppContext = exports.capListedApps = exports.selectAppsToDownload = exports.shouldFallBackToSpaceScopedListing = exports.resolveAppsLimit = exports.DEFAULT_APPS_LIMIT = void 0;
3
+ exports.appsDownloadSummary = exports.classifyAppUpload = exports.shouldWarnAllSkipped = exports.computeUpsertedTotal = exports.manifestRetargetHint = exports.classifyAppDownloadError = exports.ensureDownloadedAppContext = exports.capListedApps = exports.selectAppsToDownload = exports.shouldFallBackToSpaceScopedListing = exports.resolveAppsLimit = exports.getDataAppUuidFromReference = exports.DEFAULT_APPS_LIMIT = void 0;
4
4
  const common_1 = require("@lightdash/common");
5
+ const uuid_1 = require("uuid");
5
6
  exports.DEFAULT_APPS_LIMIT = 50;
7
+ const getDataAppUuidFromReference = (reference) => {
8
+ let url;
9
+ try {
10
+ url = new URL(reference);
11
+ }
12
+ catch {
13
+ return reference;
14
+ }
15
+ if (url.protocol !== 'http:' && url.protocol !== 'https:') {
16
+ return reference;
17
+ }
18
+ const pathSegments = url.pathname.split('/').filter(Boolean);
19
+ const appSegmentIndex = pathSegments.findIndex((segment, index) => (segment === 'apps' || segment === 'app') &&
20
+ (0, uuid_1.validate)(pathSegments[index + 1]));
21
+ return appSegmentIndex >= 0 ? pathSegments[appSegmentIndex + 1] : reference;
22
+ };
23
+ exports.getDataAppUuidFromReference = getDataAppUuidFromReference;
6
24
  /**
7
25
  * Resolves the --apps-limit flag. Commander passes the raw string (or
8
26
  * undefined when the flag was not given, so an explicit flag is
@@ -38,7 +56,7 @@ exports.shouldFallBackToSpaceScopedListing = shouldFallBackToSpaceScopedListing;
38
56
  * the space-scoped content API on servers that predate it.
39
57
  */
40
58
  const selectAppsToDownload = (request) => {
41
- const explicitUuids = request.apps ?? [];
59
+ const explicitUuids = (request.apps ?? []).map(exports.getDataAppUuidFromReference);
42
60
  if (request.includeApps) {
43
61
  return { mode: 'list-all', extraAppUuids: explicitUuids };
44
62
  }
@@ -2,6 +2,29 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const common_1 = require("@lightdash/common");
4
4
  const appsDownload_1 = require("./appsDownload");
5
+ describe('getDataAppUuidFromReference', () => {
6
+ const appUuid = 'd3afc44c-6f0f-4d9f-a267-fb739efa31dd';
7
+ const projectUuid = 'd4c8dfd2-98c0-4eb2-8395-d924aee62611';
8
+ it('keeps a bare app UUID unchanged', () => {
9
+ expect((0, appsDownload_1.getDataAppUuidFromReference)(appUuid)).toBe(appUuid);
10
+ });
11
+ it.each([
12
+ `https://app.lightdash.cloud/projects/${projectUuid}/apps/${appUuid}`,
13
+ `https://app.lightdash.cloud/projects/${projectUuid}/apps/${appUuid}/view`,
14
+ `https://app.lightdash.cloud/projects/${projectUuid}/apps/${appUuid}/versions/2/view?state=filters#preview`,
15
+ `https://app.lightdash.cloud/embed/${projectUuid}/app/${appUuid}`,
16
+ ])('extracts the app UUID from %s', (url) => {
17
+ expect((0, appsDownload_1.getDataAppUuidFromReference)(url)).toBe(appUuid);
18
+ });
19
+ it.each([
20
+ 'my-app',
21
+ `https://app.lightdash.cloud/${appUuid}`,
22
+ `https://app.lightdash.cloud/projects/${projectUuid}/apps/generate`,
23
+ `ftp://app.lightdash.cloud/projects/${projectUuid}/apps/${appUuid}`,
24
+ ])('leaves unsupported references unchanged: %s', (reference) => {
25
+ expect((0, appsDownload_1.getDataAppUuidFromReference)(reference)).toBe(reference);
26
+ });
27
+ });
5
28
  const makeDownload = () => ({
6
29
  manifest: {
7
30
  codeVersion: 1,
@@ -43,6 +66,16 @@ describe('selectAppsToDownload', () => {
43
66
  it('combines --include-apps with explicitly passed uuids', () => {
44
67
  expect((0, appsDownload_1.selectAppsToDownload)({ apps: ['uuid-a'], includeApps: true })).toEqual({ mode: 'list-all', extraAppUuids: ['uuid-a'] });
45
68
  });
69
+ it('normalizes explicit app URLs without listing apps', () => {
70
+ expect((0, appsDownload_1.selectAppsToDownload)({
71
+ apps: [
72
+ 'https://app.lightdash.cloud/projects/project-uuid/apps/d3afc44c-6f0f-4d9f-a267-fb739efa31dd/view',
73
+ ],
74
+ })).toEqual({
75
+ mode: 'explicit',
76
+ appUuids: ['d3afc44c-6f0f-4d9f-a267-fb739efa31dd'],
77
+ });
78
+ });
46
79
  it('skips apps when neither flag is passed', () => {
47
80
  expect((0, appsDownload_1.selectAppsToDownload)({})).toEqual({ mode: 'none' });
48
81
  expect((0, appsDownload_1.selectAppsToDownload)({ apps: [] })).toEqual({ mode: 'none' });
@@ -712,7 +712,7 @@ const downloadHandler = async (options) => {
712
712
  includeApps,
713
713
  });
714
714
  if (appsOnlySelection.mode === 'none') {
715
- throw new common_1.ParameterError('Nothing to download: --apps-only requires --apps <appUuids...>, --include-apps, or --include-all.');
715
+ throw new common_1.ParameterError('Nothing to download: --apps-only requires --apps <appReferences...>, --include-apps, or --include-all.');
716
716
  }
717
717
  options.skipCharts = true;
718
718
  options.skipDashboards = true;
package/dist/index.js CHANGED
@@ -365,10 +365,10 @@ const downloadCommand = commander_1.program
365
365
  .option('--include-scheduled-deliveries', 'include all scheduled deliveries in the download', false)
366
366
  .option('--include-all', 'include all optional content in the download', false)
367
367
  .option('--strip-pivot-series', 'strip per-value pivot series config from chart YAML for portable downloads', false)
368
- .option('--apps <appUuids...>', 'Include specific data apps by UUID (enterprise). Works for apps not added to a space.')
368
+ .option('--apps <appReferences...>', 'Include specific data apps by UUID or URL (enterprise). Works for apps not added to a space.')
369
369
  .option('--include-apps', "Include all of the project's data apps (enterprise), capped at --apps-limit (default: 50)", false)
370
370
  .option('--apps-limit <number>', 'Maximum number of data apps downloaded by --include-apps or --include-all (default: 50)', undefined)
371
- .option('--apps-only', 'Download only data apps (implies --skip-charts --skip-dashboards --skip-spaces). Requires --apps <appUuids...>, --include-apps, or --include-all.', false)
371
+ .option('--apps-only', 'Download only data apps (implies --skip-charts --skip-dashboards --skip-spaces). Requires --apps <appReferences...>, --include-apps, or --include-all.', false)
372
372
  .option('--organization', 'download all organization-scoped resources without selecting a project', false);
373
373
  downloadCommand.action(withOrganizationMode(download_1.downloadHandler));
374
374
  const uploadCommand = commander_1.program
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightdash/cli",
3
- "version": "0.3465.1",
3
+ "version": "0.3466.0",
4
4
  "description": "Lightdash CLI tool",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -41,8 +41,8 @@
41
41
  "unique-names-generator": "4.7.1",
42
42
  "uuid": "11.1.1",
43
43
  "yaml": "2.8.3",
44
- "@lightdash/common": "0.3465.1",
45
- "@lightdash/warehouses": "0.3465.1"
44
+ "@lightdash/common": "0.3466.0",
45
+ "@lightdash/warehouses": "0.3466.0"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@types/inquirer": "8.2.4",