postgrest-js

repository·master·Indexed 22 days ago

https://github.com/supabase/postgrest-js

An isomorphic JavaScript client for interacting with PostgREST APIs. It provides the PostgrestClient for initiating database queries and a fluent API via PostgrestFilterBuilder for constructing complex filters, including equality, comparison, pattern matching, and full-text search. The library includes deep TypeScript type inference via GetResult to map PostgreSQL data types, table relationships, and aggregate functions to TypeScript types.

Tokens
3.6K
Snippets
3
Records
18
Agent score
74%

What's inside @supabase/postgrest-js

  1. Use @supabase/postgrest-js as an end-user

    master
    If you are an end-user of the @supabase/postgrest-js package, no action is required. The package continues to be published and used in the same way as before. There are no breaking changes to the installation or usage patterns due to the repository migration.
  2. How embedded resources and relationships are typed

    master

    When performing a join in a .select() query, postgrest-js uses the relationship metadata to decide the shape of the resulting object.

    Forward Relationships

    For a forward relationship (e.g., table(relation_name)):

    • One-to-One: Returns the object directly: { relation_name: T }.
    • One-to-Many: Returns an array: { relation_name: T[] }.
    • Inner Join: If innerJoin: true is specified, the result is not nullable.

    Reverse Relationships

    For reverse relationships (e.g., child_table(parent_id)):

    • Non-self-reference: If the relationship is nullable, it returns T | null. If not, it returns T.
    • Self-reference via column: If using a column match (e.g., parent_id), it returns a single object T | null (if nullable) or T.
    • Self-reference via relation: If using the reference relation, it returns an array T[].

    Error Handling

    If a relationship cannot be resolved or is invalid, the type will resolve to a SelectQueryError containing a descriptive string, such as 'Failed to resolve relationship.' or 'Invalid Relationships cannot infer result type'.

  3. Understand Postgrest response shapes

    master

    API responses in postgrest-js follow a predictable structure based on whether the request succeeded or failed.

    • Success Response: Contains data (the payload), count (number of rows, or null), and error is explicitly null.
    • Failure Response: Contains an error object (of type PostgrestError), and both data and count are null.

    Common response type aliases include:

    • PostgrestResponse<T>: Represents a standard array of results (T[]).
    • PostgrestSingleResponse<T>: Represents either a single object of type T or a failure.
    • PostgrestMaybeSingleResponse<T>: Represents a single object of type T, null, or a failure.
  4. How the spread operator works in select queries

    master

    The spread operator (...) in a .select() query allows you to include all fields from a related table. The resulting type depends on the relationship type and the PostgREST version.

    One-to-One or Many-to-One

    The spread operator returns the object properties directly within the parent object.

    Many-to-Many (PostgREST v13+)

    If PostgrestVersion is 13 or higher and you spread over a many-to-many relationship, the library uses SpreadOnManyEnabled logic. Instead of returning an array of objects, it converts the fields into correlated arrays.

    For example, if spreading a many-to-many relation that would normally return [{a: 1, b: 2}, {a: 3, b: 4}], the spread result becomes { a: [1, 3], b: [2, 4] }.

    Errors

    If you attempt to spread a relationship that is not many-to-one or one-to-one, you will receive a SelectQueryError: "<RelationName>" and "<TargetName>" do not form a many-to-one or one-to-one relationship spread not possible.

  5. Extract table relationships from a schema

    master

    If you are providing a custom schema definition to the library, you can use GetTableRelationships to retrieve the relationship metadata for a specific table.

    GetTableRelationships<Schema, Tname>

    • Schema: A type extending GenericSchema.
    • Tname: The name of the table as a string.

    It returns the Relationships property of the specified table if it exists, otherwise it returns false.

  6. Filter queries with PostgrestFilterBuilder

    master

    The PostgrestFilterBuilder provides a fluent API for constructing PostgREST filter queries. It allows you to chain multiple filter methods to refine your database queries. Most methods return this, enabling a builder pattern.

    Common Filter Methods

    • Equality: .eq(column, value) matches rows where the column equals the value. Use .is(column, value) to check for NULL or boolean values.
    • Inequality: .neq(column, value) matches rows where the column is not equal to the value.
    • Comparison: .gt(), .gte(), .lt(), and .lte() for greater than, greater than or equal, less than, and less than or equal.
    • Pattern Matching: .like(column, pattern) and .ilike(column, pattern) (case-insensitive) for string matching. You can also use .likeAllOf() or .likeAnyOf() for multiple patterns.
    • Set Membership: .in(column, values) matches if the column value is included in the provided array.
    • JSONB/Array/Range: .contains(column, value), .containedBy(column, value), and .overlaps(column, value) for complex types.
    • Text Search: .textSearch(column, query, options) for full-text search on text or tsvector columns.
    • Logical Operators: .match(queryObject) is a shorthand for multiple .eq() calls. Use .or(filters, options) to satisfy at least one filter, and .not(column, operator, value) to negate a filter.
  7. Use filter() and not() as escape hatches

    master

    If a specific filter method is not available, you can use the generic .filter() or .not() methods. These require you to provide the operator and value following PostgREST syntax.

    Warning: When using these methods, you are responsible for ensuring that the operator and value are properly sanitized to prevent injection or syntax errors.

    • .filter(column, operator, value): Matches rows satisfying the filter.
    • .not(column, operator, value): Matches rows that do not satisfy the filter.
  8. Access Postgrest builder classes

    master

    The library exports several builder classes used internally by the client to construct complex queries. While PostgrestClient is the main interface, these classes define the core query construction logic:

    • PostgrestQueryBuilder: Handles query construction.
    • PostgrestFilterBuilder: Manages filtering logic.
    • PostgrestTransformBuilder: Manages data transformations.
    • PostgrestBuilder: General query building.
    • PostgrestError: Represents errors encountered during requests.
  9. Get the result type of a PostgREST query with GetResult

    master

    The GetResult type is the main entry point for determining the TypeScript type of a query result based on a PostgREST select string. It performs deep type inference by parsing the query string and mapping it against the database schema, table relationships, and row definitions.

    It handles several complex scenarios:

    • Standard Selects: Maps columns and aliases to their correct types.
    • RPC Calls: Infers types from the return value of a database function, allowing for chained .select() calls.
    • Embedded Resources: Automatically determines if a relationship returns a single object or an array based on the relationship direction (forward/reverse) and nullability.
    • Spread Operators: Handles ... spread syntax, including special handling for many-to-many relationships in PostgREST v13+ where fields are converted into correlated arrays.
    • Aggregate Functions: Correctly types results from functions like .sum() or .count().
    • JSON Paths: Resolves types when accessing nested JSON properties via specific paths.
    /**
     * Main entry point for constructing the result type of a PostgREST query.
     *
     * @param Schema - Database schema.
     * @param Row - The type of a row in the current table.
     * @param RelationName - The name of the current table or view.
     * @param Relationships - Relationships of the current table.
     * @param Query - The select query string literal to parse.
     * @param ClientOptions - Client configuration options.
     */
    export type GetResult<
      Schema extends GenericSchema,
      Row extends Record<string, unknown>,
      RelationName,
      Relationships,
      Query extends string,
      ClientOptions extends ClientServerOptions
    > = ...
  10. Use or() for logical OR queries

    master

    The .or() method allows you to match rows that satisfy at least one of the provided filters. The filters argument must follow PostgREST syntax.

    Options:

    • referencedTable: Use this to filter on a referenced (joined) table instead of the parent table. (Note: foreignTable is deprecated and should be replaced by referencedTable).

    Note: It is currently not possible to perform an .or() filter across multiple different tables in a single call.