Created
June 25, 2024 10:33
-
-
Save lightningspirit/af13b4b8a4d1ffaee698d9de09a62d3c to your computer and use it in GitHub Desktop.
Pocketbase typings for collections
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import PocketBaseClient from './pocketbase.ts' | |
type RecordMap = { | |
accounts: RecordAccount | |
categories: RecordCategory | |
pages: RecordPage | |
prices: RecordPrice | |
products: RecordProduct | |
users: RecordUser | |
} | |
type ModelMap = { | |
accounts: Account | |
categories: Category | |
pages: Page | |
prices: Price | |
products: Product | |
users: User | |
} | |
type Mappers = { | |
[K in keyof RecordMap]: (record: RecordMap[K]) => ModelMap[K] | |
} | |
function common(record: RecordModel) { | |
return { | |
id: record.id, | |
created: new Date(record.created), | |
updated: new Date(record.updated), | |
} | |
} | |
const mapper: Mappers = { | |
accounts(record) { | |
return { | |
...record, | |
...common(record), | |
expand: undefined, | |
} | |
}, | |
categories(record) { | |
return { | |
...record, | |
...common(record), | |
expand: undefined, | |
} | |
}, | |
pages(record) { | |
return { | |
...record, | |
...common(record), | |
expand: undefined, | |
} | |
}, | |
prices(record) { | |
return { | |
name: record.name, | |
amount: { | |
usd: record.dollar, | |
eur: record.euro, | |
}, | |
...common(record), | |
} | |
}, | |
products(record) { | |
return { | |
...record, | |
...common(record), | |
images: previews.map((it) => pb.files.getUrl(record, it)), | |
expand: { | |
author: record.expand?.author | |
? mapper.users(record.expand.author) | |
: undefined, | |
category: record.expand?.category | |
? mapper.categories(record.expand.category) | |
: undefined, | |
prices: record.expand?.prices | |
? record.expand.prices.map(mapper.prices) | |
: undefined, | |
}, | |
} | |
}, | |
users: (record) => { | |
return { | |
...record, | |
...common(record), | |
avatar: record.avatar ? pb.files.getUrl(record, record.avatar) : undefined, | |
} | |
}, | |
} | |
const pb = new PocketBaseClient<RecordMap, ModelMap>({ | |
baseUrl: process.env.POCKETBASE_URL || 'http://127.0.0.1:8090', | |
mapper, | |
}) | |
export default pb |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import PocketBase, { | |
BaseAuthStore, | |
RecordModel, | |
RecordService, | |
} from 'pocketbase' | |
type RecordMapGeneric = { | |
[s: string]: RecordModel | |
} | |
type Mapper< | |
RMap extends RecordMapGeneric, | |
MMap extends { [K in keyof RMap]: any }, | |
> = { | |
[K in keyof RMap]: (record: RMap[K]) => MMap[K] | |
} | |
class TypedRecordService< | |
RMap extends RecordMapGeneric, | |
MMap extends { [K in keyof RMap]: any }, | |
K extends keyof RMap, | |
> extends RecordService<MMap[K]> { | |
private mapper: Mapper<RMap, MMap> | |
private idOrName: K | |
constructor( | |
client: PocketBase, | |
collectionIdOrName: K, | |
mapper: Mapper<RMap, MMap>, | |
) { | |
super(client, collectionIdOrName.toString()) | |
this.idOrName = collectionIdOrName | |
this.mapper = mapper | |
} | |
decode(record: RMap[K]): MMap[K] { | |
return this.mapper[this.idOrName](record) | |
} | |
} | |
class PocketBaseClient< | |
RMap extends RecordMapGeneric, | |
MMap extends { [K in keyof RMap]: any }, | |
> extends PocketBase { | |
private mapper: Mapper<RMap, MMap> | |
private services: Partial<{ | |
[K in keyof RMap]: TypedRecordService<RMap, MMap, K> | |
}> = {} | |
constructor({ | |
mapper, | |
baseUrl, | |
authStore, | |
lang, | |
}: { | |
baseUrl?: string | |
authStore?: BaseAuthStore | null | |
lang?: string | |
mapper: Mapper<RMap, MMap> | |
}) { | |
super(baseUrl, authStore, lang) | |
this.mapper = mapper | |
} | |
collection<K extends keyof RMap>( | |
idOrName: K, | |
): TypedRecordService<RMap, MMap, K> { | |
if (!this.services[idOrName]) { | |
this.services[idOrName] = new TypedRecordService<RMap, MMap, K>( | |
this, | |
idOrName, | |
this.mapper, | |
) | |
} | |
return this.services[idOrName]! | |
} | |
} | |
export default PocketBaseClient |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment