Skip to content

Commit 503f6f1

Browse files
committed
[#251] added optional RecordService generic type
1 parent d741c3b commit 503f6f1

15 files changed

+229
-151
lines changed

CHANGELOG.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,37 @@
1+
## 0.18.3
2+
3+
- Added optional generic support for the `RecordService` ([#251](https://github.com/pocketbase/js-sdk/issues/251)).
4+
This should allow specifying a single TypeScript definition for the client, eg. using type assertion:
5+
```ts
6+
interface Task {
7+
id: string;
8+
name: string;
9+
}
10+
11+
interface Post {
12+
id: string;
13+
title: string;
14+
active: boolean;
15+
}
16+
17+
interface TypedPocketBase extends PocketBase {
18+
collection(idOrName: string): RecordService // default fallback for any other collection
19+
collection(idOrName: 'tasks'): RecordService<Task>
20+
collection(idOrName: 'posts'): RecordService<Post>
21+
}
22+
23+
...
24+
25+
const pb = new PocketBase("http://127.0.0.1:8090") as TypedPocketBase;
26+
27+
// the same as pb.collection('tasks').getOne<Task>("RECORD_ID")
28+
await pb.collection('tasks').getOne("RECORD_ID") // -> results in Task
29+
30+
// the same as pb.collection('posts').getOne<Post>("RECORD_ID")
31+
await pb.collection('posts').getOne("RECORD_ID") // -> results in Post
32+
```
33+
34+
135
## 0.18.2
236

337
- Added support for assigning a `Promise` as `AsyncAuthStore` initial value ([#249](https://github.com/pocketbase/js-sdk/issues/249)).

README.md

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Official JavaScript SDK (browser and node) for interacting with the [PocketBase
1414
- [Custom auth store](#custom-auth-store)
1515
- [Common auth store fields and methods](#common-auth-store-fields-and-methods)
1616
- [Auto cancellation](#auto-cancellation)
17-
- [Custom Record types](#custom-record-types)
17+
- [Specify TypeScript definitions](#specify-typescript-definitions)
1818
- [Custom request options](#custom-request-options)
1919
- [Send hooks](#send-hooks)
2020
- [SSR integration](#ssr-integration)
@@ -289,7 +289,7 @@ pb.collection('example').getList(1, 20); // executed
289289
To manually cancel pending requests, you could use `pb.cancelAllRequests()` or `pb.cancelRequest(requestKey)`.
290290

291291

292-
### Custom Record types
292+
### Specify TypeScript definitions
293293

294294
You could specify custom TypeScript definitions for your Record models using generics:
295295

@@ -304,6 +304,34 @@ pb.collection('tasks').getList<Task>(1, 20) // -> results in Promise<ListResult<
304304
pb.collection('tasks').getOne<Task>("RECORD_ID") // -> results in Promise<Task>
305305
```
306306

307+
Alternatively, if you don't want to type the generic argument every time you can define a global PocketBase type using type assertion:
308+
309+
```ts
310+
interface Task {
311+
id: string;
312+
name: string;
313+
}
314+
315+
interface Post {
316+
id: string;
317+
title: string;
318+
active: boolean;
319+
}
320+
321+
interface TypedPocketBase extends PocketBase {
322+
collection(idOrName: string): RecordService // default fallback for any other collection
323+
collection(idOrName: 'tasks'): RecordService<Task>
324+
collection(idOrName: 'posts'): RecordService<Post>
325+
}
326+
327+
...
328+
329+
const pb = new PocketBase("http://127.0.0.1:8090") as TypedPocketBase;
330+
331+
pb.collection('tasks').getOne("RECORD_ID") // -> results in Promise<Task>
332+
pb.collection('posts').getOne("RECORD_ID") // -> results in Promise<Post>
333+
```
334+
307335
308336
### Custom request options
309337

dist/pocketbase.cjs.d.ts

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,10 @@ declare abstract class BaseService {
108108
constructor(client: Client);
109109
}
110110
interface SendOptions extends RequestInit {
111-
[key: string]: any; // for backward compatibility
111+
// for backward compatibility and to minimize the verbosity,
112+
// any top-level field that doesn't exist in RequestInit or the
113+
// fields below will be treated as query parameter.
114+
[key: string]: any;
112115
/**
113116
* Optional custom fetch function to use for sending the request.
114117
*/
@@ -124,7 +127,7 @@ interface SendOptions extends RequestInit {
124127
*/
125128
body?: any;
126129
/**
127-
* Query params that will be appended to the request url.
130+
* Query parameters that will be appended to the request url.
128131
*/
129132
query?: {
130133
[key: string]: any;
@@ -570,7 +573,7 @@ interface OAuth2AuthConfig extends SendOptions {
570573
// optional query params to send with the PocketBase auth request (eg. fields, expand, etc.)
571574
query?: RecordOptions;
572575
}
573-
declare class RecordService extends CrudService<RecordModel> {
576+
declare class RecordService<M = RecordModel> extends CrudService<M> {
574577
readonly collectionIdOrName: string;
575578
constructor(client: Client, collectionIdOrName: string);
576579
/**
@@ -589,11 +592,11 @@ declare class RecordService extends CrudService<RecordModel> {
589592
*
590593
* Subscribe to the realtime changes of a single record in the collection.
591594
*/
592-
subscribeOne<T = RecordModel>(recordId: string, callback: (data: RecordSubscription<T>) => void): Promise<UnsubscribeFunc>;
595+
subscribeOne<T = M>(recordId: string, callback: (data: RecordSubscription<T>) => void): Promise<UnsubscribeFunc>;
593596
/**
594597
* @deprecated This form of subscribe is deprecated. Please use `subscribe("*", callback)`.
595598
*/
596-
subscribe<T = RecordModel>(callback: (data: RecordSubscription<T>) => void): Promise<UnsubscribeFunc>;
599+
subscribe<T = M>(callback: (data: RecordSubscription<T>) => void): Promise<UnsubscribeFunc>;
597600
/**
598601
* Subscribe to realtime changes to the specified topic ("*" or record id).
599602
*
@@ -607,7 +610,7 @@ declare class RecordService extends CrudService<RecordModel> {
607610
* You can use the returned `UnsubscribeFunc` to remove only a single subscription.
608611
* Or use `unsubscribe(topic)` if you want to remove all subscriptions attached to the topic.
609612
*/
610-
subscribe<T = RecordModel>(topic: string, callback: (data: RecordSubscription<T>) => void): Promise<UnsubscribeFunc>;
613+
subscribe<T = M>(topic: string, callback: (data: RecordSubscription<T>) => void): Promise<UnsubscribeFunc>;
611614
/**
612615
* Unsubscribe from all subscriptions of the specified topic
613616
* ("*" or record id).
@@ -622,27 +625,27 @@ declare class RecordService extends CrudService<RecordModel> {
622625
/**
623626
* @inheritdoc
624627
*/
625-
getFullList<T = RecordModel>(options?: RecordFullListOptions): Promise<Array<T>>;
628+
getFullList<T = M>(options?: RecordFullListOptions): Promise<Array<T>>;
626629
/**
627630
* @inheritdoc
628631
*/
629-
getFullList<T = RecordModel>(batch?: number, options?: RecordListOptions): Promise<Array<T>>;
632+
getFullList<T = M>(batch?: number, options?: RecordListOptions): Promise<Array<T>>;
630633
/**
631634
* @inheritdoc
632635
*/
633-
getList<T = RecordModel>(page?: number, perPage?: number, options?: RecordListOptions): Promise<ListResult<T>>;
636+
getList<T = M>(page?: number, perPage?: number, options?: RecordListOptions): Promise<ListResult<T>>;
634637
/**
635638
* @inheritdoc
636639
*/
637-
getFirstListItem<T = RecordModel>(filter: string, options?: RecordListOptions): Promise<T>;
640+
getFirstListItem<T = M>(filter: string, options?: RecordListOptions): Promise<T>;
638641
/**
639642
* @inheritdoc
640643
*/
641-
getOne<T = RecordModel>(id: string, options?: RecordOptions): Promise<T>;
644+
getOne<T = M>(id: string, options?: RecordOptions): Promise<T>;
642645
/**
643646
* @inheritdoc
644647
*/
645-
create<T = RecordModel>(bodyParams?: {
648+
create<T = M>(bodyParams?: {
646649
[key: string]: any;
647650
} | FormData, options?: RecordOptions): Promise<T>;
648651
/**
@@ -651,7 +654,7 @@ declare class RecordService extends CrudService<RecordModel> {
651654
* If the current `client.authStore.model` matches with the updated id, then
652655
* on success the `client.authStore.model` will be updated with the result.
653656
*/
654-
update<T = RecordModel>(id: string, bodyParams?: {
657+
update<T = M>(id: string, bodyParams?: {
655658
[key: string]: any;
656659
} | FormData, options?: RecordOptions): Promise<T>;
657660
/**
@@ -667,7 +670,7 @@ declare class RecordService extends CrudService<RecordModel> {
667670
/**
668671
* Prepare successful collection authorization response.
669672
*/
670-
protected authResponse<T = RecordModel>(responseData: any): RecordAuthResponse<T>;
673+
protected authResponse<T = M>(responseData: any): RecordAuthResponse<T>;
671674
/**
672675
* Returns all available collection auth methods.
673676
*/
@@ -680,12 +683,12 @@ declare class RecordService extends CrudService<RecordModel> {
680683
* - the authentication token
681684
* - the authenticated record model
682685
*/
683-
authWithPassword<T = RecordModel>(usernameOrEmail: string, password: string, options?: RecordOptions): Promise<RecordAuthResponse<T>>;
686+
authWithPassword<T = M>(usernameOrEmail: string, password: string, options?: RecordOptions): Promise<RecordAuthResponse<T>>;
684687
/**
685688
* @deprecated
686689
* Consider using authWithPassword(usernameOrEmail, password, options?).
687690
*/
688-
authWithPassword<T = RecordModel>(usernameOrEmail: string, password: string, body?: any, query?: any): Promise<RecordAuthResponse<T>>;
691+
authWithPassword<T = M>(usernameOrEmail: string, password: string, body?: any, query?: any): Promise<RecordAuthResponse<T>>;
689692
/**
690693
* Authenticate a single auth collection record with OAuth2 code.
691694
*
@@ -697,14 +700,14 @@ declare class RecordService extends CrudService<RecordModel> {
697700
* - the authenticated record model
698701
* - the OAuth2 account data (eg. name, email, avatar, etc.)
699702
*/
700-
authWithOAuth2Code<T = RecordModel>(provider: string, code: string, codeVerifier: string, redirectUrl: string, createData?: {
703+
authWithOAuth2Code<T = M>(provider: string, code: string, codeVerifier: string, redirectUrl: string, createData?: {
701704
[key: string]: any;
702705
}, options?: RecordOptions): Promise<RecordAuthResponse<T>>;
703706
/**
704707
* @deprecated
705708
* Consider using authWithOAuth2Code(provider, code, codeVerifier, redirectUrl, createdData, options?).
706709
*/
707-
authWithOAuth2Code<T = RecordModel>(provider: string, code: string, codeVerifier: string, redirectUrl: string, createData?: {
710+
authWithOAuth2Code<T = M>(provider: string, code: string, codeVerifier: string, redirectUrl: string, createData?: {
708711
[key: string]: any;
709712
}, body?: any, query?: any): Promise<RecordAuthResponse<T>>;
710713
/**
@@ -713,7 +716,7 @@ declare class RecordService extends CrudService<RecordModel> {
713716
* Please use `authWithOAuth2Code()` OR its simplified realtime version
714717
* as shown in https://pocketbase.io/docs/authentication/#oauth2-integration.
715718
*/
716-
authWithOAuth2<T = RecordModel>(provider: string, code: string, codeVerifier: string, redirectUrl: string, createData?: {
719+
authWithOAuth2<T = M>(provider: string, code: string, codeVerifier: string, redirectUrl: string, createData?: {
717720
[key: string]: any;
718721
}, bodyParams?: {
719722
[key: string]: any;
@@ -749,19 +752,19 @@ declare class RecordService extends CrudService<RecordModel> {
749752
* you have to configure `https://yourdomain.com/api/oauth2-redirect`
750753
* as redirect URL.
751754
*/
752-
authWithOAuth2<T = RecordModel>(options: OAuth2AuthConfig): Promise<RecordAuthResponse<T>>;
755+
authWithOAuth2<T = M>(options: OAuth2AuthConfig): Promise<RecordAuthResponse<T>>;
753756
/**
754757
* Refreshes the current authenticated record instance and
755758
* returns a new token and record data.
756759
*
757760
* On success this method also automatically updates the client's AuthStore.
758761
*/
759-
authRefresh<T = RecordModel>(options?: RecordOptions): Promise<RecordAuthResponse<T>>;
762+
authRefresh<T = M>(options?: RecordOptions): Promise<RecordAuthResponse<T>>;
760763
/**
761764
* @deprecated
762765
* Consider using authRefresh(options?).
763766
*/
764-
authRefresh<T = RecordModel>(body?: any, query?: any): Promise<RecordAuthResponse<T>>;
767+
authRefresh<T = M>(body?: any, query?: any): Promise<RecordAuthResponse<T>>;
765768
/**
766769
* Sends auth record password reset request.
767770
*/
@@ -1046,7 +1049,7 @@ declare class Client {
10461049
* @param {string} idOrName
10471050
* @return {RecordService}
10481051
*/
1049-
collection(idOrName: string): RecordService;
1052+
collection<M = RecordModel>(idOrName: string): RecordService<M>;
10501053
/**
10511054
* Globally enable or disable auto cancellation for pending duplicated requests.
10521055
*/

dist/pocketbase.cjs.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)