0

Fetch data

by
Published Jan 20, 2023
Script supabase Verified

The script

Submitted by hugo989 Bun
Verified 19 days ago
1
import { createClient, SupabaseClient } from "@supabase/[email protected]"
2

3
/**
4
 * @param token Supabase `access_token` and `refresh_token`. `expires_at` (optional) is a UNIX
5
 * timestamp in seconds.
6
 *
7
 * @param count Count algorithm to use to count rows in the table or view.
8
 * `"exact"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the hood.
9
 * `"planned"`: Approximated but fast count algorithm. Uses the Postgres statistics under the hood.
10
 * `"estimated"`: Uses exact count for low numbers and planned count for high numbers.
11
 *
12
 * @param head When set to `true`, `data` will not be returned.
13
 * Useful if you only need the count.
14
 *
15
 * @param filter Learn more at https://supabase.com/docs/reference/javascript/filter
16
 *
17
 * @param order Learn more at https://supabase.com/docs/reference/javascript/order
18
 *
19
 * @param limit Learn more at https://supabase.com/docs/reference/javascript/limit
20
 */
21
type Supabase = {
22
  url: string;
23
  key: string;
24
};
25
export async function main(
26
  auth: Supabase,
27
  table: string,
28
  columns?: string,
29
  token?: {
30
    access: string;
31
    refresh: string;
32
    expires_at?: number;
33
  },
34
  count?: "exact" | "planned" | "estimated",
35
  head?: boolean,
36
  filter?: {
37
    column: string;
38
    operator: string;
39
    value: any;
40
  },
41
  order?: {
42
    column: string;
43
    foreignTable: string;
44
    ascending?: boolean;
45
    nullsFirst?: boolean;
46
  },
47
  limit?: {
48
    count: number;
49
    foreignTable?: string;
50
  },
51
) {
52
  return await refreshAndRetryIfExpired(auth, token, async (client) => {
53
    const options = head || count ? { head, count } : undefined;
54
    let query = client.from(table).select(columns || undefined, options);
55
    if (filter?.column) {
56
      query = query.filter(filter.column, filter.operator, filter.value);
57
    }
58
    if (order?.column) {
59
      const { column, ...options } = order;
60
      query = query.order(column, options);
61
    }
62
    if (limit?.count) {
63
      const { count, foreignTable } = limit;
64
      query = query.limit(count, foreignTable ? { foreignTable } : undefined);
65
    }
66

67
    return query;
68
  });
69
}
70

71
async function refreshAndRetryIfExpired(
72
  auth: { url: string; key: string },
73
  token: { access: string; refresh: string; expires_at?: number } | undefined,
74
  fn: (client: SupabaseClient) => Promise<{ data: any; error?: any }>,
75
): Promise<{ data: any; error?: any; token?: { access: string; refresh: string; expires_at?: number } }> {
76
  const makeClient = async (autoRefreshToken: boolean) => {
77
    const client = createClient(auth.url, auth.key, {
78
      auth: { autoRefreshToken, persistSession: false },
79
    })
80
    if (token) {
81
      await client.auth.setSession({ access_token: token.access, refresh_token: token.refresh })
82
    }
83
    return client
84
  }
85
  try {
86
    let result = await fn(await makeClient(false))
87
    if (result?.error?.code === "PGRST301" && token) {
88
      const client = await makeClient(true)
89
      result = await fn(client)
90
      const { data } = await client.auth.getSession()
91
      if (data?.session) {
92
        token = {
93
          access: data.session.access_token,
94
          refresh: data.session.refresh_token,
95
          expires_at: data.session.expires_at,
96
        }
97
      }
98
    }
99
    return { ...result, token }
100
  } catch (error) {
101
    return { data: null, error }
102
  }
103
}
104

Other submissions
  • Submitted by adam186 Deno
    Created 411 days ago
    1
    import { refreshAndRetryIfExpired } from "https://deno.land/x/[email protected]/mod.ts";
    2
    
    
    3
    /**
    4
     * @param token Supabase `access_token` and `refresh_token`. `expires_at` (optional) is a UNIX
    5
     * timestamp in seconds.
    6
     *
    7
     * @param count Count algorithm to use to count rows in the table or view.
    8
     * `"exact"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the hood.
    9
     * `"planned"`: Approximated but fast count algorithm. Uses the Postgres statistics under the hood.
    10
     * `"estimated"`: Uses exact count for low numbers and planned count for high numbers.
    11
     *
    12
     * @param head When set to `true`, `data` will not be returned.
    13
     * Useful if you only need the count.
    14
     *
    15
     * @param filter Learn more at https://supabase.com/docs/reference/javascript/filter
    16
     *
    17
     * @param order Learn more at https://supabase.com/docs/reference/javascript/order
    18
     *
    19
     * @param limit Learn more at https://supabase.com/docs/reference/javascript/limit
    20
     */
    21
    type Supabase = {
    22
      url: string;
    23
      key: string;
    24
    };
    25
    export async function main(
    26
      auth: Supabase,
    27
      table: string,
    28
      columns?: string,
    29
      token?: {
    30
        access: string;
    31
        refresh: string;
    32
        expires_at?: number;
    33
      },
    34
      count?: "exact" | "planned" | "estimated",
    35
      head?: boolean,
    36
      filter?: {
    37
        column: string;
    38
        operator: string;
    39
        value: any;
    40
      },
    41
      order?: {
    42
        column: string;
    43
        foreignTable: string;
    44
        ascending?: boolean;
    45
        nullsFirst?: boolean;
    46
      },
    47
      limit?: {
    48
        count: number;
    49
        foreignTable?: string;
    50
      },
    51
    ) {
    52
      return await refreshAndRetryIfExpired(auth, token, async (client) => {
    53
        const options = head || count ? { head, count } : undefined;
    54
        let query = client.from(table).select(columns || undefined, options);
    55
        if (filter?.column) {
    56
          query = query.filter(filter.column, filter.operator, filter.value);
    57
        }
    58
        if (order?.column) {
    59
          const { column, ...options } = order;
    60
          query = query.order(column, options);
    61
        }
    62
        if (limit?.count) {
    63
          const { count, foreignTable } = limit;
    64
          query = query.limit(count, foreignTable ? { foreignTable } : undefined);
    65
        }
    66
    
    
    67
        return query;
    68
      });
    69
    }
    70
    
    
  • Submitted by adam186 Deno
    Created 1175 days ago
    1
    import { Resource } from "https://deno.land/x/[email protected]/mod.ts";
    2
    import { createClient } from "https://esm.sh/@supabase/supabase-js@2";
    3
    
    
    4
    /**
    5
     * @param access_token It is only needed if you have an affecting RLS policy enabled
    6
     * on the table that you want to access.
    7
     * Learn more about RLS here: https://supabase.com/docs/guides/auth/row-level-security
    8
     * 
    9
     * @param count Count algorithm to use to count rows in the table or view.
    10
     * `"exact"`: Exact but slow count algorithm. Performs a `COUNT(*)` under the hood.
    11
     * `"planned"`: Approximated but fast count algorithm. Uses the Postgres statistics under the hood.
    12
     * `"estimated"`: Uses exact count for low numbers and planned count for high numbers.
    13
     *
    14
     * @param head When set to `true`, `data` will not be returned.
    15
     * Useful if you only need the count.
    16
     * 
    17
     * @param filter Learn more at https://supabase.com/docs/reference/javascript/filter
    18
     * 
    19
     * @param order Learn more at https://supabase.com/docs/reference/javascript/order
    20
     * 
    21
     * @param limit Learn more at https://supabase.com/docs/reference/javascript/limit
    22
     */
    23
    export async function main(
    24
      auth: Resource<"supabase">,
    25
      table: string,
    26
      columns?: string,
    27
      access_token?: string,
    28
      count?: "exact" | "planned" | "estimated",
    29
      head?: boolean,
    30
      filter?: {
    31
        column: string;
    32
        operator: string;
    33
        value: any;
    34
      },
    35
      order?: {
    36
        column: string;
    37
        foreignTable: string;
    38
        ascending?: boolean;
    39
        nullsFirst?: boolean;
    40
      },
    41
      limit?: {
    42
        count: number;
    43
        foreignTable?: string;
    44
      },
    45
    ) {
    46
      const headers = access_token ? {
    47
        global: { headers: { Authorization: `bearer ${access_token}` } },
    48
      } : undefined
    49
      const client = createClient(auth.url, auth.key, headers);
    50
      const options = (head || count) ? { head, count } : undefined;
    51
      let query = client.from(table).select(columns || undefined, options);
    52
      if (filter?.column) {
    53
        query = query.filter(filter.column, filter.operator, filter.value);
    54
      }
    55
      if (order?.column) {
    56
        const { column, ...options } = order;
    57
        query = query.order(column, options);
    58
      }
    59
      if (limit?.count) {
    60
        const { count, foreignTable } = limit;
    61
        query = query.limit(count, foreignTable ? { foreignTable } : undefined);
    62
      }
    63
    
    
    64
      return await query;
    65
    }
    66