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)