@lightdash/cli 0.2179.1 → 0.2180.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.
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Databricks OAuth tokens result
3
+ */
4
+ export interface DatabricksOAuthTokens {
5
+ accessToken: string;
6
+ refreshToken: string;
7
+ expiresAt: number;
8
+ }
9
+ /**
10
+ * Perform Databricks U2M OAuth flow
11
+ * Opens browser for user authentication and exchanges authorization code for tokens
12
+ * @param host Databricks workspace host
13
+ * @param clientId OAuth client ID (defaults to 'databricks-cli')
14
+ */
15
+ export declare const performDatabricksOAuthFlow: (host: string, clientId: string, clientSecret: string | undefined) => Promise<DatabricksOAuthTokens>;
16
+ //# sourceMappingURL=oauth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../../../src/dbt/targets/Databricks/oauth.ts"],"names":[],"mappings":"AAQA;;GAEG;AACH,MAAM,WAAW,qBAAqB;IAClC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACrB;AAED;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,SAC7B,MAAM,YACF,MAAM,gBACF,MAAM,GAAG,SAAS,KACjC,OAAO,CAAC,qBAAqB,CAuM/B,CAAC"}
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.performDatabricksOAuthFlow = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const common_1 = require("@lightdash/common");
6
+ const http = tslib_1.__importStar(require("http"));
7
+ const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
8
+ const openid_client_1 = require("openid-client");
9
+ const url_1 = require("url");
10
+ const globalState_1 = tslib_1.__importDefault(require("../../../globalState"));
11
+ const oauth_1 = require("../../../handlers/login/oauth");
12
+ /**
13
+ * Perform Databricks U2M OAuth flow
14
+ * Opens browser for user authentication and exchanges authorization code for tokens
15
+ * @param host Databricks workspace host
16
+ * @param clientId OAuth client ID (defaults to 'databricks-cli')
17
+ */
18
+ const performDatabricksOAuthFlow = async (host, clientId, clientSecret) => {
19
+ // Create a promise that will be resolved when we get the authorization code
20
+ let resolveAuth;
21
+ let rejectAuth;
22
+ const authPromise = new Promise((resolve, reject) => {
23
+ resolveAuth = resolve;
24
+ rejectAuth = reject;
25
+ });
26
+ let port = 0;
27
+ // Generate PKCE values
28
+ const codeVerifier = openid_client_1.generators.codeVerifier();
29
+ const codeChallenge = openid_client_1.generators.codeChallenge(codeVerifier);
30
+ const state = openid_client_1.generators.state();
31
+ // Create HTTP server to handle the callback at root path
32
+ const server = http.createServer((req, res) => {
33
+ const callbackUrl = new url_1.URL(req.url || '/', `http://localhost:${port}`);
34
+ const code = callbackUrl.searchParams.get('code');
35
+ const returnedState = callbackUrl.searchParams.get('state');
36
+ const error = callbackUrl.searchParams.get('error');
37
+ res.setHeader('Content-Type', 'text/html');
38
+ if (error === 'access_denied') {
39
+ rejectAuth(new common_1.AuthorizationError(`OAuth error: access denied`));
40
+ res.writeHead(400);
41
+ res.end('<html><body><h1>Authentication Failed</h1><p>Access denied. You can close this window.</p></body></html>');
42
+ return;
43
+ }
44
+ if (error) {
45
+ rejectAuth(new common_1.AuthorizationError(`OAuth error: ${error}`));
46
+ res.writeHead(400);
47
+ res.end(`<html><body><h1>Authentication Failed</h1><p>Error: ${error}</p></body></html>`);
48
+ return;
49
+ }
50
+ if (!code || !returnedState) {
51
+ rejectAuth(new common_1.AuthorizationError('Missing authorization code or state'));
52
+ res.writeHead(400);
53
+ res.end('<html><body><h1>Authentication Failed</h1><p>Missing authorization code or state.</p></body></html>');
54
+ return;
55
+ }
56
+ if (returnedState !== state) {
57
+ rejectAuth(new common_1.AuthorizationError('Authentication session expired or invalid'));
58
+ res.writeHead(400);
59
+ res.end('<html><body><h1>Authentication Failed</h1><p>Session expired or invalid. Please close this window and try again.</p></body></html>');
60
+ return;
61
+ }
62
+ // Success - resolve the promise
63
+ resolveAuth({ code, state: returnedState });
64
+ res.writeHead(200);
65
+ res.end('<html><body><h1>Authentication Successful</h1><p>You can close this window and return to the CLI.</p></body></html>');
66
+ });
67
+ // Start the server on port 8020 (standard for Databricks CLI)
68
+ const preferredPort = 8020;
69
+ await new Promise((resolve, reject) => {
70
+ server.on('error', (err) => {
71
+ // perhaps 8020 port is busy, but we can't use a random port
72
+ reject(err);
73
+ });
74
+ server.listen(preferredPort, () => {
75
+ const address = server.address();
76
+ if (address === null)
77
+ throw new Error('Failed to get server address');
78
+ if (typeof address === 'object') {
79
+ port = address.port;
80
+ }
81
+ else {
82
+ port = parseInt(address.toString(), 10);
83
+ }
84
+ globalState_1.default.debug(`> OAuth callback server listening on port ${port}`);
85
+ resolve();
86
+ });
87
+ });
88
+ const redirectUri = `http://localhost:${port}`;
89
+ globalState_1.default.debug(`> Starting CLI callback server on URI: ${redirectUri}`);
90
+ try {
91
+ // Build Databricks authorization URL
92
+ const authUrl = new url_1.URL('/oidc/v1/authorize', `https://${host}`);
93
+ authUrl.searchParams.set('client_id', clientId);
94
+ authUrl.searchParams.set('redirect_uri', redirectUri);
95
+ authUrl.searchParams.set('response_type', 'code');
96
+ authUrl.searchParams.set('scope', 'all-apis offline_access');
97
+ authUrl.searchParams.set('code_challenge', codeChallenge);
98
+ authUrl.searchParams.set('code_challenge_method', 'S256');
99
+ authUrl.searchParams.set('state', state);
100
+ console.error(`\n🔐 Databricks Authentication`);
101
+ console.error(`Opening browser for authentication...`);
102
+ console.error(`If the browser doesn't open automatically, please visit:`);
103
+ console.error(`${authUrl.href}\n`);
104
+ // Try to open the browser
105
+ await (0, oauth_1.openBrowser)(authUrl.href);
106
+ // Wait for the authorization code
107
+ const { code } = await authPromise;
108
+ globalState_1.default.debug(`> Got authorization code ${code.substring(0, 10)}...`);
109
+ // Exchange the authorization code for tokens
110
+ const tokenUrl = new url_1.URL('/oidc/v1/token', `https://${host}`);
111
+ // Build token request parameters
112
+ const tokenParams = {
113
+ grant_type: 'authorization_code',
114
+ code,
115
+ client_id: clientId,
116
+ redirect_uri: redirectUri,
117
+ code_verifier: codeVerifier,
118
+ };
119
+ // For confidential clients (custom OAuth apps), include client_secret
120
+ if (clientSecret) {
121
+ tokenParams.client_secret = clientSecret;
122
+ }
123
+ const tokenResponse = await (0, node_fetch_1.default)(tokenUrl.href, {
124
+ method: 'POST',
125
+ headers: {
126
+ 'Content-Type': 'application/x-www-form-urlencoded',
127
+ },
128
+ body: new URLSearchParams(tokenParams),
129
+ });
130
+ if (!tokenResponse.ok) {
131
+ const errorText = await tokenResponse.text();
132
+ throw new common_1.AuthorizationError(`Token exchange failed: ${tokenResponse.status} ${errorText}`);
133
+ }
134
+ const tokenData = (await tokenResponse.json());
135
+ const accessToken = tokenData.access_token;
136
+ const refreshToken = tokenData.refresh_token;
137
+ const expiresIn = tokenData.expires_in;
138
+ if (!accessToken || !refreshToken) {
139
+ throw new common_1.AuthorizationError('No access token or refresh token received from Databricks');
140
+ }
141
+ globalState_1.default.debug(`> OAuth access token: ${accessToken.substring(0, 10)}...`);
142
+ globalState_1.default.debug(`> OAuth refresh token: ${refreshToken.substring(0, 10)}...`);
143
+ // Calculate expiration timestamp (current time + expires_in)
144
+ const expiresAt = Math.floor(Date.now() / 1000) + expiresIn;
145
+ return {
146
+ accessToken,
147
+ refreshToken,
148
+ expiresAt,
149
+ };
150
+ }
151
+ finally {
152
+ // Clean up the server
153
+ server.close();
154
+ }
155
+ };
156
+ exports.performDatabricksOAuthFlow = performDatabricksOAuthFlow;
@@ -16,6 +16,8 @@ export type DatabricksTarget = {
16
16
  auth_type?: 'token' | 'oauth';
17
17
  client_id?: string;
18
18
  client_secret?: string;
19
+ access_token?: string;
20
+ refresh_token?: string;
19
21
  threads?: number;
20
22
  compute?: DatabricksComputeConfig;
21
23
  };
@@ -1 +1 @@
1
- {"version":3,"file":"databricks.d.ts","sourceRoot":"","sources":["../../../src/dbt/targets/databricks.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,2BAA2B,EAI9B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AAGrC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,KAAK,uBAAuB,GAAG;IAC3B,CAAC,IAAI,EAAE,MAAM,GAAG;QACZ,SAAS,EAAE,MAAM,CAAC;KACrB,CAAC;CACL,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC3B,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAElB,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,SAAS,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,uBAAuB,CAAC;CACrC,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,cAAc,CAAC,gBAAgB,CAyD7D,CAAC;AAEF,eAAO,MAAM,uBAAuB,WACxB,MAAM,KACf,2BA+DF,CAAC"}
1
+ {"version":3,"file":"databricks.d.ts","sourceRoot":"","sources":["../../../src/dbt/targets/databricks.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,2BAA2B,EAI9B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,KAAK,CAAC;AAGrC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,KAAK,uBAAuB,GAAG;IAC3B,CAAC,IAAI,EAAE,MAAM,GAAG;QACZ,SAAS,EAAE,MAAM,CAAC;KACrB,CAAC;CACL,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC3B,IAAI,EAAE,YAAY,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAElB,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,SAAS,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,uBAAuB,CAAC;CACrC,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,cAAc,CAAC,gBAAgB,CAqE7D,CAAC;AAEF,eAAO,MAAM,uBAAuB,WACxB,MAAM,KACf,2BA6EF,CAAC"}
@@ -42,6 +42,18 @@ exports.databricksSchema = {
42
42
  type: 'string',
43
43
  nullable: true,
44
44
  },
45
+ access_token: {
46
+ type: 'string',
47
+ nullable: true,
48
+ },
49
+ refresh_token: {
50
+ type: 'string',
51
+ nullable: true,
52
+ },
53
+ oauth_client_id: {
54
+ type: 'string',
55
+ nullable: true,
56
+ },
45
57
  threads: {
46
58
  type: 'number',
47
59
  nullable: true,
@@ -70,19 +82,33 @@ const convertDatabricksSchema = (target) => {
70
82
  throw new common_1.ParseError(`Couldn't read profiles.yml file for ${target.type}:\n${errs}`);
71
83
  }
72
84
  const authType = target.auth_type || 'token';
73
- // OAuth M2M authentication
85
+ // OAuth authentication
74
86
  if (authType === 'oauth') {
75
- if (!target.client_id || !target.client_secret) {
76
- throw new common_1.ParseError('Databricks OAuth authentication requires client_id and client_secret in profiles.yml');
87
+ // Determine authentication type: check env var first, then auto-detect
88
+ let authenticationType;
89
+ const databricksOAuthEnv = process.env.DATABRICKS_OAUTH?.toLowerCase();
90
+ if (databricksOAuthEnv === 'u2m') {
91
+ // Force U2M (user-to-machine) - browser-based OAuth
92
+ authenticationType = common_1.DatabricksAuthenticationType.OAUTH_U2M;
93
+ }
94
+ else {
95
+ // Auto-detect based on presence of client credentials
96
+ // If both client_id and client_secret are present, assume M2M
97
+ // Otherwise, assume U2M (which uses PKCE and doesn't require secret)
98
+ authenticationType =
99
+ target.client_secret && target.client_id
100
+ ? common_1.DatabricksAuthenticationType.OAUTH_M2M
101
+ : common_1.DatabricksAuthenticationType.OAUTH_U2M;
77
102
  }
103
+ const clientId = target.client_id || 'dbt-databricks'; // Use the same default dbt client for databricks
78
104
  return {
79
105
  type: common_1.WarehouseTypes.DATABRICKS,
80
- authenticationType: common_1.DatabricksAuthenticationType.OAUTH_M2M,
106
+ authenticationType,
81
107
  catalog: target.catalog,
82
108
  database: target.schema,
83
109
  serverHostName: target.host,
84
110
  httpPath: target.http_path,
85
- oauthClientId: target.client_id,
111
+ oauthClientId: clientId,
86
112
  oauthClientSecret: target.client_secret,
87
113
  compute: Object.entries(target.compute || {}).map(([name, compute]) => ({
88
114
  name,
@@ -1 +1 @@
1
- {"version":3,"file":"getWarehouseClient.d.ts","sourceRoot":"","sources":["../../../src/handlers/dbt/getWarehouseClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,0BAA0B,EAQ1B,oBAAoB,EAEvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAEH,8BAA8B,EACjC,MAAM,uBAAuB,CAAC;AAsC/B,KAAK,oBAAoB,GAAG;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,eAAO,MAAM,cAAc,0DAKxB,oBAAoB,kCAKjB,CAAC;AA8HP,KAAK,yBAAyB,GAAG;IAC7B,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAC5B,eAAe,EAAE,UAAU,CAAC,OAAO,8BAA8B,CAAC,CAAC;IACnE,WAAW,EAAE,0BAA0B,CAAC;CAC3C,CAAC;AAEF,wBAA8B,kBAAkB,CAC5C,OAAO,EAAE,yBAAyB,GACnC,OAAO,CAAC,wBAAwB,CAAC,CAsInC"}
1
+ {"version":3,"file":"getWarehouseClient.d.ts","sourceRoot":"","sources":["../../../src/handlers/dbt/getWarehouseClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,0BAA0B,EAQ1B,oBAAoB,EAEvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAEH,8BAA8B,EACjC,MAAM,uBAAuB,CAAC;AAwC/B,KAAK,oBAAoB,GAAG;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,eAAO,MAAM,cAAc,0DAKxB,oBAAoB,kCAKjB,CAAC;AA8HP,KAAK,yBAAyB,GAAG;IAC7B,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,KAAK,wBAAwB,GAAG;IAC5B,eAAe,EAAE,UAAU,CAAC,OAAO,8BAA8B,CAAC,CAAC;IACnE,WAAW,EAAE,0BAA0B,CAAC;CAC3C,CAAC;AAEF,wBAA8B,kBAAkB,CAC5C,OAAO,EAAE,yBAAyB,GACnC,OAAO,CAAC,wBAAwB,CAAC,CA+KnC"}
@@ -10,7 +10,9 @@ const execa_1 = tslib_1.__importDefault(require("execa"));
10
10
  const path_1 = tslib_1.__importDefault(require("path"));
11
11
  const config_1 = require("../../config");
12
12
  const profile_1 = require("../../dbt/profile");
13
+ const oauth_1 = require("../../dbt/targets/Databricks/oauth");
13
14
  const globalState_1 = tslib_1.__importDefault(require("../../globalState"));
15
+ const styles = tslib_1.__importStar(require("../../styles"));
14
16
  const apiClient_1 = require("./apiClient");
15
17
  /**
16
18
  * Cache warehouse clients to avoid repeated authentication prompts
@@ -217,7 +219,7 @@ async function getWarehouseClient(options) {
217
219
  });
218
220
  globalState_1.default.debug(`> Using target ${target.type}`);
219
221
  credentials = await (0, profile_1.warehouseCredentialsFromDbtTarget)(target);
220
- // Exchange Databricks OAuth credentials for access token if needed
222
+ // Exchange Databricks OAuth M2M credentials for access token if needed
221
223
  if (credentials.type === common_1.WarehouseTypes.DATABRICKS &&
222
224
  credentials.authenticationType ===
223
225
  common_1.DatabricksAuthenticationType.OAUTH_M2M &&
@@ -225,8 +227,30 @@ async function getWarehouseClient(options) {
225
227
  credentials.oauthClientSecret &&
226
228
  !credentials.token) {
227
229
  globalState_1.default.debug(`> Exchanging Databricks OAuth credentials for access token`);
228
- const { accessToken } = await (0, warehouses_1.exchangeDatabricksOAuthCredentials)(credentials.serverHostName, credentials.oauthClientId, credentials.oauthClientSecret);
229
- credentials.token = accessToken;
230
+ try {
231
+ const { accessToken } = await (0, warehouses_1.exchangeDatabricksOAuthCredentials)(credentials.serverHostName, credentials.oauthClientId, credentials.oauthClientSecret);
232
+ credentials.token = accessToken;
233
+ }
234
+ catch (e) {
235
+ globalState_1.default.debug(`> Failed to exchange Databricks OAuth credentials for access token: ${(0, common_1.getErrorMessage)(e)}`);
236
+ console.warn(styles.error(`\nFailed to authenticate with Databricks using M2M OAuth (client_id and client_secret). ` +
237
+ `Perhaps you meant to use U2M OAuth instead? Set DATABRICKS_OAUTH=u2m environment variable to force U2M authentication.`));
238
+ process.exit(1);
239
+ }
240
+ }
241
+ // Handle Databricks OAuth U2M authentication
242
+ if (credentials.type === common_1.WarehouseTypes.DATABRICKS &&
243
+ credentials.authenticationType ===
244
+ common_1.DatabricksAuthenticationType.OAUTH_U2M &&
245
+ !credentials.token) {
246
+ // No tokens - perform OAuth flow (tokens kept in memory only)
247
+ console.error(`\nDatabricks OAuth authentication required for ${credentials.serverHostName}`);
248
+ const clientId = credentials.oauthClientId || 'dbt-databricks'; // Use the same default dbt client for databricks
249
+ const tokens = await (0, oauth_1.performDatabricksOAuthFlow)(credentials.serverHostName, clientId, credentials.oauthClientSecret);
250
+ // Store tokens in memory only
251
+ credentials.token = tokens.accessToken;
252
+ credentials.refreshToken = tokens.refreshToken;
253
+ console.error(`\n✓ Successfully authenticated with Databricks\n`);
230
254
  }
231
255
  // Check if we should use cached client (e.g., for auth methods requiring user interaction)
232
256
  const cacheKey = getWarehouseClientCacheKey(credentials);
@@ -0,0 +1,2 @@
1
+ export declare const openBrowser: (url: string) => Promise<void>;
2
+ //# sourceMappingURL=oauth.d.ts.map
@@ -0,0 +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,IAAI,CAc3D,CAAC"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ // Helper function to open browser
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.openBrowser = void 0;
5
+ const tslib_1 = require("tslib");
6
+ const child_process_1 = require("child_process");
7
+ const util_1 = require("util");
8
+ const globalState_1 = tslib_1.__importDefault(require("../../globalState"));
9
+ const execAsync = (0, util_1.promisify)(child_process_1.exec);
10
+ const openBrowser = async (url) => {
11
+ try {
12
+ const { platform } = process;
13
+ if (platform === 'darwin') {
14
+ await execAsync(`open "${url}"`);
15
+ }
16
+ else if (platform === 'win32') {
17
+ await execAsync(`start "${url}"`);
18
+ }
19
+ else {
20
+ await execAsync(`xdg-open "${url}"`);
21
+ }
22
+ }
23
+ catch (error) {
24
+ globalState_1.default.debug(`> Could not open browser automatically: ${error}`);
25
+ }
26
+ };
27
+ exports.openBrowser = openBrowser;
@@ -1 +1 @@
1
- {"version":3,"file":"oauthLogin.d.ts","sourceRoot":"","sources":["../../src/handlers/oauthLogin.ts"],"names":[],"mappings":"AAkCA,eAAO,MAAM,cAAc,QAClB,MAAM,KACZ,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CA8OvE,CAAC"}
1
+ {"version":3,"file":"oauthLogin.d.ts","sourceRoot":"","sources":["../../src/handlers/oauthLogin.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,cAAc,QAClB,MAAM,KACZ,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CA8OvE,CAAC"}
@@ -3,34 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.loginWithOauth = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const common_1 = require("@lightdash/common");
6
- const child_process_1 = require("child_process");
7
6
  const http = tslib_1.__importStar(require("http"));
8
7
  const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
9
8
  const openid_client_1 = require("openid-client");
10
9
  const url_1 = require("url");
11
- const util_1 = require("util");
12
10
  const globalState_1 = tslib_1.__importDefault(require("../globalState"));
13
11
  const styles = tslib_1.__importStar(require("../styles"));
12
+ const oauth_1 = require("./login/oauth");
14
13
  const pat_1 = require("./login/pat");
15
- const execAsync = (0, util_1.promisify)(child_process_1.exec);
16
- // Helper function to open browser
17
- const openBrowser = async (url) => {
18
- try {
19
- const { platform } = process;
20
- if (platform === 'darwin') {
21
- await execAsync(`open "${url}"`);
22
- }
23
- else if (platform === 'win32') {
24
- await execAsync(`start "${url}"`);
25
- }
26
- else {
27
- await execAsync(`xdg-open "${url}"`);
28
- }
29
- }
30
- catch (error) {
31
- globalState_1.default.debug(`> Could not open browser automatically: ${error}`);
32
- }
33
- };
34
14
  const loginWithOauth = async (url) => {
35
15
  // Create a promise that will be resolved when we get the authorization code
36
16
  let resolveAuth;
@@ -141,7 +121,7 @@ const loginWithOauth = async (url) => {
141
121
  console.error(`If the browser doesn't open automatically, please visit:`);
142
122
  console.error(`${styles.secondary(authUrl)}\n`);
143
123
  // Try to open the browser
144
- await openBrowser(authUrl);
124
+ await (0, oauth_1.openBrowser)(authUrl);
145
125
  // Wait for the authorization code
146
126
  const { code } = await authPromise;
147
127
  globalState_1.default.debug(`> Got authorization code ${code.substring(0, 10)}...`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightdash/cli",
3
- "version": "0.2179.1",
3
+ "version": "0.2180.0",
4
4
  "license": "MIT",
5
5
  "bin": {
6
6
  "lightdash": "dist/index.js"
@@ -33,8 +33,8 @@
33
33
  "parse-node-version": "^2.0.0",
34
34
  "unique-names-generator": "^4.7.1",
35
35
  "uuid": "^11.0.3",
36
- "@lightdash/common": "0.2179.1",
37
- "@lightdash/warehouses": "0.2179.1"
36
+ "@lightdash/common": "0.2180.0",
37
+ "@lightdash/warehouses": "0.2180.0"
38
38
  },
39
39
  "description": "Lightdash CLI tool",
40
40
  "devDependencies": {