Skip to content

Commit 3e431d6

Browse files
hlshenjoehanyuchenshi
authored
Update add data (#7753)
* update add data * add default uuid * update default uuid * Update firebase-vscode/src/data-connect/ad-hoc-mutations.ts Co-authored-by: Yuchen Shi <[email protected]> * Update firebase-vscode/src/data-connect/ad-hoc-mutations.ts Co-authored-by: Yuchen Shi <[email protected]> * Update firebase-vscode/src/data-connect/ad-hoc-mutations.ts Co-authored-by: Yuchen Shi <[email protected]> * address comments --------- Co-authored-by: joehan <[email protected]> Co-authored-by: Yuchen Shi <[email protected]>
1 parent 4c24ff0 commit 3e431d6

File tree

2 files changed

+90
-42
lines changed

2 files changed

+90
-42
lines changed

firebase-vscode/src/data-connect/ad-hoc-mutations.ts

Lines changed: 87 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
import vscode, { Disposable, TelemetryLogger } from "vscode";
22
import {
33
DocumentNode,
4-
GraphQLInputObjectType,
5-
GraphQLScalarType,
4+
GraphQLInputField,
65
Kind,
6+
ObjectFieldNode,
77
ObjectTypeDefinitionNode,
8+
OperationDefinitionNode,
9+
OperationTypeNode,
10+
ValueNode,
811
buildClientSchema,
9-
buildSchema,
12+
getNamedType,
13+
isInputObjectType,
14+
print,
1015
} from "graphql";
1116
import { checkIfFileExists, upsertFile } from "./file-utils";
1217
import { DataConnectService } from "./service";
@@ -135,9 +140,18 @@ query {
135140
// generate content for the file
136141
const preamble =
137142
"# This is a file for you to write an un-named mutation. \n# Only one un-named mutation is allowed per file.";
138-
const adhocMutation = await generateMutation(ast);
139-
const content = [preamble, adhocMutation].join("\n");
143+
const introspect = (await dataConnectService.introspect())?.data;
144+
const schema = buildClientSchema(introspect!);
145+
const dataType = schema.getType(`${ast.name.value}_Data`);
146+
if (!isInputObjectType(dataType)) return;
140147

148+
const adhocMutation = print(
149+
await makeAdHocMutation(
150+
Object.values(dataType.getFields()),
151+
ast.name.value,
152+
),
153+
);
154+
const content = [preamble, adhocMutation].join("\n");
141155
const basePath = vscode.workspace.rootPath + "/dataconnect/";
142156
const filePath = vscode.Uri.file(`${basePath}${ast.name.value}_insert.gql`);
143157
const doesFileExist = await checkIfFileExists(filePath);
@@ -162,46 +176,78 @@ query {
162176
}
163177
}
164178

165-
async function generateMutation(
166-
ast: ObjectTypeDefinitionNode,
167-
): Promise<string> {
168-
const introspect = (await dataConnectService.introspect())?.data;
169-
const schema = buildClientSchema(introspect!);
179+
function makeAdHocMutation(
180+
fields: GraphQLInputField[],
181+
singularName: string,
182+
): OperationDefinitionNode {
183+
const argumentFields: ObjectFieldNode[] = [];
170184

171-
const name = ast.name.value;
172-
const lowerCaseName =
173-
ast.name.value.charAt(0).toLowerCase() + ast.name.value.slice(1);
174-
const dataName = `${name}_Data`;
175-
const mutationDataType: GraphQLInputObjectType = schema.getTypeMap()[
176-
dataName
177-
] as GraphQLInputObjectType;
178-
179-
// build mutation as string
180-
const functionSpacing = "\t";
181-
const fieldSpacing = "\t\t";
182-
const mutation = [];
183-
mutation.push("mutation {"); // mutation header
184-
mutation.push(`${functionSpacing}${lowerCaseName}_insert(data: {`);
185-
for (const [fieldName, field] of Object.entries(
186-
mutationDataType.getFields(),
187-
)) {
188-
// necessary to avoid type error
189-
const fieldtype: any = field.type;
190-
// use all argument types that are of scalar, except x_expr
191-
if (
192-
isDataConnectScalarType(fieldtype.name) &&
193-
!field.name.includes("_expr")
194-
) {
195-
const defaultValue = (defaultScalarValues as any)[fieldtype.name] || "";
196-
mutation.push(
197-
`${fieldSpacing}${fieldName}: ${defaultValue} # ${fieldtype.name}`,
198-
); // field name + temp value + comment
199-
}
185+
for (const field of fields) {
186+
const type = getNamedType(field.type);
187+
const defaultValue = getDefaultScalarValue(type.name);
188+
if (!defaultValue) continue;
189+
190+
argumentFields.push({
191+
kind: Kind.OBJECT_FIELD,
192+
name: { kind: Kind.NAME, value: field.name },
193+
value: defaultValue,
194+
});
200195
}
201-
mutation.push(`${functionSpacing}})`, "}"); // closing braces/paren
202-
return mutation.join("\n");
196+
197+
return {
198+
kind: Kind.OPERATION_DEFINITION,
199+
operation: OperationTypeNode.MUTATION,
200+
selectionSet: {
201+
kind: Kind.SELECTION_SET,
202+
selections: [
203+
{
204+
kind: Kind.FIELD,
205+
name: { kind: Kind.NAME, value: `${singularName.charAt(0).toLowerCase()}${singularName.slice(1)}_insert` },
206+
arguments: [
207+
{
208+
kind: Kind.ARGUMENT,
209+
name: { kind: Kind.NAME, value: "data" },
210+
value: {
211+
kind: Kind.OBJECT,
212+
fields: argumentFields,
213+
},
214+
},
215+
],
216+
},
217+
],
218+
},
219+
};
203220
}
204221

222+
function getDefaultScalarValue(type: string): ValueNode | undefined {
223+
switch (type) {
224+
case "Any":
225+
return { kind: Kind.OBJECT, fields: [] };
226+
case "Boolean":
227+
return { kind: Kind.BOOLEAN, value: false };
228+
case "Date":
229+
return {
230+
kind: Kind.STRING,
231+
value: new Date().toISOString().substring(0, 10),
232+
};
233+
case "Float":
234+
return { kind: Kind.FLOAT, value: "0" };
235+
case "Int":
236+
return { kind: Kind.INT, value: "0" };
237+
case "Int64":
238+
return { kind: Kind.INT, value: "0" };
239+
case "String":
240+
return { kind: Kind.STRING, value: "" };
241+
case "Timestamp":
242+
return { kind: Kind.STRING, value: new Date().toISOString() };
243+
case "UUID":
244+
return { kind: Kind.STRING, value: "11111111222233334444555555555555" };
245+
case "Vector":
246+
return { kind: Kind.LIST, values: [] };
247+
default:
248+
return undefined;
249+
}
250+
}
205251
return Disposable.from(
206252
vscode.commands.registerCommand(
207253
"firebase.dataConnect.schemaAddData",

firebase-vscode/src/data-connect/terminal.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ export function runTerminalTask(
4444
resolve(`Successfully executed ${taskName} with command: ${command}`);
4545
} else {
4646
reject(
47-
new Error(`Failed to execute ${taskName} with command: ${command}`),
47+
new Error(
48+
`{${e.exitCode}}: Failed to execute ${taskName} with command: ${command}`,
49+
),
4850
);
4951
}
5052
}

0 commit comments

Comments
 (0)