Skip to content

feature: Type relationships as TExpand#135

Open
g12i wants to merge 9 commits into
patmood:mainfrom
g12i:type-relationships
Open

feature: Type relationships as TExpand#135
g12i wants to merge 9 commits into
patmood:mainfrom
g12i:type-relationships

Conversation

@g12i

@g12i g12i commented Jul 22, 2025

Copy link
Copy Markdown

This PR adds support for mapping TExpand field with actual relationships between types.

For example, given 3 collections:

Author -> (has many) -> Courses -> (has many) Chapters -> (has many) (sub) Chapters

image

It would generate following schema:

export type AuthorsResponse<Texpand = {
	courses_via_author?: CoursesRecord[]
}> = Required<AuthorsRecord> & BaseSystemFields<Texpand>
export type ChaptersResponse<Texpand = {
	course?: CoursesRecord,
	parent?: ChaptersRecord,
	chapters_via_parent?: ChaptersRecord[],
}> = Required<ChaptersRecord> & BaseSystemFields<Texpand>
export type CoursesResponse<Texpand = {
	author?: AuthorsRecord,
	chapters_via_course?: ChaptersRecord[]
}> = Required<CoursesRecord> & BaseSystemFields<Texpand>

@patmood

patmood commented Jul 24, 2025

Copy link
Copy Markdown
Owner

Thanks for the contribution and putting the work into this. It's been attempted a few times before but was ultimately too complicated.

Does it handle nested fields? They can be up to 6 levels deep.

@g12i

g12i commented Jul 24, 2025

Copy link
Copy Markdown
Author

Thanks for the contribution and putting the work into this. It's been attempted a few times before but was ultimately too complicated.

Does it handle nested fields? They can be up to 6 levels deep.

I'm afraid not @patmood - as it types it as ModelRecord and not ModelResponse.

@g12i

g12i commented Jul 26, 2025

Copy link
Copy Markdown
Author

Hey @patmood, so I'm testing that IRL, and I changed it to expand with ModelResponse. Now it is indeed recursive and works for nested fields.

image

Of course, as we don't know what the user queried for, it shows all possible outcomes.

I tried to contribute to SDK with that feature, but it wasn't approved.

pocketbase/js-sdk#351

But, in theory we could try to implement this at generated types level.

Comment thread src/constants.ts
@g12i

g12i commented Aug 7, 2025

Copy link
Copy Markdown
Author

@patmood any thoughts?

@patmood

patmood commented Aug 12, 2025 via email

Copy link
Copy Markdown
Owner

@patmood patmood mentioned this pull request Oct 1, 2025
@patmood

patmood commented Oct 7, 2025

Copy link
Copy Markdown
Owner

I haven't forgotten about this. I think the pb_schema in the repo must be outdated and is missing some relation metadata, which is why the output is unchanged for the example types. I will update it and finish reviewing.

@patmood patmood left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the slow review @g12i - This is really good stuff though.

To get this merged I this merged I think we need to:

  • get to the bottom of collectionId in the schema (were you using an old PB version?)
  • after fixing that, generate new example types
  • fix merge conflicts with latest changes

Are you still interested in getting this merged?

Comment thread src/types.ts
system: boolean
required: boolean
unique: boolean
options?: { collectionId?: string }

@patmood patmood Oct 29, 2025

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not exist in the latest version of pocketbase. collectionId is just part of the FieldSchema. So you know where you go this from? Was it a change in a recent version of pocketbase?

Suggested change
options?: { collectionId?: string }
// older pocketbase versions nested data under an `options` field
options?: { collectionId?: string }
collectionId?: string

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @patmood, I need to check. But it might take a while, as I've been doing this on another machine. Will come back to you!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool I think we can support both with a comment that the old structure is only up X version. That way it's backwards compatible.

Comment thread src/lib.ts
relationNodes.forEach((childNode) => {
childNode.fields.forEach((field) => {
const parentId =
field.type === "relation" ? field.options?.collectionId : undefined

@patmood patmood Oct 29, 2025

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was why I couldn't get it working....

Suggested change
field.type === "relation" ? field.options?.collectionId : undefined
field.options?.collectionId || field.collectionId

@patmood

patmood commented Dec 26, 2025

Copy link
Copy Markdown
Owner

Hey @g12i - Did you want to make those updates? If not, I have some time and can merge this into a different branch and take it over.

@g12i

g12i commented Jan 7, 2026

Copy link
Copy Markdown
Author

Hey @patmood, sorry I was on holiday. Now I'm back and kind of busy with day-to-day, so feel free to take it over

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants