typed-pocketbase
Advanced tools
Comparing version
{ | ||
"name": "typed-pocketbase", | ||
"version": "0.0.2", | ||
"version": "0.0.3-next.0", | ||
"description": "Add types to the PocketBase JavaScript SDK", | ||
@@ -19,13 +19,21 @@ "author": "David Plugge", | ||
], | ||
"main": "./dist/index.js", | ||
"module": "./dist/index.mjs", | ||
"types": "./dist/index.d.ts", | ||
"type": "module", | ||
"main": "./dist/client/index.js", | ||
"module": "./dist/client/index.mjs", | ||
"types": "./dist/client/index.d.ts", | ||
"bin": { | ||
"typed-pocketbase": "dist/codegen/index.js" | ||
}, | ||
"peerDependencies": { | ||
"pocketbase": "^0.15.2" | ||
}, | ||
"dependencies": { | ||
"sade": "^1.8.1" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^18.13.0", | ||
"@changesets/cli": "^2.26.1", | ||
"pocketbase": "^0.15.2", | ||
"typescript": "^5.1.3", | ||
"tsup": "^7.0.0", | ||
"tsup": "^7.1.0", | ||
"prettier": "^2.8.8" | ||
@@ -32,0 +40,0 @@ }, |
@@ -1,2 +0,2 @@ | ||
import { BaseRecord } from './types'; | ||
import { BaseRecord } from './types.js'; | ||
@@ -3,0 +3,0 @@ export type FieldsParam<T extends BaseRecord, S extends keyof T> = { |
@@ -1,4 +0,8 @@ | ||
import { BaseRecord } from './types'; | ||
import { BaseRecord } from './types.js'; | ||
type ActualFilter<T extends BaseRecord, K extends keyof T = keyof T> = [K, FilterOperand, T[K]]; | ||
type ActualFilter<T extends any, K extends keyof T = keyof T> = [ | ||
K, | ||
FilterOperand, | ||
T[K] | ||
]; | ||
@@ -39,6 +43,10 @@ export type FilterOperand = | ||
.filter(Boolean) | ||
.map((filter) => (Array.isArray(filter) ? serializeFilter(filter) : filter)); | ||
.map((filter) => | ||
Array.isArray(filter) ? serializeFilter(filter) : filter | ||
); | ||
} | ||
export function and<T extends BaseRecord>(...filters: Filter<T>[]): FilterParam<T> { | ||
export function and<T extends BaseRecord>( | ||
...filters: Filter<T>[] | ||
): FilterParam<T> { | ||
const str = serializeFilters(filters).join(' && '); | ||
@@ -49,6 +57,10 @@ | ||
export function or<T extends BaseRecord>(...filters: Filter<T>[]): FilterParam<T> { | ||
export function or<T extends BaseRecord>( | ||
...filters: Filter<T>[] | ||
): FilterParam<T> { | ||
const str = filters | ||
.filter(Boolean) | ||
.map((filter) => (Array.isArray(filter) ? serializeFilter(filter) : filter)) | ||
.map((filter) => | ||
Array.isArray(filter) ? serializeFilter(filter) : filter | ||
) | ||
.join(' || '); | ||
@@ -55,0 +67,0 @@ return `(${str})`; |
@@ -1,6 +0,20 @@ | ||
export { TypedPocketBase } from './pocketbase'; | ||
export { TypedRecordService } from './record-service'; | ||
import PocketBase from 'pocketbase'; | ||
import { GenericSchema } from './types.js'; | ||
import { TypedRecordService } from './record-service.js'; | ||
import { TypedFileService } from './file-service.js'; | ||
export { fields } from './fields'; | ||
export { and, eq, gt, gte, like, lt, lte, neq, nlike, or } from './filter'; | ||
export { asc, desc, sort } from './sort'; | ||
export { fields } from './fields.js'; | ||
export { and, or, eq, gt, gte, like, lt, lte, neq, nlike } from './filter.js'; | ||
export { expand } from './expand.js'; | ||
export { asc, desc, sort } from './sort.js'; | ||
export { GenericSchema, GenericCollection } from './types.js'; | ||
// @ts-expect-error typescript... | ||
export interface TypedPocketBase<Schema extends GenericSchema> | ||
extends PocketBase { | ||
collection<C extends keyof Schema>( | ||
idOrName: C | ||
): TypedRecordService<Schema[C]>; | ||
files: TypedFileService<Schema>; | ||
} |
import { | ||
BaseQueryParams, | ||
FullListQueryParams, | ||
ListQueryParams, | ||
ListResult, | ||
RecordListQueryParams, | ||
RecordQueryParams, | ||
RecordService, | ||
@@ -12,76 +7,154 @@ RecordSubscription, | ||
} from 'pocketbase'; | ||
import { Filter, FilterParam } from './filter'; | ||
import { BaseRecord, SystemFields, TypedRecord } from './types'; | ||
import { FieldsParam } from './fields'; | ||
import { SortParam } from './sort'; | ||
import { | ||
Simplify, | ||
GenericCollection, | ||
TypedRecord, | ||
Fields, | ||
Columns, | ||
GenericExpand, | ||
LooseAutocomplete, | ||
RecordWithExpandToDotPath, | ||
BaseRecord | ||
} from './types.js'; | ||
import { FieldsParam } from './fields.js'; | ||
import { Filter, FilterParam } from './filter.js'; | ||
import { SortParam } from './sort.js'; | ||
import { ExpandParam } from './expand.js'; | ||
// @ts-expect-error | ||
export interface TypedRecordService<T extends BaseRecord = BaseRecord> extends RecordService { | ||
getFullList<Select extends keyof T = keyof T>( | ||
queryParams?: TypedFullListQueryParams<T, Select> | undefined | ||
): Promise<TypedRecord<T, Select>[]>; | ||
export interface TypedRecordService<Collection extends GenericCollection> | ||
extends RecordService { | ||
getFullList< | ||
Select extends Fields<Collection> = Fields<Collection>, | ||
Expand extends GenericExpand = {} | ||
>( | ||
queryParams?: TypedRecordFullListQueryParams<Collection, Select, Expand> | ||
): Promise< | ||
TypedRecord<Simplify<Pick<Columns<Collection>, Select>>, Expand>[] | ||
>; | ||
getFullList<Select extends keyof T = keyof T>( | ||
getFullList< | ||
Select extends Fields<Collection> = Fields<Collection>, | ||
Expand extends GenericExpand = {} | ||
>( | ||
batch?: number, | ||
queryParams?: TypedRecordListQueryParams<T, Select> | undefined | ||
): Promise<TypedRecord<T, Select>[]>; | ||
queryParams?: TypedRecordListQueryParams<Collection, Select, Expand> | ||
): Promise< | ||
TypedRecord<Simplify<Pick<Columns<Collection>, Select>>, Expand>[] | ||
>; | ||
getList<Select extends keyof T = keyof T>( | ||
page?: number | undefined, | ||
perPage?: number | undefined, | ||
queryParams?: TypedRecordListQueryParams<T, Select> | undefined | ||
): Promise<ListResult<TypedRecord<T, Select>>>; | ||
getList< | ||
Select extends Fields<Collection> = Fields<Collection>, | ||
Expand extends GenericExpand = {} | ||
>( | ||
page?: number, | ||
perPage?: number, | ||
queryParams?: TypedRecordListQueryParams<Collection, Select, Expand> | ||
): Promise< | ||
ListResult< | ||
TypedRecord<Simplify<Pick<Columns<Collection>, Select>>, Expand> | ||
> | ||
>; | ||
getFirstListItem<Select extends keyof T = keyof T>( | ||
filter: Filter<T>, | ||
queryParams?: TypedRecordListQueryParams<T, Select> | undefined | ||
): Promise<TypedRecord<T, Select>>; | ||
getFirstListItem< | ||
Select extends Fields<Collection> = Fields<Collection>, | ||
Expand extends GenericExpand = {} | ||
>( | ||
filter: Filter<RecordWithExpandToDotPath<Collection>>, | ||
queryParams?: TypedRecordListQueryParams<Collection, Select, Expand> | ||
): Promise< | ||
TypedRecord<Simplify<Pick<Columns<Collection>, Select>>, Expand> | ||
>; | ||
getOne<Select extends keyof T = keyof T>( | ||
getOne< | ||
Select extends Fields<Collection> = Fields<Collection>, | ||
Expand extends GenericExpand = {} | ||
>( | ||
id: string, | ||
queryParams?: TypedRecordQueryParams<T, Select> | undefined | ||
): Promise<TypedRecord<T, Select>>; | ||
queryParams?: TypedRecordQueryParams<Collection, Select, Expand> | ||
): Promise< | ||
TypedRecord<Simplify<Pick<Columns<Collection>, Select>>, Expand> | ||
>; | ||
create<Select extends keyof T = keyof T>( | ||
bodyParams: Omit<T, keyof SystemFields>, | ||
queryParams?: TypedRecordQueryParams<T, Select> | ||
): Promise<TypedRecord<T, Select>>; | ||
create< | ||
Select extends Fields<Collection> = Fields<Collection>, | ||
Expand extends GenericExpand = {} | ||
>( | ||
bodyParams: Collection['record'], | ||
queryParams?: TypedRecordQueryParams<Collection, Select, Expand> | ||
): Promise< | ||
TypedRecord<Simplify<Pick<Columns<Collection>, Select>>, Expand> | ||
>; | ||
update<Select extends keyof T = keyof T>( | ||
update< | ||
Select extends Fields<Collection> = Fields<Collection>, | ||
Expand extends GenericExpand = {} | ||
>( | ||
id: string, | ||
bodyParams: Partial<Omit<T, keyof SystemFields>>, | ||
queryParams?: TypedRecordQueryParams<T, Select> | ||
): Promise<TypedRecord<T, Select>>; | ||
bodyParams: Partial<Collection['record']>, | ||
queryParams?: TypedRecordQueryParams<Collection, Select, Expand> | ||
): Promise< | ||
TypedRecord<Simplify<Pick<Columns<Collection>, Select>>, Expand> | ||
>; | ||
subscribe( | ||
topic: '*' | (string & {}), | ||
callback: (data: RecordSubscription<TypedRecord<T>>) => void | ||
topic: LooseAutocomplete<'*'>, | ||
callback: ( | ||
data: RecordSubscription<TypedRecord<Columns<Collection>>> | ||
) => void | ||
): Promise<UnsubscribeFunc>; | ||
subscribe( | ||
callback: ( | ||
data: RecordSubscription<TypedRecord<Columns<Collection>>> | ||
) => void | ||
): Promise<UnsubscribeFunc>; | ||
} | ||
export interface TypedBaseQueryParams<T extends BaseRecord, S extends keyof T> | ||
extends BaseQueryParams { | ||
fields?: FieldsParam<T, S>; | ||
export interface TypedBaseQueryParams< | ||
T extends GenericCollection, | ||
S extends Fields<T> | ||
> { | ||
fields?: FieldsParam<Columns<T>, S>; | ||
$autoCancel?: boolean; | ||
$cancelKey?: string; | ||
} | ||
export interface TypedRecordQueryParams<T extends BaseRecord, S extends keyof T> | ||
extends TypedBaseQueryParams<T, S>, | ||
Omit<RecordQueryParams, 'fields'> { | ||
expand?: string; | ||
export interface TypedListQueryParams< | ||
T extends GenericCollection, | ||
S extends Fields<T> | ||
> extends TypedBaseQueryParams<T, S> { | ||
page?: number; | ||
perPage?: number; | ||
sort?: SortParam<RecordWithExpandToDotPath<T>>; | ||
filter?: FilterParam<RecordWithExpandToDotPath<T>>; | ||
} | ||
export interface TypedListQueryParams<T extends BaseRecord, S extends keyof T> | ||
extends TypedBaseQueryParams<T, S>, | ||
Omit<ListQueryParams, 'fields' | 'filter' | 'sort'> { | ||
filter?: FilterParam<T>; | ||
sort?: SortParam<T>; | ||
export interface TypedFullListQueryParams< | ||
T extends GenericCollection, | ||
S extends Fields<T> | ||
> extends TypedListQueryParams<T, S> { | ||
batch?: number; | ||
} | ||
export interface TypedFullListQueryParams<T extends BaseRecord, S extends keyof T> | ||
extends TypedListQueryParams<T, S>, | ||
Omit<FullListQueryParams, 'fields' | 'filter' | 'sort'> {} | ||
export interface TypedRecordQueryParams< | ||
T extends GenericCollection, | ||
S extends Fields<T>, | ||
E extends GenericExpand | ||
> extends TypedBaseQueryParams<T, S> { | ||
expand?: ExpandParam<T, E>; | ||
} | ||
export interface TypedRecordListQueryParams<T extends BaseRecord, S extends keyof T> | ||
extends TypedListQueryParams<T, S>, | ||
TypedRecordQueryParams<T, S>, | ||
Omit<RecordListQueryParams, 'fields' | 'filter' | 'sort'> {} | ||
export interface TypedRecordListQueryParams< | ||
T extends GenericCollection, | ||
S extends Fields<T>, | ||
E extends GenericExpand | ||
> extends TypedListQueryParams<T, S>, | ||
TypedRecordQueryParams<T, S, E> {} | ||
export interface TypedRecordFullListQueryParams< | ||
T extends GenericCollection, | ||
S extends Fields<T>, | ||
E extends GenericExpand | ||
> extends TypedFullListQueryParams<T, S>, | ||
TypedRecordQueryParams<T, S, E> {} |
@@ -1,2 +0,2 @@ | ||
import { BaseRecord } from './types'; | ||
import { BaseRecord } from './types.js'; | ||
@@ -7,4 +7,6 @@ export type SortParam<T extends BaseRecord> = { | ||
export type PrefixedSortItem<T> = T extends string ? `${'+' | '-'}${T}` : never; | ||
export function sort<T extends BaseRecord>( | ||
...sorters: Array<SortParam<T> | `${'+' | '-'}${keyof T & string}`> | ||
...sorters: Array<SortParam<T> | PrefixedSortItem<keyof T>> | ||
): SortParam<T> { | ||
@@ -11,0 +13,0 @@ return sorters.filter(Boolean).join(','); |
115
src/types.ts
import { Record as PocketBaseRecord } from 'pocketbase'; | ||
type Simplify<T> = T extends infer o ? { [K in keyof o]: o[K] } : never; | ||
export type Simplify<T> = T extends infer o ? { [K in keyof o]: o[K] } : never; | ||
export type ArrayInnerType<T> = T extends Array<infer V> ? V : T; | ||
export type Values<T> = T[keyof T]; | ||
export type Overide<A, B> = Simplify<Omit<A, keyof B> & B>; | ||
export type RemoveIndex<T> = { | ||
[K in keyof T as string extends K | ||
? never | ||
: number extends K | ||
? never | ||
: symbol extends K | ||
? never | ||
: K]: T[K]; | ||
}; | ||
export type LooseAutocomplete<T> = T | (string & {}); | ||
export type UnionToIntersection<T> = ( | ||
T extends any ? (x: T) => any : never | ||
) extends (x: infer R) => any | ||
? R | ||
: never; | ||
export type BaseRecord = Record<string, any>; | ||
export type BaseResponse = Record<string, any>; | ||
export type BaseSystemFields = { | ||
id: string; | ||
created: string; | ||
updated: string; | ||
}; | ||
export interface GenericCollection { | ||
collectionId: string; | ||
collectionName: string; | ||
record: BaseRecord; | ||
response: BaseResponse; | ||
files: Record< | ||
string, | ||
{ | ||
thumbs: string; | ||
} | ||
>; | ||
relations: Record<string, GenericCollection | GenericCollection[]>; | ||
} | ||
export interface GenericSchema { | ||
[K: string]: GenericCollection; | ||
} | ||
export type TypedRecord< | ||
T, | ||
Keys extends keyof T = keyof T, | ||
Data = Simplify<Pick<T, Keys>> | ||
> = Data & { | ||
export(): Data; | ||
$export(): Data; | ||
} & Omit<PocketBaseRecord, 'export' | '$export'>; | ||
Data extends BaseRecord, | ||
Expand extends GenericExpand = {} | ||
> = Pick<PocketBaseRecord, 'load' | '$load' | '$isNew'> & | ||
Data & { | ||
load(data: Data): void; | ||
$load(data: Data): void; | ||
clone(): TypedRecord<Data, Expand>; | ||
$clone(): TypedRecord<Data, Expand>; | ||
export(): Data; | ||
$export(): Data; | ||
expand: Expand; | ||
}; | ||
export interface SystemFields { | ||
@@ -23,1 +72,51 @@ id: string; | ||
export type BaseCollectionRecords = Record<string, BaseRecord>; | ||
export type Fields<T extends GenericCollection> = keyof T['response']; | ||
export type Columns<T extends GenericCollection> = T['response']; | ||
export type Expands<T extends GenericCollection> = { | ||
[K in keyof T['relations']]?: T['relations'][K] extends GenericCollection[] | ||
? TypedRecord< | ||
T['relations'][K][number], | ||
Expands<T['relations'][K][number]> | ||
>[] | ||
: T['relations'][K] extends GenericCollection | ||
? TypedRecord<T['relations'][K], Expands<T['relations'][K]>> | ||
: never; | ||
}; | ||
export type GenericExpand = Record< | ||
string, | ||
TypedRecord<any> | TypedRecord<any>[] | ||
>; | ||
type JoinPath<Parts extends string[]> = Parts extends [ | ||
infer A extends string, | ||
...infer Rest extends string[] | ||
] | ||
? Rest['length'] extends 0 | ||
? A | ||
: `${A}.${JoinPath<Rest>}` | ||
: never; | ||
type _RecordWithExpandToDotPath< | ||
T extends GenericCollection, | ||
Path extends string[] = [] | ||
> = { | ||
[K in keyof T['response'] as JoinPath< | ||
[...Path, K & string] | ||
>]: T['response'][K]; | ||
} & (Path['length'] extends 4 // Supports up to 6-levels depth nested relations expansion. | ||
? {} | ||
: UnionToIntersection< | ||
Values<{ | ||
[K in keyof T['relations']]: _RecordWithExpandToDotPath< | ||
ArrayInnerType<T['relations'][K]>, | ||
[...Path, K & string] | ||
>; | ||
}> | ||
>); | ||
export type RecordWithExpandToDotPath<T extends GenericCollection> = Simplify< | ||
_RecordWithExpandToDotPath<T> | ||
>; |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
73221
101.33%21
31.25%1348
134.03%Yes
NaN2
100%6
20%2
Infinity%1
Infinity%+ Added
+ Added
+ Added