-
Notifications
You must be signed in to change notification settings - Fork 17
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
Doc validator #427
Doc validator #427
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚢
@@ -106,6 +113,10 @@ export const systemFields = <TableName extends string>( | |||
_creationTime: v.number(), | |||
}); | |||
|
|||
export type SystemFields<TableName extends string> = ReturnType< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was going to claim that we already had this in the convex package, but turns out we don't
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah it makes sense to add to the package imo
expect(userDoc.fields._creationTime).toBeDefined(); | ||
const unionDoc = doc(schema, "unionTable"); | ||
expect(unionDoc.kind).toBe("union"); | ||
if (unionDoc.kind !== "union") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
aren't these redundant with the line above?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I had to do this for typescript to stop complaining. Would be nice if there was a type assertion/ refinement as part of vitest. let me know if you know other ways to do this
Expand<V["type"] & ObjectType<Fields>>, | ||
V["isOptional"], | ||
V["fieldPaths"] & | ||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is it possible to get a VObject<Fields>
and somehow extract out field paths from there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe? It's not a property, but fields are, but afaict we don't have a fields -> FieldPaths type utility - it's just inlined in the VObject type def. Maybe I could do ObjectType<Fields> extends ObjectType<any, any, any, infer FieldPaths> ? FieldPaths : never
or something - is that better?
@@ -129,6 +140,112 @@ export const withSystemFields = < | |||
} as Expand<T & typeof system>; | |||
}; | |||
|
|||
export type AddFieldsToValidator< | |||
V extends Validator<any, any, any>, | |||
Fields extends PropertyValidators, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens when Fields
contains fields that are also in V
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right now it's just being used for _id & _creationTime, but it's a good q. I think b/c of &
it'll either work if they're the same, or be never
?
>, | ||
>( | ||
tableName: TableName, | ||
): AddFieldsToValidator< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was going to ask if you could use something similar to the Doc
type, but nope this is a validator.
I think you could maybe assemble a Validator
out of the data model type directly (especially if we're ok losing the structure of the original validator), but seems just as hard as this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I'd love to have the original validator so you could do omit(v.doc("users").fields, ["password"])
or v.doc("users").fields.address
and still have the structure / types work out
also can you think of a better name than `typedV`?
…On Thu, Jan 30, 2025 at 3:01 PM Sarah Shader ***@***.***> wrote:
***@***.**** approved this pull request.
🚢
------------------------------
In packages/convex-helpers/validators.ts
<#427 (comment)>
:
> @@ -106,6 +113,10 @@ export const systemFields = <TableName extends string>(
_creationTime: v.number(),
});
+export type SystemFields<TableName extends string> = ReturnType<
I was going to claim that we already had this in the convex package, but
turns out we don't
------------------------------
In packages/convex-helpers/server/validators.test.ts
<#427 (comment)>
:
> + const doc = await t.query(testApi.getUnion, { docId });
+ expect(doc).toBeDefined();
+ expect(doc!._creationTime).toBeTypeOf("number");
+ expect(doc!["foo"]).toBeDefined();
+});
+
+test("doc validator adds fields", async () => {
+ const t = convexTest(schema, modules);
+ await t.mutation(testApi.toDoc, {});
+ const userDoc = doc(schema, "users");
+ expect(userDoc.fields.tokenIdentifier).toBeDefined();
+ expect(userDoc.fields._id).toBeDefined();
+ expect(userDoc.fields._creationTime).toBeDefined();
+ const unionDoc = doc(schema, "unionTable");
+ expect(unionDoc.kind).toBe("union");
+ if (unionDoc.kind !== "union") {
aren't these redundant with the line above?
------------------------------
In packages/convex-helpers/validators.ts
<#427 (comment)>
:
> @@ -129,6 +140,112 @@ export const withSystemFields = <
} as Expand<T & typeof system>;
};
+export type AddFieldsToValidator<
+ V extends Validator<any, any, any>,
+ Fields extends PropertyValidators,
+> =
+ V extends VObject<infer T, infer F, infer O>
+ ? VObject<Expand<T & ObjectType<Fields>>, Expand<F & Fields>, O>
+ : Validator<
+ Expand<V["type"] & ObjectType<Fields>>,
+ V["isOptional"],
+ V["fieldPaths"] &
+ {
is it possible to get a VObject<Fields> and somehow extract out field
paths from there?
------------------------------
In packages/convex-helpers/validators.ts
<#427 (comment)>
:
> @@ -129,6 +140,112 @@ export const withSystemFields = <
} as Expand<T & typeof system>;
};
+export type AddFieldsToValidator<
+ V extends Validator<any, any, any>,
+ Fields extends PropertyValidators,
What happens when Fields contains fields that are also in V?
------------------------------
In packages/convex-helpers/validators.ts
<#427 (comment)>
:
> + /**
+ * Generates a validator for a document, including system fields.
+ * To be used in validators when passing a full document in or out of a
+ * function.
+ * @param tableName A table named in your schema.
+ * @returns A validator that matches the schema validator, adding _id and
+ * _creationTime. If the validator was a union, it will update all documents
+ * recursively, but will currently lose the VUnion-specific type.
+ */
+ doc: <
+ TableName extends TableNamesInDataModel<
+ DataModelFromSchemaDefinition<Schema>
+ >,
+ >(
+ tableName: TableName,
+ ): AddFieldsToValidator<
Was going to ask if you could use something similar to the Doc type, but
nope this is a validator.
I think you could maybe assemble a Validator out of the data model type
directly (especially if we're ok losing the structure of the original
validator), but seems just as hard as this
—
Reply to this email directly, view it on GitHub
<#427 (review)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AACZQW7DLUQJPV4HT7EVQY32NKVMLAVCNFSM6AAAAABWGJL7YSVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHMZDKOBVGIYDENZUGQ>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
adds
doc
andtypedV
validator helpersBy submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.