@lightdash/cli 1.162.1 → 1.162.2

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.
@@ -13,8 +13,13 @@ export type CompileHandlerOptions = DbtCompileOptions & {
13
13
  validateWarehouseColumns?: boolean;
14
14
  partialCompilation?: boolean;
15
15
  };
16
+ export type CompileProjectResult = {
17
+ explores: (Explore | ExploreError)[];
18
+ isProjectComplete: boolean;
19
+ };
16
20
  export declare const hasBlockingCompileError: (explore: Explore | ExploreError) => boolean;
17
21
  export declare const stripWarehouseColumnErrors: (explore: Explore | ExploreError) => Explore | ExploreError;
22
+ export declare const compileProject: (options: CompileHandlerOptions) => Promise<CompileProjectResult>;
18
23
  export declare const compile: (options: CompileHandlerOptions) => Promise<(Explore | ExploreError)[]>;
19
24
  export declare const compileHandler: (originalOptions: CompileHandlerOptions) => Promise<void>;
20
25
  //# sourceMappingURL=compile.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/handlers/compile.ts"],"names":[],"mappings":"AAAA,OAAO,EAMH,OAAO,EACP,YAAY,EAgBf,MAAM,mBAAmB,CAAC;AAoB3B,OAAO,EAAE,iBAAiB,EAA8B,MAAM,eAAe,CAAC;AAI9E,MAAM,MAAM,qBAAqB,GAAG,iBAAiB,GAAG;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF,eAAO,MAAM,uBAAuB,YACvB,OAAO,GAAG,YAAY,KAChC,OAIW,CAAC;AAEf,eAAO,MAAM,0BAA0B,YAC1B,OAAO,GAAG,YAAY,KAChC,OAAO,GAAG,YAiBZ,CAAC;AA+NF,eAAO,MAAM,OAAO,YAAmB,qBAAqB,wCAiU3D,CAAC;AAEF,eAAO,MAAM,cAAc,oBACN,qBAAqB,kBAmCzC,CAAC"}
1
+ {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../src/handlers/compile.ts"],"names":[],"mappings":"AAAA,OAAO,EAMH,OAAO,EACP,YAAY,EAgBf,MAAM,mBAAmB,CAAC;AAoB3B,OAAO,EAAE,iBAAiB,EAA8B,MAAM,eAAe,CAAC;AAI9E,MAAM,MAAM,qBAAqB,GAAG,iBAAiB,GAAG;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IAC/B,QAAQ,EAAE,CAAC,OAAO,GAAG,YAAY,CAAC,EAAE,CAAC;IACrC,iBAAiB,EAAE,OAAO,CAAC;CAC9B,CAAC;AAEF,eAAO,MAAM,uBAAuB,YACvB,OAAO,GAAG,YAAY,KAChC,OAIW,CAAC;AAEf,eAAO,MAAM,0BAA0B,YAC1B,OAAO,GAAG,YAAY,KAChC,OAAO,GAAG,YAiBZ,CAAC;AA+NF,eAAO,MAAM,cAAc,YACd,qBAAqB,KAC/B,OAAO,CAAC,oBAAoB,CAsU9B,CAAC;AAEF,eAAO,MAAM,OAAO,YACP,qBAAqB,KAC/B,OAAO,CAAC,CAAC,OAAO,GAAG,YAAY,CAAC,EAAE,CACO,CAAC;AAE7C,eAAO,MAAM,cAAc,oBACN,qBAAqB,kBAmCzC,CAAC"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.compileHandler = exports.compile = exports.stripWarehouseColumnErrors = exports.hasBlockingCompileError = void 0;
3
+ exports.compileHandler = exports.compile = exports.compileProject = exports.stripWarehouseColumnErrors = exports.hasBlockingCompileError = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const common_1 = require("@lightdash/common");
6
6
  const warehouses_1 = require("@lightdash/warehouses");
@@ -167,7 +167,7 @@ async function patchDeferredModels(compiledModels, originallySelectedModelIds, s
167
167
  return compiledModels;
168
168
  }
169
169
  }
170
- const compile = async (options) => {
170
+ const compileProject = async (options) => {
171
171
  const dbtVersionResult = await (0, getDbtVersion_1.tryGetDbtVersion)();
172
172
  const executionId = (0, uuid_1.v4)();
173
173
  const startTime = Date.now();
@@ -191,6 +191,7 @@ const compile = async (options) => {
191
191
  // Try lightdash project compile
192
192
  let explores = null;
193
193
  let dbtMetrics = null;
194
+ let isProjectComplete = true;
194
195
  explores = await getExploresFromLightdashYmlProject({
195
196
  projectDir: absoluteProjectPath,
196
197
  lightdashProjectConfig,
@@ -219,6 +220,10 @@ const compile = async (options) => {
219
220
  });
220
221
  const { compiledModelIds, originallySelectedModelIds } = await (0, compile_1.maybeCompileModelsAndJoins)({ targetDir: context.targetDir }, options);
221
222
  let manifest = await (0, manifest_1.loadManifest)({ targetDir: context.targetDir });
223
+ const projectManifestModels = (0, common_1.getModelsFromManifest)(manifest);
224
+ isProjectComplete =
225
+ (0, common_1.getCompiledModels)(projectManifestModels, compiledModelIds)
226
+ .length === projectManifestModels.length;
222
227
  let effectiveCompiledModelIds = compiledModelIds;
223
228
  if (options.combineManifest) {
224
229
  const externalManifest = await (0, manifest_1.loadCombineManifest)(options.combineManifest);
@@ -376,8 +381,10 @@ const compile = async (options) => {
376
381
  durationMs: Date.now() - startTime,
377
382
  },
378
383
  });
379
- return explores;
384
+ return { explores, isProjectComplete };
380
385
  };
386
+ exports.compileProject = compileProject;
387
+ const compile = async (options) => (await (0, exports.compileProject)(options)).explores;
381
388
  exports.compile = compile;
382
389
  const compileHandler = async (originalOptions) => {
383
390
  const options = { ...originalOptions };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=compileProject.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compileProject.test.d.ts","sourceRoot":"","sources":["../../src/handlers/compileProject.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,179 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const common_1 = require("@lightdash/common");
5
+ const promises_1 = tslib_1.__importDefault(require("fs/promises"));
6
+ const os_1 = tslib_1.__importDefault(require("os"));
7
+ const path_1 = tslib_1.__importDefault(require("path"));
8
+ const context_1 = require("../dbt/context");
9
+ const manifest_1 = require("../dbt/manifest");
10
+ const validation_1 = require("../dbt/validation");
11
+ const loader_1 = require("../lightdash/loader");
12
+ const compile_1 = require("./compile");
13
+ const compile_2 = require("./dbt/compile");
14
+ const getDbtVersion_1 = require("./dbt/getDbtVersion");
15
+ vi.mock('../analytics/analytics');
16
+ vi.mock('../config', () => ({
17
+ getConfig: vi.fn().mockResolvedValue({ user: null, context: null }),
18
+ }));
19
+ vi.mock('../dbt/context');
20
+ vi.mock('../dbt/manifest', async (importOriginal) => ({
21
+ ...(await importOriginal()),
22
+ loadCombineManifest: vi.fn(),
23
+ loadManifest: vi.fn(),
24
+ }));
25
+ vi.mock('../dbt/validation');
26
+ vi.mock('../lightdash/loader');
27
+ vi.mock('./dbt/compile');
28
+ vi.mock('./dbt/getDbtVersion');
29
+ const dbtNode = (uniqueId, resourceType, compiled) => ({
30
+ unique_id: uniqueId,
31
+ name: uniqueId.split('.').at(-1) ?? uniqueId,
32
+ resource_type: resourceType,
33
+ package_name: 'test',
34
+ path: `${uniqueId}.sql`,
35
+ original_file_path: `models/${uniqueId}.sql`,
36
+ alias: uniqueId.split('.').at(-1) ?? uniqueId,
37
+ checksum: { name: 'sha256', checksum: uniqueId },
38
+ tags: [],
39
+ refs: [],
40
+ sources: [],
41
+ depends_on: { macros: [], nodes: [] },
42
+ database: 'db',
43
+ schema: 'public',
44
+ fqn: ['test', uniqueId],
45
+ raw_code: 'SELECT 1',
46
+ columns: {
47
+ id: {
48
+ name: 'id',
49
+ data_type: common_1.DimensionType.NUMBER,
50
+ meta: {},
51
+ },
52
+ },
53
+ meta: {},
54
+ description: '',
55
+ created_at: 0,
56
+ language: 'sql',
57
+ relation_name: `"db"."public"."${uniqueId}"`,
58
+ config: { materialized: 'table' },
59
+ compiled,
60
+ });
61
+ const manifest = (nodes) => ({
62
+ metadata: {
63
+ dbt_schema_version: 'https://schemas.getdbt.com/dbt/manifest/v12.json',
64
+ generated_at: '2026-01-01T00:00:00Z',
65
+ adapter_type: 'postgres',
66
+ },
67
+ nodes,
68
+ sources: {},
69
+ macros: {},
70
+ docs: {},
71
+ exposures: {},
72
+ metrics: {},
73
+ });
74
+ const compileOptions = (projectDir) => ({
75
+ projectDir,
76
+ profilesDir: '',
77
+ target: undefined,
78
+ profile: undefined,
79
+ vars: undefined,
80
+ verbose: false,
81
+ startOfWeek: 0,
82
+ skipWarehouseCatalog: true,
83
+ skipDbtCompile: true,
84
+ useDbtList: false,
85
+ select: undefined,
86
+ models: undefined,
87
+ threads: undefined,
88
+ noVersionCheck: false,
89
+ exclude: undefined,
90
+ selector: undefined,
91
+ state: undefined,
92
+ fullRefresh: false,
93
+ defer: false,
94
+ targetPath: undefined,
95
+ favorState: false,
96
+ combineManifest: undefined,
97
+ warehouseCredentials: false,
98
+ disableTimestampConversion: false,
99
+ });
100
+ describe('compileProject completeness', () => {
101
+ let tempDir;
102
+ beforeEach(async () => {
103
+ vi.clearAllMocks();
104
+ tempDir = await promises_1.default.mkdtemp(path_1.default.join(os_1.default.tmpdir(), 'lightdash-compile-project-test-'));
105
+ await promises_1.default.writeFile(path_1.default.join(tempDir, 'lightdash.config.yml'), 'warehouse:\n type: postgres\n');
106
+ vi.mocked(getDbtVersion_1.tryGetDbtVersion).mockResolvedValue({
107
+ success: true,
108
+ version: {
109
+ verboseVersion: '1.10.19',
110
+ versionOption: common_1.SupportedDbtVersions.V1_10,
111
+ isDbtCloudCLI: false,
112
+ isDbtFusion: false,
113
+ },
114
+ });
115
+ vi.mocked(context_1.getDbtContext).mockResolvedValue({
116
+ projectName: 'test_project',
117
+ profileName: 'test_profile',
118
+ targetDir: path_1.default.join(tempDir, 'target'),
119
+ modelsDir: 'models',
120
+ });
121
+ vi.mocked(loader_1.loadLightdashModels).mockResolvedValue([]);
122
+ vi.mocked(validation_1.validateDbtModel).mockImplementation(async (_adapter, _version, models) => ({
123
+ valid: models,
124
+ invalid: [],
125
+ skipped: [],
126
+ }));
127
+ vi.spyOn(console, 'error').mockImplementation(() => undefined);
128
+ });
129
+ afterEach(async () => {
130
+ vi.restoreAllMocks();
131
+ await promises_1.default.rm(tempDir, { recursive: true, force: true });
132
+ });
133
+ test('reports an unselected model and seed manifest as complete', async () => {
134
+ const projectManifest = manifest({
135
+ 'model.test.orders': dbtNode('model.test.orders', 'model', true),
136
+ 'seed.test.countries': dbtNode('seed.test.countries', 'seed', false),
137
+ });
138
+ vi.mocked(manifest_1.loadManifest).mockResolvedValue(projectManifest);
139
+ vi.mocked(compile_2.maybeCompileModelsAndJoins).mockResolvedValue({
140
+ compiledModelIds: ['model.test.orders'],
141
+ originallySelectedModelIds: undefined,
142
+ });
143
+ const result = await (0, compile_1.compileProject)(compileOptions(tempDir));
144
+ expect(result.isProjectComplete).toBe(true);
145
+ });
146
+ test('reports a selected subset as incomplete', async () => {
147
+ const projectManifest = manifest({
148
+ 'model.test.orders': dbtNode('model.test.orders', 'model', true),
149
+ 'model.test.customers': dbtNode('model.test.customers', 'model', true),
150
+ });
151
+ vi.mocked(manifest_1.loadManifest).mockResolvedValue(projectManifest);
152
+ vi.mocked(compile_2.maybeCompileModelsAndJoins).mockResolvedValue({
153
+ compiledModelIds: ['model.test.orders'],
154
+ originallySelectedModelIds: ['model.test.orders'],
155
+ });
156
+ const result = await (0, compile_1.compileProject)(compileOptions(tempDir));
157
+ expect(result.isProjectComplete).toBe(false);
158
+ });
159
+ test('derives completeness before combining an external manifest', async () => {
160
+ const projectManifest = manifest({
161
+ 'model.test.orders': dbtNode('model.test.orders', 'model', true),
162
+ });
163
+ const externalManifest = manifest({
164
+ 'model.external.compiled': dbtNode('model.external.compiled', 'model', true),
165
+ 'model.external.uncompiled': dbtNode('model.external.uncompiled', 'model', false),
166
+ });
167
+ vi.mocked(manifest_1.loadManifest).mockResolvedValue(projectManifest);
168
+ vi.mocked(manifest_1.loadCombineManifest).mockResolvedValue(externalManifest);
169
+ vi.mocked(compile_2.maybeCompileModelsAndJoins).mockResolvedValue({
170
+ compiledModelIds: ['model.test.orders'],
171
+ originallySelectedModelIds: undefined,
172
+ });
173
+ const result = await (0, compile_1.compileProject)({
174
+ ...compileOptions(tempDir),
175
+ combineManifest: 'external-manifest.json',
176
+ });
177
+ expect(result.isProjectComplete).toBe(true);
178
+ });
179
+ });
@@ -310,7 +310,8 @@ describe('compile warehouse column validation', () => {
310
310
  });
311
311
  const deployRequest = vi
312
312
  .mocked(apiClient_1.lightdashApi)
313
- .mock.calls.find(([request]) => request.url === '/api/v1/projects/projectUuid/explores');
313
+ .mock.calls.find(([request]) => request.url ===
314
+ '/api/v1/projects/projectUuid/explores?complete=false');
314
315
  if (deployRequest === undefined) {
315
316
  throw new Error('Expected explores deploy request');
316
317
  }
@@ -23,6 +23,7 @@ type DeployHandlerOptions = DbtCompileOptions & {
23
23
  };
24
24
  type DeployArgs = DeployHandlerOptions & {
25
25
  projectUuid: string;
26
+ complete?: boolean;
26
27
  };
27
28
  export declare const deploy: (explores: (Explore | ExploreError)[], options: DeployArgs) => Promise<void>;
28
29
  export declare const deployHandler: (originalOptions: DeployHandlerOptions) => Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/handlers/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,OAAO,EACP,YAAY,EASf,MAAM,mBAAmB,CAAC;AA2B3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AASlD,KAAK,oBAAoB,GAAG,iBAAiB,GAAG;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,wBAAwB,EAAE,OAAO,CAAC;IAClC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF,KAAK,UAAU,GAAG,oBAAoB,GAAG;IACrC,WAAW,EAAE,MAAM,CAAC;CACvB,CAAC;AA8QF,eAAO,MAAM,MAAM,aACL,CAAC,OAAO,GAAG,YAAY,CAAC,EAAE,WAC3B,UAAU,KACpB,OAAO,CAAC,IAAI,CA6Id,CAAC;AAiGF,eAAO,MAAM,aAAa,oBAA2B,oBAAoB,kBAmKxE,CAAC"}
1
+ {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/handlers/deploy.ts"],"names":[],"mappings":"AAAA,OAAO,EAIH,OAAO,EACP,YAAY,EASf,MAAM,mBAAmB,CAAC;AA2B3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AASlD,KAAK,oBAAoB,GAAG,iBAAiB,GAAG;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,wBAAwB,EAAE,OAAO,CAAC;IAClC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF,KAAK,UAAU,GAAG,oBAAoB,GAAG;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AA+QF,eAAO,MAAM,MAAM,aACL,CAAC,OAAO,GAAG,YAAY,CAAC,EAAE,WAC3B,UAAU,KACpB,OAAO,CAAC,IAAI,CA6Id,CAAC;AAiGF,eAAO,MAAM,aAAa,oBAA2B,oBAAoB,kBAuKxE,CAAC"}
@@ -147,6 +147,7 @@ const deployBatched = async (explores, options) => {
147
147
  body: JSON.stringify({
148
148
  explores: batch,
149
149
  batchNumber: batchIndex,
150
+ complete: options.complete === true,
150
151
  }),
151
152
  }), batchIndex + 1);
152
153
  globalState_1.default.log(styles.success(` ✓ Batch ${batchIndex + 1} uploaded (${response.exploreCount} explores)`));
@@ -237,7 +238,7 @@ const deploy = async (explores, options) => {
237
238
  try {
238
239
  const deployResponse = await (0, apiClient_1.lightdashApi)({
239
240
  method: 'PUT',
240
- url: `/api/v1/projects/${options.projectUuid}/explores`,
241
+ url: `/api/v1/projects/${options.projectUuid}/explores?complete=${options.complete === true}`,
241
242
  body: deployPayload,
242
243
  });
243
244
  if (deployResponse) {
@@ -440,7 +441,7 @@ const deployHandler = async (originalOptions) => {
440
441
  options.disableTimestampConversion =
441
442
  await (0, timestampConversion_1.getProjectDisableTimestampConversion)(options.disableTimestampConversion, existingProjectSelection.projectUuid);
442
443
  }
443
- const explores = await (0, compile_1.compile)(options);
444
+ const { explores, isProjectComplete } = await (0, compile_1.compileProject)(options);
444
445
  let projectUuid;
445
446
  if (options.create !== undefined) {
446
447
  const project = await createNewProject(executionId, options);
@@ -462,7 +463,11 @@ const deployHandler = async (originalOptions) => {
462
463
  else {
463
464
  throw new common_1.AuthorizationError(`No active Lightdash project. Run 'lightdash login --help'`);
464
465
  }
465
- await (0, exports.deploy)(explores, { ...options, projectUuid });
466
+ await (0, exports.deploy)(explores, {
467
+ ...options,
468
+ projectUuid,
469
+ complete: isProjectComplete,
470
+ });
466
471
  const serverUrl = config.context?.serverUrl?.replace(/\/$/, '');
467
472
  let displayUrl = options.create
468
473
  ? `${serverUrl}/createProject/cli?projectUuid=${projectUuid}`
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=deploy.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy.test.d.ts","sourceRoot":"","sources":["../../src/handlers/deploy.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const common_1 = require("@lightdash/common");
4
+ const analytics_1 = require("../analytics/analytics");
5
+ const lightdash_config_1 = require("../lightdash-config");
6
+ const apiClient_1 = require("./dbt/apiClient");
7
+ const deploy_1 = require("./deploy");
8
+ vi.mock('../analytics/analytics');
9
+ vi.mock('../lightdash-config');
10
+ vi.mock('./dbt/apiClient', async (importOriginal) => ({
11
+ ...(await importOriginal()),
12
+ lightdashApi: vi.fn(),
13
+ }));
14
+ const compiledExplore = {
15
+ name: 'orders',
16
+ label: 'Orders',
17
+ tags: [],
18
+ tables: {},
19
+ baseTable: 'orders',
20
+ joinedTables: [],
21
+ targetDatabase: common_1.SupportedDbtAdapter.POSTGRES,
22
+ };
23
+ const deployOptions = {
24
+ projectDir: '/tmp/project',
25
+ profilesDir: '',
26
+ target: undefined,
27
+ profile: undefined,
28
+ vars: undefined,
29
+ verbose: false,
30
+ ignoreErrors: false,
31
+ validateWarehouseColumns: false,
32
+ projectUuid: 'project-uuid',
33
+ skipWarehouseCatalog: true,
34
+ skipDbtCompile: true,
35
+ useDbtList: false,
36
+ select: undefined,
37
+ models: undefined,
38
+ threads: undefined,
39
+ noVersionCheck: false,
40
+ exclude: undefined,
41
+ selector: undefined,
42
+ state: undefined,
43
+ fullRefresh: false,
44
+ defer: false,
45
+ targetPath: undefined,
46
+ favorState: false,
47
+ combineManifest: undefined,
48
+ };
49
+ describe('deploy completeness transport', () => {
50
+ beforeEach(() => {
51
+ vi.clearAllMocks();
52
+ vi.mocked(lightdash_config_1.readAndLoadLightdashProjectConfig).mockResolvedValue({
53
+ spotlight: { default_visibility: 'show' },
54
+ });
55
+ vi.mocked(analytics_1.LightdashAnalytics.track).mockResolvedValue(undefined);
56
+ });
57
+ it.each([
58
+ { complete: true, expected: 'true' },
59
+ { complete: false, expected: 'false' },
60
+ { complete: undefined, expected: 'false' },
61
+ ])('sends complete=$expected on the default upload', async ({ complete, expected }) => {
62
+ vi.mocked(apiClient_1.lightdashApi).mockImplementation(async ({ url }) => {
63
+ if (url.includes('/explores?')) {
64
+ return {
65
+ exploreCount: 1,
66
+ warnings: {
67
+ warningCount: 0,
68
+ exploresWithWarnings: [],
69
+ },
70
+ };
71
+ }
72
+ return null;
73
+ });
74
+ await (0, deploy_1.deploy)([compiledExplore], {
75
+ ...deployOptions,
76
+ complete,
77
+ });
78
+ expect(apiClient_1.lightdashApi).toHaveBeenCalledWith(expect.objectContaining({
79
+ method: 'PUT',
80
+ url: `/api/v1/projects/project-uuid/explores?complete=${expected}`,
81
+ body: JSON.stringify([compiledExplore]),
82
+ }));
83
+ });
84
+ test('includes the completeness assertion in every batch body', async () => {
85
+ vi.mocked(apiClient_1.lightdashApi).mockImplementation(async ({ url }) => {
86
+ if (url.endsWith('/deploy')) {
87
+ return {
88
+ deploySessionUuid: 'deploy-session-uuid',
89
+ };
90
+ }
91
+ if (url.endsWith('/batch')) {
92
+ return { batchNumber: 0, exploreCount: 1 };
93
+ }
94
+ if (url.endsWith('/finalize')) {
95
+ return {
96
+ exploreCount: 1,
97
+ warnings: {
98
+ warningCount: 0,
99
+ exploresWithWarnings: [],
100
+ },
101
+ status: common_1.DeploySessionStatus.COMPLETED,
102
+ };
103
+ }
104
+ return null;
105
+ });
106
+ await (0, deploy_1.deploy)([compiledExplore], {
107
+ ...deployOptions,
108
+ complete: false,
109
+ useBatchedDeploy: true,
110
+ });
111
+ expect(apiClient_1.lightdashApi).toHaveBeenCalledWith({
112
+ method: 'POST',
113
+ url: '/api/v2/projects/project-uuid/deploy/deploy-session-uuid/batch',
114
+ body: JSON.stringify({
115
+ explores: [compiledExplore],
116
+ batchNumber: 0,
117
+ complete: false,
118
+ }),
119
+ });
120
+ });
121
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../src/handlers/preview.ts"],"names":[],"mappings":"AACA,OAAO,EACH,+BAA+B,EAKlC,MAAM,mBAAmB,CAAC;AAgB3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAOlD,KAAK,qBAAqB,GAAG,iBAAiB,GAAG;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;IACtB,kBAAkB,EAAE,+BAA+B,CAAC;IACpD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,wBAAwB,EAAE,OAAO,CAAC;IAClC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF,KAAK,yBAAyB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CACpB,CAAC;AA2GF,eAAO,MAAM,cAAc,oBACN,qBAAqB,KACvC,OAAO,CAAC,IAAI,CAmSd,CAAC;AAEF,eAAO,MAAM,mBAAmB,oBACX,qBAAqB,KACvC,OAAO,CAAC,IAAI,CA8Kd,CAAC;AAEF,eAAO,MAAM,kBAAkB,YAClB,yBAAyB,KACnC,OAAO,CAAC,IAAI,CA0Cd,CAAC"}
1
+ {"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../src/handlers/preview.ts"],"names":[],"mappings":"AACA,OAAO,EACH,+BAA+B,EAKlC,MAAM,mBAAmB,CAAC;AAgB3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAOlD,KAAK,qBAAqB,GAAG,iBAAiB,GAAG;IAC7C,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,OAAO,CAAC;IACtB,kBAAkB,EAAE,+BAA+B,CAAC;IACpD,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,wBAAwB,EAAE,OAAO,CAAC;IAClC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAChC,CAAC;AAEF,KAAK,yBAAyB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CACpB,CAAC;AA2GF,eAAO,MAAM,cAAc,oBACN,qBAAqB,KACvC,OAAO,CAAC,IAAI,CAsSd,CAAC;AAEF,eAAO,MAAM,mBAAmB,oBACX,qBAAqB,KACvC,OAAO,CAAC,IAAI,CAgLd,CAAC;AAEF,eAAO,MAAM,kBAAkB,YAClB,yBAAyB,KACnC,OAAO,CAAC,IAAI,CA0Cd,CAAC"}
@@ -216,10 +216,11 @@ const previewHandler = async (originalOptions) => {
216
216
  },
217
217
  });
218
218
  try {
219
- const explores = await (0, compile_1.compile)(options);
219
+ const { explores, isProjectComplete } = await (0, compile_1.compileProject)(options);
220
220
  await (0, deploy_1.deploy)(explores, {
221
221
  ...options,
222
222
  projectUuid: project.projectUuid,
223
+ complete: isProjectComplete,
223
224
  });
224
225
  await (0, config_1.setPreviewProject)(project.projectUuid, name);
225
226
  process.on('SIGINT', async () => {
@@ -264,9 +265,11 @@ const previewHandler = async (originalOptions) => {
264
265
  watcher.unwatch(manifestFilePath);
265
266
  // Deploying will change manifest.json too, so we need to stop watching the file until it is deployed
266
267
  if (project) {
267
- await (0, deploy_1.deploy)(await (0, compile_1.compile)(options), {
268
+ const compileResult = await (0, compile_1.compileProject)(options);
269
+ await (0, deploy_1.deploy)(compileResult.explores, {
268
270
  ...options,
269
271
  projectUuid: project.projectUuid,
272
+ complete: compileResult.isProjectComplete,
270
273
  });
271
274
  }
272
275
  console.error(`${styles.success('✔')} Preview updated \n`);
@@ -348,10 +351,11 @@ const startPreviewHandler = async (originalOptions) => {
348
351
  // Update
349
352
  options.disableTimestampConversion =
350
353
  await (0, timestampConversion_1.getProjectDisableTimestampConversion)(options.disableTimestampConversion, previewProject.projectUuid);
351
- const explores = await (0, compile_1.compile)(options);
354
+ const { explores, isProjectComplete } = await (0, compile_1.compileProject)(options);
352
355
  await (0, deploy_1.deploy)(explores, {
353
356
  ...options,
354
357
  projectUuid: previewProject.projectUuid,
358
+ complete: isProjectComplete,
355
359
  });
356
360
  const url = await projectUrl(previewProject);
357
361
  console.error(`Project updated on ${url}`);
@@ -408,10 +412,11 @@ const startPreviewHandler = async (originalOptions) => {
408
412
  (0, timestampConversion_1.getDisableTimestampConversionFromProject)(project.warehouseConnection);
409
413
  globalState_1.default.debug(`> Using disable-timestamp-conversion=${String(options.disableTimestampConversion ?? false)} from preview project settings`);
410
414
  }
411
- const explores = await (0, compile_1.compile)(options);
415
+ const { explores, isProjectComplete } = await (0, compile_1.compileProject)(options);
412
416
  await (0, deploy_1.deploy)(explores, {
413
417
  ...options,
414
418
  projectUuid: project.projectUuid,
419
+ complete: isProjectComplete,
415
420
  });
416
421
  const url = await projectUrl(project);
417
422
  if (!hasContentCopy) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightdash/cli",
3
- "version": "1.162.1",
3
+ "version": "1.162.2",
4
4
  "description": "Lightdash CLI tool",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -45,8 +45,8 @@
45
45
  "unique-names-generator": "4.7.1",
46
46
  "uuid": "11.1.1",
47
47
  "yaml": "2.8.3",
48
- "@lightdash/common": "1.162.1",
49
- "@lightdash/warehouses": "1.162.1"
48
+ "@lightdash/common": "1.162.2",
49
+ "@lightdash/warehouses": "1.162.2"
50
50
  },
51
51
  "devDependencies": {
52
52
  "@types/inquirer": "8.2.4",