diff --git a/examples/ent-rsvp/backend/src/graphql/generated/mutations/address/address_create_type.ts b/examples/ent-rsvp/backend/src/graphql/generated/mutations/address/address_create_type.ts index 5d0954fdc..0519a92c2 100644 --- a/examples/ent-rsvp/backend/src/graphql/generated/mutations/address/address_create_type.ts +++ b/examples/ent-rsvp/backend/src/graphql/generated/mutations/address/address_create_type.ts @@ -90,7 +90,7 @@ export const AddressCreateType: GraphQLFieldConfig< state: input.state, zipCode: input.zipCode, apartment: input.apartment, - ownerId: mustDecodeIDFromGQLID(input.ownerId), + ownerId: mustDecodeIDFromGQLID(input.ownerId.toString()), ownerType: input.ownerType, }).saveX(); return { address: address }; diff --git a/examples/ent-rsvp/backend/src/graphql/generated/mutations/address/address_edit_type.ts b/examples/ent-rsvp/backend/src/graphql/generated/mutations/address/address_edit_type.ts index 0b0d476af..9dd0c4a0e 100644 --- a/examples/ent-rsvp/backend/src/graphql/generated/mutations/address/address_edit_type.ts +++ b/examples/ent-rsvp/backend/src/graphql/generated/mutations/address/address_edit_type.ts @@ -101,7 +101,9 @@ export const AddressEditType: GraphQLFieldConfig< state: input.state, zipCode: input.zipCode, apartment: input.apartment, - ownerId: mustDecodeNullableIDFromGQLID(input.ownerId), + ownerId: mustDecodeNullableIDFromGQLID( + input.ownerId?.toString() ?? input.ownerId, + ), ownerType: input.ownerType, }, ); diff --git a/examples/ent-rsvp/backend/src/graphql/generated/mutations/event_activity/event_activity_create_type.ts b/examples/ent-rsvp/backend/src/graphql/generated/mutations/event_activity/event_activity_create_type.ts index 38577c672..a7c690b23 100644 --- a/examples/ent-rsvp/backend/src/graphql/generated/mutations/event_activity/event_activity_create_type.ts +++ b/examples/ent-rsvp/backend/src/graphql/generated/mutations/event_activity/event_activity_create_type.ts @@ -120,9 +120,11 @@ export const EventActivityCreateType: GraphQLFieldConfig< const eventActivity = await CreateEventActivityAction.create( context.getViewer(), { - addressId: mustDecodeNullableIDFromGQLID(input.addressId), + addressId: mustDecodeNullableIDFromGQLID( + input.addressId?.toString() ?? input.addressId, + ), name: input.name, - eventId: mustDecodeIDFromGQLID(input.eventId), + eventId: mustDecodeIDFromGQLID(input.eventId.toString()), startTime: input.startTime, endTime: input.endTime, location: input.location, diff --git a/examples/ent-rsvp/backend/src/graphql/generated/mutations/event_activity/event_activity_edit_type.ts b/examples/ent-rsvp/backend/src/graphql/generated/mutations/event_activity/event_activity_edit_type.ts index a3951450d..ca51b305b 100644 --- a/examples/ent-rsvp/backend/src/graphql/generated/mutations/event_activity/event_activity_edit_type.ts +++ b/examples/ent-rsvp/backend/src/graphql/generated/mutations/event_activity/event_activity_edit_type.ts @@ -102,9 +102,13 @@ export const EventActivityEditType: GraphQLFieldConfig< context.getViewer(), mustDecodeIDFromGQLID(input.id), { - addressId: mustDecodeNullableIDFromGQLID(input.addressId), + addressId: mustDecodeNullableIDFromGQLID( + input.addressId?.toString() ?? input.addressId, + ), name: input.name, - eventId: mustDecodeNullableIDFromGQLID(input.eventId), + eventId: mustDecodeNullableIDFromGQLID( + input.eventId?.toString() ?? input.eventId, + ), startTime: input.startTime, endTime: input.endTime, location: input.location, diff --git a/examples/ent-rsvp/backend/src/graphql/generated/mutations/event_activity/event_activity_rsvp_status_edit_type.ts b/examples/ent-rsvp/backend/src/graphql/generated/mutations/event_activity/event_activity_rsvp_status_edit_type.ts index 30d19a0c5..c8daa6f26 100644 --- a/examples/ent-rsvp/backend/src/graphql/generated/mutations/event_activity/event_activity_rsvp_status_edit_type.ts +++ b/examples/ent-rsvp/backend/src/graphql/generated/mutations/event_activity/event_activity_rsvp_status_edit_type.ts @@ -84,7 +84,7 @@ export const EventActivityRsvpStatusEditType: GraphQLFieldConfig< mustDecodeIDFromGQLID(input.id), { rsvpStatus: input.rsvpStatus, - guestId: mustDecodeIDFromGQLID(input.guestId), + guestId: mustDecodeIDFromGQLID(input.guestId.toString()), dietaryRestrictions: input.dietaryRestrictions, }, ); diff --git a/examples/ent-rsvp/backend/src/graphql/generated/mutations/guest/guest_create_type.ts b/examples/ent-rsvp/backend/src/graphql/generated/mutations/guest/guest_create_type.ts index a48c47bef..278deb5f6 100644 --- a/examples/ent-rsvp/backend/src/graphql/generated/mutations/guest/guest_create_type.ts +++ b/examples/ent-rsvp/backend/src/graphql/generated/mutations/guest/guest_create_type.ts @@ -94,13 +94,17 @@ export const GuestCreateType: GraphQLFieldConfig< _info: GraphQLResolveInfo, ): Promise => { const guest = await CreateGuestAction.create(context.getViewer(), { - addressId: mustDecodeNullableIDFromGQLID(input.addressId), + addressId: mustDecodeNullableIDFromGQLID( + input.addressId?.toString() ?? input.addressId, + ), name: input.name, - eventId: mustDecodeIDFromGQLID(input.eventId), + eventId: mustDecodeIDFromGQLID(input.eventId.toString()), emailAddress: input.emailAddress, - guestGroupId: mustDecodeIDFromGQLID(input.guestGroupId), + guestGroupId: mustDecodeIDFromGQLID(input.guestGroupId.toString()), title: input.title, - guestDataId: mustDecodeNullableIDFromGQLID(input.guestDataId), + guestDataId: mustDecodeNullableIDFromGQLID( + input.guestDataId?.toString() ?? input.guestDataId, + ), tag: input.tag, }).saveX(); return { guest: guest }; diff --git a/examples/ent-rsvp/backend/src/graphql/generated/mutations/guest_group/guest_group_create_type.ts b/examples/ent-rsvp/backend/src/graphql/generated/mutations/guest_group/guest_group_create_type.ts index 64c59b1e3..73c763ba7 100644 --- a/examples/ent-rsvp/backend/src/graphql/generated/mutations/guest_group/guest_group_create_type.ts +++ b/examples/ent-rsvp/backend/src/graphql/generated/mutations/guest_group/guest_group_create_type.ts @@ -104,7 +104,7 @@ export const GuestGroupCreateType: GraphQLFieldConfig< context.getViewer(), { invitationName: input.invitationName, - eventId: mustDecodeIDFromGQLID(input.eventId), + eventId: mustDecodeIDFromGQLID(input.eventId.toString()), tag: input.tag, guests: input.guests, }, diff --git a/examples/ent-rsvp/backend/src/graphql/generated/mutations/import_guests_type.ts b/examples/ent-rsvp/backend/src/graphql/generated/mutations/import_guests_type.ts index dcfeead20..b178cbe82 100644 --- a/examples/ent-rsvp/backend/src/graphql/generated/mutations/import_guests_type.ts +++ b/examples/ent-rsvp/backend/src/graphql/generated/mutations/import_guests_type.ts @@ -42,7 +42,7 @@ export const ImportGuestsType: GraphQLFieldConfig< const r = new ImportGuestResolver(); return r.importGuests( context, - mustDecodeIDFromGQLID(args.eventId), + mustDecodeIDFromGQLID(args.eventId.toString()), args.file, ); }, diff --git a/examples/ent-rsvp/backend/src/graphql/generated/resolvers/event_activity_type.ts b/examples/ent-rsvp/backend/src/graphql/generated/resolvers/event_activity_type.ts index 04fce2938..24f3219bc 100644 --- a/examples/ent-rsvp/backend/src/graphql/generated/resolvers/event_activity_type.ts +++ b/examples/ent-rsvp/backend/src/graphql/generated/resolvers/event_activity_type.ts @@ -65,7 +65,7 @@ class EventActivityCanViewerDo { { ...args, rsvpStatus: args.rsvpStatus, - guestId: mustDecodeIDFromGQLID(args.guestId), + guestId: mustDecodeIDFromGQLID(args.guestId.toString()), dietaryRestrictions: args.dietaryRestrictions, }, ); diff --git a/examples/ent-rsvp/backend/src/graphql/generated/resolvers/with_address_type.ts b/examples/ent-rsvp/backend/src/graphql/generated/resolvers/with_address_type.ts index 18240d1b4..ef666f265 100644 --- a/examples/ent-rsvp/backend/src/graphql/generated/resolvers/with_address_type.ts +++ b/examples/ent-rsvp/backend/src/graphql/generated/resolvers/with_address_type.ts @@ -5,5 +5,5 @@ import { EventActivityType, GuestType } from "src/graphql/resolvers/internal"; export const WithAddressType = new GraphQLUnionType({ name: "WithAddress", - types: () => [EventActivityType, GuestType], + types: () => [GuestType, EventActivityType], }); diff --git a/examples/simple/src/ent/generated/types.ts b/examples/simple/src/ent/generated/types.ts index a8dfbb1ff..4952d2c06 100644 --- a/examples/simple/src/ent/generated/types.ts +++ b/examples/simple/src/ent/generated/types.ts @@ -4,9 +4,6 @@ */ import { ID } from "@snowtop/ent"; -import { Builder } from "@snowtop/ent/action"; -import { File } from ".."; -import { ExampleViewer as ExampleViewerAlias } from "../../viewer/viewer"; export enum NodeType { // Address is the node type for the Address object. Used to identify this node in edges and other places. @@ -731,8 +728,8 @@ export function convertNullableUserPreferredShiftList( } export interface Attachment { - fileId: ID | Builder; - dupeFileId?: ID | null | Builder; + fileId: ID; + dupeFileId?: ID | null; note?: string | null; date: Date; phoneNumber?: string | null; @@ -827,6 +824,8 @@ export interface UserPrefsStruct { finishedNux?: boolean | null; enableNotifs?: boolean | null; notifTypes: NotifType[]; + homeAddressId?: ID | null; + allAddressIds?: ID[] | null; } export function convertUserPrefsStruct(input: any): UserPrefsStruct { @@ -834,6 +833,8 @@ export function convertUserPrefsStruct(input: any): UserPrefsStruct { finishedNux: input.finished_nux, enableNotifs: input.enable_notifs, notifTypes: input.notif_types, + homeAddressId: input.home_address_id, + allAddressIds: input.all_address_ids, }; } diff --git a/examples/simple/src/ent/tests/user.test.ts b/examples/simple/src/ent/tests/user.test.ts index 7e6d8fb7d..e032ef1f8 100644 --- a/examples/simple/src/ent/tests/user.test.ts +++ b/examples/simple/src/ent/tests/user.test.ts @@ -1092,12 +1092,12 @@ test("jsonb types", async () => { }, ], }).saveX(); - expect(await user.prefs()).toStrictEqual({ + expect(await user.prefs()).toMatchObject({ enableNotifs: undefined, finishedNux: true, notifTypes: [NotifType.EMAIL], }); - expect(await user.prefsList()).toStrictEqual([ + expect(await user.prefsList()).toMatchObject([ { enableNotifs: undefined, finishedNux: true, diff --git a/examples/simple/src/graphql/generated/mutations/bulk_upload_contact_type.ts b/examples/simple/src/graphql/generated/mutations/bulk_upload_contact_type.ts index cdd37e4cd..cd3b09ece 100644 --- a/examples/simple/src/graphql/generated/mutations/bulk_upload_contact_type.ts +++ b/examples/simple/src/graphql/generated/mutations/bulk_upload_contact_type.ts @@ -57,7 +57,7 @@ export const BulkUploadContactType: GraphQLFieldConfig< const r = new ImportContactResolver(); return r.bulkUploadContact( context, - mustDecodeIDFromGQLID(args.userId), + mustDecodeIDFromGQLID(args.userId.toString()), args.file, args.defaultLabel, args.defaultLabel2, diff --git a/examples/simple/src/graphql/generated/mutations/comment/comment_create_type.ts b/examples/simple/src/graphql/generated/mutations/comment/comment_create_type.ts index 1c297b376..87e49b36a 100644 --- a/examples/simple/src/graphql/generated/mutations/comment/comment_create_type.ts +++ b/examples/simple/src/graphql/generated/mutations/comment/comment_create_type.ts @@ -98,13 +98,17 @@ export const CommentCreateType: GraphQLFieldConfig< _info: GraphQLResolveInfo, ): Promise => { const comment = await CreateCommentAction.create(context.getViewer(), { - authorId: mustDecodeIDFromGQLID(input.authorId), + authorId: mustDecodeIDFromGQLID(input.authorId.toString()), body: input.body, - articleId: mustDecodeIDFromGQLID(input.articleId), + articleId: mustDecodeIDFromGQLID(input.articleId.toString()), articleType: input.articleType, - attachmentId: mustDecodeNullableIDFromGQLID(input.attachmentId), + attachmentId: mustDecodeNullableIDFromGQLID( + input.attachmentId?.toString() ?? input.attachmentId, + ), attachmentType: input.attachmentType, - stickerId: mustDecodeNullableIDFromGQLID(input.stickerId), + stickerId: mustDecodeNullableIDFromGQLID( + input.stickerId?.toString() ?? input.stickerId, + ), stickerType: input.stickerType, }).saveX(); return { comment: comment }; diff --git a/examples/simple/src/graphql/generated/mutations/comment/comment_edit_type.ts b/examples/simple/src/graphql/generated/mutations/comment/comment_edit_type.ts index 8a77d602a..52c9e4dca 100644 --- a/examples/simple/src/graphql/generated/mutations/comment/comment_edit_type.ts +++ b/examples/simple/src/graphql/generated/mutations/comment/comment_edit_type.ts @@ -103,11 +103,17 @@ export const CommentEditType: GraphQLFieldConfig< mustDecodeIDFromGQLID(input.id), { body: input.body, - articleId: mustDecodeNullableIDFromGQLID(input.articleId), + articleId: mustDecodeNullableIDFromGQLID( + input.articleId?.toString() ?? input.articleId, + ), articleType: input.articleType, - attachmentId: mustDecodeNullableIDFromGQLID(input.attachmentId), + attachmentId: mustDecodeNullableIDFromGQLID( + input.attachmentId?.toString() ?? input.attachmentId, + ), attachmentType: input.attachmentType, - stickerId: mustDecodeNullableIDFromGQLID(input.stickerId), + stickerId: mustDecodeNullableIDFromGQLID( + input.stickerId?.toString() ?? input.stickerId, + ), stickerType: input.stickerType, }, ); diff --git a/examples/simple/src/graphql/generated/mutations/contact/contact_create_type.ts b/examples/simple/src/graphql/generated/mutations/contact/contact_create_type.ts index 003521b21..0d391c8dd 100644 --- a/examples/simple/src/graphql/generated/mutations/contact/contact_create_type.ts +++ b/examples/simple/src/graphql/generated/mutations/contact/contact_create_type.ts @@ -16,7 +16,10 @@ import { GraphQLString, } from "graphql"; import { RequestContext } from "@snowtop/ent"; -import { mustDecodeIDFromGQLID } from "@snowtop/ent/graphql"; +import { + mustDecodeIDFromGQLID, + mustDecodeNullableIDFromGQLID, +} from "@snowtop/ent/graphql"; import { Contact } from "../../../../ent"; import CreateContactAction, { ContactCreateInput, @@ -127,8 +130,16 @@ export const ContactCreateType: GraphQLFieldConfig< const contact = await CreateContactAction.create(context.getViewer(), { firstName: input.firstName, lastName: input.lastName, - userId: mustDecodeIDFromGQLID(input.userId), - attachments: input.attachments, + userId: mustDecodeIDFromGQLID(input.userId.toString()), + attachments: input.attachments?.map((item: any) => ({ + ...item, + fileId: mustDecodeIDFromGQLID(item.fileId.toString()), + dupeFileId: item.dupeFileId + ? mustDecodeNullableIDFromGQLID( + item.dupeFileId?.toString() ?? item.dupeFileId, + ) + : undefined, + })), emails: input.emails, phoneNumbers: input.phoneNumbers, }).saveX(); diff --git a/examples/simple/src/graphql/generated/mutations/contact/contact_edit_type.ts b/examples/simple/src/graphql/generated/mutations/contact/contact_edit_type.ts index 0125ed6ba..7c7b5eb53 100644 --- a/examples/simple/src/graphql/generated/mutations/contact/contact_edit_type.ts +++ b/examples/simple/src/graphql/generated/mutations/contact/contact_edit_type.ts @@ -16,7 +16,10 @@ import { GraphQLString, } from "graphql"; import { RequestContext } from "@snowtop/ent"; -import { mustDecodeIDFromGQLID } from "@snowtop/ent/graphql"; +import { + mustDecodeIDFromGQLID, + mustDecodeNullableIDFromGQLID, +} from "@snowtop/ent/graphql"; import { Contact } from "../../../../ent"; import EditContactAction, { ContactEditInput, @@ -115,14 +118,24 @@ export const ContactEditType: GraphQLFieldConfig< mustDecodeIDFromGQLID(input.id), { emailIds: input.emailIds - ? input.emailIds.map((i: any) => mustDecodeIDFromGQLID(i)) + ? input.emailIds.map((i: any) => mustDecodeIDFromGQLID(i.toString())) : undefined, phoneNumberIds: input.phoneNumberIds - ? input.phoneNumberIds.map((i: any) => mustDecodeIDFromGQLID(i)) + ? input.phoneNumberIds.map((i: any) => + mustDecodeIDFromGQLID(i.toString()), + ) : undefined, firstName: input.firstName, lastName: input.lastName, - attachments: input.attachments, + attachments: input.attachments?.map((item: any) => ({ + ...item, + fileId: mustDecodeIDFromGQLID(item.fileId.toString()), + dupeFileId: item.dupeFileId + ? mustDecodeNullableIDFromGQLID( + item.dupeFileId?.toString() ?? item.dupeFileId, + ) + : undefined, + })), emails: input.emails, }, ); diff --git a/examples/simple/src/graphql/generated/mutations/contact_email/contact_email_create_type.ts b/examples/simple/src/graphql/generated/mutations/contact_email/contact_email_create_type.ts index b07f3941a..c469f0c46 100644 --- a/examples/simple/src/graphql/generated/mutations/contact_email/contact_email_create_type.ts +++ b/examples/simple/src/graphql/generated/mutations/contact_email/contact_email_create_type.ts @@ -88,8 +88,8 @@ export const ContactEmailCreateType: GraphQLFieldConfig< context.getViewer(), { extra: input.extra, - contactId: mustDecodeIDFromGQLID(input.contactId), - ownerId: mustDecodeIDFromGQLID(input.ownerId), + contactId: mustDecodeIDFromGQLID(input.contactId.toString()), + ownerId: mustDecodeIDFromGQLID(input.ownerId.toString()), emailAddress: input.emailAddress, label: input.label, }, diff --git a/examples/simple/src/graphql/generated/mutations/contact_phone_number/contact_phone_number_create_type.ts b/examples/simple/src/graphql/generated/mutations/contact_phone_number/contact_phone_number_create_type.ts index dd9706554..804a4cace 100644 --- a/examples/simple/src/graphql/generated/mutations/contact_phone_number/contact_phone_number_create_type.ts +++ b/examples/simple/src/graphql/generated/mutations/contact_phone_number/contact_phone_number_create_type.ts @@ -89,8 +89,8 @@ export const ContactPhoneNumberCreateType: GraphQLFieldConfig< context.getViewer(), { extra: input.extra, - contactId: mustDecodeIDFromGQLID(input.contactId), - ownerId: mustDecodeIDFromGQLID(input.ownerId), + contactId: mustDecodeIDFromGQLID(input.contactId.toString()), + ownerId: mustDecodeIDFromGQLID(input.ownerId.toString()), phoneNumber: input.phoneNumber, label: input.label, }, diff --git a/examples/simple/src/graphql/generated/mutations/event/event_create_type.ts b/examples/simple/src/graphql/generated/mutations/event/event_create_type.ts index 17ca08ee3..fe0fdc634 100644 --- a/examples/simple/src/graphql/generated/mutations/event/event_create_type.ts +++ b/examples/simple/src/graphql/generated/mutations/event/event_create_type.ts @@ -105,14 +105,24 @@ export const EventCreateType: GraphQLFieldConfig< ): Promise => { const event = await CreateEventAction.create(context.getViewer(), { name: input.name, - creatorId: mustDecodeIDFromGQLID(input.creatorId), + creatorId: mustDecodeIDFromGQLID(input.creatorId.toString()), startTime: input.startTime, endTime: input.endTime, location: input.eventLocation, - addressId: mustDecodeNullableIDFromGQLID(input.addressId), + addressId: mustDecodeNullableIDFromGQLID( + input.addressId?.toString() ?? input.addressId, + ), coverPhoto: input.coverPhoto, coverPhoto2: input.coverPhoto2, - attachments: input.attachments, + attachments: input.attachments?.map((item: any) => ({ + ...item, + fileId: mustDecodeIDFromGQLID(item.fileId.toString()), + dupeFileId: item.dupeFileId + ? mustDecodeNullableIDFromGQLID( + item.dupeFileId?.toString() ?? item.dupeFileId, + ) + : undefined, + })), }).saveX(); return { event: event }; }, diff --git a/examples/simple/src/graphql/generated/mutations/event/event_edit_type.ts b/examples/simple/src/graphql/generated/mutations/event/event_edit_type.ts index a0a8afedf..2378f8aee 100644 --- a/examples/simple/src/graphql/generated/mutations/event/event_edit_type.ts +++ b/examples/simple/src/graphql/generated/mutations/event/event_edit_type.ts @@ -112,10 +112,20 @@ export const EventEditType: GraphQLFieldConfig< startTime: input.startTime, endTime: input.endTime, location: input.eventLocation, - addressId: mustDecodeNullableIDFromGQLID(input.addressId), + addressId: mustDecodeNullableIDFromGQLID( + input.addressId?.toString() ?? input.addressId, + ), coverPhoto: input.coverPhoto, coverPhoto2: input.coverPhoto2, - attachments: input.attachments, + attachments: input.attachments?.map((item: any) => ({ + ...item, + fileId: mustDecodeIDFromGQLID(item.fileId.toString()), + dupeFileId: item.dupeFileId + ? mustDecodeNullableIDFromGQLID( + item.dupeFileId?.toString() ?? item.dupeFileId, + ) + : undefined, + })), }, ); return { event }; diff --git a/examples/simple/src/graphql/generated/mutations/event/event_rsvp_status_clear_type.ts b/examples/simple/src/graphql/generated/mutations/event/event_rsvp_status_clear_type.ts index 729e422e9..934238504 100644 --- a/examples/simple/src/graphql/generated/mutations/event/event_rsvp_status_clear_type.ts +++ b/examples/simple/src/graphql/generated/mutations/event/event_rsvp_status_clear_type.ts @@ -78,7 +78,7 @@ export const EventRsvpStatusClearType: GraphQLFieldConfig< context.getViewer(), mustDecodeIDFromGQLID(input.id), { - userId: mustDecodeIDFromGQLID(input.userId), + userId: mustDecodeIDFromGQLID(input.userId.toString()), }, ); return { event }; diff --git a/examples/simple/src/graphql/generated/mutations/event/event_rsvp_status_edit_type.ts b/examples/simple/src/graphql/generated/mutations/event/event_rsvp_status_edit_type.ts index 860fb9f62..6622683ed 100644 --- a/examples/simple/src/graphql/generated/mutations/event/event_rsvp_status_edit_type.ts +++ b/examples/simple/src/graphql/generated/mutations/event/event_rsvp_status_edit_type.ts @@ -83,7 +83,7 @@ export const EventRsvpStatusEditType: GraphQLFieldConfig< mustDecodeIDFromGQLID(input.id), { rsvpStatus: input.rsvpStatus, - userId: mustDecodeIDFromGQLID(input.userId), + userId: mustDecodeIDFromGQLID(input.userId.toString()), }, ); return { event }; diff --git a/examples/simple/src/graphql/generated/mutations/file/file_create_type.ts b/examples/simple/src/graphql/generated/mutations/file/file_create_type.ts index b55e8ce95..fcc7eb027 100644 --- a/examples/simple/src/graphql/generated/mutations/file/file_create_type.ts +++ b/examples/simple/src/graphql/generated/mutations/file/file_create_type.ts @@ -79,7 +79,7 @@ export const FileCreateType: GraphQLFieldConfig< const file = await CreateFileAction.create(context.getViewer(), { name: input.name, path: input.path, - creatorId: mustDecodeIDFromGQLID(input.creatorId), + creatorId: mustDecodeIDFromGQLID(input.creatorId.toString()), }).saveX(); return { file: file }; }, diff --git a/examples/simple/src/graphql/generated/mutations/file/file_edit_type.ts b/examples/simple/src/graphql/generated/mutations/file/file_edit_type.ts index 5af7a0f8b..51047d618 100644 --- a/examples/simple/src/graphql/generated/mutations/file/file_edit_type.ts +++ b/examples/simple/src/graphql/generated/mutations/file/file_edit_type.ts @@ -90,7 +90,9 @@ export const FileEditType: GraphQLFieldConfig< { name: input.name, path: input.path, - creatorId: mustDecodeNullableIDFromGQLID(input.creatorId), + creatorId: mustDecodeNullableIDFromGQLID( + input.creatorId?.toString() ?? input.creatorId, + ), }, ); return { file }; diff --git a/examples/simple/src/graphql/generated/mutations/input/user_prefs_struct_input_type.ts b/examples/simple/src/graphql/generated/mutations/input/user_prefs_struct_input_type.ts index ec9f32603..6b88700ca 100644 --- a/examples/simple/src/graphql/generated/mutations/input/user_prefs_struct_input_type.ts +++ b/examples/simple/src/graphql/generated/mutations/input/user_prefs_struct_input_type.ts @@ -5,6 +5,7 @@ import { GraphQLBoolean, + GraphQLID, GraphQLInputFieldConfigMap, GraphQLInputObjectType, GraphQLList, @@ -26,5 +27,11 @@ export const UserPrefsStructInputType = new GraphQLInputObjectType({ new GraphQLList(new GraphQLNonNull(NotifTypeType)), ), }, + homeAddressId: { + type: GraphQLID, + }, + allAddressIds: { + type: new GraphQLList(new GraphQLNonNull(GraphQLID)), + }, }), }); diff --git a/examples/simple/src/graphql/generated/mutations/user/user_create_type.ts b/examples/simple/src/graphql/generated/mutations/user/user_create_type.ts index 594ec1136..77a716537 100644 --- a/examples/simple/src/graphql/generated/mutations/user/user_create_type.ts +++ b/examples/simple/src/graphql/generated/mutations/user/user_create_type.ts @@ -18,6 +18,7 @@ import { import { RequestContext } from "@snowtop/ent"; import { mustDecodeIDFromGQLID, + mustDecodeNullableIDFromGQLID, transformUnionTypes, } from "@snowtop/ent/graphql"; import { User } from "../../../../ent"; @@ -132,14 +133,45 @@ export const UserCreateType: GraphQLFieldConfig< phoneNumber: input.phoneNumber, password: input.password, nicknames: input.nicknames, - prefs: input.prefs, + prefs: input.prefs + ? { + ...input.prefs, + homeAddressId: input.prefs.homeAddressId + ? mustDecodeNullableIDFromGQLID( + input.prefs.homeAddressId?.toString() ?? + input.prefs.homeAddressId, + ) + : undefined, + allAddressIds: input.prefs.allAddressIds + ? input.prefs.allAddressIds + ? input.prefs.allAddressIds.map((i: any) => + mustDecodeIDFromGQLID(i.toString()), + ) + : undefined + : undefined, + } + : undefined, prefsDiff: input.prefsDiff, daysOff: input.daysOff, preferredShift: input.preferredShift, funUuids: input.funUuids - ? input.funUuids.map((i: any) => mustDecodeIDFromGQLID(i)) + ? input.funUuids.map((i: any) => mustDecodeIDFromGQLID(i.toString())) : undefined, - prefsList: input.prefsList, + prefsList: input.prefsList?.map((item: any) => ({ + ...item, + homeAddressId: item.homeAddressId + ? mustDecodeNullableIDFromGQLID( + item.homeAddressId?.toString() ?? item.homeAddressId, + ) + : undefined, + allAddressIds: item.allAddressIds + ? item.allAddressIds + ? item.allAddressIds.map((i: any) => + mustDecodeIDFromGQLID(i.toString()), + ) + : undefined + : undefined, + })), superNestedObject: input.superNestedObject, nestedList: input.nestedList, intEnum: input.intEnum, diff --git a/examples/simple/src/graphql/generated/mutations/user_statistics/user_statistics_create_type.ts b/examples/simple/src/graphql/generated/mutations/user_statistics/user_statistics_create_type.ts index 932eb2c70..b1f629ca0 100644 --- a/examples/simple/src/graphql/generated/mutations/user_statistics/user_statistics_create_type.ts +++ b/examples/simple/src/graphql/generated/mutations/user_statistics/user_statistics_create_type.ts @@ -76,7 +76,7 @@ export const UserStatisticsCreateType: GraphQLFieldConfig< const userStatistics = await CreateUserStatisticsAction.create( context.getViewer(), { - userId: mustDecodeIDFromGQLID(input.userId), + userId: mustDecodeIDFromGQLID(input.userId.toString()), authCodeEmailsSent: input.authCodeEmailsSent, }, ).saveX(); diff --git a/examples/simple/src/graphql/generated/resolvers/attachment_type.ts b/examples/simple/src/graphql/generated/resolvers/attachment_type.ts index aca22d710..dd93300f8 100644 --- a/examples/simple/src/graphql/generated/resolvers/attachment_type.ts +++ b/examples/simple/src/graphql/generated/resolvers/attachment_type.ts @@ -5,14 +5,15 @@ import { GraphQLFieldConfigMap, - GraphQLID, GraphQLNonNull, GraphQLObjectType, GraphQLString, } from "graphql"; import { RequestContext } from "@snowtop/ent"; import { GraphQLTime } from "@snowtop/ent/graphql"; +import { File } from "../../../ent"; import { Attachment } from "../../../ent/generated/types"; +import { FileType } from "../../resolvers/internal"; import { ExampleViewer as ExampleViewerAlias } from "../../../viewer/viewer"; export const AttachmentType = new GraphQLObjectType({ @@ -21,11 +22,28 @@ export const AttachmentType = new GraphQLObjectType({ Attachment, RequestContext > => ({ - fileId: { - type: new GraphQLNonNull(GraphQLID), + file: { + type: FileType, + resolve: ( + obj: Attachment, + args: {}, + context: RequestContext, + ) => { + return File.load(context.getViewer(), obj.fileId); + }, }, - dupeFileId: { - type: GraphQLID, + dupeFile: { + type: FileType, + resolve: ( + obj: Attachment, + args: {}, + context: RequestContext, + ) => { + if (obj.dupeFileId === null || obj.dupeFileId === undefined) { + return null; + } + return File.load(context.getViewer(), obj.dupeFileId); + }, }, note: { type: GraphQLString, diff --git a/examples/simple/src/graphql/generated/resolvers/can_viewer_do_query_type.ts b/examples/simple/src/graphql/generated/resolvers/can_viewer_do_query_type.ts index a6bf30b47..9f9bb5912 100644 --- a/examples/simple/src/graphql/generated/resolvers/can_viewer_do_query_type.ts +++ b/examples/simple/src/graphql/generated/resolvers/can_viewer_do_query_type.ts @@ -27,7 +27,7 @@ class GlobalCanViewerDo { async contactCreate(args: any): Promise { const action = CreateContactAction.create(this.context.getViewer(), { ...args, - userId: mustDecodeIDFromGQLID(args.userId), + userId: mustDecodeIDFromGQLID(args.userId.toString()), }); return applyPrivacyPolicy( this.context.getViewer(), @@ -40,8 +40,8 @@ class GlobalCanViewerDo { const action = CreateContactEmailAction.create(this.context.getViewer(), { ...args, extra: args.extra, - contactId: mustDecodeIDFromGQLID(args.contactId), - ownerId: mustDecodeIDFromGQLID(args.ownerId), + contactId: mustDecodeIDFromGQLID(args.contactId.toString()), + ownerId: mustDecodeIDFromGQLID(args.ownerId.toString()), emailAddress: args.emailAddress, label: args.label, }); diff --git a/examples/simple/src/graphql/generated/resolvers/comment_connection_query_type.ts b/examples/simple/src/graphql/generated/resolvers/comment_connection_query_type.ts index c1890159d..e2b9b5ee5 100644 --- a/examples/simple/src/graphql/generated/resolvers/comment_connection_query_type.ts +++ b/examples/simple/src/graphql/generated/resolvers/comment_connection_query_type.ts @@ -77,7 +77,7 @@ export const CommentConnectionQueryType: GraphQLFieldConfig< _info: GraphQLResolveInfo, ) => { args.ids = args.ids - ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i)) + ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i.toString())) : undefined; return new GraphQLEdgeConnection( context.getViewer(), diff --git a/examples/simple/src/graphql/generated/resolvers/comment_list_deprecated_query_type.ts b/examples/simple/src/graphql/generated/resolvers/comment_list_deprecated_query_type.ts index 2348565e1..1ddf9c225 100644 --- a/examples/simple/src/graphql/generated/resolvers/comment_list_deprecated_query_type.ts +++ b/examples/simple/src/graphql/generated/resolvers/comment_list_deprecated_query_type.ts @@ -53,9 +53,9 @@ export const CommentListDeprecatedQueryType: GraphQLFieldConfig< context: RequestContext, _info: GraphQLResolveInfo, ) => { - args.id = mustDecodeNullableIDFromGQLID(args.id); + args.id = mustDecodeNullableIDFromGQLID(args.id?.toString() ?? args.id); args.ids = args.ids - ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i)) + ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i.toString())) : undefined; const whereQueries = [ diff --git a/examples/simple/src/graphql/generated/resolvers/contact_connection_query_type.ts b/examples/simple/src/graphql/generated/resolvers/contact_connection_query_type.ts index 2946311d3..c38cb7506 100644 --- a/examples/simple/src/graphql/generated/resolvers/contact_connection_query_type.ts +++ b/examples/simple/src/graphql/generated/resolvers/contact_connection_query_type.ts @@ -77,7 +77,7 @@ export const ContactConnectionQueryType: GraphQLFieldConfig< _info: GraphQLResolveInfo, ) => { args.ids = args.ids - ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i)) + ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i.toString())) : undefined; return new GraphQLEdgeConnection( context.getViewer(), diff --git a/examples/simple/src/graphql/generated/resolvers/contact_email_connection_query_type.ts b/examples/simple/src/graphql/generated/resolvers/contact_email_connection_query_type.ts index ed5fea28d..766ee4ed7 100644 --- a/examples/simple/src/graphql/generated/resolvers/contact_email_connection_query_type.ts +++ b/examples/simple/src/graphql/generated/resolvers/contact_email_connection_query_type.ts @@ -77,7 +77,7 @@ export const ContactEmailConnectionQueryType: GraphQLFieldConfig< _info: GraphQLResolveInfo, ) => { args.ids = args.ids - ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i)) + ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i.toString())) : undefined; return new GraphQLEdgeConnection( context.getViewer(), diff --git a/examples/simple/src/graphql/generated/resolvers/contact_email_list_deprecated_query_type.ts b/examples/simple/src/graphql/generated/resolvers/contact_email_list_deprecated_query_type.ts index 59d600854..ab9147441 100644 --- a/examples/simple/src/graphql/generated/resolvers/contact_email_list_deprecated_query_type.ts +++ b/examples/simple/src/graphql/generated/resolvers/contact_email_list_deprecated_query_type.ts @@ -55,9 +55,9 @@ export const ContactEmailListDeprecatedQueryType: GraphQLFieldConfig< context: RequestContext, _info: GraphQLResolveInfo, ) => { - args.id = mustDecodeNullableIDFromGQLID(args.id); + args.id = mustDecodeNullableIDFromGQLID(args.id?.toString() ?? args.id); args.ids = args.ids - ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i)) + ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i.toString())) : undefined; const whereQueries = [ diff --git a/examples/simple/src/graphql/generated/resolvers/contact_info_type.ts b/examples/simple/src/graphql/generated/resolvers/contact_info_type.ts index acc228817..755b6bbda 100644 --- a/examples/simple/src/graphql/generated/resolvers/contact_info_type.ts +++ b/examples/simple/src/graphql/generated/resolvers/contact_info_type.ts @@ -11,5 +11,5 @@ import { export const ContactInfoType = new GraphQLUnionType({ name: "ContactInfo", - types: () => [ContactEmailType, ContactPhoneNumberType], + types: () => [ContactPhoneNumberType, ContactEmailType], }); diff --git a/examples/simple/src/graphql/generated/resolvers/contact_list_deprecated_query_type.ts b/examples/simple/src/graphql/generated/resolvers/contact_list_deprecated_query_type.ts index 4c160b3c8..2a4a11ae2 100644 --- a/examples/simple/src/graphql/generated/resolvers/contact_list_deprecated_query_type.ts +++ b/examples/simple/src/graphql/generated/resolvers/contact_list_deprecated_query_type.ts @@ -53,9 +53,9 @@ export const ContactListDeprecatedQueryType: GraphQLFieldConfig< context: RequestContext, _info: GraphQLResolveInfo, ) => { - args.id = mustDecodeNullableIDFromGQLID(args.id); + args.id = mustDecodeNullableIDFromGQLID(args.id?.toString() ?? args.id); args.ids = args.ids - ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i)) + ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i.toString())) : undefined; const whereQueries = [ diff --git a/examples/simple/src/graphql/generated/resolvers/contact_phone_number_connection_query_type.ts b/examples/simple/src/graphql/generated/resolvers/contact_phone_number_connection_query_type.ts index 2ce50fabb..b1db7f7d5 100644 --- a/examples/simple/src/graphql/generated/resolvers/contact_phone_number_connection_query_type.ts +++ b/examples/simple/src/graphql/generated/resolvers/contact_phone_number_connection_query_type.ts @@ -77,7 +77,7 @@ export const ContactPhoneNumberConnectionQueryType: GraphQLFieldConfig< _info: GraphQLResolveInfo, ) => { args.ids = args.ids - ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i)) + ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i.toString())) : undefined; return new GraphQLEdgeConnection( context.getViewer(), diff --git a/examples/simple/src/graphql/generated/resolvers/contact_phone_number_list_deprecated_query_type.ts b/examples/simple/src/graphql/generated/resolvers/contact_phone_number_list_deprecated_query_type.ts index c3a75ad45..b938f1645 100644 --- a/examples/simple/src/graphql/generated/resolvers/contact_phone_number_list_deprecated_query_type.ts +++ b/examples/simple/src/graphql/generated/resolvers/contact_phone_number_list_deprecated_query_type.ts @@ -55,9 +55,9 @@ export const ContactPhoneNumberListDeprecatedQueryType: GraphQLFieldConfig< context: RequestContext, _info: GraphQLResolveInfo, ) => { - args.id = mustDecodeNullableIDFromGQLID(args.id); + args.id = mustDecodeNullableIDFromGQLID(args.id?.toString() ?? args.id); args.ids = args.ids - ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i)) + ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i.toString())) : undefined; const whereQueries = [ diff --git a/examples/simple/src/graphql/generated/resolvers/event_connection_query_type.ts b/examples/simple/src/graphql/generated/resolvers/event_connection_query_type.ts index 3ed2c0ad9..f4946c8c0 100644 --- a/examples/simple/src/graphql/generated/resolvers/event_connection_query_type.ts +++ b/examples/simple/src/graphql/generated/resolvers/event_connection_query_type.ts @@ -77,7 +77,7 @@ export const EventConnectionQueryType: GraphQLFieldConfig< _info: GraphQLResolveInfo, ) => { args.ids = args.ids - ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i)) + ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i.toString())) : undefined; return new GraphQLEdgeConnection( context.getViewer(), diff --git a/examples/simple/src/graphql/generated/resolvers/event_list_deprecated_query_type.ts b/examples/simple/src/graphql/generated/resolvers/event_list_deprecated_query_type.ts index d870c1511..93ff54052 100644 --- a/examples/simple/src/graphql/generated/resolvers/event_list_deprecated_query_type.ts +++ b/examples/simple/src/graphql/generated/resolvers/event_list_deprecated_query_type.ts @@ -53,9 +53,9 @@ export const EventListDeprecatedQueryType: GraphQLFieldConfig< context: RequestContext, _info: GraphQLResolveInfo, ) => { - args.id = mustDecodeNullableIDFromGQLID(args.id); + args.id = mustDecodeNullableIDFromGQLID(args.id?.toString() ?? args.id); args.ids = args.ids - ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i)) + ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i.toString())) : undefined; const whereQueries = [ diff --git a/examples/simple/src/graphql/generated/resolvers/feedback_type.ts b/examples/simple/src/graphql/generated/resolvers/feedback_type.ts index 910ff4cd3..01fe58ab0 100644 --- a/examples/simple/src/graphql/generated/resolvers/feedback_type.ts +++ b/examples/simple/src/graphql/generated/resolvers/feedback_type.ts @@ -14,9 +14,9 @@ import { export const FeedbackType = new GraphQLUnionType({ name: "Feedback", types: () => [ + UserType, + ContactType, ContactPhoneNumberType, ContactEmailType, - ContactType, - UserType, ], }); diff --git a/examples/simple/src/graphql/generated/resolvers/file_connection_query_type.ts b/examples/simple/src/graphql/generated/resolvers/file_connection_query_type.ts index d81223e14..ee431bb41 100644 --- a/examples/simple/src/graphql/generated/resolvers/file_connection_query_type.ts +++ b/examples/simple/src/graphql/generated/resolvers/file_connection_query_type.ts @@ -77,7 +77,7 @@ export const FileConnectionQueryType: GraphQLFieldConfig< _info: GraphQLResolveInfo, ) => { args.ids = args.ids - ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i)) + ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i.toString())) : undefined; return new GraphQLEdgeConnection( context.getViewer(), diff --git a/examples/simple/src/graphql/generated/resolvers/file_list_deprecated_query_type.ts b/examples/simple/src/graphql/generated/resolvers/file_list_deprecated_query_type.ts index e739ed05a..5023e6ac5 100644 --- a/examples/simple/src/graphql/generated/resolvers/file_list_deprecated_query_type.ts +++ b/examples/simple/src/graphql/generated/resolvers/file_list_deprecated_query_type.ts @@ -53,9 +53,9 @@ export const FileListDeprecatedQueryType: GraphQLFieldConfig< context: RequestContext, _info: GraphQLResolveInfo, ) => { - args.id = mustDecodeNullableIDFromGQLID(args.id); + args.id = mustDecodeNullableIDFromGQLID(args.id?.toString() ?? args.id); args.ids = args.ids - ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i)) + ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i.toString())) : undefined; const whereQueries = [ diff --git a/examples/simple/src/graphql/generated/resolvers/holiday_connection_query_type.ts b/examples/simple/src/graphql/generated/resolvers/holiday_connection_query_type.ts index 40973ed76..7c29c1ff1 100644 --- a/examples/simple/src/graphql/generated/resolvers/holiday_connection_query_type.ts +++ b/examples/simple/src/graphql/generated/resolvers/holiday_connection_query_type.ts @@ -77,7 +77,7 @@ export const HolidayConnectionQueryType: GraphQLFieldConfig< _info: GraphQLResolveInfo, ) => { args.ids = args.ids - ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i)) + ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i.toString())) : undefined; return new GraphQLEdgeConnection( context.getViewer(), diff --git a/examples/simple/src/graphql/generated/resolvers/holiday_list_deprecated_query_type.ts b/examples/simple/src/graphql/generated/resolvers/holiday_list_deprecated_query_type.ts index 8061de5a7..e14cec450 100644 --- a/examples/simple/src/graphql/generated/resolvers/holiday_list_deprecated_query_type.ts +++ b/examples/simple/src/graphql/generated/resolvers/holiday_list_deprecated_query_type.ts @@ -53,9 +53,9 @@ export const HolidayListDeprecatedQueryType: GraphQLFieldConfig< context: RequestContext, _info: GraphQLResolveInfo, ) => { - args.id = mustDecodeNullableIDFromGQLID(args.id); + args.id = mustDecodeNullableIDFromGQLID(args.id?.toString() ?? args.id); args.ids = args.ids - ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i)) + ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i.toString())) : undefined; const whereQueries = [ diff --git a/examples/simple/src/graphql/generated/resolvers/hours_of_operation_connection_query_type.ts b/examples/simple/src/graphql/generated/resolvers/hours_of_operation_connection_query_type.ts index a288551ff..e182d6641 100644 --- a/examples/simple/src/graphql/generated/resolvers/hours_of_operation_connection_query_type.ts +++ b/examples/simple/src/graphql/generated/resolvers/hours_of_operation_connection_query_type.ts @@ -77,7 +77,7 @@ export const HoursOfOperationConnectionQueryType: GraphQLFieldConfig< _info: GraphQLResolveInfo, ) => { args.ids = args.ids - ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i)) + ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i.toString())) : undefined; return new GraphQLEdgeConnection( context.getViewer(), diff --git a/examples/simple/src/graphql/generated/resolvers/hours_of_operation_list_deprecated_query_type.ts b/examples/simple/src/graphql/generated/resolvers/hours_of_operation_list_deprecated_query_type.ts index 39e75b704..374aa71ec 100644 --- a/examples/simple/src/graphql/generated/resolvers/hours_of_operation_list_deprecated_query_type.ts +++ b/examples/simple/src/graphql/generated/resolvers/hours_of_operation_list_deprecated_query_type.ts @@ -55,9 +55,9 @@ export const HoursOfOperationListDeprecatedQueryType: GraphQLFieldConfig< context: RequestContext, _info: GraphQLResolveInfo, ) => { - args.id = mustDecodeNullableIDFromGQLID(args.id); + args.id = mustDecodeNullableIDFromGQLID(args.id?.toString() ?? args.id); args.ids = args.ids - ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i)) + ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i.toString())) : undefined; const whereQueries = [ diff --git a/examples/simple/src/graphql/generated/resolvers/user_connection_query_type.ts b/examples/simple/src/graphql/generated/resolvers/user_connection_query_type.ts index 7e9dd1ea9..c3f7b7305 100644 --- a/examples/simple/src/graphql/generated/resolvers/user_connection_query_type.ts +++ b/examples/simple/src/graphql/generated/resolvers/user_connection_query_type.ts @@ -77,7 +77,7 @@ export const UserConnectionQueryType: GraphQLFieldConfig< _info: GraphQLResolveInfo, ) => { args.ids = args.ids - ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i)) + ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i.toString())) : undefined; return new GraphQLEdgeConnection( context.getViewer(), diff --git a/examples/simple/src/graphql/generated/resolvers/user_list_deprecated_query_type.ts b/examples/simple/src/graphql/generated/resolvers/user_list_deprecated_query_type.ts index d129389a2..e45d3763f 100644 --- a/examples/simple/src/graphql/generated/resolvers/user_list_deprecated_query_type.ts +++ b/examples/simple/src/graphql/generated/resolvers/user_list_deprecated_query_type.ts @@ -53,9 +53,9 @@ export const UserListDeprecatedQueryType: GraphQLFieldConfig< context: RequestContext, _info: GraphQLResolveInfo, ) => { - args.id = mustDecodeNullableIDFromGQLID(args.id); + args.id = mustDecodeNullableIDFromGQLID(args.id?.toString() ?? args.id); args.ids = args.ids - ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i)) + ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i.toString())) : undefined; const whereQueries = [ diff --git a/examples/simple/src/graphql/generated/resolvers/user_prefs_struct_type.ts b/examples/simple/src/graphql/generated/resolvers/user_prefs_struct_type.ts index 972145483..4f6f9df75 100644 --- a/examples/simple/src/graphql/generated/resolvers/user_prefs_struct_type.ts +++ b/examples/simple/src/graphql/generated/resolvers/user_prefs_struct_type.ts @@ -11,8 +11,9 @@ import { GraphQLObjectType, } from "graphql"; import { RequestContext } from "@snowtop/ent"; +import { Address } from "../../../ent"; import { UserPrefsStruct } from "../../../ent/generated/types"; -import { NotifTypeType } from "../../resolvers/internal"; +import { AddressType, NotifTypeType } from "../../resolvers/internal"; import { ExampleViewer as ExampleViewerAlias } from "../../../viewer/viewer"; export const UserPrefsStructType = new GraphQLObjectType({ @@ -32,5 +33,35 @@ export const UserPrefsStructType = new GraphQLObjectType({ new GraphQLList(new GraphQLNonNull(NotifTypeType)), ), }, + homeAddress: { + type: AddressType, + resolve: ( + obj: UserPrefsStruct, + args: {}, + context: RequestContext, + ) => { + if (obj.homeAddressId === null || obj.homeAddressId === undefined) { + return null; + } + return Address.load(context.getViewer(), obj.homeAddressId); + }, + }, + allAddresses: { + type: new GraphQLList(new GraphQLNonNull(AddressType)), + resolve: async ( + obj: UserPrefsStruct, + args: {}, + context: RequestContext, + ) => { + if (obj.allAddressIds === null || obj.allAddressIds === undefined) { + return null; + } + const objs = await Address.loadMany( + context.getViewer(), + ...obj.allAddressIds, + ); + return Array.from(objs.values()); + }, + }, }), }); diff --git a/examples/simple/src/graphql/generated/resolvers/user_statistics_connection_query_type.ts b/examples/simple/src/graphql/generated/resolvers/user_statistics_connection_query_type.ts index 5a7ac77d0..845d46a44 100644 --- a/examples/simple/src/graphql/generated/resolvers/user_statistics_connection_query_type.ts +++ b/examples/simple/src/graphql/generated/resolvers/user_statistics_connection_query_type.ts @@ -77,7 +77,7 @@ export const UserStatisticsConnectionQueryType: GraphQLFieldConfig< _info: GraphQLResolveInfo, ) => { args.ids = args.ids - ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i)) + ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i.toString())) : undefined; return new GraphQLEdgeConnection( context.getViewer(), diff --git a/examples/simple/src/graphql/generated/resolvers/user_statistics_list_deprecated_query_type.ts b/examples/simple/src/graphql/generated/resolvers/user_statistics_list_deprecated_query_type.ts index 11ff7b3c1..f4e24d79a 100644 --- a/examples/simple/src/graphql/generated/resolvers/user_statistics_list_deprecated_query_type.ts +++ b/examples/simple/src/graphql/generated/resolvers/user_statistics_list_deprecated_query_type.ts @@ -55,9 +55,9 @@ export const UserStatisticsListDeprecatedQueryType: GraphQLFieldConfig< context: RequestContext, _info: GraphQLResolveInfo, ) => { - args.id = mustDecodeNullableIDFromGQLID(args.id); + args.id = mustDecodeNullableIDFromGQLID(args.id?.toString() ?? args.id); args.ids = args.ids - ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i)) + ? args.ids.map((i: any) => mustDecodeIDFromGQLID(i.toString())) : undefined; const whereQueries = [ diff --git a/examples/simple/src/graphql/generated/schema.gql b/examples/simple/src/graphql/generated/schema.gql index 938b7dbaa..9ae5198c7 100644 --- a/examples/simple/src/graphql/generated/schema.gql +++ b/examples/simple/src/graphql/generated/schema.gql @@ -229,8 +229,8 @@ type Address implements Node { } type Attachment { - fileId: ID! - dupeFileId: ID + file: File + dupeFile: File note: String date: Time! phoneNumber: String @@ -288,12 +288,14 @@ type ContactInfoExtra { source: ContactInfoSource! } +union ContactInfo = ContactEmail | ContactPhoneNumber + input ContactItemFilter { emailDomain: String phoneNumberAreaCode: String } -union ContactItemResult = ContactEmail | ContactPhoneNumber | ContactDate +union ContactItemResult = ContactDate | ContactEmail | ContactPhoneNumber interface ContactItem { contact: Contact @@ -366,7 +368,7 @@ type Event implements Node { cities: [City!]! } -union Feedback = ContactPhoneNumber | ContactEmail | Contact | User +union Feedback = Contact | ContactEmail | ContactPhoneNumber | User type File implements Node { creator: User @@ -461,6 +463,8 @@ type UserPrefsStruct { finishedNux: Boolean enableNotifs: Boolean notifTypes: [NotifType!]! + homeAddress: Address + allAddresses: [Address!] } type UserStatistics implements Node { @@ -535,7 +539,7 @@ type User implements Node { cities: [City!]! } -union WithDayOfWeek = HoursOfOperation | Holiday +union WithDayOfWeek = Holiday | HoursOfOperation type AddressToHostedEventsEdge implements Edge { node: Event! @@ -1646,6 +1650,8 @@ input UserPrefsStructInput { finishedNux: Boolean enableNotifs: Boolean notifTypes: [NotifType!]! + homeAddressId: ID + allAddressIds: [ID!] } input UserStatisticsArgInput { diff --git a/examples/simple/src/graphql/generated/schema.ts b/examples/simple/src/graphql/generated/schema.ts index 3a7e884ff..5ae42d11a 100644 --- a/examples/simple/src/graphql/generated/schema.ts +++ b/examples/simple/src/graphql/generated/schema.ts @@ -199,6 +199,7 @@ import { ContactEmailType, ContactInfoExtraType, ContactInfoSourceType, + ContactInfoType, ContactItemFilterType, ContactItemResultType, ContactItemType, @@ -324,6 +325,7 @@ export default new GraphQLSchema({ ContactEmailCanViewerDoType, ContactEmailType, ContactInfoExtraType, + ContactInfoType, ContactItemFilterType, ContactItemResultType, ContactItemType, diff --git a/examples/simple/src/graphql/resolvers/internal.ts b/examples/simple/src/graphql/resolvers/internal.ts index d4ed30ec8..eddbde88e 100644 --- a/examples/simple/src/graphql/resolvers/internal.ts +++ b/examples/simple/src/graphql/resolvers/internal.ts @@ -20,6 +20,7 @@ export * from "../generated/resolvers/user_super_nested_object_type"; export * from "../generated/resolvers/address_type"; export * from "../generated/resolvers/comment_type"; export * from "../generated/resolvers/contact_email_type"; +export * from "../generated/resolvers/contact_info_type"; export * from "../generated/resolvers/contact_phone_number_type"; export * from "../generated/resolvers/contact_type"; export * from "../generated/resolvers/event_type"; diff --git a/examples/simple/src/graphql/tests/contact_type.test.ts b/examples/simple/src/graphql/tests/contact_type.test.ts index caa9da50c..10ec0a1a3 100644 --- a/examples/simple/src/graphql/tests/contact_type.test.ts +++ b/examples/simple/src/graphql/tests/contact_type.test.ts @@ -1,4 +1,4 @@ -import { advanceBy } from "jest-date-mock"; +import { advanceBy, advanceTo } from "jest-date-mock"; import { Viewer } from "@snowtop/ent"; import { expectMutation, @@ -18,6 +18,7 @@ import { ContactLabel } from "src/ent/generated/types"; import EditContactAction from "src/ent/contact/actions/edit_contact_action"; import CreateContactEmailAction from "src/ent/contact_email/actions/create_contact_email_action"; import CreateContactPhoneNumberAction from "src/ent/contact_phone_number/actions/create_contact_phone_number_action"; +import CreateFileAction from "src/ent/file/actions/create_file_action"; afterEach(() => { clearAuthHandlers(); @@ -68,6 +69,7 @@ async function createUser(): Promise { password: "pa$$w0rd", }).saveX(); } + async function createContact(user?: User): Promise { if (!user) { user = await createUser(); @@ -326,3 +328,64 @@ test("global canViewerDo", async () => { ], ); }); + +test("create contact with attachments", async () => { + let user = await createUser(); + const file = await CreateFileAction.create(user.viewer, { + creatorId: user.id, + name: "test.png", + path: "/tmp/test.png", + }).saveX(); + const file2 = await CreateFileAction.create(user.viewer, { + creatorId: user.id, + name: "test.png2", + path: "/tmp/test.png2", + }).saveX(); + const d = new Date(); + advanceTo(d); + + const email = randomEmail(); + + await expectMutation( + { + mutation: "contactCreate", + viewer: user.viewer, + schema, + args: { + firstName: "Jon", + lastName: "Snow", + userId: encodeGQLID(user), + emails: [ + { + emailAddress: email, + label: ContactLabel.Home.toUpperCase(), + ownerId: encodeGQLID(user), + }, + ], + attachments: [ + { + fileId: encodeGQLID(file), + note: "note", + date: d.toISOString(), + dupeFileId: encodeGQLID(file), + }, + { + fileId: encodeGQLID(file2), + note: "note2", + date: d.toISOString(), + dupeFileId: encodeGQLID(file2), + }, + ], + }, + }, + ["contact.firstName", "Jon"], + ["contact.lastName", "Snow"], + ["contact.emails[0].emailAddress", email], + ["contact.attachments[0].file.id", encodeGQLID(file)], + ["contact.attachments[0].dupeFile.id", encodeGQLID(file)], + ["contact.attachments[0].note", "note"], + ["contact.attachments[1].dupeFile.id", encodeGQLID(file2)], + ["contact.attachments[1].file.id", encodeGQLID(file2)], + ["contact.attachments[1].note", "note2"], + ); +}); diff --git a/examples/simple/src/graphql/tests/user_type.test.ts b/examples/simple/src/graphql/tests/user_type.test.ts index bb8712634..e1bcc2d0d 100644 --- a/examples/simple/src/graphql/tests/user_type.test.ts +++ b/examples/simple/src/graphql/tests/user_type.test.ts @@ -940,12 +940,12 @@ test("create with prefs+prefsList", async () => { async function (id: string) { const entID = mustDecodeIDFromGQLID(id); const user = await User.loadX(new ExampleViewer(entID), entID); - expect(await user.prefs()).toStrictEqual({ + expect(await user.prefs()).toMatchObject({ enableNotifs: undefined, finishedNux: true, notifTypes: [NotifType.EMAIL], }); - expect(await user.prefsList()).toStrictEqual([ + expect(await user.prefsList()).toMatchObject([ { enableNotifs: undefined, finishedNux: true, diff --git a/examples/simple/src/schema/__global__schema.ts b/examples/simple/src/schema/__global__schema.ts index e29e365ff..f571c476b 100644 --- a/examples/simple/src/schema/__global__schema.ts +++ b/examples/simple/src/schema/__global__schema.ts @@ -10,6 +10,7 @@ import { UUIDType, StringType, TimestampType, + UUIDListType, } from "@snowtop/ent/schema/"; const glo: GlobalSchema = { @@ -40,6 +41,18 @@ const glo: GlobalSchema = { tsType: "NotifType", graphQLType: "NotifType", }), + homeAddressId: UUIDType({ + nullable: true, + fieldEdge: { + schema: "Address", + }, + }), + allAddressIds: UUIDListType({ + fieldEdge: { + schema: "Address", + }, + nullable: true, + }), }, }), responses: EnumType({ diff --git a/examples/simple/src/schema/user_schema.ts b/examples/simple/src/schema/user_schema.ts index 0f48648d2..73480e9e6 100644 --- a/examples/simple/src/schema/user_schema.ts +++ b/examples/simple/src/schema/user_schema.ts @@ -133,7 +133,9 @@ const UserSchema = new EntSchema({ function: "convertSuperNestedObject", }, fields: { - uuid: UUIDType(), + uuid: UUIDType({ + disableBase64Encode: true, + }), int: IntegerType(), string: StringType(), bool: BooleanType(), @@ -147,7 +149,9 @@ const UserSchema = new EntSchema({ nullable: true, tsType: "UserNestedObject", fields: { - nested_uuid: UUIDType(), + nested_uuid: UUIDType({ + disableBase64Encode: true, + }), nested_int: IntegerType(), nested_string: StringType(), nested_bool: BooleanType(), @@ -161,7 +165,9 @@ const UserSchema = new EntSchema({ nullable: true, tsType: "UserNestedNestedObject", fields: { - nested_nested_uuid: UUIDType(), + nested_nested_uuid: UUIDType({ + disableBase64Encode: true, + }), nested_nested_int: IntegerType(), nested_nested_string: StringType(), nested_nested_bool: BooleanType({ nullable: true }), diff --git a/examples/todo-sqlite/src/graphql/generated/schema.gql b/examples/todo-sqlite/src/graphql/generated/schema.gql index 5056da24d..9f420ed59 100644 --- a/examples/todo-sqlite/src/graphql/generated/schema.gql +++ b/examples/todo-sqlite/src/graphql/generated/schema.gql @@ -91,8 +91,6 @@ type Tag implements Node { todos(first: Int, after: String, last: Int, before: String): TagToTodosConnection! } -union TodoContainer = Workspace | Account - type Todo implements Node { assignee: Account creator: Account diff --git a/examples/todo-sqlite/src/graphql/generated/schema.ts b/examples/todo-sqlite/src/graphql/generated/schema.ts index c76ac15ef..6e7d7d1a8 100644 --- a/examples/todo-sqlite/src/graphql/generated/schema.ts +++ b/examples/todo-sqlite/src/graphql/generated/schema.ts @@ -98,7 +98,6 @@ import { RootToOpenTodosConnectionType, TagToTodosConnectionType, TagType, - TodoContainerType, TodoToTagsConnectionType, TodoToTodoScopeConnectionType, TodoType, @@ -118,7 +117,6 @@ export default new GraphQLSchema({ CountryInfoType, CountryType, TagType, - TodoContainerType, TodoType, WorkspaceType, AccountToClosedTodosDupConnectionType(), diff --git a/examples/todo-sqlite/src/graphql/resolvers/internal.ts b/examples/todo-sqlite/src/graphql/resolvers/internal.ts index 9cf63fbc8..8d945a073 100644 --- a/examples/todo-sqlite/src/graphql/resolvers/internal.ts +++ b/examples/todo-sqlite/src/graphql/resolvers/internal.ts @@ -6,7 +6,6 @@ export * from "src/graphql/generated/resolvers/country_info_type"; export * from "src/graphql/generated/resolvers/country_type"; export * from "src/graphql/generated/resolvers/account_type"; export * from "src/graphql/generated/resolvers/tag_type"; -export * from "src/graphql/generated/resolvers/todo_container_type"; export * from "src/graphql/generated/resolvers/todo_type"; export * from "src/graphql/generated/resolvers/workspace_type"; export * from "src/graphql/generated/resolvers/account/account_to_closed_todos_dup_connection_type"; diff --git a/internal/enttype/type.go b/internal/enttype/type.go index 764c4309c..282ef28b1 100644 --- a/internal/enttype/type.go +++ b/internal/enttype/type.go @@ -250,6 +250,8 @@ func (t *idType) GetImportType() Import { // UUIDType type IDType struct { idType + // uuid types that are not backed by id fields in the db shouldn't be base64 encoded + DisableBase64Encode bool } func (t *IDType) GetGraphQLType() string { @@ -272,15 +274,15 @@ func (t *IDType) GetTSGraphQLImports(input bool) []*tsimport.ImportPath { } func (t *IDType) CustomGQLRender(cfg Config, v string) string { - if !cfg.Base64EncodeIDs() { + if !cfg.Base64EncodeIDs() || t.DisableBase64Encode { return v } - return fmt.Sprintf("mustDecodeIDFromGQLID(%s)", v) + return fmt.Sprintf("mustDecodeIDFromGQLID(%s.toString())", v) } func (t *IDType) ArgImports(cfg Config) []*tsimport.ImportPath { - if !cfg.Base64EncodeIDs() { + if !cfg.Base64EncodeIDs() || t.DisableBase64Encode { return []*tsimport.ImportPath{} } return []*tsimport.ImportPath{ @@ -290,6 +292,7 @@ func (t *IDType) ArgImports(cfg Config) []*tsimport.ImportPath { type NullableIDType struct { idType + DisableBase64Encode bool } func (t *NullableIDType) GetGraphQLType() string { @@ -311,15 +314,16 @@ func (t *NullableIDType) GetTSGraphQLImports(input bool) []*tsimport.ImportPath } func (t *NullableIDType) CustomGQLRender(cfg Config, v string) string { - if !cfg.Base64EncodeIDs() { + if !cfg.Base64EncodeIDs() || t.DisableBase64Encode { return v } - return fmt.Sprintf("mustDecodeNullableIDFromGQLID(%s)", v) + // account for null and undefined and keeping null as null + return fmt.Sprintf("mustDecodeNullableIDFromGQLID(%s?.toString() ?? %s)", v, v) } func (t *NullableIDType) ArgImports(cfg Config) []*tsimport.ImportPath { - if !cfg.Base64EncodeIDs() { + if !cfg.Base64EncodeIDs() || t.DisableBase64Encode { return []*tsimport.ImportPath{} } diff --git a/internal/field/field_info.go b/internal/field/field_info.go index 9f34718c5..ffe1d7ce1 100644 --- a/internal/field/field_info.go +++ b/internal/field/field_info.go @@ -11,8 +11,9 @@ import ( ) type Options struct { - SortFields bool - FieldOverrides map[string]*input.FieldOverride + SortFields bool + FieldOverrides map[string]*input.FieldOverride + ForceDisableBuilderType bool } // NewFieldInfoFromInputs generates Fields based on FieldInputs @@ -51,6 +52,9 @@ func NewFieldInfoFromInputs(cfg codegenapi.Config, nodeName string, fields []*in if err := fieldInfo.addField(f); err != nil { errs = append(errs, err) } + if options.ForceDisableBuilderType { + f.disableBuilderType = true + } for _, derivedField := range field.DerivedFields { f2, err := newFieldFromInput(cfg, nodeName, derivedField) if err != nil { @@ -93,7 +97,6 @@ type FieldInfo struct { NonEntFields []*NonEntField // keep track of computed fields just to know they exist computedFields map[string]bool - getFieldsFn bool primaryKeys []string diff --git a/internal/graphql/generate_ts_code.go b/internal/graphql/generate_ts_code.go index b810e631f..0f1eae557 100644 --- a/internal/graphql/generate_ts_code.go +++ b/internal/graphql/generate_ts_code.go @@ -2403,23 +2403,62 @@ func getCanViewerSeeInfoObject(processor *codegen.Processor, result *objectType, return canViewerSee, nil } -func addSingularEdge(edge edge.Edge, obj *objectType) error { - gqlField := &fieldType{ +func createFieldTypeForSingularEdge(edge edge.Edge) *fieldType { + return &fieldType{ Name: edge.GraphQLEdgeName(), HasResolveFunction: true, FieldImports: getGQLFileImports(edge.GetTSGraphQLTypeImports(), false), FunctionContents: []string{fmt.Sprintf("return obj.load%s();", edge.CamelCaseEdgeName())}, } +} + +func addSingularEdge(edge edge.Edge, obj *objectType) error { + gqlField := createFieldTypeForSingularEdge(edge) return obj.addField(gqlField) } -func addPluralEdge(edge edge.Edge, obj *objectType) error { - gqlField := &fieldType{ +func addSingularEdgeFromExternal(processor *codegen.Processor, edge edge.Edge, f *field.Field, obj *objectType) error { + gqlField := createFieldTypeForSingularEdge(edge) + var contents []string + + tsFieldName := f.TsFieldName(processor.Config) + if f.Nullable() { + contents = append(contents, fmt.Sprintf("if (obj.%s === null || obj.%s === undefined) { return null;}", tsFieldName, tsFieldName)) + } + contents = append(contents, fmt.Sprintf("return %s.load(context.getViewer(), obj.%s);", edge.GetNodeInfo().Node, tsFieldName)) + gqlField.ExtraImports = append(gqlField.ExtraImports, tsimport.NewLocalEntImportPath(edge.GetNodeInfo().Node)) + gqlField.FunctionContents = contents + return obj.addField(gqlField) +} + +func createFieldTypeForPluralEdge(edge edge.Edge) *fieldType { + return &fieldType{ Name: edge.GraphQLEdgeName(), HasResolveFunction: true, FieldImports: getGQLFileImports(edge.GetTSGraphQLTypeImports(), false), FunctionContents: []string{fmt.Sprintf("return obj.load%s();", edge.CamelCaseEdgeName())}, } +} + +func addPluralEdge(edge edge.Edge, obj *objectType) error { + gqlField := createFieldTypeForPluralEdge(edge) + return obj.addField(gqlField) +} + +func addPluralEdgeFromExternal(processor *codegen.Processor, edge edge.Edge, f *field.Field, obj *objectType) error { + gqlField := createFieldTypeForPluralEdge(edge) + gqlField.HasAsyncModifier = true + + var contents []string + tsFieldName := f.TsFieldName(processor.Config) + if f.Nullable() { + contents = append(contents, fmt.Sprintf("if (obj.%s === null || obj.%s === undefined) { return null;}", tsFieldName, tsFieldName)) + } + contents = append(contents, fmt.Sprintf("const objs = await %s.loadMany(context.getViewer(), ...obj.%s);", edge.GetNodeInfo().Node, tsFieldName)) + contents = append(contents, "return Array.from(objs.values());") + + gqlField.ExtraImports = append(gqlField.ExtraImports, tsimport.NewLocalEntImportPath(edge.GetNodeInfo().Node)) + gqlField.FunctionContents = contents return obj.addField(gqlField) } @@ -2932,6 +2971,74 @@ func processActionField(processor *codegen.Processor, a action.Action, f action. argImports = append(argImports, getGQLFileImports(customRenderer.ArgImports(processor.Config), true)...) } + var customList []string + var listType bool + + customType, ok := f.GetFieldType().(enttype.TSTypeWithCustomType) + if ok { + cti := customType.GetCustomTypeInfo() + if cti != nil { + + ci, ok := processor.Schema.CustomInterfaces[cti.TSInterface] + if ok { + + for _, f := range ci.Fields { + nestedType := f.GetFieldType() + + customRenderer, ok := nestedType.(enttype.CustomGQLRenderer) + if !ok { + continue + } + listType = enttype.IsListType(typ) + nestedInputField := fmt.Sprintf("%s.%s", inputField, f.GetGraphQLName()) + + if listType { + // if list type, operate on "item in a loop" + nestedInputField = fmt.Sprintf("item.%s", f.GetGraphQLName()) + } + nestedInputFieldPrefix := nestedInputField + nestedInputField = customRenderer.CustomGQLRender(processor.Config, nestedInputField) + if nestedInputField == nestedInputFieldPrefix { + // nothing changed here + continue + } + argImports = append(argImports, getGQLFileImports(customRenderer.ArgImports(processor.Config), true)...) + + if f.Nullable() { + nestedInputField = fmt.Sprintf("%s: %s ? %s: undefined", + f.GetGraphQLName(), + nestedInputFieldPrefix, + nestedInputField, + ) + } else { + nestedInputField = fmt.Sprintf("%s: %s", f.GetGraphQLName(), nestedInputField) + } + + customList = append(customList, nestedInputField) + } + } + } + } + + resPrefix := inputField + res := resPrefix + + if len(customList) > 0 { + if listType { + res = fmt.Sprintf("{...item, %s}", strings.Join(customList, ",")) + + } else { + res = fmt.Sprintf("{...%s, %s}", resPrefix, strings.Join(customList, ",")) + } + + if listType { + res = fmt.Sprintf("%s?.map((item: any) => ( %s ))", resPrefix, res) + } else if f.Nullable() { + res = fmt.Sprintf("%s ? %s: undefined", resPrefix, res) + } + inputField = res + } + return fmt.Sprintf( "%s: %s,", f.TSPublicAPIName(), @@ -3246,10 +3353,61 @@ func buildCustomInterfaceNode(processor *codegen.Processor, ci *customtype.Custo Name: f.GetGraphQLName(), FieldImports: getGQLFileImports(f.GetTSGraphQLTypeForFieldImports(ciInfo.input), ciInfo.input), } + + fieldName := fmt.Sprintf("obj.%s", f.TsFieldName(processor.Config)) + + if !ciInfo.input { + fieldEdge := f.FieldEdgeInfo() + + if fieldEdge == nil { + if fkey := f.ForeignKeyInfo(); fkey != nil { + // handle types declared with foreignKey + // TODO should probably throw since this doesn't actually make sense since the foreignKey won't be respected + fieldEdge = &base.FieldEdgeInfo{ + Schema: fkey.Schema, + } + } + } + + // should exist for id fields... + if fieldEdge != nil { + + e, err := edge.GetFieldEdge( + processor.Config, + f.FieldName, + fieldEdge, + f.Nullable(), + f.GetFieldType(), + ) + + if err != nil { + return nil, err + } + + if e != nil { + // these 2 should change to loading via the constructor instead of this way + // i.e. Foo.loadEnt or whatever the API is + if e.IsList() { + if err := addPluralEdgeFromExternal(processor, e, f, result); err != nil { + return nil, err + } + + } else { + if err := addSingularEdgeFromExternal(processor, e, f, result); err != nil { + return nil, err + } + } + + continue + } + } + } + if !ciInfo.input && f.TsFieldName(processor.Config) != f.GetGraphQLName() { ft.HasResolveFunction = true - ft.FunctionContents = []string{fmt.Sprintf("return obj.%s", f.TsFieldName(processor.Config))} + ft.FunctionContents = []string{fmt.Sprintf("return %s", fieldName)} } + // } if err := result.addField(ft); err != nil { return nil, err } diff --git a/internal/schema/input/input.go b/internal/schema/input/input.go index 0cf0ea870..234a7c1fe 100644 --- a/internal/schema/input/input.go +++ b/internal/schema/input/input.go @@ -226,6 +226,7 @@ type Field struct { UserConvert *UserConvertType `json:"convert,omitempty"` FetchOnDemand bool `json:"fetchOnDemand,omitempty"` DBOnly bool `json:"dbOnly,omitempty"` + DisableBase64Encode bool `json:"disableBase64Encode,omitempty"` Immutable bool `json:"immutable,omitempty"` @@ -377,13 +378,13 @@ func getJSONOrJSONBType(typ *FieldType, nullable bool) enttype.TSType { } } -func getTypeFor(nodeName, fieldName string, typ *FieldType, nullable bool, foreignKey *ForeignKey) (enttype.TSType, error) { +func getTypeFor(nodeName, fieldName string, typ *FieldType, nullable bool, foreignKey *ForeignKey, disableBase64Encode bool) (enttype.TSType, error) { switch typ.DBType { case UUID: if nullable { - return &enttype.NullableIDType{}, nil + return &enttype.NullableIDType{DisableBase64Encode: disableBase64Encode}, nil } - return &enttype.IDType{}, nil + return &enttype.IDType{DisableBase64Encode: disableBase64Encode}, nil case Int64ID: return nil, fmt.Errorf("unsupported Int64ID type") // return &enttype.IntegerType{}, nil @@ -583,7 +584,7 @@ func (f *Field) GetEntType(nodeName string) (enttype.TSType, error) { if f.Type.ListElemType == nil { return nil, fmt.Errorf("list elem type for list is nil") } - elemType, err := getTypeFor(nodeName, f.Name, f.Type.ListElemType, false, nil) + elemType, err := getTypeFor(nodeName, f.Name, f.Type.ListElemType, false, nil, f.DisableBase64Encode) if err != nil { return nil, err } @@ -596,7 +597,7 @@ func (f *Field) GetEntType(nodeName string) (enttype.TSType, error) { ElemType: elemType, }, nil } else { - return getTypeFor(nodeName, f.Name, f.Type, f.Nullable, f.ForeignKey) + return getTypeFor(nodeName, f.Name, f.Type, f.Nullable, f.ForeignKey, f.DisableBase64Encode) } } diff --git a/internal/schema/schema.go b/internal/schema/schema.go index 4f71e0fac..b27ba9dd2 100644 --- a/internal/schema/schema.go +++ b/internal/schema/schema.go @@ -902,7 +902,10 @@ func (s *Schema) checkForEnum(cfg codegenapi.Config, f *field.Field, ci *customt } actualSubFields := subFields.([]*input.Field) // use the parent of the field to determine or just nest it all the way based on parent - fi, err := field.NewFieldInfoFromInputs(cfg, f.FieldName, actualSubFields, &field.Options{}) + fi, err := field.NewFieldInfoFromInputs(cfg, f.FieldName, actualSubFields, &field.Options{ + // no builder type on sub-fields + ForceDisableBuilderType: true, + }) if err != nil { return err } @@ -959,7 +962,9 @@ func (s *Schema) checkCustomInterface(cfg codegenapi.Config, f *field.Field, roo root.Children = append(root.Children, ci) } - fi, err := field.NewFieldInfoFromInputs(cfg, f.FieldName, subFields, &field.Options{}) + fi, err := field.NewFieldInfoFromInputs(cfg, f.FieldName, subFields, &field.Options{ + ForceDisableBuilderType: true, + }) if err != nil { return nil, err } @@ -1015,7 +1020,9 @@ func (s *Schema) getCustomUnion(cfg codegenapi.Config, f *field.Field, globalTyp } actualSubFields := unionFields.([]*input.Field) - fi, err := field.NewFieldInfoFromInputs(cfg, f.FieldName, actualSubFields, &field.Options{}) + fi, err := field.NewFieldInfoFromInputs(cfg, f.FieldName, actualSubFields, &field.Options{ + ForceDisableBuilderType: true, + }) if err != nil { return nil, err } @@ -1027,7 +1034,9 @@ func (s *Schema) getCustomUnion(cfg codegenapi.Config, f *field.Field, globalTyp ci.GraphQLFieldName = f2.GetGraphQLName() // get the fields and add to custom interface - fi2, err := field.NewFieldInfoFromInputs(cfg, f2.FieldName, subFields, &field.Options{}) + fi2, err := field.NewFieldInfoFromInputs(cfg, f2.FieldName, subFields, &field.Options{ + ForceDisableBuilderType: true, + }) if err != nil { return nil, err } diff --git a/ts/src/schema/schema.ts b/ts/src/schema/schema.ts index 737098d4d..8276d190a 100644 --- a/ts/src/schema/schema.ts +++ b/ts/src/schema/schema.ts @@ -592,6 +592,9 @@ export interface FieldOptions { fetchOnDemand?: boolean; + // on uuid types, provides the ability to disable base 64 encoding of the uuid if for example this is a raw uuid not associated with an ent/object in the db + disableBase64Encode?: boolean; + // if dbOnly, field isn't exposed in ent and graphql // will still exit in the db and not be removed // allows keeping the field in the db and avoid data loss if we still want the field for some reason