Skip to content

Commit 68f3939

Browse files
author
FalkWolsky
committed
Improving Firestore Firebase Datasource 2
1 parent 97302c1 commit 68f3939

File tree

2 files changed

+89
-10
lines changed

2 files changed

+89
-10
lines changed

server/node-service/src/plugins/firebase/run.ts

Lines changed: 88 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -132,21 +132,100 @@ export async function runFirebasePlugin(
132132

133133
if (actionName === "FS.QueryFireStore") {
134134
const data = await withFirestoreCollection(async (ref) => {
135+
const structuredQuery = actionData.query;
136+
if (!structuredQuery) {
137+
throw badRequest("Missing structuredQuery in action data");
138+
}
139+
135140
let query: FirebaseFirestore.Query<FirebaseFirestore.DocumentData> = ref;
141+
142+
// Apply `where` filters
143+
if (structuredQuery.where && structuredQuery.where.fieldFilter) {
144+
const fieldFilter = structuredQuery.where.fieldFilter;
145+
const fieldPath = fieldFilter.field?.fieldPath;
146+
const operator = fieldFilter.op;
147+
const value = fieldFilter.value;
148+
149+
if (!fieldPath || !operator || value === undefined) {
150+
throw badRequest("Invalid fieldFilter in where clause");
151+
}
152+
153+
let firestoreOp: FirebaseFirestore.WhereFilterOp;
154+
switch (operator) {
155+
case "EQUAL":
156+
firestoreOp = "==";
157+
break;
158+
case "GREATER_THAN":
159+
firestoreOp = ">";
160+
break;
161+
case "LESS_THAN":
162+
firestoreOp = "<";
163+
break;
164+
case "GREATER_THAN_OR_EQUAL":
165+
firestoreOp = ">=";
166+
break;
167+
case "LESS_THAN_OR_EQUAL":
168+
firestoreOp = "<=";
169+
break;
170+
case "ARRAY_CONTAINS":
171+
firestoreOp = "array-contains";
172+
break;
173+
default:
174+
throw badRequest(`Unsupported operator: ${operator}`);
175+
}
176+
177+
const actualValue = value.integerValue ?? value.stringValue ?? value.booleanValue ?? value.doubleValue;
178+
if (actualValue === undefined) {
179+
throw badRequest("Unsupported value type in structuredQuery");
180+
}
136181

137-
// Parse Query JSON from actionData.query
138-
if (actionData.query) {
139-
for (const condition of actionData.query) {
140-
const { field, op, value } = condition;
141-
if (!field || !op || value === undefined) {
142-
throw badRequest("Invalid query condition: " + JSON.stringify(condition));
182+
query = query.where(fieldPath, firestoreOp, actualValue);
183+
}
184+
185+
// Apply `orderBy`
186+
if (structuredQuery.orderBy && Array.isArray(structuredQuery.orderBy)) {
187+
for (const order of structuredQuery.orderBy) {
188+
if (order.field && order.field.fieldPath) {
189+
query = query.orderBy(
190+
order.field.fieldPath,
191+
(order.direction || "asc") as FirebaseFirestore.OrderByDirection
192+
);
143193
}
144-
query = query.where(field, op as WhereFilterOp, value);
145194
}
146195
}
147-
148-
// Execute the query and retrieve results
196+
197+
// Apply `limit`
198+
if (structuredQuery.limit) {
199+
query = query.limit(structuredQuery.limit);
200+
}
201+
202+
// Apply `offset` (Firestore SDK doesn't support offset directly; simulate it with startAfter)
203+
if (structuredQuery.offset) {
204+
const offsetSnapshot = await query.limit(structuredQuery.offset).get();
205+
const lastVisible = offsetSnapshot.docs[offsetSnapshot.docs.length - 1];
206+
if (lastVisible) {
207+
query = query.startAfter(lastVisible);
208+
}
209+
}
210+
211+
// Apply `startAt` and `endAt` cursors, checking for undefined values
212+
if (structuredQuery.startAt && structuredQuery.startAt.values) {
213+
const startAtValues = structuredQuery.startAt.values.map((v: { integerValue: any; stringValue: any; booleanValue: any; doubleValue: any; }) => v.integerValue ?? v.stringValue ?? v.booleanValue ?? v.doubleValue).filter((value: any) => value !== undefined);
214+
if (startAtValues.length > 0) {
215+
query = query.startAt(...startAtValues);
216+
}
217+
}
218+
219+
if (structuredQuery.endAt && structuredQuery.endAt.values) {
220+
const endAtValues = structuredQuery.endAt.values.map((v: { integerValue: any; stringValue: any; booleanValue: any; doubleValue: any; }) => v.integerValue ?? v.stringValue ?? v.booleanValue ?? v.doubleValue).filter((value: any) => value !== undefined);
221+
if (endAtValues.length > 0) {
222+
query = query.endAt(...endAtValues);
223+
}
224+
}
225+
226+
// Execute the query
149227
const snapshot = await query.get();
228+
150229
if (snapshot.empty) {
151230
return [];
152231
}

server/node-service/src/plugins/openAi/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse";
88

99
const spec = readYaml(path.join(__dirname, "./openAi.yaml"));
1010
const specs = {
11-
"v1.0": spec,
11+
"v1.0": spec as OpenAPIV3.Document,
1212
}
1313

1414
const dataSourceConfig = {

0 commit comments

Comments
 (0)