This commit is contained in:
Stefan Pejcic
2024-11-07 19:03:37 +01:00
parent c6df945ed5
commit 09f9f9502d
2472 changed files with 620417 additions and 0 deletions

View File

@@ -0,0 +1,298 @@
import nock from "nock";
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.post("/auth/v1/token", {
email: "info@refine.dev",
password: "refine-supabase",
gotrue_meta_security: {},
})
.query({ grant_type: "password" })
.reply(
200,
{
access_token:
"eyJhbGciOiJIUzI1NiIsImtpZCI6IldGWnFuOWt6bnBJZTIvL2wiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzE0MDM5MDk1LCJpYXQiOjE3MTQwMzU0OTUsImlzcyI6Imh0dHBzOi8vaXdkZnp2ZnFidG9rcWV0bWJtYnAuc3VwYWJhc2UuY28vYXV0aC92MSIsInN1YiI6ImJkZWZhYzgxLTJiZDEtNDRkMS1iNWVkLTdhYmVkYjk2Y2NjZSIsImVtYWlsIjoiaW5mb0ByZWZpbmUuZGV2IiwicGhvbmUiOiIiLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCJ9LCJ1c2VyX21ldGFkYXRhIjp7fSwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTcxNDAzNTQ5NX1dLCJzZXNzaW9uX2lkIjoiY2NjMWUzODEtNmFkYS00OTdkLWIxYjAtOWM4ZmJjNWQwYWZmIiwiaXNfYW5vbnltb3VzIjpmYWxzZX0.yVJ6lWNwdQCsbPsP5tfJk7Xjtx2bHRBaiyaox6KcMX0",
token_type: "bearer",
expires_in: 3600,
expires_at: 1714039095,
refresh_token: "R0tQR-e2RgQQdsS7OTMCWQ",
user: {
id: "bdefac81-2bd1-44d1-b5ed-7abedb96ccce",
aud: "authenticated",
role: "authenticated",
email: "info@refine.dev",
email_confirmed_at: "2021-09-08T11:09:24.284171Z",
phone: "",
confirmation_sent_at: "2021-09-08T11:08:06.793257Z",
confirmed_at: "2021-09-08T11:09:24.284171Z",
recovery_sent_at: "2024-02-04T09:33:53.383988Z",
last_sign_in_at: "2024-04-25T08:58:15.046729193Z",
app_metadata: { provider: "email" },
user_metadata: {},
identities: [
{
identity_id: "6b8dcf5b-f068-401b-95ae-ddd93d771b74",
id: "bdefac81-2bd1-44d1-b5ed-7abedb96ccce",
user_id: "bdefac81-2bd1-44d1-b5ed-7abedb96ccce",
identity_data: {
email: "info@refine.dev",
sub: "bdefac81-2bd1-44d1-b5ed-7abedb96ccce",
},
provider: "email",
last_sign_in_at: "2022-11-25T00:00:00Z",
created_at: "2022-11-25T00:00:00Z",
updated_at: "2022-11-25T00:00:00Z",
email: "info@refine.dev",
},
],
created_at: "2021-09-08T11:08:06.789274Z",
updated_at: "2024-04-25T08:58:15.04881Z",
is_anonymous: false,
},
},
[
"Date",
"Thu, 25 Apr 2024 08:58:15 GMT",
"Content-Type",
"application/json",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"CF-Ray",
"879d21512ac6519b-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Set-Cookie",
"sb-access-token=eyJhbGciOiJIUzI1NiIsImtpZCI6IldGWnFuOWt6bnBJZTIvL2wiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzE0MDM5MDk1LCJpYXQiOjE3MTQwMzU0OTUsImlzcyI6Imh0dHBzOi8vaXdkZnp2ZnFidG9rcWV0bWJtYnAuc3VwYWJhc2UuY28vYXV0aC92MSIsInN1YiI6ImJkZWZhYzgxLTJiZDEtNDRkMS1iNWVkLTdhYmVkYjk2Y2NjZSIsImVtYWlsIjoiaW5mb0ByZWZpbmUuZGV2IiwicGhvbmUiOiIiLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCJ9LCJ1c2VyX21ldGFkYXRhIjp7fSwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTcxNDAzNTQ5NX1dLCJzZXNzaW9uX2lkIjoiY2NjMWUzODEtNmFkYS00OTdkLWIxYjAtOWM4ZmJjNWQwYWZmIiwiaXNfYW5vbnltb3VzIjpmYWxzZX0.yVJ6lWNwdQCsbPsP5tfJk7Xjtx2bHRBaiyaox6KcMX0; Path=/; Expires=Fri, 26 Apr 2024 08:58:15 GMT; Max-Age=86400; HttpOnly; Secure",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Vary",
"Accept-Encoding, Origin",
"Via",
"kong/2.8.1",
"sb-gateway-version",
"1",
"Set-Cookie",
"sb-refresh-token=R0tQR-e2RgQQdsS7OTMCWQ; Path=/; Expires=Fri, 26 Apr 2024 08:58:15 GMT; Max-Age=86400; HttpOnly; Secure",
"x-kong-proxy-latency",
"1",
"x-kong-upstream-latency",
"90",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.post("/rest/v1/posts", {
title: "foo",
slug: "foo-bar",
content: "bar",
categoryId: 2,
})
.query({ select: "%2A" })
.reply(
201,
[
{
id: 12893,
title: "foo",
slug: "foo-bar",
createdAt: "2024-04-25T08:58:15.561287+00:00",
content: "bar",
categoryId: 2,
images: null,
},
],
[
"Date",
"Thu, 25 Apr 2024 08:58:15 GMT",
"Content-Type",
"application/json; charset=utf-8",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"Content-Range",
"*/*",
"CF-Ray",
"879d2155cf286970-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Via",
"kong/2.8.1",
"content-profile",
"public",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"3",
"x-kong-upstream-latency",
"7",
"Vary",
"Accept-Encoding",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.post("/rest/v1/posts", {
title: "foo",
slug: "foo-bar",
content: "bar",
categoryId: 2,
})
.query({ select: "%2A" })
.reply(
201,
[
{
id: 12894,
title: "foo",
slug: "foo-bar",
createdAt: "2024-04-25T08:58:15.88472+00:00",
content: "bar",
categoryId: 2,
images: null,
},
],
[
"Date",
"Thu, 25 Apr 2024 08:58:15 GMT",
"Content-Type",
"application/json; charset=utf-8",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"Content-Range",
"*/*",
"CF-Ray",
"879d21585813724e-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Via",
"kong/2.8.1",
"content-profile",
"public",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"0",
"x-kong-upstream-latency",
"7",
"Vary",
"Accept-Encoding",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.post("/rest/v1/posts", {})
.query({ select: "%2A" })
.reply(
406,
{
code: "PGRST106",
details: null,
hint: null,
message: "The schema must be one of the following: public, storage",
},
[
"Date",
"Thu, 25 Apr 2024 08:58:16 GMT",
"Content-Type",
"application/json; charset=utf-8",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"CF-Ray",
"879d2159d8847212-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Via",
"kong/2.8.1",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"1",
"x-kong-upstream-latency",
"0",
"Vary",
"Accept-Encoding",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.post("/auth/v1/logout")
.query({ scope: "global" })
.reply(204, "", [
"Date",
"Thu, 25 Apr 2024 08:58:16 GMT",
"Connection",
"close",
"CF-Ray",
"879d215b9ec65184-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Set-Cookie",
"sb-access-token=; Path=/; Expires=Wed, 24 Apr 2024 22:58:16 GMT; Max-Age=0; HttpOnly; Secure",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Vary",
"Origin, Accept-Encoding",
"Via",
"kong/2.8.1",
"sb-gateway-version",
"1",
"Set-Cookie",
"sb-refresh-token=; Path=/; Expires=Wed, 24 Apr 2024 22:58:16 GMT; Max-Age=0; HttpOnly; Secure",
"x-kong-proxy-latency",
"1",
"x-kong-upstream-latency",
"11",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
]);

View File

@@ -0,0 +1,56 @@
import { dataProvider } from "../../src/index";
import supabaseClient from "../supabaseClient";
import "./index.mock";
describe("create", () => {
it("correct response with `select`", async () => {
const { data } = await dataProvider(supabaseClient).create({
resource: "posts",
variables: {
title: "foo",
slug: "foo-bar",
content: "bar",
categoryId: 2,
},
meta: {
select: "*",
},
});
expect(data["id"]).toEqual(12893);
expect(data["title"]).toEqual("foo");
expect(data["slug"]).toEqual("foo-bar");
expect(data["content"]).toEqual("bar");
expect(data["categoryId"]).toEqual(2);
});
it("should change schema", async () => {
const { data } = await dataProvider(supabaseClient).create({
resource: "posts",
variables: {
title: "foo",
slug: "foo-bar",
content: "bar",
categoryId: 2,
},
meta: {
schema: "public",
select: "*",
},
});
expect(data["title"]).toEqual("foo");
try {
await dataProvider(supabaseClient).create({
resource: "posts",
variables: {},
meta: {
schema: "private",
},
});
} catch (error: any) {
expect(error.code).toEqual("PGRST106");
}
});
});

View File

@@ -0,0 +1,318 @@
import nock from "nock";
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.post("/auth/v1/token", {
email: "info@refine.dev",
password: "refine-supabase",
gotrue_meta_security: {},
})
.query({ grant_type: "password" })
.reply(
200,
{
access_token:
"eyJhbGciOiJIUzI1NiIsImtpZCI6IldGWnFuOWt6bnBJZTIvL2wiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzE0MDM5MjQ3LCJpYXQiOjE3MTQwMzU2NDcsImlzcyI6Imh0dHBzOi8vaXdkZnp2ZnFidG9rcWV0bWJtYnAuc3VwYWJhc2UuY28vYXV0aC92MSIsInN1YiI6ImJkZWZhYzgxLTJiZDEtNDRkMS1iNWVkLTdhYmVkYjk2Y2NjZSIsImVtYWlsIjoiaW5mb0ByZWZpbmUuZGV2IiwicGhvbmUiOiIiLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCJ9LCJ1c2VyX21ldGFkYXRhIjp7fSwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTcxNDAzNTY0N31dLCJzZXNzaW9uX2lkIjoiMmNmNTNmNzAtN2JmNC00Y2Q4LWJjNGEtMjQ0YWNhZDZmOTYzIiwiaXNfYW5vbnltb3VzIjpmYWxzZX0.JBhZFZU2u_ACen9Oqq4SnwxS1jMtu9V4Q9LUlkpWN1A",
token_type: "bearer",
expires_in: 3600,
expires_at: 1714039247,
refresh_token: "StH_4ldWnYhySTr7QDsEMA",
user: {
id: "bdefac81-2bd1-44d1-b5ed-7abedb96ccce",
aud: "authenticated",
role: "authenticated",
email: "info@refine.dev",
email_confirmed_at: "2021-09-08T11:09:24.284171Z",
phone: "",
confirmation_sent_at: "2021-09-08T11:08:06.793257Z",
confirmed_at: "2021-09-08T11:09:24.284171Z",
recovery_sent_at: "2024-02-04T09:33:53.383988Z",
last_sign_in_at: "2024-04-25T09:00:47.430784517Z",
app_metadata: { provider: "email" },
user_metadata: {},
identities: [
{
identity_id: "6b8dcf5b-f068-401b-95ae-ddd93d771b74",
id: "bdefac81-2bd1-44d1-b5ed-7abedb96ccce",
user_id: "bdefac81-2bd1-44d1-b5ed-7abedb96ccce",
identity_data: {
email: "info@refine.dev",
sub: "bdefac81-2bd1-44d1-b5ed-7abedb96ccce",
},
provider: "email",
last_sign_in_at: "2022-11-25T00:00:00Z",
created_at: "2022-11-25T00:00:00Z",
updated_at: "2022-11-25T00:00:00Z",
email: "info@refine.dev",
},
],
created_at: "2021-09-08T11:08:06.789274Z",
updated_at: "2024-04-25T09:00:47.432602Z",
is_anonymous: false,
},
},
[
"Date",
"Thu, 25 Apr 2024 09:00:47 GMT",
"Content-Type",
"application/json",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"CF-Ray",
"879d25098fce7207-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Set-Cookie",
"sb-access-token=eyJhbGciOiJIUzI1NiIsImtpZCI6IldGWnFuOWt6bnBJZTIvL2wiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzE0MDM5MjQ3LCJpYXQiOjE3MTQwMzU2NDcsImlzcyI6Imh0dHBzOi8vaXdkZnp2ZnFidG9rcWV0bWJtYnAuc3VwYWJhc2UuY28vYXV0aC92MSIsInN1YiI6ImJkZWZhYzgxLTJiZDEtNDRkMS1iNWVkLTdhYmVkYjk2Y2NjZSIsImVtYWlsIjoiaW5mb0ByZWZpbmUuZGV2IiwicGhvbmUiOiIiLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCJ9LCJ1c2VyX21ldGFkYXRhIjp7fSwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTcxNDAzNTY0N31dLCJzZXNzaW9uX2lkIjoiMmNmNTNmNzAtN2JmNC00Y2Q4LWJjNGEtMjQ0YWNhZDZmOTYzIiwiaXNfYW5vbnltb3VzIjpmYWxzZX0.JBhZFZU2u_ACen9Oqq4SnwxS1jMtu9V4Q9LUlkpWN1A; Path=/; Expires=Fri, 26 Apr 2024 09:00:47 GMT; Max-Age=86400; HttpOnly; Secure",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Vary",
"Accept-Encoding, Origin",
"Via",
"kong/2.8.1",
"sb-gateway-version",
"1",
"Set-Cookie",
"sb-refresh-token=StH_4ldWnYhySTr7QDsEMA; Path=/; Expires=Fri, 26 Apr 2024 09:00:47 GMT; Max-Age=86400; HttpOnly; Secure",
"x-kong-proxy-latency",
"1",
"x-kong-upstream-latency",
"90",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.post("/rest/v1/posts", [
{ title: "foo", slug: "foo-bar", content: "bar", categoryId: 2 },
{ title: "foo-2", slug: "foo-bar-2", content: "bar-2", categoryId: 1 },
])
.query({
columns: "%22title%22%2C%22slug%22%2C%22content%22%2C%22categoryId%22",
select: "%2A",
})
.reply(
201,
[
{
id: 12895,
title: "foo",
slug: "foo-bar",
createdAt: "2024-04-25T09:00:47.766685+00:00",
content: "bar",
categoryId: 2,
images: null,
},
{
id: 12896,
title: "foo-2",
slug: "foo-bar-2",
createdAt: "2024-04-25T09:00:47.766685+00:00",
content: "bar-2",
categoryId: 1,
images: null,
},
],
[
"Date",
"Thu, 25 Apr 2024 09:00:47 GMT",
"Content-Type",
"application/json; charset=utf-8",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"Content-Range",
"*/*",
"CF-Ray",
"879d250dca78778e-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Via",
"kong/2.8.1",
"content-profile",
"public",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"0",
"x-kong-upstream-latency",
"5",
"Vary",
"Accept-Encoding",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.post("/rest/v1/posts", [
{ title: "foo", slug: "foo-bar", content: "bar", categoryId: 2 },
{ title: "foo-2", slug: "foo-bar-2", content: "bar-2", categoryId: 1 },
])
.query({
columns: "%22title%22%2C%22slug%22%2C%22content%22%2C%22categoryId%22",
select: "%2A",
})
.reply(
201,
[
{
id: 12897,
title: "foo",
slug: "foo-bar",
createdAt: "2024-04-25T09:00:48.264931+00:00",
content: "bar",
categoryId: 2,
images: null,
},
{
id: 12898,
title: "foo-2",
slug: "foo-bar-2",
createdAt: "2024-04-25T09:00:48.264931+00:00",
content: "bar-2",
categoryId: 1,
images: null,
},
],
[
"Date",
"Thu, 25 Apr 2024 09:00:48 GMT",
"Content-Type",
"application/json; charset=utf-8",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"Content-Range",
"*/*",
"CF-Ray",
"879d25103a3b693e-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Via",
"kong/2.8.1",
"content-profile",
"public",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"2",
"x-kong-upstream-latency",
"4",
"Vary",
"Accept-Encoding",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.post("/rest/v1/posts", [])
.query({ select: "%2A" })
.reply(
406,
{
code: "PGRST106",
details: null,
hint: null,
message: "The schema must be one of the following: public, storage",
},
[
"Date",
"Thu, 25 Apr 2024 09:00:48 GMT",
"Content-Type",
"application/json; charset=utf-8",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"CF-Ray",
"879d25125ed67240-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Via",
"kong/2.8.1",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"0",
"x-kong-upstream-latency",
"1",
"Vary",
"Accept-Encoding",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.post("/auth/v1/logout")
.query({ scope: "global" })
.reply(204, "", [
"Date",
"Thu, 25 Apr 2024 09:00:48 GMT",
"Connection",
"close",
"CF-Ray",
"879d2513ce1c7210-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Set-Cookie",
"sb-access-token=; Path=/; Expires=Wed, 24 Apr 2024 23:00:48 GMT; Max-Age=0; HttpOnly; Secure",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Vary",
"Origin, Accept-Encoding",
"Via",
"kong/2.8.1",
"sb-gateway-version",
"1",
"Set-Cookie",
"sb-refresh-token=; Path=/; Expires=Wed, 24 Apr 2024 23:00:48 GMT; Max-Age=0; HttpOnly; Secure",
"x-kong-proxy-latency",
"0",
"x-kong-upstream-latency",
"5",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
]);

View File

@@ -0,0 +1,79 @@
import { dataProvider } from "../../src/index";
import supabaseClient from "../supabaseClient";
import "./index.mock";
describe("createMany", () => {
it("correct response with `select`", async () => {
const { data } = await dataProvider(supabaseClient).createMany!({
resource: "posts",
variables: [
{
title: "foo",
slug: "foo-bar",
content: "bar",
categoryId: 2,
},
{
title: "foo-2",
slug: "foo-bar-2",
content: "bar-2",
categoryId: 1,
},
],
meta: {
select: "*",
},
});
expect(data[0]["id"]).toEqual(12895);
expect(data[0]["title"]).toEqual("foo");
expect(data[0]["slug"]).toEqual("foo-bar");
expect(data[0]["content"]).toEqual("bar");
expect(data[0]["categoryId"]).toEqual(2);
expect(data[1]["id"]).toEqual(12896);
expect(data[1]["title"]).toEqual("foo-2");
expect(data[1]["slug"]).toEqual("foo-bar-2");
expect(data[1]["content"]).toEqual("bar-2");
expect(data[1]["categoryId"]).toEqual(1);
});
it("should change schema", async () => {
const { data } = await dataProvider(supabaseClient).createMany({
resource: "posts",
variables: [
{
title: "foo",
slug: "foo-bar",
content: "bar",
categoryId: 2,
},
{
title: "foo-2",
slug: "foo-bar-2",
content: "bar-2",
categoryId: 1,
},
],
meta: {
schema: "public",
select: "*",
},
});
expect(data[0]["title"]).toEqual("foo");
expect(data[1]["title"]).toEqual("foo-2");
try {
await dataProvider(supabaseClient).createMany({
resource: "posts",
variables: [],
meta: {
schema: "private",
},
});
} catch (error: any) {
expect(error.code).toEqual("PGRST106");
}
});
});

View File

@@ -0,0 +1,17 @@
import { dataProvider } from "../../src/index";
import supabaseClient from "../supabaseClient";
describe("custom", () => {
it("correct get response", async () => {
try {
await dataProvider(supabaseClient).custom!({
url: "posts",
method: "get",
});
} catch (error) {
expect(error).toEqual(
Error("Not implemented on refine-supabase data provider."),
);
}
});
});

View File

@@ -0,0 +1,248 @@
import nock from "nock";
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.post("/auth/v1/token", {
email: "info@refine.dev",
password: "refine-supabase",
gotrue_meta_security: {},
})
.query({ grant_type: "password" })
.reply(
200,
{
access_token:
"eyJhbGciOiJIUzI1NiIsImtpZCI6IldGWnFuOWt6bnBJZTIvL2wiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzE0MDM5NTkyLCJpYXQiOjE3MTQwMzU5OTIsImlzcyI6Imh0dHBzOi8vaXdkZnp2ZnFidG9rcWV0bWJtYnAuc3VwYWJhc2UuY28vYXV0aC92MSIsInN1YiI6ImJkZWZhYzgxLTJiZDEtNDRkMS1iNWVkLTdhYmVkYjk2Y2NjZSIsImVtYWlsIjoiaW5mb0ByZWZpbmUuZGV2IiwicGhvbmUiOiIiLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCJ9LCJ1c2VyX21ldGFkYXRhIjp7fSwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTcxNDAzNTk5Mn1dLCJzZXNzaW9uX2lkIjoiNGM5YTcxYzQtMjhkNS00YjU0LTkwMzEtOWFjMTYzYzdlZTRjIiwiaXNfYW5vbnltb3VzIjpmYWxzZX0.GCCzlV2ZEibr22xEi5OnlcAD3vOzSRkmm1yIU_RwxHg",
token_type: "bearer",
expires_in: 3600,
expires_at: 1714039592,
refresh_token: "rG9KcdigcT1zovxRbUs8Yg",
user: {
id: "bdefac81-2bd1-44d1-b5ed-7abedb96ccce",
aud: "authenticated",
role: "authenticated",
email: "info@refine.dev",
email_confirmed_at: "2021-09-08T11:09:24.284171Z",
phone: "",
confirmation_sent_at: "2021-09-08T11:08:06.793257Z",
confirmed_at: "2021-09-08T11:09:24.284171Z",
recovery_sent_at: "2024-02-04T09:33:53.383988Z",
last_sign_in_at: "2024-04-25T09:06:32.672091588Z",
app_metadata: { provider: "email" },
user_metadata: {},
identities: [
{
identity_id: "6b8dcf5b-f068-401b-95ae-ddd93d771b74",
id: "bdefac81-2bd1-44d1-b5ed-7abedb96ccce",
user_id: "bdefac81-2bd1-44d1-b5ed-7abedb96ccce",
identity_data: {
email: "info@refine.dev",
sub: "bdefac81-2bd1-44d1-b5ed-7abedb96ccce",
},
provider: "email",
last_sign_in_at: "2022-11-25T00:00:00Z",
created_at: "2022-11-25T00:00:00Z",
updated_at: "2022-11-25T00:00:00Z",
email: "info@refine.dev",
},
],
created_at: "2021-09-08T11:08:06.789274Z",
updated_at: "2024-04-25T09:06:32.674256Z",
is_anonymous: false,
},
},
[
"Date",
"Thu, 25 Apr 2024 09:06:32 GMT",
"Content-Type",
"application/json",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"CF-Ray",
"879d2d778a795172-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Set-Cookie",
"sb-access-token=eyJhbGciOiJIUzI1NiIsImtpZCI6IldGWnFuOWt6bnBJZTIvL2wiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzE0MDM5NTkyLCJpYXQiOjE3MTQwMzU5OTIsImlzcyI6Imh0dHBzOi8vaXdkZnp2ZnFidG9rcWV0bWJtYnAuc3VwYWJhc2UuY28vYXV0aC92MSIsInN1YiI6ImJkZWZhYzgxLTJiZDEtNDRkMS1iNWVkLTdhYmVkYjk2Y2NjZSIsImVtYWlsIjoiaW5mb0ByZWZpbmUuZGV2IiwicGhvbmUiOiIiLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCJ9LCJ1c2VyX21ldGFkYXRhIjp7fSwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTcxNDAzNTk5Mn1dLCJzZXNzaW9uX2lkIjoiNGM5YTcxYzQtMjhkNS00YjU0LTkwMzEtOWFjMTYzYzdlZTRjIiwiaXNfYW5vbnltb3VzIjpmYWxzZX0.GCCzlV2ZEibr22xEi5OnlcAD3vOzSRkmm1yIU_RwxHg; Path=/; Expires=Fri, 26 Apr 2024 09:06:32 GMT; Max-Age=86400; HttpOnly; Secure",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Vary",
"Accept-Encoding, Origin",
"Via",
"kong/2.8.1",
"sb-gateway-version",
"1",
"Set-Cookie",
"sb-refresh-token=rG9KcdigcT1zovxRbUs8Yg; Path=/; Expires=Fri, 26 Apr 2024 09:06:32 GMT; Max-Age=86400; HttpOnly; Secure",
"x-kong-proxy-latency",
"1",
"x-kong-upstream-latency",
"90",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.delete("/rest/v1/posts")
.query({ id: "eq.1" })
.reply(204, "", [
"Date",
"Thu, 25 Apr 2024 09:06:33 GMT",
"Connection",
"close",
"Content-Range",
"*/*",
"CF-Ray",
"879d2d7b9d557255-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Via",
"kong/2.8.1",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"0",
"x-kong-upstream-latency",
"5",
"Vary",
"Accept-Encoding",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
]);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.delete("/rest/v1/posts")
.query({ id: "eq.1" })
.reply(204, "", [
"Date",
"Thu, 25 Apr 2024 09:06:33 GMT",
"Connection",
"close",
"Content-Range",
"*/*",
"CF-Ray",
"879d2d7eddbe7218-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Via",
"kong/2.8.1",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"1",
"x-kong-upstream-latency",
"3",
"Vary",
"Accept-Encoding",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
]);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.delete("/rest/v1/posts")
.query({ id: "eq.123" })
.reply(
406,
{
code: "PGRST106",
details: null,
hint: null,
message: "The schema must be one of the following: public, storage",
},
[
"Date",
"Thu, 25 Apr 2024 09:06:33 GMT",
"Content-Type",
"application/json; charset=utf-8",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"CF-Ray",
"879d2d8079c251a7-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Via",
"kong/2.8.1",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"1",
"x-kong-upstream-latency",
"1",
"Vary",
"Accept-Encoding",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.post("/auth/v1/logout")
.query({ scope: "global" })
.reply(204, "", [
"Date",
"Thu, 25 Apr 2024 09:06:34 GMT",
"Connection",
"close",
"CF-Ray",
"879d2d822a47696d-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Set-Cookie",
"sb-access-token=; Path=/; Expires=Wed, 24 Apr 2024 23:06:34 GMT; Max-Age=0; HttpOnly; Secure",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Vary",
"Origin, Accept-Encoding",
"Via",
"kong/2.8.1",
"sb-gateway-version",
"1",
"Set-Cookie",
"sb-refresh-token=; Path=/; Expires=Wed, 24 Apr 2024 23:06:34 GMT; Max-Age=0; HttpOnly; Secure",
"x-kong-proxy-latency",
"1",
"x-kong-upstream-latency",
"4",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
]);

View File

@@ -0,0 +1,37 @@
import { dataProvider } from "../../src/index";
import supabaseClient from "../supabaseClient";
import "./index.mock";
describe("deleteMany", () => {
it("correct response", async () => {
const promise = dataProvider(supabaseClient).deleteMany!({
resource: "posts",
ids: [1],
});
await expect(promise).resolves.not.toThrow();
});
it("should change schema", async () => {
const ids = [1];
const promise = dataProvider(supabaseClient).deleteMany({
resource: "posts",
ids,
});
await expect(promise).resolves.not.toThrow();
const promise2 = dataProvider(supabaseClient).deleteMany({
resource: "posts",
ids: [123],
meta: {
schema: "private",
},
});
await expect(promise2).rejects.toEqual(
expect.objectContaining({ code: "PGRST106" }),
);
});
});

View File

@@ -0,0 +1,120 @@
import nock from "nock";
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.delete("/rest/v1/posts")
.query({ id: "eq.27" })
.reply(204, "", [
"Date",
"Thu, 25 Apr 2024 09:08:08 GMT",
"Connection",
"close",
"Content-Range",
"*/*",
"CF-Ray",
"879d2fd0396e7237-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Via",
"kong/2.8.1",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"0",
"x-kong-upstream-latency",
"3",
"Vary",
"Accept-Encoding",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
]);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.delete("/rest/v1/posts")
.query({ id: "eq.40" })
.reply(204, "", [
"Date",
"Thu, 25 Apr 2024 09:08:08 GMT",
"Connection",
"close",
"Content-Range",
"*/*",
"CF-Ray",
"879d2fd028db724c-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Via",
"kong/2.8.1",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"0",
"x-kong-upstream-latency",
"4",
"Vary",
"Accept-Encoding",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
]);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.delete("/rest/v1/posts")
.query({ id: "eq.41" })
.reply(
406,
{
code: "PGRST106",
details: null,
hint: null,
message: "The schema must be one of the following: public, storage",
},
[
"Date",
"Thu, 25 Apr 2024 09:08:08 GMT",
"Content-Type",
"application/json; charset=utf-8",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"CF-Ray",
"879d2fd1bfa37248-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Via",
"kong/2.8.1",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"1",
"x-kong-upstream-latency",
"1",
"Vary",
"Accept-Encoding",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);

View File

@@ -0,0 +1,40 @@
import { dataProvider } from "../../src/index";
import supabaseClient from "../supabaseClient";
import "./index.mock";
describe("deleteOne", () => {
it("correct response", async () => {
const promise = dataProvider(supabaseClient).deleteOne({
resource: "posts",
id: "40",
});
expect(promise).resolves.not.toThrow();
});
it("should change schema", async () => {
const id = 27;
const promise = dataProvider(supabaseClient).deleteOne({
resource: "posts",
id,
meta: {
schema: "public",
},
});
await expect(promise).resolves.not.toThrow();
const promise2 = dataProvider(supabaseClient).deleteOne({
resource: "posts",
id: 41,
meta: {
schema: "private",
},
});
await expect(promise2).rejects.toEqual(
expect.objectContaining({ code: "PGRST106" }),
);
});
});

View File

@@ -0,0 +1,14 @@
import { dataProvider } from "../../src/index";
import supabaseClient from "../supabaseClient";
describe("getApiUrl", () => {
it("correct get response", async () => {
try {
dataProvider(supabaseClient).getApiUrl();
} catch (error) {
expect(error).toEqual(
Error("Not implemented on refine-supabase data provider."),
);
}
});
});

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,452 @@
import type { SupabaseClient } from "@supabase/supabase-js";
import { dataProvider } from "../../src/index";
import supabaseClient from "../supabaseClient";
import "./index.mock";
describe("getList", () => {
it("correct response", async () => {
const { data, total } = await dataProvider(supabaseClient).getList({
resource: "posts",
});
expect(data[0]["id"]).toBe(1);
expect(data[0]["title"]).toBe("Black Psorotichia Lichen");
expect(total).toBe(20);
});
it("correct response with metadata select", async () => {
const { data, total } = await dataProvider(supabaseClient).getList({
resource: "posts",
meta: {
select: "title",
},
});
expect(Object.keys(data[0]).length).toBe(1);
expect(data[0]["title"]).toBe("Black Psorotichia Lichen");
expect(total).toBe(20);
});
it("correct response with metadata count", async () => {
const { data, total } = await dataProvider(supabaseClient).getList({
resource: "posts",
meta: {
count: "estimated",
},
});
expect(data[0]["id"]).toBe(1);
expect(data[0]["title"]).toBe("Black Psorotichia Lichen");
expect(total).toBe(20);
});
it("correct sorting response", async () => {
const { data, total } = await dataProvider(supabaseClient).getList({
resource: "posts",
sorters: [
{
field: "title",
order: "asc",
},
],
});
expect(data[0]["id"]).toBe(16);
expect(data[0]["title"]).toBe("Anopteris");
expect(total).toBe(20);
});
describe("Supabase order", () => {
const mockSupabaseOrder = jest.fn();
const mockSupabaseClient = {
select: () => mockSupabaseClient,
from: () => mockSupabaseClient,
range: () => mockSupabaseClient,
schema: () => mockSupabaseClient,
order: mockSupabaseOrder,
} as unknown as SupabaseClient;
it("correct sorting object with foreignTable", async () => {
await dataProvider(mockSupabaseClient).getList({
resource: "posts",
sorters: [
{
field: "categories.title",
order: "asc",
},
],
});
expect(mockSupabaseOrder).toHaveBeenCalledWith("title", {
ascending: true,
foreignTable: "categories",
});
});
it("correct sorting object with nested foreignTable", async () => {
await dataProvider(mockSupabaseClient).getList({
resource: "posts",
sorters: [
{
field: "categories.tags.title",
order: "asc",
},
],
});
expect(mockSupabaseOrder).toHaveBeenCalledWith("title", {
ascending: true,
foreignTable: "categories.tags",
});
});
it("correct sorting object without foreignTable", async () => {
await dataProvider(mockSupabaseClient).getList({
resource: "posts",
sorters: [
{
field: "title",
order: "asc",
},
],
});
expect(mockSupabaseOrder).toHaveBeenCalledWith("title", {
ascending: true,
});
});
});
});
describe("filtering", () => {
it("eq operator should work correctly", async () => {
const { data, total } = await dataProvider(supabaseClient).getList({
resource: "posts",
filters: [
{
field: "title",
operator: "eq",
value: "Basil Mountainmint",
},
],
});
expect(data[0]["title"]).toBe("Basil Mountainmint");
expect(total).toBe(1);
});
it("ne operator should work correctly", async () => {
const { data, total } = await dataProvider(supabaseClient).getList({
resource: "posts",
filters: [
{
field: "title",
operator: "ne",
value: "Basil Mountainmint",
},
],
});
expect(data[0]["title"]).not.toBe("Basil Mountainmint");
expect(total).toBe(19);
});
it("lt operator should work correctly", async () => {
const { data, total } = await dataProvider(supabaseClient).getList({
resource: "posts",
filters: [
{
field: "id",
operator: "lt",
value: 3,
},
],
});
expect(data[0]["id"]).toBe(1);
expect(data[1]["id"]).toBe(2);
expect(total).toBe(2);
});
it("gt operator should work correctly", async () => {
const { data, total } = await dataProvider(supabaseClient).getList({
resource: "posts",
filters: [
{
field: "id",
operator: "gt",
value: 3,
},
],
});
expect(data[0]["id"]).toBe(4);
expect(data[1]["id"]).toBe(5);
expect(total).toBe(17);
});
it("lte operator should work correctly", async () => {
const { data, total } = await dataProvider(supabaseClient).getList({
resource: "posts",
filters: [
{
field: "id",
operator: "lte",
value: 2,
},
],
});
expect(data[0]["id"]).toBe(1);
expect(data[1]["id"]).toBe(2);
expect(total).toBe(2);
});
it("gte operator should work correctly", async () => {
const { data, total } = await dataProvider(supabaseClient).getList({
resource: "posts",
filters: [
{
field: "id",
operator: "gte",
value: 20,
},
],
});
expect(data[0]["id"]).toBe(20);
expect(total).toBe(1);
});
it("in operator should work correctly", async () => {
const { data, total } = await dataProvider(supabaseClient).getList({
resource: "posts",
filters: [
{
field: "id",
operator: "in",
value: ["2", "3"],
},
],
});
expect(data[0]["id"]).toBe(2);
expect(data[1]["id"]).toBe(3);
expect(total).toBe(2);
});
it("contains operator should work correctly", async () => {
const { data, total } = await dataProvider(supabaseClient).getList({
resource: "posts",
filters: [
{
field: "title",
operator: "contains",
value: "Basil",
},
],
});
expect(data).toHaveLength(1);
expect(data[0].title).toBe("Basil Mountainmint");
expect(total).toBe(1);
});
it("containss operator should work correctly", async () => {
const { data, total } = await dataProvider(supabaseClient).getList({
resource: "posts",
filters: [
{
field: "title",
operator: "containss",
value: "Basil",
},
],
});
expect(data[0]["title"]).toBe("Basil Mountainmint");
expect(total).toBe(1);
});
it("null operator should work correctly", async () => {
const { data, total } = await dataProvider(supabaseClient).getList({
resource: "posts",
filters: [
{
field: "content",
operator: "null",
value: null,
},
],
});
expect(data).toHaveLength(0);
expect(total).toBe(0);
});
it("or operator should work correctly", async () => {
const { data, total } = await dataProvider(supabaseClient).getList({
resource: "posts",
filters: [
{
operator: "or",
value: [
{
field: "title",
operator: "eq",
value: "Dust Lichen",
},
{
field: "title",
operator: "eq",
value: "Black Psorotichia Lichen",
},
],
},
],
});
expect(data[0]["title"]).toBe("Black Psorotichia Lichen");
expect(data[1]["title"]).toBe("Dust Lichen");
expect(total).toBe(2);
});
it("ina operator should work correctly with or", async () => {
const { data, total } = await dataProvider(supabaseClient).getList({
resource: "posts",
filters: [
{
operator: "or",
value: [
{
field: "id",
operator: "eq",
value: "2",
},
{
field: "tags",
operator: "ina",
value: ["recipes", "personal", "food"],
},
],
},
],
});
expect(data[0]["title"]).toBe("Oakwoods Prairie Clover");
expect(data[1]["title"]).toBe("Samsung Galaxy S21");
expect(data[2]["title"]).toBe("Black Psorotichia Lichen");
expect(total).toBe(3);
});
it("ina operator should work correctly", async () => {
const { data, total } = await dataProvider(supabaseClient).getList({
resource: "posts",
filters: [
{
field: "tags",
operator: "ina",
value: ["health", "travel"],
},
],
});
expect(data[0]["id"]).toBe(6);
expect(data[1]["id"]).toBe(2);
expect(data[2]["id"]).toBe(1);
expect(total).toBe(3);
});
it("nina operator should work correctly", async () => {
const { data, total } = await dataProvider(supabaseClient).getList({
resource: "posts",
filters: [
{
field: "tags",
operator: "nina",
value: ["lifestyle", "personal"],
},
],
});
expect(data[0]["id"]).toBe(7);
expect(data[1]["id"]).toBe(8);
expect(data[2]["id"]).toBe(11);
expect(data[3]["id"]).toBe(5);
expect(data[4]["id"]).toBe(2);
expect(total).toBe(5);
});
it("nina operator should work correctly with or", async () => {
const { data, total } = await dataProvider(supabaseClient).getList({
resource: "posts",
filters: [
{
operator: "or",
value: [
{
field: "tags",
operator: "ina",
value: ["technology", "education"],
},
{
field: "tags",
operator: "nina",
value: ["lifestyle", "personal"],
},
],
},
],
});
expect(data[0]["title"]).toBe("Sickle Island Spleenwort");
expect(data[1]["title"]).toBe("Oakwoods Prairie Clover");
expect(data[2]["title"]).toBe("Funck's Wart Lichen");
expect(data[3]["title"]).toBe("test");
expect(data[4]["title"]).toBe("Samsung Galaxy S21");
expect(data[5]["title"]).toBe("Black Psorotichia Lichen");
expect(total).toBe(6);
});
it("contains operator should work correctly with or", async () => {
const { data, total } = await dataProvider(supabaseClient).getList({
resource: "posts",
filters: [
{
operator: "or",
value: [
{
field: "title",
operator: "contains",
value: "Black Psorotichia",
},
{
field: "content",
operator: "contains",
value: "Sed sagittis",
},
],
},
],
});
expect(data).toHaveLength(2);
expect(data[0].title).toBe("Black Psorotichia Lichen");
expect(data[1].title).toBe("Dust Lichen");
expect(total).toBe(2);
});
it("should change schema", async () => {
const { data } = await dataProvider(supabaseClient).getList({
resource: "posts",
meta: {
schema: "public",
select: "*",
},
});
expect(data.length).toBeGreaterThan(0);
const promise = dataProvider(supabaseClient).getList({
resource: "products",
meta: {
schema: "private",
},
});
await expect(promise).rejects.toEqual(
expect.objectContaining({ code: "PGRST106" }),
);
});
});

View File

@@ -0,0 +1,234 @@
import nock from "nock";
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.get("/rest/v1/posts")
.query({ select: "%2A", id: "in.%282%2C3%29" })
.reply(
200,
[
{
id: 2,
title: "Great Plains Flatsedge",
slug: "5aecd7b0-cf28-40b4-ad48-7d4c6718837e",
createdAt: "2024-04-24T13:20:10.200327+00:00",
content:
"In hac habitasse platea dictumst. Etiam faucibus cursus urna. Ut tellus.\n\nNulla ut erat id mauris vulputate elementum. Nullam varius. Nulla facilisi.\n\nCras non velit nec nisi vulputate nonummy. Maecenas tincidunt lacus at velit. Vivamus vel nulla eget eros elementum pellentesque.",
categoryId: 8,
images: null,
},
{
id: 3,
title: "Copperweed",
slug: "8d9116f0-ee0e-48ec-8d76-c056d041820f",
createdAt: "2024-04-24T13:20:10.200327+00:00",
content:
"Morbi non lectus. Aliquam sit amet diam in magna bibendum imperdiet. Nullam orci pede, venenatis non, sodales sed, tincidunt eu, felis.",
categoryId: 1,
images: null,
},
],
[
"Date",
"Thu, 25 Apr 2024 09:09:30 GMT",
"Content-Type",
"application/json; charset=utf-8",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"Content-Range",
"0-1/*",
"CF-Ray",
"879d31d06c387218-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Content-Location",
"/posts?id=in.%282%2C3%29&select=%2A",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Vary",
"Accept-Encoding",
"Via",
"kong/2.8.1",
"content-profile",
"public",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"1",
"x-kong-upstream-latency",
"3",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.get("/rest/v1/posts")
.query({ select: "title", id: "in.%283%2C4%29" })
.reply(
200,
[{ title: "Copperweed" }, { title: "Bastard Toadflax" }],
[
"Date",
"Thu, 25 Apr 2024 09:09:30 GMT",
"Content-Type",
"application/json; charset=utf-8",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"Content-Range",
"0-1/*",
"CF-Ray",
"879d31d29c005142-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Content-Location",
"/posts?id=in.%283%2C4%29&select=title",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Vary",
"Accept-Encoding",
"Via",
"kong/2.8.1",
"content-profile",
"public",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"1",
"x-kong-upstream-latency",
"3",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.get("/rest/v1/posts")
.query({ select: "%2A", id: "in.%281%2C2%29" })
.reply(
200,
[
{
id: 1,
title: "Black Psorotichia Lichen",
slug: "61a31089-c85d-48a0-a4be-d5dce5c96b6a",
createdAt: "2024-04-24T13:20:10.200327+00:00",
content:
"Integer tincidunt ante vel ipsum. Praesent blandit lacinia erat. Vestibulum sed magna at nunc commodo placerat.\n\nPraesent blandit. Nam nulla. Integer pede justo, lacinia eget, tincidunt eget, tempus vel, pede.\n\nMorbi porttitor lorem id ligula. Suspendisse ornare consequat lectus. In est risus, auctor sed, tristique in, tempus sit amet, sem.",
categoryId: 7,
images: null,
},
{
id: 2,
title: "Great Plains Flatsedge",
slug: "5aecd7b0-cf28-40b4-ad48-7d4c6718837e",
createdAt: "2024-04-24T13:20:10.200327+00:00",
content:
"In hac habitasse platea dictumst. Etiam faucibus cursus urna. Ut tellus.\n\nNulla ut erat id mauris vulputate elementum. Nullam varius. Nulla facilisi.\n\nCras non velit nec nisi vulputate nonummy. Maecenas tincidunt lacus at velit. Vivamus vel nulla eget eros elementum pellentesque.",
categoryId: 8,
images: null,
},
],
[
"Date",
"Thu, 25 Apr 2024 09:09:31 GMT",
"Content-Type",
"application/json; charset=utf-8",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"Content-Range",
"0-1/*",
"CF-Ray",
"879d31d4bba76950-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Content-Location",
"/posts?id=in.%281%2C2%29&select=%2A",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Vary",
"Accept-Encoding",
"Via",
"kong/2.8.1",
"content-profile",
"public",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"1",
"x-kong-upstream-latency",
"3",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.get("/rest/v1/posts")
.query({ select: "%2A", id: "in.%281%2C2%29" })
.reply(
406,
{
code: "PGRST106",
details: null,
hint: null,
message: "The schema must be one of the following: public, storage",
},
[
"Date",
"Thu, 25 Apr 2024 09:09:31 GMT",
"Content-Type",
"application/json; charset=utf-8",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"CF-Ray",
"879d31d7c8dd514d-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Via",
"kong/2.8.1",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"1",
"x-kong-upstream-latency",
"0",
"Vary",
"Accept-Encoding",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);

View File

@@ -0,0 +1,64 @@
import nock from "nock";
import { dataProvider } from "../../src/index";
import supabaseClient from "../supabaseClient";
import "./index.mock";
describe("getMany", () => {
it("correct response", async () => {
const response = await dataProvider(supabaseClient).getMany!({
resource: "posts",
ids: ["2", "3"],
});
const { data } = response;
expect(data[0]["id"]).toBe(2);
expect(data[1]["id"]).toBe(3);
expect(response.data.length).toBe(2);
});
it("correct response with select metadata", async () => {
const { data } = await dataProvider(supabaseClient).getMany!({
resource: "posts",
ids: ["3", "4"],
meta: {
select: "title",
},
});
expect(Object.keys(data[0]).length).toBe(1);
expect(data[0]["title"]).toBe("Copperweed");
expect(data[1]["title"]).toBe("Bastard Toadflax");
expect(data.length).toBe(2);
});
it("should change schema", async () => {
const { data } = await dataProvider(supabaseClient).getMany({
resource: "posts",
ids: [1, 2],
meta: {
schema: "public",
select: "*",
},
});
expect(data).toEqual(
expect.arrayContaining([
expect.objectContaining({ id: 1, title: "Black Psorotichia Lichen" }),
expect.objectContaining({ id: 2, title: "Great Plains Flatsedge" }),
]),
);
const promise = dataProvider(supabaseClient).getMany({
resource: "posts",
ids: [1, 2],
meta: {
schema: "private",
},
});
await expect(promise).rejects.toEqual(
expect.objectContaining({ code: "PGRST106" }),
);
});
});

View File

@@ -0,0 +1,108 @@
import nock from "nock";
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.get("/rest/v1/posts")
.query({ select: "%2A", id: "eq.2" })
.reply(
200,
[
{
id: 2,
title: "Great Plains Flatsedge",
slug: "5aecd7b0-cf28-40b4-ad48-7d4c6718837e",
createdAt: "2024-04-24T13:20:10.200327+00:00",
content:
"In hac habitasse platea dictumst. Etiam faucibus cursus urna. Ut tellus.\n\nNulla ut erat id mauris vulputate elementum. Nullam varius. Nulla facilisi.\n\nCras non velit nec nisi vulputate nonummy. Maecenas tincidunt lacus at velit. Vivamus vel nulla eget eros elementum pellentesque.",
categoryId: 8,
images: null,
},
],
[
"Date",
"Thu, 25 Apr 2024 09:10:35 GMT",
"Content-Type",
"application/json; charset=utf-8",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"Content-Range",
"0-0/*",
"CF-Ray",
"879d3362ae3d5184-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Content-Location",
"/posts?id=eq.2&select=%2A",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Vary",
"Accept-Encoding",
"Via",
"kong/2.8.1",
"content-profile",
"public",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"1",
"x-kong-upstream-latency",
"3",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.get("/rest/v1/posts")
.query({ select: "title", id: "eq.3" })
.reply(
200,
[{ title: "Copperweed" }],
[
"Date",
"Thu, 25 Apr 2024 09:10:35 GMT",
"Content-Type",
"application/json; charset=utf-8",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"Content-Range",
"0-0/*",
"CF-Ray",
"879d33679f16724e-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Content-Location",
"/posts?id=eq.3&select=title",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Vary",
"Accept-Encoding",
"Via",
"kong/2.8.1",
"content-profile",
"public",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"1",
"x-kong-upstream-latency",
"3",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);

View File

@@ -0,0 +1,29 @@
import nock from "nock";
import { dataProvider } from "../../src";
import supabaseClient from "../supabaseClient";
import "./index.mock";
describe("getOne", () => {
it("correct response", async () => {
const { data } = await dataProvider(supabaseClient).getOne({
resource: "posts",
id: "2",
});
expect(data.title).toBe("Great Plains Flatsedge");
expect(data.categoryId).toEqual(8);
});
it("correct response with select metadata", async () => {
const { data } = await dataProvider(supabaseClient).getOne({
resource: "posts",
id: "3",
meta: {
select: "title",
},
});
expect(Object.keys(data).length).toBe(1);
expect(data.title).toBe("Copperweed");
});
});

View File

@@ -0,0 +1,8 @@
import nock from "nock";
// nock.recorder.rec();
afterAll(() => {
nock.cleanAll();
nock.restore();
});

View File

@@ -0,0 +1,15 @@
import { createClient } from "../src/index";
const SUPABASE_URL = "https://iwdfzvfqbtokqetmbmbp.supabase.co";
const SUPABASE_KEY =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYW5vbiIsImlhdCI6MTYzMDU2NzAxMCwiZXhwIjoxOTQ2MTQzMDEwfQ._gr6kXGkQBi9BM9dx5vKaNKYj_DJN1xlkarprGpM_fU";
const supabaseClient = createClient(SUPABASE_URL, SUPABASE_KEY, {
global: {
headers: {
"Accept-Encoding": "identity",
},
},
});
export default supabaseClient;

View File

@@ -0,0 +1,292 @@
import nock from "nock";
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.post("/auth/v1/token", {
email: "info@refine.dev",
password: "refine-supabase",
gotrue_meta_security: {},
})
.query({ grant_type: "password" })
.reply(
200,
{
access_token:
"eyJhbGciOiJIUzI1NiIsImtpZCI6IldGWnFuOWt6bnBJZTIvL2wiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzE0MDM5OTAzLCJpYXQiOjE3MTQwMzYzMDMsImlzcyI6Imh0dHBzOi8vaXdkZnp2ZnFidG9rcWV0bWJtYnAuc3VwYWJhc2UuY28vYXV0aC92MSIsInN1YiI6ImJkZWZhYzgxLTJiZDEtNDRkMS1iNWVkLTdhYmVkYjk2Y2NjZSIsImVtYWlsIjoiaW5mb0ByZWZpbmUuZGV2IiwicGhvbmUiOiIiLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCJ9LCJ1c2VyX21ldGFkYXRhIjp7fSwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTcxNDAzNjMwM31dLCJzZXNzaW9uX2lkIjoiNzZlZGVjZmItY2NkMS00OTVlLWIxZDAtOGJjMTZjY2QxMWIyIiwiaXNfYW5vbnltb3VzIjpmYWxzZX0.h1ujlkSBF2ffMtawITfk1e55ekrQBIHDe8Q9AHr9hkI",
token_type: "bearer",
expires_in: 3600,
expires_at: 1714039903,
refresh_token: "FsqYSQlJiUAHRzFTlhyBAw",
user: {
id: "bdefac81-2bd1-44d1-b5ed-7abedb96ccce",
aud: "authenticated",
role: "authenticated",
email: "info@refine.dev",
email_confirmed_at: "2021-09-08T11:09:24.284171Z",
phone: "",
confirmation_sent_at: "2021-09-08T11:08:06.793257Z",
confirmed_at: "2021-09-08T11:09:24.284171Z",
recovery_sent_at: "2024-02-04T09:33:53.383988Z",
last_sign_in_at: "2024-04-25T09:11:43.634259122Z",
app_metadata: { provider: "email" },
user_metadata: {},
identities: [
{
identity_id: "6b8dcf5b-f068-401b-95ae-ddd93d771b74",
id: "bdefac81-2bd1-44d1-b5ed-7abedb96ccce",
user_id: "bdefac81-2bd1-44d1-b5ed-7abedb96ccce",
identity_data: {
email: "info@refine.dev",
sub: "bdefac81-2bd1-44d1-b5ed-7abedb96ccce",
},
provider: "email",
last_sign_in_at: "2022-11-25T00:00:00Z",
created_at: "2022-11-25T00:00:00Z",
updated_at: "2022-11-25T00:00:00Z",
email: "info@refine.dev",
},
],
created_at: "2021-09-08T11:08:06.789274Z",
updated_at: "2024-04-25T09:11:43.636138Z",
is_anonymous: false,
},
},
[
"Date",
"Thu, 25 Apr 2024 09:11:43 GMT",
"Content-Type",
"application/json",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"CF-Ray",
"879d35106bb851ad-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Set-Cookie",
"sb-access-token=eyJhbGciOiJIUzI1NiIsImtpZCI6IldGWnFuOWt6bnBJZTIvL2wiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzE0MDM5OTAzLCJpYXQiOjE3MTQwMzYzMDMsImlzcyI6Imh0dHBzOi8vaXdkZnp2ZnFidG9rcWV0bWJtYnAuc3VwYWJhc2UuY28vYXV0aC92MSIsInN1YiI6ImJkZWZhYzgxLTJiZDEtNDRkMS1iNWVkLTdhYmVkYjk2Y2NjZSIsImVtYWlsIjoiaW5mb0ByZWZpbmUuZGV2IiwicGhvbmUiOiIiLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCJ9LCJ1c2VyX21ldGFkYXRhIjp7fSwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTcxNDAzNjMwM31dLCJzZXNzaW9uX2lkIjoiNzZlZGVjZmItY2NkMS00OTVlLWIxZDAtOGJjMTZjY2QxMWIyIiwiaXNfYW5vbnltb3VzIjpmYWxzZX0.h1ujlkSBF2ffMtawITfk1e55ekrQBIHDe8Q9AHr9hkI; Path=/; Expires=Fri, 26 Apr 2024 09:11:43 GMT; Max-Age=86400; HttpOnly; Secure",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Vary",
"Accept-Encoding, Origin",
"Via",
"kong/2.8.1",
"sb-gateway-version",
"1",
"Set-Cookie",
"sb-refresh-token=FsqYSQlJiUAHRzFTlhyBAw; Path=/; Expires=Fri, 26 Apr 2024 09:11:43 GMT; Max-Age=86400; HttpOnly; Secure",
"x-kong-proxy-latency",
"0",
"x-kong-upstream-latency",
"96",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.patch("/rest/v1/posts", {
title: "test",
categoryId: 5,
content: "test content",
})
.query({ id: "eq.1", select: "%2A" })
.reply(
200,
[
{
id: 1,
title: "test",
slug: "61a31089-c85d-48a0-a4be-d5dce5c96b6a",
createdAt: "2024-04-24T13:20:10.200327+00:00",
content: "test content",
categoryId: 5,
images: null,
},
],
[
"Date",
"Thu, 25 Apr 2024 09:11:43 GMT",
"Content-Type",
"application/json; charset=utf-8",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"Content-Range",
"0-0/*",
"CF-Ray",
"879d3512cb5d515f-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Vary",
"Accept-Encoding",
"Via",
"kong/2.8.1",
"content-profile",
"public",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"3",
"x-kong-upstream-latency",
"5",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.patch("/rest/v1/posts", { title: "IPhone 16" })
.query({ id: "eq.1", select: "%2A" })
.reply(
200,
[
{
id: 1,
title: "IPhone 16",
slug: "61a31089-c85d-48a0-a4be-d5dce5c96b6a",
createdAt: "2024-04-24T13:20:10.200327+00:00",
content: "test content",
categoryId: 5,
images: null,
},
],
[
"Date",
"Thu, 25 Apr 2024 09:11:44 GMT",
"Content-Type",
"application/json; charset=utf-8",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"Content-Range",
"0-0/*",
"CF-Ray",
"879d35145e6f720c-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Vary",
"Accept-Encoding",
"Via",
"kong/2.8.1",
"content-profile",
"public",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"0",
"x-kong-upstream-latency",
"5",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.patch("/rest/v1/posts", { title: "IPhone 16" })
.query({ id: "eq.1", select: "%2A" })
.reply(
406,
{
code: "PGRST106",
details: null,
hint: null,
message: "The schema must be one of the following: public, storage",
},
[
"Date",
"Thu, 25 Apr 2024 09:11:44 GMT",
"Content-Type",
"application/json; charset=utf-8",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"CF-Ray",
"879d3515fad66966-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Via",
"kong/2.8.1",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"3",
"x-kong-upstream-latency",
"1",
"Vary",
"Accept-Encoding",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.post("/auth/v1/logout")
.query({ scope: "global" })
.reply(204, "", [
"Date",
"Thu, 25 Apr 2024 09:11:44 GMT",
"Connection",
"close",
"CF-Ray",
"879d3518ffc1515a-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Set-Cookie",
"sb-access-token=; Path=/; Expires=Wed, 24 Apr 2024 23:11:44 GMT; Max-Age=0; HttpOnly; Secure",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Vary",
"Origin, Accept-Encoding",
"Via",
"kong/2.8.1",
"sb-gateway-version",
"1",
"Set-Cookie",
"sb-refresh-token=; Path=/; Expires=Wed, 24 Apr 2024 23:11:44 GMT; Max-Age=0; HttpOnly; Secure",
"x-kong-proxy-latency",
"1",
"x-kong-upstream-latency",
"5",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
]);

View File

@@ -0,0 +1,63 @@
import { dataProvider } from "../../src";
import supabaseClient from "../supabaseClient";
import "./index.mock";
describe("update", () => {
it("correct response with `select`", async () => {
const { data } = await dataProvider(supabaseClient).update({
id: 1,
resource: "posts",
variables: {
title: "test",
categoryId: 5,
content: "test content",
},
meta: {
select: "*",
},
});
expect(data).toEqual(
expect.objectContaining({
id: 1,
title: "test",
categoryId: 5,
content: "test content",
}),
);
});
it("should change schema", async () => {
const id = 1;
const { data } = await dataProvider(supabaseClient).update({
id,
resource: "posts",
variables: {
title: "IPhone 16",
},
meta: {
select: "*",
},
});
expect(data).toEqual(
expect.objectContaining({ id: 1, title: "IPhone 16" }),
);
const promise = dataProvider(supabaseClient).update({
id,
resource: "posts",
variables: {
title: "IPhone 16",
},
meta: {
schema: "private",
},
});
await expect(promise).rejects.toEqual(
expect.objectContaining({ code: "PGRST106" }),
);
});
});

View File

@@ -0,0 +1,397 @@
import nock from "nock";
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.post("/auth/v1/token", {
email: "info@refine.dev",
password: "refine-supabase",
gotrue_meta_security: {},
})
.query({ grant_type: "password" })
.reply(
200,
{
access_token:
"eyJhbGciOiJIUzI1NiIsImtpZCI6IldGWnFuOWt6bnBJZTIvL2wiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzE0MDM5OTc5LCJpYXQiOjE3MTQwMzYzNzksImlzcyI6Imh0dHBzOi8vaXdkZnp2ZnFidG9rcWV0bWJtYnAuc3VwYWJhc2UuY28vYXV0aC92MSIsInN1YiI6ImJkZWZhYzgxLTJiZDEtNDRkMS1iNWVkLTdhYmVkYjk2Y2NjZSIsImVtYWlsIjoiaW5mb0ByZWZpbmUuZGV2IiwicGhvbmUiOiIiLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCJ9LCJ1c2VyX21ldGFkYXRhIjp7fSwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTcxNDAzNjM3OX1dLCJzZXNzaW9uX2lkIjoiZjRlNjkwNTgtOWY0Ni00YmYwLWI3MjQtZDVkY2ZkMmY5ZmQyIiwiaXNfYW5vbnltb3VzIjpmYWxzZX0.FWA46pwyXCu-BfBoMZwNCooGi1teFtoQ_E7_noCL7hU",
token_type: "bearer",
expires_in: 3600,
expires_at: 1714039979,
refresh_token: "RgfN0VQQ6MCOAHoJis5lVw",
user: {
id: "bdefac81-2bd1-44d1-b5ed-7abedb96ccce",
aud: "authenticated",
role: "authenticated",
email: "info@refine.dev",
email_confirmed_at: "2021-09-08T11:09:24.284171Z",
phone: "",
confirmation_sent_at: "2021-09-08T11:08:06.793257Z",
confirmed_at: "2021-09-08T11:09:24.284171Z",
recovery_sent_at: "2024-02-04T09:33:53.383988Z",
last_sign_in_at: "2024-04-25T09:12:59.984007107Z",
app_metadata: { provider: "email" },
user_metadata: {},
identities: [
{
identity_id: "6b8dcf5b-f068-401b-95ae-ddd93d771b74",
id: "bdefac81-2bd1-44d1-b5ed-7abedb96ccce",
user_id: "bdefac81-2bd1-44d1-b5ed-7abedb96ccce",
identity_data: {
email: "info@refine.dev",
sub: "bdefac81-2bd1-44d1-b5ed-7abedb96ccce",
},
provider: "email",
last_sign_in_at: "2022-11-25T00:00:00Z",
created_at: "2022-11-25T00:00:00Z",
updated_at: "2022-11-25T00:00:00Z",
email: "info@refine.dev",
},
],
created_at: "2021-09-08T11:08:06.789274Z",
updated_at: "2024-04-25T09:12:59.985841Z",
is_anonymous: false,
},
},
[
"Date",
"Thu, 25 Apr 2024 09:13:00 GMT",
"Content-Type",
"application/json",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"CF-Ray",
"879d36ec2b315178-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Set-Cookie",
"sb-access-token=eyJhbGciOiJIUzI1NiIsImtpZCI6IldGWnFuOWt6bnBJZTIvL2wiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOiJhdXRoZW50aWNhdGVkIiwiZXhwIjoxNzE0MDM5OTc5LCJpYXQiOjE3MTQwMzYzNzksImlzcyI6Imh0dHBzOi8vaXdkZnp2ZnFidG9rcWV0bWJtYnAuc3VwYWJhc2UuY28vYXV0aC92MSIsInN1YiI6ImJkZWZhYzgxLTJiZDEtNDRkMS1iNWVkLTdhYmVkYjk2Y2NjZSIsImVtYWlsIjoiaW5mb0ByZWZpbmUuZGV2IiwicGhvbmUiOiIiLCJhcHBfbWV0YWRhdGEiOnsicHJvdmlkZXIiOiJlbWFpbCJ9LCJ1c2VyX21ldGFkYXRhIjp7fSwicm9sZSI6ImF1dGhlbnRpY2F0ZWQiLCJhYWwiOiJhYWwxIiwiYW1yIjpbeyJtZXRob2QiOiJwYXNzd29yZCIsInRpbWVzdGFtcCI6MTcxNDAzNjM3OX1dLCJzZXNzaW9uX2lkIjoiZjRlNjkwNTgtOWY0Ni00YmYwLWI3MjQtZDVkY2ZkMmY5ZmQyIiwiaXNfYW5vbnltb3VzIjpmYWxzZX0.FWA46pwyXCu-BfBoMZwNCooGi1teFtoQ_E7_noCL7hU; Path=/; Expires=Fri, 26 Apr 2024 09:12:59 GMT; Max-Age=86400; HttpOnly; Secure",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Vary",
"Accept-Encoding, Origin",
"Via",
"kong/2.8.1",
"sb-gateway-version",
"1",
"Set-Cookie",
"sb-refresh-token=RgfN0VQQ6MCOAHoJis5lVw; Path=/; Expires=Fri, 26 Apr 2024 09:12:59 GMT; Max-Age=86400; HttpOnly; Secure",
"x-kong-proxy-latency",
"4",
"x-kong-upstream-latency",
"90",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.patch("/rest/v1/posts", {
title: "test",
categoryId: 12,
content: "test content",
})
.query({ id: "eq.5", select: "%2A" })
.reply(
200,
[
{
id: 5,
title: "test",
slug: "6ca3651b-ce0b-45c7-9bd3-ece235142da5",
createdAt: "2024-04-24T13:20:10.200327+00:00",
content: "test content",
categoryId: 12,
images: null,
},
],
[
"Date",
"Thu, 25 Apr 2024 09:13:00 GMT",
"Content-Type",
"application/json; charset=utf-8",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"Content-Range",
"0-0/*",
"CF-Ray",
"879d36efdc2a68ac-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Vary",
"Accept-Encoding",
"Via",
"kong/2.8.1",
"content-profile",
"public",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"3",
"x-kong-upstream-latency",
"6",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.patch("/rest/v1/posts", { title: "Samsung Galaxy S21" })
.query({ id: "eq.1", select: "%2A" })
.reply(
200,
[
{
id: 1,
title: "Samsung Galaxy S21",
slug: "61a31089-c85d-48a0-a4be-d5dce5c96b6a",
createdAt: "2024-04-24T13:20:10.200327+00:00",
content:
"Integer tincidunt ante vel ipsum. Praesent blandit lacinia erat. Vestibulum sed magna at nunc commodo placerat.\n\nPraesent blandit. Nam nulla. Integer pede justo, lacinia eget, tincidunt eget, tempus vel, pede.\n\nMorbi porttitor lorem id ligula. Suspendisse ornare consequat lectus. In est risus, auctor sed, tristique in, tempus sit amet, sem.",
categoryId: 7,
images: null,
},
],
[
"Date",
"Thu, 25 Apr 2024 09:13:00 GMT",
"Content-Type",
"application/json; charset=utf-8",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"Content-Range",
"0-0/*",
"CF-Ray",
"879d36f1fe315105-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Vary",
"Accept-Encoding",
"Via",
"kong/2.8.1",
"content-profile",
"public",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"0",
"x-kong-upstream-latency",
"4",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.patch("/rest/v1/posts", { title: "Samsung Galaxy S21" })
.query({ id: "eq.2", select: "%2A" })
.reply(
200,
[
{
id: 2,
title: "Samsung Galaxy S21",
slug: "5aecd7b0-cf28-40b4-ad48-7d4c6718837e",
createdAt: "2024-04-24T13:20:10.200327+00:00",
content:
"In hac habitasse platea dictumst. Etiam faucibus cursus urna. Ut tellus.\n\nNulla ut erat id mauris vulputate elementum. Nullam varius. Nulla facilisi.\n\nCras non velit nec nisi vulputate nonummy. Maecenas tincidunt lacus at velit. Vivamus vel nulla eget eros elementum pellentesque.",
categoryId: 8,
images: null,
},
],
[
"Date",
"Thu, 25 Apr 2024 09:13:00 GMT",
"Content-Type",
"application/json; charset=utf-8",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"Content-Range",
"0-0/*",
"CF-Ray",
"879d36f208677790-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Vary",
"Accept-Encoding",
"Via",
"kong/2.8.1",
"content-profile",
"public",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"0",
"x-kong-upstream-latency",
"6",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.patch("/rest/v1/posts", { title: "foo" })
.query({ id: "eq.1", select: "%2A" })
.reply(
406,
{
code: "PGRST106",
details: null,
hint: null,
message: "The schema must be one of the following: public, storage",
},
[
"Date",
"Thu, 25 Apr 2024 09:13:01 GMT",
"Content-Type",
"application/json; charset=utf-8",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"CF-Ray",
"879d36f5adfe696e-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Via",
"kong/2.8.1",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"0",
"x-kong-upstream-latency",
"1",
"Vary",
"Accept-Encoding",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.patch("/rest/v1/posts", { title: "foo" })
.query({ id: "eq.2", select: "%2A" })
.reply(
406,
{
code: "PGRST106",
details: null,
hint: null,
message: "The schema must be one of the following: public, storage",
},
[
"Date",
"Thu, 25 Apr 2024 09:13:01 GMT",
"Content-Type",
"application/json; charset=utf-8",
"Transfer-Encoding",
"chunked",
"Connection",
"close",
"CF-Ray",
"879d36f5ad0750c3-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Via",
"kong/2.8.1",
"sb-gateway-version",
"1",
"x-kong-proxy-latency",
"5",
"x-kong-upstream-latency",
"1",
"Vary",
"Accept-Encoding",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
],
);
nock("https://iwdfzvfqbtokqetmbmbp.supabase.co:443", {
encodedQueryParams: true,
})
.post("/auth/v1/logout")
.query({ scope: "global" })
.reply(204, "", [
"Date",
"Thu, 25 Apr 2024 09:13:01 GMT",
"Connection",
"close",
"CF-Ray",
"879d36f6eb4351a1-IST",
"CF-Cache-Status",
"DYNAMIC",
"Access-Control-Allow-Origin",
"*",
"Set-Cookie",
"sb-access-token=; Path=/; Expires=Wed, 24 Apr 2024 23:13:01 GMT; Max-Age=0; HttpOnly; Secure",
"Strict-Transport-Security",
"max-age=15552000; includeSubDomains",
"Vary",
"Origin, Accept-Encoding",
"Via",
"kong/2.8.1",
"sb-gateway-version",
"1",
"Set-Cookie",
"sb-refresh-token=; Path=/; Expires=Wed, 24 Apr 2024 23:13:01 GMT; Max-Age=0; HttpOnly; Secure",
"x-kong-proxy-latency",
"0",
"x-kong-upstream-latency",
"6",
"Server",
"cloudflare",
"alt-svc",
'h3=":443"; ma=86400',
]);

View File

@@ -0,0 +1,65 @@
import { dataProvider } from "../../src/index";
import supabaseClient from "../supabaseClient";
import "./index.mock";
describe("updateMany", () => {
it("correct response with `select`", async () => {
const { data } = await dataProvider(supabaseClient).updateMany!({
resource: "posts",
ids: [5],
variables: {
title: "test",
categoryId: 12,
content: "test content",
},
meta: {
select: "*",
},
});
expect(data[0]).toEqual(
expect.objectContaining({
id: 5,
title: "test",
categoryId: 12,
content: "test content",
}),
);
});
it("should change schema", async () => {
const { data } = await dataProvider(supabaseClient).updateMany({
resource: "posts",
ids: [1, 2],
variables: {
title: "Samsung Galaxy S21",
},
meta: {
schema: "public",
select: "*",
},
});
expect(data[0]).toEqual(
expect.objectContaining({ id: 1, title: "Samsung Galaxy S21" }),
);
expect(data[1]).toEqual(
expect.objectContaining({ id: 2, title: "Samsung Galaxy S21" }),
);
const promise = dataProvider(supabaseClient).updateMany({
resource: "posts",
ids: [1, 2],
variables: {
title: "foo",
},
meta: {
schema: "private",
},
});
await expect(promise).rejects.toEqual(
expect.objectContaining({ code: "PGRST106" }),
);
});
});

View File

@@ -0,0 +1,16 @@
import type { CrudFilter } from "@refinedev/core";
import { generateFilter } from "../../src/utils";
describe("generateFilter", () => {
it("should throw error if operator is and", () => {
const filter = {
field: "id",
operator: "and",
value: "5",
} as unknown as CrudFilter;
expect(() => generateFilter(filter, jest.fn())).toThrowError(
"Operator 'and' is not supported",
);
});
});

View File

@@ -0,0 +1,26 @@
import { handleError } from "../../src/utils";
import type { PostgrestError } from "@supabase/supabase-js";
import type { HttpError } from "@refinedev/core";
describe("handleError", () => {
it("should transform PostgrestError into HttpError and reject the promise", async () => {
const postgrestError: PostgrestError = {
message: "Test error message",
code: "404",
details: "Not found",
hint: "Check your endpoint",
};
const expectedHttpError: HttpError = {
...postgrestError,
message: postgrestError.message,
statusCode: Number.parseInt(postgrestError.code),
};
try {
await handleError(postgrestError);
} catch (error) {
expect(error).toEqual(expectedHttpError);
}
});
});

View File

@@ -0,0 +1,56 @@
import { mapOperator } from "../../src/utils";
import type { CrudOperators } from "@refinedev/core";
describe("mapOperator", () => {
it("should correctly map CrudOperators to their corresponding string values", () => {
const testCases: Record<CrudOperators, string> = {
eq: "eq",
ne: "neq",
lt: "lt",
gt: "gt",
lte: "lte",
gte: "gte",
in: "in",
ina: "cs",
nin: "not.in",
nina: "not.cs",
contains: "ilike",
ncontains: "not.ilike",
containss: "like",
ncontainss: "not.like",
null: "is",
nnull: "not.is",
or: "or",
and: "and",
between: "",
nbetween: "",
startswith: "startswith",
nstartswith: "nstartswith",
endswith: "endswith",
nendswith: "nendswith",
startswiths: "startswiths",
nstartswiths: "nstartswiths",
endswiths: "endswiths",
nendswiths: "nendswiths",
};
for (const operator in testCases) {
if (operator === "between" || operator === "nbetween") {
expect(() => mapOperator(operator as CrudOperators)).toThrowError(
`Operator ${operator} is not supported`,
);
} else {
expect(mapOperator(operator as CrudOperators)).toBe(
testCases[operator as CrudOperators],
);
}
}
});
it.each(["unsupported", null, undefined])(
"should unsupported operator returns self",
(operator) => {
expect(mapOperator(operator as CrudOperators)).toBe(operator);
},
);
});