-
Notifications
You must be signed in to change notification settings - Fork 1.1k
[VS Code] Edit missing variables / auth #9301
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 56 commits
3bcb8a6
ca20d04
65c3517
8eacec9
917d677
5037519
28066b4
3b198a7
8f56a02
c262070
c54d915
de2e555
0fec8de
13a45a4
264cca7
81d8321
b737bda
408ba12
b5a280d
3b2c322
70f11e6
0465394
60e602c
32ac9d6
33a3e12
78c1d5c
7704556
19e04b2
5fce3cb
e7160a4
68a4308
5c63261
47fb77e
b17202a
d18149f
c22811a
2e8baae
de80467
740f7b3
fec96f4
3ab012f
f26d990
b04ed2a
af3e7e8
9ab24dc
cdca6f2
baf8aa3
f2f428d
71b5168
fad60fe
67c60a4
ec5a264
8ea9345
1456d18
cc8021a
6e9b538
f9a4a50
2318b8f
20b5961
5050106
7d3383f
5111f04
bbfaa74
b152886
7837c69
a339a81
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
import { print, Kind, OperationDefinitionNode } from "graphql"; | ||
import { globalSignal } from "../../utils/globals"; | ||
import { getDefaultScalarValue } from "../ad-hoc-mutations"; | ||
import { AuthParams, AuthParamsKind } from "../../../common/messaging/protocol"; | ||
import { Impersonation } from "../../dataconnect/types"; | ||
import { Disposable } from "vscode"; | ||
import { ExtensionBrokerImpl } from "../../extension-broker"; | ||
import { AnalyticsLogger, DATA_CONNECT_EVENT_NAME } from "../../analytics"; | ||
|
||
/** | ||
* Contains the unparsed JSON object mutation/query variables. | ||
* The JSON may be invalid. | ||
*/ | ||
export const executionArgsJSON = globalSignal("{}"); | ||
export const executionAuthParams = globalSignal<AuthParams>({kind: AuthParamsKind.ADMIN}); | ||
|
||
export class ExecutionParamsService implements Disposable { | ||
constructor(readonly broker: ExtensionBrokerImpl, readonly analyticsLogger: AnalyticsLogger) { | ||
this.disposable.push({ | ||
dispose: broker.on( | ||
"defineAuthParams", | ||
(auth) => (executionAuthParams.value = auth) | ||
), | ||
}); | ||
this.disposable.push({ | ||
dispose: broker.on( | ||
"defineVariables", | ||
(value) => (executionArgsJSON.value = value), | ||
) | ||
}); | ||
} | ||
|
||
disposable: Disposable[] = []; | ||
|
||
dispose() { | ||
for (const disposable of this.disposable) { | ||
disposable.dispose(); | ||
} | ||
} | ||
|
||
executeGraphqlVariables(): Record<string, any> { | ||
const variables = executionArgsJSON.value; | ||
if (!variables) { | ||
return {}; | ||
} | ||
try { | ||
return JSON.parse(variables); | ||
} catch (e: any) { | ||
throw new Error( | ||
"Unable to parse variables as JSON. Check the variables pane.\n" + e.message, | ||
); | ||
} | ||
} | ||
|
||
executeGraphqlExtensions(): { impersonate?: Impersonation } { | ||
const auth = executionAuthParams.value; | ||
switch (auth.kind) { | ||
case AuthParamsKind.ADMIN: | ||
this.analyticsLogger.logger.logUsage(DATA_CONNECT_EVENT_NAME.RUN_AUTH_ADMIN); | ||
return {}; | ||
case AuthParamsKind.UNAUTHENTICATED: | ||
this.analyticsLogger.logger.logUsage(DATA_CONNECT_EVENT_NAME.RUN_AUTH_UNAUTHENTICATED); | ||
return { impersonate: { unauthenticated: true, includeDebugDetails: true } }; | ||
case AuthParamsKind.AUTHENTICATED: | ||
this.analyticsLogger.logger.logUsage(DATA_CONNECT_EVENT_NAME.RUN_AUTH_AUTHENTICATED); | ||
try { | ||
return { | ||
impersonate: | ||
{ authClaims: JSON.parse(auth.claims), includeDebugDetails: true } | ||
}; | ||
} catch (e: any) { | ||
throw new Error( | ||
"Unable to parse auth claims as JSON. Check the authentication panel.\n" + e.message, | ||
); | ||
} | ||
default: | ||
throw new Error(`Unknown auth params kind: ${auth}`); | ||
fredzqm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
|
||
async applyDetectedFixes(ast: OperationDefinitionNode): Promise<void> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It'd be great to unit test this file/function specifically, ensuring it doesn't overwrite user set varisbles. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Great suggestion. With gemini CLI's help, just added a unit test for it~ |
||
const userVars = this.executeGraphqlVariables(); | ||
const fixes = []; | ||
{ | ||
const undefinedVars = []; | ||
for (const varName in userVars) { | ||
if (!ast.variableDefinitions?.find((v) => v.variable.name.value === varName)) { | ||
delete userVars[varName]; | ||
undefinedVars.push(varName); | ||
} | ||
} | ||
if (undefinedVars.length > 0) { | ||
this.analyticsLogger.logger.logUsage(DATA_CONNECT_EVENT_NAME.RUN_UNDEFINED_VARIABLES); | ||
fixes.push(`Removed undefined variables: ${undefinedVars.map((v) => "$" + v).join(", ")}.`); | ||
} | ||
} | ||
{ | ||
const missingRequiredVars = []; | ||
for (const variable of ast.variableDefinitions || []) { | ||
const varName = variable.variable.name.value; | ||
if (variable.type.kind === Kind.NON_NULL_TYPE && userVars[varName] === undefined) { | ||
userVars[varName] = getDefaultScalarValue(print(variable.type.type)); | ||
missingRequiredVars.push(varName); | ||
} | ||
} | ||
if (missingRequiredVars.length > 0) { | ||
this.analyticsLogger.logger.logUsage(DATA_CONNECT_EVENT_NAME.RUN_MISSING_VARIABLES); | ||
fixes.push(`Included required variables: ${missingRequiredVars.map((v) => "$" + v).join(", ")}.`); | ||
} | ||
} | ||
if (fixes.length === 0) { | ||
return; | ||
} | ||
executionArgsJSON.value = JSON.stringify(userVars, null, 2); | ||
this.broker.send("notifyVariables", { variables: executionArgsJSON.value, fixes }); | ||
return; | ||
} | ||
} |
Uh oh!
There was an error while loading. Please reload this page.