Skip to content
This repository was archived by the owner on Nov 19, 2024. It is now read-only.

Commit 7ddb89f

Browse files
authored
Merge pull request #1 from satohshi/optional-expand
update
2 parents 7bd7f1b + fb97424 commit 7ddb89f

File tree

4 files changed

+257
-89
lines changed

4 files changed

+257
-89
lines changed

.changeset/modern-books-beam.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
"pb-option-builder": patch
3+
---
4+
5+
- Better handling of situations where relation field in "expand" is optional
6+
- Added autocomplete for "sort"
7+
- Added support for ":excerpt" modifier

README.md

+53-8
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ This is how you would normally write options for the PocketBase SDK:
99
fields: 'id,title,expand.comments(post).user,expand.comments(post).message,expand.tags.id,expand.tags.name'
1010
}
1111
```
12-
Writing options manually like this is very error-prone and hard to read/maintain.
12+
Writing options manually like this is very error-prone, and makes the code very hard to read/maintain.
1313

1414
This option builder allows you to write it like this instead:
1515
```js
@@ -22,7 +22,7 @@ This option builder allows you to write it like this instead:
2222
]
2323
}
2424
```
25-
It comes with autocomplete for `key`, `fields` and `expand` options, and also provides you a way to **type the response**.
25+
It comes with autocomplete for `key`, `fields`, `expand` and `sort` options, and also provides you a way to **type the response**.
2626

2727

2828
## Installation
@@ -80,8 +80,10 @@ type Relations = {
8080

8181
// back-relations
8282
"posts(tags)": Array<Post>
83-
"comments(post)": Array<Comment>
84-
"comments(user)": Array<Comment>
83+
84+
// Add "?" modifier to annotate optional relation fields
85+
"comments(post)"?: Array<Comment> // i.e. post might not have any comments
86+
"comments(user)"?: Array<Comment> // i.e. user might not have any comments
8587
}
8688
```
8789
@@ -101,7 +103,7 @@ const [optionsObj, typeObj] = optionBuilder({
101103
expand: [
102104
{
103105
key: 'tags'
104-
// returns all fields if it's not specified
106+
// returns all fields if not specified
105107
},
106108
{
107109
key: 'comments(post)',
@@ -127,7 +129,7 @@ const result = await pb.collection('posts').getOne<typeof typeObj>(optionsObj);
127129
It's a bit hacky and not very pretty, but does the job.
128130

129131

130-
### Parameter type for `optionBuilder`:
132+
### Parameter type for the option builder:
131133
```ts
132134
{
133135
// Table name as defined in "Schema"
@@ -152,7 +154,6 @@ ExpandItem {
152154
fields?: // same as above
153155
expand?: // same as above
154156
}
155-
156157
```
157158

158159

@@ -161,7 +162,7 @@ ExpandItem {
161162
You might run into a situation where you have a component that requires a specific set of fields to be passed to it, and it makes sense to fetch the item directly in one route, but in another, it makes sense to do so through `expand`.
162163

163164

164-
Because of the way the argument for the option builder is structured, the `fields` array is portable.
165+
Because of the way the parameter for the option builder is structured, the `fields` array is portable.
165166
You can define the fields in one place, and use it either at the top level, or in the `expand` option **as is** .
166167

167168
Example:
@@ -199,6 +200,49 @@ const [optionsObj, typeObj] = optionBuilder({
199200
})
200201
```
201202

203+
204+
### Handling of optional relation fields
205+
Let's say you want to get a post with its comments using `expand`.
206+
When the post doesn't have any comments, the SDK (or PocketBase itself rather) returns:
207+
208+
```ts
209+
{
210+
id: "1",
211+
title: "Lorem ipsum",
212+
tags: ["lorem", "ipsum"],
213+
created: "2024-01-01T00:00:00.000Z",
214+
updated: "2024-01-01T00:00:00.000Z"
215+
}
216+
```
217+
218+
The response won't even have
219+
220+
```ts
221+
{
222+
expand: undefined
223+
}
224+
// or
225+
{
226+
expand: {
227+
"comments(post)": []
228+
}
229+
}
230+
```
231+
232+
So if all the specified expands are for optional relation fields, the option builder will add `?` modifier to the expand field itself.
233+
i.e. the return type will be:
234+
235+
```ts
236+
Post & {
237+
expand?: {
238+
"comments(post)": Comment[]
239+
}
240+
}
241+
```
242+
243+
If you don't need this much of type-safety and find this behaviour annoying, you can opt out by not adding `?` when defining `Relation`.
244+
245+
202246
## Caveat:
203247
In order for back-relations to work, you need to have the forward-relations defined as well.
204248
```ts
@@ -221,6 +265,7 @@ const [optionsObj, typeObj] = optionBuilder({
221265
})
222266
```
223267

268+
224269
## Why not just integrate this into the SDK?
225270
- This way, you can start using this in existing projects without having to change anything. I think most of the time, you don't need to pass in any options to the SDK, so installing a new custom SDK for a very few instances where you need to seems like an overkill.
226271
- There are many functionalities of the official SDK that I don't use or understand fully, and I don't want to maintain a fork of it just for this.

0 commit comments

Comments
 (0)