diff --git a/i18n/README.ar.md b/i18n/README.ar.md
index 5d16a996cba..d65d540e37a 100644
--- a/i18n/README.ar.md
+++ b/i18n/README.ar.md
@@ -24,9 +24,10 @@
## المجتمع والدعم
-- [مندى المجتمع](https://github.com/supabase/supabase/discussions). الأفضل لـ: المساعدة في البناء، والنقاش حول أفضل ممارسات قاعدة البيانات.
+- [منتدى المجتمع](https://github.com/supabase/supabase/discussions). الأفضل لـ: المساعدة في البناء، والنقاش حول أفضل ممارسات قاعدة البيانات.
- [مشاكل GitHub](https://github.com/supabase/supabase/issues). الأفضل لـ: المشاكل والأخطاء التي تواجهها عند استخدامك لـ(Supabase).
- [دعم البريد الإلكتروني](https://supabase.com/docs/support#business-support). الأفضل لـ: مشاكل مع قاعدة بياناتك أو البنية التحتية.
+- [ديسكورد](https://discord.supabase.com/). الأفضل لـ: مشاركة التطبيقات الخاصه بك وقضاء بعض الوقت مع المجتمع.
## الحالة
diff --git a/studio/tests/pages/projects/LogPanel.test.js b/studio/tests/pages/projects/LogPanel.test.js
index b707a7303c0..581ec8605df 100644
--- a/studio/tests/pages/projects/LogPanel.test.js
+++ b/studio/tests/pages/projects/LogPanel.test.js
@@ -72,17 +72,28 @@ test('timestamp from filter default value', async () => {
render()
userEvent.click(await screen.findByText('Custom'))
await screen.findByDisplayValue('2022-01-18T10:43:39+0000')
-})
-test('timestamp from filter', async () => {
- const mockFn = jest.fn()
- render()
- const dropdown = await screen.findByText(/Now/)
-
- // click the dropdown
- userEvent.click(dropdown)
-
// TODO: use screen.findByLabelText when https://github.com/supabase/ui/issues/310 is resolved
await screen.findByText('From')
+ await screen.findByTitle('Reset')
+})
+
+test('timestamp from filter error handling', async () => {
+ const mockFn = jest.fn()
+ render()
+ userEvent.click(await screen.findByText(/Now/))
+
+ // display iso timestamp
+ const year = new Date().getFullYear()
+ const input = await screen.findByDisplayValue(RegExp(year))
+ userEvent.clear(input)
+ userEvent.type(input, '123456')
+ await screen.findByText(/[iI]nvalid ISO 8601 timestamp/)
+})
+
+test('timestamp from filter value change', async () => {
+ const mockFn = jest.fn()
+ render()
+ userEvent.click(await screen.findByText(/Now/))
// display iso timestamp
const year = new Date().getFullYear()
const input = await screen.findByDisplayValue(RegExp(year))
@@ -90,19 +101,12 @@ test('timestamp from filter', async () => {
// replace the input's value
userEvent.clear(input)
- // type some random input to check for error handling
- userEvent.type(input, '123456')
- await screen.findByText(/[iI]nvalid ISO 8601 timestamp/)
- userEvent.clear(input)
- await expect(screen.findByText(/[iI]nvalid ISO 8601 timestamp/)).rejects.toThrow()
-
// get time 20 mins before
const newDate = new Date()
newDate.setMinutes(new Date().getMinutes() - 20)
userEvent.type(input, newDate.toISOString())
// input actions
- await screen.findByTitle('Reset')
const set = await screen.findByRole('button', { name: 'Set' })
userEvent.click(set)
diff --git a/web/docs/guides/database.mdx b/web/docs/guides/database.mdx
index ba024cf68fa..65f0e041a0f 100644
--- a/web/docs/guides/database.mdx
+++ b/web/docs/guides/database.mdx
@@ -138,6 +138,73 @@ Migrating projects can be achieved using standard PostgreSQL tooling. This is pa
6. Run `TRUNCATE storage.objects` in the *new* project's SQL editor
7. Run `ALTER ROLE postgres NOSUPERUSER` in the *new* project's SQL editor
+#### Migrate storage objects
+
+This script moves storage objects from one project to another. If you have more than 10k objects, we can move the objects for you. Just contact us at [support@supabase.io](mailto:support@supabase.io).
+
+```js
+const { createClient } = require("@supabase/supabase-js");
+
+const OLD_PROJECT_URL = "https://xxx.supabase.co";
+const OLD_PROJECT_SERVICE_KEY = "old-project-service-key-xxx";
+
+const NEW_PROJECT_URL = "https://yyy.supabase.co";
+const NEW_PROJECT_SERVICE_KEY = "new-project-service-key-yyy";
+
+(async () => {
+ const oldSupabaseRestClient = createClient(
+ OLD_PROJECT_URL,
+ OLD_PROJECT_SERVICE_KEY,
+ { schema: "storage" }
+ );
+ const oldSupabaseClient = createClient(
+ OLD_PROJECT_URL,
+ OLD_PROJECT_SERVICE_KEY
+ );
+ const newSupabaseClient = createClient(
+ NEW_PROJECT_URL,
+ NEW_PROJECT_SERVICE_KEY
+ );
+
+ // make sure you update max_rows in postgrest settings if you have a lot of objects
+ // or paginate here
+ const { data: oldObjects, error } = await oldSupabaseRestClient
+ .from("objects")
+ .select();
+ if (error) {
+ console.log("error getting objects from old bucket");
+ throw error;
+ }
+
+ for (const objectData of oldObjects) {
+ console.log(`moving ${objectData.id}`);
+ try {
+ const { data, error: downloadObjectError } =
+ await oldSupabaseClient.storage
+ .from(objectData.bucket_id)
+ .download(objectData.name);
+ if (downloadObjectError) {
+ throw downloadObjectError;
+ }
+
+ const { _, error: uploadObjectError } = await newSupabaseClient.storage
+ .from(objectData.bucket_id)
+ .upload(objectData.name, data, {
+ upsert: true,
+ contentType: objectData.metadata.mimetype,
+ cacheControl: objectData.metadata.cacheControl,
+ });
+ if (uploadObjectError) {
+ throw uploadObjectError;
+ }
+ } catch (err) {
+ console.log("error moving ", objectData);
+ console.log(err);
+ }
+ }
+})();
+```
+
#### Caveats
- The new project will have the old project's Storage buckets, but not the objects. You will need to migrate Storage objects manually.
diff --git a/web/docs/guides/with-expo.mdx b/web/docs/guides/with-expo.mdx
index 62bab155081..c0eeb3e2dce 100644
--- a/web/docs/guides/with-expo.mdx
+++ b/web/docs/guides/with-expo.mdx
@@ -154,10 +154,12 @@ expo init supabaseReactNative
cd supabaseReactNative
```
-Then let's install the only additional dependency: [supabase-js](https://github.com/supabase/supabase-js)
+Then let's install the additional dependencies: [supabase-js](https://github.com/supabase/supabase-js)
```bash
yarn add @supabase/supabase-js
+yarn add react-native-elements
+yarn add react-native-safe-area-context
```
Now let's create a helper file to initialize the Supabase client.
@@ -182,7 +184,7 @@ We'll use Magic Links, so users can sign in with their email without using passw
```jsx title="components/Auth.js"
import React, {useState} from 'react'
import {Alert, StyleSheet, View} from 'react-native'
-import {supabaseClient} from '../lib/initSupabase'
+import {supabase} from '../lib/supabase'
import {Button, Input} from 'react-native-elements'
export default function Auth() {
@@ -267,7 +269,7 @@ Let's create a new component for that called `Account.js`.
```jsx title="components/Account.js"
import { useState, useEffect } from 'react'
-import { supabase } from '../utils/supabaseClient'
+import { supabase } from '../utils/supabase'
import {StyleSheet, View} from 'react-native'
import {Button, Input} from 'react-native-elements'
@@ -386,10 +388,10 @@ Now that we have all the components in place, let's update `app.js`:
```jsx title="app.js"
import { useState, useEffect } from 'react'
-import { supabase } from './lib/supabaseClient'
+import { supabase } from './lib/supabase'
import Auth from './components/Auth'
import Account from './components/Account'
-import View from 'react-native'
+import { View } from 'react-native'
export default function App() {
const [session, setSession] = useState(null)