@lightdash/cli 2.562.0 → 2.563.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.
Files changed (176) hide show
  1. package/dist/.tsbuildinfo.build +1 -1
  2. package/dist/agentConnectionConnectOption.d.ts +8 -0
  3. package/dist/agentConnectionConnectOption.d.ts.map +1 -0
  4. package/dist/agentConnectionConnectOption.js +39 -0
  5. package/dist/agentConnectionOption.d.ts +3 -0
  6. package/dist/agentConnectionOption.d.ts.map +1 -0
  7. package/dist/agentConnectionOption.js +48 -0
  8. package/dist/agentConnections/agentTokenProvider.d.ts +13 -0
  9. package/dist/agentConnections/agentTokenProvider.d.ts.map +1 -0
  10. package/dist/agentConnections/agentTokenProvider.js +294 -0
  11. package/dist/agentConnections/apiUrl.d.ts +4 -0
  12. package/dist/agentConnections/apiUrl.d.ts.map +1 -0
  13. package/dist/agentConnections/apiUrl.js +37 -0
  14. package/dist/agentConnections/commandPolicy.d.ts +14 -0
  15. package/dist/agentConnections/commandPolicy.d.ts.map +1 -0
  16. package/dist/agentConnections/commandPolicy.js +108 -0
  17. package/dist/agentConnections/configLock.d.ts +12 -0
  18. package/dist/agentConnections/configLock.d.ts.map +1 -0
  19. package/dist/agentConnections/configLock.js +191 -0
  20. package/dist/agentConnections/connectInputs.d.ts +20 -0
  21. package/dist/agentConnections/connectInputs.d.ts.map +1 -0
  22. package/dist/agentConnections/connectInputs.js +49 -0
  23. package/dist/agentConnections/fixtures.d.ts +3 -0
  24. package/dist/agentConnections/fixtures.d.ts.map +1 -0
  25. package/dist/agentConnections/fixtures.js +36 -0
  26. package/dist/agentConnections/initialToken.d.ts +26 -0
  27. package/dist/agentConnections/initialToken.d.ts.map +1 -0
  28. package/dist/agentConnections/initialToken.js +93 -0
  29. package/dist/agentConnections/lifecycle.d.ts +17 -0
  30. package/dist/agentConnections/lifecycle.d.ts.map +1 -0
  31. package/dist/agentConnections/lifecycle.js +44 -0
  32. package/dist/agentConnections/personalRecovery.d.ts +27 -0
  33. package/dist/agentConnections/personalRecovery.d.ts.map +1 -0
  34. package/dist/agentConnections/personalRecovery.js +71 -0
  35. package/dist/agentConnections/projectSelection.d.ts +4 -0
  36. package/dist/agentConnections/projectSelection.d.ts.map +1 -0
  37. package/dist/agentConnections/projectSelection.js +48 -0
  38. package/dist/agentConnections/providerProcess.fixture.d.ts +2 -0
  39. package/dist/agentConnections/providerProcess.fixture.d.ts.map +1 -0
  40. package/dist/agentConnections/providerProcess.fixture.js +19 -0
  41. package/dist/agentConnections/requestPolicy.d.ts +11 -0
  42. package/dist/agentConnections/requestPolicy.d.ts.map +1 -0
  43. package/dist/agentConnections/requestPolicy.js +76 -0
  44. package/dist/agentConnections/schema.d.ts +66 -0
  45. package/dist/agentConnections/schema.d.ts.map +1 -0
  46. package/dist/agentConnections/schema.js +184 -0
  47. package/dist/agentConnections/statusResponse.d.ts +10 -0
  48. package/dist/agentConnections/statusResponse.d.ts.map +1 -0
  49. package/dist/agentConnections/statusResponse.js +146 -0
  50. package/dist/agentConnections/store.d.ts +36 -0
  51. package/dist/agentConnections/store.d.ts.map +1 -0
  52. package/dist/agentConnections/store.js +275 -0
  53. package/dist/agentConnections/warehouseStatus.d.ts +30 -0
  54. package/dist/agentConnections/warehouseStatus.d.ts.map +1 -0
  55. package/dist/agentConnections/warehouseStatus.js +184 -0
  56. package/dist/analytics/analytics.d.ts.map +1 -1
  57. package/dist/analytics/analytics.js +4 -0
  58. package/dist/config.d.ts +3 -1
  59. package/dist/config.d.ts.map +1 -1
  60. package/dist/config.js +2 -2
  61. package/dist/credentials.d.ts +27 -0
  62. package/dist/credentials.d.ts.map +1 -0
  63. package/dist/credentials.js +161 -0
  64. package/dist/dbt/models.d.ts.map +1 -1
  65. package/dist/dbt/models.js +45 -14
  66. package/dist/handlers/agentAccess.d.ts.map +1 -1
  67. package/dist/handlers/agentAccess.js +9 -1
  68. package/dist/handlers/agentConnect.d.ts.map +1 -1
  69. package/dist/handlers/agentConnect.js +2 -0
  70. package/dist/handlers/agentConnectionConnect.d.ts +5 -0
  71. package/dist/handlers/agentConnectionConnect.d.ts.map +1 -0
  72. package/dist/handlers/agentConnectionConnect.js +371 -0
  73. package/dist/handlers/agentConnectionStatus.d.ts +7 -0
  74. package/dist/handlers/agentConnectionStatus.d.ts.map +1 -0
  75. package/dist/handlers/agentConnectionStatus.js +228 -0
  76. package/dist/handlers/agentRevoke.d.ts +7 -0
  77. package/dist/handlers/agentRevoke.d.ts.map +1 -0
  78. package/dist/handlers/agentRevoke.js +144 -0
  79. package/dist/handlers/agentStatus.d.ts +4 -1
  80. package/dist/handlers/agentStatus.d.ts.map +1 -1
  81. package/dist/handlers/agentStatus.js +7 -0
  82. package/dist/handlers/apps/createApp.d.ts.map +1 -1
  83. package/dist/handlers/apps/createApp.js +2 -0
  84. package/dist/handlers/apps/preview.d.ts.map +1 -1
  85. package/dist/handlers/apps/preview.js +6 -0
  86. package/dist/handlers/apps/previewProxy.d.ts.map +1 -1
  87. package/dist/handlers/apps/previewProxy.js +2 -0
  88. package/dist/handlers/apps/validate.d.ts.map +1 -1
  89. package/dist/handlers/apps/validate.js +20 -8
  90. package/dist/handlers/compile.d.ts.map +1 -1
  91. package/dist/handlers/compile.js +3 -0
  92. package/dist/handlers/connectSnowflake.d.ts.map +1 -1
  93. package/dist/handlers/connectSnowflake.js +2 -0
  94. package/dist/handlers/createProject.d.ts.map +1 -1
  95. package/dist/handlers/createProject.js +2 -0
  96. package/dist/handlers/dbt/apiClient.d.ts +4 -2
  97. package/dist/handlers/dbt/apiClient.d.ts.map +1 -1
  98. package/dist/handlers/dbt/apiClient.js +138 -4
  99. package/dist/handlers/dbt/compile.d.ts.map +1 -1
  100. package/dist/handlers/dbt/compile.js +13 -2
  101. package/dist/handlers/dbt/getDbtProfileTargetName.d.ts.map +1 -1
  102. package/dist/handlers/dbt/getDbtProfileTargetName.js +12 -4
  103. package/dist/handlers/dbt/getDbtVersion.d.ts.map +1 -1
  104. package/dist/handlers/dbt/getDbtVersion.js +12 -4
  105. package/dist/handlers/dbt/getWarehouseClient.d.ts.map +1 -1
  106. package/dist/handlers/dbt/getWarehouseClient.js +15 -5
  107. package/dist/handlers/dbt/refresh.d.ts.map +1 -1
  108. package/dist/handlers/dbt/refresh.js +2 -0
  109. package/dist/handlers/dbt/run.d.ts.map +1 -1
  110. package/dist/handlers/dbt/run.js +10 -3
  111. package/dist/handlers/deploy.d.ts.map +1 -1
  112. package/dist/handlers/deploy.js +17 -1
  113. package/dist/handlers/diagnostics.d.ts.map +1 -1
  114. package/dist/handlers/diagnostics.js +2 -0
  115. package/dist/handlers/download.d.ts.map +1 -1
  116. package/dist/handlers/download.js +19 -5
  117. package/dist/handlers/exportChartImage.d.ts.map +1 -1
  118. package/dist/handlers/exportChartImage.js +2 -0
  119. package/dist/handlers/generateExposures.d.ts.map +1 -1
  120. package/dist/handlers/generateExposures.js +4 -1
  121. package/dist/handlers/getProject.d.ts.map +1 -1
  122. package/dist/handlers/getProject.js +25 -1
  123. package/dist/handlers/listProjects.d.ts.map +1 -1
  124. package/dist/handlers/listProjects.js +2 -0
  125. package/dist/handlers/login/connectionBrowser.d.ts +2 -0
  126. package/dist/handlers/login/connectionBrowser.d.ts.map +1 -0
  127. package/dist/handlers/login/connectionBrowser.js +22 -0
  128. package/dist/handlers/login/loopback.d.ts +15 -0
  129. package/dist/handlers/login/loopback.d.ts.map +1 -0
  130. package/dist/handlers/login/loopback.js +135 -0
  131. package/dist/handlers/login/oauth.d.ts.map +1 -1
  132. package/dist/handlers/login/oauth.js +16 -3
  133. package/dist/handlers/login/pat.d.ts.map +1 -1
  134. package/dist/handlers/login/pat.js +2 -0
  135. package/dist/handlers/login.d.ts.map +1 -1
  136. package/dist/handlers/login.js +8 -1
  137. package/dist/handlers/oauthLogin.d.ts.map +1 -1
  138. package/dist/handlers/oauthLogin.js +2 -0
  139. package/dist/handlers/ordinary/harness.mocks.d.ts +42 -0
  140. package/dist/handlers/ordinary/harness.mocks.d.ts.map +1 -0
  141. package/dist/handlers/ordinary/harness.mocks.js +180 -0
  142. package/dist/handlers/preAggregateAudit.d.ts.map +1 -1
  143. package/dist/handlers/preAggregateAudit.js +2 -0
  144. package/dist/handlers/preview.d.ts.map +1 -1
  145. package/dist/handlers/preview.js +4 -0
  146. package/dist/handlers/renameHandler.d.ts.map +1 -1
  147. package/dist/handlers/renameHandler.js +2 -0
  148. package/dist/handlers/renameProject.d.ts.map +1 -1
  149. package/dist/handlers/renameProject.js +2 -0
  150. package/dist/handlers/resolveProjectFlag.d.ts.map +1 -1
  151. package/dist/handlers/resolveProjectFlag.js +5 -0
  152. package/dist/handlers/runChart.d.ts.map +1 -1
  153. package/dist/handlers/runChart.js +7 -2
  154. package/dist/handlers/selectProject.d.ts.map +1 -1
  155. package/dist/handlers/selectProject.js +5 -0
  156. package/dist/handlers/setProject.d.ts.map +1 -1
  157. package/dist/handlers/setProject.js +5 -0
  158. package/dist/handlers/setWarehouse.d.ts.map +1 -1
  159. package/dist/handlers/setWarehouse.js +2 -0
  160. package/dist/handlers/slugUpdate.d.ts.map +1 -1
  161. package/dist/handlers/slugUpdate.js +2 -0
  162. package/dist/handlers/sourceSelection.d.ts.map +1 -1
  163. package/dist/handlers/sourceSelection.js +13 -2
  164. package/dist/handlers/sql.d.ts.map +1 -1
  165. package/dist/handlers/sql.js +7 -2
  166. package/dist/handlers/utils.d.ts +3 -0
  167. package/dist/handlers/utils.d.ts.map +1 -1
  168. package/dist/handlers/utils.js +39 -0
  169. package/dist/handlers/validate.d.ts.map +1 -1
  170. package/dist/handlers/validate.js +2 -0
  171. package/dist/handlers/warehouseCatalog.d.ts.map +1 -1
  172. package/dist/handlers/warehouseCatalog.js +7 -2
  173. package/dist/index.js +43 -3
  174. package/dist/lightdash-config/index.d.ts.map +1 -1
  175. package/dist/lightdash-config/index.js +4 -1
  176. package/package.json +3 -3
@@ -6,11 +6,13 @@ const fs_1 = require("fs");
6
6
  const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
7
7
  const uuid_1 = require("uuid");
8
8
  const config_1 = require("../config");
9
+ const credentials_1 = require("../credentials");
9
10
  const globalState_1 = tslib_1.__importDefault(require("../globalState"));
10
11
  const styles = tslib_1.__importStar(require("../styles"));
11
12
  const apiClient_1 = require("./dbt/apiClient");
12
13
  const resolveProjectFlag_1 = require("./resolveProjectFlag");
13
14
  const exportChartImageHandler = async (chartUuidOrSlug, options) => {
15
+ (0, credentials_1.refuseAgentConnection)();
14
16
  globalState_1.default.setVerbose(options.verbose ?? false);
15
17
  const spinner = globalState_1.default.startSpinner(`Exporting chart image for '${chartUuidOrSlug}'...`);
16
18
  const isChartUuid = (0, uuid_1.validate)(chartUuidOrSlug);
@@ -1 +1 @@
1
- {"version":3,"file":"generateExposures.d.ts","sourceRoot":"","sources":["../../src/handlers/generateExposures.ts"],"names":[],"mappings":"AAkBA,KAAK,+BAA+B,GAAG;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,wBAAwB,YACxB,+BAA+B,kBA6G3C,CAAC"}
1
+ {"version":3,"file":"generateExposures.d.ts","sourceRoot":"","sources":["../../src/handlers/generateExposures.ts"],"names":[],"mappings":"AAmBA,KAAK,+BAA+B,GAAG;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,wBAAwB,YACxB,+BAA+B,kBAmH3C,CAAC"}
@@ -9,6 +9,7 @@ const path = tslib_1.__importStar(require("path"));
9
9
  const uuid_1 = require("uuid");
10
10
  const analytics_1 = require("../analytics/analytics");
11
11
  const config_1 = require("../config");
12
+ const credentials_1 = require("../credentials");
12
13
  const globalState_1 = tslib_1.__importDefault(require("../globalState"));
13
14
  const styles = tslib_1.__importStar(require("../styles"));
14
15
  const apiClient_1 = require("./dbt/apiClient");
@@ -17,7 +18,9 @@ const generateExposuresHandler = async (options) => {
17
18
  globalState_1.default.setVerbose(options.verbose);
18
19
  await (0, apiClient_1.checkLightdashVersion)();
19
20
  const executionId = (0, uuid_1.v4)();
20
- const config = await (0, config_1.getConfig)();
21
+ const config = await ((0, credentials_1.getAgentConnectionSelection)() === null
22
+ ? (0, config_1.getConfig)()
23
+ : (0, config_1.getConfig)({ readOnly: true }).then(async (currentConfig) => (await Promise.resolve().then(() => tslib_1.__importStar(require('../agentConnections/projectSelection')))).configWithAgentProject(currentConfig)));
21
24
  if (!(config.context?.project && config.context.serverUrl)) {
22
25
  throw new common_1.AuthorizationError(`No active Lightdash project. Run 'lightdash login --help'`);
23
26
  }
@@ -1 +1 @@
1
- {"version":3,"file":"getProject.d.ts","sourceRoot":"","sources":["../../src/handlers/getProject.ts"],"names":[],"mappings":"AAKA,KAAK,iBAAiB,GAAG;IACrB,OAAO,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,iBAAiB,YAAmB,iBAAiB,kBAsCjE,CAAC"}
1
+ {"version":3,"file":"getProject.d.ts","sourceRoot":"","sources":["../../src/handlers/getProject.ts"],"names":[],"mappings":"AAMA,KAAK,iBAAiB,GAAG;IACrB,OAAO,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,iBAAiB,YAAmB,iBAAiB,kBAsEjE,CAAC"}
@@ -4,6 +4,7 @@ exports.getProjectHandler = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const analytics_1 = require("../analytics/analytics");
6
6
  const config_1 = require("../config");
7
+ const credentials_1 = require("../credentials");
7
8
  const globalState_1 = tslib_1.__importDefault(require("../globalState"));
8
9
  const styles = tslib_1.__importStar(require("../styles"));
9
10
  const getProjectHandler = async (options) => {
@@ -11,7 +12,30 @@ const getProjectHandler = async (options) => {
11
12
  let success = true;
12
13
  globalState_1.default.setVerbose(options.verbose);
13
14
  try {
14
- const config = await (0, config_1.getConfig)();
15
+ const config = await ((0, credentials_1.getAgentConnectionSelection)() === null
16
+ ? (0, config_1.getConfig)()
17
+ : (0, config_1.getConfig)({ readOnly: true }));
18
+ if ((0, credentials_1.getAgentConnectionSelection)() !== null) {
19
+ const credential = await (0, credentials_1.resolveCredential)(config);
20
+ if (credential.kind !== 'agent_connection')
21
+ throw new Error('An agent connection credential is required.');
22
+ const { publicConnectionReport } = await Promise.resolve().then(() => tslib_1.__importStar(require('../agentConnections/statusResponse')));
23
+ const { approvedProjects } = publicConnectionReport(credential.slot, [config.context?.apiKey, config.context?.proxyAuthorization]);
24
+ globalState_1.default.debug(`> Agent connection: ${JSON.stringify({ name: credential.slot.name, approvedProjects })}`);
25
+ if (approvedProjects.length === 1) {
26
+ const project = approvedProjects[0];
27
+ console.error(styles.bold('\nCurrent project:\n'));
28
+ console.error(` Name: ${project.name ?? 'Name unavailable'}`);
29
+ console.error(` UUID: ${project.projectUuid}`);
30
+ console.error('');
31
+ }
32
+ else {
33
+ console.error(`This connection is approved for ${approvedProjects.length} projects. Pass --project on the command.`);
34
+ for (const project of approvedProjects)
35
+ console.error(` ${project.name ?? 'Name unavailable'} (${project.projectUuid})`);
36
+ }
37
+ return;
38
+ }
15
39
  globalState_1.default.debug(`> Config: ${JSON.stringify(config)}`);
16
40
  const projectUuid = config.context?.project;
17
41
  const projectName = config.context?.projectName;
@@ -1 +1 @@
1
- {"version":3,"file":"listProjects.d.ts","sourceRoot":"","sources":["../../src/handlers/listProjects.ts"],"names":[],"mappings":"AAMA,KAAK,mBAAmB,GAAG;IACvB,OAAO,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,mBAAmB,YAAmB,mBAAmB,kBAqDrE,CAAC"}
1
+ {"version":3,"file":"listProjects.d.ts","sourceRoot":"","sources":["../../src/handlers/listProjects.ts"],"names":[],"mappings":"AAOA,KAAK,mBAAmB,GAAG;IACvB,OAAO,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,mBAAmB,YAAmB,mBAAmB,kBAsDrE,CAAC"}
@@ -3,11 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.listProjectsHandler = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const common_1 = require("@lightdash/common");
6
+ const commandPolicy_1 = require("../agentConnections/commandPolicy");
6
7
  const analytics_1 = require("../analytics/analytics");
7
8
  const globalState_1 = tslib_1.__importDefault(require("../globalState"));
8
9
  const styles = tslib_1.__importStar(require("../styles"));
9
10
  const apiClient_1 = require("./dbt/apiClient");
10
11
  const listProjectsHandler = async (options) => {
12
+ (0, commandPolicy_1.assertAgentCommandAllowed)('config list-projects');
11
13
  const startTime = Date.now();
12
14
  let success = true;
13
15
  globalState_1.default.setVerbose(options.verbose);
@@ -0,0 +1,2 @@
1
+ export declare const openConnectionBrowser: (url: string) => Promise<boolean>;
2
+ //# sourceMappingURL=connectionBrowser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connectionBrowser.d.ts","sourceRoot":"","sources":["../../../src/handlers/login/connectionBrowser.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,qBAAqB,QAAS,MAAM,KAAG,OAAO,CAAC,OAAO,CAmBlE,CAAC"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.openConnectionBrowser = void 0;
4
+ const child_process_1 = require("child_process");
5
+ const credentials_1 = require("../../credentials");
6
+ const openConnectionBrowser = (url) => {
7
+ (0, credentials_1.refuseAgentConnection)(true);
8
+ const { platform } = process;
9
+ let executable = 'xdg-open';
10
+ if (platform === 'darwin')
11
+ executable = 'open';
12
+ else if (platform === 'win32')
13
+ executable = 'rundll32.exe';
14
+ const args = platform === 'win32' ? ['url.dll,FileProtocolHandler', url] : [url];
15
+ const env = { ...process.env };
16
+ delete env.LIGHTDASH_API_KEY;
17
+ delete env.LIGHTDASH_PROXY_AUTHORIZATION;
18
+ return new Promise((resolve) => {
19
+ (0, child_process_1.execFile)(executable, args, { timeout: 5000, shell: false, env }, (error) => resolve(error === null));
20
+ });
21
+ };
22
+ exports.openConnectionBrowser = openConnectionBrowser;
@@ -0,0 +1,15 @@
1
+ export type ConnectionCallback = {
2
+ code: string;
3
+ grantUuid: string | null;
4
+ };
5
+ export declare const createConnectionLoopback: ({ port, state, issuer, signal, }: {
6
+ port: number;
7
+ state: string;
8
+ issuer: string;
9
+ signal: AbortSignal;
10
+ }) => Promise<{
11
+ redirectUri: string;
12
+ result: Promise<ConnectionCallback>;
13
+ close: () => Promise<void>;
14
+ }>;
15
+ //# sourceMappingURL=loopback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loopback.d.ts","sourceRoot":"","sources":["../../../src/handlers/login/loopback.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,kBAAkB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAC5E,eAAO,MAAM,wBAAwB,qCAKlC;IACC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,WAAW,CAAC;CACvB;;;;EA2IA,CAAC"}
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createConnectionLoopback = void 0;
4
+ const http_1 = require("http");
5
+ const createConnectionLoopback = async ({ port, state, issuer, signal, }) => {
6
+ let settled = false;
7
+ let resolveResult = () => { };
8
+ let rejectResult = () => { };
9
+ const result = new Promise((resolve, reject) => {
10
+ resolveResult = resolve;
11
+ rejectResult = reject;
12
+ });
13
+ void result.catch(() => { });
14
+ const abort = () => {
15
+ if (!settled) {
16
+ settled = true;
17
+ rejectResult(new Error('Agent connection approval timed out or was cancelled. No credential was saved.'));
18
+ }
19
+ };
20
+ const handle = (req, res) => {
21
+ const invalid = () => {
22
+ res.writeHead(400);
23
+ res.end('Invalid approval callback.');
24
+ };
25
+ let url;
26
+ try {
27
+ url = new URL(req.url ?? '/', 'http://localhost');
28
+ }
29
+ catch {
30
+ invalid();
31
+ return;
32
+ }
33
+ const params = url.searchParams;
34
+ const unique = [
35
+ 'state',
36
+ 'code',
37
+ 'iss',
38
+ 'error',
39
+ 'grant_uuid',
40
+ 'error_description',
41
+ ].every((key) => params.getAll(key).length <= 1);
42
+ const code = params.get('code');
43
+ const error = params.get('error');
44
+ if (settled ||
45
+ req.method !== 'GET' ||
46
+ req.url?.split('?', 1)[0] !== '/callback' ||
47
+ url.pathname !== '/callback' ||
48
+ !unique ||
49
+ params.get('state') !== state ||
50
+ params.get('iss') !== issuer ||
51
+ (code === null) === (error === null) ||
52
+ code === '' ||
53
+ error === '') {
54
+ invalid();
55
+ return;
56
+ }
57
+ settled = true;
58
+ res.writeHead(200, {
59
+ 'Content-Type': 'text/plain',
60
+ 'Cache-Control': 'no-store',
61
+ });
62
+ res.end('You can return to the CLI.');
63
+ if (error !== null)
64
+ rejectResult(new Error('Agent connection approval was denied. No credential was saved.'));
65
+ else
66
+ resolveResult({ code: code, grantUuid: params.get('grant_uuid') });
67
+ };
68
+ let servers = [];
69
+ const closeServers = async () => {
70
+ const closing = servers;
71
+ servers = [];
72
+ await Promise.all(closing.map((server) => {
73
+ server.closeAllConnections();
74
+ return new Promise((resolve) => {
75
+ server.close(() => resolve());
76
+ });
77
+ }));
78
+ };
79
+ const listen = (host, onPort) => new Promise((resolve, reject) => {
80
+ const server = (0, http_1.createServer)(handle);
81
+ servers.push(server);
82
+ server.once('error', reject);
83
+ server.listen(onPort, host, () => {
84
+ const address = server.address();
85
+ if (!address || typeof address === 'string')
86
+ reject(new Error('No listener address'));
87
+ else
88
+ resolve(address.port);
89
+ });
90
+ });
91
+ // localhost can resolve to either loopback family, so listen on both.
92
+ const listenOnLoopback = async (attempt = 0) => {
93
+ const bound = await listen('127.0.0.1', port);
94
+ try {
95
+ await listen('::1', bound);
96
+ return bound;
97
+ }
98
+ catch (error) {
99
+ const code = error instanceof Error && 'code' in error ? error.code : null;
100
+ if (code === 'EADDRNOTAVAIL' || code === 'EAFNOSUPPORT') {
101
+ servers = servers.slice(0, 1);
102
+ return bound;
103
+ }
104
+ await closeServers();
105
+ if (code !== 'EADDRINUSE' || port !== 0 || attempt >= 4)
106
+ throw error;
107
+ return listenOnLoopback(attempt + 1);
108
+ }
109
+ };
110
+ const close = async () => {
111
+ signal.removeEventListener('abort', abort);
112
+ abort();
113
+ await closeServers();
114
+ };
115
+ signal.addEventListener('abort', abort, { once: true });
116
+ if (signal.aborted) {
117
+ await close();
118
+ throw new Error('Agent connection approval was cancelled.');
119
+ }
120
+ try {
121
+ const bound = await listenOnLoopback();
122
+ if (signal.aborted)
123
+ throw new Error('Could not start the approval callback listener.');
124
+ return {
125
+ redirectUri: `http://localhost:${bound}/callback`,
126
+ result,
127
+ close,
128
+ };
129
+ }
130
+ catch {
131
+ await close();
132
+ throw new Error('Could not start the approval callback listener.');
133
+ }
134
+ };
135
+ exports.createConnectionLoopback = createConnectionLoopback;
@@ -1 +1 @@
1
- {"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../../src/handlers/login/oauth.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,WAAW,QAAe,MAAM,KAAG,OAAO,CAAC,OAAO,CAgB9D,CAAC"}
1
+ {"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../../src/handlers/login/oauth.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,WAAW,QAAe,MAAM,KAAG,OAAO,CAAC,OAAO,CA0B9D,CAAC"}
@@ -5,19 +5,32 @@ exports.openBrowser = void 0;
5
5
  const tslib_1 = require("tslib");
6
6
  const child_process_1 = require("child_process");
7
7
  const util_1 = require("util");
8
+ const credentials_1 = require("../../credentials");
8
9
  const globalState_1 = tslib_1.__importDefault(require("../../globalState"));
9
10
  const execAsync = (0, util_1.promisify)(child_process_1.exec);
10
11
  const openBrowser = async (url) => {
12
+ const childEnv = (0, credentials_1.getAgentConnectionSelection)() !== null
13
+ ? await (0, credentials_1.getAgentConnectionChildEnvironment)()
14
+ : null;
11
15
  try {
12
16
  const { platform } = process;
13
17
  if (platform === 'darwin') {
14
- await execAsync(`open "${url}"`);
18
+ if (childEnv !== null)
19
+ await execAsync(`open "${url}"`, { env: childEnv });
20
+ else
21
+ await execAsync(`open "${url}"`);
15
22
  }
16
23
  else if (platform === 'win32') {
17
- await execAsync(`start "${url}"`);
24
+ if (childEnv !== null)
25
+ await execAsync(`start "${url}"`, { env: childEnv });
26
+ else
27
+ await execAsync(`start "${url}"`);
18
28
  }
19
29
  else {
20
- await execAsync(`xdg-open "${url}"`);
30
+ if (childEnv !== null)
31
+ await execAsync(`xdg-open "${url}"`, { env: childEnv });
32
+ else
33
+ await execAsync(`xdg-open "${url}"`);
21
34
  }
22
35
  return true;
23
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"pat.d.ts","sourceRoot":"","sources":["../../../src/handlers/login/pat.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,2BAA2B,YAC3B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,OAC1B,MAAM,kBACI,MAAM,KACtB,OAAO,CAAC,MAAM,CAyBhB,CAAC"}
1
+ {"version":3,"file":"pat.d.ts","sourceRoot":"","sources":["../../../src/handlers/login/pat.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,2BAA2B,YAC3B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,OAC1B,MAAM,kBACI,MAAM,KACtB,OAAO,CAAC,MAAM,CA0BhB,CAAC"}
@@ -4,7 +4,9 @@ exports.generatePersonalAccessToken = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const common_1 = require("@lightdash/common");
6
6
  const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
7
+ const credentials_1 = require("../../credentials");
7
8
  const generatePersonalAccessToken = async (headers, url, hoursToExpire = 720) => {
9
+ (0, credentials_1.refuseAgentConnection)(true);
8
10
  const patUrl = new URL(`/api/v1/user/me/personal-access-tokens`, url).href;
9
11
  const now = new Date();
10
12
  const createToken = {
@@ -1 +1 @@
1
- {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/handlers/login.ts"],"names":[],"mappings":"AAkBA,KAAK,YAAY,GAAG;IAChB,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;CACpB,CAAC;AA8CF;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,UACzB,MAAM,GAAG,SAAS,QACpB,MAAM,CAAC,UAAU,KACvB,OAAqE,CAAC;AA2HzE,eAAO,MAAM,KAAK,aACJ,MAAM,GAAG,SAAS,WACnB,YAAY,kBAoKxB,CAAC"}
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/handlers/login.ts"],"names":[],"mappings":"AAmBA,KAAK,YAAY,GAAG;IAChB,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;CACpB,CAAC;AA8CF;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,UACzB,MAAM,GAAG,SAAS,QACpB,MAAM,CAAC,UAAU,KACvB,OAGF,CAAC;AA6HF,eAAO,MAAM,KAAK,aACJ,MAAM,GAAG,SAAS,WACnB,YAAY,kBAqKxB,CAAC"}
@@ -8,6 +8,7 @@ const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
8
8
  const url_1 = require("url");
9
9
  const analytics_1 = require("../analytics/analytics");
10
10
  const config_1 = require("../config");
11
+ const credentials_1 = require("../credentials");
11
12
  const globalState_1 = tslib_1.__importDefault(require("../globalState"));
12
13
  const styles = tslib_1.__importStar(require("../styles"));
13
14
  const apiClient_1 = require("./dbt/apiClient");
@@ -61,12 +62,16 @@ const getLoginMethod = (options) => {
61
62
  * $LIGHTDASH_API_KEY` is a documented CI pattern — there both tokens are the
62
63
  * same and nothing is shadowed.
63
64
  */
64
- const isApiKeyEnvVarShadowing = (token, env = process.env) => !!env.LIGHTDASH_API_KEY && env.LIGHTDASH_API_KEY !== token;
65
+ const isApiKeyEnvVarShadowing = (token, env = process.env) => {
66
+ (0, credentials_1.refuseAgentConnection)(true);
67
+ return !!env.LIGHTDASH_API_KEY && env.LIGHTDASH_API_KEY !== token;
68
+ };
65
69
  exports.isApiKeyEnvVarShadowing = isApiKeyEnvVarShadowing;
66
70
  const apiKeyEnvVarWarning = (when) => styles.warning(when === 'before-login'
67
71
  ? `\n⚠️ LIGHTDASH_API_KEY is set and takes precedence over the token saved by \`lightdash login\` (${config_1.configFilePath}).\n Every command will keep using LIGHTDASH_API_KEY until you unset it:\n\n ${styles.bold('unset LIGHTDASH_API_KEY')}\n`
68
72
  : ` ⚠️ LIGHTDASH_API_KEY is still set and takes precedence — run ${styles.bold('unset LIGHTDASH_API_KEY')} for this login to take effect.\n`);
69
73
  const loginWithToken = async (url, token) => {
74
+ (0, credentials_1.refuseAgentConnection)(true);
70
75
  const userInfoUrl = new url_1.URL(`/api/v1/user`, url).href;
71
76
  const response = await (0, node_fetch_1.default)(userInfoUrl, {
72
77
  method: 'GET',
@@ -84,6 +89,7 @@ const loginWithToken = async (url, token) => {
84
89
  };
85
90
  };
86
91
  const loginWithEmailPassword = async (url, email, password) => {
92
+ (0, credentials_1.refuseAgentConnection)(true);
87
93
  const loginUrl = new url_1.URL('/api/v1/login', url).href;
88
94
  const loginResponse = await (0, node_fetch_1.default)(loginUrl, {
89
95
  method: 'POST',
@@ -141,6 +147,7 @@ const loginWithEmailPassword = async (url, email, password) => {
141
147
  };
142
148
  };
143
149
  const login = async (urlInput, options) => {
150
+ (0, credentials_1.refuseAgentConnection)(true);
144
151
  globalState_1.default.setVerbose(options.verbose);
145
152
  await (0, apiClient_1.checkLightdashVersion)();
146
153
  // If no URL provided, try to use the saved URL from config
@@ -1 +1 @@
1
- {"version":3,"file":"oauthLogin.d.ts","sourceRoot":"","sources":["../../src/handlers/oauthLogin.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,cAAc,QAClB,MAAM,cACC,MAAM,KACnB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAoPvE,CAAC"}
1
+ {"version":3,"file":"oauthLogin.d.ts","sourceRoot":"","sources":["../../src/handlers/oauthLogin.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,cAAc,QAClB,MAAM,cACC,MAAM,KACnB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAqPvE,CAAC"}
@@ -7,11 +7,13 @@ const http = tslib_1.__importStar(require("http"));
7
7
  const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
8
8
  const openid_client_1 = require("openid-client");
9
9
  const url_1 = require("url");
10
+ const credentials_1 = require("../credentials");
10
11
  const globalState_1 = tslib_1.__importDefault(require("../globalState"));
11
12
  const styles = tslib_1.__importStar(require("../styles"));
12
13
  const oauth_1 = require("./login/oauth");
13
14
  const pat_1 = require("./login/pat");
14
15
  const loginWithOauth = async (url, oauthPort) => {
16
+ (0, credentials_1.refuseAgentConnection)(true);
15
17
  // Create a promise that will be resolved when we get the authorization code
16
18
  let resolveAuth;
17
19
  let rejectAuth;
@@ -0,0 +1,42 @@
1
+ import { type IncomingHttpHeaders, type Server } from 'http';
2
+ import type { Config } from '../../config';
3
+ export type RecordedRequest = {
4
+ method: string;
5
+ path: string;
6
+ authorization: string | undefined;
7
+ body: string;
8
+ };
9
+ export type Reply = {
10
+ method: string;
11
+ path: string;
12
+ results?: unknown;
13
+ status?: number;
14
+ error?: string;
15
+ body?: string;
16
+ disconnect?: boolean;
17
+ raw?: string;
18
+ };
19
+ export declare class OrdinaryServer {
20
+ private readonly received;
21
+ readonly requests: RecordedRequest[];
22
+ readonly headers: IncomingHttpHeaders[];
23
+ readonly unexpected: RecordedRequest[];
24
+ readonly replies: Reply[];
25
+ readonly server: Server;
26
+ url: string;
27
+ onRequest: (() => void) | null;
28
+ constructor();
29
+ start(): Promise<void>;
30
+ waitForRequest(count: number): Promise<void>;
31
+ close(): Promise<void>;
32
+ expectComplete(): void;
33
+ }
34
+ export declare const personalConfig: (serverUrl: string) => Config;
35
+ export declare const saveConfig: (home: string, config: Config) => Promise<string>;
36
+ export declare const request: (method: string, url: string, body?: string) => RecordedRequest;
37
+ export declare const runOrdinaryCli: (home: string, args: string[]) => Promise<{
38
+ code: number | null;
39
+ stdout: string;
40
+ stderr: string;
41
+ }>;
42
+ //# sourceMappingURL=harness.mocks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harness.mocks.d.ts","sourceRoot":"","sources":["../../../src/handlers/ordinary/harness.mocks.ts"],"names":[],"mappings":"AAGA,OAAO,EAAgB,KAAK,mBAAmB,EAAE,KAAK,MAAM,EAAE,MAAM,MAAM,CAAC;AAO3E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,MAAM,eAAe,GAAG;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,IAAI,EAAE,MAAM,CAAC;CAChB,CAAC;AACF,MAAM,MAAM,KAAK,GAAG;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AACF,qBAAa,cAAc;IACvB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAsB;IAC/C,QAAQ,CAAC,QAAQ,EAAE,eAAe,EAAE,CAAM;IAC1C,QAAQ,CAAC,OAAO,EAAE,mBAAmB,EAAE,CAAM;IAC7C,QAAQ,CAAC,UAAU,EAAE,eAAe,EAAE,CAAM;IAC5C,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,CAAM;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,GAAG,SAAM;IACT,SAAS,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAQ;IACtC,cAgEC;IACK,KAAK,kBAQV;IACK,cAAc,CAAC,KAAK,EAAE,MAAM,iBAWjC;IACK,KAAK,kBAMV;IACD,cAAc,SAGb;CACJ;AACD,eAAO,MAAM,cAAc,cAAe,MAAM,KAAG,MAcjD,CAAC;AACH,eAAO,MAAM,UAAU,SAAgB,MAAM,UAAU,MAAM,oBAK5D,CAAC;AACF,eAAO,MAAM,OAAO,WACR,MAAM,OACT,MAAM,oBAEZ,eAKD,CAAC;AAEH,eAAO,MAAM,cAAc,SAAgB,MAAM,QAAQ,MAAM,EAAE;UAsB/C,MAAM,GAAG,IAAI;YACX,MAAM;YACN,MAAM;EAuBzB,CAAC"}
@@ -0,0 +1,180 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runOrdinaryCli = exports.request = exports.saveConfig = exports.personalConfig = exports.OrdinaryServer = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const child_process_1 = require("child_process");
6
+ const events_1 = require("events");
7
+ const fs_1 = require("fs");
8
+ const http_1 = require("http");
9
+ const yaml = tslib_1.__importStar(require("js-yaml"));
10
+ const path_1 = tslib_1.__importDefault(require("path"));
11
+ const timers_1 = require("timers");
12
+ class OrdinaryServer {
13
+ received = new events_1.EventEmitter();
14
+ requests = [];
15
+ headers = [];
16
+ unexpected = [];
17
+ replies = [];
18
+ server;
19
+ url = '';
20
+ onRequest = null;
21
+ constructor() {
22
+ this.server = (0, http_1.createServer)((req, res) => {
23
+ let body = '';
24
+ req.on('data', (chunk) => {
25
+ body += String(chunk);
26
+ });
27
+ req.on('end', () => {
28
+ const request = {
29
+ method: req.method,
30
+ path: req.url,
31
+ authorization: req.headers.authorization,
32
+ body,
33
+ };
34
+ this.requests.push(request);
35
+ this.headers.push(req.headers);
36
+ this.onRequest?.();
37
+ this.received.emit('request');
38
+ const reply = this.replies.shift();
39
+ if (!reply ||
40
+ reply.method !== req.method ||
41
+ reply.path !== req.url ||
42
+ (reply.body !== undefined && reply.body !== body)) {
43
+ this.unexpected.push(request);
44
+ res.writeHead(500, { 'content-type': 'application/json' });
45
+ res.end(JSON.stringify({
46
+ status: 'error',
47
+ error: {
48
+ name: 'Unexpected',
49
+ message: 'Unexpected request',
50
+ },
51
+ }));
52
+ return;
53
+ }
54
+ if (reply.disconnect) {
55
+ req.socket.destroy();
56
+ return;
57
+ }
58
+ res.writeHead(reply.status ?? 200, {
59
+ 'content-type': reply.raw === undefined
60
+ ? 'application/json'
61
+ : 'text/plain',
62
+ });
63
+ res.end(reply.raw ??
64
+ JSON.stringify(reply.error
65
+ ? {
66
+ status: 'error',
67
+ error: {
68
+ name: 'Fixture',
69
+ message: reply.error,
70
+ statusCode: reply.status,
71
+ },
72
+ }
73
+ : { status: 'ok', results: reply.results }));
74
+ });
75
+ });
76
+ }
77
+ async start() {
78
+ await new Promise((resolve) => {
79
+ this.server.listen(0, '127.0.0.1', resolve);
80
+ });
81
+ const address = this.server.address();
82
+ if (!address || typeof address === 'string')
83
+ throw new Error('Missing server');
84
+ this.url = `http://127.0.0.1:${address.port}`;
85
+ }
86
+ async waitForRequest(count) {
87
+ if (this.requests.length >= count)
88
+ return;
89
+ await new Promise((resolve) => {
90
+ const check = () => {
91
+ if (this.requests.length >= count) {
92
+ this.received.off('request', check);
93
+ resolve();
94
+ }
95
+ };
96
+ this.received.on('request', check);
97
+ });
98
+ }
99
+ async close() {
100
+ this.received.removeAllListeners();
101
+ this.server.closeAllConnections();
102
+ await new Promise((resolve) => {
103
+ this.server.close(() => resolve());
104
+ });
105
+ }
106
+ expectComplete() {
107
+ expect(this.unexpected).toEqual([]);
108
+ expect(this.replies).toEqual([]);
109
+ }
110
+ }
111
+ exports.OrdinaryServer = OrdinaryServer;
112
+ const personalConfig = (serverUrl) => ({
113
+ user: {
114
+ anonymousUuid: 'fixed',
115
+ userUuid: 'person',
116
+ organizationUuid: 'org',
117
+ },
118
+ context: {
119
+ serverUrl,
120
+ apiKey: 'ldpat_pin',
121
+ project: '11111111-1111-4111-8111-111111111111',
122
+ projectName: 'Main',
123
+ source: 'finance',
124
+ },
125
+ answers: { permissionToStoreWarehouseCredentials: false },
126
+ });
127
+ exports.personalConfig = personalConfig;
128
+ const saveConfig = async (home, config) => {
129
+ const file = path_1.default.join(home, '.config/lightdash/config.yaml');
130
+ await fs_1.promises.mkdir(path_1.default.dirname(file), { recursive: true });
131
+ await fs_1.promises.writeFile(file, yaml.dump(config));
132
+ return file;
133
+ };
134
+ exports.saveConfig = saveConfig;
135
+ const request = (method, url, body = '') => ({
136
+ method,
137
+ path: url,
138
+ body,
139
+ authorization: 'ApiKey ldpat_pin',
140
+ });
141
+ exports.request = request;
142
+ const runOrdinaryCli = async (home, args) => {
143
+ const entry = path_1.default.join(home, 'ordinary-entry.cjs');
144
+ const analytics = path_1.default.resolve(__dirname, '../../analytics/analytics.ts');
145
+ const index = path_1.default.resolve(__dirname, '../../index.ts');
146
+ await fs_1.promises.writeFile(entry, `const { LightdashAnalytics } = require(${JSON.stringify(analytics)}); LightdashAnalytics.track = async () => {}; LightdashAnalytics.identify = async () => {}; require(${JSON.stringify(index)});`);
147
+ const env = {
148
+ ...process.env,
149
+ HOME: home,
150
+ NO_COLOR: '1',
151
+ FORCE_COLOR: '0',
152
+ CI: 'true',
153
+ };
154
+ const child = (0, child_process_1.spawn)(process.execPath, ['--import', 'tsx', entry, ...args], {
155
+ env,
156
+ stdio: ['ignore', 'pipe', 'pipe'],
157
+ });
158
+ let timer;
159
+ try {
160
+ return await new Promise((resolve, reject) => {
161
+ timer = (0, timers_1.setTimeout)(() => reject(new Error('Ordinary CLI child timed out after 20s')), 20_000);
162
+ let stdout = '';
163
+ let stderr = '';
164
+ child.stdout.on('data', (chunk) => {
165
+ stdout += String(chunk);
166
+ });
167
+ child.stderr.on('data', (chunk) => {
168
+ stderr += String(chunk);
169
+ });
170
+ child.on('error', reject);
171
+ child.on('close', (code) => resolve({ code, stdout, stderr }));
172
+ });
173
+ }
174
+ finally {
175
+ (0, timers_1.clearTimeout)(timer);
176
+ if (child.exitCode === null && child.signalCode === null)
177
+ child.kill('SIGKILL');
178
+ }
179
+ };
180
+ exports.runOrdinaryCli = runOrdinaryCli;