├── .eslintignore ├── .eslintrc ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── config.yml ├── dependabot.yaml └── workflows │ ├── main.yaml │ └── size.yaml ├── .gitignore ├── .husky ├── .gitignore └── pre-commit ├── .lintstagedrc ├── .npmignore ├── .prettierignore ├── .prettierrc ├── .size-limit.json ├── .vim └── coc-settings.json ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── docs ├── .gitignore ├── README.md ├── bin │ └── stork.bin ├── next-env.d.ts ├── next.config.js ├── package.json ├── pages │ ├── _app.tsx │ ├── _document.tsx │ ├── documentation │ │ ├── auth │ │ │ ├── meta.json │ │ │ ├── use-auth-state-change.md │ │ │ ├── use-reset-password.md │ │ │ ├── use-signin.md │ │ │ ├── use-signout.md │ │ │ └── use-signup.md │ │ ├── data │ │ │ ├── meta.json │ │ │ ├── use-delete.md │ │ │ ├── use-filter.md │ │ │ ├── use-insert.md │ │ │ ├── use-select.md │ │ │ ├── use-update.md │ │ │ └── use-upsert.md │ │ ├── meta.json │ │ ├── provider.md │ │ ├── realtime │ │ │ ├── meta.json │ │ │ ├── use-realtime.md │ │ │ └── use-subscription.md │ │ ├── storage │ │ │ └── meta.json │ │ └── use-client.md │ ├── getting-started.md │ ├── index.md │ ├── meta.json │ └── recipes │ │ ├── meta.json │ │ └── use-auth.md ├── public │ └── stork.wasm ├── theme.config.js ├── tsconfig.json └── yarn.lock ├── jest.config.ts ├── package.json ├── src ├── context.ts ├── hooks │ ├── auth │ │ ├── index.ts │ │ ├── state.ts │ │ ├── use-auth-state-change.ts │ │ ├── use-reset-password.ts │ │ ├── use-signin.ts │ │ ├── use-signout.ts │ │ └── use-signup.ts │ ├── data │ │ ├── index.ts │ │ ├── state.ts │ │ ├── use-delete.ts │ │ ├── use-filter.ts │ │ ├── use-insert.ts │ │ ├── use-select.ts │ │ ├── use-update.ts │ │ └── use-upsert.ts │ ├── index.ts │ ├── realtime │ │ ├── index.ts │ │ ├── use-realtime.ts │ │ └── use-subscription.ts │ └── use-client.ts ├── index.ts └── types.ts ├── test ├── hooks │ ├── __snapshots__ │ │ └── use-client.test.tsx.snap │ ├── auth │ │ ├── __snapshots__ │ │ │ ├── use-auth-state-change.test.tsx.snap │ │ │ ├── use-reset-password.test.tsx.snap │ │ │ ├── use-signin.test.tsx.snap │ │ │ ├── use-signout.test.tsx.snap │ │ │ └── use-signup.test.tsx.snap │ │ ├── use-auth-state-change.test.tsx │ │ ├── use-reset-password.test.tsx │ │ ├── use-signin.test.tsx │ │ ├── use-signout.test.tsx │ │ └── use-signup.test.tsx │ ├── data │ │ ├── __snapshots__ │ │ │ ├── use-delete.test.tsx.snap │ │ │ ├── use-insert.test.tsx.snap │ │ │ ├── use-select.test.tsx.snap │ │ │ ├── use-update.test.tsx.snap │ │ │ └── use-upsert.test.tsx.snap │ │ ├── use-delete.test.tsx │ │ ├── use-filter.test.tsx │ │ ├── use-insert.test.tsx │ │ ├── use-select.test.tsx │ │ ├── use-update.test.tsx │ │ └── use-upsert.test.tsx │ ├── realtime │ │ ├── __snapshots__ │ │ │ ├── use-realtime.test.tsx.snap │ │ │ └── use-subscription.test.tsx.snap │ │ ├── use-realtime.test.tsx │ │ └── use-subscription.test.tsx │ └── use-client.test.tsx └── utils.tsx ├── tsconfig.json ├── vite.config.ts └── yarn.lock /.eslintignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | docs/ 3 | node_modules/ 4 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "root": true, 3 | "parser": "@typescript-eslint/parser", 4 | "parserOptions": { 5 | "ecmaVersion": 8, 6 | "sourceType": "module", 7 | "ecmaFeatures": { 8 | "impliedStrict": true, 9 | "experimentalObjectRestSpread": true 10 | }, 11 | "allowImportExportEverywhere": true 12 | }, 13 | "plugins": ["@typescript-eslint", "import", "react", "testing-library"], 14 | "extends": [ 15 | "eslint:recommended", 16 | "plugin:@typescript-eslint/recommended", 17 | "plugin:import/errors", 18 | "plugin:import/warnings", 19 | "plugin:import/typescript", 20 | "plugin:jest-dom/recommended", 21 | "plugin:testing-library/react", 22 | "plugin:react/recommended", 23 | "plugin:react-hooks/recommended", 24 | "plugin:prettier/recommended", 25 | "prettier" 26 | ], 27 | "rules": { 28 | // `@typescript-eslint` 29 | // https://github.com/typescript-eslint/typescript-eslint 30 | "@typescript-eslint/explicit-module-boundary-types": "off", 31 | "@typescript-eslint/no-explicit-any": "off", 32 | "@typescript-eslint/no-unused-vars": [ 33 | 2, 34 | { 35 | "argsIgnorePattern": "^_" 36 | } 37 | ], 38 | "@typescript-eslint/no-var-requires": "off", 39 | // `eslint-plugin-import` 40 | // https://github.com/benmosher/eslint-plugin-import 41 | "import/order": [ 42 | "error", 43 | { 44 | "groups": ["external", "internal"], 45 | "newlines-between": "always-and-inside-groups" 46 | } 47 | ], 48 | "sort-imports": [ 49 | "warn", 50 | { 51 | "ignoreCase": false, 52 | "ignoreDeclarationSort": true, 53 | "ignoreMemberSort": false 54 | } 55 | ], 56 | // `eslint-plugin-react` 57 | // https://github.com/yannickcr/eslint-plugin-react 58 | "react/display-name": "off", 59 | "react/jsx-boolean-value": ["warn", "never"], 60 | "react/jsx-sort-props": [ 61 | "error", 62 | { 63 | "callbacksLast": true 64 | } 65 | ], 66 | "react/jsx-wrap-multilines": "error", 67 | "react/no-array-index-key": "error", 68 | "react/no-multi-comp": "off", 69 | "react/prop-types": "off", 70 | "react/self-closing-comp": "warn" 71 | }, 72 | "settings": { 73 | "import/parsers": { 74 | "@typescript-eslint/parser": [".ts", ".tsx"] 75 | }, 76 | "import/resolver": { 77 | "typescript": { 78 | "alwaysTryTypes": true 79 | } 80 | }, 81 | "react": { 82 | "version": "detect" 83 | } 84 | }, 85 | "env": { 86 | "es6": true, 87 | "browser": true, 88 | "node": true, 89 | "jest": true 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Create a bug report for the `react-supabase` library 4 | --- 5 | 6 | # Bug report 7 | 8 | ## Description / Observed Behavior 9 | 10 | What kind of issues did you encounter? 11 | 12 | ## Expected Behavior 13 | 14 | How did you expect it to behave? 15 | 16 | ## Repro Steps / Code Example 17 | 18 | Or share your code snippet or a [CodeSandbox](https://codesandbox.io) link is also appreciated! 19 | 20 | ## Additional Context 21 | 22 | `react-supabase` version. 23 | Add any other context about the problem here. 24 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Ask Question 4 | url: https://github.com/tmm/react-supabase/discussions 5 | about: Ask questions and discuss with other community members 6 | -------------------------------------------------------------------------------- /.github/dependabot.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: 'npm' 4 | directory: '/' 5 | schedule: 6 | interval: 'monthly' 7 | open-pull-requests-limit: 0 8 | 9 | - package-ecosystem: 'github-actions' 10 | directory: '/' 11 | schedule: 12 | interval: 'monthly' 13 | -------------------------------------------------------------------------------- /.github/workflows/main.yaml: -------------------------------------------------------------------------------- 1 | name: Main 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: [main] 7 | 8 | jobs: 9 | lint: 10 | name: Lint 11 | runs-on: ubuntu-latest 12 | strategy: 13 | matrix: 14 | node-version: [14] 15 | steps: 16 | - name: Check out 17 | uses: actions/checkout@v2 18 | 19 | - name: Set up Node ${{ matrix.node-version }} 20 | uses: actions/setup-node@v2 21 | with: 22 | node-version: ${{ matrix.node-version }} 23 | 24 | - name: Load yarn cache 25 | uses: actions/cache@v2.1.7 26 | id: yarn-cache 27 | with: 28 | path: ./node_modules 29 | key: ${{ runner.os }}-yarn-cache-${{ hashFiles('**/yarn.lock') }} 30 | restore-keys: ${{ runner.os }}-yarn-cache- 31 | 32 | - name: Install dependencies 33 | if: steps.yarn-cache.outputs.cache-hit != 'true' 34 | run: yarn --frozen-lockfile 35 | 36 | - name: Lint code 37 | run: yarn lint 38 | 39 | - name: Check types 40 | run: yarn lint:types 41 | 42 | - name: Format other files 43 | run: yarn lint:format --check 44 | 45 | test: 46 | name: Test 47 | runs-on: ubuntu-latest 48 | strategy: 49 | matrix: 50 | node-version: [14] 51 | steps: 52 | - name: Check out 53 | uses: actions/checkout@v2 54 | 55 | - name: Set up Node ${{ matrix.node-version }} 56 | uses: actions/setup-node@v2 57 | with: 58 | node-version: ${{ matrix.node-version }} 59 | 60 | - name: Load yarn cache 61 | uses: actions/cache@v2.1.7 62 | id: yarn-cache 63 | with: 64 | path: ./node_modules 65 | key: ${{ runner.os }}-yarn-cache-${{ hashFiles('**/yarn.lock') }} 66 | restore-keys: ${{ runner.os }}-yarn-cache- 67 | 68 | - name: Install dependencies 69 | if: steps.yarn-cache.outputs.cache-hit != 'true' 70 | run: yarn --frozen-lockfile 71 | 72 | - name: Run tests 73 | run: yarn test 74 | -------------------------------------------------------------------------------- /.github/workflows/size.yaml: -------------------------------------------------------------------------------- 1 | name: Size 2 | 3 | on: 4 | pull_request: 5 | 6 | jobs: 7 | size: 8 | name: Size 9 | runs-on: ubuntu-latest 10 | strategy: 11 | matrix: 12 | node-version: [14] 13 | steps: 14 | - name: Check out 15 | uses: actions/checkout@v2 16 | 17 | - name: Set up Node ${{ matrix.node-version }} 18 | uses: actions/setup-node@v2 19 | with: 20 | node-version: ${{ matrix.node-version }} 21 | 22 | - name: Load yarn cache 23 | uses: actions/cache@v2.1.7 24 | id: yarn-cache 25 | with: 26 | path: ./node_modules 27 | key: ${{ runner.os }}-yarn-cache-${{ hashFiles('**/yarn.lock') }} 28 | restore-keys: ${{ runner.os }}-yarn-cache- 29 | 30 | - name: Install dependencies 31 | if: steps.yarn-cache.outputs.cache-hit != 'true' 32 | run: yarn --frozen-lockfile 33 | 34 | - uses: andresz1/size-limit-action@v1.5.1 35 | with: 36 | github_token: ${{ secrets.GITHUB_TOKEN }} 37 | skip_step: install 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .eslintcache 3 | dist/ 4 | node_modules/ 5 | yarn-debug.log* 6 | yarn-error.log* 7 | -------------------------------------------------------------------------------- /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn lint-staged 5 | -------------------------------------------------------------------------------- /.lintstagedrc: -------------------------------------------------------------------------------- 1 | { 2 | "*.{js,ts,tsx}": ["yarn lint:fix"], 3 | "*.{json,md,yaml}": ["yarn lint:format"], 4 | } 5 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | *.log 2 | *.tgz 3 | .env 4 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ 3 | yarn.lock 4 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "arrowParens": "always", 3 | "endOfLine": "lf", 4 | "printWidth": 80, 5 | "semi": false, 6 | "singleQuote": true, 7 | "tabWidth": 4, 8 | "trailingComma": "all", 9 | "overrides": [ 10 | { 11 | "files": "*.md", 12 | "options": { 13 | "tabWidth": 2 14 | } 15 | }, 16 | { 17 | "files": "*.yaml", 18 | "options": { 19 | "tabWidth": 2 20 | } 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /.size-limit.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "path": "dist/index.cjs.js", 4 | "limit": "5 KB" 5 | }, 6 | { 7 | "path": "dist/index.es.js", 8 | "limit": "5 KB" 9 | } 10 | ] 11 | -------------------------------------------------------------------------------- /.vim/coc-settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "eslint.autoFixOnSave": true, 3 | "eslint.probe": [ 4 | "css", 5 | "javascript", 6 | "javascriptreact", 7 | "json", 8 | "markdown", 9 | "typescript", 10 | "typescriptreact" 11 | ], 12 | "eslint.packageManager": "yarn" 13 | } 14 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution Guidelines 2 | 3 | Thank you for reading this guide and we appreciate any contribution. 4 | 5 | ## Ask a Question 6 | 7 | You can use the repository's [Discussions](https://github.com/tmm/react-supabase/discussions) page to ask any questions, post feedback or share your experience on how you use this library. 8 | 9 | ## Report a Bug 10 | 11 | Whenever you find something which is not working properly, please first search the repository's [Issues](https://github.com/tmm/react-supabase/issues) page and make sure it's not reported by someone else already. 12 | 13 | If not, feel free to open an issue with the detailed description of the problem and the expected behavior. And reproduction (for example a [CodeSandbox](https://codesandbox.io) link) will be extremely helpful. 14 | 15 | ## Request for a New Feature 16 | 17 | For new features, it would be great to have some discussions from the community before starting working on it. You can either create an issue (if there isn't one) or post a thread in the [Discussions](https://github.com/tmm/react-supabase/discussions) page to describe the feature that you want to have. 18 | 19 | If possible, you can add other additional context like how this feature can be implemented technically, what other alternative solutions we can have, etc. 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Tom Meagher 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Introduction 2 | 3 | `react-supabase` is a React Hooks library for [Supabase](https://supabase.io). 4 | 5 | Visit the [docs site](https://react-supabase.vercel.app) for more info. 6 | 7 |
8 | 9 | ## Installation 10 | 11 | ``` 12 | yarn add react-supabase @supabase/supabase-js 13 | # or 14 | npm install --save react-supabase @supabase/supabase-js 15 | ``` 16 | 17 |
18 | 19 | ## Quick Start 20 | 21 | Create a Supabase client and pass it to the `Provider`: 22 | 23 | ```tsx 24 | import { createClient } from '@supabase/supabase-js' 25 | import { Provider } from 'react-supabase' 26 | 27 | const client = createClient('https://xyzcompany.supabase.co', 'public-anon-key') 28 | 29 | const App = () => ( 30 | 31 | 32 | 33 | ) 34 | ``` 35 | 36 | Now every component inside and under the `Provider` can use the Supabase client and hooks: 37 | 38 | ```tsx 39 | import { useRealtime } from 'react-supabase' 40 | 41 | const Todos = () => { 42 | const [result, reexecute] = useRealtime('todos') 43 | 44 | const { data, fetching, error } = result 45 | 46 | if (fetching) return

Loading...

47 | if (error) return

Oh no... {error.message}

48 | 49 | return ( 50 | 55 | ) 56 | } 57 | ``` 58 | 59 |
60 | 61 | ## License 62 | 63 | The MIT License. 64 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | .next/* 2 | public/*.st 3 | public/*.toml 4 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | ``` 2 | yarn 3 | yarn dev 4 | ``` 5 | -------------------------------------------------------------------------------- /docs/bin/stork.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/awesomedev08/react-supabase/fcc4eac38a6426e03863bd159d00c8cf0b5cb31d/docs/bin/stork.bin -------------------------------------------------------------------------------- /docs/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /docs/next.config.js: -------------------------------------------------------------------------------- 1 | const withNextra = require('nextra')({ 2 | theme: 'nextra-theme-docs', 3 | themeConfig: './theme.config.js', 4 | stork: true, 5 | }) 6 | module.exports = withNextra() 7 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docs", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "private": true, 7 | "scripts": { 8 | "dev": "next dev", 9 | "build": "STORK_PATH=$(pwd)/bin/stork.bin next build", 10 | "start": "next start" 11 | }, 12 | "dependencies": { 13 | "next": "^10.2.0", 14 | "nextra": "^0.4.4", 15 | "nextra-theme-docs": "^1.1.6", 16 | "react": "^17.0.2", 17 | "react-dom": "^17.0.2" 18 | }, 19 | "devDependencies": { 20 | "@types/react": "^17.0.4", 21 | "@types/react-dom": "^17.0.3", 22 | "typescript": "^4.2.4" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /docs/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import 'nextra-theme-docs/style.css' 2 | 3 | export default function Nextra({ Component, pageProps }) { 4 | return 5 | } 6 | -------------------------------------------------------------------------------- /docs/pages/_document.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | Head, 3 | Html, 4 | Main, 5 | default as NextDocument, 6 | NextScript, 7 | } from 'next/document' 8 | 9 | class Document extends NextDocument { 10 | render() { 11 | return ( 12 | 13 | 14 | 15 |
16 | 17 | 18 |