@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.
- package/dist/.tsbuildinfo +1 -1
- package/dist/handlers/compile.d.ts +5 -0
- package/dist/handlers/compile.d.ts.map +1 -1
- package/dist/handlers/compile.js +10 -3
- package/dist/handlers/compileProject.test.d.ts +2 -0
- package/dist/handlers/compileProject.test.d.ts.map +1 -0
- package/dist/handlers/compileProject.test.js +179 -0
- package/dist/handlers/compileWarehouseColumnValidation.test.js +2 -1
- package/dist/handlers/deploy.d.ts +1 -0
- package/dist/handlers/deploy.d.ts.map +1 -1
- package/dist/handlers/deploy.js +8 -3
- package/dist/handlers/deploy.test.d.ts +2 -0
- package/dist/handlers/deploy.test.d.ts.map +1 -0
- package/dist/handlers/deploy.test.js +121 -0
- package/dist/handlers/preview.d.ts.map +1 -1
- package/dist/handlers/preview.js +9 -4
- package/package.json +3 -3
|
@@ -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,
|
|
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"}
|
package/dist/handlers/compile.js
CHANGED
|
@@ -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
|
|
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 @@
|
|
|
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 ===
|
|
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;
|
|
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"}
|
package/dist/handlers/deploy.js
CHANGED
|
@@ -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.
|
|
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, {
|
|
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 @@
|
|
|
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,
|
|
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"}
|
package/dist/handlers/preview.js
CHANGED
|
@@ -216,10 +216,11 @@ const previewHandler = async (originalOptions) => {
|
|
|
216
216
|
},
|
|
217
217
|
});
|
|
218
218
|
try {
|
|
219
|
-
const explores = await (0, compile_1.
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
49
|
-
"@lightdash/warehouses": "1.162.
|
|
48
|
+
"@lightdash/common": "1.162.2",
|
|
49
|
+
"@lightdash/warehouses": "1.162.2"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"@types/inquirer": "8.2.4",
|