├── .github └── workflows │ ├── docs.yml │ ├── release.yml │ └── tests.yml ├── .gitignore ├── .npmignore ├── .prettierignore ├── .prettierrc ├── .releaserc.json ├── LICENSE ├── README.md ├── docs └── v1 │ ├── .nojekyll │ ├── assets │ ├── highlight.css │ ├── icons.css │ ├── icons.png │ ├── icons@2x.png │ ├── main.js │ ├── search.js │ ├── style.css │ ├── widgets.png │ └── widgets@2x.png │ ├── classes │ └── FunctionsClient.html │ ├── index.html │ ├── modules.html │ └── spec.json ├── jest.config.ts ├── jsr.json ├── package-lock.json ├── package.json ├── src ├── FunctionsClient.ts ├── edge-runtime.d.ts ├── helper.ts ├── index.ts ├── types.ts └── version.ts ├── test ├── functions │ ├── hello │ │ └── index.ts │ ├── hijack │ │ └── index.ts │ └── mirror │ │ └── index.ts ├── models │ └── mirrorResponse.ts ├── relay │ └── container.ts ├── spec │ ├── hello.spec.ts │ ├── hijack.spec.ts │ └── params.spec.ts └── utils │ ├── binaries.ts │ ├── fetch.ts │ ├── jest-custom-reporter.ts │ └── timeoutPromise.ts ├── tsconfig.json └── tsconfig.module.json /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | name: Docs 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | paths: 8 | - 'src/**' 9 | workflow_dispatch: 10 | 11 | jobs: 12 | docs: 13 | name: Publish docs / OS ${{ matrix.os }} / Node ${{ matrix.node }} 14 | strategy: 15 | matrix: 16 | os: [ubuntu-latest] 17 | node: ['20'] 18 | 19 | runs-on: ${{ matrix.os }} 20 | 21 | steps: 22 | - uses: actions/checkout@v4 23 | 24 | - name: Set up Node 25 | uses: actions/setup-node@v4 26 | with: 27 | node-version: ${{ matrix.node }} 28 | 29 | - run: | 30 | npm ci 31 | npm run docs 32 | npm run docs:json 33 | 34 | - name: Publish 35 | uses: peaceiris/actions-gh-pages@v3 36 | with: 37 | github_token: ${{ secrets.GITHUB_TOKEN }} 38 | publish_dir: docs 39 | force_orphan: true 40 | commit_message: 'docs: update' 41 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | - next 8 | - rc 9 | workflow_dispatch: 10 | 11 | jobs: 12 | release: 13 | name: Release / Node ${{ matrix.node }} 14 | strategy: 15 | matrix: 16 | node: ['20'] 17 | 18 | runs-on: ubuntu-latest 19 | 20 | permissions: 21 | contents: write 22 | issues: write 23 | id-token: write 24 | 25 | steps: 26 | - uses: actions/checkout@v4 27 | 28 | - name: Set up Node 29 | uses: actions/setup-node@v4 30 | with: 31 | node-version: ${{ matrix.node }} 32 | 33 | - run: | 34 | npm ci 35 | npm run build 36 | 37 | - uses: cycjimmy/semantic-release-action@v4 38 | with: 39 | semantic_version: 19 40 | env: 41 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 42 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 43 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: 4 | pull_request: 5 | push: 6 | branches: 7 | - main 8 | - rc 9 | workflow_dispatch: 10 | 11 | jobs: 12 | autotests: 13 | name: Run tests 14 | strategy: 15 | matrix: 16 | node: ['20'] 17 | 18 | runs-on: ubuntu-latest 19 | 20 | steps: 21 | - uses: actions/checkout@v4 22 | 23 | - name: Set up Node 24 | uses: actions/setup-node@v4 25 | with: 26 | node-version: ${{ matrix.node }} 27 | 28 | - name: Install dependencies 29 | run: npm ci 30 | 31 | - name: Run Test 32 | run: npm run test:coverage 33 | 34 | - name: Upload coverage results to Coveralls 35 | uses: coverallsapp/github-action@master 36 | with: 37 | github-token: ${{ secrets.GITHUB_TOKEN }} 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .DS_Store 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | *.lcov 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # TypeScript v1 declaration files 46 | typings/ 47 | 48 | # TypeScript cache 49 | *.tsbuildinfo 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Microbundle cache 58 | .rpt2_cache/ 59 | .rts2_cache_cjs/ 60 | .rts2_cache_es/ 61 | .rts2_cache_umd/ 62 | 63 | # Optional REPL history 64 | .node_repl_history 65 | 66 | # Output of 'npm pack' 67 | *.tgz 68 | 69 | # Yarn Integrity file 70 | .yarn-integrity 71 | 72 | # dotenv environment variables file 73 | .env 74 | .env.test 75 | 76 | # parcel-bundler cache (https://parceljs.org/) 77 | .cache 78 | 79 | # Next.js build output 80 | .next 81 | 82 | # Nuxt.js build / generate output 83 | .nuxt 84 | dist 85 | 86 | # Gatsby files 87 | .cache/ 88 | # Comment in the public line in if your project uses Gatsby and *not* Next.js 89 | # https://nextjs.org/blog/next-9-1#public-directory-support 90 | # public 91 | 92 | # vuepress build output 93 | .vuepress/dist 94 | 95 | # Serverless directories 96 | .serverless/ 97 | 98 | # FuseBox cache 99 | .fusebox/ 100 | 101 | # DynamoDB Local files 102 | .dynamodb/ 103 | 104 | # TernJS port file 105 | .tern-port 106 | 107 | # Generated docs 108 | docs/v2 109 | 110 | # Test reports 111 | allure-results 112 | allure-report 113 | 114 | # IDE specific 115 | .vscode 116 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | *.log 2 | npm-debug.log* 3 | 4 | # Coverage directory used by tools like istanbul 5 | coverage 6 | .nyc_output 7 | 8 | # Dependency directories 9 | node_modules 10 | 11 | # npm package lock 12 | package-lock.json 13 | yarn.lock 14 | 15 | # project files 16 | src 17 | test 18 | examples 19 | example 20 | example-next-js 21 | umd_temp 22 | CHANGELOG.md 23 | .travis.yml 24 | .editorconfig 25 | .eslintignore 26 | .eslintrc 27 | .babelrc 28 | .gitignore 29 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .expo 2 | .next 3 | node_modules 4 | package-lock.json 5 | docker* -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "tabWidth": 2, 4 | "semi": false, 5 | "singleQuote": true, 6 | "printWidth": 100 7 | } 8 | -------------------------------------------------------------------------------- /.releaserc.json: -------------------------------------------------------------------------------- 1 | { 2 | "branches": [ 3 | { "name": "main" }, 4 | { "name": "next", "channel": "next", "prerelease": true }, 5 | { "name": "rc", "channel": "rc", "prerelease": true } 6 | ], 7 | "plugins": [ 8 | [ 9 | "semantic-release-plugin-update-version-in-files", 10 | { 11 | "files": [ 12 | "src/version.ts", 13 | "dist/main/version.js", 14 | "dist/main/version.d.ts", 15 | "dist/module/version.js", 16 | "dist/module/version.d.ts" 17 | ], 18 | "placeholder": "0.0.0-automated" 19 | } 20 | ], 21 | "@semantic-release/commit-analyzer", 22 | "@semantic-release/release-notes-generator", 23 | "@semantic-release/github", 24 | "@semantic-release/npm", 25 | "@sebbo2002/semantic-release-jsr" 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Supabase 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 | # `functions-js` 2 | 3 | [![Coverage Status](https://coveralls.io/repos/github/supabase/functions-js/badge.svg?branch=main)](https://coveralls.io/github/supabase/functions-js?branch=main) 4 | 5 | JS Client library to interact with Supabase Functions. 6 | 7 | ## Docs 8 | 9 | 10 | 11 | ## testing 12 | 13 | To run tests you will need Node 20+. 14 | 15 | You are going to need docker daemon running to execute tests. 16 | 17 | To start test run use the following command: 18 | 19 | ```sh 20 | npm i 21 | npm run test 22 | ``` 23 | -------------------------------------------------------------------------------- /docs/v1/.nojekyll: -------------------------------------------------------------------------------- 1 | TypeDoc added this file to prevent GitHub Pages from using Jekyll. You can turn off this behavior by setting the `githubPages` option to false. -------------------------------------------------------------------------------- /docs/v1/assets/highlight.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --light-code-background: #F5F5F5; 3 | --dark-code-background: #1E1E1E; 4 | } 5 | 6 | @media (prefers-color-scheme: light) { :root { 7 | --code-background: var(--light-code-background); 8 | } } 9 | 10 | @media (prefers-color-scheme: dark) { :root { 11 | --code-background: var(--dark-code-background); 12 | } } 13 | 14 | body.light { 15 | --code-background: var(--light-code-background); 16 | } 17 | 18 | body.dark { 19 | --code-background: var(--dark-code-background); 20 | } 21 | 22 | pre, code { background: var(--code-background); } 23 | -------------------------------------------------------------------------------- /docs/v1/assets/icons.css: -------------------------------------------------------------------------------- 1 | .tsd-kind-icon { 2 | display: block; 3 | position: relative; 4 | padding-left: 20px; 5 | text-indent: -20px; 6 | } 7 | .tsd-kind-icon:before { 8 | content: ""; 9 | display: inline-block; 10 | vertical-align: middle; 11 | width: 17px; 12 | height: 17px; 13 | margin: 0 3px 2px 0; 14 | background-image: url(./icons.png); 15 | } 16 | @media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { 17 | .tsd-kind-icon:before { 18 | background-image: url(./icons@2x.png); 19 | background-size: 238px 204px; 20 | } 21 | } 22 | 23 | .tsd-signature.tsd-kind-icon:before { 24 | background-position: 0 -153px; 25 | } 26 | 27 | .tsd-kind-object-literal > .tsd-kind-icon:before { 28 | background-position: 0px -17px; 29 | } 30 | .tsd-kind-object-literal.tsd-is-protected > .tsd-kind-icon:before { 31 | background-position: -17px -17px; 32 | } 33 | .tsd-kind-object-literal.tsd-is-private > .tsd-kind-icon:before { 34 | background-position: -34px -17px; 35 | } 36 | 37 | .tsd-kind-class > .tsd-kind-icon:before { 38 | background-position: 0px -34px; 39 | } 40 | .tsd-kind-class.tsd-is-protected > .tsd-kind-icon:before { 41 | background-position: -17px -34px; 42 | } 43 | .tsd-kind-class.tsd-is-private > .tsd-kind-icon:before { 44 | background-position: -34px -34px; 45 | } 46 | 47 | .tsd-kind-class.tsd-has-type-parameter > .tsd-kind-icon:before { 48 | background-position: 0px -51px; 49 | } 50 | .tsd-kind-class.tsd-has-type-parameter.tsd-is-protected 51 | > .tsd-kind-icon:before { 52 | background-position: -17px -51px; 53 | } 54 | .tsd-kind-class.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { 55 | background-position: -34px -51px; 56 | } 57 | 58 | .tsd-kind-interface > .tsd-kind-icon:before { 59 | background-position: 0px -68px; 60 | } 61 | .tsd-kind-interface.tsd-is-protected > .tsd-kind-icon:before { 62 | background-position: -17px -68px; 63 | } 64 | .tsd-kind-interface.tsd-is-private > .tsd-kind-icon:before { 65 | background-position: -34px -68px; 66 | } 67 | 68 | .tsd-kind-interface.tsd-has-type-parameter > .tsd-kind-icon:before { 69 | background-position: 0px -85px; 70 | } 71 | .tsd-kind-interface.tsd-has-type-parameter.tsd-is-protected 72 | > .tsd-kind-icon:before { 73 | background-position: -17px -85px; 74 | } 75 | .tsd-kind-interface.tsd-has-type-parameter.tsd-is-private 76 | > .tsd-kind-icon:before { 77 | background-position: -34px -85px; 78 | } 79 | 80 | .tsd-kind-namespace > .tsd-kind-icon:before { 81 | background-position: 0px -102px; 82 | } 83 | .tsd-kind-namespace.tsd-is-protected > .tsd-kind-icon:before { 84 | background-position: -17px -102px; 85 | } 86 | .tsd-kind-namespace.tsd-is-private > .tsd-kind-icon:before { 87 | background-position: -34px -102px; 88 | } 89 | 90 | .tsd-kind-module > .tsd-kind-icon:before { 91 | background-position: 0px -102px; 92 | } 93 | .tsd-kind-module.tsd-is-protected > .tsd-kind-icon:before { 94 | background-position: -17px -102px; 95 | } 96 | .tsd-kind-module.tsd-is-private > .tsd-kind-icon:before { 97 | background-position: -34px -102px; 98 | } 99 | 100 | .tsd-kind-enum > .tsd-kind-icon:before { 101 | background-position: 0px -119px; 102 | } 103 | .tsd-kind-enum.tsd-is-protected > .tsd-kind-icon:before { 104 | background-position: -17px -119px; 105 | } 106 | .tsd-kind-enum.tsd-is-private > .tsd-kind-icon:before { 107 | background-position: -34px -119px; 108 | } 109 | 110 | .tsd-kind-enum-member > .tsd-kind-icon:before { 111 | background-position: 0px -136px; 112 | } 113 | .tsd-kind-enum-member.tsd-is-protected > .tsd-kind-icon:before { 114 | background-position: -17px -136px; 115 | } 116 | .tsd-kind-enum-member.tsd-is-private > .tsd-kind-icon:before { 117 | background-position: -34px -136px; 118 | } 119 | 120 | .tsd-kind-signature > .tsd-kind-icon:before { 121 | background-position: 0px -153px; 122 | } 123 | .tsd-kind-signature.tsd-is-protected > .tsd-kind-icon:before { 124 | background-position: -17px -153px; 125 | } 126 | .tsd-kind-signature.tsd-is-private > .tsd-kind-icon:before { 127 | background-position: -34px -153px; 128 | } 129 | 130 | .tsd-kind-type-alias > .tsd-kind-icon:before { 131 | background-position: 0px -170px; 132 | } 133 | .tsd-kind-type-alias.tsd-is-protected > .tsd-kind-icon:before { 134 | background-position: -17px -170px; 135 | } 136 | .tsd-kind-type-alias.tsd-is-private > .tsd-kind-icon:before { 137 | background-position: -34px -170px; 138 | } 139 | 140 | .tsd-kind-type-alias.tsd-has-type-parameter > .tsd-kind-icon:before { 141 | background-position: 0px -187px; 142 | } 143 | .tsd-kind-type-alias.tsd-has-type-parameter.tsd-is-protected 144 | > .tsd-kind-icon:before { 145 | background-position: -17px -187px; 146 | } 147 | .tsd-kind-type-alias.tsd-has-type-parameter.tsd-is-private 148 | > .tsd-kind-icon:before { 149 | background-position: -34px -187px; 150 | } 151 | 152 | .tsd-kind-variable > .tsd-kind-icon:before { 153 | background-position: -136px -0px; 154 | } 155 | .tsd-kind-variable.tsd-is-protected > .tsd-kind-icon:before { 156 | background-position: -153px -0px; 157 | } 158 | .tsd-kind-variable.tsd-is-private > .tsd-kind-icon:before { 159 | background-position: -119px -0px; 160 | } 161 | .tsd-kind-variable.tsd-parent-kind-class > .tsd-kind-icon:before { 162 | background-position: -51px -0px; 163 | } 164 | .tsd-kind-variable.tsd-parent-kind-class.tsd-is-inherited 165 | > .tsd-kind-icon:before { 166 | background-position: -68px -0px; 167 | } 168 | .tsd-kind-variable.tsd-parent-kind-class.tsd-is-protected 169 | > .tsd-kind-icon:before { 170 | background-position: -85px -0px; 171 | } 172 | .tsd-kind-variable.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited 173 | > .tsd-kind-icon:before { 174 | background-position: -102px -0px; 175 | } 176 | .tsd-kind-variable.tsd-parent-kind-class.tsd-is-private 177 | > .tsd-kind-icon:before { 178 | background-position: -119px -0px; 179 | } 180 | .tsd-kind-variable.tsd-parent-kind-enum > .tsd-kind-icon:before { 181 | background-position: -170px -0px; 182 | } 183 | .tsd-kind-variable.tsd-parent-kind-enum.tsd-is-protected 184 | > .tsd-kind-icon:before { 185 | background-position: -187px -0px; 186 | } 187 | .tsd-kind-variable.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { 188 | background-position: -119px -0px; 189 | } 190 | .tsd-kind-variable.tsd-parent-kind-interface > .tsd-kind-icon:before { 191 | background-position: -204px -0px; 192 | } 193 | .tsd-kind-variable.tsd-parent-kind-interface.tsd-is-inherited 194 | > .tsd-kind-icon:before { 195 | background-position: -221px -0px; 196 | } 197 | 198 | .tsd-kind-property > .tsd-kind-icon:before { 199 | background-position: -136px -0px; 200 | } 201 | .tsd-kind-property.tsd-is-protected > .tsd-kind-icon:before { 202 | background-position: -153px -0px; 203 | } 204 | .tsd-kind-property.tsd-is-private > .tsd-kind-icon:before { 205 | background-position: -119px -0px; 206 | } 207 | .tsd-kind-property.tsd-parent-kind-class > .tsd-kind-icon:before { 208 | background-position: -51px -0px; 209 | } 210 | .tsd-kind-property.tsd-parent-kind-class.tsd-is-inherited 211 | > .tsd-kind-icon:before { 212 | background-position: -68px -0px; 213 | } 214 | .tsd-kind-property.tsd-parent-kind-class.tsd-is-protected 215 | > .tsd-kind-icon:before { 216 | background-position: -85px -0px; 217 | } 218 | .tsd-kind-property.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited 219 | > .tsd-kind-icon:before { 220 | background-position: -102px -0px; 221 | } 222 | .tsd-kind-property.tsd-parent-kind-class.tsd-is-private 223 | > .tsd-kind-icon:before { 224 | background-position: -119px -0px; 225 | } 226 | .tsd-kind-property.tsd-parent-kind-enum > .tsd-kind-icon:before { 227 | background-position: -170px -0px; 228 | } 229 | .tsd-kind-property.tsd-parent-kind-enum.tsd-is-protected 230 | > .tsd-kind-icon:before { 231 | background-position: -187px -0px; 232 | } 233 | .tsd-kind-property.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { 234 | background-position: -119px -0px; 235 | } 236 | .tsd-kind-property.tsd-parent-kind-interface > .tsd-kind-icon:before { 237 | background-position: -204px -0px; 238 | } 239 | .tsd-kind-property.tsd-parent-kind-interface.tsd-is-inherited 240 | > .tsd-kind-icon:before { 241 | background-position: -221px -0px; 242 | } 243 | 244 | .tsd-kind-get-signature > .tsd-kind-icon:before { 245 | background-position: -136px -17px; 246 | } 247 | .tsd-kind-get-signature.tsd-is-protected > .tsd-kind-icon:before { 248 | background-position: -153px -17px; 249 | } 250 | .tsd-kind-get-signature.tsd-is-private > .tsd-kind-icon:before { 251 | background-position: -119px -17px; 252 | } 253 | .tsd-kind-get-signature.tsd-parent-kind-class > .tsd-kind-icon:before { 254 | background-position: -51px -17px; 255 | } 256 | .tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-inherited 257 | > .tsd-kind-icon:before { 258 | background-position: -68px -17px; 259 | } 260 | .tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-protected 261 | > .tsd-kind-icon:before { 262 | background-position: -85px -17px; 263 | } 264 | .tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited 265 | > .tsd-kind-icon:before { 266 | background-position: -102px -17px; 267 | } 268 | .tsd-kind-get-signature.tsd-parent-kind-class.tsd-is-private 269 | > .tsd-kind-icon:before { 270 | background-position: -119px -17px; 271 | } 272 | .tsd-kind-get-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { 273 | background-position: -170px -17px; 274 | } 275 | .tsd-kind-get-signature.tsd-parent-kind-enum.tsd-is-protected 276 | > .tsd-kind-icon:before { 277 | background-position: -187px -17px; 278 | } 279 | .tsd-kind-get-signature.tsd-parent-kind-enum.tsd-is-private 280 | > .tsd-kind-icon:before { 281 | background-position: -119px -17px; 282 | } 283 | .tsd-kind-get-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { 284 | background-position: -204px -17px; 285 | } 286 | .tsd-kind-get-signature.tsd-parent-kind-interface.tsd-is-inherited 287 | > .tsd-kind-icon:before { 288 | background-position: -221px -17px; 289 | } 290 | 291 | .tsd-kind-set-signature > .tsd-kind-icon:before { 292 | background-position: -136px -34px; 293 | } 294 | .tsd-kind-set-signature.tsd-is-protected > .tsd-kind-icon:before { 295 | background-position: -153px -34px; 296 | } 297 | .tsd-kind-set-signature.tsd-is-private > .tsd-kind-icon:before { 298 | background-position: -119px -34px; 299 | } 300 | .tsd-kind-set-signature.tsd-parent-kind-class > .tsd-kind-icon:before { 301 | background-position: -51px -34px; 302 | } 303 | .tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-inherited 304 | > .tsd-kind-icon:before { 305 | background-position: -68px -34px; 306 | } 307 | .tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-protected 308 | > .tsd-kind-icon:before { 309 | background-position: -85px -34px; 310 | } 311 | .tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited 312 | > .tsd-kind-icon:before { 313 | background-position: -102px -34px; 314 | } 315 | .tsd-kind-set-signature.tsd-parent-kind-class.tsd-is-private 316 | > .tsd-kind-icon:before { 317 | background-position: -119px -34px; 318 | } 319 | .tsd-kind-set-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { 320 | background-position: -170px -34px; 321 | } 322 | .tsd-kind-set-signature.tsd-parent-kind-enum.tsd-is-protected 323 | > .tsd-kind-icon:before { 324 | background-position: -187px -34px; 325 | } 326 | .tsd-kind-set-signature.tsd-parent-kind-enum.tsd-is-private 327 | > .tsd-kind-icon:before { 328 | background-position: -119px -34px; 329 | } 330 | .tsd-kind-set-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { 331 | background-position: -204px -34px; 332 | } 333 | .tsd-kind-set-signature.tsd-parent-kind-interface.tsd-is-inherited 334 | > .tsd-kind-icon:before { 335 | background-position: -221px -34px; 336 | } 337 | 338 | .tsd-kind-accessor > .tsd-kind-icon:before { 339 | background-position: -136px -51px; 340 | } 341 | .tsd-kind-accessor.tsd-is-protected > .tsd-kind-icon:before { 342 | background-position: -153px -51px; 343 | } 344 | .tsd-kind-accessor.tsd-is-private > .tsd-kind-icon:before { 345 | background-position: -119px -51px; 346 | } 347 | .tsd-kind-accessor.tsd-parent-kind-class > .tsd-kind-icon:before { 348 | background-position: -51px -51px; 349 | } 350 | .tsd-kind-accessor.tsd-parent-kind-class.tsd-is-inherited 351 | > .tsd-kind-icon:before { 352 | background-position: -68px -51px; 353 | } 354 | .tsd-kind-accessor.tsd-parent-kind-class.tsd-is-protected 355 | > .tsd-kind-icon:before { 356 | background-position: -85px -51px; 357 | } 358 | .tsd-kind-accessor.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited 359 | > .tsd-kind-icon:before { 360 | background-position: -102px -51px; 361 | } 362 | .tsd-kind-accessor.tsd-parent-kind-class.tsd-is-private 363 | > .tsd-kind-icon:before { 364 | background-position: -119px -51px; 365 | } 366 | .tsd-kind-accessor.tsd-parent-kind-enum > .tsd-kind-icon:before { 367 | background-position: -170px -51px; 368 | } 369 | .tsd-kind-accessor.tsd-parent-kind-enum.tsd-is-protected 370 | > .tsd-kind-icon:before { 371 | background-position: -187px -51px; 372 | } 373 | .tsd-kind-accessor.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { 374 | background-position: -119px -51px; 375 | } 376 | .tsd-kind-accessor.tsd-parent-kind-interface > .tsd-kind-icon:before { 377 | background-position: -204px -51px; 378 | } 379 | .tsd-kind-accessor.tsd-parent-kind-interface.tsd-is-inherited 380 | > .tsd-kind-icon:before { 381 | background-position: -221px -51px; 382 | } 383 | 384 | .tsd-kind-function > .tsd-kind-icon:before { 385 | background-position: -136px -68px; 386 | } 387 | .tsd-kind-function.tsd-is-protected > .tsd-kind-icon:before { 388 | background-position: -153px -68px; 389 | } 390 | .tsd-kind-function.tsd-is-private > .tsd-kind-icon:before { 391 | background-position: -119px -68px; 392 | } 393 | .tsd-kind-function.tsd-parent-kind-class > .tsd-kind-icon:before { 394 | background-position: -51px -68px; 395 | } 396 | .tsd-kind-function.tsd-parent-kind-class.tsd-is-inherited 397 | > .tsd-kind-icon:before { 398 | background-position: -68px -68px; 399 | } 400 | .tsd-kind-function.tsd-parent-kind-class.tsd-is-protected 401 | > .tsd-kind-icon:before { 402 | background-position: -85px -68px; 403 | } 404 | .tsd-kind-function.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited 405 | > .tsd-kind-icon:before { 406 | background-position: -102px -68px; 407 | } 408 | .tsd-kind-function.tsd-parent-kind-class.tsd-is-private 409 | > .tsd-kind-icon:before { 410 | background-position: -119px -68px; 411 | } 412 | .tsd-kind-function.tsd-parent-kind-enum > .tsd-kind-icon:before { 413 | background-position: -170px -68px; 414 | } 415 | .tsd-kind-function.tsd-parent-kind-enum.tsd-is-protected 416 | > .tsd-kind-icon:before { 417 | background-position: -187px -68px; 418 | } 419 | .tsd-kind-function.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { 420 | background-position: -119px -68px; 421 | } 422 | .tsd-kind-function.tsd-parent-kind-interface > .tsd-kind-icon:before { 423 | background-position: -204px -68px; 424 | } 425 | .tsd-kind-function.tsd-parent-kind-interface.tsd-is-inherited 426 | > .tsd-kind-icon:before { 427 | background-position: -221px -68px; 428 | } 429 | 430 | .tsd-kind-method > .tsd-kind-icon:before { 431 | background-position: -136px -68px; 432 | } 433 | .tsd-kind-method.tsd-is-protected > .tsd-kind-icon:before { 434 | background-position: -153px -68px; 435 | } 436 | .tsd-kind-method.tsd-is-private > .tsd-kind-icon:before { 437 | background-position: -119px -68px; 438 | } 439 | .tsd-kind-method.tsd-parent-kind-class > .tsd-kind-icon:before { 440 | background-position: -51px -68px; 441 | } 442 | .tsd-kind-method.tsd-parent-kind-class.tsd-is-inherited 443 | > .tsd-kind-icon:before { 444 | background-position: -68px -68px; 445 | } 446 | .tsd-kind-method.tsd-parent-kind-class.tsd-is-protected 447 | > .tsd-kind-icon:before { 448 | background-position: -85px -68px; 449 | } 450 | .tsd-kind-method.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited 451 | > .tsd-kind-icon:before { 452 | background-position: -102px -68px; 453 | } 454 | .tsd-kind-method.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { 455 | background-position: -119px -68px; 456 | } 457 | .tsd-kind-method.tsd-parent-kind-enum > .tsd-kind-icon:before { 458 | background-position: -170px -68px; 459 | } 460 | .tsd-kind-method.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { 461 | background-position: -187px -68px; 462 | } 463 | .tsd-kind-method.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { 464 | background-position: -119px -68px; 465 | } 466 | .tsd-kind-method.tsd-parent-kind-interface > .tsd-kind-icon:before { 467 | background-position: -204px -68px; 468 | } 469 | .tsd-kind-method.tsd-parent-kind-interface.tsd-is-inherited 470 | > .tsd-kind-icon:before { 471 | background-position: -221px -68px; 472 | } 473 | 474 | .tsd-kind-call-signature > .tsd-kind-icon:before { 475 | background-position: -136px -68px; 476 | } 477 | .tsd-kind-call-signature.tsd-is-protected > .tsd-kind-icon:before { 478 | background-position: -153px -68px; 479 | } 480 | .tsd-kind-call-signature.tsd-is-private > .tsd-kind-icon:before { 481 | background-position: -119px -68px; 482 | } 483 | .tsd-kind-call-signature.tsd-parent-kind-class > .tsd-kind-icon:before { 484 | background-position: -51px -68px; 485 | } 486 | .tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-inherited 487 | > .tsd-kind-icon:before { 488 | background-position: -68px -68px; 489 | } 490 | .tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected 491 | > .tsd-kind-icon:before { 492 | background-position: -85px -68px; 493 | } 494 | .tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited 495 | > .tsd-kind-icon:before { 496 | background-position: -102px -68px; 497 | } 498 | .tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-private 499 | > .tsd-kind-icon:before { 500 | background-position: -119px -68px; 501 | } 502 | .tsd-kind-call-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { 503 | background-position: -170px -68px; 504 | } 505 | .tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-protected 506 | > .tsd-kind-icon:before { 507 | background-position: -187px -68px; 508 | } 509 | .tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-private 510 | > .tsd-kind-icon:before { 511 | background-position: -119px -68px; 512 | } 513 | .tsd-kind-call-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { 514 | background-position: -204px -68px; 515 | } 516 | .tsd-kind-call-signature.tsd-parent-kind-interface.tsd-is-inherited 517 | > .tsd-kind-icon:before { 518 | background-position: -221px -68px; 519 | } 520 | 521 | .tsd-kind-function.tsd-has-type-parameter > .tsd-kind-icon:before { 522 | background-position: -136px -85px; 523 | } 524 | .tsd-kind-function.tsd-has-type-parameter.tsd-is-protected 525 | > .tsd-kind-icon:before { 526 | background-position: -153px -85px; 527 | } 528 | .tsd-kind-function.tsd-has-type-parameter.tsd-is-private 529 | > .tsd-kind-icon:before { 530 | background-position: -119px -85px; 531 | } 532 | .tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class 533 | > .tsd-kind-icon:before { 534 | background-position: -51px -85px; 535 | } 536 | .tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-inherited 537 | > .tsd-kind-icon:before { 538 | background-position: -68px -85px; 539 | } 540 | .tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected 541 | > .tsd-kind-icon:before { 542 | background-position: -85px -85px; 543 | } 544 | .tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited 545 | > .tsd-kind-icon:before { 546 | background-position: -102px -85px; 547 | } 548 | .tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-private 549 | > .tsd-kind-icon:before { 550 | background-position: -119px -85px; 551 | } 552 | .tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum 553 | > .tsd-kind-icon:before { 554 | background-position: -170px -85px; 555 | } 556 | .tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-protected 557 | > .tsd-kind-icon:before { 558 | background-position: -187px -85px; 559 | } 560 | .tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-private 561 | > .tsd-kind-icon:before { 562 | background-position: -119px -85px; 563 | } 564 | .tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-interface 565 | > .tsd-kind-icon:before { 566 | background-position: -204px -85px; 567 | } 568 | .tsd-kind-function.tsd-has-type-parameter.tsd-parent-kind-interface.tsd-is-inherited 569 | > .tsd-kind-icon:before { 570 | background-position: -221px -85px; 571 | } 572 | 573 | .tsd-kind-method.tsd-has-type-parameter > .tsd-kind-icon:before { 574 | background-position: -136px -85px; 575 | } 576 | .tsd-kind-method.tsd-has-type-parameter.tsd-is-protected 577 | > .tsd-kind-icon:before { 578 | background-position: -153px -85px; 579 | } 580 | .tsd-kind-method.tsd-has-type-parameter.tsd-is-private > .tsd-kind-icon:before { 581 | background-position: -119px -85px; 582 | } 583 | .tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class 584 | > .tsd-kind-icon:before { 585 | background-position: -51px -85px; 586 | } 587 | .tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-inherited 588 | > .tsd-kind-icon:before { 589 | background-position: -68px -85px; 590 | } 591 | .tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected 592 | > .tsd-kind-icon:before { 593 | background-position: -85px -85px; 594 | } 595 | .tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited 596 | > .tsd-kind-icon:before { 597 | background-position: -102px -85px; 598 | } 599 | .tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-class.tsd-is-private 600 | > .tsd-kind-icon:before { 601 | background-position: -119px -85px; 602 | } 603 | .tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum 604 | > .tsd-kind-icon:before { 605 | background-position: -170px -85px; 606 | } 607 | .tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-protected 608 | > .tsd-kind-icon:before { 609 | background-position: -187px -85px; 610 | } 611 | .tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-enum.tsd-is-private 612 | > .tsd-kind-icon:before { 613 | background-position: -119px -85px; 614 | } 615 | .tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-interface 616 | > .tsd-kind-icon:before { 617 | background-position: -204px -85px; 618 | } 619 | .tsd-kind-method.tsd-has-type-parameter.tsd-parent-kind-interface.tsd-is-inherited 620 | > .tsd-kind-icon:before { 621 | background-position: -221px -85px; 622 | } 623 | 624 | .tsd-kind-constructor > .tsd-kind-icon:before { 625 | background-position: -136px -102px; 626 | } 627 | .tsd-kind-constructor.tsd-is-protected > .tsd-kind-icon:before { 628 | background-position: -153px -102px; 629 | } 630 | .tsd-kind-constructor.tsd-is-private > .tsd-kind-icon:before { 631 | background-position: -119px -102px; 632 | } 633 | .tsd-kind-constructor.tsd-parent-kind-class > .tsd-kind-icon:before { 634 | background-position: -51px -102px; 635 | } 636 | .tsd-kind-constructor.tsd-parent-kind-class.tsd-is-inherited 637 | > .tsd-kind-icon:before { 638 | background-position: -68px -102px; 639 | } 640 | .tsd-kind-constructor.tsd-parent-kind-class.tsd-is-protected 641 | > .tsd-kind-icon:before { 642 | background-position: -85px -102px; 643 | } 644 | .tsd-kind-constructor.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited 645 | > .tsd-kind-icon:before { 646 | background-position: -102px -102px; 647 | } 648 | .tsd-kind-constructor.tsd-parent-kind-class.tsd-is-private 649 | > .tsd-kind-icon:before { 650 | background-position: -119px -102px; 651 | } 652 | .tsd-kind-constructor.tsd-parent-kind-enum > .tsd-kind-icon:before { 653 | background-position: -170px -102px; 654 | } 655 | .tsd-kind-constructor.tsd-parent-kind-enum.tsd-is-protected 656 | > .tsd-kind-icon:before { 657 | background-position: -187px -102px; 658 | } 659 | .tsd-kind-constructor.tsd-parent-kind-enum.tsd-is-private 660 | > .tsd-kind-icon:before { 661 | background-position: -119px -102px; 662 | } 663 | .tsd-kind-constructor.tsd-parent-kind-interface > .tsd-kind-icon:before { 664 | background-position: -204px -102px; 665 | } 666 | .tsd-kind-constructor.tsd-parent-kind-interface.tsd-is-inherited 667 | > .tsd-kind-icon:before { 668 | background-position: -221px -102px; 669 | } 670 | 671 | .tsd-kind-constructor-signature > .tsd-kind-icon:before { 672 | background-position: -136px -102px; 673 | } 674 | .tsd-kind-constructor-signature.tsd-is-protected > .tsd-kind-icon:before { 675 | background-position: -153px -102px; 676 | } 677 | .tsd-kind-constructor-signature.tsd-is-private > .tsd-kind-icon:before { 678 | background-position: -119px -102px; 679 | } 680 | .tsd-kind-constructor-signature.tsd-parent-kind-class > .tsd-kind-icon:before { 681 | background-position: -51px -102px; 682 | } 683 | .tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-inherited 684 | > .tsd-kind-icon:before { 685 | background-position: -68px -102px; 686 | } 687 | .tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-protected 688 | > .tsd-kind-icon:before { 689 | background-position: -85px -102px; 690 | } 691 | .tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited 692 | > .tsd-kind-icon:before { 693 | background-position: -102px -102px; 694 | } 695 | .tsd-kind-constructor-signature.tsd-parent-kind-class.tsd-is-private 696 | > .tsd-kind-icon:before { 697 | background-position: -119px -102px; 698 | } 699 | .tsd-kind-constructor-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { 700 | background-position: -170px -102px; 701 | } 702 | .tsd-kind-constructor-signature.tsd-parent-kind-enum.tsd-is-protected 703 | > .tsd-kind-icon:before { 704 | background-position: -187px -102px; 705 | } 706 | .tsd-kind-constructor-signature.tsd-parent-kind-enum.tsd-is-private 707 | > .tsd-kind-icon:before { 708 | background-position: -119px -102px; 709 | } 710 | .tsd-kind-constructor-signature.tsd-parent-kind-interface 711 | > .tsd-kind-icon:before { 712 | background-position: -204px -102px; 713 | } 714 | .tsd-kind-constructor-signature.tsd-parent-kind-interface.tsd-is-inherited 715 | > .tsd-kind-icon:before { 716 | background-position: -221px -102px; 717 | } 718 | 719 | .tsd-kind-index-signature > .tsd-kind-icon:before { 720 | background-position: -136px -119px; 721 | } 722 | .tsd-kind-index-signature.tsd-is-protected > .tsd-kind-icon:before { 723 | background-position: -153px -119px; 724 | } 725 | .tsd-kind-index-signature.tsd-is-private > .tsd-kind-icon:before { 726 | background-position: -119px -119px; 727 | } 728 | .tsd-kind-index-signature.tsd-parent-kind-class > .tsd-kind-icon:before { 729 | background-position: -51px -119px; 730 | } 731 | .tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-inherited 732 | > .tsd-kind-icon:before { 733 | background-position: -68px -119px; 734 | } 735 | .tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-protected 736 | > .tsd-kind-icon:before { 737 | background-position: -85px -119px; 738 | } 739 | .tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited 740 | > .tsd-kind-icon:before { 741 | background-position: -102px -119px; 742 | } 743 | .tsd-kind-index-signature.tsd-parent-kind-class.tsd-is-private 744 | > .tsd-kind-icon:before { 745 | background-position: -119px -119px; 746 | } 747 | .tsd-kind-index-signature.tsd-parent-kind-enum > .tsd-kind-icon:before { 748 | background-position: -170px -119px; 749 | } 750 | .tsd-kind-index-signature.tsd-parent-kind-enum.tsd-is-protected 751 | > .tsd-kind-icon:before { 752 | background-position: -187px -119px; 753 | } 754 | .tsd-kind-index-signature.tsd-parent-kind-enum.tsd-is-private 755 | > .tsd-kind-icon:before { 756 | background-position: -119px -119px; 757 | } 758 | .tsd-kind-index-signature.tsd-parent-kind-interface > .tsd-kind-icon:before { 759 | background-position: -204px -119px; 760 | } 761 | .tsd-kind-index-signature.tsd-parent-kind-interface.tsd-is-inherited 762 | > .tsd-kind-icon:before { 763 | background-position: -221px -119px; 764 | } 765 | 766 | .tsd-kind-event > .tsd-kind-icon:before { 767 | background-position: -136px -136px; 768 | } 769 | .tsd-kind-event.tsd-is-protected > .tsd-kind-icon:before { 770 | background-position: -153px -136px; 771 | } 772 | .tsd-kind-event.tsd-is-private > .tsd-kind-icon:before { 773 | background-position: -119px -136px; 774 | } 775 | .tsd-kind-event.tsd-parent-kind-class > .tsd-kind-icon:before { 776 | background-position: -51px -136px; 777 | } 778 | .tsd-kind-event.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { 779 | background-position: -68px -136px; 780 | } 781 | .tsd-kind-event.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { 782 | background-position: -85px -136px; 783 | } 784 | .tsd-kind-event.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited 785 | > .tsd-kind-icon:before { 786 | background-position: -102px -136px; 787 | } 788 | .tsd-kind-event.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { 789 | background-position: -119px -136px; 790 | } 791 | .tsd-kind-event.tsd-parent-kind-enum > .tsd-kind-icon:before { 792 | background-position: -170px -136px; 793 | } 794 | .tsd-kind-event.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { 795 | background-position: -187px -136px; 796 | } 797 | .tsd-kind-event.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { 798 | background-position: -119px -136px; 799 | } 800 | .tsd-kind-event.tsd-parent-kind-interface > .tsd-kind-icon:before { 801 | background-position: -204px -136px; 802 | } 803 | .tsd-kind-event.tsd-parent-kind-interface.tsd-is-inherited 804 | > .tsd-kind-icon:before { 805 | background-position: -221px -136px; 806 | } 807 | 808 | .tsd-is-static > .tsd-kind-icon:before { 809 | background-position: -136px -153px; 810 | } 811 | .tsd-is-static.tsd-is-protected > .tsd-kind-icon:before { 812 | background-position: -153px -153px; 813 | } 814 | .tsd-is-static.tsd-is-private > .tsd-kind-icon:before { 815 | background-position: -119px -153px; 816 | } 817 | .tsd-is-static.tsd-parent-kind-class > .tsd-kind-icon:before { 818 | background-position: -51px -153px; 819 | } 820 | .tsd-is-static.tsd-parent-kind-class.tsd-is-inherited > .tsd-kind-icon:before { 821 | background-position: -68px -153px; 822 | } 823 | .tsd-is-static.tsd-parent-kind-class.tsd-is-protected > .tsd-kind-icon:before { 824 | background-position: -85px -153px; 825 | } 826 | .tsd-is-static.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited 827 | > .tsd-kind-icon:before { 828 | background-position: -102px -153px; 829 | } 830 | .tsd-is-static.tsd-parent-kind-class.tsd-is-private > .tsd-kind-icon:before { 831 | background-position: -119px -153px; 832 | } 833 | .tsd-is-static.tsd-parent-kind-enum > .tsd-kind-icon:before { 834 | background-position: -170px -153px; 835 | } 836 | .tsd-is-static.tsd-parent-kind-enum.tsd-is-protected > .tsd-kind-icon:before { 837 | background-position: -187px -153px; 838 | } 839 | .tsd-is-static.tsd-parent-kind-enum.tsd-is-private > .tsd-kind-icon:before { 840 | background-position: -119px -153px; 841 | } 842 | .tsd-is-static.tsd-parent-kind-interface > .tsd-kind-icon:before { 843 | background-position: -204px -153px; 844 | } 845 | .tsd-is-static.tsd-parent-kind-interface.tsd-is-inherited 846 | > .tsd-kind-icon:before { 847 | background-position: -221px -153px; 848 | } 849 | 850 | .tsd-is-static.tsd-kind-function > .tsd-kind-icon:before { 851 | background-position: -136px -170px; 852 | } 853 | .tsd-is-static.tsd-kind-function.tsd-is-protected > .tsd-kind-icon:before { 854 | background-position: -153px -170px; 855 | } 856 | .tsd-is-static.tsd-kind-function.tsd-is-private > .tsd-kind-icon:before { 857 | background-position: -119px -170px; 858 | } 859 | .tsd-is-static.tsd-kind-function.tsd-parent-kind-class > .tsd-kind-icon:before { 860 | background-position: -51px -170px; 861 | } 862 | .tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-inherited 863 | > .tsd-kind-icon:before { 864 | background-position: -68px -170px; 865 | } 866 | .tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected 867 | > .tsd-kind-icon:before { 868 | background-position: -85px -170px; 869 | } 870 | .tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited 871 | > .tsd-kind-icon:before { 872 | background-position: -102px -170px; 873 | } 874 | .tsd-is-static.tsd-kind-function.tsd-parent-kind-class.tsd-is-private 875 | > .tsd-kind-icon:before { 876 | background-position: -119px -170px; 877 | } 878 | .tsd-is-static.tsd-kind-function.tsd-parent-kind-enum > .tsd-kind-icon:before { 879 | background-position: -170px -170px; 880 | } 881 | .tsd-is-static.tsd-kind-function.tsd-parent-kind-enum.tsd-is-protected 882 | > .tsd-kind-icon:before { 883 | background-position: -187px -170px; 884 | } 885 | .tsd-is-static.tsd-kind-function.tsd-parent-kind-enum.tsd-is-private 886 | > .tsd-kind-icon:before { 887 | background-position: -119px -170px; 888 | } 889 | .tsd-is-static.tsd-kind-function.tsd-parent-kind-interface 890 | > .tsd-kind-icon:before { 891 | background-position: -204px -170px; 892 | } 893 | .tsd-is-static.tsd-kind-function.tsd-parent-kind-interface.tsd-is-inherited 894 | > .tsd-kind-icon:before { 895 | background-position: -221px -170px; 896 | } 897 | 898 | .tsd-is-static.tsd-kind-method > .tsd-kind-icon:before { 899 | background-position: -136px -170px; 900 | } 901 | .tsd-is-static.tsd-kind-method.tsd-is-protected > .tsd-kind-icon:before { 902 | background-position: -153px -170px; 903 | } 904 | .tsd-is-static.tsd-kind-method.tsd-is-private > .tsd-kind-icon:before { 905 | background-position: -119px -170px; 906 | } 907 | .tsd-is-static.tsd-kind-method.tsd-parent-kind-class > .tsd-kind-icon:before { 908 | background-position: -51px -170px; 909 | } 910 | .tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-inherited 911 | > .tsd-kind-icon:before { 912 | background-position: -68px -170px; 913 | } 914 | .tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected 915 | > .tsd-kind-icon:before { 916 | background-position: -85px -170px; 917 | } 918 | .tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited 919 | > .tsd-kind-icon:before { 920 | background-position: -102px -170px; 921 | } 922 | .tsd-is-static.tsd-kind-method.tsd-parent-kind-class.tsd-is-private 923 | > .tsd-kind-icon:before { 924 | background-position: -119px -170px; 925 | } 926 | .tsd-is-static.tsd-kind-method.tsd-parent-kind-enum > .tsd-kind-icon:before { 927 | background-position: -170px -170px; 928 | } 929 | .tsd-is-static.tsd-kind-method.tsd-parent-kind-enum.tsd-is-protected 930 | > .tsd-kind-icon:before { 931 | background-position: -187px -170px; 932 | } 933 | .tsd-is-static.tsd-kind-method.tsd-parent-kind-enum.tsd-is-private 934 | > .tsd-kind-icon:before { 935 | background-position: -119px -170px; 936 | } 937 | .tsd-is-static.tsd-kind-method.tsd-parent-kind-interface 938 | > .tsd-kind-icon:before { 939 | background-position: -204px -170px; 940 | } 941 | .tsd-is-static.tsd-kind-method.tsd-parent-kind-interface.tsd-is-inherited 942 | > .tsd-kind-icon:before { 943 | background-position: -221px -170px; 944 | } 945 | 946 | .tsd-is-static.tsd-kind-call-signature > .tsd-kind-icon:before { 947 | background-position: -136px -170px; 948 | } 949 | .tsd-is-static.tsd-kind-call-signature.tsd-is-protected 950 | > .tsd-kind-icon:before { 951 | background-position: -153px -170px; 952 | } 953 | .tsd-is-static.tsd-kind-call-signature.tsd-is-private > .tsd-kind-icon:before { 954 | background-position: -119px -170px; 955 | } 956 | .tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class 957 | > .tsd-kind-icon:before { 958 | background-position: -51px -170px; 959 | } 960 | .tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-inherited 961 | > .tsd-kind-icon:before { 962 | background-position: -68px -170px; 963 | } 964 | .tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected 965 | > .tsd-kind-icon:before { 966 | background-position: -85px -170px; 967 | } 968 | .tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited 969 | > .tsd-kind-icon:before { 970 | background-position: -102px -170px; 971 | } 972 | .tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-class.tsd-is-private 973 | > .tsd-kind-icon:before { 974 | background-position: -119px -170px; 975 | } 976 | .tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum 977 | > .tsd-kind-icon:before { 978 | background-position: -170px -170px; 979 | } 980 | .tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-protected 981 | > .tsd-kind-icon:before { 982 | background-position: -187px -170px; 983 | } 984 | .tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-enum.tsd-is-private 985 | > .tsd-kind-icon:before { 986 | background-position: -119px -170px; 987 | } 988 | .tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-interface 989 | > .tsd-kind-icon:before { 990 | background-position: -204px -170px; 991 | } 992 | .tsd-is-static.tsd-kind-call-signature.tsd-parent-kind-interface.tsd-is-inherited 993 | > .tsd-kind-icon:before { 994 | background-position: -221px -170px; 995 | } 996 | 997 | .tsd-is-static.tsd-kind-event > .tsd-kind-icon:before { 998 | background-position: -136px -187px; 999 | } 1000 | .tsd-is-static.tsd-kind-event.tsd-is-protected > .tsd-kind-icon:before { 1001 | background-position: -153px -187px; 1002 | } 1003 | .tsd-is-static.tsd-kind-event.tsd-is-private > .tsd-kind-icon:before { 1004 | background-position: -119px -187px; 1005 | } 1006 | .tsd-is-static.tsd-kind-event.tsd-parent-kind-class > .tsd-kind-icon:before { 1007 | background-position: -51px -187px; 1008 | } 1009 | .tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-inherited 1010 | > .tsd-kind-icon:before { 1011 | background-position: -68px -187px; 1012 | } 1013 | .tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected 1014 | > .tsd-kind-icon:before { 1015 | background-position: -85px -187px; 1016 | } 1017 | .tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-protected.tsd-is-inherited 1018 | > .tsd-kind-icon:before { 1019 | background-position: -102px -187px; 1020 | } 1021 | .tsd-is-static.tsd-kind-event.tsd-parent-kind-class.tsd-is-private 1022 | > .tsd-kind-icon:before { 1023 | background-position: -119px -187px; 1024 | } 1025 | .tsd-is-static.tsd-kind-event.tsd-parent-kind-enum > .tsd-kind-icon:before { 1026 | background-position: -170px -187px; 1027 | } 1028 | .tsd-is-static.tsd-kind-event.tsd-parent-kind-enum.tsd-is-protected 1029 | > .tsd-kind-icon:before { 1030 | background-position: -187px -187px; 1031 | } 1032 | .tsd-is-static.tsd-kind-event.tsd-parent-kind-enum.tsd-is-private 1033 | > .tsd-kind-icon:before { 1034 | background-position: -119px -187px; 1035 | } 1036 | .tsd-is-static.tsd-kind-event.tsd-parent-kind-interface 1037 | > .tsd-kind-icon:before { 1038 | background-position: -204px -187px; 1039 | } 1040 | .tsd-is-static.tsd-kind-event.tsd-parent-kind-interface.tsd-is-inherited 1041 | > .tsd-kind-icon:before { 1042 | background-position: -221px -187px; 1043 | } 1044 | -------------------------------------------------------------------------------- /docs/v1/assets/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/supabase/functions-js/749ff0596f5d043ff69e1b775d65d863639201ac/docs/v1/assets/icons.png -------------------------------------------------------------------------------- /docs/v1/assets/icons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/supabase/functions-js/749ff0596f5d043ff69e1b775d65d863639201ac/docs/v1/assets/icons@2x.png -------------------------------------------------------------------------------- /docs/v1/assets/search.js: -------------------------------------------------------------------------------- 1 | window.searchData = JSON.parse("{\"kinds\":{\"128\":\"Class\",\"512\":\"Constructor\",\"1024\":\"Property\",\"2048\":\"Method\",\"65536\":\"Type literal\"},\"rows\":[{\"id\":0,\"kind\":128,\"name\":\"FunctionsClient\",\"url\":\"classes/FunctionsClient.html\",\"classes\":\"tsd-kind-class\"},{\"id\":1,\"kind\":512,\"name\":\"constructor\",\"url\":\"classes/FunctionsClient.html#constructor\",\"classes\":\"tsd-kind-constructor tsd-parent-kind-class\",\"parent\":\"FunctionsClient\"},{\"id\":2,\"kind\":1024,\"name\":\"url\",\"url\":\"classes/FunctionsClient.html#url\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-protected\",\"parent\":\"FunctionsClient\"},{\"id\":3,\"kind\":1024,\"name\":\"headers\",\"url\":\"classes/FunctionsClient.html#headers\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-protected\",\"parent\":\"FunctionsClient\"},{\"id\":4,\"kind\":1024,\"name\":\"fetch\",\"url\":\"classes/FunctionsClient.html#fetch\",\"classes\":\"tsd-kind-property tsd-parent-kind-class tsd-is-protected\",\"parent\":\"FunctionsClient\"},{\"id\":5,\"kind\":65536,\"name\":\"__type\",\"url\":\"classes/FunctionsClient.html#__type\",\"classes\":\"tsd-kind-type-literal tsd-parent-kind-class\",\"parent\":\"FunctionsClient\"},{\"id\":6,\"kind\":2048,\"name\":\"setAuth\",\"url\":\"classes/FunctionsClient.html#setAuth\",\"classes\":\"tsd-kind-method tsd-parent-kind-class\",\"parent\":\"FunctionsClient\"},{\"id\":7,\"kind\":2048,\"name\":\"invoke\",\"url\":\"classes/FunctionsClient.html#invoke\",\"classes\":\"tsd-kind-method tsd-parent-kind-class tsd-has-type-parameter\",\"parent\":\"FunctionsClient\"}],\"index\":{\"version\":\"2.3.9\",\"fields\":[\"name\",\"parent\"],\"fieldVectors\":[[\"name/0\",[0,0.572]],[\"parent/0\",[]],[\"name/1\",[1,17.918]],[\"parent/1\",[0,0.054]],[\"name/2\",[2,17.918]],[\"parent/2\",[0,0.054]],[\"name/3\",[3,17.918]],[\"parent/3\",[0,0.054]],[\"name/4\",[4,17.918]],[\"parent/4\",[0,0.054]],[\"name/5\",[5,17.918]],[\"parent/5\",[0,0.054]],[\"name/6\",[6,17.918]],[\"parent/6\",[0,0.054]],[\"name/7\",[7,17.918]],[\"parent/7\",[0,0.054]]],\"invertedIndex\":[[\"__type\",{\"_index\":5,\"name\":{\"5\":{}},\"parent\":{}}],[\"constructor\",{\"_index\":1,\"name\":{\"1\":{}},\"parent\":{}}],[\"fetch\",{\"_index\":4,\"name\":{\"4\":{}},\"parent\":{}}],[\"functionsclient\",{\"_index\":0,\"name\":{\"0\":{}},\"parent\":{\"1\":{},\"2\":{},\"3\":{},\"4\":{},\"5\":{},\"6\":{},\"7\":{}}}],[\"headers\",{\"_index\":3,\"name\":{\"3\":{}},\"parent\":{}}],[\"invoke\",{\"_index\":7,\"name\":{\"7\":{}},\"parent\":{}}],[\"setauth\",{\"_index\":6,\"name\":{\"6\":{}},\"parent\":{}}],[\"url\",{\"_index\":2,\"name\":{\"2\":{}},\"parent\":{}}]],\"pipeline\":[]}}"); -------------------------------------------------------------------------------- /docs/v1/assets/style.css: -------------------------------------------------------------------------------- 1 | @import url("./icons.css"); 2 | 3 | :root { 4 | /* Light */ 5 | --light-color-background: #fcfcfc; 6 | --light-color-secondary-background: #fff; 7 | --light-color-text: #222; 8 | --light-color-text-aside: #707070; 9 | --light-color-link: #4da6ff; 10 | --light-color-menu-divider: #eee; 11 | --light-color-menu-divider-focus: #000; 12 | --light-color-menu-label: #707070; 13 | --light-color-panel: var(--light-color-secondary-background); 14 | --light-color-panel-divider: #eee; 15 | --light-color-comment-tag: #707070; 16 | --light-color-comment-tag-text: #fff; 17 | --light-color-ts: #9600ff; 18 | --light-color-ts-interface: #647f1b; 19 | --light-color-ts-enum: #937210; 20 | --light-color-ts-class: #0672de; 21 | --light-color-ts-private: #707070; 22 | --light-color-toolbar: #fff; 23 | --light-color-toolbar-text: #333; 24 | --light-icon-filter: invert(0); 25 | --light-external-icon: url("data:image/svg+xml;utf8,"); 26 | 27 | /* Dark */ 28 | --dark-color-background: #36393f; 29 | --dark-color-secondary-background: #2f3136; 30 | --dark-color-text: #ffffff; 31 | --dark-color-text-aside: #e6e4e4; 32 | --dark-color-link: #00aff4; 33 | --dark-color-menu-divider: #eee; 34 | --dark-color-menu-divider-focus: #000; 35 | --dark-color-menu-label: #707070; 36 | --dark-color-panel: var(--dark-color-secondary-background); 37 | --dark-color-panel-divider: #818181; 38 | --dark-color-comment-tag: #dcddde; 39 | --dark-color-comment-tag-text: #2f3136; 40 | --dark-color-ts: #c97dff; 41 | --dark-color-ts-interface: #9cbe3c; 42 | --dark-color-ts-enum: #d6ab29; 43 | --dark-color-ts-class: #3695f3; 44 | --dark-color-ts-private: #e2e2e2; 45 | --dark-color-toolbar: #34373c; 46 | --dark-color-toolbar-text: #ffffff; 47 | --dark-icon-filter: invert(1); 48 | --dark-external-icon: url("data:image/svg+xml;utf8,"); 49 | } 50 | 51 | @media (prefers-color-scheme: light) { 52 | :root { 53 | --color-background: var(--light-color-background); 54 | --color-secondary-background: var(--light-color-secondary-background); 55 | --color-text: var(--light-color-text); 56 | --color-text-aside: var(--light-color-text-aside); 57 | --color-link: var(--light-color-link); 58 | --color-menu-divider: var(--light-color-menu-divider); 59 | --color-menu-divider-focus: var(--light-color-menu-divider-focus); 60 | --color-menu-label: var(--light-color-menu-label); 61 | --color-panel: var(--light-color-panel); 62 | --color-panel-divider: var(--light-color-panel-divider); 63 | --color-comment-tag: var(--light-color-comment-tag); 64 | --color-comment-tag-text: var(--light-color-comment-tag-text); 65 | --color-ts: var(--light-color-ts); 66 | --color-ts-interface: var(--light-color-ts-interface); 67 | --color-ts-enum: var(--light-color-ts-enum); 68 | --color-ts-class: var(--light-color-ts-class); 69 | --color-ts-private: var(--light-color-ts-private); 70 | --color-toolbar: var(--light-color-toolbar); 71 | --color-toolbar-text: var(--light-color-toolbar-text); 72 | --icon-filter: var(--light-icon-filter); 73 | --external-icon: var(--light-external-icon); 74 | } 75 | } 76 | 77 | @media (prefers-color-scheme: dark) { 78 | :root { 79 | --color-background: var(--dark-color-background); 80 | --color-secondary-background: var(--dark-color-secondary-background); 81 | --color-text: var(--dark-color-text); 82 | --color-text-aside: var(--dark-color-text-aside); 83 | --color-link: var(--dark-color-link); 84 | --color-menu-divider: var(--dark-color-menu-divider); 85 | --color-menu-divider-focus: var(--dark-color-menu-divider-focus); 86 | --color-menu-label: var(--dark-color-menu-label); 87 | --color-panel: var(--dark-color-panel); 88 | --color-panel-divider: var(--dark-color-panel-divider); 89 | --color-comment-tag: var(--dark-color-comment-tag); 90 | --color-comment-tag-text: var(--dark-color-comment-tag-text); 91 | --color-ts: var(--dark-color-ts); 92 | --color-ts-interface: var(--dark-color-ts-interface); 93 | --color-ts-enum: var(--dark-color-ts-enum); 94 | --color-ts-class: var(--dark-color-ts-class); 95 | --color-ts-private: var(--dark-color-ts-private); 96 | --color-toolbar: var(--dark-color-toolbar); 97 | --color-toolbar-text: var(--dark-color-toolbar-text); 98 | --icon-filter: var(--dark-icon-filter); 99 | --external-icon: var(--dark-external-icon); 100 | } 101 | } 102 | 103 | body { 104 | margin: 0; 105 | } 106 | 107 | body.light { 108 | --color-background: var(--light-color-background); 109 | --color-secondary-background: var(--light-color-secondary-background); 110 | --color-text: var(--light-color-text); 111 | --color-text-aside: var(--light-color-text-aside); 112 | --color-link: var(--light-color-link); 113 | --color-menu-divider: var(--light-color-menu-divider); 114 | --color-menu-divider-focus: var(--light-color-menu-divider-focus); 115 | --color-menu-label: var(--light-color-menu-label); 116 | --color-panel: var(--light-color-panel); 117 | --color-panel-divider: var(--light-color-panel-divider); 118 | --color-comment-tag: var(--light-color-comment-tag); 119 | --color-comment-tag-text: var(--light-color-comment-tag-text); 120 | --color-ts: var(--light-color-ts); 121 | --color-ts-interface: var(--light-color-ts-interface); 122 | --color-ts-enum: var(--light-color-ts-enum); 123 | --color-ts-class: var(--light-color-ts-class); 124 | --color-ts-private: var(--light-color-ts-private); 125 | --color-toolbar: var(--light-color-toolbar); 126 | --color-toolbar-text: var(--light-color-toolbar-text); 127 | --icon-filter: var(--light-icon-filter); 128 | --external-icon: var(--light-external-icon); 129 | } 130 | 131 | body.dark { 132 | --color-background: var(--dark-color-background); 133 | --color-secondary-background: var(--dark-color-secondary-background); 134 | --color-text: var(--dark-color-text); 135 | --color-text-aside: var(--dark-color-text-aside); 136 | --color-link: var(--dark-color-link); 137 | --color-menu-divider: var(--dark-color-menu-divider); 138 | --color-menu-divider-focus: var(--dark-color-menu-divider-focus); 139 | --color-menu-label: var(--dark-color-menu-label); 140 | --color-panel: var(--dark-color-panel); 141 | --color-panel-divider: var(--dark-color-panel-divider); 142 | --color-comment-tag: var(--dark-color-comment-tag); 143 | --color-comment-tag-text: var(--dark-color-comment-tag-text); 144 | --color-ts: var(--dark-color-ts); 145 | --color-ts-interface: var(--dark-color-ts-interface); 146 | --color-ts-enum: var(--dark-color-ts-enum); 147 | --color-ts-class: var(--dark-color-ts-class); 148 | --color-ts-private: var(--dark-color-ts-private); 149 | --color-toolbar: var(--dark-color-toolbar); 150 | --color-toolbar-text: var(--dark-color-toolbar-text); 151 | --icon-filter: var(--dark-icon-filter); 152 | --external-icon: var(--dark-external-icon); 153 | } 154 | 155 | h1, 156 | h2, 157 | h3, 158 | h4, 159 | h5, 160 | h6 { 161 | line-height: 1.2; 162 | } 163 | 164 | h1 { 165 | font-size: 2em; 166 | margin: 0.67em 0; 167 | } 168 | 169 | h2 { 170 | font-size: 1.5em; 171 | margin: 0.83em 0; 172 | } 173 | 174 | h3 { 175 | font-size: 1.17em; 176 | margin: 1em 0; 177 | } 178 | 179 | h4, 180 | .tsd-index-panel h3 { 181 | font-size: 1em; 182 | margin: 1.33em 0; 183 | } 184 | 185 | h5 { 186 | font-size: 0.83em; 187 | margin: 1.67em 0; 188 | } 189 | 190 | h6 { 191 | font-size: 0.67em; 192 | margin: 2.33em 0; 193 | } 194 | 195 | pre { 196 | white-space: pre; 197 | white-space: pre-wrap; 198 | word-wrap: break-word; 199 | } 200 | 201 | dl, 202 | menu, 203 | ol, 204 | ul { 205 | margin: 1em 0; 206 | } 207 | 208 | dd { 209 | margin: 0 0 0 40px; 210 | } 211 | 212 | .container { 213 | max-width: 1200px; 214 | margin: 0 auto; 215 | padding: 0 40px; 216 | } 217 | @media (max-width: 640px) { 218 | .container { 219 | padding: 0 20px; 220 | } 221 | } 222 | 223 | .container-main { 224 | padding-bottom: 200px; 225 | } 226 | 227 | .row { 228 | display: flex; 229 | position: relative; 230 | margin: 0 -10px; 231 | } 232 | .row:after { 233 | visibility: hidden; 234 | display: block; 235 | content: ""; 236 | clear: both; 237 | height: 0; 238 | } 239 | 240 | .col-4, 241 | .col-8 { 242 | box-sizing: border-box; 243 | float: left; 244 | padding: 0 10px; 245 | } 246 | 247 | .col-4 { 248 | width: 33.3333333333%; 249 | } 250 | .col-8 { 251 | width: 66.6666666667%; 252 | } 253 | 254 | ul.tsd-descriptions > li > :first-child, 255 | .tsd-panel > :first-child, 256 | .col-8 > :first-child, 257 | .col-4 > :first-child, 258 | ul.tsd-descriptions > li > :first-child > :first-child, 259 | .tsd-panel > :first-child > :first-child, 260 | .col-8 > :first-child > :first-child, 261 | .col-4 > :first-child > :first-child, 262 | ul.tsd-descriptions > li > :first-child > :first-child > :first-child, 263 | .tsd-panel > :first-child > :first-child > :first-child, 264 | .col-8 > :first-child > :first-child > :first-child, 265 | .col-4 > :first-child > :first-child > :first-child { 266 | margin-top: 0; 267 | } 268 | ul.tsd-descriptions > li > :last-child, 269 | .tsd-panel > :last-child, 270 | .col-8 > :last-child, 271 | .col-4 > :last-child, 272 | ul.tsd-descriptions > li > :last-child > :last-child, 273 | .tsd-panel > :last-child > :last-child, 274 | .col-8 > :last-child > :last-child, 275 | .col-4 > :last-child > :last-child, 276 | ul.tsd-descriptions > li > :last-child > :last-child > :last-child, 277 | .tsd-panel > :last-child > :last-child > :last-child, 278 | .col-8 > :last-child > :last-child > :last-child, 279 | .col-4 > :last-child > :last-child > :last-child { 280 | margin-bottom: 0; 281 | } 282 | 283 | @keyframes fade-in { 284 | from { 285 | opacity: 0; 286 | } 287 | to { 288 | opacity: 1; 289 | } 290 | } 291 | @keyframes fade-out { 292 | from { 293 | opacity: 1; 294 | visibility: visible; 295 | } 296 | to { 297 | opacity: 0; 298 | } 299 | } 300 | @keyframes fade-in-delayed { 301 | 0% { 302 | opacity: 0; 303 | } 304 | 33% { 305 | opacity: 0; 306 | } 307 | 100% { 308 | opacity: 1; 309 | } 310 | } 311 | @keyframes fade-out-delayed { 312 | 0% { 313 | opacity: 1; 314 | visibility: visible; 315 | } 316 | 66% { 317 | opacity: 0; 318 | } 319 | 100% { 320 | opacity: 0; 321 | } 322 | } 323 | @keyframes shift-to-left { 324 | from { 325 | transform: translate(0, 0); 326 | } 327 | to { 328 | transform: translate(-25%, 0); 329 | } 330 | } 331 | @keyframes unshift-to-left { 332 | from { 333 | transform: translate(-25%, 0); 334 | } 335 | to { 336 | transform: translate(0, 0); 337 | } 338 | } 339 | @keyframes pop-in-from-right { 340 | from { 341 | transform: translate(100%, 0); 342 | } 343 | to { 344 | transform: translate(0, 0); 345 | } 346 | } 347 | @keyframes pop-out-to-right { 348 | from { 349 | transform: translate(0, 0); 350 | visibility: visible; 351 | } 352 | to { 353 | transform: translate(100%, 0); 354 | } 355 | } 356 | body { 357 | background: var(--color-background); 358 | font-family: "Segoe UI", sans-serif; 359 | font-size: 16px; 360 | color: var(--color-text); 361 | } 362 | 363 | a { 364 | color: var(--color-link); 365 | text-decoration: none; 366 | } 367 | a:hover { 368 | text-decoration: underline; 369 | } 370 | a.external[target="_blank"] { 371 | background-image: var(--external-icon); 372 | background-position: top 3px right; 373 | background-repeat: no-repeat; 374 | padding-right: 13px; 375 | } 376 | 377 | code, 378 | pre { 379 | font-family: Menlo, Monaco, Consolas, "Courier New", monospace; 380 | padding: 0.2em; 381 | margin: 0; 382 | font-size: 14px; 383 | } 384 | 385 | pre { 386 | padding: 10px; 387 | } 388 | pre code { 389 | padding: 0; 390 | font-size: 100%; 391 | } 392 | 393 | blockquote { 394 | margin: 1em 0; 395 | padding-left: 1em; 396 | border-left: 4px solid gray; 397 | } 398 | 399 | .tsd-typography { 400 | line-height: 1.333em; 401 | } 402 | .tsd-typography ul { 403 | list-style: square; 404 | padding: 0 0 0 20px; 405 | margin: 0; 406 | } 407 | .tsd-typography h4, 408 | .tsd-typography .tsd-index-panel h3, 409 | .tsd-index-panel .tsd-typography h3, 410 | .tsd-typography h5, 411 | .tsd-typography h6 { 412 | font-size: 1em; 413 | margin: 0; 414 | } 415 | .tsd-typography h5, 416 | .tsd-typography h6 { 417 | font-weight: normal; 418 | } 419 | .tsd-typography p, 420 | .tsd-typography ul, 421 | .tsd-typography ol { 422 | margin: 1em 0; 423 | } 424 | 425 | @media (min-width: 901px) and (max-width: 1024px) { 426 | html .col-content { 427 | width: 72%; 428 | } 429 | html .col-menu { 430 | width: 28%; 431 | } 432 | html .tsd-navigation { 433 | padding-left: 10px; 434 | } 435 | } 436 | @media (max-width: 900px) { 437 | html .col-content { 438 | float: none; 439 | width: 100%; 440 | } 441 | html .col-menu { 442 | position: fixed !important; 443 | overflow: auto; 444 | -webkit-overflow-scrolling: touch; 445 | z-index: 1024; 446 | top: 0 !important; 447 | bottom: 0 !important; 448 | left: auto !important; 449 | right: 0 !important; 450 | width: 100%; 451 | padding: 20px 20px 0 0; 452 | max-width: 450px; 453 | visibility: hidden; 454 | background-color: var(--color-panel); 455 | transform: translate(100%, 0); 456 | } 457 | html .col-menu > *:last-child { 458 | padding-bottom: 20px; 459 | } 460 | html .overlay { 461 | content: ""; 462 | display: block; 463 | position: fixed; 464 | z-index: 1023; 465 | top: 0; 466 | left: 0; 467 | right: 0; 468 | bottom: 0; 469 | background-color: rgba(0, 0, 0, 0.75); 470 | visibility: hidden; 471 | } 472 | 473 | .to-has-menu .overlay { 474 | animation: fade-in 0.4s; 475 | } 476 | 477 | .to-has-menu :is(header, footer, .col-content) { 478 | animation: shift-to-left 0.4s; 479 | } 480 | 481 | .to-has-menu .col-menu { 482 | animation: pop-in-from-right 0.4s; 483 | } 484 | 485 | .from-has-menu .overlay { 486 | animation: fade-out 0.4s; 487 | } 488 | 489 | .from-has-menu :is(header, footer, .col-content) { 490 | animation: unshift-to-left 0.4s; 491 | } 492 | 493 | .from-has-menu .col-menu { 494 | animation: pop-out-to-right 0.4s; 495 | } 496 | 497 | .has-menu body { 498 | overflow: hidden; 499 | } 500 | .has-menu .overlay { 501 | visibility: visible; 502 | } 503 | .has-menu :is(header, footer, .col-content) { 504 | transform: translate(-25%, 0); 505 | } 506 | .has-menu .col-menu { 507 | visibility: visible; 508 | transform: translate(0, 0); 509 | display: grid; 510 | grid-template-rows: auto 1fr; 511 | max-height: 100vh; 512 | } 513 | .has-menu .tsd-navigation { 514 | max-height: 100%; 515 | } 516 | } 517 | 518 | .tsd-page-title { 519 | padding: 70px 0 20px 0; 520 | margin: 0 0 40px 0; 521 | background: var(--color-panel); 522 | box-shadow: 0 0 5px rgba(0, 0, 0, 0.35); 523 | } 524 | .tsd-page-title h1 { 525 | margin: 0; 526 | } 527 | 528 | .tsd-breadcrumb { 529 | margin: 0; 530 | padding: 0; 531 | color: var(--color-text-aside); 532 | } 533 | .tsd-breadcrumb a { 534 | color: var(--color-text-aside); 535 | text-decoration: none; 536 | } 537 | .tsd-breadcrumb a:hover { 538 | text-decoration: underline; 539 | } 540 | .tsd-breadcrumb li { 541 | display: inline; 542 | } 543 | .tsd-breadcrumb li:after { 544 | content: " / "; 545 | } 546 | 547 | dl.tsd-comment-tags { 548 | overflow: hidden; 549 | } 550 | dl.tsd-comment-tags dt { 551 | float: left; 552 | padding: 1px 5px; 553 | margin: 0 10px 0 0; 554 | border-radius: 4px; 555 | border: 1px solid var(--color-comment-tag); 556 | color: var(--color-comment-tag); 557 | font-size: 0.8em; 558 | font-weight: normal; 559 | } 560 | dl.tsd-comment-tags dd { 561 | margin: 0 0 10px 0; 562 | } 563 | dl.tsd-comment-tags dd:before, 564 | dl.tsd-comment-tags dd:after { 565 | display: table; 566 | content: " "; 567 | } 568 | dl.tsd-comment-tags dd pre, 569 | dl.tsd-comment-tags dd:after { 570 | clear: both; 571 | } 572 | dl.tsd-comment-tags p { 573 | margin: 0; 574 | } 575 | 576 | .tsd-panel.tsd-comment .lead { 577 | font-size: 1.1em; 578 | line-height: 1.333em; 579 | margin-bottom: 2em; 580 | } 581 | .tsd-panel.tsd-comment .lead:last-child { 582 | margin-bottom: 0; 583 | } 584 | 585 | .toggle-protected .tsd-is-private { 586 | display: none; 587 | } 588 | 589 | .toggle-public .tsd-is-private, 590 | .toggle-public .tsd-is-protected, 591 | .toggle-public .tsd-is-private-protected { 592 | display: none; 593 | } 594 | 595 | .toggle-inherited .tsd-is-inherited { 596 | display: none; 597 | } 598 | 599 | .toggle-externals .tsd-is-external { 600 | display: none; 601 | } 602 | 603 | #tsd-filter { 604 | position: relative; 605 | display: inline-block; 606 | height: 40px; 607 | vertical-align: bottom; 608 | } 609 | .no-filter #tsd-filter { 610 | display: none; 611 | } 612 | #tsd-filter .tsd-filter-group { 613 | display: inline-block; 614 | height: 40px; 615 | vertical-align: bottom; 616 | white-space: nowrap; 617 | } 618 | #tsd-filter input { 619 | display: none; 620 | } 621 | @media (max-width: 900px) { 622 | #tsd-filter .tsd-filter-group { 623 | display: block; 624 | position: absolute; 625 | top: 40px; 626 | right: 20px; 627 | height: auto; 628 | background-color: var(--color-panel); 629 | visibility: hidden; 630 | transform: translate(50%, 0); 631 | box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); 632 | } 633 | .has-options #tsd-filter .tsd-filter-group { 634 | visibility: visible; 635 | } 636 | .to-has-options #tsd-filter .tsd-filter-group { 637 | animation: fade-in 0.2s; 638 | } 639 | .from-has-options #tsd-filter .tsd-filter-group { 640 | animation: fade-out 0.2s; 641 | } 642 | #tsd-filter label, 643 | #tsd-filter .tsd-select { 644 | display: block; 645 | padding-right: 20px; 646 | } 647 | } 648 | 649 | footer { 650 | border-top: 1px solid var(--color-panel-divider); 651 | background-color: var(--color-panel); 652 | } 653 | footer:after { 654 | content: ""; 655 | display: table; 656 | } 657 | footer.with-border-bottom { 658 | border-bottom: 1px solid var(--color-panel-divider); 659 | } 660 | footer .tsd-legend-group { 661 | font-size: 0; 662 | } 663 | footer .tsd-legend { 664 | display: inline-block; 665 | width: 25%; 666 | padding: 0; 667 | font-size: 16px; 668 | list-style: none; 669 | line-height: 1.333em; 670 | vertical-align: top; 671 | } 672 | @media (max-width: 900px) { 673 | footer .tsd-legend { 674 | width: 50%; 675 | } 676 | } 677 | 678 | .tsd-hierarchy { 679 | list-style: square; 680 | padding: 0 0 0 20px; 681 | margin: 0; 682 | } 683 | .tsd-hierarchy .target { 684 | font-weight: bold; 685 | } 686 | 687 | .tsd-index-panel .tsd-index-content { 688 | margin-bottom: -30px !important; 689 | } 690 | .tsd-index-panel .tsd-index-section { 691 | margin-bottom: 30px !important; 692 | } 693 | .tsd-index-panel h3 { 694 | margin: 0 -20px 10px -20px; 695 | padding: 0 20px 10px 20px; 696 | border-bottom: 1px solid var(--color-panel-divider); 697 | } 698 | .tsd-index-panel ul.tsd-index-list { 699 | -webkit-column-count: 3; 700 | -moz-column-count: 3; 701 | -ms-column-count: 3; 702 | -o-column-count: 3; 703 | column-count: 3; 704 | -webkit-column-gap: 20px; 705 | -moz-column-gap: 20px; 706 | -ms-column-gap: 20px; 707 | -o-column-gap: 20px; 708 | column-gap: 20px; 709 | padding: 0; 710 | list-style: none; 711 | line-height: 1.333em; 712 | } 713 | @media (max-width: 900px) { 714 | .tsd-index-panel ul.tsd-index-list { 715 | -webkit-column-count: 1; 716 | -moz-column-count: 1; 717 | -ms-column-count: 1; 718 | -o-column-count: 1; 719 | column-count: 1; 720 | } 721 | } 722 | @media (min-width: 901px) and (max-width: 1024px) { 723 | .tsd-index-panel ul.tsd-index-list { 724 | -webkit-column-count: 2; 725 | -moz-column-count: 2; 726 | -ms-column-count: 2; 727 | -o-column-count: 2; 728 | column-count: 2; 729 | } 730 | } 731 | .tsd-index-panel ul.tsd-index-list li { 732 | -webkit-page-break-inside: avoid; 733 | -moz-page-break-inside: avoid; 734 | -ms-page-break-inside: avoid; 735 | -o-page-break-inside: avoid; 736 | page-break-inside: avoid; 737 | } 738 | .tsd-index-panel a, 739 | .tsd-index-panel .tsd-parent-kind-module a { 740 | color: var(--color-ts); 741 | } 742 | .tsd-index-panel .tsd-parent-kind-interface a { 743 | color: var(--color-ts-interface); 744 | } 745 | .tsd-index-panel .tsd-parent-kind-enum a { 746 | color: var(--color-ts-enum); 747 | } 748 | .tsd-index-panel .tsd-parent-kind-class a { 749 | color: var(--color-ts-class); 750 | } 751 | .tsd-index-panel .tsd-kind-module a { 752 | color: var(--color-ts); 753 | } 754 | .tsd-index-panel .tsd-kind-interface a { 755 | color: var(--color-ts-interface); 756 | } 757 | .tsd-index-panel .tsd-kind-enum a { 758 | color: var(--color-ts-enum); 759 | } 760 | .tsd-index-panel .tsd-kind-class a { 761 | color: var(--color-ts-class); 762 | } 763 | .tsd-index-panel .tsd-is-private a { 764 | color: var(--color-ts-private); 765 | } 766 | 767 | .tsd-flag { 768 | display: inline-block; 769 | padding: 1px 5px; 770 | border-radius: 4px; 771 | color: var(--color-comment-tag-text); 772 | background-color: var(--color-comment-tag); 773 | text-indent: 0; 774 | font-size: 14px; 775 | font-weight: normal; 776 | } 777 | 778 | .tsd-anchor { 779 | position: absolute; 780 | top: -100px; 781 | } 782 | 783 | .tsd-member { 784 | position: relative; 785 | } 786 | .tsd-member .tsd-anchor + h3 { 787 | margin-top: 0; 788 | margin-bottom: 0; 789 | border-bottom: none; 790 | } 791 | .tsd-member [data-tsd-kind] { 792 | color: var(--color-ts); 793 | } 794 | .tsd-member [data-tsd-kind="Interface"] { 795 | color: var(--color-ts-interface); 796 | } 797 | .tsd-member [data-tsd-kind="Enum"] { 798 | color: var(--color-ts-enum); 799 | } 800 | .tsd-member [data-tsd-kind="Class"] { 801 | color: var(--color-ts-class); 802 | } 803 | .tsd-member [data-tsd-kind="Private"] { 804 | color: var(--color-ts-private); 805 | } 806 | 807 | .tsd-navigation { 808 | margin: 0 0 0 40px; 809 | } 810 | .tsd-navigation a { 811 | display: block; 812 | padding-top: 2px; 813 | padding-bottom: 2px; 814 | border-left: 2px solid transparent; 815 | color: var(--color-text); 816 | text-decoration: none; 817 | transition: border-left-color 0.1s; 818 | } 819 | .tsd-navigation a:hover { 820 | text-decoration: underline; 821 | } 822 | .tsd-navigation ul { 823 | margin: 0; 824 | padding: 0; 825 | list-style: none; 826 | } 827 | .tsd-navigation li { 828 | padding: 0; 829 | } 830 | 831 | .tsd-navigation.primary { 832 | padding-bottom: 40px; 833 | } 834 | .tsd-navigation.primary a { 835 | display: block; 836 | padding-top: 6px; 837 | padding-bottom: 6px; 838 | } 839 | .tsd-navigation.primary ul li a { 840 | padding-left: 5px; 841 | } 842 | .tsd-navigation.primary ul li li a { 843 | padding-left: 25px; 844 | } 845 | .tsd-navigation.primary ul li li li a { 846 | padding-left: 45px; 847 | } 848 | .tsd-navigation.primary ul li li li li a { 849 | padding-left: 65px; 850 | } 851 | .tsd-navigation.primary ul li li li li li a { 852 | padding-left: 85px; 853 | } 854 | .tsd-navigation.primary ul li li li li li li a { 855 | padding-left: 105px; 856 | } 857 | .tsd-navigation.primary > ul { 858 | border-bottom: 1px solid var(--color-panel-divider); 859 | } 860 | .tsd-navigation.primary li { 861 | border-top: 1px solid var(--color-panel-divider); 862 | } 863 | .tsd-navigation.primary li.current > a { 864 | font-weight: bold; 865 | } 866 | .tsd-navigation.primary li.label span { 867 | display: block; 868 | padding: 20px 0 6px 5px; 869 | color: var(--color-menu-label); 870 | } 871 | .tsd-navigation.primary li.globals + li > span, 872 | .tsd-navigation.primary li.globals + li > a { 873 | padding-top: 20px; 874 | } 875 | 876 | .tsd-navigation.secondary { 877 | max-height: calc(100vh - 1rem - 40px); 878 | overflow: auto; 879 | position: sticky; 880 | top: calc(0.5rem + 40px); 881 | transition: 0.3s; 882 | } 883 | .tsd-navigation.secondary.tsd-navigation--toolbar-hide { 884 | max-height: calc(100vh - 1rem); 885 | top: 0.5rem; 886 | } 887 | .tsd-navigation.secondary ul { 888 | transition: opacity 0.2s; 889 | } 890 | .tsd-navigation.secondary ul li a { 891 | padding-left: 25px; 892 | } 893 | .tsd-navigation.secondary ul li li a { 894 | padding-left: 45px; 895 | } 896 | .tsd-navigation.secondary ul li li li a { 897 | padding-left: 65px; 898 | } 899 | .tsd-navigation.secondary ul li li li li a { 900 | padding-left: 85px; 901 | } 902 | .tsd-navigation.secondary ul li li li li li a { 903 | padding-left: 105px; 904 | } 905 | .tsd-navigation.secondary ul li li li li li li a { 906 | padding-left: 125px; 907 | } 908 | .tsd-navigation.secondary ul.current a { 909 | border-left-color: var(--color-panel-divider); 910 | } 911 | .tsd-navigation.secondary li.focus > a, 912 | .tsd-navigation.secondary ul.current li.focus > a { 913 | border-left-color: var(--color-menu-divider-focus); 914 | } 915 | .tsd-navigation.secondary li.current { 916 | margin-top: 20px; 917 | margin-bottom: 20px; 918 | border-left-color: var(--color-panel-divider); 919 | } 920 | .tsd-navigation.secondary li.current > a { 921 | font-weight: bold; 922 | } 923 | 924 | @media (min-width: 901px) { 925 | .menu-sticky-wrap { 926 | position: static; 927 | } 928 | } 929 | 930 | .tsd-panel { 931 | margin: 20px 0; 932 | padding: 20px; 933 | background-color: var(--color-panel); 934 | box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); 935 | } 936 | .tsd-panel:empty { 937 | display: none; 938 | } 939 | .tsd-panel > h1, 940 | .tsd-panel > h2, 941 | .tsd-panel > h3 { 942 | margin: 1.5em -20px 10px -20px; 943 | padding: 0 20px 10px 20px; 944 | border-bottom: 1px solid var(--color-panel-divider); 945 | } 946 | .tsd-panel > h1.tsd-before-signature, 947 | .tsd-panel > h2.tsd-before-signature, 948 | .tsd-panel > h3.tsd-before-signature { 949 | margin-bottom: 0; 950 | border-bottom: 0; 951 | } 952 | .tsd-panel table { 953 | display: block; 954 | width: 100%; 955 | overflow: auto; 956 | margin-top: 10px; 957 | word-break: normal; 958 | word-break: keep-all; 959 | border-collapse: collapse; 960 | } 961 | .tsd-panel table th { 962 | font-weight: bold; 963 | } 964 | .tsd-panel table th, 965 | .tsd-panel table td { 966 | padding: 6px 13px; 967 | border: 1px solid var(--color-panel-divider); 968 | } 969 | .tsd-panel table tr { 970 | background: var(--color-background); 971 | } 972 | .tsd-panel table tr:nth-child(even) { 973 | background: var(--color-secondary-background); 974 | } 975 | 976 | .tsd-panel-group { 977 | margin: 60px 0; 978 | } 979 | .tsd-panel-group > h1, 980 | .tsd-panel-group > h2, 981 | .tsd-panel-group > h3 { 982 | padding-left: 20px; 983 | padding-right: 20px; 984 | } 985 | 986 | #tsd-search { 987 | transition: background-color 0.2s; 988 | } 989 | #tsd-search .title { 990 | position: relative; 991 | z-index: 2; 992 | } 993 | #tsd-search .field { 994 | position: absolute; 995 | left: 0; 996 | top: 0; 997 | right: 40px; 998 | height: 40px; 999 | } 1000 | #tsd-search .field input { 1001 | box-sizing: border-box; 1002 | position: relative; 1003 | top: -50px; 1004 | z-index: 1; 1005 | width: 100%; 1006 | padding: 0 10px; 1007 | opacity: 0; 1008 | outline: 0; 1009 | border: 0; 1010 | background: transparent; 1011 | color: var(--color-text); 1012 | } 1013 | #tsd-search .field label { 1014 | position: absolute; 1015 | overflow: hidden; 1016 | right: -40px; 1017 | } 1018 | #tsd-search .field input, 1019 | #tsd-search .title { 1020 | transition: opacity 0.2s; 1021 | } 1022 | #tsd-search .results { 1023 | position: absolute; 1024 | visibility: hidden; 1025 | top: 40px; 1026 | width: 100%; 1027 | margin: 0; 1028 | padding: 0; 1029 | list-style: none; 1030 | box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); 1031 | } 1032 | #tsd-search .results li { 1033 | padding: 0 10px; 1034 | background-color: var(--color-background); 1035 | } 1036 | #tsd-search .results li:nth-child(even) { 1037 | background-color: var(--color-panel); 1038 | } 1039 | #tsd-search .results li.state { 1040 | display: none; 1041 | } 1042 | #tsd-search .results li.current, 1043 | #tsd-search .results li:hover { 1044 | background-color: var(--color-panel-divider); 1045 | } 1046 | #tsd-search .results a { 1047 | display: block; 1048 | } 1049 | #tsd-search .results a:before { 1050 | top: 10px; 1051 | } 1052 | #tsd-search .results span.parent { 1053 | color: var(--color-text-aside); 1054 | font-weight: normal; 1055 | } 1056 | #tsd-search.has-focus { 1057 | background-color: var(--color-panel-divider); 1058 | } 1059 | #tsd-search.has-focus .field input { 1060 | top: 0; 1061 | opacity: 1; 1062 | } 1063 | #tsd-search.has-focus .title { 1064 | z-index: 0; 1065 | opacity: 0; 1066 | } 1067 | #tsd-search.has-focus .results { 1068 | visibility: visible; 1069 | } 1070 | #tsd-search.loading .results li.state.loading { 1071 | display: block; 1072 | } 1073 | #tsd-search.failure .results li.state.failure { 1074 | display: block; 1075 | } 1076 | 1077 | .tsd-signature { 1078 | margin: 0 0 1em 0; 1079 | padding: 10px; 1080 | border: 1px solid var(--color-panel-divider); 1081 | font-family: Menlo, Monaco, Consolas, "Courier New", monospace; 1082 | font-size: 14px; 1083 | overflow-x: auto; 1084 | } 1085 | .tsd-signature.tsd-kind-icon { 1086 | padding-left: 30px; 1087 | } 1088 | .tsd-signature.tsd-kind-icon:before { 1089 | top: 10px; 1090 | left: 10px; 1091 | } 1092 | .tsd-panel > .tsd-signature { 1093 | margin-left: -20px; 1094 | margin-right: -20px; 1095 | border-width: 1px 0; 1096 | } 1097 | .tsd-panel > .tsd-signature.tsd-kind-icon { 1098 | padding-left: 40px; 1099 | } 1100 | .tsd-panel > .tsd-signature.tsd-kind-icon:before { 1101 | left: 20px; 1102 | } 1103 | 1104 | .tsd-signature-symbol { 1105 | color: var(--color-text-aside); 1106 | font-weight: normal; 1107 | } 1108 | 1109 | .tsd-signature-type { 1110 | font-style: italic; 1111 | font-weight: normal; 1112 | } 1113 | 1114 | .tsd-signatures { 1115 | padding: 0; 1116 | margin: 0 0 1em 0; 1117 | border: 1px solid var(--color-panel-divider); 1118 | } 1119 | .tsd-signatures .tsd-signature { 1120 | margin: 0; 1121 | border-width: 1px 0 0 0; 1122 | transition: background-color 0.1s; 1123 | } 1124 | .tsd-signatures .tsd-signature:first-child { 1125 | border-top-width: 0; 1126 | } 1127 | .tsd-signatures .tsd-signature.current { 1128 | background-color: var(--color-panel-divider); 1129 | } 1130 | .tsd-signatures.active > .tsd-signature { 1131 | cursor: pointer; 1132 | } 1133 | .tsd-panel > .tsd-signatures { 1134 | margin-left: -20px; 1135 | margin-right: -20px; 1136 | border-width: 1px 0; 1137 | } 1138 | .tsd-panel > .tsd-signatures .tsd-signature.tsd-kind-icon { 1139 | padding-left: 40px; 1140 | } 1141 | .tsd-panel > .tsd-signatures .tsd-signature.tsd-kind-icon:before { 1142 | left: 20px; 1143 | } 1144 | .tsd-panel > a.anchor + .tsd-signatures { 1145 | border-top-width: 0; 1146 | margin-top: -20px; 1147 | } 1148 | 1149 | ul.tsd-descriptions { 1150 | position: relative; 1151 | overflow: hidden; 1152 | padding: 0; 1153 | list-style: none; 1154 | } 1155 | ul.tsd-descriptions.active > .tsd-description { 1156 | display: none; 1157 | } 1158 | ul.tsd-descriptions.active > .tsd-description.current { 1159 | display: block; 1160 | } 1161 | ul.tsd-descriptions.active > .tsd-description.fade-in { 1162 | animation: fade-in-delayed 0.3s; 1163 | } 1164 | ul.tsd-descriptions.active > .tsd-description.fade-out { 1165 | animation: fade-out-delayed 0.3s; 1166 | position: absolute; 1167 | display: block; 1168 | top: 0; 1169 | left: 0; 1170 | right: 0; 1171 | opacity: 0; 1172 | visibility: hidden; 1173 | } 1174 | ul.tsd-descriptions h4, 1175 | ul.tsd-descriptions .tsd-index-panel h3, 1176 | .tsd-index-panel ul.tsd-descriptions h3 { 1177 | font-size: 16px; 1178 | margin: 1em 0 0.5em 0; 1179 | } 1180 | 1181 | ul.tsd-parameters, 1182 | ul.tsd-type-parameters { 1183 | list-style: square; 1184 | margin: 0; 1185 | padding-left: 20px; 1186 | } 1187 | ul.tsd-parameters > li.tsd-parameter-signature, 1188 | ul.tsd-type-parameters > li.tsd-parameter-signature { 1189 | list-style: none; 1190 | margin-left: -20px; 1191 | } 1192 | ul.tsd-parameters h5, 1193 | ul.tsd-type-parameters h5 { 1194 | font-size: 16px; 1195 | margin: 1em 0 0.5em 0; 1196 | } 1197 | ul.tsd-parameters .tsd-comment, 1198 | ul.tsd-type-parameters .tsd-comment { 1199 | margin-top: -0.5em; 1200 | } 1201 | 1202 | .tsd-sources { 1203 | font-size: 14px; 1204 | color: var(--color-text-aside); 1205 | margin: 0 0 1em 0; 1206 | } 1207 | .tsd-sources a { 1208 | color: var(--color-text-aside); 1209 | text-decoration: underline; 1210 | } 1211 | .tsd-sources ul, 1212 | .tsd-sources p { 1213 | margin: 0 !important; 1214 | } 1215 | .tsd-sources ul { 1216 | list-style: none; 1217 | padding: 0; 1218 | } 1219 | 1220 | .tsd-page-toolbar { 1221 | position: fixed; 1222 | z-index: 1; 1223 | top: 0; 1224 | left: 0; 1225 | width: 100%; 1226 | height: 40px; 1227 | color: var(--color-toolbar-text); 1228 | background: var(--color-toolbar); 1229 | border-bottom: 1px solid var(--color-panel-divider); 1230 | transition: transform 0.3s linear; 1231 | } 1232 | .tsd-page-toolbar a { 1233 | color: var(--color-toolbar-text); 1234 | text-decoration: none; 1235 | } 1236 | .tsd-page-toolbar a.title { 1237 | font-weight: bold; 1238 | } 1239 | .tsd-page-toolbar a.title:hover { 1240 | text-decoration: underline; 1241 | } 1242 | .tsd-page-toolbar .table-wrap { 1243 | display: table; 1244 | width: 100%; 1245 | height: 40px; 1246 | } 1247 | .tsd-page-toolbar .table-cell { 1248 | display: table-cell; 1249 | position: relative; 1250 | white-space: nowrap; 1251 | line-height: 40px; 1252 | } 1253 | .tsd-page-toolbar .table-cell:first-child { 1254 | width: 100%; 1255 | } 1256 | 1257 | .tsd-page-toolbar--hide { 1258 | transform: translateY(-100%); 1259 | } 1260 | 1261 | .tsd-select .tsd-select-list li:before, 1262 | .tsd-select .tsd-select-label:before, 1263 | .tsd-widget:before { 1264 | content: ""; 1265 | display: inline-block; 1266 | width: 40px; 1267 | height: 40px; 1268 | margin: 0 -8px 0 0; 1269 | background-image: url(./widgets.png); 1270 | background-repeat: no-repeat; 1271 | text-indent: -1024px; 1272 | vertical-align: bottom; 1273 | filter: var(--icon-filter); 1274 | } 1275 | @media (-webkit-min-device-pixel-ratio: 1.5), (min-resolution: 144dpi) { 1276 | .tsd-select .tsd-select-list li:before, 1277 | .tsd-select .tsd-select-label:before, 1278 | .tsd-widget:before { 1279 | background-image: url(./widgets@2x.png); 1280 | background-size: 320px 40px; 1281 | } 1282 | } 1283 | 1284 | .tsd-widget { 1285 | display: inline-block; 1286 | overflow: hidden; 1287 | opacity: 0.8; 1288 | height: 40px; 1289 | transition: opacity 0.1s, background-color 0.2s; 1290 | vertical-align: bottom; 1291 | cursor: pointer; 1292 | } 1293 | .tsd-widget:hover { 1294 | opacity: 0.9; 1295 | } 1296 | .tsd-widget.active { 1297 | opacity: 1; 1298 | background-color: var(--color-panel-divider); 1299 | } 1300 | .tsd-widget.no-caption { 1301 | width: 40px; 1302 | } 1303 | .tsd-widget.no-caption:before { 1304 | margin: 0; 1305 | } 1306 | .tsd-widget.search:before { 1307 | background-position: 0 0; 1308 | } 1309 | .tsd-widget.menu:before { 1310 | background-position: -40px 0; 1311 | } 1312 | .tsd-widget.options:before { 1313 | background-position: -80px 0; 1314 | } 1315 | .tsd-widget.options, 1316 | .tsd-widget.menu { 1317 | display: none; 1318 | } 1319 | @media (max-width: 900px) { 1320 | .tsd-widget.options, 1321 | .tsd-widget.menu { 1322 | display: inline-block; 1323 | } 1324 | } 1325 | input[type="checkbox"] + .tsd-widget:before { 1326 | background-position: -120px 0; 1327 | } 1328 | input[type="checkbox"]:checked + .tsd-widget:before { 1329 | background-position: -160px 0; 1330 | } 1331 | 1332 | .tsd-select { 1333 | position: relative; 1334 | display: inline-block; 1335 | height: 40px; 1336 | transition: opacity 0.1s, background-color 0.2s; 1337 | vertical-align: bottom; 1338 | cursor: pointer; 1339 | } 1340 | .tsd-select .tsd-select-label { 1341 | opacity: 0.6; 1342 | transition: opacity 0.2s; 1343 | } 1344 | .tsd-select .tsd-select-label:before { 1345 | background-position: -240px 0; 1346 | } 1347 | .tsd-select.active .tsd-select-label { 1348 | opacity: 0.8; 1349 | } 1350 | .tsd-select.active .tsd-select-list { 1351 | visibility: visible; 1352 | opacity: 1; 1353 | transition-delay: 0s; 1354 | } 1355 | .tsd-select .tsd-select-list { 1356 | position: absolute; 1357 | visibility: hidden; 1358 | top: 40px; 1359 | left: 0; 1360 | margin: 0; 1361 | padding: 0; 1362 | opacity: 0; 1363 | list-style: none; 1364 | box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); 1365 | transition: visibility 0s 0.2s, opacity 0.2s; 1366 | } 1367 | .tsd-select .tsd-select-list li { 1368 | padding: 0 20px 0 0; 1369 | background-color: var(--color-background); 1370 | } 1371 | .tsd-select .tsd-select-list li:before { 1372 | background-position: 40px 0; 1373 | } 1374 | .tsd-select .tsd-select-list li:nth-child(even) { 1375 | background-color: var(--color-panel); 1376 | } 1377 | .tsd-select .tsd-select-list li:hover { 1378 | background-color: var(--color-panel-divider); 1379 | } 1380 | .tsd-select .tsd-select-list li.selected:before { 1381 | background-position: -200px 0; 1382 | } 1383 | @media (max-width: 900px) { 1384 | .tsd-select .tsd-select-list { 1385 | top: 0; 1386 | left: auto; 1387 | right: 100%; 1388 | margin-right: -5px; 1389 | } 1390 | .tsd-select .tsd-select-label:before { 1391 | background-position: -280px 0; 1392 | } 1393 | } 1394 | 1395 | img { 1396 | max-width: 100%; 1397 | } 1398 | 1399 | .tsd-anchor-icon { 1400 | margin-left: 10px; 1401 | vertical-align: middle; 1402 | color: var(--color-text); 1403 | } 1404 | 1405 | .tsd-anchor-icon svg { 1406 | width: 1em; 1407 | height: 1em; 1408 | visibility: hidden; 1409 | } 1410 | 1411 | .tsd-anchor-link:hover > .tsd-anchor-icon svg { 1412 | visibility: visible; 1413 | } 1414 | -------------------------------------------------------------------------------- /docs/v1/assets/widgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/supabase/functions-js/749ff0596f5d043ff69e1b775d65d863639201ac/docs/v1/assets/widgets.png -------------------------------------------------------------------------------- /docs/v1/assets/widgets@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/supabase/functions-js/749ff0596f5d043ff69e1b775d65d863639201ac/docs/v1/assets/widgets@2x.png -------------------------------------------------------------------------------- /docs/v1/classes/FunctionsClient.html: -------------------------------------------------------------------------------- 1 | FunctionsClient | @supabase/functions-js
Options
All
  • Public
  • Public/Protected
  • All
Menu

Hierarchy

  • FunctionsClient

Index

Constructors

Properties

Methods

Constructors

  • new FunctionsClient(url: string, __namedParameters?: { customFetch?: (input: RequestInfo, init?: RequestInit) => Promise<Response>; headers?: Record<string, string> }): FunctionsClient
  • Parameters

    • url: string
    • __namedParameters: { customFetch?: (input: RequestInfo, init?: RequestInit) => Promise<Response>; headers?: Record<string, string> } = {}
      • Optional customFetch?: (input: RequestInfo, init?: RequestInit) => Promise<Response>
          • (input: RequestInfo, init?: RequestInit): Promise<Response>
          • Parameters

            • input: RequestInfo
            • Optional init: RequestInit

            Returns Promise<Response>

      • Optional headers?: Record<string, string>

    Returns FunctionsClient

Properties

fetch: (input: RequestInfo, init?: RequestInit) => Promise<Response>

Type declaration

    • (input: RequestInfo, init?: RequestInit): Promise<Response>
    • Parameters

      • input: RequestInfo
      • Optional init: RequestInit

      Returns Promise<Response>

headers: Record<string, string>
url: string

Methods

  • invoke<T>(functionName: string, invokeOptions?: FunctionInvokeOptions): Promise<{ data: T; error: null } | { data: null; error: Error }>
  • 2 |

    Invokes a function

    3 |

    Type parameters

    • T = any

    Parameters

    • functionName: string
      4 |

      the name of the function to invoke

      5 |
    • Optional invokeOptions: FunctionInvokeOptions
      6 |

      object with the following properties 7 | headers: object representing the headers to send with the request 8 | body: the body of the request 9 | responseType: how the response should be parsed. The default is json

      10 |

    Returns Promise<{ data: T; error: null } | { data: null; error: Error }>

  • setAuth(token: string): void
  • 11 |

    Updates the authorization header

    12 |
    params

    token - the new jwt token sent in the authorisation header

    13 |

    Parameters

    • token: string

    Returns void

Generated using TypeDoc

-------------------------------------------------------------------------------- /docs/v1/index.html: -------------------------------------------------------------------------------- 1 | @supabase/functions-js
Options
All
  • Public
  • Public/Protected
  • All
Menu

@supabase/functions-js

2 | 3 |

functions-js

4 |
5 |

JS Client library to interact with Supabase Functions.

6 |

Generated using TypeDoc

-------------------------------------------------------------------------------- /docs/v1/modules.html: -------------------------------------------------------------------------------- 1 | @supabase/functions-js
Options
All
  • Public
  • Public/Protected
  • All
Menu

@supabase/functions-js

Generated using TypeDoc

-------------------------------------------------------------------------------- /docs/v1/spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 0, 3 | "name": "@supabase/functions-js", 4 | "kind": 1, 5 | "kindString": "Project", 6 | "flags": {}, 7 | "originalName": "", 8 | "children": [ 9 | { 10 | "id": 1, 11 | "name": "FunctionsClient", 12 | "kind": 128, 13 | "kindString": "Class", 14 | "flags": {}, 15 | "children": [ 16 | { 17 | "id": 2, 18 | "name": "constructor", 19 | "kind": 512, 20 | "kindString": "Constructor", 21 | "flags": {}, 22 | "sources": [ 23 | { 24 | "fileName": "src/index.ts", 25 | "line": 9, 26 | "character": 2 27 | } 28 | ], 29 | "signatures": [ 30 | { 31 | "id": 3, 32 | "name": "new FunctionsClient", 33 | "kind": 16384, 34 | "kindString": "Constructor signature", 35 | "flags": {}, 36 | "parameters": [ 37 | { 38 | "id": 4, 39 | "name": "url", 40 | "kind": 32768, 41 | "kindString": "Parameter", 42 | "flags": {}, 43 | "type": { 44 | "type": "intrinsic", 45 | "name": "string" 46 | } 47 | }, 48 | { 49 | "id": 5, 50 | "name": "__namedParameters", 51 | "kind": 32768, 52 | "kindString": "Parameter", 53 | "flags": {}, 54 | "type": { 55 | "type": "reflection", 56 | "declaration": { 57 | "id": 6, 58 | "name": "__type", 59 | "kind": 65536, 60 | "kindString": "Type literal", 61 | "flags": {}, 62 | "children": [ 63 | { 64 | "id": 8, 65 | "name": "customFetch", 66 | "kind": 1024, 67 | "kindString": "Property", 68 | "flags": { 69 | "isOptional": true 70 | }, 71 | "sources": [ 72 | { 73 | "fileName": "src/index.ts", 74 | "line": 16, 75 | "character": 6 76 | } 77 | ], 78 | "type": { 79 | "type": "reflection", 80 | "declaration": { 81 | "id": 9, 82 | "name": "__type", 83 | "kind": 65536, 84 | "kindString": "Type literal", 85 | "flags": {}, 86 | "signatures": [ 87 | { 88 | "id": 10, 89 | "name": "__type", 90 | "kind": 4096, 91 | "kindString": "Call signature", 92 | "flags": {}, 93 | "parameters": [ 94 | { 95 | "id": 11, 96 | "name": "input", 97 | "kind": 32768, 98 | "kindString": "Parameter", 99 | "flags": {}, 100 | "type": { 101 | "type": "reference", 102 | "qualifiedName": "RequestInfo", 103 | "package": "typescript", 104 | "name": "RequestInfo" 105 | } 106 | }, 107 | { 108 | "id": 12, 109 | "name": "init", 110 | "kind": 32768, 111 | "kindString": "Parameter", 112 | "flags": { 113 | "isOptional": true 114 | }, 115 | "type": { 116 | "type": "reference", 117 | "qualifiedName": "RequestInit", 118 | "package": "typescript", 119 | "name": "RequestInit" 120 | } 121 | } 122 | ], 123 | "type": { 124 | "type": "reference", 125 | "typeArguments": [ 126 | { 127 | "type": "reference", 128 | "qualifiedName": "Response", 129 | "package": "typescript", 130 | "name": "Response" 131 | } 132 | ], 133 | "qualifiedName": "Promise", 134 | "package": "typescript", 135 | "name": "Promise" 136 | } 137 | } 138 | ] 139 | } 140 | } 141 | }, 142 | { 143 | "id": 7, 144 | "name": "headers", 145 | "kind": 1024, 146 | "kindString": "Property", 147 | "flags": { 148 | "isOptional": true 149 | }, 150 | "sources": [ 151 | { 152 | "fileName": "src/index.ts", 153 | "line": 15, 154 | "character": 6 155 | } 156 | ], 157 | "type": { 158 | "type": "reference", 159 | "typeArguments": [ 160 | { 161 | "type": "intrinsic", 162 | "name": "string" 163 | }, 164 | { 165 | "type": "intrinsic", 166 | "name": "string" 167 | } 168 | ], 169 | "qualifiedName": "Record", 170 | "package": "typescript", 171 | "name": "Record" 172 | } 173 | } 174 | ], 175 | "groups": [ 176 | { 177 | "title": "Properties", 178 | "kind": 1024, 179 | "children": [ 180 | 8, 181 | 7 182 | ] 183 | } 184 | ] 185 | } 186 | }, 187 | "defaultValue": "{}" 188 | } 189 | ], 190 | "type": { 191 | "type": "reference", 192 | "id": 1, 193 | "name": "FunctionsClient" 194 | } 195 | } 196 | ] 197 | }, 198 | { 199 | "id": 15, 200 | "name": "fetch", 201 | "kind": 1024, 202 | "kindString": "Property", 203 | "flags": { 204 | "isProtected": true 205 | }, 206 | "sources": [ 207 | { 208 | "fileName": "src/index.ts", 209 | "line": 7, 210 | "character": 12 211 | } 212 | ], 213 | "type": { 214 | "type": "reflection", 215 | "declaration": { 216 | "id": 16, 217 | "name": "__type", 218 | "kind": 65536, 219 | "kindString": "Type literal", 220 | "flags": {}, 221 | "signatures": [ 222 | { 223 | "id": 17, 224 | "name": "__type", 225 | "kind": 4096, 226 | "kindString": "Call signature", 227 | "flags": {}, 228 | "parameters": [ 229 | { 230 | "id": 18, 231 | "name": "input", 232 | "kind": 32768, 233 | "kindString": "Parameter", 234 | "flags": {}, 235 | "type": { 236 | "type": "reference", 237 | "qualifiedName": "RequestInfo", 238 | "package": "typescript", 239 | "name": "RequestInfo" 240 | } 241 | }, 242 | { 243 | "id": 19, 244 | "name": "init", 245 | "kind": 32768, 246 | "kindString": "Parameter", 247 | "flags": { 248 | "isOptional": true 249 | }, 250 | "type": { 251 | "type": "reference", 252 | "qualifiedName": "RequestInit", 253 | "package": "typescript", 254 | "name": "RequestInit" 255 | } 256 | } 257 | ], 258 | "type": { 259 | "type": "reference", 260 | "typeArguments": [ 261 | { 262 | "type": "reference", 263 | "qualifiedName": "Response", 264 | "package": "typescript", 265 | "name": "Response" 266 | } 267 | ], 268 | "qualifiedName": "Promise", 269 | "package": "typescript", 270 | "name": "Promise" 271 | } 272 | } 273 | ] 274 | } 275 | } 276 | }, 277 | { 278 | "id": 14, 279 | "name": "headers", 280 | "kind": 1024, 281 | "kindString": "Property", 282 | "flags": { 283 | "isProtected": true 284 | }, 285 | "sources": [ 286 | { 287 | "fileName": "src/index.ts", 288 | "line": 6, 289 | "character": 12 290 | } 291 | ], 292 | "type": { 293 | "type": "reference", 294 | "typeArguments": [ 295 | { 296 | "type": "intrinsic", 297 | "name": "string" 298 | }, 299 | { 300 | "type": "intrinsic", 301 | "name": "string" 302 | } 303 | ], 304 | "qualifiedName": "Record", 305 | "package": "typescript", 306 | "name": "Record" 307 | } 308 | }, 309 | { 310 | "id": 13, 311 | "name": "url", 312 | "kind": 1024, 313 | "kindString": "Property", 314 | "flags": { 315 | "isProtected": true 316 | }, 317 | "sources": [ 318 | { 319 | "fileName": "src/index.ts", 320 | "line": 5, 321 | "character": 12 322 | } 323 | ], 324 | "type": { 325 | "type": "intrinsic", 326 | "name": "string" 327 | } 328 | }, 329 | { 330 | "id": 23, 331 | "name": "invoke", 332 | "kind": 2048, 333 | "kindString": "Method", 334 | "flags": {}, 335 | "sources": [ 336 | { 337 | "fileName": "src/index.ts", 338 | "line": 40, 339 | "character": 8 340 | } 341 | ], 342 | "signatures": [ 343 | { 344 | "id": 24, 345 | "name": "invoke", 346 | "kind": 4096, 347 | "kindString": "Call signature", 348 | "flags": {}, 349 | "comment": { 350 | "shortText": "Invokes a function" 351 | }, 352 | "typeParameter": [ 353 | { 354 | "id": 25, 355 | "name": "T", 356 | "kind": 131072, 357 | "kindString": "Type parameter", 358 | "flags": {}, 359 | "default": { 360 | "type": "intrinsic", 361 | "name": "any" 362 | } 363 | } 364 | ], 365 | "parameters": [ 366 | { 367 | "id": 26, 368 | "name": "functionName", 369 | "kind": 32768, 370 | "kindString": "Parameter", 371 | "flags": {}, 372 | "comment": { 373 | "shortText": "the name of the function to invoke" 374 | }, 375 | "type": { 376 | "type": "intrinsic", 377 | "name": "string" 378 | } 379 | }, 380 | { 381 | "id": 27, 382 | "name": "invokeOptions", 383 | "kind": 32768, 384 | "kindString": "Parameter", 385 | "flags": { 386 | "isOptional": true 387 | }, 388 | "comment": { 389 | "shortText": "object with the following properties\n`headers`: object representing the headers to send with the request\n`body`: the body of the request\n`responseType`: how the response should be parsed. The default is `json`\n" 390 | }, 391 | "type": { 392 | "type": "reference", 393 | "name": "FunctionInvokeOptions" 394 | } 395 | } 396 | ], 397 | "type": { 398 | "type": "reference", 399 | "typeArguments": [ 400 | { 401 | "type": "union", 402 | "types": [ 403 | { 404 | "type": "reflection", 405 | "declaration": { 406 | "id": 28, 407 | "name": "__type", 408 | "kind": 65536, 409 | "kindString": "Type literal", 410 | "flags": {}, 411 | "children": [ 412 | { 413 | "id": 29, 414 | "name": "data", 415 | "kind": 1024, 416 | "kindString": "Property", 417 | "flags": {}, 418 | "sources": [ 419 | { 420 | "fileName": "src/index.ts", 421 | "line": 43, 422 | "character": 15 423 | } 424 | ], 425 | "type": { 426 | "type": "reference", 427 | "id": 25, 428 | "name": "T" 429 | } 430 | }, 431 | { 432 | "id": 30, 433 | "name": "error", 434 | "kind": 1024, 435 | "kindString": "Property", 436 | "flags": {}, 437 | "sources": [ 438 | { 439 | "fileName": "src/index.ts", 440 | "line": 43, 441 | "character": 24 442 | } 443 | ], 444 | "type": { 445 | "type": "literal", 446 | "value": null 447 | } 448 | } 449 | ], 450 | "groups": [ 451 | { 452 | "title": "Properties", 453 | "kind": 1024, 454 | "children": [ 455 | 29, 456 | 30 457 | ] 458 | } 459 | ] 460 | } 461 | }, 462 | { 463 | "type": "reflection", 464 | "declaration": { 465 | "id": 31, 466 | "name": "__type", 467 | "kind": 65536, 468 | "kindString": "Type literal", 469 | "flags": {}, 470 | "children": [ 471 | { 472 | "id": 32, 473 | "name": "data", 474 | "kind": 1024, 475 | "kindString": "Property", 476 | "flags": {}, 477 | "sources": [ 478 | { 479 | "fileName": "src/index.ts", 480 | "line": 43, 481 | "character": 42 482 | } 483 | ], 484 | "type": { 485 | "type": "literal", 486 | "value": null 487 | } 488 | }, 489 | { 490 | "id": 33, 491 | "name": "error", 492 | "kind": 1024, 493 | "kindString": "Property", 494 | "flags": {}, 495 | "sources": [ 496 | { 497 | "fileName": "src/index.ts", 498 | "line": 43, 499 | "character": 54 500 | } 501 | ], 502 | "type": { 503 | "type": "reference", 504 | "qualifiedName": "Error", 505 | "package": "typescript", 506 | "name": "Error" 507 | } 508 | } 509 | ], 510 | "groups": [ 511 | { 512 | "title": "Properties", 513 | "kind": 1024, 514 | "children": [ 515 | 32, 516 | 33 517 | ] 518 | } 519 | ] 520 | } 521 | } 522 | ] 523 | } 524 | ], 525 | "qualifiedName": "Promise", 526 | "package": "typescript", 527 | "name": "Promise" 528 | } 529 | } 530 | ] 531 | }, 532 | { 533 | "id": 20, 534 | "name": "setAuth", 535 | "kind": 2048, 536 | "kindString": "Method", 537 | "flags": {}, 538 | "sources": [ 539 | { 540 | "fileName": "src/index.ts", 541 | "line": 28, 542 | "character": 2 543 | } 544 | ], 545 | "signatures": [ 546 | { 547 | "id": 21, 548 | "name": "setAuth", 549 | "kind": 4096, 550 | "kindString": "Call signature", 551 | "flags": {}, 552 | "comment": { 553 | "shortText": "Updates the authorization header", 554 | "tags": [ 555 | { 556 | "tag": "params", 557 | "text": "token - the new jwt token sent in the authorisation header\n" 558 | } 559 | ] 560 | }, 561 | "parameters": [ 562 | { 563 | "id": 22, 564 | "name": "token", 565 | "kind": 32768, 566 | "kindString": "Parameter", 567 | "flags": {}, 568 | "type": { 569 | "type": "intrinsic", 570 | "name": "string" 571 | } 572 | } 573 | ], 574 | "type": { 575 | "type": "intrinsic", 576 | "name": "void" 577 | } 578 | } 579 | ] 580 | } 581 | ], 582 | "groups": [ 583 | { 584 | "title": "Constructors", 585 | "kind": 512, 586 | "children": [ 587 | 2 588 | ] 589 | }, 590 | { 591 | "title": "Properties", 592 | "kind": 1024, 593 | "children": [ 594 | 15, 595 | 14, 596 | 13 597 | ] 598 | }, 599 | { 600 | "title": "Methods", 601 | "kind": 2048, 602 | "children": [ 603 | 23, 604 | 20 605 | ] 606 | } 607 | ], 608 | "sources": [ 609 | { 610 | "fileName": "src/index.ts", 611 | "line": 4, 612 | "character": 13 613 | } 614 | ] 615 | } 616 | ], 617 | "groups": [ 618 | { 619 | "title": "Classes", 620 | "kind": 128, 621 | "children": [ 622 | 1 623 | ] 624 | } 625 | ], 626 | "sources": [ 627 | { 628 | "fileName": "src/index.ts", 629 | "line": 1, 630 | "character": 0 631 | } 632 | ] 633 | } -------------------------------------------------------------------------------- /jest.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from '@jest/types' 2 | 3 | const config: Config.InitialOptions = { 4 | preset: 'ts-jest', 5 | transform: { 6 | '^.+\\.ts?$': 'ts-jest', 7 | }, 8 | moduleFileExtensions: ['ts', 'js', 'cjs', 'json', 'node'], 9 | setupFilesAfterEnv: ['./test/utils/jest-custom-reporter.ts'], 10 | testTimeout: 60000, 11 | collectCoverageFrom: [ 12 | '!**/node_modules/**', 13 | 'src/**/*.{ts,tsx}', 14 | '!src/version.ts', 15 | '!src/index.ts', 16 | '!**/*.d.ts', 17 | ], 18 | coverageProvider: 'v8', 19 | coverageThreshold: { 20 | global: { 21 | branches: 0, 22 | functions: 0, 23 | lines: 0, 24 | statements: 0, 25 | }, 26 | }, 27 | } 28 | export default config 29 | -------------------------------------------------------------------------------- /jsr.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@supabase/functions-js", 3 | "version": "0.0.0-automated", 4 | "exports": { 5 | ".": "./src/index.ts", 6 | "./edge-runtime.d.ts": "./src/edge-runtime.d.ts" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@supabase/functions-js", 3 | "version": "0.0.0-automated", 4 | "description": "JS Client library to interact with Supabase Functions.", 5 | "main": "dist/main/index.js", 6 | "module": "dist/module/index.js", 7 | "types": "dist/module/index.d.ts", 8 | "sideEffects": false, 9 | "scripts": { 10 | "clean": "rimraf dist docs/v2", 11 | "format": "prettier --write \"{src,test}/**/*.ts\"", 12 | "build": "run-s clean format build:*", 13 | "build:main": "tsc -p tsconfig.json", 14 | "build:module": "tsc -p tsconfig.module.json", 15 | "docs": "typedoc src/index.ts --out docs/v2", 16 | "docs:json": "typedoc --json docs/v2/spec.json --excludeExternals src/index.ts", 17 | "test": "jest", 18 | "test:coverage": "jest --coverage" 19 | }, 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/supabase/functions-js.git" 23 | }, 24 | "keywords": [ 25 | "functions", 26 | "supabase" 27 | ], 28 | "author": "Supabase", 29 | "files": [ 30 | "dist", 31 | "src" 32 | ], 33 | "license": "MIT", 34 | "bugs": { 35 | "url": "https://github.com/supabase/functions-js/issues" 36 | }, 37 | "homepage": "https://github.com/supabase/functions-js#readme", 38 | "dependencies": { 39 | "@supabase/node-fetch": "^2.6.14" 40 | }, 41 | "devDependencies": { 42 | "@sebbo2002/semantic-release-jsr": "^1.0.0", 43 | "@types/jest": "^28.1.0", 44 | "@types/jsonwebtoken": "^8.5.8", 45 | "@types/node": "^18.7.0", 46 | "genversion": "^3.0.2", 47 | "jest": "^28.1.0", 48 | "jsonwebtoken": "^9.0.0", 49 | "nanoid": "^3.3.1", 50 | "npm-run-all": "^4.1.5", 51 | "openai": "^4.52.5", 52 | "prettier": "^2.6.0", 53 | "rimraf": "^3.0.2", 54 | "semantic-release-plugin-update-version-in-files": "^1.1.0", 55 | "testcontainers": "^8.5.1", 56 | "ts-jest": "^28.0.0", 57 | "ts-node": "^10.9.0", 58 | "ts-test-decorators": "^0.0.6", 59 | "typedoc": "^0.22.13", 60 | "typescript": "^4.6.2" 61 | }, 62 | "publishConfig": { 63 | "access": "public" 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /src/FunctionsClient.ts: -------------------------------------------------------------------------------- 1 | import { resolveFetch } from './helper' 2 | import { 3 | Fetch, 4 | FunctionsFetchError, 5 | FunctionsHttpError, 6 | FunctionsRelayError, 7 | FunctionsResponse, 8 | FunctionInvokeOptions, 9 | FunctionRegion, 10 | } from './types' 11 | 12 | export class FunctionsClient { 13 | protected url: string 14 | protected headers: Record 15 | protected region: FunctionRegion 16 | protected fetch: Fetch 17 | 18 | constructor( 19 | url: string, 20 | { 21 | headers = {}, 22 | customFetch, 23 | region = FunctionRegion.Any, 24 | }: { 25 | headers?: Record 26 | customFetch?: Fetch 27 | region?: FunctionRegion 28 | } = {} 29 | ) { 30 | this.url = url 31 | this.headers = headers 32 | this.region = region 33 | this.fetch = resolveFetch(customFetch) 34 | } 35 | 36 | /** 37 | * Updates the authorization header 38 | * @param token - the new jwt token sent in the authorisation header 39 | */ 40 | setAuth(token: string) { 41 | this.headers.Authorization = `Bearer ${token}` 42 | } 43 | 44 | /** 45 | * Invokes a function 46 | * @param functionName - The name of the Function to invoke. 47 | * @param options - Options for invoking the Function. 48 | */ 49 | async invoke( 50 | functionName: string, 51 | options: FunctionInvokeOptions = {} 52 | ): Promise> { 53 | try { 54 | const { headers, method, body: functionArgs } = options 55 | let _headers: Record = {} 56 | let { region } = options 57 | if (!region) { 58 | region = this.region 59 | } 60 | if (region && region !== 'any') { 61 | _headers['x-region'] = region 62 | } 63 | let body: any 64 | if ( 65 | functionArgs && 66 | ((headers && !Object.prototype.hasOwnProperty.call(headers, 'Content-Type')) || !headers) 67 | ) { 68 | if ( 69 | (typeof Blob !== 'undefined' && functionArgs instanceof Blob) || 70 | functionArgs instanceof ArrayBuffer 71 | ) { 72 | // will work for File as File inherits Blob 73 | // also works for ArrayBuffer as it is the same underlying structure as a Blob 74 | _headers['Content-Type'] = 'application/octet-stream' 75 | body = functionArgs 76 | } else if (typeof functionArgs === 'string') { 77 | // plain string 78 | _headers['Content-Type'] = 'text/plain' 79 | body = functionArgs 80 | } else if (typeof FormData !== 'undefined' && functionArgs instanceof FormData) { 81 | // don't set content-type headers 82 | // Request will automatically add the right boundary value 83 | body = functionArgs 84 | } else { 85 | // default, assume this is JSON 86 | _headers['Content-Type'] = 'application/json' 87 | body = JSON.stringify(functionArgs) 88 | } 89 | } 90 | 91 | const response = await this.fetch(`${this.url}/${functionName}`, { 92 | method: method || 'POST', 93 | // headers priority is (high to low): 94 | // 1. invoke-level headers 95 | // 2. client-level headers 96 | // 3. default Content-Type header 97 | headers: { ..._headers, ...this.headers, ...headers }, 98 | body, 99 | }).catch((fetchError) => { 100 | throw new FunctionsFetchError(fetchError) 101 | }) 102 | 103 | const isRelayError = response.headers.get('x-relay-error') 104 | if (isRelayError && isRelayError === 'true') { 105 | throw new FunctionsRelayError(response) 106 | } 107 | 108 | if (!response.ok) { 109 | throw new FunctionsHttpError(response) 110 | } 111 | 112 | let responseType = (response.headers.get('Content-Type') ?? 'text/plain').split(';')[0].trim() 113 | let data: any 114 | if (responseType === 'application/json') { 115 | data = await response.json() 116 | } else if (responseType === 'application/octet-stream') { 117 | data = await response.blob() 118 | } else if (responseType === 'text/event-stream') { 119 | data = response 120 | } else if (responseType === 'multipart/form-data') { 121 | data = await response.formData() 122 | } else { 123 | // default to text 124 | data = await response.text() 125 | } 126 | 127 | return { data, error: null } 128 | } catch (error) { 129 | return { data: null, error } 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/edge-runtime.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace Supabase { 2 | export interface ModelOptions { 3 | /** 4 | * Pool embeddings by taking their mean. Applies only for `gte-small` model 5 | */ 6 | mean_pool?: boolean 7 | 8 | /** 9 | * Normalize the embeddings result. Applies only for `gte-small` model 10 | */ 11 | normalize?: boolean 12 | 13 | /** 14 | * Stream response from model. Applies only for LLMs like `mistral` (default: false) 15 | */ 16 | stream?: boolean 17 | 18 | /** 19 | * Automatically abort the request to the model after specified time (in seconds). Applies only for LLMs like `mistral` (default: 60) 20 | */ 21 | timeout?: number 22 | 23 | /** 24 | * Mode for the inference API host. (default: 'ollama') 25 | */ 26 | mode?: 'ollama' | 'openaicompatible' 27 | signal?: AbortSignal 28 | } 29 | 30 | export class Session { 31 | /** 32 | * Create a new model session using given model 33 | */ 34 | constructor(model: string, sessionOptions?: unknown) 35 | 36 | /** 37 | * Execute the given prompt in model session 38 | */ 39 | run( 40 | prompt: 41 | | string 42 | | Omit, 43 | modelOptions?: ModelOptions 44 | ): unknown 45 | } 46 | 47 | /** 48 | * Provides AI related APIs 49 | */ 50 | export interface Ai { 51 | readonly Session: typeof Session 52 | } 53 | 54 | /** 55 | * Provides AI related APIs 56 | */ 57 | export const ai: Ai 58 | } 59 | 60 | declare namespace EdgeRuntime { 61 | export function waitUntil(promise: Promise): Promise; 62 | } 63 | -------------------------------------------------------------------------------- /src/helper.ts: -------------------------------------------------------------------------------- 1 | import { Fetch } from './types' 2 | 3 | export const resolveFetch = (customFetch?: Fetch): Fetch => { 4 | let _fetch: Fetch 5 | if (customFetch) { 6 | _fetch = customFetch 7 | } else if (typeof fetch === 'undefined') { 8 | _fetch = (...args) => 9 | import('@supabase/node-fetch' as any).then(({ default: fetch }) => fetch(...args)) 10 | } else { 11 | _fetch = fetch 12 | } 13 | return (...args) => _fetch(...args) 14 | } 15 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export { FunctionsClient } from './FunctionsClient' 2 | export { 3 | type FunctionInvokeOptions, 4 | FunctionsError, 5 | FunctionsFetchError, 6 | FunctionsHttpError, 7 | FunctionsRelayError, 8 | FunctionRegion, 9 | type FunctionsResponse, 10 | } from './types' 11 | -------------------------------------------------------------------------------- /src/types.ts: -------------------------------------------------------------------------------- 1 | export type Fetch = typeof fetch 2 | 3 | /** 4 | * Response format 5 | * 6 | */ 7 | export interface FunctionsResponseSuccess { 8 | data: T 9 | error: null 10 | } 11 | export interface FunctionsResponseFailure { 12 | data: null 13 | error: any 14 | } 15 | export type FunctionsResponse = FunctionsResponseSuccess | FunctionsResponseFailure 16 | 17 | export class FunctionsError extends Error { 18 | context: any 19 | constructor(message: string, name = 'FunctionsError', context?: any) { 20 | super(message) 21 | this.name = name 22 | this.context = context 23 | } 24 | } 25 | 26 | export class FunctionsFetchError extends FunctionsError { 27 | constructor(context: any) { 28 | super('Failed to send a request to the Edge Function', 'FunctionsFetchError', context) 29 | } 30 | } 31 | 32 | export class FunctionsRelayError extends FunctionsError { 33 | constructor(context: any) { 34 | super('Relay Error invoking the Edge Function', 'FunctionsRelayError', context) 35 | } 36 | } 37 | 38 | export class FunctionsHttpError extends FunctionsError { 39 | constructor(context: any) { 40 | super('Edge Function returned a non-2xx status code', 'FunctionsHttpError', context) 41 | } 42 | } 43 | // Define the enum for the 'region' property 44 | export enum FunctionRegion { 45 | Any = 'any', 46 | ApNortheast1 = 'ap-northeast-1', 47 | ApNortheast2 = 'ap-northeast-2', 48 | ApSouth1 = 'ap-south-1', 49 | ApSoutheast1 = 'ap-southeast-1', 50 | ApSoutheast2 = 'ap-southeast-2', 51 | CaCentral1 = 'ca-central-1', 52 | EuCentral1 = 'eu-central-1', 53 | EuWest1 = 'eu-west-1', 54 | EuWest2 = 'eu-west-2', 55 | EuWest3 = 'eu-west-3', 56 | SaEast1 = 'sa-east-1', 57 | UsEast1 = 'us-east-1', 58 | UsWest1 = 'us-west-1', 59 | UsWest2 = 'us-west-2', 60 | } 61 | 62 | export type FunctionInvokeOptions = { 63 | /** 64 | * Object representing the headers to send with the request. 65 | * */ 66 | headers?: { [key: string]: string } 67 | /** 68 | * The HTTP verb of the request 69 | */ 70 | method?: 'POST' | 'GET' | 'PUT' | 'PATCH' | 'DELETE' 71 | /** 72 | * The Region to invoke the function in. 73 | */ 74 | region?: FunctionRegion 75 | /** 76 | * The body of the request. 77 | */ 78 | body?: 79 | | File 80 | | Blob 81 | | ArrayBuffer 82 | | FormData 83 | | ReadableStream 84 | | Record 85 | | string 86 | } 87 | -------------------------------------------------------------------------------- /src/version.ts: -------------------------------------------------------------------------------- 1 | export const version = '0.0.0-automated' 2 | -------------------------------------------------------------------------------- /test/functions/hello/index.ts: -------------------------------------------------------------------------------- 1 | import { serve } from 'https://deno.land/std/http/server.ts' 2 | 3 | serve(() => new Response('Hello World')) 4 | -------------------------------------------------------------------------------- /test/functions/hijack/index.ts: -------------------------------------------------------------------------------- 1 | import { serve } from 'https://deno.land/std@0.130.0/http/server.ts' 2 | 3 | serve((req) => { 4 | const p = Deno.upgradeHttp(req) 5 | 6 | // Run this async IIFE concurrently, first packet won't arrive 7 | // until we return HTTP101 response. 8 | ;(async () => { 9 | const [conn, firstPacket] = await p 10 | const decoder = new TextDecoder() 11 | const text = decoder.decode(firstPacket) 12 | console.log(text) 13 | // Hello 14 | const uint8Array = new Uint8Array([72, 101, 108, 108, 111]) 15 | conn.write(uint8Array) 16 | conn.close() 17 | })() 18 | 19 | // HTTP101 - Switching Protocols 20 | return new Response(null, { status: 101 }) 21 | }) 22 | -------------------------------------------------------------------------------- /test/functions/mirror/index.ts: -------------------------------------------------------------------------------- 1 | import { serve } from 'https://deno.land/std/http/server.ts' 2 | 3 | serve(async (request: Request) => { 4 | let body 5 | let contentType = 'application/json' 6 | switch (request.headers.get('response-type')) { 7 | case 'json': { 8 | body = await request.json() 9 | break 10 | } 11 | case 'form': { 12 | const formBody = await request.formData() 13 | body = [] 14 | for (const e of formBody.entries()) { 15 | body.push(e) 16 | } 17 | break 18 | } 19 | case 'blob': { 20 | const data = await request.blob() 21 | body = await data.text() 22 | contentType = 'application/octet-stream' 23 | break 24 | } 25 | case 'arrayBuffer': { 26 | const data = await request.arrayBuffer() 27 | body = new TextDecoder().decode(data || new Uint8Array()) 28 | contentType = 'application/octet-stream' 29 | break 30 | } 31 | default: { 32 | body = await request.text() 33 | contentType = 'text/plain' 34 | break 35 | } 36 | } 37 | const headers = [] 38 | for (const h of request.headers.entries()) { 39 | headers.push(h) 40 | } 41 | const resp = { 42 | url: request.url ?? 'empty', 43 | method: request.method ?? 'empty', 44 | headers: headers ?? 'empty', 45 | body: body ?? 'empty', 46 | } 47 | 48 | let responseData 49 | if (request.headers.get('response-type') === 'blob') { 50 | responseData = new Blob([JSON.stringify(resp)], { type: 'application/json' }) 51 | } else { 52 | responseData = JSON.stringify(resp) 53 | } 54 | return new Response(responseData, { 55 | status: 200, 56 | headers: { 57 | 'content-type': 'application/json', 58 | }, 59 | }) 60 | }) 61 | -------------------------------------------------------------------------------- /test/models/mirrorResponse.ts: -------------------------------------------------------------------------------- 1 | export interface MirrorResponse { 2 | url: string 3 | method: string 4 | headers: string | {} 5 | body: string | {} 6 | } 7 | -------------------------------------------------------------------------------- /test/relay/container.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs' 2 | import { nanoid } from 'nanoid' 3 | // @ts-ignore 4 | import nodeFetch from '@supabase/node-fetch' 5 | import { sign } from 'jsonwebtoken' 6 | import { GenericContainer, Network, StartedTestContainer, Wait } from 'testcontainers' 7 | import { ExecResult } from 'testcontainers/dist/docker/types' 8 | import { attach, log } from '../utils/jest-custom-reporter' 9 | import { ContentType } from 'allure-js-commons' 10 | 11 | /** 12 | * A Relay contains a running relay container that has a unique ID and two promises: 13 | * one for the `deno cache` and one for the `deno run` the required function 14 | */ 15 | export class Relay { 16 | container: StartedTestContainer 17 | id: string 18 | execCache: Promise 19 | execRun: Promise 20 | constructor( 21 | container: StartedTestContainer, 22 | id: string, 23 | execCache: Promise, 24 | execRun: Promise 25 | ) { 26 | this.container = container 27 | this.id = id 28 | this.execCache = execCache 29 | this.execRun = execRun 30 | } 31 | } 32 | 33 | /** 34 | * It starts a docker container with a deno relay, and waits for it to be ready 35 | * @param {string} slug - the name of the function to deploy 36 | * @param {string} jwtSecret - the JWT secret to access function 37 | * @param {string} [denoOrigin=http://localhost:8000] - the origin of the deno server 38 | * @param {Map} env - list of environment variables for deno relay 39 | * @returns {Promise} A Relay object. 40 | */ 41 | export async function runRelay( 42 | slug: string, 43 | jwtSecret: string, 44 | denoOrigin: string = 'http://localhost:8000', 45 | env?: Map 46 | ): Promise { 47 | // read function to deploy 48 | log('read function body') 49 | const functionBytes = fs.readFileSync('test/functions/' + slug + '/index.ts', 'utf8') 50 | attach('function body', functionBytes, ContentType.TEXT) 51 | 52 | // random id for parallel execution 53 | const id = nanoid(5) 54 | 55 | //create network 56 | log('add network') 57 | const network = await new Network({ name: 'supabase_network_' + id }).start() 58 | 59 | // create relay container 60 | log(`create relay ${slug + '-' + id}`) 61 | const relay = await new GenericContainer('supabase/deno-relay:v1.5.0') 62 | .withName(slug + '-' + id) 63 | .withBindMount(`${process.cwd()}/test/functions/${slug}`, `/home/deno/${slug}`, 'ro') 64 | .withNetworkMode(network.getName()) 65 | .withExposedPorts(8081) 66 | .withWaitStrategy(Wait.forLogMessage('Listening on http://0.0.0.0:8081')) 67 | .withStartupTimeout(15000) 68 | .withReuse() 69 | 70 | // add envs 71 | env = parseEnv(env, jwtSecret, denoOrigin) 72 | env && env.forEach((value, key) => relay.withEnv(key, value)) 73 | 74 | // start relay and function 75 | log(`start relay ${slug + '-' + id}`) 76 | const startedRelay = await relay.start() 77 | const execCache = startedRelay.exec(['deno', 'cache', `/home/deno/${slug}/index.ts`]) 78 | const execRun = startedRelay.exec([ 79 | 'deno', 80 | 'run', 81 | '--allow-all', 82 | '--watch', 83 | '--unstable', 84 | `/home/deno/${slug}/index.ts`, 85 | ]) 86 | 87 | // wait till function is running 88 | log(`check function is healthy: ${slug + '-' + id}`) 89 | for (let ctr = 0; ctr < 30; ctr++) { 90 | try { 91 | const healthCheck = await nodeFetch( 92 | `http://localhost:${startedRelay.getMappedPort(8081)}/${slug}`, 93 | { 94 | method: 'POST', 95 | headers: { 96 | Authorization: `Bearer ${sign({ name: 'check' }, jwtSecret)}`, 97 | }, 98 | } 99 | ) 100 | if (healthCheck.ok || healthCheck.status === 101) { 101 | log(`function started to serve: ${slug + '-' + id}`) 102 | return { container: startedRelay, id, execCache, execRun } 103 | } 104 | } catch { 105 | /* we actually don't care about errors here */ 106 | } 107 | await new Promise((resolve) => setTimeout(resolve, 500)) 108 | } 109 | 110 | // if function hasn't started, stop container and throw 111 | log(`function failed to start: ${slug + '-' + id}`) 112 | startedRelay.stop() 113 | throw new Error("function haven'start correctly") 114 | } 115 | 116 | /** 117 | * If the JWT_SECRET and DENO_ORIGIN environment is not set, set it 118 | * @param env - The environment variables. 119 | * @param {string} jwtSecret - The JWT secret. 120 | * @param {string} denoOrigin - The origin of the Deno server. 121 | * @returns {Map} - `env` variables map. 122 | */ 123 | function parseEnv( 124 | env: Map | undefined | null, 125 | jwtSecret: string, 126 | denoOrigin: string 127 | ): Map { 128 | if (env) { 129 | !env.has('JWT_SECRET') && jwtSecret && env.set('JWT_SECRET', jwtSecret) 130 | !env.has('DENO_ORIGIN') && denoOrigin && env.set('DENO_ORIGIN', denoOrigin) 131 | } else { 132 | env = new Map([ 133 | ['JWT_SECRET', jwtSecret], 134 | ['DENO_ORIGIN', denoOrigin], 135 | ]) 136 | } 137 | return env 138 | } 139 | -------------------------------------------------------------------------------- /test/spec/hello.spec.ts: -------------------------------------------------------------------------------- 1 | import 'jest' 2 | import { nanoid } from 'nanoid' 3 | import { sign } from 'jsonwebtoken' 4 | import { ContentType } from 'allure-js-commons' 5 | 6 | import { FunctionsClient } from '../../src/index' 7 | 8 | import { Relay, runRelay } from '../relay/container' 9 | import { attach, log } from '../utils/jest-custom-reporter' 10 | import { getCustomFetch } from '../utils/fetch' 11 | 12 | describe('basic tests (hello function)', () => { 13 | let relay: Relay 14 | const jwtSecret = nanoid(10) 15 | const apiKey = sign({ name: 'anon' }, jwtSecret) 16 | 17 | beforeAll(async () => { 18 | relay = await runRelay('hello', jwtSecret) 19 | }) 20 | 21 | afterAll(async () => { 22 | relay && relay.container && (await relay.container.stop()) 23 | }) 24 | 25 | test('invoke hello with auth header', async () => { 26 | /** 27 | * @feature auth 28 | */ 29 | log('create FunctionsClient') 30 | const fclient = new FunctionsClient(`http://localhost:${relay.container.getMappedPort(8081)}`, { 31 | headers: { 32 | Authorization: `Bearer ${apiKey}`, 33 | }, 34 | }) 35 | 36 | log('invoke hello') 37 | const { data, error } = await fclient.invoke('hello', {}) 38 | 39 | log('assert no error') 40 | expect(error).toBeNull() 41 | log(`assert ${data} is equal to 'Hello World'`) 42 | expect(data).toEqual('Hello World') 43 | }) 44 | 45 | test('invoke hello with setAuth', async () => { 46 | /** 47 | * @feature auth 48 | */ 49 | log('create FunctionsClient') 50 | const fclient = new FunctionsClient(`http://localhost:${relay.container.getMappedPort(8081)}`) 51 | attach('setAuth', apiKey, ContentType.TEXT) 52 | fclient.setAuth(apiKey) 53 | 54 | log('invoke hello') 55 | const { data, error } = await fclient.invoke('hello', {}) 56 | 57 | log('assert no error') 58 | expect(error).toBeNull() 59 | log(`assert ${data} is equal to 'Hello World'`) 60 | expect(data).toEqual('Hello World') 61 | }) 62 | 63 | test('invoke hello with setAuth wrong key', async () => { 64 | /** 65 | * @feature errors 66 | */ 67 | log('create FunctionsClient') 68 | const fclient = new FunctionsClient(`http://localhost:${relay.container.getMappedPort(8081)}`) 69 | const wrongKey = sign({ name: 'anon' }, 'wrong_jwt') 70 | attach('setAuth with wrong jwt', wrongKey, ContentType.TEXT) 71 | fclient.setAuth(wrongKey) 72 | 73 | log('invoke hello') 74 | const { data, error } = await fclient.invoke('hello', {}) 75 | 76 | log('check error') 77 | expect(error).not.toBeNull() 78 | expect(error?.message).toEqual('Relay Error invoking the Edge Function') 79 | expect(data).toBeNull() 80 | }) 81 | 82 | test('invoke hello: auth override by setAuth wrong key', async () => { 83 | /** 84 | * @feature auth 85 | */ 86 | log('create FunctionsClient') 87 | const fclient = new FunctionsClient(`http://localhost:${relay.container.getMappedPort(8081)}`, { 88 | headers: { 89 | Authorization: `Bearer ${apiKey}`, 90 | }, 91 | }) 92 | const wrongKey = sign({ name: 'anon' }, 'wrong_jwt') 93 | attach('setAuth with wrong jwt', wrongKey, ContentType.TEXT) 94 | fclient.setAuth(wrongKey) 95 | 96 | log('invoke hello') 97 | const { data, error } = await fclient.invoke('hello', {}) 98 | 99 | log('check error') 100 | expect(error).not.toBeNull() 101 | expect(error?.message).toEqual('Relay Error invoking the Edge Function') 102 | expect(data).toBeNull() 103 | }) 104 | 105 | test('invoke hello: auth override by setAuth right key', async () => { 106 | /** 107 | * @feature auth 108 | */ 109 | const wrongKey = sign({ name: 'anon' }, 'wrong_jwt') 110 | 111 | log('create FunctionsClient with wrong jwt') 112 | const fclient = new FunctionsClient(`http://localhost:${relay.container.getMappedPort(8081)}`, { 113 | headers: { 114 | Authorization: `Bearer ${wrongKey}`, 115 | }, 116 | }) 117 | 118 | attach('setAuth with right jwt', apiKey, ContentType.TEXT) 119 | fclient.setAuth(apiKey) 120 | 121 | log('invoke hello') 122 | const { data, error } = await fclient.invoke('hello', {}) 123 | 124 | log('assert no error') 125 | expect(error).toBeNull() 126 | log(`assert ${data} is equal to 'Hello World'`) 127 | expect(data).toEqual('Hello World') 128 | }) 129 | 130 | test('invoke hello with auth header in invoke', async () => { 131 | /** 132 | * @feature auth 133 | */ 134 | log('create FunctionsClient') 135 | const fclient = new FunctionsClient(`http://localhost:${relay.container.getMappedPort(8081)}`) 136 | 137 | log('invoke hello with Authorization header') 138 | const { data, error } = await fclient.invoke('hello', { 139 | headers: { 140 | Authorization: `Bearer ${apiKey}`, 141 | }, 142 | }) 143 | 144 | log('assert no error') 145 | expect(error).toBeNull() 146 | log(`assert ${data} is equal to 'Hello World'`) 147 | expect(data).toEqual('Hello World') 148 | }) 149 | 150 | test('invoke hello with auth header override in invoke', async () => { 151 | /** 152 | * @feature auth 153 | */ 154 | log('create FunctionsClient with wrong jwt') 155 | const fclient = new FunctionsClient(`http://localhost:${relay.container.getMappedPort(8081)}`) 156 | 157 | const wrongKey = sign({ name: 'anon' }, 'wrong_jwt') 158 | attach('setAuth with wrong jwt', wrongKey, ContentType.TEXT) 159 | fclient.setAuth(wrongKey) 160 | 161 | log('invoke hello with Authorization header') 162 | const { data, error } = await fclient.invoke('hello', { 163 | headers: { 164 | Authorization: `Bearer ${apiKey}`, 165 | }, 166 | }) 167 | 168 | log('assert no error') 169 | expect(error).toBeNull() 170 | log(`assert ${data} is equal to 'Hello World'`) 171 | expect(data).toEqual('Hello World') 172 | }) 173 | 174 | test('invoke hello with wrong auth header overridden in invoke', async () => { 175 | /** 176 | * @feature auth 177 | */ 178 | log('create FunctionsClient with wrong jwt') 179 | const fclient = new FunctionsClient(`http://localhost:${relay.container.getMappedPort(8081)}`, { 180 | headers: { 181 | Authorization: `Bearer ${apiKey}`, 182 | }, 183 | }) 184 | 185 | const wrongKey = sign({ name: 'anon' }, 'wrong_jwt') 186 | log('invoke hello with wrong Authorization header') 187 | const { data, error } = await fclient.invoke('hello', { 188 | headers: { 189 | Authorization: `Bearer ${wrongKey}`, 190 | }, 191 | }) 192 | 193 | log('check error') 194 | expect(error).not.toBeNull() 195 | expect(error?.message).toEqual('Relay Error invoking the Edge Function') 196 | expect(data).toBeNull() 197 | }) 198 | 199 | it.skip('invoke missing function', async () => { 200 | /** 201 | * @feature errors 202 | */ 203 | log('create FunctionsClient') 204 | const fclient = new FunctionsClient(`http://localhost:${relay.container.getMappedPort(8081)}`, { 205 | headers: { 206 | Authorization: `Bearer ${apiKey}`, 207 | }, 208 | }) 209 | 210 | log('invoke hello') 211 | const { data, error } = await fclient.invoke('missing', {}) 212 | 213 | log('check error') 214 | expect(error).not.toBeNull() 215 | expect(error?.message).toEqual('Invalid JWT') 216 | expect(data).toBeNull() 217 | }) 218 | 219 | test('invoke with custom fetch', async () => { 220 | /** 221 | * @feature fetch 222 | */ 223 | log('create FunctionsClient') 224 | const fclient = new FunctionsClient(`http://localhost:${relay.container.getMappedPort(8081)}`, { 225 | customFetch: getCustomFetch( 226 | `http://localhost:${relay.container.getMappedPort(8081)}/${'hello'}`, 227 | { 228 | method: 'POST', 229 | headers: { 230 | Authorization: `Bearer ${apiKey}`, 231 | }, 232 | } 233 | ), 234 | }) 235 | 236 | log('invoke hello') 237 | const { data, error } = await fclient.invoke('', {}) 238 | 239 | log('assert no error') 240 | expect(error).toBeNull() 241 | log(`assert ${data} is equal to 'Hello World'`) 242 | expect(data).toEqual('Hello World') 243 | }) 244 | 245 | test('invoke with custom fetch GET method', async () => { 246 | /** 247 | * @feature fetch 248 | */ 249 | log('create FunctionsClient') 250 | const fclient = new FunctionsClient(`http://localhost:${relay.container.getMappedPort(8081)}`, { 251 | customFetch: getCustomFetch( 252 | `http://localhost:${relay.container.getMappedPort(8081)}/${'hello'}`, 253 | { 254 | method: 'GET', 255 | headers: { 256 | Authorization: `Bearer ${apiKey}`, 257 | }, 258 | } 259 | ), 260 | }) 261 | 262 | log('invoke hello') 263 | const { data, error } = await fclient.invoke('', {}) 264 | 265 | log('assert no error') 266 | expect(error).toBeNull() 267 | log(`assert ${data} is equal to 'Hello World'`) 268 | expect(data).toEqual('Hello World') 269 | }) 270 | 271 | test('invoke hello with custom fetch override header', async () => { 272 | /** 273 | * @feature fetch 274 | */ 275 | const wrongKey = sign({ name: 'anon' }, 'wrong_jwt') 276 | log('create FunctionsClient') 277 | const fclient = new FunctionsClient(`http://localhost:${relay.container.getMappedPort(8081)}`, { 278 | headers: { 279 | Authorization: `Bearer ${wrongKey}`, 280 | }, 281 | customFetch: getCustomFetch( 282 | `http://localhost:${relay.container.getMappedPort(8081)}/${'hello'}`, 283 | { 284 | method: 'Post', 285 | headers: { 286 | Authorization: `Bearer ${apiKey}`, 287 | }, 288 | } 289 | ), 290 | }) 291 | 292 | log('invoke hello with Authorization header') 293 | const { data, error } = await fclient.invoke('hello', {}) 294 | 295 | log('assert no error') 296 | expect(error).toBeNull() 297 | log(`assert ${data} is equal to 'Hello World'`) 298 | expect(data).toEqual('Hello World') 299 | }) 300 | }) 301 | -------------------------------------------------------------------------------- /test/spec/hijack.spec.ts: -------------------------------------------------------------------------------- 1 | import 'jest' 2 | import { nanoid } from 'nanoid' 3 | import { sign } from 'jsonwebtoken' 4 | 5 | import { FunctionsClient } from '../../src/index' 6 | 7 | import { Relay, runRelay } from '../relay/container' 8 | import { attach, log } from '../utils/jest-custom-reporter' 9 | 10 | describe('hijack connection', () => { 11 | let relay: Relay 12 | const jwtSecret = nanoid(10) 13 | const apiKey = sign({ name: 'anon' }, jwtSecret) 14 | const func = 'hijack' 15 | 16 | beforeAll(async () => { 17 | relay = await runRelay(func, jwtSecret) 18 | }) 19 | 20 | afterAll(async () => { 21 | relay && relay.container && (await relay.container.stop()) 22 | }) 23 | 24 | test('invoke func', async () => { 25 | /** 26 | * @feature hijack 27 | */ 28 | log('create FunctionsClient') 29 | const fclient = new FunctionsClient(`http://localhost:${relay.container.getMappedPort(8081)}`, { 30 | headers: { 31 | Authorization: `Bearer ${apiKey}`, 32 | }, 33 | }) 34 | 35 | log('invoke func') 36 | const { data, error } = await fclient.invoke(func, {}) 37 | 38 | log('assert error to be "Connection Upgrade is not supported"') 39 | expect(error).not.toBeNull() 40 | }) 41 | }) 42 | -------------------------------------------------------------------------------- /test/spec/params.spec.ts: -------------------------------------------------------------------------------- 1 | import { Blob } from 'buffer' 2 | import querystring from 'querystring' 3 | 4 | import 'jest' 5 | import { nanoid } from 'nanoid' 6 | import { sign } from 'jsonwebtoken' 7 | import { ContentType } from 'allure-js-commons' 8 | 9 | import { FunctionsClient } from '../../src/index' 10 | import { FunctionRegion } from '../../src/types' 11 | import { Relay, runRelay } from '../relay/container' 12 | import { attach, log } from '../utils/jest-custom-reporter' 13 | import { str2ab } from '../utils/binaries' 14 | import { MirrorResponse } from '../models/mirrorResponse' 15 | 16 | describe('params reached to function', () => { 17 | let relay: Relay 18 | const jwtSecret = nanoid(10) 19 | const apiKey = sign({ name: 'anon' }, jwtSecret) 20 | 21 | beforeAll(async () => { 22 | relay = await runRelay('mirror', jwtSecret) 23 | }) 24 | 25 | afterAll(async () => { 26 | relay && relay.container && (await relay.container.stop()) 27 | }) 28 | 29 | test('invoke mirror', async () => { 30 | /** 31 | * @feature core 32 | */ 33 | log('create FunctionsClient') 34 | const fclient = new FunctionsClient(`http://localhost:${relay.container.getMappedPort(8081)}`, { 35 | headers: { 36 | Authorization: `Bearer ${apiKey}`, 37 | }, 38 | }) 39 | 40 | log('invoke mirror') 41 | const { data, error } = await fclient.invoke('mirror', {}) 42 | 43 | log('assert no error') 44 | expect(error).toBeNull() 45 | 46 | const expected = { 47 | url: 'http://localhost:8000/mirror', 48 | method: 'POST', 49 | headers: data?.headers ?? [], 50 | body: '', 51 | } 52 | attach( 53 | 'check data from function', 54 | `expected: ${JSON.stringify(expected)}\n actual: ${JSON.stringify(data)}`, 55 | ContentType.TEXT 56 | ) 57 | expect(data).toEqual(expected) 58 | }) 59 | 60 | test('invoke mirror with client header', async () => { 61 | /** 62 | * @feature headers 63 | */ 64 | log('create FunctionsClient') 65 | const fclient = new FunctionsClient(`http://localhost:${relay.container.getMappedPort(8081)}`, { 66 | headers: { 67 | Authorization: `Bearer ${apiKey}`, 68 | CustomHeader: 'check me', 69 | }, 70 | }) 71 | 72 | log('invoke mirror') 73 | const { data, error } = await fclient.invoke('mirror', {}) 74 | 75 | log('assert no error') 76 | expect(error).toBeNull() 77 | 78 | const expected = { 79 | url: 'http://localhost:8000/mirror', 80 | method: 'POST', 81 | headers: data?.headers ?? [], 82 | body: '', 83 | } 84 | attach( 85 | 'check data from function', 86 | `expected: ${JSON.stringify(expected)}\n actual: ${JSON.stringify(data)}`, 87 | ContentType.TEXT 88 | ) 89 | expect(data).toEqual(expected) 90 | attach( 91 | 'check headers from function', 92 | `expected to include: ${['customheader', 'check me']}\n actual: ${JSON.stringify( 93 | data?.headers 94 | )}`, 95 | ContentType.TEXT 96 | ) 97 | expect( 98 | (data?.headers as [Array]).filter( 99 | ([k, v]) => k === 'customheader' && v === 'check me' 100 | ).length > 0 101 | ).toBe(true) 102 | }) 103 | 104 | test('invoke mirror with invoke header', async () => { 105 | /** 106 | * @feature headers 107 | */ 108 | log('create FunctionsClient') 109 | const fclient = new FunctionsClient(`http://localhost:${relay.container.getMappedPort(8081)}`) 110 | 111 | log('invoke mirror') 112 | const customHeader = nanoid() 113 | const { data, error } = await fclient.invoke('mirror', { 114 | headers: { 115 | 'custom-header': customHeader, 116 | Authorization: `Bearer ${apiKey}`, 117 | }, 118 | }) 119 | 120 | log('assert no error') 121 | expect(error).toBeNull() 122 | 123 | const expected = { 124 | url: 'http://localhost:8000/mirror', 125 | method: 'POST', 126 | headers: data?.headers ?? [], 127 | body: '', 128 | } 129 | attach( 130 | 'check data from function', 131 | `expected: ${JSON.stringify(expected)}\n actual: ${JSON.stringify(data)}`, 132 | ContentType.TEXT 133 | ) 134 | expect(data).toEqual(expected) 135 | attach( 136 | 'check headers from function', 137 | `expected to include: ${['custom-header', customHeader]}\n actual: ${JSON.stringify( 138 | data?.headers 139 | )}`, 140 | ContentType.TEXT 141 | ) 142 | expect( 143 | (data?.headers as [Array]).filter( 144 | ([k, v]) => k === 'custom-header' && v === customHeader 145 | ).length > 0 146 | ).toBe(true) 147 | }) 148 | 149 | test('invoke mirror set valid region on request', async () => { 150 | /** 151 | * @feature headers 152 | */ 153 | log('create FunctionsClient') 154 | const fclient = new FunctionsClient(`http://localhost:${relay.container.getMappedPort(8081)}`) 155 | 156 | log('invoke mirror') 157 | const customHeader = nanoid() 158 | const validRegion = FunctionRegion.ApNortheast1 159 | 160 | const { data, error } = await fclient.invoke('mirror', { 161 | headers: { 162 | 'custom-header': customHeader, 163 | Authorization: `Bearer ${apiKey}`, 164 | }, 165 | region: validRegion, 166 | }) 167 | 168 | log('assert no error') 169 | const expected = { 170 | url: 'http://localhost:8000/mirror', 171 | method: 'POST', 172 | headers: data?.headers ?? [], 173 | body: '', 174 | } 175 | expect(data).toEqual(expected) 176 | attach( 177 | 'check headers from function', 178 | `expected to include: ${['custom-header', customHeader]}\n actual: ${JSON.stringify( 179 | data?.headers 180 | )}`, 181 | ContentType.TEXT 182 | ) 183 | console.log(data?.headers) 184 | expect( 185 | (data?.headers as [Array]).filter(([k, v]) => k === 'x-region' && v === validRegion) 186 | .length > 0 187 | ).toBe(true) 188 | }) 189 | 190 | test('invoke with region overrides region in the client', async () => { 191 | /** 192 | * @feature headers 193 | */ 194 | log('create FunctionsClient') 195 | const fclient = new FunctionsClient(`http://localhost:${relay.container.getMappedPort(8081)}`, { 196 | region: FunctionRegion.ApNortheast1, 197 | }) 198 | 199 | log('invoke mirror') 200 | const customHeader = nanoid() 201 | const validRegion = FunctionRegion.ApSoutheast1 202 | 203 | const { data, error } = await fclient.invoke('mirror', { 204 | headers: { 205 | 'custom-header': customHeader, 206 | Authorization: `Bearer ${apiKey}`, 207 | }, 208 | region: validRegion, 209 | }) 210 | 211 | log('assert no error') 212 | const expected = { 213 | url: 'http://localhost:8000/mirror', 214 | method: 'POST', 215 | headers: data?.headers ?? [], 216 | body: '', 217 | } 218 | expect(data).toEqual(expected) 219 | attach( 220 | 'check headers from function', 221 | `expected to include: ${['custom-header', customHeader]}\n actual: ${JSON.stringify( 222 | data?.headers 223 | )}`, 224 | ContentType.TEXT 225 | ) 226 | console.log(data?.headers) 227 | expect( 228 | (data?.headers as [Array]).filter(([k, v]) => k === 'x-region' && v === validRegion) 229 | .length > 0 230 | ).toBe(true) 231 | }) 232 | 233 | test('starts client with default region, invoke reverts to any (no x-region header)', async () => { 234 | /** 235 | * @feature headers 236 | */ 237 | log('create FunctionsClient') 238 | const validRegion = FunctionRegion.ApSoutheast1 239 | const fclient = new FunctionsClient(`http://localhost:${relay.container.getMappedPort(8081)}`, { 240 | region: validRegion, 241 | }) 242 | 243 | log('invoke mirror') 244 | const customHeader = nanoid() 245 | 246 | const { data, error } = await fclient.invoke('mirror', { 247 | headers: { 248 | 'custom-header': customHeader, 249 | Authorization: `Bearer ${apiKey}`, 250 | }, 251 | region: FunctionRegion.Any, 252 | }) 253 | 254 | log('assert no error') 255 | const expected = { 256 | url: 'http://localhost:8000/mirror', 257 | method: 'POST', 258 | headers: data?.headers ?? [], 259 | body: '', 260 | } 261 | expect(data).toEqual(expected) 262 | attach( 263 | 'check headers from function', 264 | `expected to include: ${['custom-header', customHeader]}\n actual: ${JSON.stringify( 265 | data?.headers 266 | )}`, 267 | ContentType.TEXT 268 | ) 269 | console.log(data?.headers) 270 | expect( 271 | (data?.headers as [Array]).filter(([k, v]) => k === 'x-region' && v === validRegion) 272 | .length == 0 273 | ).toBe(true) 274 | }) 275 | 276 | test('invoke region set only on the constructor', async () => { 277 | /** 278 | * @feature headers 279 | */ 280 | log('create FunctionsClient') 281 | const fclient = new FunctionsClient(`http://localhost:${relay.container.getMappedPort(8081)}`, { 282 | region: FunctionRegion.ApNortheast1, 283 | }) 284 | 285 | log('invoke mirror') 286 | const customHeader = nanoid() 287 | 288 | const { data, error } = await fclient.invoke('mirror', { 289 | headers: { 290 | 'custom-header': customHeader, 291 | Authorization: `Bearer ${apiKey}`, 292 | }, 293 | }) 294 | 295 | log('assert no error') 296 | expect( 297 | (data?.headers as [Array]).filter( 298 | ([k, v]) => k === 'x-region' && v === FunctionRegion.ApNortheast1 299 | ).length > 0 300 | ).toBe(true) 301 | }) 302 | 303 | test('invoke mirror with body formData', async () => { 304 | /** 305 | * @feature body 306 | */ 307 | log('create FunctionsClient') 308 | const fclient = new FunctionsClient(`http://localhost:${relay.container.getMappedPort(8081)}`) 309 | attach('setAuth', apiKey, ContentType.TEXT) 310 | fclient.setAuth(apiKey) 311 | 312 | log('invoke mirror') 313 | var form = new FormData() 314 | const formData = [ 315 | [nanoid(5), nanoid(10)], 316 | [nanoid(7), nanoid(5)], 317 | [nanoid(15), nanoid()], 318 | ] 319 | formData.forEach((e) => form.append(e[0], e[1])) 320 | 321 | const { data, error } = await fclient.invoke('mirror', { 322 | body: form, 323 | headers: { 324 | 'response-type': 'form', 325 | }, 326 | }) 327 | 328 | log('assert no error') 329 | expect(error).toBeNull() 330 | 331 | const expected = { 332 | url: 'http://localhost:8000/mirror', 333 | method: 'POST', 334 | headers: data?.headers ?? [], 335 | body: formData, 336 | } 337 | attach( 338 | 'check data from function', 339 | `expected: ${JSON.stringify(expected)}\n actual: ${JSON.stringify(data)}`, 340 | ContentType.TEXT 341 | ) 342 | expect(data).toEqual(expected) 343 | }) 344 | 345 | test('invoke mirror with body json', async () => { 346 | /** 347 | * @feature body 348 | */ 349 | log('create FunctionsClient') 350 | const fclient = new FunctionsClient(`http://localhost:${relay.container.getMappedPort(8081)}`) 351 | attach('setAuth', apiKey, ContentType.TEXT) 352 | fclient.setAuth(apiKey) 353 | 354 | log('invoke mirror') 355 | const body = { 356 | one: nanoid(10), 357 | two: nanoid(5), 358 | three: nanoid(), 359 | num: 11, 360 | flag: false, 361 | } 362 | const { data, error } = await fclient.invoke('mirror', { 363 | body: JSON.stringify(body), 364 | headers: { 365 | 'content-type': 'application/json', 366 | 'response-type': 'json', 367 | }, 368 | }) 369 | 370 | log('assert no error') 371 | expect(error).toBeNull() 372 | 373 | const expected = { 374 | url: 'http://localhost:8000/mirror', 375 | method: 'POST', 376 | headers: data?.headers ?? [], 377 | body: body, 378 | } 379 | attach( 380 | 'check data from function', 381 | `expected: ${JSON.stringify(expected)}\n actual: ${JSON.stringify(data)}`, 382 | ContentType.TEXT 383 | ) 384 | expect(data).toEqual(expected) 385 | }) 386 | 387 | test('invoke mirror with body arrayBuffer', async () => { 388 | /** 389 | * @feature body 390 | */ 391 | log('create FunctionsClient') 392 | const fclient = new FunctionsClient(`http://localhost:${relay.container.getMappedPort(8081)}`) 393 | attach('setAuth', apiKey, ContentType.TEXT) 394 | fclient.setAuth(apiKey) 395 | 396 | log('invoke mirror') 397 | const body = { 398 | one: nanoid(10), 399 | two: nanoid(5), 400 | three: nanoid(), 401 | num: 11, 402 | flag: false, 403 | } 404 | const arrayBuffer = str2ab(JSON.stringify(body)) 405 | const { data, error } = await fclient.invoke('mirror', { 406 | body: arrayBuffer, 407 | headers: { 408 | 'content-type': 'application/octet-stream', 409 | 'response-type': 'arrayBuffer', 410 | }, 411 | }) 412 | 413 | log('assert no error') 414 | expect(error).toBeNull() 415 | 416 | const expected = { 417 | url: 'http://localhost:8000/mirror', 418 | method: 'POST', 419 | body: arrayBuffer, 420 | } 421 | expect(data).toMatchObject(expected) 422 | }) 423 | 424 | test('invoke mirror with body blob', async () => { 425 | /** 426 | * @feature body 427 | */ 428 | log('create FunctionsClient') 429 | const fclient = new FunctionsClient(`http://localhost:${relay.container.getMappedPort(8081)}`) 430 | attach('setAuth', apiKey, ContentType.TEXT) 431 | fclient.setAuth(apiKey) 432 | 433 | log('invoke mirror') 434 | const body = { 435 | one: nanoid(10), 436 | two: nanoid(5), 437 | three: nanoid(), 438 | num: 11, 439 | flag: false, 440 | } 441 | const bodyEncoded = str2ab(JSON.stringify(body)) 442 | const { data, error } = await fclient.invoke('mirror', { 443 | body: bodyEncoded, 444 | headers: { 445 | 'content-type': 'application/octet-stream', 446 | 'response-type': 'blob', 447 | }, 448 | }) 449 | 450 | log('assert no error') 451 | expect(error).toBeNull() 452 | 453 | const expected = { 454 | url: 'http://localhost:8000/mirror', 455 | method: 'POST', 456 | body: bodyEncoded, 457 | } 458 | expect(data).toMatchObject(expected) 459 | }) 460 | 461 | test('invoke mirror with url params', async () => { 462 | /** 463 | * @feature body 464 | */ 465 | log('create FunctionsClient') 466 | const fclient = new FunctionsClient(`http://localhost:${relay.container.getMappedPort(8081)}`) 467 | attach('setAuth', apiKey, ContentType.TEXT) 468 | fclient.setAuth(apiKey) 469 | 470 | log('invoke mirror') 471 | const body = { 472 | one: nanoid(10), 473 | two: nanoid(5), 474 | three: nanoid(), 475 | num: '11', 476 | flag: 'false', 477 | } 478 | const queryParams = new URLSearchParams(body) 479 | const { data, error } = await fclient.invoke( 480 | `mirror?${queryParams.toString()}`, 481 | {} 482 | ) 483 | 484 | log('assert no error') 485 | expect(error).toBeNull() 486 | 487 | const expected = { 488 | url: `http://localhost:8000/mirror?${queryParams.toString()}`, 489 | method: 'POST', 490 | } 491 | expect(data).toMatchObject(expected) 492 | }) 493 | }) 494 | -------------------------------------------------------------------------------- /test/utils/binaries.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Convert a buffer to a string 3 | * @param buf - the buffer to convert to a string 4 | * @returns The string representation of the buffer. 5 | */ 6 | export function ab2str(buf: ArrayBufferLike) { 7 | let str = '' 8 | 9 | new Uint16Array(buf).forEach(function (byte: number) { 10 | str += String.fromCharCode(byte) 11 | }) 12 | return str 13 | } 14 | 15 | /** 16 | * Convert a string to an array buffer 17 | * @param str - The string to be converted into an ArrayBuffer. 18 | * @returns The array buffer that contains the string. 19 | */ 20 | export function str2ab(str: string) { 21 | var buf = new ArrayBuffer(str.length * 2) // 2 bytes for each char 22 | var bufView = new Uint16Array(buf) 23 | for (var i = 0, strLen = str.length; i < strLen; i++) { 24 | bufView[i] = str.charCodeAt(i) 25 | } 26 | return buf 27 | } 28 | -------------------------------------------------------------------------------- /test/utils/fetch.ts: -------------------------------------------------------------------------------- 1 | // @ts-ignore 2 | import nodeFetch from '@supabase/node-fetch' 3 | 4 | /** 5 | * It returns a crossFetch function that uses overridden input: RequestInfo and init?: RequestInit for 6 | * testing purpose 7 | * @param {RequestInfo} reqInfo - RequestInfo or url of request 8 | * @param {RequestInit | undefined} [reqInit] - The RequestInit object. 9 | * @returns A new crossFetch function that ignores args and returns a response promise. 10 | */ 11 | export function getCustomFetch( 12 | reqInfo: RequestInfo | URL, 13 | reqInit?: RequestInit | undefined 14 | ): (input: RequestInfo | URL, init?: RequestInit | undefined) => Promise { 15 | return (input, init) => nodeFetch(reqInfo, reqInit) 16 | } 17 | -------------------------------------------------------------------------------- /test/utils/jest-custom-reporter.ts: -------------------------------------------------------------------------------- 1 | // TODO: replace with a working implementation 2 | export function attach(name: string, content: string | Buffer, type: any): void { 3 | // getAllure().step(name, () => { 4 | // getAllure().attachment(type.toString(), content, type) 5 | // }) 6 | } 7 | 8 | export function log(name: string, description?: string): void { 9 | console.info(description ? `${name}: ${description}` : name) 10 | } 11 | -------------------------------------------------------------------------------- /test/utils/timeoutPromise.ts: -------------------------------------------------------------------------------- 1 | export default async function timeoutRequest(request: Promise, timeout: number): Promise { 2 | let timer: NodeJS.Timeout 3 | 4 | request.finally(() => clearTimeout(timer)) 5 | 6 | const timeoutPromise = new Promise((_, reject) => { 7 | timer = setTimeout(() => reject(new Error(`Timeout (${timeout}) for task exceeded`)), timeout) 8 | }) 9 | 10 | return Promise.race([request, timeoutPromise]) 11 | } 12 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["src"], 3 | "exclude": ["node_modules/**/*.ts"], 4 | "compilerOptions": { 5 | "declaration": true, 6 | "declarationMap": true, 7 | "module": "CommonJS", 8 | "outDir": "dist/main", 9 | "rootDir": "src", 10 | "sourceMap": true, 11 | "target": "ES2015", 12 | 13 | "strict": true, 14 | 15 | "esModuleInterop": true, 16 | "moduleResolution": "Node", 17 | "isolatedModules": true, 18 | 19 | "forceConsistentCasingInFileNames": true, 20 | "stripInternal": true, 21 | "allowSyntheticDefaultImports": true 22 | }, 23 | "typeRoots": [ 24 | "./src/types" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /tsconfig.module.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./tsconfig", 3 | "compilerOptions": { 4 | "module": "ES2020", 5 | "outDir": "dist/module" 6 | } 7 | } 8 | --------------------------------------------------------------------------------