Skip to content

feat(types): setup postgrest-13 types inference #618

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ on:
jobs:
test:
name: Test
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ on:
jobs:
docs:
name: Publish docs
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:
jobs:
release:
name: Release
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v2

Expand Down
2 changes: 1 addition & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
collectCoverageFrom: ['src/**/*'],
collectCoverageFrom: ['src/**/*', '!src/types.ts'],
}
23 changes: 17 additions & 6 deletions src/PostgrestBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ import type {
CheckMatchingArrayTypes,
MergePartialResult,
IsValidResultOverride,
ClientServerOptions,
} from './types'
import PostgrestError from './PostgrestError'
import { ContainsNull } from './select-query-parser/types'

export default abstract class PostgrestBuilder<Result, ThrowOnError extends boolean = false>
implements
export default abstract class PostgrestBuilder<
ClientOptions extends ClientServerOptions,
Copy link
Member

Choose a reason for hiding this comment

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

Won't block the PR based on this but I have a hunch that adding new type parameters at the start/middle of the parameter list will break some 3rd party lib relying on the typings

Copy link
Member Author

Choose a reason for hiding this comment

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

Hum that's true, I've looked for usage on github: https://github.com/search?q=language%3ATypeScript++PostgrestBuilder%3C&type=code&p=3

Most of them seems to be forks though. Maybe we could pass this into a new major version though.

Or maybe in the changelog we can give a fix solution for compatibility:

import type { PostgrestBuilder as BasePostgrestBuilder } from '@supabase/posgrest-js';

type PostgrestBuilder<R, TE extends boolean = false> = BasePostgrestBuilder<{}, R, TE>

Didn't tested it but this should allow to use the PostgrestBuilder type as before 🤔

I think I remember having trouble pushing this as a last argument because then, it required to always also define the ThrowOnError param which has default set.

Result,
ThrowOnError extends boolean = false
> implements
PromiseLike<
ThrowOnError extends true ? PostgrestResponseSuccess<Result> : PostgrestSingleResponse<Result>
>
Expand All @@ -28,7 +32,7 @@ export default abstract class PostgrestBuilder<Result, ThrowOnError extends bool
protected fetch: Fetch
protected isMaybeSingle: boolean

constructor(builder: PostgrestBuilder<Result>) {
constructor(builder: PostgrestBuilder<ClientOptions, Result>) {
this.method = builder.method
this.url = builder.url
this.headers = builder.headers
Expand All @@ -53,9 +57,9 @@ export default abstract class PostgrestBuilder<Result, ThrowOnError extends bool
*
* {@link https://github.com/supabase/supabase-js/issues/92}
*/
throwOnError(): this & PostgrestBuilder<Result, true> {
throwOnError(): this & PostgrestBuilder<ClientOptions, Result, true> {
this.shouldThrowOnError = true
return this as this & PostgrestBuilder<Result, true>
return this as this & PostgrestBuilder<ClientOptions, Result, true>
}

/**
Expand Down Expand Up @@ -224,9 +228,14 @@ export default abstract class PostgrestBuilder<Result, ThrowOnError extends bool
* @typeParam NewResult - The new result type to override with
* @deprecated Use overrideTypes<yourType, { merge: false }>() method at the end of your call chain instead
*/
returns<NewResult>(): PostgrestBuilder<CheckMatchingArrayTypes<Result, NewResult>, ThrowOnError> {
returns<NewResult>(): PostgrestBuilder<
ClientOptions,
CheckMatchingArrayTypes<Result, NewResult>,
ThrowOnError
> {
/* istanbul ignore next */
return this as unknown as PostgrestBuilder<
ClientOptions,
CheckMatchingArrayTypes<Result, NewResult>,
ThrowOnError
>
Expand Down Expand Up @@ -258,6 +267,7 @@ export default abstract class PostgrestBuilder<Result, ThrowOnError extends bool
NewResult,
Options extends { merge?: boolean } = { merge: true }
>(): PostgrestBuilder<
ClientOptions,
IsValidResultOverride<Result, NewResult, false, false> extends true
? // Preserve the optionality of the result if the overriden type is an object (case of chaining with `maybeSingle`)
ContainsNull<Result> extends true
Expand All @@ -267,6 +277,7 @@ export default abstract class PostgrestBuilder<Result, ThrowOnError extends bool
ThrowOnError
> {
return this as unknown as PostgrestBuilder<
ClientOptions,
IsValidResultOverride<Result, NewResult, false, false> extends true
? // Preserve the optionality of the result if the overriden type is an object (case of chaining with `maybeSingle`)
ContainsNull<Result> extends true
Expand Down
27 changes: 17 additions & 10 deletions src/PostgrestClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import PostgrestQueryBuilder from './PostgrestQueryBuilder'
import PostgrestFilterBuilder from './PostgrestFilterBuilder'
import PostgrestBuilder from './PostgrestBuilder'
import { DEFAULT_HEADERS } from './constants'
import { Fetch, GenericSchema } from './types'
import { Fetch, GenericSchema, ClientServerOptions, GetGenericDatabaseWithOptions } from './types'

/**
* PostgREST client.
Expand All @@ -16,11 +16,16 @@ import { Fetch, GenericSchema } from './types'
*/
export default class PostgrestClient<
Database = any,
SchemaName extends string & keyof Database = 'public' extends keyof Database
ClientOptions extends ClientServerOptions = GetGenericDatabaseWithOptions<
Database,
{ PostgrestVersion: '12' }
>['options'],
SchemaName extends string &
keyof GetGenericDatabaseWithOptions<Database>['db'] = 'public' extends keyof GetGenericDatabaseWithOptions<Database>['db']
? 'public'
: string & keyof Database,
Schema extends GenericSchema = Database[SchemaName] extends GenericSchema
? Database[SchemaName]
: string & keyof GetGenericDatabaseWithOptions<Database>['db'],
Schema extends GenericSchema = GetGenericDatabaseWithOptions<Database>['db'][SchemaName] extends GenericSchema
? GetGenericDatabaseWithOptions<Database>['db'][SchemaName]
: any
> {
url: string
Expand Down Expand Up @@ -59,16 +64,16 @@ export default class PostgrestClient<
from<
TableName extends string & keyof Schema['Tables'],
Table extends Schema['Tables'][TableName]
>(relation: TableName): PostgrestQueryBuilder<Schema, Table, TableName>
>(relation: TableName): PostgrestQueryBuilder<ClientOptions, Schema, Table, TableName>
from<ViewName extends string & keyof Schema['Views'], View extends Schema['Views'][ViewName]>(
relation: ViewName
): PostgrestQueryBuilder<Schema, View, ViewName>
): PostgrestQueryBuilder<ClientOptions, Schema, View, ViewName>
/**
* Perform a query on a table or a view.
*
* @param relation - The table or view name to query
*/
from(relation: string): PostgrestQueryBuilder<Schema, any, any> {
from(relation: string): PostgrestQueryBuilder<ClientOptions, Schema, any, any> {
const url = new URL(`${this.url}/${relation}`)
return new PostgrestQueryBuilder(url, {
headers: { ...this.headers },
Expand All @@ -84,10 +89,11 @@ export default class PostgrestClient<
*
* @param schema - The schema to query
*/
schema<DynamicSchema extends string & keyof Database>(
schema<DynamicSchema extends string & keyof GetGenericDatabaseWithOptions<Database>['db']>(
schema: DynamicSchema
): PostgrestClient<
Database,
ClientOptions,
DynamicSchema,
Database[DynamicSchema] extends GenericSchema ? Database[DynamicSchema] : any
> {
Expand Down Expand Up @@ -134,6 +140,7 @@ export default class PostgrestClient<
count?: 'exact' | 'planned' | 'estimated'
} = {}
): PostgrestFilterBuilder<
ClientOptions,
Schema,
Fn['Returns'] extends any[]
? Fn['Returns'][number] extends Record<string, unknown>
Expand Down Expand Up @@ -176,6 +183,6 @@ export default class PostgrestClient<
body,
fetch: this.fetch,
allowEmpty: false,
} as unknown as PostgrestBuilder<Fn['Returns']>)
} as unknown as PostgrestBuilder<ClientOptions, Fn['Returns']>)
}
}
14 changes: 12 additions & 2 deletions src/PostgrestFilterBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import PostgrestTransformBuilder from './PostgrestTransformBuilder'
import { JsonPathToAccessor, JsonPathToType } from './select-query-parser/utils'
import { GenericSchema } from './types'
import { ClientServerOptions, GenericSchema } from './types'

type FilterOperator =
| 'eq'
Expand Down Expand Up @@ -69,13 +69,23 @@ type ResolveFilterRelationshipValue<
: unknown
: never

export type InvalidMethodError<S extends string> = { Error: S }

export default class PostgrestFilterBuilder<
ClientOptions extends ClientServerOptions,
Schema extends GenericSchema,
Row extends Record<string, unknown>,
Result,
RelationName = unknown,
Relationships = unknown
> extends PostgrestTransformBuilder<Schema, Row, Result, RelationName, Relationships> {
> extends PostgrestTransformBuilder<
ClientOptions,
Schema,
Row,
Result,
RelationName,
Relationships
> {
/**
* Match only rows where `column` is equal to `value`.
*
Expand Down
Loading