diff --git a/.gitignore b/.gitignore index 1ce1547..a7e8add 100644 --- a/.gitignore +++ b/.gitignore @@ -131,5 +131,9 @@ react-native .yarn/install-state.gz .pnp.* -copilot-instructions.md +.github/ +!.github/workflows/ tests/.test-config.json +mailpit* + +.DS_Store diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..fae8e3d --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "typescript.tsdk": "node_modules/typescript/lib", + "typescript.enablePromptUseWorkspaceTsdk": true +} diff --git a/README.md b/README.md index 1998d1c..fe6ddc8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,29 @@ # Appwrite GraphQL -This is a GraphQL library for Appwrite, built with the power of [@tanstack/react-query](https://github.com/TanStack/query) and inspired by [react-appwrite](https://github.com/react-appwrite/react-appwrite). +This is a fully featured GraphQL library built with [@tanstack/react-query](https://github.com/TanStack/query) on top of the Appwrite web SDK. + +What this project handles for you: + +- Dual build for both React and React Native +- Full Appwrite SDK v22 parity via React hooks +- Optimistic Mutations + - Documents +- Query Caching +- Offline-first support + - Built-in offline persisters (localStorage, AsyncStorage) + - Custom offline persister support +- SSR Support +- Field selection + - Prevent over-fetching +- Suspense queries + - Documents + - Collections +- Pagination hooks + - Standard Pagination + - Infinite Scroll +- Appwrite QueryBuilder +- Query key builder +- React Query Devtools support ## Installation @@ -10,30 +33,166 @@ npm install --save @zeroin.earth/appwrite-graphql bun add @zeroin.earth/appwrite-graphql ``` +### Peer Dependencies + + - `react` - `19.0.1` + - `appwrite` - `22.4.1` + - `@tanstack/react-query` - `^5.70.0` + +React Native: + + - `@react-native-async-storage/async-storage` + - `@react-native-community/netinfo` + - `react-native-appwrite` + ## Usage -### Set up -You must provide the Appwrite URL and Project ID as environment variables. It does not matter how they are provided as long as they can be accessed from `process.env.`: +### Provider + +The library is designed to use a single wrapper, ``. There sre multiple ways you can configure the wrapper based upon your app's needs: -```js -/* Endpoint - Pick one */ -APPWRITE_ENDPOINT= -NEXT_PUBLIC_APPWRITE_URL= -EXPO_PUBLIC_APPWRITE_URL= +1. Basic (no offline) — React -/* Project ID - Pick one */ -APPWRITE_PROJECT_ID= -NEXT_PUBLIC_APPWRITE_PROJECT_ID -EXPO_PUBLIC_APPWRITE_PROJECT_ID +```tsx +import { AppwriteProvider, createAppwriteClient } from '@zeroin.earth/appwrite-graphql' + +const client = createAppwriteClient({ + endpoint: 'https://cloud.appwrite.io/v1', + projectId: 'my-project', +}) + +function App() { + return ( + + {/* your app */} + + ) +} ``` -### Provider -If you need to provide a custom endpoint and project ID, and can't use one of the above environment variables, you may override the default variables using the ``: +2. Offline-first — React -```jsx - - - +```tsx +import { + AppwriteProvider, + createOfflineClient, + webNetworkAdapter, +} from '@zeroin.earth/appwrite-graphql' + +const { appwrite, queryClient, persister } = createOfflineClient({ + endpoint: 'https://cloud.appwrite.io/v1', + projectId: 'my-project', + storage: localStorage, // or any AsyncStorage-compatible interface + networkAdapter: webNetworkAdapter(), +}) + +function App() { + return ( + console.log('Cache restored mutations replayed')} + > + {/* your app */} + + ) +} +``` + +3. Offline-first — React Native + +```tsx +import AsyncStorage from '@react-native-async-storage/async-storage' +import { + AppwriteProvider, + createOfflineClient, +} from '@zeroin.earth/appwrite-graphql' +import { reactNativeNetworkAdapter } from '@zeroin.earth/appwrite-graphql/react-native' + +const { appwrite, queryClient, persister } = createOfflineClient({ + endpoint: 'https://cloud.appwrite.io/v1', + projectId: 'my-project', + storage: AsyncStorage, + networkAdapter: reactNativeNetworkAdapter(), +}) + +function App() { + return ( + + {/* your app */} + + ) +} +``` + +4. Offline-first — React with custom persister + +```tsx +import { + AppwriteProvider, + createOfflineClient, + webNetworkAdapter, + type Persister, +} from '@zeroin.earth/appwrite-graphql' + +const myPersister: Persister = { + persistClient: async (client) => { /* write to your storage */ }, + restoreClient: async () => { /* read from your storage */ }, + removeClient: async () => { /* clear your storage */ }, +} + +const { appwrite, queryClient, persister } = createOfflineClient({ + endpoint: 'https://cloud.appwrite.io/v1', + projectId: 'my-project', + persister: myPersister, + networkAdapter: webNetworkAdapter(), +}) + +function App() { + return ( + + {/* your app */} + + ) +} +``` + +5. Offline — Imperative / non-React + +```tsx +import { + createOfflineClient, + webNetworkAdapter, +} from '@zeroin.earth/appwrite-graphql' + +const client = createOfflineClient({ + endpoint: 'https://cloud.appwrite.io/v1', + projectId: 'my-project', + storage: localStorage, + networkAdapter: webNetworkAdapter(), +}) + +// Start persistence — restores cache from storage, subscribes to +// future changes, and replays paused mutations once restored. +const { unsubscribe, restored } = client.startPersistence() + +await restored +console.log('Cache restored, paused mutations replayed') + +// Use client.queryClient and client.appwrite directly +// ... + +// Cleanup when done +unsubscribe() ``` ### Hooks @@ -88,26 +247,3 @@ export function Form() { }; } ``` - -### Using Fragments - -```jsx -import { - fragments, - getFragmentData, - useAccount, -} from "@zeroin.earth/appwrite-graphql"; - -export function Profile() { - const { data, isLoading } = useAccount({}); - const account = getFragmentData(fragments.Account_UserFragment, data); - - return ( -
- {data && ( -

{`Welcome, ${account?.name ?? "Visitor"}!`}

- )} -
- ); -} -``` diff --git a/bun.lock b/bun.lock index bf3ee21..32297fe 100644 --- a/bun.lock +++ b/bun.lock @@ -6,51 +6,58 @@ "name": "@zeroin.earth/appwrite-graphql", "dependencies": { "@graphql-typed-document-node/core": "^3.2.0", + "@tanstack/query-async-storage-persister": "^5.90.24", + "@tanstack/react-query-devtools": "^5.91.3", + "@tanstack/react-query-persist-client": "^5.90.24", + "gql.tada": "^1.9.0", "graphql": "^16.10.0", "graphql-scalars": "^1.24.2", "immer": "^11.1.4", }, "devDependencies": { - "@apollo/client": "^4.1.6", - "@graphql-codegen/cli": "^6.1.2", - "@graphql-codegen/client-preset": "^5.2.3", + "@eslint/js": "^10.0.1", "@happy-dom/global-registrator": "^20.7.0", + "@react-native-async-storage/async-storage": "^3.0.1", + "@react-native-community/netinfo": "^12.0.1", "@tanstack/react-query": "^5.70.0", "@testing-library/react": "^16.3.2", "@testing-library/react-hooks": "^8.0.1", "@types/bun": "latest", "@types/identity-obj-proxy": "^3.0.2", - "@types/jest": "^29.5.14", "@types/react": "^19.2.14", "appwrite": "^22.4.1", + "eslint": "^10.0.2", + "eslint-plugin-simple-import-sort": "^12.1.1", "happy-dom": "^20.7.0", "identity-obj-proxy": "^3.0.0", - "jest": "^29.7.0", - "jotai": "^2.12.2", + "mailpit-api": "^1.7.1", "node-appwrite": "^22.1.2", "otpauth": "^9.5.0", "react": "19.1.0", "react-dom": "19.1.0", "react-native-appwrite": "^0.24.1", - "ts-jest": "^29.3.0", "tsup": "^8.4.0", - "typescript": "^5.8.2", + "typescript": "^5.9.3", + "typescript-eslint": "^8.56.1", }, "peerDependencies": { + "@react-native-async-storage/async-storage": "^3.0.1", + "@react-native-community/netinfo": "^12.0.1", "@tanstack/react-query": "^5.70.0", "appwrite": "^22.4.1", - "jotai": "^2.12.2", "react-native-appwrite": "^0.24.1", }, "optionalPeers": [ + "@react-native-async-storage/async-storage", + "@react-native-community/netinfo", "react-native-appwrite", ], }, }, "packages": { - "@apollo/client": ["@apollo/client@4.1.6", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@wry/caches": "^1.0.0", "@wry/equality": "^0.5.6", "@wry/trie": "^0.5.0", "graphql-tag": "^2.12.6", "optimism": "^0.18.0", "tslib": "^2.3.0" }, "peerDependencies": { "graphql": "^16.0.0", "graphql-ws": "^5.5.5 || ^6.0.3", "react": "^17.0.0 || ^18.0.0 || >=19.0.0-rc", "react-dom": "^17.0.0 || ^18.0.0 || >=19.0.0-rc", "rxjs": "^7.3.0", "subscriptions-transport-ws": "^0.9.0 || ^0.11.0" }, "optionalPeers": ["graphql-ws", "react", "react-dom", "subscriptions-transport-ws"] }, "sha512-ak8uzqmKeX3u9BziGf83RRyODAJKFkPG72hTNvEj4WjMWFmuKW2gGN1i3OfajKT6yuGjvo+n23ES2zqWDKFCZg=="], + "@0no-co/graphql.web": ["@0no-co/graphql.web@1.2.0", "", { "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0" }, "optionalPeers": ["graphql"] }, "sha512-/1iHy9TTr63gE1YcR5idjx8UREz1s0kFhydf3bBLCXyqjhkIc6igAzTOx3zPifCwFR87tsh/4Pa9cNts6d2otw=="], - "@ardatan/relay-compiler": ["@ardatan/relay-compiler@12.0.3", "", { "dependencies": { "@babel/generator": "^7.26.10", "@babel/parser": "^7.26.10", "@babel/runtime": "^7.26.10", "chalk": "^4.0.0", "fb-watchman": "^2.0.0", "immutable": "~3.7.6", "invariant": "^2.2.4", "nullthrows": "^1.1.1", "relay-runtime": "12.0.0", "signedsource": "^1.0.0" }, "peerDependencies": { "graphql": "*" }, "bin": { "relay-compiler": "bin/relay-compiler" } }, "sha512-mBDFOGvAoVlWaWqs3hm1AciGHSQE1rqFc/liZTyYz/Oek9yZdT5H26pH2zAFuEiTiBVPPyMuqf5VjOFPI2DGsQ=="], + "@0no-co/graphqlsp": ["@0no-co/graphqlsp@1.15.2", "", { "dependencies": { "@gql.tada/internal": "^1.0.0", "graphql": "^15.5.0 || ^16.0.0 || ^17.0.0" }, "peerDependencies": { "typescript": "^5.0.0" } }, "sha512-Ys031WnS3sTQQBtRTkQsYnw372OlW72ais4sp0oh2UMPRNyxxnq85zRfU4PIdoy9kWriysPT5BYAkgIxhbonFA=="], "@babel/code-frame": ["@babel/code-frame@7.29.0", "", { "dependencies": { "@babel/helper-validator-identifier": "^7.28.5", "js-tokens": "^4.0.0", "picocolors": "^1.1.1" } }, "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw=="], @@ -120,8 +127,6 @@ "@babel/plugin-syntax-flow": ["@babel/plugin-syntax-flow@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-D+OrJumc9McXNEBI/JmFnc/0uCM2/Y3PEBG3gfV3QIYkKv5pvnpzFrl1kYCrcHJP8nOeFB/SHi1IHz29pNGuew=="], - "@babel/plugin-syntax-import-assertions": ["@babel/plugin-syntax-import-assertions@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw=="], - "@babel/plugin-syntax-import-attributes": ["@babel/plugin-syntax-import-attributes@7.28.6", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.28.6" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw=="], "@babel/plugin-syntax-import-meta": ["@babel/plugin-syntax-import-meta@7.10.4", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g=="], @@ -238,14 +243,6 @@ "@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="], - "@bcoe/v8-coverage": ["@bcoe/v8-coverage@0.2.3", "", {}, "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw=="], - - "@envelop/core": ["@envelop/core@5.5.1", "", { "dependencies": { "@envelop/instrumentation": "^1.0.0", "@envelop/types": "^5.2.1", "@whatwg-node/promise-helpers": "^1.2.4", "tslib": "^2.5.0" } }, "sha512-3DQg8sFskDo386TkL5j12jyRAdip/8yzK3x7YGbZBgobZ4aKXrvDU0GppU0SnmrpQnNaiTUsxBs9LKkwQ/eyvw=="], - - "@envelop/instrumentation": ["@envelop/instrumentation@1.0.0", "", { "dependencies": { "@whatwg-node/promise-helpers": "^1.2.1", "tslib": "^2.5.0" } }, "sha512-cxgkB66RQB95H3X27jlnxCRNTmPuSTgmBAq6/4n2Dtv4hsk4yz8FadA1ggmd0uZzvKqWD6CR+WFgTjhDqg7eyw=="], - - "@envelop/types": ["@envelop/types@5.2.1", "", { "dependencies": { "@whatwg-node/promise-helpers": "^1.0.0", "tslib": "^2.5.0" } }, "sha512-CsFmA3u3c2QoLDTfEpGr4t25fjMU31nyvse7IzWTvb0ZycuPjMjb0fjlheh+PbhBYb9YLugnT2uY6Mwcg1o+Zg=="], - "@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.3", "", { "os": "aix", "cpu": "ppc64" }, "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg=="], "@esbuild/android-arm": ["@esbuild/android-arm@0.27.3", "", { "os": "android", "cpu": "arm" }, "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA=="], @@ -298,6 +295,22 @@ "@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.3", "", { "os": "win32", "cpu": "x64" }, "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA=="], + "@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.1", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ=="], + + "@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.2", "", {}, "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew=="], + + "@eslint/config-array": ["@eslint/config-array@0.23.2", "", { "dependencies": { "@eslint/object-schema": "^3.0.2", "debug": "^4.3.1", "minimatch": "^10.2.1" } }, "sha512-YF+fE6LV4v5MGWRGj7G404/OZzGNepVF8fxk7jqmqo3lrza7a0uUcDnROGRBG1WFC1omYUS/Wp1f42i0M+3Q3A=="], + + "@eslint/config-helpers": ["@eslint/config-helpers@0.5.2", "", { "dependencies": { "@eslint/core": "^1.1.0" } }, "sha512-a5MxrdDXEvqnIq+LisyCX6tQMPF/dSJpCfBgBauY+pNZ28yCtSsTvyTYrMhaI+LK26bVyCJfJkT0u8KIj2i1dQ=="], + + "@eslint/core": ["@eslint/core@1.1.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-/nr9K9wkr3P1EzFTdFdMoLuo1PmIxjmwvPozwoSodjNBdefGujXQUF93u1DDZpEaTuDvMsIQddsd35BwtrW9Xw=="], + + "@eslint/js": ["@eslint/js@10.0.1", "", { "peerDependencies": { "eslint": "^10.0.0" }, "optionalPeers": ["eslint"] }, "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA=="], + + "@eslint/object-schema": ["@eslint/object-schema@3.0.2", "", {}, "sha512-HOy56KJt48Bx8KmJ+XGQNSUMT/6dZee/M54XyUyuvTvPXJmsERRvBchsUVx1UMe1WwIH49XLAczNC7V2INsuUw=="], + + "@eslint/plugin-kit": ["@eslint/plugin-kit@0.6.0", "", { "dependencies": { "@eslint/core": "^1.1.0", "levn": "^0.4.1" } }, "sha512-bIZEUzOI1jkhviX2cp5vNyXQc6olzb2ohewQubuYlMXZ2Q/XjBO0x0XhGPvc9fjSIiUN0vw+0hq53BJ4eQSJKQ=="], + "@expo/cli": ["@expo/cli@55.0.12", "", { "dependencies": { "@expo/code-signing-certificates": "^0.0.6", "@expo/config": "~55.0.8", "@expo/config-plugins": "~55.0.6", "@expo/devcert": "^1.2.1", "@expo/env": "~2.1.1", "@expo/image-utils": "^0.8.12", "@expo/json-file": "^10.0.12", "@expo/log-box": "55.0.7", "@expo/metro": "~54.2.0", "@expo/metro-config": "~55.0.9", "@expo/osascript": "^2.4.2", "@expo/package-manager": "^1.10.3", "@expo/plist": "^0.5.2", "@expo/prebuild-config": "^55.0.7", "@expo/require-utils": "^55.0.2", "@expo/router-server": "^55.0.8", "@expo/schema-utils": "^55.0.2", "@expo/spawn-async": "^1.7.2", "@expo/ws-tunnel": "^1.0.1", "@expo/xcpretty": "^4.4.0", "@react-native/dev-middleware": "0.83.2", "accepts": "^1.3.8", "arg": "^5.0.2", "better-opn": "~3.0.2", "bplist-creator": "0.1.0", "bplist-parser": "^0.3.1", "chalk": "^4.0.0", "ci-info": "^3.3.0", "compression": "^1.7.4", "connect": "^3.7.0", "debug": "^4.3.4", "dnssd-advertise": "^1.1.3", "expo-server": "^55.0.5", "fetch-nodeshim": "^0.4.6", "getenv": "^2.0.0", "glob": "^13.0.0", "lan-network": "^0.2.0", "multitars": "^0.2.3", "node-forge": "^1.3.3", "npm-package-arg": "^11.0.0", "ora": "^3.4.0", "picomatch": "^4.0.3", "pretty-format": "^29.7.0", "progress": "^2.0.3", "prompts": "^2.3.2", "resolve-from": "^5.0.0", "semver": "^7.6.0", "send": "^0.19.0", "slugify": "^1.3.4", "source-map-support": "~0.5.21", "stacktrace-parser": "^0.1.10", "structured-headers": "^0.4.1", "terminal-link": "^2.1.1", "toqr": "^0.1.1", "wrap-ansi": "^7.0.0", "ws": "^8.12.1", "zod": "^3.25.76" }, "peerDependencies": { "expo": "*", "expo-router": "*", "react-native": "*" }, "optionalPeers": ["expo-router", "react-native"], "bin": { "expo-internal": "build/bin/cli" } }, "sha512-I2r0SPEx1svcaFXzyaC/Xd+U1y6mF7tbMRtVK3Z+ifB8pTe/H4UJ7CivTGpn8b5btsabNQjADAlnURgjP5dHYA=="], "@expo/code-signing-certificates": ["@expo/code-signing-certificates@0.0.6", "", { "dependencies": { "node-forge": "^1.3.3" } }, "sha512-iNe0puxwBNEcuua9gmTGzq+SuMDa0iATai1FlFTMHJ/vUmKvN/V//drXoLJkVb5i5H3iE/n/qIJxyoBnXouD0w=="], @@ -356,115 +369,21 @@ "@expo/xcpretty": ["@expo/xcpretty@4.4.1", "", { "dependencies": { "@babel/code-frame": "^7.20.0", "chalk": "^4.1.0", "js-yaml": "^4.1.0" }, "bin": { "excpretty": "build/cli.js" } }, "sha512-KZNxZvnGCtiM2aYYZ6Wz0Ix5r47dAvpNLApFtZWnSoERzAdOMzVBOPysBoM0JlF6FKWZ8GPqgn6qt3dV/8Zlpg=="], - "@fastify/busboy": ["@fastify/busboy@3.2.0", "", {}, "sha512-m9FVDXU3GT2ITSe0UaMA5rU3QkfC/UXtCU8y0gSN/GugTqtVldOBWIB5V6V3sbmenVZUIpU6f+mPEO2+m5iTaA=="], - - "@graphql-codegen/add": ["@graphql-codegen/add@6.0.0", "", { "dependencies": { "@graphql-codegen/plugin-helpers": "^6.0.0", "tslib": "~2.6.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "sha512-biFdaURX0KTwEJPQ1wkT6BRgNasqgQ5KbCI1a3zwtLtO7XTo7/vKITPylmiU27K5DSOWYnY/1jfSqUAEBuhZrQ=="], - - "@graphql-codegen/cli": ["@graphql-codegen/cli@6.1.2", "", { "dependencies": { "@babel/generator": "^7.18.13", "@babel/template": "^7.18.10", "@babel/types": "^7.18.13", "@graphql-codegen/client-preset": "^5.2.0", "@graphql-codegen/core": "^5.0.0", "@graphql-codegen/plugin-helpers": "^6.1.0", "@graphql-tools/apollo-engine-loader": "^8.0.0", "@graphql-tools/code-file-loader": "^8.0.0", "@graphql-tools/git-loader": "^8.0.0", "@graphql-tools/github-loader": "^9.0.0", "@graphql-tools/graphql-file-loader": "^8.0.0", "@graphql-tools/json-file-loader": "^8.0.0", "@graphql-tools/load": "^8.1.0", "@graphql-tools/url-loader": "^9.0.0", "@graphql-tools/utils": "^10.0.0", "@inquirer/prompts": "^7.8.2", "@whatwg-node/fetch": "^0.10.0", "chalk": "^4.1.0", "cosmiconfig": "^9.0.0", "debounce": "^2.0.0", "detect-indent": "^6.0.0", "graphql-config": "^5.1.1", "is-glob": "^4.0.1", "jiti": "^2.3.0", "json-to-pretty-yaml": "^1.2.2", "listr2": "^9.0.0", "log-symbols": "^4.0.0", "micromatch": "^4.0.5", "shell-quote": "^1.7.3", "string-env-interpolation": "^1.0.1", "ts-log": "^2.2.3", "tslib": "^2.4.0", "yaml": "^2.3.1", "yargs": "^17.0.0" }, "peerDependencies": { "@parcel/watcher": "^2.1.0", "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" }, "optionalPeers": ["@parcel/watcher"], "bin": { "gql-gen": "cjs/bin.js", "graphql-codegen": "cjs/bin.js", "graphql-codegen-esm": "esm/bin.js", "graphql-code-generator": "cjs/bin.js" } }, "sha512-BQ49LF0jnQNL12rU1RucTemoX1bHx8slR4B11nOrp4k5NTojhcc1A1czzU5wXCK/1+ezNHrVGONWg3jxZUy08w=="], - - "@graphql-codegen/client-preset": ["@graphql-codegen/client-preset@5.2.3", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.20.2", "@babel/template": "^7.20.7", "@graphql-codegen/add": "^6.0.0", "@graphql-codegen/gql-tag-operations": "5.1.3", "@graphql-codegen/plugin-helpers": "^6.1.0", "@graphql-codegen/typed-document-node": "^6.1.6", "@graphql-codegen/typescript": "^5.0.8", "@graphql-codegen/typescript-operations": "^5.0.8", "@graphql-codegen/visitor-plugin-common": "^6.2.3", "@graphql-tools/documents": "^1.0.0", "@graphql-tools/utils": "^10.0.0", "@graphql-typed-document-node/core": "3.2.0", "tslib": "~2.6.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0", "graphql-sock": "^1.0.0" }, "optionalPeers": ["graphql-sock"] }, "sha512-zgbk0dTY+KC/8TG00RGct6HnXWJU6jQaty3wAXKl1CvCXTKO73pW8Npph+RSJMTEEXb+QuJL3vyaPiGM1gw8sw=="], - - "@graphql-codegen/core": ["@graphql-codegen/core@5.0.0", "", { "dependencies": { "@graphql-codegen/plugin-helpers": "^6.0.0", "@graphql-tools/schema": "^10.0.0", "@graphql-tools/utils": "^10.0.0", "tslib": "~2.6.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "sha512-vLTEW0m8LbE4xgRwbFwCdYxVkJ1dBlVJbQyLb9Q7bHnVFgHAP982Xo8Uv7FuPBmON+2IbTjkCqhFLHVZbqpvjQ=="], - - "@graphql-codegen/gql-tag-operations": ["@graphql-codegen/gql-tag-operations@5.1.3", "", { "dependencies": { "@graphql-codegen/plugin-helpers": "^6.1.0", "@graphql-codegen/visitor-plugin-common": "6.2.3", "@graphql-tools/utils": "^10.0.0", "auto-bind": "~4.0.0", "tslib": "~2.6.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "sha512-yh/GTGW5Nf8f/zaCHZwWb04ItWAm+UfUJf7pb6n4SrqRxvWOSJk36LJ4l8UuDW1tmAOobjeXB8HSKSJsUjmA1g=="], - - "@graphql-codegen/plugin-helpers": ["@graphql-codegen/plugin-helpers@6.1.0", "", { "dependencies": { "@graphql-tools/utils": "^10.0.0", "change-case-all": "1.0.15", "common-tags": "1.8.2", "import-from": "4.0.0", "lodash": "~4.17.0", "tslib": "~2.6.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "sha512-JJypehWTcty9kxKiqH7TQOetkGdOYjY78RHlI+23qB59cV2wxjFFVf8l7kmuXS4cpGVUNfIjFhVr7A1W7JMtdA=="], - - "@graphql-codegen/schema-ast": ["@graphql-codegen/schema-ast@5.0.0", "", { "dependencies": { "@graphql-codegen/plugin-helpers": "^6.0.0", "@graphql-tools/utils": "^10.0.0", "tslib": "~2.6.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "sha512-jn7Q3PKQc0FxXjbpo9trxzlz/GSFQWxL042l0iC8iSbM/Ar+M7uyBwMtXPsev/3Razk+osQyreghIz0d2+6F7Q=="], - - "@graphql-codegen/typed-document-node": ["@graphql-codegen/typed-document-node@6.1.6", "", { "dependencies": { "@graphql-codegen/plugin-helpers": "^6.1.0", "@graphql-codegen/visitor-plugin-common": "6.2.3", "auto-bind": "~4.0.0", "change-case-all": "1.0.15", "tslib": "~2.6.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "sha512-USuQdUWBXij9HQl+GWXuLm05kjpOVwViBfnNi7ijES4HFwAmt/EDAnYSCfUoOHCfFQeWcfqYbtcUGJO9iXiSYQ=="], - - "@graphql-codegen/typescript": ["@graphql-codegen/typescript@5.0.8", "", { "dependencies": { "@graphql-codegen/plugin-helpers": "^6.1.0", "@graphql-codegen/schema-ast": "^5.0.0", "@graphql-codegen/visitor-plugin-common": "6.2.3", "auto-bind": "~4.0.0", "tslib": "~2.6.0" }, "peerDependencies": { "graphql": "^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "sha512-lUW6ari+rXP6tz5B0LXjmV9rEMOphoCZAkt+SJGObLQ6w6544ZsXSsRga/EJiSvZ1fRfm9yaFoErOZ56IVThyg=="], - - "@graphql-codegen/typescript-operations": ["@graphql-codegen/typescript-operations@5.0.8", "", { "dependencies": { "@graphql-codegen/plugin-helpers": "^6.1.0", "@graphql-codegen/typescript": "^5.0.8", "@graphql-codegen/visitor-plugin-common": "6.2.3", "auto-bind": "~4.0.0", "tslib": "~2.6.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0", "graphql-sock": "^1.0.0" }, "optionalPeers": ["graphql-sock"] }, "sha512-5H58DnDIy59Q+wcPRu13UnAS7fkMCW/vPI1+g8rHBmxuV9YGyGlVL9lE/fmJ06181hI7G9YGuUaoFYMJFU6bxQ=="], - - "@graphql-codegen/visitor-plugin-common": ["@graphql-codegen/visitor-plugin-common@6.2.3", "", { "dependencies": { "@graphql-codegen/plugin-helpers": "^6.1.0", "@graphql-tools/optimize": "^2.0.0", "@graphql-tools/relay-operation-optimizer": "^7.0.0", "@graphql-tools/utils": "^10.0.0", "auto-bind": "~4.0.0", "change-case-all": "1.0.15", "dependency-graph": "^1.0.0", "graphql-tag": "^2.11.0", "parse-filepath": "^1.0.2", "tslib": "~2.6.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "sha512-Rewl/QRFfIOXHFK3i/ts4VodsaB4N22kckH1zweTzq7SFodkfrqGrLa/MrGLJ/q6aUuqGiqao7f4Za2IjjkCxw=="], - - "@graphql-hive/signal": ["@graphql-hive/signal@2.0.0", "", {}, "sha512-Pz8wB3K0iU6ae9S1fWfsmJX24CcGeTo6hE7T44ucmV/ALKRj+bxClmqrYcDT7v3f0d12Rh4FAXBb6gon+WkDpQ=="], - - "@graphql-tools/apollo-engine-loader": ["@graphql-tools/apollo-engine-loader@8.0.28", "", { "dependencies": { "@graphql-tools/utils": "^11.0.0", "@whatwg-node/fetch": "^0.10.13", "sync-fetch": "0.6.0", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-MzgDrUuoxp6dZeo54zLBL3cEJKJtM3N/2RqK0rbPxPq5X2z6TUA7EGg8vIFTUkt5xelAsUrm8/4ai41ZDdxOng=="], - - "@graphql-tools/batch-execute": ["@graphql-tools/batch-execute@10.0.5", "", { "dependencies": { "@graphql-tools/utils": "^11.0.0", "@whatwg-node/promise-helpers": "^1.3.2", "dataloader": "^2.2.3", "tslib": "^2.8.1" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-dL13tXkfGvAzLq2XfzTKAy9logIcltKYRuPketxdh3Ok3U6PN1HKMCHfrE9cmtAsxD96/8Hlghz5AtM+LRv/ig=="], - - "@graphql-tools/code-file-loader": ["@graphql-tools/code-file-loader@8.1.28", "", { "dependencies": { "@graphql-tools/graphql-tag-pluck": "8.3.27", "@graphql-tools/utils": "^11.0.0", "globby": "^11.0.3", "tslib": "^2.4.0", "unixify": "^1.0.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-BL3Ft/PFlXDE5nNuqA36hYci7Cx+8bDrPDc8X3VSpZy9iKFBY+oQ+IwqnEHCkt8OSp2n2V0gqTg4u3fcQP1Kwg=="], - - "@graphql-tools/delegate": ["@graphql-tools/delegate@12.0.8", "", { "dependencies": { "@graphql-tools/batch-execute": "^10.0.5", "@graphql-tools/executor": "^1.4.13", "@graphql-tools/schema": "^10.0.29", "@graphql-tools/utils": "^11.0.0", "@repeaterjs/repeater": "^3.0.6", "@whatwg-node/promise-helpers": "^1.3.2", "dataloader": "^2.2.3", "tslib": "^2.8.1" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-yltGepWaJ9KsBY3QREJrZUKadhaiT4mO4ZO42hF/vfD2fIIOKZjn99qCSZBJ0YpVbLctPrgWrgDs3WgAl13fsA=="], - - "@graphql-tools/documents": ["@graphql-tools/documents@1.0.1", "", { "dependencies": { "lodash.sortby": "^4.7.0", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-aweoMH15wNJ8g7b2r4C4WRuJxZ0ca8HtNO54rkye/3duxTkW4fGBEutCx03jCIr5+a1l+4vFJNP859QnAVBVCA=="], - - "@graphql-tools/executor": ["@graphql-tools/executor@1.5.1", "", { "dependencies": { "@graphql-tools/utils": "^11.0.0", "@graphql-typed-document-node/core": "^3.2.0", "@repeaterjs/repeater": "^3.0.4", "@whatwg-node/disposablestack": "^0.0.6", "@whatwg-node/promise-helpers": "^1.0.0", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-n94Qcu875Mji9GQ52n5UbgOTxlgvFJicBPYD+FRks9HKIQpdNPjkkrKZUYNG51XKa+bf03rxNflm4+wXhoHHrA=="], - - "@graphql-tools/executor-common": ["@graphql-tools/executor-common@1.0.6", "", { "dependencies": { "@envelop/core": "^5.4.0", "@graphql-tools/utils": "^11.0.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-23/K5C+LSlHDI0mj2SwCJ33RcELCcyDUgABm1Z8St7u/4Z5+95i925H/NAjUyggRjiaY8vYtNiMOPE49aPX1sg=="], - - "@graphql-tools/executor-graphql-ws": ["@graphql-tools/executor-graphql-ws@3.1.4", "", { "dependencies": { "@graphql-tools/executor-common": "^1.0.6", "@graphql-tools/utils": "^11.0.0", "@whatwg-node/disposablestack": "^0.0.6", "graphql-ws": "^6.0.6", "isows": "^1.0.7", "tslib": "^2.8.1", "ws": "^8.18.3" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-wCQfWYLwg1JZmQ7rGaFy74AQyVFxpeqz19WWIGRgANiYlm+T0K3Hs6POgi0+nL3HvwxJIxhUlaRLFvkqm1zxSA=="], - - "@graphql-tools/executor-http": ["@graphql-tools/executor-http@3.1.0", "", { "dependencies": { "@graphql-hive/signal": "^2.0.0", "@graphql-tools/executor-common": "^1.0.6", "@graphql-tools/utils": "^11.0.0", "@repeaterjs/repeater": "^3.0.4", "@whatwg-node/disposablestack": "^0.0.6", "@whatwg-node/fetch": "^0.10.13", "@whatwg-node/promise-helpers": "^1.3.2", "meros": "^1.3.2", "tslib": "^2.8.1" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-DTaNU1rT2sxffwQlt+Aw68cHQWfGkjsaRk1D8nvG+DcCR8RNQo0d9qYt7pXIcfXYcQLb/OkABcGSuCfkopvHJg=="], - - "@graphql-tools/executor-legacy-ws": ["@graphql-tools/executor-legacy-ws@1.1.25", "", { "dependencies": { "@graphql-tools/utils": "^11.0.0", "@types/ws": "^8.0.0", "isomorphic-ws": "^5.0.0", "tslib": "^2.4.0", "ws": "^8.19.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-6uf4AEXO0QMxJ7AWKVPqEZXgYBJaiz5vf29X0boG8QtcqWy8mqkXKWLND2Swdx0SbEx0efoGFcjuKufUcB0ASQ=="], - - "@graphql-tools/git-loader": ["@graphql-tools/git-loader@8.0.32", "", { "dependencies": { "@graphql-tools/graphql-tag-pluck": "8.3.27", "@graphql-tools/utils": "^11.0.0", "is-glob": "4.0.3", "micromatch": "^4.0.8", "tslib": "^2.4.0", "unixify": "^1.0.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-H5HTp2vevv0rRMEnCJBVmVF8md3LpJI1C1+d6OtzvmuONJ8mOX2mkf9rtoqwiztynVegaDUekvMFsc9k5iE2WA=="], - - "@graphql-tools/github-loader": ["@graphql-tools/github-loader@9.0.6", "", { "dependencies": { "@graphql-tools/executor-http": "^3.0.6", "@graphql-tools/graphql-tag-pluck": "^8.3.27", "@graphql-tools/utils": "^11.0.0", "@whatwg-node/fetch": "^0.10.13", "@whatwg-node/promise-helpers": "^1.0.0", "sync-fetch": "0.6.0", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-hhlt2MMkRcvDva/qyzqFddXzaMmRnriJ0Ts+/LcNeYnB8hcEqRMpF9RCsHYjo1mFRaiu8i4PSIpXyyFu3To7Ow=="], - - "@graphql-tools/graphql-file-loader": ["@graphql-tools/graphql-file-loader@8.1.9", "", { "dependencies": { "@graphql-tools/import": "7.1.9", "@graphql-tools/utils": "^11.0.0", "globby": "^11.0.3", "tslib": "^2.4.0", "unixify": "^1.0.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-rkLK46Q62Zxift8B6Kfw6h8SH3pCR3DPCfNeC/lpLwYReezZz+2ARuLDFZjQGjW+4lpMwiAw8CIxDyQAUgqU6A=="], - - "@graphql-tools/graphql-tag-pluck": ["@graphql-tools/graphql-tag-pluck@8.3.27", "", { "dependencies": { "@babel/core": "^7.26.10", "@babel/parser": "^7.26.10", "@babel/plugin-syntax-import-assertions": "^7.26.0", "@babel/traverse": "^7.26.10", "@babel/types": "^7.26.10", "@graphql-tools/utils": "^11.0.0", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-CJ0WVXhGYsfFngpRrAAcjRHyxSDHx4dEz2W15bkwvt9he/AWhuyXm07wuGcoLrl0q0iQp1BiRjU7D8SxWZo3JQ=="], - - "@graphql-tools/import": ["@graphql-tools/import@7.1.9", "", { "dependencies": { "@graphql-tools/utils": "^11.0.0", "@theguild/federation-composition": "^0.21.1", "resolve-from": "5.0.0", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-mHzOgyfzsAgstaZPIFEtKg4GVH4FbDHeHYrSs73mAPKS5F59/FlRuUJhAoRnxbVnc3qIZ6EsWBjOjNbnPK8viA=="], - - "@graphql-tools/json-file-loader": ["@graphql-tools/json-file-loader@8.0.26", "", { "dependencies": { "@graphql-tools/utils": "^11.0.0", "globby": "^11.0.3", "tslib": "^2.4.0", "unixify": "^1.0.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-kwy9IFi5QtXXTLBgWkvA1RqsZeJDn0CxsTbhNlziCzmga9fNo7qtZ18k9FYIq3EIoQQlok+b7W7yeyJATA2xhw=="], - - "@graphql-tools/load": ["@graphql-tools/load@8.1.8", "", { "dependencies": { "@graphql-tools/schema": "^10.0.31", "@graphql-tools/utils": "^11.0.0", "p-limit": "3.1.0", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-gxO662b64qZSToK3N6XUxWG5E6HOUjlg5jEnmGvD4bMtGJ0HwEe/BaVZbBQemCfLkxYjwRIBiVfOY9o0JyjZJg=="], - - "@graphql-tools/merge": ["@graphql-tools/merge@9.1.7", "", { "dependencies": { "@graphql-tools/utils": "^11.0.0", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-Y5E1vTbTabvcXbkakdFUt4zUIzB1fyaEnVmIWN0l0GMed2gdD01TpZWLUm4RNAxpturvolrb24oGLQrBbPLSoQ=="], - - "@graphql-tools/optimize": ["@graphql-tools/optimize@2.0.0", "", { "dependencies": { "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-nhdT+CRGDZ+bk68ic+Jw1OZ99YCDIKYA5AlVAnBHJvMawSx9YQqQAIj4refNc1/LRieGiuWvhbG3jvPVYho0Dg=="], - - "@graphql-tools/relay-operation-optimizer": ["@graphql-tools/relay-operation-optimizer@7.0.27", "", { "dependencies": { "@ardatan/relay-compiler": "^12.0.3", "@graphql-tools/utils": "^11.0.0", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-rdkL1iDMFaGDiHWd7Bwv7hbhrhnljkJaD0MXeqdwQlZVgVdUDlMot2WuF7CEKVgijpH6eSC6AxXMDeqVgSBS2g=="], + "@gql.tada/cli-utils": ["@gql.tada/cli-utils@1.7.2", "", { "dependencies": { "@0no-co/graphqlsp": "^1.12.13", "@gql.tada/internal": "1.0.8", "graphql": "^15.5.0 || ^16.0.0 || ^17.0.0" }, "peerDependencies": { "@gql.tada/svelte-support": "1.0.1", "@gql.tada/vue-support": "1.0.1", "typescript": "^5.0.0" }, "optionalPeers": ["@gql.tada/svelte-support", "@gql.tada/vue-support"] }, "sha512-Qbc7hbLvCz6IliIJpJuKJa9p05b2Jona7ov7+qofCsMRxHRZE1kpAmZMvL8JCI4c0IagpIlWNaMizXEQUe8XjQ=="], - "@graphql-tools/schema": ["@graphql-tools/schema@10.0.31", "", { "dependencies": { "@graphql-tools/merge": "^9.1.7", "@graphql-tools/utils": "^11.0.0", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-ZewRgWhXef6weZ0WiP7/MV47HXiuFbFpiDUVLQl6mgXsWSsGELKFxQsyUCBos60Qqy1JEFAIu3Ns6GGYjGkqkQ=="], - - "@graphql-tools/url-loader": ["@graphql-tools/url-loader@9.0.6", "", { "dependencies": { "@graphql-tools/executor-graphql-ws": "^3.1.2", "@graphql-tools/executor-http": "^3.0.6", "@graphql-tools/executor-legacy-ws": "^1.1.25", "@graphql-tools/utils": "^11.0.0", "@graphql-tools/wrap": "^11.1.1", "@types/ws": "^8.0.0", "@whatwg-node/fetch": "^0.10.13", "@whatwg-node/promise-helpers": "^1.0.0", "isomorphic-ws": "^5.0.0", "sync-fetch": "0.6.0", "tslib": "^2.4.0", "ws": "^8.19.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-QdJI3f7ANDMYfYazRgJzzybznjOrQAOuDXweC9xmKgPZoTqNxEAsatiy69zcpTf6092taJLyrqRH6R7xUTzf4A=="], - - "@graphql-tools/utils": ["@graphql-tools/utils@10.11.0", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@whatwg-node/promise-helpers": "^1.0.0", "cross-inspect": "1.0.1", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-iBFR9GXIs0gCD+yc3hoNswViL1O5josI33dUqiNStFI/MHLCEPduasceAcazRH77YONKNiviHBV8f7OgcT4o2Q=="], - - "@graphql-tools/wrap": ["@graphql-tools/wrap@11.1.8", "", { "dependencies": { "@graphql-tools/delegate": "^12.0.8", "@graphql-tools/schema": "^10.0.29", "@graphql-tools/utils": "^11.0.0", "@whatwg-node/promise-helpers": "^1.3.2", "tslib": "^2.8.1" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-VnU7K6IDvj7kM9Viz6oAQNc6lV380u7oOG1hYau5pzHB+h1VrTYg/jHXNtWrXwB88lhCgGHjrQCJJt4wz4QdQQ=="], + "@gql.tada/internal": ["@gql.tada/internal@1.0.8", "", { "dependencies": { "@0no-co/graphql.web": "^1.0.5" }, "peerDependencies": { "graphql": "^15.5.0 || ^16.0.0 || ^17.0.0", "typescript": "^5.0.0" } }, "sha512-XYdxJhtHC5WtZfdDqtKjcQ4d7R1s0d1rnlSs3OcBEUbYiPoJJfZU7tWsVXuv047Z6msvmr4ompJ7eLSK5Km57g=="], "@graphql-typed-document-node/core": ["@graphql-typed-document-node/core@3.2.0", "", { "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ=="], "@happy-dom/global-registrator": ["@happy-dom/global-registrator@20.7.0", "", { "dependencies": { "@types/node": ">=20.0.0", "happy-dom": "^20.7.0" } }, "sha512-JdsfSUVeWDP8klYL4y4C4Fae0nAv2V/2W+gHhdiuktyKGZvbSZfJpsk4loakPhTtxt91KHdDroXCCZcFIJrfYQ=="], - "@inquirer/ansi": ["@inquirer/ansi@1.0.2", "", {}, "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ=="], - - "@inquirer/checkbox": ["@inquirer/checkbox@4.3.2", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/core": "^10.3.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA=="], - - "@inquirer/confirm": ["@inquirer/confirm@5.1.21", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ=="], - - "@inquirer/core": ["@inquirer/core@10.3.2", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "cli-width": "^4.1.0", "mute-stream": "^2.0.0", "signal-exit": "^4.1.0", "wrap-ansi": "^6.2.0", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A=="], - - "@inquirer/editor": ["@inquirer/editor@4.2.23", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/external-editor": "^1.0.3", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ=="], - - "@inquirer/expand": ["@inquirer/expand@4.0.23", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew=="], - - "@inquirer/external-editor": ["@inquirer/external-editor@1.0.3", "", { "dependencies": { "chardet": "^2.1.1", "iconv-lite": "^0.7.0" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA=="], - - "@inquirer/figures": ["@inquirer/figures@1.0.15", "", {}, "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g=="], - - "@inquirer/input": ["@inquirer/input@4.3.1", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g=="], + "@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="], - "@inquirer/number": ["@inquirer/number@3.0.23", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg=="], + "@humanfs/node": ["@humanfs/node@0.16.7", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ=="], - "@inquirer/password": ["@inquirer/password@4.0.23", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA=="], + "@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="], - "@inquirer/prompts": ["@inquirer/prompts@7.10.1", "", { "dependencies": { "@inquirer/checkbox": "^4.3.2", "@inquirer/confirm": "^5.1.21", "@inquirer/editor": "^4.2.23", "@inquirer/expand": "^4.0.23", "@inquirer/input": "^4.3.1", "@inquirer/number": "^3.0.23", "@inquirer/password": "^4.0.23", "@inquirer/rawlist": "^4.1.11", "@inquirer/search": "^3.2.2", "@inquirer/select": "^4.4.2" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg=="], - - "@inquirer/rawlist": ["@inquirer/rawlist@4.1.11", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw=="], - - "@inquirer/search": ["@inquirer/search@3.2.2", "", { "dependencies": { "@inquirer/core": "^10.3.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA=="], - - "@inquirer/select": ["@inquirer/select@4.4.2", "", { "dependencies": { "@inquirer/ansi": "^1.0.2", "@inquirer/core": "^10.3.2", "@inquirer/figures": "^1.0.15", "@inquirer/type": "^3.0.10", "yoctocolors-cjs": "^2.1.3" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w=="], - - "@inquirer/type": ["@inquirer/type@3.0.10", "", { "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA=="], + "@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="], "@isaacs/ttlcache": ["@isaacs/ttlcache@1.4.1", "", {}, "sha512-RQgQ4uQ+pLbqXfOmieB91ejmLwvSgv9nLx6sT6sD83s7umBypgg+OIBOBbEUiJXrfpnp9j0mRhYYdzp9uqq3lA=="], @@ -472,32 +391,14 @@ "@istanbuljs/schema": ["@istanbuljs/schema@0.1.3", "", {}, "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA=="], - "@jest/console": ["@jest/console@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "jest-message-util": "^29.7.0", "jest-util": "^29.7.0", "slash": "^3.0.0" } }, "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg=="], - - "@jest/core": ["@jest/core@29.7.0", "", { "dependencies": { "@jest/console": "^29.7.0", "@jest/reporters": "^29.7.0", "@jest/test-result": "^29.7.0", "@jest/transform": "^29.7.0", "@jest/types": "^29.6.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "ci-info": "^3.2.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", "jest-changed-files": "^29.7.0", "jest-config": "^29.7.0", "jest-haste-map": "^29.7.0", "jest-message-util": "^29.7.0", "jest-regex-util": "^29.6.3", "jest-resolve": "^29.7.0", "jest-resolve-dependencies": "^29.7.0", "jest-runner": "^29.7.0", "jest-runtime": "^29.7.0", "jest-snapshot": "^29.7.0", "jest-util": "^29.7.0", "jest-validate": "^29.7.0", "jest-watcher": "^29.7.0", "micromatch": "^4.0.4", "pretty-format": "^29.7.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" }, "optionalPeers": ["node-notifier"] }, "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg=="], - "@jest/create-cache-key-function": ["@jest/create-cache-key-function@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3" } }, "sha512-4QqS3LY5PBmTRHj9sAg1HLoPzqAI0uOX6wI/TRqHIcOxlFidy6YEmCQJk6FSZjNLGCeubDMfmkWL+qaLKhSGQA=="], "@jest/environment": ["@jest/environment@29.7.0", "", { "dependencies": { "@jest/fake-timers": "^29.7.0", "@jest/types": "^29.6.3", "@types/node": "*", "jest-mock": "^29.7.0" } }, "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw=="], - "@jest/expect": ["@jest/expect@29.7.0", "", { "dependencies": { "expect": "^29.7.0", "jest-snapshot": "^29.7.0" } }, "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ=="], - - "@jest/expect-utils": ["@jest/expect-utils@29.7.0", "", { "dependencies": { "jest-get-type": "^29.6.3" } }, "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA=="], - "@jest/fake-timers": ["@jest/fake-timers@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3", "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", "jest-message-util": "^29.7.0", "jest-mock": "^29.7.0", "jest-util": "^29.7.0" } }, "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ=="], - "@jest/globals": ["@jest/globals@29.7.0", "", { "dependencies": { "@jest/environment": "^29.7.0", "@jest/expect": "^29.7.0", "@jest/types": "^29.6.3", "jest-mock": "^29.7.0" } }, "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ=="], - - "@jest/reporters": ["@jest/reporters@29.7.0", "", { "dependencies": { "@bcoe/v8-coverage": "^0.2.3", "@jest/console": "^29.7.0", "@jest/test-result": "^29.7.0", "@jest/transform": "^29.7.0", "@jest/types": "^29.6.3", "@jridgewell/trace-mapping": "^0.3.18", "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", "glob": "^7.1.3", "graceful-fs": "^4.2.9", "istanbul-lib-coverage": "^3.0.0", "istanbul-lib-instrument": "^6.0.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", "jest-message-util": "^29.7.0", "jest-util": "^29.7.0", "jest-worker": "^29.7.0", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", "v8-to-istanbul": "^9.0.1" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" }, "optionalPeers": ["node-notifier"] }, "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg=="], - "@jest/schemas": ["@jest/schemas@29.6.3", "", { "dependencies": { "@sinclair/typebox": "^0.27.8" } }, "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA=="], - "@jest/source-map": ["@jest/source-map@29.6.3", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.18", "callsites": "^3.0.0", "graceful-fs": "^4.2.9" } }, "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw=="], - - "@jest/test-result": ["@jest/test-result@29.7.0", "", { "dependencies": { "@jest/console": "^29.7.0", "@jest/types": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA=="], - - "@jest/test-sequencer": ["@jest/test-sequencer@29.7.0", "", { "dependencies": { "@jest/test-result": "^29.7.0", "graceful-fs": "^4.2.9", "jest-haste-map": "^29.7.0", "slash": "^3.0.0" } }, "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw=="], - "@jest/transform": ["@jest/transform@29.7.0", "", { "dependencies": { "@babel/core": "^7.11.6", "@jest/types": "^29.6.3", "@jridgewell/trace-mapping": "^0.3.18", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", "jest-haste-map": "^29.7.0", "jest-regex-util": "^29.6.3", "jest-util": "^29.7.0", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", "write-file-atomic": "^4.0.2" } }, "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw=="], "@jest/types": ["@jest/types@29.6.3", "", { "dependencies": { "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", "@types/yargs": "^17.0.8", "chalk": "^4.0.0" } }, "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw=="], @@ -516,11 +417,9 @@ "@noble/hashes": ["@noble/hashes@2.0.1", "", {}, "sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw=="], - "@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="], - - "@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="], + "@react-native-async-storage/async-storage": ["@react-native-async-storage/async-storage@3.0.1", "", { "dependencies": { "idb": "8.0.3" }, "peerDependencies": { "react": "*", "react-native": "*" } }, "sha512-VHwHb19sMg4Xh3W5M6YmJ/HSm1uh8RYFa6Dozm9o/jVYTYUgz2BmDXqXF7sum3glQaR34/hlwVc94px1sSdC2A=="], - "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="], + "@react-native-community/netinfo": ["@react-native-community/netinfo@12.0.1", "", { "peerDependencies": { "react": "*", "react-native": ">=0.59" } }, "sha512-P/3caXIvfYSJG8AWJVefukg+ZGRPs+M4Lp3pNJtgcTYoJxCjWrKQGNnCkj/Cz//zWa/avGed0i/wzm0T8vV2IQ=="], "@react-native/assets-registry": ["@react-native/assets-registry@0.84.0", "", {}, "sha512-YiU9h1IN0pvvZsHbd03MaD7mE2q+ySaKMlE9tWK+3iiwtbEaMQOsMUuSJ1er2LU6ERMWfhfvCYgWpKRGOMeN8A=="], @@ -546,8 +445,6 @@ "@react-native/virtualized-lists": ["@react-native/virtualized-lists@0.84.0", "", { "dependencies": { "invariant": "^2.2.4", "nullthrows": "^1.1.1" }, "peerDependencies": { "@types/react": "^19.2.0", "react": "*", "react-native": "*" }, "optionalPeers": ["@types/react"] }, "sha512-ugwSj0Gb4MYrcm8uQrQw8qHPx5RKGDLuZRAP/AuwneFizHx8YCLBEFbOYRGWgxHBRtkJ70D1o+jpIx3CK3p5lw=="], - "@repeaterjs/repeater": ["@repeaterjs/repeater@3.0.6", "", {}, "sha512-Javneu5lsuhwNCryN+pXH93VPQ8g0dBX7wItHFgYiwQmzE1sVdg5tWHiOgHywzL2W21XQopa7IwIEnNbmeUJYA=="], - "@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.59.0", "", { "os": "android", "cpu": "arm" }, "sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg=="], "@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.59.0", "", { "os": "android", "cpu": "arm64" }, "sha512-hZ+Zxj3SySm4A/DylsDKZAeVg0mvi++0PYVceVyX7hemkw7OreKdCvW2oQ3T1FMZvCaQXqOTHb8qmBShoqk69Q=="], @@ -604,18 +501,26 @@ "@sinonjs/fake-timers": ["@sinonjs/fake-timers@10.3.0", "", { "dependencies": { "@sinonjs/commons": "^3.0.0" } }, "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA=="], + "@tanstack/query-async-storage-persister": ["@tanstack/query-async-storage-persister@5.90.24", "", { "dependencies": { "@tanstack/query-core": "5.90.20", "@tanstack/query-persist-client-core": "5.92.1" } }, "sha512-3mljhSqeyu4xqF6BzNAzCe5MbteWPlOWHegLLmgiyppAENjaE0HpJcJAHlKaGhrP5IUhh3zytxW0gSydjmgwIw=="], + "@tanstack/query-core": ["@tanstack/query-core@5.90.20", "", {}, "sha512-OMD2HLpNouXEfZJWcKeVKUgQ5n+n3A2JFmBaScpNDUqSrQSjiveC7dKMe53uJUg1nDG16ttFPz2xfilz6i2uVg=="], + "@tanstack/query-devtools": ["@tanstack/query-devtools@5.93.0", "", {}, "sha512-+kpsx1NQnOFTZsw6HAFCW3HkKg0+2cepGtAWXjiiSOJJ1CtQpt72EE2nyZb+AjAbLRPoeRmPJ8MtQd8r8gsPdg=="], + + "@tanstack/query-persist-client-core": ["@tanstack/query-persist-client-core@5.92.1", "", { "dependencies": { "@tanstack/query-core": "5.90.20" } }, "sha512-XGzB1lulFrGc8UwQnMI12r71R7ock/XOZvDaz3Fu3xrxCFwLHuFcABAOkIolS/6hFHe0pRdsBRXd4Q8ECqiCug=="], + "@tanstack/react-query": ["@tanstack/react-query@5.90.21", "", { "dependencies": { "@tanstack/query-core": "5.90.20" }, "peerDependencies": { "react": "^18 || ^19" } }, "sha512-0Lu6y5t+tvlTJMTO7oh5NSpJfpg/5D41LlThfepTixPYkJ0sE2Jj0m0f6yYqujBwIXlId87e234+MxG3D3g7kg=="], + "@tanstack/react-query-devtools": ["@tanstack/react-query-devtools@5.91.3", "", { "dependencies": { "@tanstack/query-devtools": "5.93.0" }, "peerDependencies": { "@tanstack/react-query": "^5.90.20", "react": "^18 || ^19" } }, "sha512-nlahjMtd/J1h7IzOOfqeyDh5LNfG0eULwlltPEonYy0QL+nqrBB+nyzJfULV+moL7sZyxc2sHdNJki+vLA9BSA=="], + + "@tanstack/react-query-persist-client": ["@tanstack/react-query-persist-client@5.90.24", "", { "dependencies": { "@tanstack/query-persist-client-core": "5.92.1" }, "peerDependencies": { "@tanstack/react-query": "^5.90.21", "react": "^18 || ^19" } }, "sha512-FkfU37vHq61Efr/qGiz+CUNmGfCky1jjsaZFuS5MsWwA9vPHudCwmdirgyTx+RfcQxyHON904q/pc48zrIEhxg=="], + "@testing-library/dom": ["@testing-library/dom@10.4.1", "", { "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", "@types/aria-query": "^5.0.1", "aria-query": "5.3.0", "dom-accessibility-api": "^0.5.9", "lz-string": "^1.5.0", "picocolors": "1.1.1", "pretty-format": "^27.0.2" } }, "sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg=="], "@testing-library/react": ["@testing-library/react@16.3.2", "", { "dependencies": { "@babel/runtime": "^7.12.5" }, "peerDependencies": { "@testing-library/dom": "^10.0.0", "@types/react": "^18.0.0 || ^19.0.0", "@types/react-dom": "^18.0.0 || ^19.0.0", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react", "@types/react-dom"] }, "sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g=="], "@testing-library/react-hooks": ["@testing-library/react-hooks@8.0.1", "", { "dependencies": { "@babel/runtime": "^7.12.5", "react-error-boundary": "^3.1.0" }, "peerDependencies": { "@types/react": "^16.9.0 || ^17.0.0", "react": "^16.9.0 || ^17.0.0", "react-dom": "^16.9.0 || ^17.0.0", "react-test-renderer": "^16.9.0 || ^17.0.0" }, "optionalPeers": ["@types/react", "react-dom", "react-test-renderer"] }, "sha512-Aqhl2IVmLt8IovEVarNDFuJDVWVvhnr9/GCU6UUnrYXwgDFF9h2L2o2P9KBni1AST5sT6riAyoukFLyjQUgD/g=="], - "@theguild/federation-composition": ["@theguild/federation-composition@0.21.3", "", { "dependencies": { "constant-case": "^3.0.4", "debug": "4.4.3", "json5": "^2.2.3", "lodash.sortby": "^4.7.0" }, "peerDependencies": { "graphql": "^16.0.0" } }, "sha512-+LlHTa4UbRpZBog3ggAxjYIFvdfH3UMvvBUptur19TMWkqU4+n3GmN+mDjejU+dyBXIG27c25RsiQP1HyvM99g=="], - "@types/aria-query": ["@types/aria-query@5.0.4", "", {}, "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw=="], "@types/babel__core": ["@types/babel__core@7.20.5", "", { "dependencies": { "@babel/parser": "^7.20.7", "@babel/types": "^7.20.7", "@types/babel__generator": "*", "@types/babel__template": "*", "@types/babel__traverse": "*" } }, "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA=="], @@ -628,6 +533,8 @@ "@types/bun": ["@types/bun@1.3.9", "", { "dependencies": { "bun-types": "1.3.9" } }, "sha512-KQ571yULOdWJiMH+RIWIOZ7B2RXQGpL1YQrBtLIV3FqDcCu6FsbFUBwhdKUlCKUpS3PJDsHlJ1QKlpxoVR+xtw=="], + "@types/esrecurse": ["@types/esrecurse@4.3.1", "", {}, "sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw=="], + "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="], "@types/graceful-fs": ["@types/graceful-fs@4.1.9", "", { "dependencies": { "@types/node": "*" } }, "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ=="], @@ -640,7 +547,7 @@ "@types/istanbul-reports": ["@types/istanbul-reports@3.0.4", "", { "dependencies": { "@types/istanbul-lib-report": "*" } }, "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ=="], - "@types/jest": ["@types/jest@29.5.14", "", { "dependencies": { "expect": "^29.0.0", "pretty-format": "^29.0.0" } }, "sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ=="], + "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="], "@types/node": ["@types/node@25.3.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-4K3bqJpXpqfg2XKGK9bpDTc6xO/xoUP/RBWS7AtRMug6zZFaRekiLzjVtAoZMquxoAbzBvy5nxQ7veS5eYzf8A=="], @@ -656,23 +563,27 @@ "@types/yargs-parser": ["@types/yargs-parser@21.0.3", "", {}, "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ=="], - "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], + "@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.56.1", "", { "dependencies": { "@eslint-community/regexpp": "^4.12.2", "@typescript-eslint/scope-manager": "8.56.1", "@typescript-eslint/type-utils": "8.56.1", "@typescript-eslint/utils": "8.56.1", "@typescript-eslint/visitor-keys": "8.56.1", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.56.1", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-Jz9ZztpB37dNC+HU2HI28Bs9QXpzCz+y/twHOwhyrIRdbuVDxSytJNDl6z/aAKlaRIwC7y8wJdkBv7FxYGgi0A=="], + + "@typescript-eslint/parser": ["@typescript-eslint/parser@8.56.1", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.56.1", "@typescript-eslint/types": "8.56.1", "@typescript-eslint/typescript-estree": "8.56.1", "@typescript-eslint/visitor-keys": "8.56.1", "debug": "^4.4.3" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-klQbnPAAiGYFyI02+znpBRLyjL4/BrBd0nyWkdC0s/6xFLkXYQ8OoRrSkqacS1ddVxf/LDyODIKbQ5TgKAf/Fg=="], + + "@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.56.1", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.56.1", "@typescript-eslint/types": "^8.56.1", "debug": "^4.4.3" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-TAdqQTzHNNvlVFfR+hu2PDJrURiwKsUvxFn1M0h95BB8ah5jejas08jUWG4dBA68jDMI988IvtfdAI53JzEHOQ=="], - "@whatwg-node/disposablestack": ["@whatwg-node/disposablestack@0.0.6", "", { "dependencies": { "@whatwg-node/promise-helpers": "^1.0.0", "tslib": "^2.6.3" } }, "sha512-LOtTn+JgJvX8WfBVJtF08TGrdjuFzGJc4mkP8EdDI8ADbvO7kiexYep1o8dwnt0okb0jYclCDXF13xU7Ge4zSw=="], + "@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.56.1", "", { "dependencies": { "@typescript-eslint/types": "8.56.1", "@typescript-eslint/visitor-keys": "8.56.1" } }, "sha512-YAi4VDKcIZp0O4tz/haYKhmIDZFEUPOreKbfdAN3SzUDMcPhJ8QI99xQXqX+HoUVq8cs85eRKnD+rne2UAnj2w=="], - "@whatwg-node/fetch": ["@whatwg-node/fetch@0.10.13", "", { "dependencies": { "@whatwg-node/node-fetch": "^0.8.3", "urlpattern-polyfill": "^10.0.0" } }, "sha512-b4PhJ+zYj4357zwk4TTuF2nEe0vVtOrwdsrNo5hL+u1ojXNhh1FgJ6pg1jzDlwlT4oBdzfSwaBwMCtFCsIWg8Q=="], + "@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.56.1", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-qOtCYzKEeyr3aR9f28mPJqBty7+DBqsdd63eO0yyDwc6vgThj2UjWfJIcsFeSucYydqcuudMOprZ+x1SpF3ZuQ=="], - "@whatwg-node/node-fetch": ["@whatwg-node/node-fetch@0.8.5", "", { "dependencies": { "@fastify/busboy": "^3.1.1", "@whatwg-node/disposablestack": "^0.0.6", "@whatwg-node/promise-helpers": "^1.3.2", "tslib": "^2.6.3" } }, "sha512-4xzCl/zphPqlp9tASLVeUhB5+WJHbuWGYpfoC2q1qh5dw0AqZBW7L27V5roxYWijPxj4sspRAAoOH3d2ztaHUQ=="], + "@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.56.1", "", { "dependencies": { "@typescript-eslint/types": "8.56.1", "@typescript-eslint/typescript-estree": "8.56.1", "@typescript-eslint/utils": "8.56.1", "debug": "^4.4.3", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-yB/7dxi7MgTtGhZdaHCemf7PuwrHMenHjmzgUW1aJpO+bBU43OycnM3Wn+DdvDO/8zzA9HlhaJ0AUGuvri4oGg=="], - "@whatwg-node/promise-helpers": ["@whatwg-node/promise-helpers@1.3.2", "", { "dependencies": { "tslib": "^2.6.3" } }, "sha512-Nst5JdK47VIl9UcGwtv2Rcgyn5lWtZ0/mhRQ4G8NN2isxpq2TO30iqHzmwoJycjWuyUfg3GFXqP/gFHXeV57IA=="], + "@typescript-eslint/types": ["@typescript-eslint/types@8.56.1", "", {}, "sha512-dbMkdIUkIkchgGDIv7KLUpa0Mda4IYjo4IAMJUZ+3xNoUXxMsk9YtKpTHSChRS85o+H9ftm51gsK1dZReY9CVw=="], - "@wry/caches": ["@wry/caches@1.0.1", "", { "dependencies": { "tslib": "^2.3.0" } }, "sha512-bXuaUNLVVkD20wcGBWRyo7j9N3TxePEWFZj2Y+r9OoUzfqmavM84+mFykRicNsBqatba5JLay1t48wxaXaWnlA=="], + "@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.56.1", "", { "dependencies": { "@typescript-eslint/project-service": "8.56.1", "@typescript-eslint/tsconfig-utils": "8.56.1", "@typescript-eslint/types": "8.56.1", "@typescript-eslint/visitor-keys": "8.56.1", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", "tinyglobby": "^0.2.15", "ts-api-utils": "^2.4.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-qzUL1qgalIvKWAf9C1HpvBjif+Vm6rcT5wZd4VoMb9+Km3iS3Cv9DY6dMRMDtPnwRAFyAi7YXJpTIEXLvdfPxg=="], - "@wry/context": ["@wry/context@0.7.4", "", { "dependencies": { "tslib": "^2.3.0" } }, "sha512-jmT7Sb4ZQWI5iyu3lobQxICu2nC/vbUhP0vIdd6tHC9PTfenmRmuIFqktc6GH9cgi+ZHnsLWPvfSvc4DrYmKiQ=="], + "@typescript-eslint/utils": ["@typescript-eslint/utils@8.56.1", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", "@typescript-eslint/scope-manager": "8.56.1", "@typescript-eslint/types": "8.56.1", "@typescript-eslint/typescript-estree": "8.56.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-HPAVNIME3tABJ61siYlHzSWCGtOoeP2RTIaHXFMPqjrQKCGB9OgUVdiNgH7TJS2JNIQ5qQ4RsAUDuGaGme/KOA=="], - "@wry/equality": ["@wry/equality@0.5.7", "", { "dependencies": { "tslib": "^2.3.0" } }, "sha512-BRFORjsTuQv5gxcXsuDXx6oGRhuVsEGwZy6LOzRRfgu+eSfxbhUQ9L9YtSEIuIjY/o7g3iWFjrc5eSY1GXP2Dw=="], + "@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.56.1", "", { "dependencies": { "@typescript-eslint/types": "8.56.1", "eslint-visitor-keys": "^5.0.0" } }, "sha512-KiROIzYdEV85YygXw6BI/Dx4fnBlFQu6Mq4QE4MOH9fFnhohw6wX/OAvDY2/C+ut0I3RSPKenvZJIVYqJNkhEw=="], - "@wry/trie": ["@wry/trie@0.5.0", "", { "dependencies": { "tslib": "^2.3.0" } }, "sha512-FNoYzHawTMk/6KMQoEG5O4PuioX19UbwdQKF44yw0nLfOypfQdjtfZzo/UIJWAJ23sNIFbD1Ug9lbaDGMwbqQA=="], + "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="], "@xmldom/xmldom": ["@xmldom/xmldom@0.8.11", "", {}, "sha512-cQzWCtO6C8TQiYl1ruKNn2U6Ao4o4WBBcbL61yJl84x+j5sOWWFU9X7DpND8XZG3daDppSsigMdfAIl2upQBRw=="], @@ -682,15 +593,19 @@ "acorn": ["acorn@8.16.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw=="], + "acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="], + "agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], + "ajv": ["ajv@6.14.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw=="], + "anser": ["anser@1.4.10", "", {}, "sha512-hCv9AqTQ8ycjpSd3upOJd7vFwW1JaoYQ7tpham03GJ1ca8/65rqn0RpaWpItOAd6ylW9wAw6luXYPJIyPFVOww=="], "ansi-escapes": ["ansi-escapes@4.3.2", "", { "dependencies": { "type-fest": "^0.21.3" } }, "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ=="], "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], + "ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], "any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="], @@ -704,11 +619,11 @@ "aria-query": ["aria-query@5.3.0", "", { "dependencies": { "dequal": "^2.0.3" } }, "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A=="], - "array-union": ["array-union@2.1.0", "", {}, "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw=="], - "asap": ["asap@2.0.6", "", {}, "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="], - "auto-bind": ["auto-bind@4.0.0", "", {}, "sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ=="], + "asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="], + + "axios": ["axios@1.13.6", "", { "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^1.1.0" } }, "sha512-ChTCHMouEe2kn713WHbQGcuYrr6fXTBiu460OTwWrWob16g1bXn4vtz07Ope7ewMozJAnEquLk5lWQWtBig9DQ=="], "babel-jest": ["babel-jest@29.7.0", "", { "dependencies": { "@jest/transform": "^29.7.0", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", "babel-preset-jest": "^29.6.3", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" }, "peerDependencies": { "@babel/core": "^7.8.0" } }, "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg=="], @@ -758,8 +673,6 @@ "browserslist": ["browserslist@4.28.1", "", { "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", "electron-to-chromium": "^1.5.263", "node-releases": "^2.0.27", "update-browserslist-db": "^1.2.0" }, "bin": { "browserslist": "cli.js" } }, "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA=="], - "bs-logger": ["bs-logger@0.2.6", "", { "dependencies": { "fast-json-stable-stringify": "2.x" } }, "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog=="], - "bser": ["bser@2.1.1", "", { "dependencies": { "node-int64": "^0.4.0" } }, "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ=="], "buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="], @@ -772,26 +685,14 @@ "cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="], - "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], - - "camel-case": ["camel-case@4.1.2", "", { "dependencies": { "pascal-case": "^3.1.2", "tslib": "^2.0.3" } }, "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw=="], + "call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="], "camelcase": ["camelcase@6.3.0", "", {}, "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA=="], "caniuse-lite": ["caniuse-lite@1.0.30001774", "", {}, "sha512-DDdwPGz99nmIEv216hKSgLD+D4ikHQHjBC/seF98N9CPqRX4M5mSxT9eTV6oyisnJcuzxtZy4n17yKKQYmYQOA=="], - "capital-case": ["capital-case@1.0.4", "", { "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3", "upper-case-first": "^2.0.2" } }, "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A=="], - "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="], - "change-case": ["change-case@4.1.2", "", { "dependencies": { "camel-case": "^4.1.2", "capital-case": "^1.0.4", "constant-case": "^3.0.4", "dot-case": "^3.0.4", "header-case": "^2.0.4", "no-case": "^3.0.4", "param-case": "^3.0.4", "pascal-case": "^3.1.2", "path-case": "^3.0.4", "sentence-case": "^3.0.4", "snake-case": "^3.0.4", "tslib": "^2.0.3" } }, "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A=="], - - "change-case-all": ["change-case-all@1.0.15", "", { "dependencies": { "change-case": "^4.1.2", "is-lower-case": "^2.0.2", "is-upper-case": "^2.0.2", "lower-case": "^2.0.2", "lower-case-first": "^2.0.2", "sponge-case": "^1.0.1", "swap-case": "^2.0.2", "title-case": "^3.0.3", "upper-case": "^2.0.2", "upper-case-first": "^2.0.2" } }, "sha512-3+GIFhk3sNuvFAJKU46o26OdzudQlPNBCu1ZQi3cMeMHhty1bhDxu2WrEilVNYaGvqUtR1VSigFcJOiS13dRhQ=="], - - "char-regex": ["char-regex@1.0.2", "", {}, "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw=="], - - "chardet": ["chardet@2.1.1", "", {}, "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ=="], - "chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], "chrome-launcher": ["chrome-launcher@0.15.2", "", { "dependencies": { "@types/node": "*", "escape-string-regexp": "^4.0.0", "is-wsl": "^2.2.0", "lighthouse-logger": "^1.0.0" }, "bin": { "print-chrome-path": "bin/print-chrome-path.js" } }, "sha512-zdLEwNo3aUVzIhKhTtXfxhdvZhUghrnmkvcAq2NoDd+LeOHKf03H5jwZ8T/STsAlzyALkBVK552iaG1fGf1xVQ=="], @@ -800,34 +701,22 @@ "ci-info": ["ci-info@3.9.0", "", {}, "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ=="], - "cjs-module-lexer": ["cjs-module-lexer@1.4.3", "", {}, "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q=="], - - "cli-cursor": ["cli-cursor@5.0.0", "", { "dependencies": { "restore-cursor": "^5.0.0" } }, "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw=="], + "cli-cursor": ["cli-cursor@2.1.0", "", { "dependencies": { "restore-cursor": "^2.0.0" } }, "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw=="], "cli-spinners": ["cli-spinners@2.9.2", "", {}, "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg=="], - "cli-truncate": ["cli-truncate@5.1.1", "", { "dependencies": { "slice-ansi": "^7.1.0", "string-width": "^8.0.0" } }, "sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A=="], - - "cli-width": ["cli-width@4.1.0", "", {}, "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ=="], - "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], "clone": ["clone@1.0.4", "", {}, "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg=="], - "co": ["co@4.6.0", "", {}, "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ=="], - - "collect-v8-coverage": ["collect-v8-coverage@1.0.3", "", {}, "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw=="], - "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="], "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="], - "colorette": ["colorette@2.0.20", "", {}, "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w=="], + "combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="], "commander": ["commander@12.1.0", "", {}, "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA=="], - "common-tags": ["common-tags@1.8.2", "", {}, "sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA=="], - "compressible": ["compressible@2.0.18", "", { "dependencies": { "mime-db": ">= 1.43.0 < 2" } }, "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg=="], "compression": ["compression@1.8.1", "", { "dependencies": { "bytes": "3.1.2", "compressible": "~2.0.18", "debug": "2.6.9", "negotiator": "~0.6.4", "on-headers": "~1.1.0", "safe-buffer": "5.2.1", "vary": "~1.1.2" } }, "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w=="], @@ -840,33 +729,17 @@ "consola": ["consola@3.4.2", "", {}, "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA=="], - "constant-case": ["constant-case@3.0.4", "", { "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3", "upper-case": "^2.0.2" } }, "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ=="], - "convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="], "core-js-compat": ["core-js-compat@3.48.0", "", { "dependencies": { "browserslist": "^4.28.1" } }, "sha512-OM4cAF3D6VtH/WkLtWvyNC56EZVXsZdU3iqaMG2B4WvYrlqU831pc4UtG5yp0sE9z8Y02wVN7PjW5Zf9Gt0f1Q=="], - "cosmiconfig": ["cosmiconfig@9.0.0", "", { "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0" }, "peerDependencies": { "typescript": ">=4.9.5" }, "optionalPeers": ["typescript"] }, "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg=="], - - "create-jest": ["create-jest@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", "jest-config": "^29.7.0", "jest-util": "^29.7.0", "prompts": "^2.0.1" }, "bin": { "create-jest": "bin/create-jest.js" } }, "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q=="], - - "cross-fetch": ["cross-fetch@3.2.0", "", { "dependencies": { "node-fetch": "^2.7.0" } }, "sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q=="], - - "cross-inspect": ["cross-inspect@1.0.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-Pcw1JTvZLSJH83iiGWt6fRcT+BjZlCDRVwYLbUcHzv/CRpB7r0MlSrGbIyQvVSNyGnbt7G4AXuyCiDR3POvZ1A=="], - "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="], "csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="], - "data-uri-to-buffer": ["data-uri-to-buffer@4.0.1", "", {}, "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A=="], - - "dataloader": ["dataloader@2.2.3", "", {}, "sha512-y2krtASINtPFS1rSDjacrFgn1dcUuoREVabwlOGOe4SdxenREqwjwjElAdwvbGM7kgZz9a3KVicWR7vcz8rnzA=="], - - "debounce": ["debounce@2.2.0", "", {}, "sha512-Xks6RUDLZFdz8LIdR6q0MTH44k7FikOmnh5xkSjMig6ch45afc8sjTjRQf3P6ax8dMgcQrYO/AR2RGWURrruqw=="], - "debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="], - "dedent": ["dedent@1.7.1", "", { "peerDependencies": { "babel-plugin-macros": "^3.1.0" }, "optionalPeers": ["babel-plugin-macros"] }, "sha512-9JmrhGZpOlEgOLdQgSm0zxFaYoQon408V1v49aqTWuXENVlnCuY9JBZcXZiCsZQWDjTm5Qf/nIvAy77mXDAjEg=="], + "deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="], "deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="], @@ -874,51 +747,41 @@ "define-lazy-prop": ["define-lazy-prop@2.0.0", "", {}, "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og=="], - "depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="], + "delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="], - "dependency-graph": ["dependency-graph@1.0.0", "", {}, "sha512-cW3gggJ28HZ/LExwxP2B++aiKxhJXMSIt9K48FOXQkm+vuG5gyatXnLsONRJdzO/7VfjDIiaOOa/bs4l464Lwg=="], + "depd": ["depd@2.0.0", "", {}, "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="], "dequal": ["dequal@2.0.3", "", {}, "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA=="], "destroy": ["destroy@1.2.0", "", {}, "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="], - "detect-indent": ["detect-indent@6.1.0", "", {}, "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA=="], - "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="], - "detect-newline": ["detect-newline@3.1.0", "", {}, "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA=="], - - "diff-sequences": ["diff-sequences@29.6.3", "", {}, "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q=="], - - "dir-glob": ["dir-glob@3.0.1", "", { "dependencies": { "path-type": "^4.0.0" } }, "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA=="], - "dnssd-advertise": ["dnssd-advertise@1.1.3", "", {}, "sha512-XENsHi3MBzWOCAXif3yZvU1Ah0l+nhJj1sjWL6TnOAYKvGiFhbTx32xHN7+wLMLUOCj7Nr0evADWG4R8JtqCDA=="], "dom-accessibility-api": ["dom-accessibility-api@0.5.16", "", {}, "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg=="], - "dot-case": ["dot-case@3.0.4", "", { "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" } }, "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w=="], - - "dset": ["dset@3.1.4", "", {}, "sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA=="], + "dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="], "ee-first": ["ee-first@1.1.1", "", {}, "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow=="], "electron-to-chromium": ["electron-to-chromium@1.5.302", "", {}, "sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg=="], - "emittery": ["emittery@0.13.1", "", {}, "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ=="], - "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="], "encodeurl": ["encodeurl@2.0.0", "", {}, "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg=="], "entities": ["entities@7.0.1", "", {}, "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA=="], - "env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="], + "error-stack-parser": ["error-stack-parser@2.1.4", "", { "dependencies": { "stackframe": "^1.3.4" } }, "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ=="], - "environment": ["environment@1.1.0", "", {}, "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q=="], + "es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="], - "error-ex": ["error-ex@1.3.4", "", { "dependencies": { "is-arrayish": "^0.2.1" } }, "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ=="], + "es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="], - "error-stack-parser": ["error-stack-parser@2.1.4", "", { "dependencies": { "stackframe": "^1.3.4" } }, "sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ=="], + "es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="], + + "es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="], "esbuild": ["esbuild@0.27.3", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.3", "@esbuild/android-arm": "0.27.3", "@esbuild/android-arm64": "0.27.3", "@esbuild/android-x64": "0.27.3", "@esbuild/darwin-arm64": "0.27.3", "@esbuild/darwin-x64": "0.27.3", "@esbuild/freebsd-arm64": "0.27.3", "@esbuild/freebsd-x64": "0.27.3", "@esbuild/linux-arm": "0.27.3", "@esbuild/linux-arm64": "0.27.3", "@esbuild/linux-ia32": "0.27.3", "@esbuild/linux-loong64": "0.27.3", "@esbuild/linux-mips64el": "0.27.3", "@esbuild/linux-ppc64": "0.27.3", "@esbuild/linux-riscv64": "0.27.3", "@esbuild/linux-s390x": "0.27.3", "@esbuild/linux-x64": "0.27.3", "@esbuild/netbsd-arm64": "0.27.3", "@esbuild/netbsd-x64": "0.27.3", "@esbuild/openbsd-arm64": "0.27.3", "@esbuild/openbsd-x64": "0.27.3", "@esbuild/openharmony-arm64": "0.27.3", "@esbuild/sunos-x64": "0.27.3", "@esbuild/win32-arm64": "0.27.3", "@esbuild/win32-ia32": "0.27.3", "@esbuild/win32-x64": "0.27.3" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg=="], @@ -926,21 +789,33 @@ "escape-html": ["escape-html@1.0.3", "", {}, "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="], - "escape-string-regexp": ["escape-string-regexp@2.0.0", "", {}, "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w=="], + "escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], + + "eslint": ["eslint@10.0.2", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.2", "@eslint/config-array": "^0.23.2", "@eslint/config-helpers": "^0.5.2", "@eslint/core": "^1.1.0", "@eslint/plugin-kit": "^0.6.0", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.14.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^9.1.1", "eslint-visitor-keys": "^5.0.1", "espree": "^11.1.1", "esquery": "^1.7.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "minimatch": "^10.2.1", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-uYixubwmqJZH+KLVYIVKY1JQt7tysXhtj21WSvjcSmU5SVNzMus1bgLe+pAt816yQ8opKfheVVoPLqvVMGejYw=="], + + "eslint-plugin-simple-import-sort": ["eslint-plugin-simple-import-sort@12.1.1", "", { "peerDependencies": { "eslint": ">=5.0.0" } }, "sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA=="], + + "eslint-scope": ["eslint-scope@9.1.1", "", { "dependencies": { "@types/esrecurse": "^4.3.1", "@types/estree": "^1.0.8", "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-GaUN0sWim5qc8KVErfPBWmc31LEsOkrUJbvJZV+xuL3u2phMUK4HIvXlWAakfC8W4nzlK+chPEAkYOYb5ZScIw=="], + + "eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="], + + "espree": ["espree@11.1.1", "", { "dependencies": { "acorn": "^8.16.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^5.0.1" } }, "sha512-AVHPqQoZYc+RUM4/3Ly5udlZY/U4LS8pIG05jEjWM2lQMU/oaZ7qshzAl2YP1tfNmXfftH3ohurfwNAug+MnsQ=="], "esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="], - "etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="], + "esquery": ["esquery@1.7.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g=="], - "event-target-shim": ["event-target-shim@5.0.1", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="], + "esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="], + + "estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="], - "eventemitter3": ["eventemitter3@5.0.4", "", {}, "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw=="], + "esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="], - "execa": ["execa@5.1.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.1", "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg=="], + "etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="], - "exit": ["exit@0.1.2", "", {}, "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ=="], + "event-target-polyfill": ["event-target-polyfill@0.0.4", "", {}, "sha512-Gs6RLjzlLRdT8X9ZipJdIZI/Y6/HhRLyq9RdDlCsnpxr/+Nn6bU2EFGuC94GjxqhM+Nmij2Vcq98yoHrU8uNFQ=="], - "expect": ["expect@29.7.0", "", { "dependencies": { "@jest/expect-utils": "^29.7.0", "jest-get-type": "^29.6.3", "jest-matcher-utils": "^29.7.0", "jest-message-util": "^29.7.0", "jest-util": "^29.7.0" } }, "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw=="], + "event-target-shim": ["event-target-shim@5.0.1", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="], "expo": ["expo@55.0.2", "", { "dependencies": { "@babel/runtime": "^7.20.0", "@expo/cli": "55.0.12", "@expo/config": "~55.0.8", "@expo/config-plugins": "~55.0.6", "@expo/devtools": "55.0.2", "@expo/fingerprint": "0.16.5", "@expo/local-build-cache-provider": "55.0.6", "@expo/log-box": "55.0.7", "@expo/metro": "~54.2.0", "@expo/metro-config": "55.0.9", "@expo/vector-icons": "^15.0.2", "@ungap/structured-clone": "^1.3.0", "babel-preset-expo": "~55.0.8", "expo-asset": "~55.0.7", "expo-constants": "~55.0.7", "expo-file-system": "~55.0.9", "expo-font": "~55.0.4", "expo-keep-awake": "~55.0.4", "expo-modules-autolinking": "55.0.8", "expo-modules-core": "55.0.12", "pretty-format": "^29.7.0", "react-refresh": "^0.14.2", "whatwg-url-minimum": "^0.1.1" }, "peerDependencies": { "@expo/dom-webview": "*", "@expo/metro-runtime": "*", "react": "*", "react-native": "*", "react-native-webview": "*" }, "optionalPeers": ["@expo/dom-webview", "@expo/metro-runtime", "react-native-webview"], "bin": { "expo": "bin/cli", "fingerprint": "bin/fingerprint", "expo-modules-autolinking": "bin/autolinking" } }, "sha512-e2UtZe3OrgcAMPVtCeTe8AyEUz65XxqPwPxV2rgjklmniaR+z1J5lywCnf1qsJP6eRMI893mXln5puO/ddLTIg=="], @@ -962,39 +837,41 @@ "exponential-backoff": ["exponential-backoff@3.1.3", "", {}, "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA=="], - "fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="], + "fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="], "fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="], - "fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="], + "fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="], "fb-dotslash": ["fb-dotslash@0.5.8", "", { "bin": { "dotslash": "bin/dotslash" } }, "sha512-XHYLKk9J4BupDxi9bSEhkfss0m+Vr9ChTrjhf9l2iw3jB5C7BnY4GVPoMcqbrTutsKJso6yj2nAB6BI/F2oZaA=="], "fb-watchman": ["fb-watchman@2.0.2", "", { "dependencies": { "bser": "2.1.1" } }, "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA=="], - "fbjs": ["fbjs@3.0.5", "", { "dependencies": { "cross-fetch": "^3.1.5", "fbjs-css-vars": "^1.0.0", "loose-envify": "^1.0.0", "object-assign": "^4.1.0", "promise": "^7.1.1", "setimmediate": "^1.0.5", "ua-parser-js": "^1.0.35" } }, "sha512-ztsSx77JBtkuMrEypfhgc3cI0+0h+svqeie7xHbh1k/IKdcydnvadp/mUaGgjAOXQmQSxsqgaRhS3q9fy+1kxg=="], - - "fbjs-css-vars": ["fbjs-css-vars@1.0.2", "", {}, "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ=="], - "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="], - "fetch-blob": ["fetch-blob@3.2.0", "", { "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" } }, "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ=="], - "fetch-nodeshim": ["fetch-nodeshim@0.4.8", "", {}, "sha512-YW5vG33rabBq6JpYosLNoXoaMN69/WH26MeeX2hkDVjN6UlvRGq3Wkazl9H0kisH95aMu/HtHL64JUvv/+Nv/g=="], + "file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="], + "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], "finalhandler": ["finalhandler@1.1.2", "", { "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "on-finished": "~2.3.0", "parseurl": "~1.3.3", "statuses": "~1.5.0", "unpipe": "~1.0.0" } }, "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA=="], - "find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="], + "find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="], "fix-dts-default-cjs-exports": ["fix-dts-default-cjs-exports@1.0.1", "", { "dependencies": { "magic-string": "^0.30.17", "mlly": "^1.7.4", "rollup": "^4.34.8" } }, "sha512-pVIECanWFC61Hzl2+oOCtoJ3F17kglZC/6N94eRWycFgBH35hHx0Li604ZIzhseh97mf2p0cv7vVrOZGoqhlEg=="], + "flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="], + + "flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="], + "flow-enums-runtime": ["flow-enums-runtime@0.0.6", "", {}, "sha512-3PYnM29RFXwvAN6Pc/scUfkI7RwhQ/xqyLUyPNlXUp9S40zI8nup9tUSrTLSVnWGBN38FNiGWbwZOB6uR4OGdw=="], + "follow-redirects": ["follow-redirects@1.15.11", "", {}, "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ=="], + "fontfaceobserver": ["fontfaceobserver@2.3.0", "", {}, "sha512-6FPvD/IVyT4ZlNe7Wcn5Fb/4ChigpucKYSvD6a+0iMoLn2inpo711eyIcKjmDtE5XNcgAkSH9uN/nfAeZzHEfg=="], - "formdata-polyfill": ["formdata-polyfill@4.0.10", "", { "dependencies": { "fetch-blob": "^3.1.2" } }, "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g=="], + "form-data": ["form-data@4.0.5", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w=="], "fresh": ["fresh@0.5.2", "", {}, "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q=="], @@ -1008,43 +885,39 @@ "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="], - "get-east-asian-width": ["get-east-asian-width@1.5.0", "", {}, "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA=="], + "get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="], "get-package-type": ["get-package-type@0.1.0", "", {}, "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q=="], - "get-stream": ["get-stream@6.0.1", "", {}, "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="], + "get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="], "getenv": ["getenv@2.0.0", "", {}, "sha512-VilgtJj/ALgGY77fiLam5iD336eSWi96Q15JSAG1zi8NRBysm3LXKdGnHb4m5cuyxvOLQQKWpBZAT6ni4FI2iQ=="], - "glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], + "glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], + + "glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="], - "glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], + "gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="], - "globby": ["globby@11.1.0", "", { "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", "fast-glob": "^3.2.9", "ignore": "^5.2.0", "merge2": "^1.4.1", "slash": "^3.0.0" } }, "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g=="], + "gql.tada": ["gql.tada@1.9.0", "", { "dependencies": { "@0no-co/graphql.web": "^1.0.5", "@0no-co/graphqlsp": "^1.12.13", "@gql.tada/cli-utils": "1.7.2", "@gql.tada/internal": "1.0.8" }, "peerDependencies": { "typescript": "^5.0.0" }, "bin": { "gql.tada": "bin/cli.js", "gql-tada": "bin/cli.js" } }, "sha512-1LMiA46dRs5oF7Qev6vMU32gmiNvM3+3nHoQZA9K9j2xQzH8xOAWnnJrLSbZOFHTSdFxqn86TL6beo1/7ja/aA=="], "graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="], "graphql": ["graphql@16.13.0", "", {}, "sha512-uSisMYERbaB9bkA9M4/4dnqyktaEkf1kMHNKq/7DHyxVeWqHQ2mBmVqm5u6/FVHwF3iCNalKcg82Zfl+tffWoA=="], - "graphql-config": ["graphql-config@5.1.5", "", { "dependencies": { "@graphql-tools/graphql-file-loader": "^8.0.0", "@graphql-tools/json-file-loader": "^8.0.0", "@graphql-tools/load": "^8.1.0", "@graphql-tools/merge": "^9.0.0", "@graphql-tools/url-loader": "^8.0.0", "@graphql-tools/utils": "^10.0.0", "cosmiconfig": "^8.1.0", "jiti": "^2.0.0", "minimatch": "^9.0.5", "string-env-interpolation": "^1.0.1", "tslib": "^2.4.0" }, "peerDependencies": { "cosmiconfig-toml-loader": "^1.0.0", "graphql": "^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" }, "optionalPeers": ["cosmiconfig-toml-loader"] }, "sha512-mG2LL1HccpU8qg5ajLROgdsBzx/o2M6kgI3uAmoaXiSH9PCUbtIyLomLqUtCFaAeG2YCFsl0M5cfQ9rKmDoMVA=="], - "graphql-scalars": ["graphql-scalars@1.25.0", "", { "dependencies": { "tslib": "^2.5.0" }, "peerDependencies": { "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "sha512-b0xyXZeRFkne4Eq7NAnL400gStGqG/Sx9VqX0A05nHyEbv57UJnWKsjNnrpVqv5e/8N1MUxkt0wwcRXbiyKcFg=="], - "graphql-tag": ["graphql-tag@2.12.6", "", { "dependencies": { "tslib": "^2.1.0" }, "peerDependencies": { "graphql": "^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0" } }, "sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg=="], - - "graphql-ws": ["graphql-ws@6.0.7", "", { "peerDependencies": { "@fastify/websocket": "^10 || ^11", "crossws": "~0.3", "graphql": "^15.10.1 || ^16", "ws": "^8" }, "optionalPeers": ["@fastify/websocket", "crossws", "ws"] }, "sha512-yoLRW+KRlDmnnROdAu7sX77VNLC0bsFoZyGQJLy1cF+X/SkLg/fWkRGrEEYQK8o2cafJ2wmEaMqMEZB3U3DYDg=="], - - "handlebars": ["handlebars@4.7.8", "", { "dependencies": { "minimist": "^1.2.5", "neo-async": "^2.6.2", "source-map": "^0.6.1", "wordwrap": "^1.0.0" }, "optionalDependencies": { "uglify-js": "^3.1.4" }, "bin": { "handlebars": "bin/handlebars" } }, "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ=="], - "happy-dom": ["happy-dom@20.7.0", "", { "dependencies": { "@types/node": ">=20.0.0", "@types/whatwg-mimetype": "^3.0.2", "@types/ws": "^8.18.1", "entities": "^7.0.1", "whatwg-mimetype": "^3.0.0", "ws": "^8.18.3" } }, "sha512-hR/uLYQdngTyEfxnOoa+e6KTcfBFyc1hgFj/Cc144A5JJUuHFYqIEBDcD4FeGqUeKLRZqJ9eN9u7/GDjYEgS1g=="], "harmony-reflect": ["harmony-reflect@1.6.2", "", {}, "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g=="], "has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="], - "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], + "has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="], + + "has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="], - "header-case": ["header-case@2.0.4", "", { "dependencies": { "capital-case": "^1.0.4", "tslib": "^2.0.3" } }, "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q=="], + "hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="], "hermes-compiler": ["hermes-compiler@250829098.0.7", "", {}, "sha512-8QOmg1VjAWv8poFVslJDY8qkvjTy/UiO3R/hyGoC0IAchLzBdS9/TmAvI9cN1F3yLTEjimAIQQtUslpBMPXVVg=="], @@ -1054,15 +927,11 @@ "hosted-git-info": ["hosted-git-info@7.0.2", "", { "dependencies": { "lru-cache": "^10.0.1" } }, "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w=="], - "html-escaper": ["html-escaper@2.0.2", "", {}, "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg=="], - "http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="], "https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="], - "human-signals": ["human-signals@2.1.0", "", {}, "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="], - - "iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="], + "idb": ["idb@8.0.3", "", {}, "sha512-LtwtVyVYO5BqRvcsKuB2iUMnHwPVByPCXFXOpuU96IZPPoPN6xjOGxZQ74pgSVVLQWtUOYgyeL4GE98BY5D3wg=="], "identity-obj-proxy": ["identity-obj-proxy@3.0.0", "", { "dependencies": { "harmony-reflect": "^1.4.6" } }, "sha512-00n6YnVHKrinT9t0d9+5yZC6UBNJANpYEQvL2LlX6Ab9lnmxzIRcEmTPuyGScvl1+jKuCICX1Z0Ab1pPKKdikA=="], @@ -1072,14 +941,6 @@ "immer": ["immer@11.1.4", "", {}, "sha512-XREFCPo6ksxVzP4E0ekD5aMdf8WMwmdNaz6vuvxgI40UaEiu6q3p8X52aU6GdyvLY3XXX/8R7JOTXStz/nBbRw=="], - "immutable": ["immutable@3.7.6", "", {}, "sha512-AizQPcaofEtO11RZhPPHBOJRdo/20MKQF9mBLnVkBoyHi1/zXK8fzVdnEpSV9gxqtnh6Qomfp3F0xT5qP/vThw=="], - - "import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="], - - "import-from": ["import-from@4.0.0", "", {}, "sha512-P9J71vT5nLlDeV8FHs5nNxaLbrpfAV5cF5srvbZfpwpcJoM/xZR3hiv+q+SAnuSmuGbXMWud063iIMx/V/EWZQ=="], - - "import-local": ["import-local@3.2.0", "", { "dependencies": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" }, "bin": { "import-local-fixture": "fixtures/cli.js" } }, "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA=="], - "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="], "inflight": ["inflight@1.0.6", "", { "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="], @@ -1088,10 +949,6 @@ "invariant": ["invariant@2.2.4", "", { "dependencies": { "loose-envify": "^1.0.0" } }, "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA=="], - "is-absolute": ["is-absolute@1.0.0", "", { "dependencies": { "is-relative": "^1.0.0", "is-windows": "^1.0.1" } }, "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA=="], - - "is-arrayish": ["is-arrayish@0.2.1", "", {}, "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="], - "is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="], "is-docker": ["is-docker@2.2.1", "", { "bin": { "is-docker": "cli.js" } }, "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ=="], @@ -1100,59 +957,17 @@ "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="], - "is-generator-fn": ["is-generator-fn@2.1.0", "", {}, "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ=="], - "is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="], - "is-lower-case": ["is-lower-case@2.0.2", "", { "dependencies": { "tslib": "^2.0.3" } }, "sha512-bVcMJy4X5Og6VZfdOZstSexlEy20Sr0k/p/b2IlQJlfdKAQuMpiv5w2Ccxb8sKdRUNAG1PnHVHjFSdRDVS6NlQ=="], - "is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="], - "is-relative": ["is-relative@1.0.0", "", { "dependencies": { "is-unc-path": "^1.0.0" } }, "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA=="], - - "is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="], - - "is-unc-path": ["is-unc-path@1.0.0", "", { "dependencies": { "unc-path-regex": "^0.1.2" } }, "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ=="], - - "is-unicode-supported": ["is-unicode-supported@0.1.0", "", {}, "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw=="], - - "is-upper-case": ["is-upper-case@2.0.2", "", { "dependencies": { "tslib": "^2.0.3" } }, "sha512-44pxmxAvnnAOwBg4tHPnkfvgjPwbc5QIsSstNU+YcJ1ovxVzCWpSGosPJOZh/a1tdl81fbgnLc9LLv+x2ywbPQ=="], - - "is-windows": ["is-windows@1.0.2", "", {}, "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="], - "is-wsl": ["is-wsl@2.2.0", "", { "dependencies": { "is-docker": "^2.0.0" } }, "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww=="], "isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="], - "isomorphic-ws": ["isomorphic-ws@5.0.0", "", { "peerDependencies": { "ws": "*" } }, "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw=="], - - "isows": ["isows@1.0.7", "", { "peerDependencies": { "ws": "*" } }, "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg=="], - "istanbul-lib-coverage": ["istanbul-lib-coverage@3.2.2", "", {}, "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg=="], - "istanbul-lib-instrument": ["istanbul-lib-instrument@6.0.3", "", { "dependencies": { "@babel/core": "^7.23.9", "@babel/parser": "^7.23.9", "@istanbuljs/schema": "^0.1.3", "istanbul-lib-coverage": "^3.2.0", "semver": "^7.5.4" } }, "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q=="], - - "istanbul-lib-report": ["istanbul-lib-report@3.0.1", "", { "dependencies": { "istanbul-lib-coverage": "^3.0.0", "make-dir": "^4.0.0", "supports-color": "^7.1.0" } }, "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw=="], - - "istanbul-lib-source-maps": ["istanbul-lib-source-maps@4.0.1", "", { "dependencies": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", "source-map": "^0.6.1" } }, "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw=="], - - "istanbul-reports": ["istanbul-reports@3.2.0", "", { "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" } }, "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA=="], - - "jest": ["jest@29.7.0", "", { "dependencies": { "@jest/core": "^29.7.0", "@jest/types": "^29.6.3", "import-local": "^3.0.2", "jest-cli": "^29.7.0" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" }, "optionalPeers": ["node-notifier"], "bin": { "jest": "bin/jest.js" } }, "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw=="], - - "jest-changed-files": ["jest-changed-files@29.7.0", "", { "dependencies": { "execa": "^5.0.0", "jest-util": "^29.7.0", "p-limit": "^3.1.0" } }, "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w=="], - - "jest-circus": ["jest-circus@29.7.0", "", { "dependencies": { "@jest/environment": "^29.7.0", "@jest/expect": "^29.7.0", "@jest/test-result": "^29.7.0", "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^1.0.0", "is-generator-fn": "^2.0.0", "jest-each": "^29.7.0", "jest-matcher-utils": "^29.7.0", "jest-message-util": "^29.7.0", "jest-runtime": "^29.7.0", "jest-snapshot": "^29.7.0", "jest-util": "^29.7.0", "p-limit": "^3.1.0", "pretty-format": "^29.7.0", "pure-rand": "^6.0.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw=="], - - "jest-cli": ["jest-cli@29.7.0", "", { "dependencies": { "@jest/core": "^29.7.0", "@jest/test-result": "^29.7.0", "@jest/types": "^29.6.3", "chalk": "^4.0.0", "create-jest": "^29.7.0", "exit": "^0.1.2", "import-local": "^3.0.2", "jest-config": "^29.7.0", "jest-util": "^29.7.0", "jest-validate": "^29.7.0", "yargs": "^17.3.1" }, "peerDependencies": { "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" }, "optionalPeers": ["node-notifier"], "bin": { "jest": "bin/jest.js" } }, "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg=="], - - "jest-config": ["jest-config@29.7.0", "", { "dependencies": { "@babel/core": "^7.11.6", "@jest/test-sequencer": "^29.7.0", "@jest/types": "^29.6.3", "babel-jest": "^29.7.0", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.3", "graceful-fs": "^4.2.9", "jest-circus": "^29.7.0", "jest-environment-node": "^29.7.0", "jest-get-type": "^29.6.3", "jest-regex-util": "^29.6.3", "jest-resolve": "^29.7.0", "jest-runner": "^29.7.0", "jest-util": "^29.7.0", "jest-validate": "^29.7.0", "micromatch": "^4.0.4", "parse-json": "^5.2.0", "pretty-format": "^29.7.0", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, "peerDependencies": { "@types/node": "*", "ts-node": ">=9.0.0" }, "optionalPeers": ["@types/node", "ts-node"] }, "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ=="], - - "jest-diff": ["jest-diff@29.7.0", "", { "dependencies": { "chalk": "^4.0.0", "diff-sequences": "^29.6.3", "jest-get-type": "^29.6.3", "pretty-format": "^29.7.0" } }, "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw=="], - - "jest-docblock": ["jest-docblock@29.7.0", "", { "dependencies": { "detect-newline": "^3.0.0" } }, "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g=="], - - "jest-each": ["jest-each@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3", "chalk": "^4.0.0", "jest-get-type": "^29.6.3", "jest-util": "^29.7.0", "pretty-format": "^29.7.0" } }, "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ=="], + "istanbul-lib-instrument": ["istanbul-lib-instrument@5.2.1", "", { "dependencies": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", "@istanbuljs/schema": "^0.1.2", "istanbul-lib-coverage": "^3.2.0", "semver": "^6.3.0" } }, "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg=="], "jest-environment-node": ["jest-environment-node@29.7.0", "", { "dependencies": { "@jest/environment": "^29.7.0", "@jest/fake-timers": "^29.7.0", "@jest/types": "^29.6.3", "@types/node": "*", "jest-mock": "^29.7.0", "jest-util": "^29.7.0" } }, "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw=="], @@ -1160,42 +975,22 @@ "jest-haste-map": ["jest-haste-map@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.9", "jest-regex-util": "^29.6.3", "jest-util": "^29.7.0", "jest-worker": "^29.7.0", "micromatch": "^4.0.4", "walker": "^1.0.8" }, "optionalDependencies": { "fsevents": "^2.3.2" } }, "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA=="], - "jest-leak-detector": ["jest-leak-detector@29.7.0", "", { "dependencies": { "jest-get-type": "^29.6.3", "pretty-format": "^29.7.0" } }, "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw=="], - - "jest-matcher-utils": ["jest-matcher-utils@29.7.0", "", { "dependencies": { "chalk": "^4.0.0", "jest-diff": "^29.7.0", "jest-get-type": "^29.6.3", "pretty-format": "^29.7.0" } }, "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g=="], - "jest-message-util": ["jest-message-util@29.7.0", "", { "dependencies": { "@babel/code-frame": "^7.12.13", "@jest/types": "^29.6.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", "pretty-format": "^29.7.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w=="], "jest-mock": ["jest-mock@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", "jest-util": "^29.7.0" } }, "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw=="], - "jest-pnp-resolver": ["jest-pnp-resolver@1.2.3", "", { "peerDependencies": { "jest-resolve": "*" }, "optionalPeers": ["jest-resolve"] }, "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w=="], - "jest-regex-util": ["jest-regex-util@29.6.3", "", {}, "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg=="], - "jest-resolve": ["jest-resolve@29.7.0", "", { "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "jest-haste-map": "^29.7.0", "jest-pnp-resolver": "^1.2.2", "jest-util": "^29.7.0", "jest-validate": "^29.7.0", "resolve": "^1.20.0", "resolve.exports": "^2.0.0", "slash": "^3.0.0" } }, "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA=="], - - "jest-resolve-dependencies": ["jest-resolve-dependencies@29.7.0", "", { "dependencies": { "jest-regex-util": "^29.6.3", "jest-snapshot": "^29.7.0" } }, "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA=="], - - "jest-runner": ["jest-runner@29.7.0", "", { "dependencies": { "@jest/console": "^29.7.0", "@jest/environment": "^29.7.0", "@jest/test-result": "^29.7.0", "@jest/transform": "^29.7.0", "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.13.1", "graceful-fs": "^4.2.9", "jest-docblock": "^29.7.0", "jest-environment-node": "^29.7.0", "jest-haste-map": "^29.7.0", "jest-leak-detector": "^29.7.0", "jest-message-util": "^29.7.0", "jest-resolve": "^29.7.0", "jest-runtime": "^29.7.0", "jest-util": "^29.7.0", "jest-watcher": "^29.7.0", "jest-worker": "^29.7.0", "p-limit": "^3.1.0", "source-map-support": "0.5.13" } }, "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ=="], - - "jest-runtime": ["jest-runtime@29.7.0", "", { "dependencies": { "@jest/environment": "^29.7.0", "@jest/fake-timers": "^29.7.0", "@jest/globals": "^29.7.0", "@jest/source-map": "^29.6.3", "@jest/test-result": "^29.7.0", "@jest/transform": "^29.7.0", "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", "jest-haste-map": "^29.7.0", "jest-message-util": "^29.7.0", "jest-mock": "^29.7.0", "jest-regex-util": "^29.6.3", "jest-resolve": "^29.7.0", "jest-snapshot": "^29.7.0", "jest-util": "^29.7.0", "slash": "^3.0.0", "strip-bom": "^4.0.0" } }, "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ=="], - - "jest-snapshot": ["jest-snapshot@29.7.0", "", { "dependencies": { "@babel/core": "^7.11.6", "@babel/generator": "^7.7.2", "@babel/plugin-syntax-jsx": "^7.7.2", "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/types": "^7.3.3", "@jest/expect-utils": "^29.7.0", "@jest/transform": "^29.7.0", "@jest/types": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", "expect": "^29.7.0", "graceful-fs": "^4.2.9", "jest-diff": "^29.7.0", "jest-get-type": "^29.6.3", "jest-matcher-utils": "^29.7.0", "jest-message-util": "^29.7.0", "jest-util": "^29.7.0", "natural-compare": "^1.4.0", "pretty-format": "^29.7.0", "semver": "^7.5.3" } }, "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw=="], - "jest-util": ["jest-util@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", "graceful-fs": "^4.2.9", "picomatch": "^2.2.3" } }, "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA=="], "jest-validate": ["jest-validate@29.7.0", "", { "dependencies": { "@jest/types": "^29.6.3", "camelcase": "^6.2.0", "chalk": "^4.0.0", "jest-get-type": "^29.6.3", "leven": "^3.1.0", "pretty-format": "^29.7.0" } }, "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw=="], - "jest-watcher": ["jest-watcher@29.7.0", "", { "dependencies": { "@jest/test-result": "^29.7.0", "@jest/types": "^29.6.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.13.1", "jest-util": "^29.7.0", "string-length": "^4.0.1" } }, "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g=="], - "jest-worker": ["jest-worker@29.7.0", "", { "dependencies": { "@types/node": "*", "jest-util": "^29.7.0", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" } }, "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw=="], "jimp-compact": ["jimp-compact@0.16.1", "", {}, "sha512-dZ6Ra7u1G8c4Letq/B5EzAxj4tLFHL+cGtdpR+PVm4yzPDj+lCk+AbivWt1eOM+ikzkowtyV7qSqX6qr3t71Ww=="], "jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], - "jotai": ["jotai@2.18.0", "", { "peerDependencies": { "@babel/core": ">=7.0.0", "@babel/template": ">=7.0.0", "@types/react": ">=17.0.0", "react": ">=17.0.0" }, "optionalPeers": ["@babel/core", "@babel/template", "@types/react", "react"] }, "sha512-XI38kGWAvtxAZ+cwHcTgJsd+kJOJGf3OfL4XYaXWZMZ7IIY8e53abpIHvtVn1eAgJ5dlgwlGFnP4psrZ/vZbtA=="], - "joycon": ["joycon@3.1.1", "", {}, "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw=="], "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], @@ -1208,18 +1003,24 @@ "json-bigint": ["json-bigint@1.0.0", "", { "dependencies": { "bignumber.js": "^9.0.0" } }, "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ=="], - "json-parse-even-better-errors": ["json-parse-even-better-errors@2.3.1", "", {}, "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w=="], + "json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="], + + "json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="], - "json-to-pretty-yaml": ["json-to-pretty-yaml@1.2.2", "", { "dependencies": { "remedial": "^1.0.7", "remove-trailing-spaces": "^1.0.6" } }, "sha512-rvm6hunfCcqegwYaG5T4yKJWxc9FXFgBVrcTZ4XfSVRwa5HA/Xs+vB/Eo9treYYHCeNM0nrSUr82V/M31Urc7A=="], + "json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="], "json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="], + "keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="], + "kleur": ["kleur@3.0.3", "", {}, "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w=="], "lan-network": ["lan-network@0.2.0", "", { "bin": { "lan-network": "dist/lan-network-cli.js" } }, "sha512-EZgbsXMrGS+oK+Ta12mCjzBFse+SIewGdwrSTr5g+MSymnjpox2x05ceI20PQejJOFvOgzcXrfDk/SdY7dSCtw=="], "leven": ["leven@3.1.0", "", {}, "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A=="], + "levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="], + "lighthouse-logger": ["lighthouse-logger@1.4.2", "", { "dependencies": { "debug": "^2.6.9", "marky": "^1.2.2" } }, "sha512-gPWxznF6TKmUHrOQjlVo2UbaL2EJ71mb2CCeRs/2qBpi4L/g4LUVc9+3lKQ6DTUZwJswfM7ainGrLO1+fOqa2g=="], "lightningcss": ["lightningcss@1.31.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.31.1", "lightningcss-darwin-arm64": "1.31.1", "lightningcss-darwin-x64": "1.31.1", "lightningcss-freebsd-x64": "1.31.1", "lightningcss-linux-arm-gnueabihf": "1.31.1", "lightningcss-linux-arm64-gnu": "1.31.1", "lightningcss-linux-arm64-musl": "1.31.1", "lightningcss-linux-x64-gnu": "1.31.1", "lightningcss-linux-x64-musl": "1.31.1", "lightningcss-win32-arm64-msvc": "1.31.1", "lightningcss-win32-x64-msvc": "1.31.1" } }, "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ=="], @@ -1250,56 +1051,36 @@ "lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="], - "listr2": ["listr2@9.0.5", "", { "dependencies": { "cli-truncate": "^5.0.0", "colorette": "^2.0.20", "eventemitter3": "^5.0.1", "log-update": "^6.1.0", "rfdc": "^1.4.1", "wrap-ansi": "^9.0.0" } }, "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g=="], - "load-tsconfig": ["load-tsconfig@0.2.5", "", {}, "sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg=="], - "locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="], - - "lodash": ["lodash@4.17.23", "", {}, "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w=="], + "locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="], "lodash.debounce": ["lodash.debounce@4.0.8", "", {}, "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="], - "lodash.memoize": ["lodash.memoize@4.1.2", "", {}, "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag=="], - - "lodash.sortby": ["lodash.sortby@4.7.0", "", {}, "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA=="], - "lodash.throttle": ["lodash.throttle@4.1.1", "", {}, "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="], - "log-symbols": ["log-symbols@4.1.0", "", { "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" } }, "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg=="], - - "log-update": ["log-update@6.1.0", "", { "dependencies": { "ansi-escapes": "^7.0.0", "cli-cursor": "^5.0.0", "slice-ansi": "^7.1.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" } }, "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w=="], + "log-symbols": ["log-symbols@2.2.0", "", { "dependencies": { "chalk": "^2.0.1" } }, "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg=="], "loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="], - "lower-case": ["lower-case@2.0.2", "", { "dependencies": { "tslib": "^2.0.3" } }, "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg=="], - - "lower-case-first": ["lower-case-first@2.0.2", "", { "dependencies": { "tslib": "^2.0.3" } }, "sha512-EVm/rR94FJTZi3zefZ82fLWab+GX14LJN4HrWBcuo6Evmsl9hEfnqxgcHCKb9q+mNf6EVdsjx/qucYFIIB84pg=="], - "lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="], "lz-string": ["lz-string@1.5.0", "", { "bin": { "lz-string": "bin/bin.js" } }, "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ=="], "magic-string": ["magic-string@0.30.21", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" } }, "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ=="], - "make-dir": ["make-dir@4.0.0", "", { "dependencies": { "semver": "^7.5.3" } }, "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw=="], - - "make-error": ["make-error@1.3.6", "", {}, "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw=="], + "mailpit-api": ["mailpit-api@1.7.1", "", { "dependencies": { "axios": "^1.13.5", "partysocket": "^1.1.10", "ws": "^8.18.3" } }, "sha512-a4+shTeSYQiy5bADcsA/TXj+D9errJu9Z2ZE3vJAuI6sQxz9n/h3r/pVkKDyMIie6GsBXAzyooPl8X7hvXmnWQ=="], "makeerror": ["makeerror@1.0.12", "", { "dependencies": { "tmpl": "1.0.5" } }, "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg=="], - "map-cache": ["map-cache@0.2.2", "", {}, "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg=="], - "marky": ["marky@1.3.0", "", {}, "sha512-ocnPZQLNpvbedwTy9kNrQEsknEfgvcLMvOtz3sFeWApDq1MXH1TqkCIx58xlpESsfwQOnuBO9beyQuNGzVvuhQ=="], + "math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="], + "memoize-one": ["memoize-one@5.2.1", "", {}, "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q=="], "merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="], - "merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="], - - "meros": ["meros@1.3.2", "", { "peerDependencies": { "@types/node": ">=13" }, "optionalPeers": ["@types/node"] }, "sha512-Q3mobPbvEx7XbwhnC1J1r60+5H6EZyNccdzSz0eGexJRwouUtTZxPVRGdqKtxlpD84ScK4+tIGldkqDtCKdI0A=="], - "metro": ["metro@0.83.4", "", { "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/core": "^7.25.2", "@babel/generator": "^7.29.1", "@babel/parser": "^7.29.0", "@babel/template": "^7.28.6", "@babel/traverse": "^7.29.0", "@babel/types": "^7.29.0", "accepts": "^2.0.0", "chalk": "^4.0.0", "ci-info": "^2.0.0", "connect": "^3.6.5", "debug": "^4.4.0", "error-stack-parser": "^2.0.6", "flow-enums-runtime": "^0.0.6", "graceful-fs": "^4.2.4", "hermes-parser": "0.33.3", "image-size": "^1.0.2", "invariant": "^2.2.4", "jest-worker": "^29.7.0", "jsc-safe-url": "^0.2.2", "lodash.throttle": "^4.1.1", "metro-babel-transformer": "0.83.4", "metro-cache": "0.83.4", "metro-cache-key": "0.83.4", "metro-config": "0.83.4", "metro-core": "0.83.4", "metro-file-map": "0.83.4", "metro-resolver": "0.83.4", "metro-runtime": "0.83.4", "metro-source-map": "0.83.4", "metro-symbolicate": "0.83.4", "metro-transform-plugins": "0.83.4", "metro-transform-worker": "0.83.4", "mime-types": "^3.0.1", "nullthrows": "^1.1.1", "serialize-error": "^2.1.0", "source-map": "^0.5.6", "throat": "^5.0.0", "ws": "^7.5.10", "yargs": "^17.6.2" }, "bin": { "metro": "src/cli.js" } }, "sha512-eBkAtcob+YmvSLL+/rsFiK8dHNfDbQA2/pi0lnxg3E6LLtUpwDfdGJ9WBWXkj0PVeOhoWQyj9Rt7s/+6k/GXuA=="], "metro-babel-transformer": ["metro-babel-transformer@0.83.3", "", { "dependencies": { "@babel/core": "^7.25.2", "flow-enums-runtime": "^0.0.6", "hermes-parser": "0.32.0", "nullthrows": "^1.1.1" } }, "sha512-1vxlvj2yY24ES1O5RsSIvg4a4WeL7PFXgKOHvXTXiW0deLvQr28ExXj6LjwCCDZ4YZLhq6HddLpZnX4dEdSq5g=="], @@ -1332,17 +1113,13 @@ "mime": ["mime@1.6.0", "", { "bin": { "mime": "cli.js" } }, "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="], - "mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], - - "mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], - - "mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="], + "mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], - "mimic-function": ["mimic-function@5.0.1", "", {}, "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA=="], + "mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], - "minimatch": ["minimatch@9.0.8", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-reYkDYtj/b19TeqbNZCV4q9t+Yxylf/rYBsLb42SXJatTv4/ylq5lEiAmhA/IToxO7NI2UzNMghHoHuaqDkAjw=="], + "mimic-fn": ["mimic-fn@1.2.0", "", {}, "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="], - "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="], + "minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="], "minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="], @@ -1354,8 +1131,6 @@ "multitars": ["multitars@0.2.4", "", {}, "sha512-XgLbg1HHchFauMCQPRwMj6MSyDd5koPlTA1hM3rUFkeXzGpjU/I9fP3to7yrObE9jcN8ChIOQGrM0tV0kUZaKg=="], - "mute-stream": ["mute-stream@2.0.0", "", {}, "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA=="], - "mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="], "nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], @@ -1364,16 +1139,8 @@ "negotiator": ["negotiator@0.6.3", "", {}, "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="], - "neo-async": ["neo-async@2.6.2", "", {}, "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="], - - "no-case": ["no-case@3.0.4", "", { "dependencies": { "lower-case": "^2.0.2", "tslib": "^2.0.3" } }, "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg=="], - "node-appwrite": ["node-appwrite@22.1.2", "", { "dependencies": { "json-bigint": "1.0.0", "node-fetch-native-with-agent": "1.7.2" } }, "sha512-iK30EBV+/rkU2jbHR+i2BK+7axlxjuF/G7X290jGwOc7Wa/qkkK67icgU4M+XJgCUsInha4ZeH0dWs7Gw0RT9A=="], - "node-domexception": ["node-domexception@1.0.0", "", {}, "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="], - - "node-fetch": ["node-fetch@3.3.2", "", { "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", "formdata-polyfill": "^4.0.10" } }, "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA=="], - "node-fetch-native-with-agent": ["node-fetch-native-with-agent@1.7.2", "", {}, "sha512-5MaOOCuJEvcckoz7/tjdx1M6OusOY6Xc5f459IaruGStWnKzlI1qpNgaAwmn4LmFYcsSlj+jBMk84wmmRxfk5g=="], "node-forge": ["node-forge@1.3.3", "", {}, "sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg=="], @@ -1382,12 +1149,10 @@ "node-releases": ["node-releases@2.0.27", "", {}, "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA=="], - "normalize-path": ["normalize-path@2.1.1", "", { "dependencies": { "remove-trailing-separator": "^1.0.1" } }, "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w=="], + "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], "npm-package-arg": ["npm-package-arg@11.0.3", "", { "dependencies": { "hosted-git-info": "^7.0.0", "proc-log": "^4.0.0", "semver": "^7.3.5", "validate-npm-package-name": "^5.0.0" } }, "sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw=="], - "npm-run-path": ["npm-run-path@4.0.1", "", { "dependencies": { "path-key": "^3.0.0" } }, "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw=="], - "nullthrows": ["nullthrows@1.1.1", "", {}, "sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw=="], "ob1": ["ob1@0.83.4", "", { "dependencies": { "flow-enums-runtime": "^0.0.6" } }, "sha512-9JiflaRKCkxKzH8uuZlax72cHzZ8iFLsNIORFOAKDgZUOfvfwYWOVS0ezGLzPp/yEhVktD+PTTImC0AAehSOBw=="], @@ -1400,11 +1165,11 @@ "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="], - "onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="], + "onetime": ["onetime@2.0.1", "", { "dependencies": { "mimic-fn": "^1.0.0" } }, "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ=="], "open": ["open@7.4.2", "", { "dependencies": { "is-docker": "^2.0.0", "is-wsl": "^2.1.1" } }, "sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q=="], - "optimism": ["optimism@0.18.1", "", { "dependencies": { "@wry/caches": "^1.0.0", "@wry/context": "^0.7.0", "@wry/trie": "^0.5.0", "tslib": "^2.3.0" } }, "sha512-mLXNwWPa9dgFyDqkNi54sjDyNJ9/fTI6WGBLgnXku1vdKY/jovHfZT5r+aiVeFFLOz+foPNOm5YJ4mqgld2GBQ=="], + "optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="], "ora": ["ora@3.4.0", "", { "dependencies": { "chalk": "^2.4.2", "cli-cursor": "^2.1.0", "cli-spinners": "^2.0.0", "log-symbols": "^2.2.0", "strip-ansi": "^5.2.0", "wcwidth": "^1.0.1" } }, "sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg=="], @@ -1412,25 +1177,15 @@ "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], - "p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="], + "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], "p-try": ["p-try@2.2.0", "", {}, "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ=="], - "param-case": ["param-case@3.0.4", "", { "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" } }, "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A=="], - - "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], - - "parse-filepath": ["parse-filepath@1.0.2", "", { "dependencies": { "is-absolute": "^1.0.0", "map-cache": "^0.2.0", "path-root": "^0.1.1" } }, "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q=="], - - "parse-json": ["parse-json@5.2.0", "", { "dependencies": { "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", "json-parse-even-better-errors": "^2.3.0", "lines-and-columns": "^1.1.6" } }, "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg=="], - "parse-png": ["parse-png@2.1.0", "", { "dependencies": { "pngjs": "^3.3.0" } }, "sha512-Nt/a5SfCLiTnQAjx3fHlqp8hRgTL3z7kTQZzvIMS9uCAepnCyjpdEc6M/sz69WqMBdaDBw9sF1F1UaHROYzGkQ=="], "parseurl": ["parseurl@1.3.3", "", {}, "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="], - "pascal-case": ["pascal-case@3.1.2", "", { "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3" } }, "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g=="], - - "path-case": ["path-case@3.0.4", "", { "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" } }, "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg=="], + "partysocket": ["partysocket@1.1.16", "", { "dependencies": { "event-target-polyfill": "^0.0.4" }, "peerDependencies": { "react": ">=17" }, "optionalPeers": ["react"] }, "sha512-d7xFv+ZC7x0p/DAHWJ5FhxQhimIx+ucyZY+kxL0cKddLBmK9c4p2tEA/L+dOOrWm6EYrRwrBjKQV0uSzOY9x1w=="], "path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="], @@ -1440,24 +1195,16 @@ "path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="], - "path-root": ["path-root@0.1.1", "", { "dependencies": { "path-root-regex": "^0.1.0" } }, "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg=="], - - "path-root-regex": ["path-root-regex@0.1.2", "", {}, "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ=="], - "path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="], - "path-type": ["path-type@4.0.0", "", {}, "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="], - "pathe": ["pathe@2.0.3", "", {}, "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w=="], "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], - "picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], + "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], "pirates": ["pirates@4.0.7", "", {}, "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA=="], - "pkg-dir": ["pkg-dir@4.2.0", "", { "dependencies": { "find-up": "^4.0.0" } }, "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ=="], - "pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="], "plist": ["plist@3.1.0", "", { "dependencies": { "@xmldom/xmldom": "^0.8.8", "base64-js": "^1.5.1", "xmlbuilder": "^15.1.1" } }, "sha512-uysumyrvkUX0rX/dEVqt8gC3sTBzd4zoWfLeS29nb53imdaXVvLINYXTI2GNqzaMuvacNx4uJQ8+b3zXR0pkgQ=="], @@ -1468,6 +1215,8 @@ "postcss-load-config": ["postcss-load-config@6.0.1", "", { "dependencies": { "lilconfig": "^3.1.1" }, "peerDependencies": { "jiti": ">=1.21.0", "postcss": ">=8.0.9", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["jiti", "postcss", "tsx", "yaml"] }, "sha512-oPtTM4oerL+UXmx+93ytZVN82RrlY/wPUV8IeDxFrzIjXOLF1pN+EmKPLbubvKHT2HC20xXsCAH2Z+CKV6Oz/g=="], + "prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="], + "pretty-format": ["pretty-format@29.7.0", "", { "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" } }, "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ=="], "proc-log": ["proc-log@4.2.0", "", {}, "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA=="], @@ -1478,11 +1227,11 @@ "prompts": ["prompts@2.4.2", "", { "dependencies": { "kleur": "^3.0.3", "sisteransi": "^1.0.5" } }, "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q=="], - "pure-rand": ["pure-rand@6.1.0", "", {}, "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA=="], + "proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="], - "queue": ["queue@6.0.2", "", { "dependencies": { "inherits": "~2.0.3" } }, "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA=="], + "punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="], - "queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="], + "queue": ["queue@6.0.2", "", { "dependencies": { "inherits": "~2.0.3" } }, "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA=="], "range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="], @@ -1516,44 +1265,22 @@ "regjsparser": ["regjsparser@0.13.0", "", { "dependencies": { "jsesc": "~3.1.0" }, "bin": { "regjsparser": "bin/parser" } }, "sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q=="], - "relay-runtime": ["relay-runtime@12.0.0", "", { "dependencies": { "@babel/runtime": "^7.0.0", "fbjs": "^3.0.0", "invariant": "^2.2.4" } }, "sha512-QU6JKr1tMsry22DXNy9Whsq5rmvwr3LSZiiWV/9+DFpuTWvp+WFhobWMc8TC4OjKFfNhEZy7mOiqUAn5atQtug=="], - - "remedial": ["remedial@1.0.8", "", {}, "sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg=="], - - "remove-trailing-separator": ["remove-trailing-separator@1.1.0", "", {}, "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw=="], - - "remove-trailing-spaces": ["remove-trailing-spaces@1.0.9", "", {}, "sha512-xzG7w5IRijvIkHIjDk65URsJJ7k4J95wmcArY5PRcmjldIOl7oTvG8+X2Ag690R7SfwiOcHrWZKVc1Pp5WIOzA=="], - "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="], "resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="], - "resolve-cwd": ["resolve-cwd@3.0.0", "", { "dependencies": { "resolve-from": "^5.0.0" } }, "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg=="], - "resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="], "resolve-workspace-root": ["resolve-workspace-root@2.0.1", "", {}, "sha512-nR23LHAvaI6aHtMg6RWoaHpdR4D881Nydkzi2CixINyg9T00KgaJdJI6Vwty+Ps8WLxZHuxsS0BseWjxSA4C+w=="], - "resolve.exports": ["resolve.exports@2.0.3", "", {}, "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A=="], - - "restore-cursor": ["restore-cursor@5.1.0", "", { "dependencies": { "onetime": "^7.0.0", "signal-exit": "^4.1.0" } }, "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA=="], - - "reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="], - - "rfdc": ["rfdc@1.4.1", "", {}, "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA=="], + "restore-cursor": ["restore-cursor@2.0.0", "", { "dependencies": { "onetime": "^2.0.0", "signal-exit": "^3.0.2" } }, "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q=="], "rimraf": ["rimraf@3.0.2", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" } }, "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="], "rollup": ["rollup@4.59.0", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.59.0", "@rollup/rollup-android-arm64": "4.59.0", "@rollup/rollup-darwin-arm64": "4.59.0", "@rollup/rollup-darwin-x64": "4.59.0", "@rollup/rollup-freebsd-arm64": "4.59.0", "@rollup/rollup-freebsd-x64": "4.59.0", "@rollup/rollup-linux-arm-gnueabihf": "4.59.0", "@rollup/rollup-linux-arm-musleabihf": "4.59.0", "@rollup/rollup-linux-arm64-gnu": "4.59.0", "@rollup/rollup-linux-arm64-musl": "4.59.0", "@rollup/rollup-linux-loong64-gnu": "4.59.0", "@rollup/rollup-linux-loong64-musl": "4.59.0", "@rollup/rollup-linux-ppc64-gnu": "4.59.0", "@rollup/rollup-linux-ppc64-musl": "4.59.0", "@rollup/rollup-linux-riscv64-gnu": "4.59.0", "@rollup/rollup-linux-riscv64-musl": "4.59.0", "@rollup/rollup-linux-s390x-gnu": "4.59.0", "@rollup/rollup-linux-x64-gnu": "4.59.0", "@rollup/rollup-linux-x64-musl": "4.59.0", "@rollup/rollup-openbsd-x64": "4.59.0", "@rollup/rollup-openharmony-arm64": "4.59.0", "@rollup/rollup-win32-arm64-msvc": "4.59.0", "@rollup/rollup-win32-ia32-msvc": "4.59.0", "@rollup/rollup-win32-x64-gnu": "4.59.0", "@rollup/rollup-win32-x64-msvc": "4.59.0", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-2oMpl67a3zCH9H79LeMcbDhXW/UmWG/y2zuqnF2jQq5uq9TbM9TVyXvA4+t+ne2IIkBdrLpAaRQAvo7YI/Yyeg=="], - "run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="], - - "rxjs": ["rxjs@7.8.2", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA=="], - "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="], - "safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="], - "sax": ["sax@1.4.4", "", {}, "sha512-1n3r/tGXO6b6VXMdFT54SHzT9ytu9yr7TaELowdYpMqY/Ao7EnlQGmAQ1+RatX7Tkkdm6hONI2owqNx2aZj5Sw=="], "scheduler": ["scheduler@0.26.0", "", {}, "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="], @@ -1562,14 +1289,10 @@ "send": ["send@0.19.2", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "~0.5.2", "http-errors": "~2.0.1", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "~2.4.1", "range-parser": "~1.2.1", "statuses": "~2.0.2" } }, "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg=="], - "sentence-case": ["sentence-case@3.0.4", "", { "dependencies": { "no-case": "^3.0.4", "tslib": "^2.0.3", "upper-case-first": "^2.0.2" } }, "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg=="], - "serialize-error": ["serialize-error@2.1.0", "", {}, "sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw=="], "serve-static": ["serve-static@1.16.3", "", { "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", "send": "~0.19.1" } }, "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA=="], - "setimmediate": ["setimmediate@1.0.5", "", {}, "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="], - "setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="], "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="], @@ -1580,27 +1303,19 @@ "signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], - "signedsource": ["signedsource@1.0.0", "", {}, "sha512-6+eerH9fEnNmi/hyM1DXcRK3pWdoMQtlkQ+ns0ntzunjKqp5i3sKCc80ym8Fib3iaYhdJUOPdhlJWj1tvge2Ww=="], - "simple-plist": ["simple-plist@1.3.1", "", { "dependencies": { "bplist-creator": "0.1.0", "bplist-parser": "0.3.1", "plist": "^3.0.5" } }, "sha512-iMSw5i0XseMnrhtIzRb7XpQEXepa9xhWxGUojHBL43SIpQuDQkh3Wpy67ZbDzZVr6EKxvwVChnVpdl8hEVLDiw=="], "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="], "slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="], - "slice-ansi": ["slice-ansi@7.1.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w=="], - "slugify": ["slugify@1.6.6", "", {}, "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw=="], - "snake-case": ["snake-case@3.0.4", "", { "dependencies": { "dot-case": "^3.0.4", "tslib": "^2.0.3" } }, "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg=="], - "source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="], "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="], - "source-map-support": ["source-map-support@0.5.13", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w=="], - - "sponge-case": ["sponge-case@1.0.1", "", { "dependencies": { "tslib": "^2.0.3" } }, "sha512-dblb9Et4DAtiZ5YSUZHLl4XhH4uK80GhAZrVXdN4O2P4gQ40Wa5UIOPUHlA/nFd2PLblBZWUioLMMAVrgpoYcA=="], + "source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="], "sprintf-js": ["sprintf-js@1.0.3", "", {}, "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="], @@ -1614,20 +1329,10 @@ "stream-buffers": ["stream-buffers@2.2.0", "", {}, "sha512-uyQK/mx5QjHun80FLJTfaWE7JtwfRMKBLkMne6udYOmvH0CawotVa7TfgYHzAnpphn4+TweIx1QKMnRIbipmUg=="], - "string-env-interpolation": ["string-env-interpolation@1.0.1", "", {}, "sha512-78lwMoCcn0nNu8LszbP1UA7g55OeE4v7rCeWnM5B453rnNr4aq+5it3FEYtZrSEiMvHZOZ9Jlqb0OD0M2VInqg=="], - - "string-length": ["string-length@4.0.2", "", { "dependencies": { "char-regex": "^1.0.2", "strip-ansi": "^6.0.0" } }, "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ=="], - "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="], "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "strip-bom": ["strip-bom@4.0.0", "", {}, "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w=="], - - "strip-final-newline": ["strip-final-newline@2.0.0", "", {}, "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="], - - "strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="], - "structured-headers": ["structured-headers@0.4.1", "", {}, "sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg=="], "sucrase": ["sucrase@3.35.1", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", "tinyglobby": "^0.2.11", "ts-interface-checker": "^0.1.9" }, "bin": { "sucrase": "bin/sucrase", "sucrase-node": "bin/sucrase-node" } }, "sha512-DhuTmvZWux4H1UOnWMB3sk0sbaCVOoQZjv8u1rDoTV0HTdGem9hkAZtl4JZy8P2z4Bg0nT+YMeOFyVr4zcG5Tw=="], @@ -1638,10 +1343,6 @@ "supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="], - "swap-case": ["swap-case@2.0.2", "", { "dependencies": { "tslib": "^2.0.3" } }, "sha512-kc6S2YS/2yXbtkSMunBtKdah4VFETZ8Oh6ONSmSd9bRxhqTrtARUCBUiWXH3xVPpvR7tz2CSnkuXVE42EcGnMw=="], - - "sync-fetch": ["sync-fetch@0.6.0", "", { "dependencies": { "node-fetch": "^3.3.2", "timeout-signal": "^2.0.0", "whatwg-mimetype": "^4.0.0" } }, "sha512-IELLEvzHuCfc1uTsshPK58ViSdNqXxlml1U+fmwJIKLYKOr/rAtBrorE2RYm5IHaMpDNlmC0fr1LAvdXvyheEQ=="], - "terminal-link": ["terminal-link@2.1.1", "", { "dependencies": { "ansi-escapes": "^4.2.1", "supports-hyperlinks": "^2.0.0" } }, "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ=="], "terser": ["terser@5.46.0", "", { "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, "bin": { "terser": "bin/terser" } }, "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg=="], @@ -1654,14 +1355,10 @@ "throat": ["throat@5.0.0", "", {}, "sha512-fcwX4mndzpLQKBS1DVYhGAcYaYt7vsHNIvQV+WXMvnow5cgjPphq5CaayLaGsjRdSCKZFNGt7/GYAuXaNOiYCA=="], - "timeout-signal": ["timeout-signal@2.0.0", "", {}, "sha512-YBGpG4bWsHoPvofT6y/5iqulfXIiIErl5B0LdtHT1mGXDFTAhhRrbUpTvBgYbovr+3cKblya2WAOcpoy90XguA=="], - "tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="], "tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="], - "title-case": ["title-case@3.0.3", "", { "dependencies": { "tslib": "^2.0.3" } }, "sha512-e1zGYRvbffpcHIrnuqT0Dh+gEJtDaxDSoG4JAIpq4oDFyooziLBIiYQv0GBT4FUAnUop5uZ1hiIAj7oAF6sOCA=="], - "tmpl": ["tmpl@1.0.5", "", {}, "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw=="], "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], @@ -1670,34 +1367,28 @@ "toqr": ["toqr@0.1.1", "", {}, "sha512-FWAPzCIHZHnrE/5/w9MPk0kK25hSQSH2IKhYh9PyjS3SG/+IEMvlwIHbhz+oF7xl54I+ueZlVnMjyzdSwLmAwA=="], - "tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="], - "tree-kill": ["tree-kill@1.2.2", "", { "bin": { "tree-kill": "cli.js" } }, "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A=="], - "ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="], - - "ts-jest": ["ts-jest@29.4.6", "", { "dependencies": { "bs-logger": "^0.2.6", "fast-json-stable-stringify": "^2.1.0", "handlebars": "^4.7.8", "json5": "^2.2.3", "lodash.memoize": "^4.1.2", "make-error": "^1.3.6", "semver": "^7.7.3", "type-fest": "^4.41.0", "yargs-parser": "^21.1.1" }, "peerDependencies": { "@babel/core": ">=7.0.0-beta.0 <8", "@jest/transform": "^29.0.0 || ^30.0.0", "@jest/types": "^29.0.0 || ^30.0.0", "babel-jest": "^29.0.0 || ^30.0.0", "jest": "^29.0.0 || ^30.0.0", "jest-util": "^29.0.0 || ^30.0.0", "typescript": ">=4.3 <6" }, "optionalPeers": ["@babel/core", "@jest/transform", "@jest/types", "babel-jest", "jest-util"], "bin": { "ts-jest": "cli.js" } }, "sha512-fSpWtOO/1AjSNQguk43hb/JCo16oJDnMJf3CdEGNkqsEX3t0KX96xvyX1D7PfLCpVoKu4MfVrqUkFyblYoY4lA=="], + "ts-api-utils": ["ts-api-utils@2.4.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-3TaVTaAv2gTiMB35i3FiGJaRfwb3Pyn/j3m/bfAvGe8FB7CF6u+LMYqYlDh7reQf7UNvoTvdfAqHGmPGOSsPmA=="], - "ts-log": ["ts-log@2.2.7", "", {}, "sha512-320x5Ggei84AxzlXp91QkIGSw5wgaLT6GeAH0KsqDmRZdVWW2OiSeVvElVoatk3f7nicwXlElXsoFkARiGE2yg=="], + "ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="], "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], "tsup": ["tsup@8.5.1", "", { "dependencies": { "bundle-require": "^5.1.0", "cac": "^6.7.14", "chokidar": "^4.0.3", "consola": "^3.4.0", "debug": "^4.4.0", "esbuild": "^0.27.0", "fix-dts-default-cjs-exports": "^1.0.0", "joycon": "^3.1.1", "picocolors": "^1.1.1", "postcss-load-config": "^6.0.1", "resolve-from": "^5.0.0", "rollup": "^4.34.8", "source-map": "^0.7.6", "sucrase": "^3.35.0", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.11", "tree-kill": "^1.2.2" }, "peerDependencies": { "@microsoft/api-extractor": "^7.36.0", "@swc/core": "^1", "postcss": "^8.4.12", "typescript": ">=4.5.0" }, "optionalPeers": ["@microsoft/api-extractor", "@swc/core", "postcss", "typescript"], "bin": { "tsup": "dist/cli-default.js", "tsup-node": "dist/cli-node.js" } }, "sha512-xtgkqwdhpKWr3tKPmCkvYmS9xnQK3m3XgxZHwSUjvfTjp7YfXe5tT3GgWi0F2N+ZSMsOeWeZFh7ZZFg5iPhing=="], + "type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="], + "type-detect": ["type-detect@4.0.8", "", {}, "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g=="], - "type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="], + "type-fest": ["type-fest@0.7.1", "", {}, "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg=="], "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], - "ua-parser-js": ["ua-parser-js@1.0.41", "", { "bin": { "ua-parser-js": "script/cli.js" } }, "sha512-LbBDqdIC5s8iROCUjMbW1f5dJQTEFB1+KO9ogbvlb3nm9n4YHa5p4KTvFPWvh2Hs8gZMBuiB1/8+pdfe/tDPug=="], + "typescript-eslint": ["typescript-eslint@8.56.1", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.56.1", "@typescript-eslint/parser": "8.56.1", "@typescript-eslint/typescript-estree": "8.56.1", "@typescript-eslint/utils": "8.56.1" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-U4lM6pjmBX7J5wk4szltF7I1cGBHXZopnAXCMXb3+fZ3B/0Z3hq3wS/CCUB2NZBNAExK92mCU2tEohWuwVMsDQ=="], "ufo": ["ufo@1.6.3", "", {}, "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q=="], - "uglify-js": ["uglify-js@3.19.3", "", { "bin": { "uglifyjs": "bin/uglifyjs" } }, "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ=="], - - "unc-path-regex": ["unc-path-regex@0.1.2", "", {}, "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg=="], - "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="], "unicode-canonical-property-names-ecmascript": ["unicode-canonical-property-names-ecmascript@2.0.1", "", {}, "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg=="], @@ -1708,24 +1399,16 @@ "unicode-property-aliases-ecmascript": ["unicode-property-aliases-ecmascript@2.2.0", "", {}, "sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ=="], - "unixify": ["unixify@1.0.0", "", { "dependencies": { "normalize-path": "^2.1.1" } }, "sha512-6bc58dPYhCMHHuwxldQxO3RRNZ4eCogZ/st++0+fcC1nr0jiGUtAdBJ2qzmLQWSxbtz42pWt4QQMiZ9HvZf5cg=="], - "unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="], "update-browserslist-db": ["update-browserslist-db@1.2.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w=="], - "upper-case": ["upper-case@2.0.2", "", { "dependencies": { "tslib": "^2.0.3" } }, "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg=="], - - "upper-case-first": ["upper-case-first@2.0.2", "", { "dependencies": { "tslib": "^2.0.3" } }, "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg=="], - - "urlpattern-polyfill": ["urlpattern-polyfill@10.1.0", "", {}, "sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw=="], + "uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="], "utils-merge": ["utils-merge@1.0.1", "", {}, "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA=="], "uuid": ["uuid@7.0.3", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg=="], - "v8-to-istanbul": ["v8-to-istanbul@9.3.0", "", { "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", "convert-source-map": "^2.0.0" } }, "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA=="], - "validate-npm-package-name": ["validate-npm-package-name@5.0.1", "", {}, "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ=="], "vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="], @@ -1736,23 +1419,17 @@ "wcwidth": ["wcwidth@1.0.1", "", { "dependencies": { "defaults": "^1.0.3" } }, "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg=="], - "web-streams-polyfill": ["web-streams-polyfill@3.3.3", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="], - - "webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="], - "whatwg-fetch": ["whatwg-fetch@3.6.20", "", {}, "sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg=="], "whatwg-mimetype": ["whatwg-mimetype@3.0.0", "", {}, "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q=="], - "whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="], - "whatwg-url-minimum": ["whatwg-url-minimum@0.1.1", "", {}, "sha512-u2FNVjFVFZhdjb502KzXy1gKn1mEisQRJssmSJT8CPhZdZa0AP6VCbWlXERKyGu0l09t0k50FiDiralpGhBxgA=="], "which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="], - "wordwrap": ["wordwrap@1.0.0", "", {}, "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q=="], + "word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="], - "wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="], + "wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="], @@ -1778,8 +1455,6 @@ "yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], - "yoctocolors-cjs": ["yoctocolors-cjs@2.1.3", "", {}, "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw=="], - "zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], "@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], @@ -1792,26 +1467,12 @@ "@babel/plugin-transform-runtime/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - "@expo/cli/@react-native/dev-middleware": ["@react-native/dev-middleware@0.83.2", "", { "dependencies": { "@isaacs/ttlcache": "^1.4.1", "@react-native/debugger-frontend": "0.83.2", "@react-native/debugger-shell": "0.83.2", "chrome-launcher": "^0.15.2", "chromium-edge-launcher": "^0.2.0", "connect": "^3.6.5", "debug": "^4.4.0", "invariant": "^2.2.4", "nullthrows": "^1.1.1", "open": "^7.0.3", "serve-static": "^1.16.2", "ws": "^7.5.10" } }, "sha512-Zi4EVaAm28+icD19NN07Gh8Pqg/84QQu+jn4patfWKNkcToRFP5vPEbbp0eLOGWS+BVB1d1Fn5lvMrJsBbFcOg=="], - - "@expo/cli/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], - - "@expo/cli/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], - - "@expo/cli/source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="], + "@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="], - "@expo/cli/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], - - "@expo/config/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], - - "@expo/config-plugins/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], + "@expo/cli/@react-native/dev-middleware": ["@react-native/dev-middleware@0.83.2", "", { "dependencies": { "@isaacs/ttlcache": "^1.4.1", "@react-native/debugger-frontend": "0.83.2", "@react-native/debugger-shell": "0.83.2", "chrome-launcher": "^0.15.2", "chromium-edge-launcher": "^0.2.0", "connect": "^3.6.5", "debug": "^4.4.0", "invariant": "^2.2.4", "nullthrows": "^1.1.1", "open": "^7.0.3", "serve-static": "^1.16.2", "ws": "^7.5.10" } }, "sha512-Zi4EVaAm28+icD19NN07Gh8Pqg/84QQu+jn4patfWKNkcToRFP5vPEbbp0eLOGWS+BVB1d1Fn5lvMrJsBbFcOg=="], "@expo/devcert/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="], - "@expo/fingerprint/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], - - "@expo/fingerprint/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="], - "@expo/metro/metro": ["metro@0.83.3", "", { "dependencies": { "@babel/code-frame": "^7.24.7", "@babel/core": "^7.25.2", "@babel/generator": "^7.25.0", "@babel/parser": "^7.25.3", "@babel/template": "^7.25.0", "@babel/traverse": "^7.25.3", "@babel/types": "^7.25.2", "accepts": "^1.3.7", "chalk": "^4.0.0", "ci-info": "^2.0.0", "connect": "^3.6.5", "debug": "^4.4.0", "error-stack-parser": "^2.0.6", "flow-enums-runtime": "^0.0.6", "graceful-fs": "^4.2.4", "hermes-parser": "0.32.0", "image-size": "^1.0.2", "invariant": "^2.2.4", "jest-worker": "^29.7.0", "jsc-safe-url": "^0.2.2", "lodash.throttle": "^4.1.1", "metro-babel-transformer": "0.83.3", "metro-cache": "0.83.3", "metro-cache-key": "0.83.3", "metro-config": "0.83.3", "metro-core": "0.83.3", "metro-file-map": "0.83.3", "metro-resolver": "0.83.3", "metro-runtime": "0.83.3", "metro-source-map": "0.83.3", "metro-symbolicate": "0.83.3", "metro-transform-plugins": "0.83.3", "metro-transform-worker": "0.83.3", "mime-types": "^2.1.27", "nullthrows": "^1.1.1", "serialize-error": "^2.1.0", "source-map": "^0.5.6", "throat": "^5.0.0", "ws": "^7.5.10", "yargs": "^17.6.2" }, "bin": { "metro": "src/cli.js" } }, "sha512-+rP+/GieOzkt97hSJ0MrPOuAH/jpaS21ZDvL9DJ35QYRDlQcwzcvUlGUf79AnQxq/2NPiS/AULhhM4TKutIt8Q=="], "@expo/metro/metro-config": ["metro-config@0.83.3", "", { "dependencies": { "connect": "^3.6.5", "flow-enums-runtime": "^0.0.6", "jest-validate": "^29.7.0", "metro": "0.83.3", "metro-cache": "0.83.3", "metro-core": "0.83.3", "metro-runtime": "0.83.3", "yaml": "^2.6.1" } }, "sha512-mTel7ipT0yNjKILIan04bkJkuCzUUkm2SeEaTads8VfEecCh+ltXchdq6DovXJqzQAXuR2P9cxZB47Lg4klriA=="], @@ -1824,80 +1485,12 @@ "@expo/metro/metro-symbolicate": ["metro-symbolicate@0.83.3", "", { "dependencies": { "flow-enums-runtime": "^0.0.6", "invariant": "^2.2.4", "metro-source-map": "0.83.3", "nullthrows": "^1.1.1", "source-map": "^0.5.6", "vlq": "^1.0.0" }, "bin": { "metro-symbolicate": "src/index.js" } }, "sha512-F/YChgKd6KbFK3eUR5HdUsfBqVsanf5lNTwFd4Ca7uuxnHgBC3kR/Hba/RGkenR3pZaGNp5Bu9ZqqP52Wyhomw=="], - "@expo/metro-config/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], - - "@expo/metro-config/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], - "@expo/prebuild-config/@react-native/normalize-colors": ["@react-native/normalize-colors@0.83.2", "", {}, "sha512-gkZAb9LoVVzNuYzzOviH7DiPTXQoZPHuiTH2+O2+VWNtOkiznjgvqpwYAhg58a5zfRq5GXlbBdf5mzRj5+3Y5Q=="], - "@graphql-codegen/add/tslib": ["tslib@2.6.3", "", {}, "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="], - - "@graphql-codegen/client-preset/tslib": ["tslib@2.6.3", "", {}, "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="], - - "@graphql-codegen/core/tslib": ["tslib@2.6.3", "", {}, "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="], - - "@graphql-codegen/gql-tag-operations/tslib": ["tslib@2.6.3", "", {}, "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="], - - "@graphql-codegen/plugin-helpers/tslib": ["tslib@2.6.3", "", {}, "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="], - - "@graphql-codegen/schema-ast/tslib": ["tslib@2.6.3", "", {}, "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="], - - "@graphql-codegen/typed-document-node/tslib": ["tslib@2.6.3", "", {}, "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="], - - "@graphql-codegen/typescript/tslib": ["tslib@2.6.3", "", {}, "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="], - - "@graphql-codegen/typescript-operations/tslib": ["tslib@2.6.3", "", {}, "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="], - - "@graphql-codegen/visitor-plugin-common/tslib": ["tslib@2.6.3", "", {}, "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="], - - "@graphql-tools/apollo-engine-loader/@graphql-tools/utils": ["@graphql-tools/utils@11.0.0", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@whatwg-node/promise-helpers": "^1.0.0", "cross-inspect": "1.0.1", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA=="], - - "@graphql-tools/batch-execute/@graphql-tools/utils": ["@graphql-tools/utils@11.0.0", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@whatwg-node/promise-helpers": "^1.0.0", "cross-inspect": "1.0.1", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA=="], - - "@graphql-tools/code-file-loader/@graphql-tools/utils": ["@graphql-tools/utils@11.0.0", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@whatwg-node/promise-helpers": "^1.0.0", "cross-inspect": "1.0.1", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA=="], - - "@graphql-tools/delegate/@graphql-tools/utils": ["@graphql-tools/utils@11.0.0", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@whatwg-node/promise-helpers": "^1.0.0", "cross-inspect": "1.0.1", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA=="], - - "@graphql-tools/executor/@graphql-tools/utils": ["@graphql-tools/utils@11.0.0", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@whatwg-node/promise-helpers": "^1.0.0", "cross-inspect": "1.0.1", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA=="], - - "@graphql-tools/executor-common/@graphql-tools/utils": ["@graphql-tools/utils@11.0.0", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@whatwg-node/promise-helpers": "^1.0.0", "cross-inspect": "1.0.1", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA=="], - - "@graphql-tools/executor-graphql-ws/@graphql-tools/utils": ["@graphql-tools/utils@11.0.0", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@whatwg-node/promise-helpers": "^1.0.0", "cross-inspect": "1.0.1", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA=="], - - "@graphql-tools/executor-http/@graphql-tools/utils": ["@graphql-tools/utils@11.0.0", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@whatwg-node/promise-helpers": "^1.0.0", "cross-inspect": "1.0.1", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA=="], - - "@graphql-tools/executor-legacy-ws/@graphql-tools/utils": ["@graphql-tools/utils@11.0.0", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@whatwg-node/promise-helpers": "^1.0.0", "cross-inspect": "1.0.1", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA=="], - - "@graphql-tools/git-loader/@graphql-tools/utils": ["@graphql-tools/utils@11.0.0", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@whatwg-node/promise-helpers": "^1.0.0", "cross-inspect": "1.0.1", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA=="], - - "@graphql-tools/github-loader/@graphql-tools/utils": ["@graphql-tools/utils@11.0.0", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@whatwg-node/promise-helpers": "^1.0.0", "cross-inspect": "1.0.1", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA=="], - - "@graphql-tools/graphql-file-loader/@graphql-tools/utils": ["@graphql-tools/utils@11.0.0", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@whatwg-node/promise-helpers": "^1.0.0", "cross-inspect": "1.0.1", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA=="], - - "@graphql-tools/graphql-tag-pluck/@graphql-tools/utils": ["@graphql-tools/utils@11.0.0", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@whatwg-node/promise-helpers": "^1.0.0", "cross-inspect": "1.0.1", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA=="], - - "@graphql-tools/import/@graphql-tools/utils": ["@graphql-tools/utils@11.0.0", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@whatwg-node/promise-helpers": "^1.0.0", "cross-inspect": "1.0.1", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA=="], - - "@graphql-tools/json-file-loader/@graphql-tools/utils": ["@graphql-tools/utils@11.0.0", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@whatwg-node/promise-helpers": "^1.0.0", "cross-inspect": "1.0.1", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA=="], - - "@graphql-tools/load/@graphql-tools/utils": ["@graphql-tools/utils@11.0.0", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@whatwg-node/promise-helpers": "^1.0.0", "cross-inspect": "1.0.1", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA=="], - - "@graphql-tools/merge/@graphql-tools/utils": ["@graphql-tools/utils@11.0.0", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@whatwg-node/promise-helpers": "^1.0.0", "cross-inspect": "1.0.1", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA=="], - - "@graphql-tools/relay-operation-optimizer/@graphql-tools/utils": ["@graphql-tools/utils@11.0.0", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@whatwg-node/promise-helpers": "^1.0.0", "cross-inspect": "1.0.1", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA=="], - - "@graphql-tools/schema/@graphql-tools/utils": ["@graphql-tools/utils@11.0.0", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@whatwg-node/promise-helpers": "^1.0.0", "cross-inspect": "1.0.1", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA=="], - - "@graphql-tools/url-loader/@graphql-tools/utils": ["@graphql-tools/utils@11.0.0", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@whatwg-node/promise-helpers": "^1.0.0", "cross-inspect": "1.0.1", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA=="], - - "@graphql-tools/wrap/@graphql-tools/utils": ["@graphql-tools/utils@11.0.0", "", { "dependencies": { "@graphql-typed-document-node/core": "^3.1.1", "@whatwg-node/promise-helpers": "^1.0.0", "cross-inspect": "1.0.1", "tslib": "^2.4.0" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-bM1HeZdXA2C3LSIeLOnH/bcqSgbQgKEDrjxODjqi3y58xai2TkNrtYcQSoWzGbt9VMN1dORGjR7Vem8SPnUFQA=="], - - "@inquirer/core/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], - - "@inquirer/core/wrap-ansi": ["wrap-ansi@6.2.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA=="], - "@istanbuljs/load-nyc-config/camelcase": ["camelcase@5.3.1", "", {}, "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg=="], + "@istanbuljs/load-nyc-config/find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="], + "@istanbuljs/load-nyc-config/js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="], "@react-native/babel-plugin-codegen/@react-native/codegen": ["@react-native/codegen@0.83.2", "", { "dependencies": { "@babel/core": "^7.25.2", "@babel/parser": "^7.25.3", "glob": "^7.1.1", "hermes-parser": "0.32.0", "invariant": "^2.2.4", "nullthrows": "^1.1.1", "yargs": "^17.6.2" } }, "sha512-9uK6X1miCXqtL4c759l74N/XbQeneWeQVjoV7SD2CGJuW7ZefxaoYenwGPs7rMoCdtS6wuIyR3hXQ+uWEBGYXA=="], @@ -1906,25 +1499,19 @@ "@testing-library/dom/pretty-format": ["pretty-format@27.5.1", "", { "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" } }, "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ=="], - "accepts/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], + "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], "ansi-escapes/type-fest": ["type-fest@0.21.3", "", {}, "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w=="], - "anymatch/normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="], - - "babel-plugin-istanbul/istanbul-lib-instrument": ["istanbul-lib-instrument@5.2.1", "", { "dependencies": { "@babel/core": "^7.12.3", "@babel/parser": "^7.14.7", "@istanbuljs/schema": "^0.1.2", "istanbul-lib-coverage": "^3.2.0", "semver": "^6.3.0" } }, "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg=="], + "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], "babel-plugin-polyfill-corejs2/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], "better-opn/open": ["open@8.4.2", "", { "dependencies": { "define-lazy-prop": "^2.0.0", "is-docker": "^2.1.1", "is-wsl": "^2.2.0" } }, "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ=="], - "chrome-launcher/escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], + "chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], - "chromium-edge-launcher/escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="], - - "cli-truncate/string-width": ["string-width@8.2.0", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw=="], - - "cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], + "compressible/mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], "compression/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], @@ -1932,14 +1519,10 @@ "connect/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], - "cross-fetch/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], - "expo/expo-file-system": ["expo-file-system@55.0.9", "", { "peerDependencies": { "expo": "*", "react-native": "*" } }, "sha512-jJ0BMGSBk0YgyxG9GB71qLW+jSWqjWkRnOhSGn9ry98XL045faNKPJ7rq94ENmNjt98QLEm5I+NEvBxt/EYAdQ=="], "expo-modules-autolinking/commander": ["commander@7.2.0", "", {}, "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="], - "fbjs/promise": ["promise@7.3.1", "", { "dependencies": { "asap": "~2.0.3" } }, "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg=="], - "finalhandler/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], "finalhandler/encodeurl": ["encodeurl@1.0.2", "", {}, "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="], @@ -1948,27 +1531,17 @@ "finalhandler/statuses": ["statuses@1.5.0", "", {}, "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA=="], - "glob/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="], - - "graphql-config/@graphql-tools/url-loader": ["@graphql-tools/url-loader@8.0.33", "", { "dependencies": { "@graphql-tools/executor-graphql-ws": "^2.0.1", "@graphql-tools/executor-http": "^1.1.9", "@graphql-tools/executor-legacy-ws": "^1.1.19", "@graphql-tools/utils": "^10.9.1", "@graphql-tools/wrap": "^10.0.16", "@types/ws": "^8.0.0", "@whatwg-node/fetch": "^0.10.0", "@whatwg-node/promise-helpers": "^1.0.0", "isomorphic-ws": "^5.0.0", "sync-fetch": "0.6.0-2", "tslib": "^2.4.0", "ws": "^8.17.1" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-Fu626qcNHcqAj8uYd7QRarcJn5XZ863kmxsg1sm0fyjyfBJnsvC7ddFt6Hayz5kxVKfsnjxiDfPMXanvsQVBKw=="], - - "graphql-config/cosmiconfig": ["cosmiconfig@8.3.6", "", { "dependencies": { "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0", "path-type": "^4.0.0" }, "peerDependencies": { "typescript": ">=4.9.5" }, "optionalPeers": ["typescript"] }, "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA=="], - - "handlebars/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], - "hosted-git-info/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], - "import-fresh/resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], + "istanbul-lib-instrument/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - "istanbul-lib-source-maps/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], + "jest-util/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], "jest-worker/supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="], "lighthouse-logger/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], - "log-update/ansi-escapes": ["ansi-escapes@7.3.0", "", { "dependencies": { "environment": "^1.0.0" } }, "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg=="], - - "log-update/strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="], + "log-symbols/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="], "metro/accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="], @@ -1990,6 +1563,8 @@ "metro/metro-transform-worker": ["metro-transform-worker@0.83.4", "", { "dependencies": { "@babel/core": "^7.25.2", "@babel/generator": "^7.29.1", "@babel/parser": "^7.29.0", "@babel/types": "^7.29.0", "flow-enums-runtime": "^0.0.6", "metro": "0.83.4", "metro-babel-transformer": "0.83.4", "metro-cache": "0.83.4", "metro-cache-key": "0.83.4", "metro-minify-terser": "0.83.4", "metro-source-map": "0.83.4", "metro-transform-plugins": "0.83.4", "nullthrows": "^1.1.1" } }, "sha512-6I81IZLeU/0ww7OBgCPALFl0OE0FQwvIuKCtuViSiKufmislF7kVr7IHH9GYtQuZcnualQ82gYeQ11KzZQTouw=="], + "metro/mime-types": ["mime-types@3.0.2", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A=="], + "metro/source-map": ["source-map@0.5.7", "", {}, "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ=="], "metro/ws": ["ws@7.5.10", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ=="], @@ -2008,59 +1583,39 @@ "metro-transform-worker/metro-source-map": ["metro-source-map@0.83.3", "", { "dependencies": { "@babel/traverse": "^7.25.3", "@babel/traverse--for-generate-function-map": "npm:@babel/traverse@^7.25.3", "@babel/types": "^7.25.2", "flow-enums-runtime": "^0.0.6", "invariant": "^2.2.4", "metro-symbolicate": "0.83.3", "nullthrows": "^1.1.1", "ob1": "0.83.3", "source-map": "^0.5.6", "vlq": "^1.0.0" } }, "sha512-xkC3qwUBh2psVZgVavo8+r2C9Igkk3DibiOXSAht1aYRRcztEZNFtAMtfSB7sdO2iFMx2Mlyu++cBxz/fhdzQg=="], - "ora/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="], - - "ora/cli-cursor": ["cli-cursor@2.1.0", "", { "dependencies": { "restore-cursor": "^2.0.0" } }, "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw=="], + "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], - "ora/log-symbols": ["log-symbols@2.2.0", "", { "dependencies": { "chalk": "^2.0.1" } }, "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg=="], + "ora/chalk": ["chalk@2.4.2", "", { "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ=="], "ora/strip-ansi": ["strip-ansi@5.2.0", "", { "dependencies": { "ansi-regex": "^4.1.0" } }, "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA=="], - "p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], - "path-scurry/lru-cache": ["lru-cache@11.2.6", "", {}, "sha512-ESL2CrkS/2wTPfuend7Zhkzo2u0daGJ/A2VucJOgQ/C48S/zB8MMeMHSGKYpXhIjbPxfuezITkaBH1wqv00DDQ=="], - "pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], - "react-devtools-core/ws": ["ws@7.5.10", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ=="], "react-native/scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="], "react-native/ws": ["ws@7.5.10", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ=="], - "restore-cursor/onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="], - - "restore-cursor/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="], + "rimraf/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], "send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], "simple-plist/bplist-parser": ["bplist-parser@0.3.1", "", { "dependencies": { "big-integer": "1.6.x" } }, "sha512-PyJxiNtA5T2PlLIeBot4lbp7rj4OadzjnMZD/G5zuBNt8ei/yCU7+wW0h2bag9vr8c+/WuRWmSxbqAl9hL1rBA=="], - "slice-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], - - "slice-ansi/is-fullwidth-code-point": ["is-fullwidth-code-point@5.1.0", "", { "dependencies": { "get-east-asian-width": "^1.3.1" } }, "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ=="], - "source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], - "stacktrace-parser/type-fest": ["type-fest@0.7.1", "", {}, "sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg=="], + "stack-utils/escape-string-regexp": ["escape-string-regexp@2.0.0", "", {}, "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w=="], "sucrase/commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="], - "sync-fetch/whatwg-mimetype": ["whatwg-mimetype@4.0.0", "", {}, "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg=="], - "terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="], - "terser/source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="], + "test-exclude/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], "test-exclude/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="], - "tinyglobby/picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="], - - "wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], - - "wrap-ansi/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="], - - "wrap-ansi/strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="], + "wrap-ansi/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], "xml2js/xmlbuilder": ["xmlbuilder@11.0.1", "", {}, "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="], @@ -2070,20 +1625,8 @@ "@expo/cli/@react-native/dev-middleware/ws": ["ws@7.5.10", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ=="], - "@expo/cli/glob/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="], - - "@expo/cli/source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], - - "@expo/config-plugins/glob/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="], - - "@expo/config/glob/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="], - - "@expo/metro-config/glob/minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="], - "@expo/metro/metro/ci-info": ["ci-info@2.0.0", "", {}, "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ=="], - "@expo/metro/metro/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], - "@expo/metro/metro/source-map": ["source-map@0.5.7", "", {}, "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ=="], "@expo/metro/metro/ws": ["ws@7.5.10", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ=="], @@ -2094,37 +1637,27 @@ "@expo/metro/metro-symbolicate/source-map": ["source-map@0.5.7", "", {}, "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ=="], + "@istanbuljs/load-nyc-config/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="], + "@istanbuljs/load-nyc-config/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], - "@testing-library/dom/pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], + "@react-native/babel-plugin-codegen/@react-native/codegen/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="], "@testing-library/dom/pretty-format/react-is": ["react-is@17.0.2", "", {}, "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="], - "accepts/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], - - "babel-plugin-istanbul/istanbul-lib-instrument/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - - "cli-truncate/string-width/strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="], - "compression/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], "connect/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], "finalhandler/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], - "glob/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="], - - "graphql-config/@graphql-tools/url-loader/@graphql-tools/executor-graphql-ws": ["@graphql-tools/executor-graphql-ws@2.0.7", "", { "dependencies": { "@graphql-tools/executor-common": "^0.0.6", "@graphql-tools/utils": "^10.9.1", "@whatwg-node/disposablestack": "^0.0.6", "graphql-ws": "^6.0.6", "isomorphic-ws": "^5.0.0", "tslib": "^2.8.1", "ws": "^8.18.3" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-J27za7sKF6RjhmvSOwOQFeNhNHyP4f4niqPnerJmq73OtLx9Y2PGOhkXOEB0PjhvPJceuttkD2O1yMgEkTGs3Q=="], - - "graphql-config/@graphql-tools/url-loader/@graphql-tools/executor-http": ["@graphql-tools/executor-http@1.3.3", "", { "dependencies": { "@graphql-hive/signal": "^1.0.0", "@graphql-tools/executor-common": "^0.0.4", "@graphql-tools/utils": "^10.8.1", "@repeaterjs/repeater": "^3.0.4", "@whatwg-node/disposablestack": "^0.0.6", "@whatwg-node/fetch": "^0.10.4", "@whatwg-node/promise-helpers": "^1.3.0", "meros": "^1.2.1", "tslib": "^2.8.1" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-LIy+l08/Ivl8f8sMiHW2ebyck59JzyzO/yF9SFS4NH6MJZUezA1xThUXCDIKhHiD56h/gPojbkpcFvM2CbNE7A=="], + "lighthouse-logger/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], - "graphql-config/@graphql-tools/url-loader/@graphql-tools/wrap": ["@graphql-tools/wrap@10.1.4", "", { "dependencies": { "@graphql-tools/delegate": "^10.2.23", "@graphql-tools/schema": "^10.0.25", "@graphql-tools/utils": "^10.9.1", "@whatwg-node/promise-helpers": "^1.3.0", "tslib": "^2.8.1" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-7pyNKqXProRjlSdqOtrbnFRMQAVamCmEREilOXtZujxY6kYit3tvWWSjUrcIOheltTffoRh7EQSjpy2JDCzasg=="], + "log-symbols/chalk/ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="], - "graphql-config/@graphql-tools/url-loader/sync-fetch": ["sync-fetch@0.6.0-2", "", { "dependencies": { "node-fetch": "^3.3.2", "timeout-signal": "^2.0.0", "whatwg-mimetype": "^4.0.0" } }, "sha512-c7AfkZ9udatCuAy9RSfiGPpeOKKUAUK5e1cXadLOGUjasdxqYqAK0jTNkM/FSEyJ3a5Ra27j/tw/PS0qLmaF/A=="], + "log-symbols/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], - "lighthouse-logger/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], - - "log-update/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], + "log-symbols/chalk/supports-color": ["supports-color@5.5.0", "", { "dependencies": { "has-flag": "^3.0.0" } }, "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="], "metro-transform-worker/metro/ci-info": ["ci-info@2.0.0", "", {}, "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ=="], @@ -2136,8 +1669,6 @@ "metro-transform-worker/metro/metro-symbolicate": ["metro-symbolicate@0.83.3", "", { "dependencies": { "flow-enums-runtime": "^0.0.6", "invariant": "^2.2.4", "metro-source-map": "0.83.3", "nullthrows": "^1.1.1", "source-map": "^0.5.6", "vlq": "^1.0.0" }, "bin": { "metro-symbolicate": "src/index.js" } }, "sha512-F/YChgKd6KbFK3eUR5HdUsfBqVsanf5lNTwFd4Ca7uuxnHgBC3kR/Hba/RGkenR3pZaGNp5Bu9ZqqP52Wyhomw=="], - "metro-transform-worker/metro/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="], - "metro-transform-worker/metro/source-map": ["source-map@0.5.7", "", {}, "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ=="], "metro-transform-worker/metro/ws": ["ws@7.5.10", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ=="], @@ -2154,56 +1685,48 @@ "metro/metro-transform-worker/metro-minify-terser": ["metro-minify-terser@0.83.4", "", { "dependencies": { "flow-enums-runtime": "^0.0.6", "terser": "^5.15.0" } }, "sha512-KmZnpxfj0nPIRkbBNTc6xul5f5GPvWL5kQ1UkisB7qFkgh6+UiJG+L4ukJ2sK7St6+8Za/Cb68MUEYkUouIYcQ=="], + "metro/mime-types/mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="], + "ora/chalk/ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="], "ora/chalk/escape-string-regexp": ["escape-string-regexp@1.0.5", "", {}, "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="], "ora/chalk/supports-color": ["supports-color@5.5.0", "", { "dependencies": { "has-flag": "^3.0.0" } }, "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow=="], - "ora/cli-cursor/restore-cursor": ["restore-cursor@2.0.0", "", { "dependencies": { "onetime": "^2.0.0", "signal-exit": "^3.0.2" } }, "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q=="], - "ora/strip-ansi/ansi-regex": ["ansi-regex@4.1.1", "", {}, "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g=="], - "send/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], + "rimraf/glob/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="], - "terser/source-map-support/source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="], + "send/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], "test-exclude/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="], - "wrap-ansi/string-width/emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="], - - "wrap-ansi/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], - - "@expo/metro/metro/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], - - "cli-truncate/string-width/strip-ansi/ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="], - - "glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], - - "graphql-config/@graphql-tools/url-loader/@graphql-tools/executor-graphql-ws/@graphql-tools/executor-common": ["@graphql-tools/executor-common@0.0.6", "", { "dependencies": { "@envelop/core": "^5.3.0", "@graphql-tools/utils": "^10.9.1" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-JAH/R1zf77CSkpYATIJw+eOJwsbWocdDjY+avY7G+P5HCXxwQjAjWVkJI1QJBQYjPQDVxwf1fmTZlIN3VOadow=="], + "@istanbuljs/load-nyc-config/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="], - "graphql-config/@graphql-tools/url-loader/@graphql-tools/executor-http/@graphql-hive/signal": ["@graphql-hive/signal@1.0.0", "", {}, "sha512-RiwLMc89lTjvyLEivZ/qxAC5nBHoS2CtsWFSOsN35sxG9zoo5Z+JsFHM8MlvmO9yt+MJNIyC5MLE1rsbOphlag=="], + "@react-native/babel-plugin-codegen/@react-native/codegen/glob/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="], - "graphql-config/@graphql-tools/url-loader/@graphql-tools/executor-http/@graphql-tools/executor-common": ["@graphql-tools/executor-common@0.0.4", "", { "dependencies": { "@envelop/core": "^5.2.3", "@graphql-tools/utils": "^10.8.1" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-SEH/OWR+sHbknqZyROCFHcRrbZeUAyjCsgpVWCRjqjqRbiJiXq6TxNIIOmpXgkrXWW/2Ev4Wms6YSGJXjdCs6Q=="], + "log-symbols/chalk/ansi-styles/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="], - "graphql-config/@graphql-tools/url-loader/@graphql-tools/wrap/@graphql-tools/delegate": ["@graphql-tools/delegate@10.2.23", "", { "dependencies": { "@graphql-tools/batch-execute": "^9.0.19", "@graphql-tools/executor": "^1.4.9", "@graphql-tools/schema": "^10.0.25", "@graphql-tools/utils": "^10.9.1", "@repeaterjs/repeater": "^3.0.6", "@whatwg-node/promise-helpers": "^1.3.0", "dataloader": "^2.2.3", "dset": "^3.1.2", "tslib": "^2.8.1" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-xrPtl7f1LxS+B6o+W7ueuQh67CwRkfl+UKJncaslnqYdkxKmNBB4wnzVcW8ZsRdwbsla/v43PtwAvSlzxCzq2w=="], - - "graphql-config/@graphql-tools/url-loader/sync-fetch/whatwg-mimetype": ["whatwg-mimetype@4.0.0", "", {}, "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg=="], - - "metro-transform-worker/metro/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="], + "log-symbols/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="], "ora/chalk/ansi-styles/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="], "ora/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="], - "ora/cli-cursor/restore-cursor/onetime": ["onetime@2.0.1", "", { "dependencies": { "mimic-fn": "^1.0.0" } }, "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ=="], + "rimraf/glob/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="], "test-exclude/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], - "graphql-config/@graphql-tools/url-loader/@graphql-tools/wrap/@graphql-tools/delegate/@graphql-tools/batch-execute": ["@graphql-tools/batch-execute@9.0.19", "", { "dependencies": { "@graphql-tools/utils": "^10.9.1", "@whatwg-node/promise-helpers": "^1.3.0", "dataloader": "^2.2.3", "tslib": "^2.8.1" }, "peerDependencies": { "graphql": "^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, "sha512-VGamgY4PLzSx48IHPoblRw0oTaBa7S26RpZXt0Y4NN90ytoE0LutlpB2484RbkfcTjv9wa64QD474+YP1kEgGA=="], + "@istanbuljs/load-nyc-config/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="], + + "@react-native/babel-plugin-codegen/@react-native/codegen/glob/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="], + + "log-symbols/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="], "ora/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="], - "ora/cli-cursor/restore-cursor/onetime/mimic-fn": ["mimic-fn@1.2.0", "", {}, "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="], + "rimraf/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], + + "@react-native/babel-plugin-codegen/@react-native/codegen/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], } } diff --git a/bunfig.toml b/bunfig.toml index 950bace..d208bdb 100644 --- a/bunfig.toml +++ b/bunfig.toml @@ -1,7 +1,8 @@ [test] -preload = ["./tests/setup/preload.ts"] +preload = ["./tests/setup/preload.ts", "./tests/__mocks__/Realtime.ts"] coveragePathIgnorePatterns = [ "tests/**", - "src/__generated__/**" + "src/__generated__/**", + "src/offline/network/**" ] diff --git a/codegen.ts b/codegen.ts deleted file mode 100644 index 30087e4..0000000 --- a/codegen.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { CodegenConfig } from '@graphql-codegen/cli' - -const config: CodegenConfig = { - overwrite: true, - schema: 'src/schema.graphql', - documents: ['src/**/*.tsx', 'src/**/*.ts', 'app/**/*.tsx', 'app/**/*.ts'], - generates: { - 'src/__generated__/': { - preset: 'client', - plugins: [], - presetConfig: { - gqlTagName: 'gql', - fragmentMasking: { - unmaskFunctionName: 'getFragmentData', - }, - }, - }, - }, -} - -export default config diff --git a/eslint.config.mjs b/eslint.config.mjs new file mode 100644 index 0000000..f82dbbc --- /dev/null +++ b/eslint.config.mjs @@ -0,0 +1,70 @@ +// @ts-check + +import eslint from '@eslint/js' +import { defineConfig } from 'eslint/config' +import tseslint from 'typescript-eslint' +import simpleImportSort from 'eslint-plugin-simple-import-sort' + +export default defineConfig( + eslint.configs.recommended, + tseslint.configs.recommended, + { + ignores: [ + 'eslint.config.mjs', + 'react-native/**', + 'dist/**', + 'src/__generated__/**', + 'node_modules/**', + 'post-build.js', + ], + }, + { + files: ['**/*.{js,mjs,cjs,ts,jsx,tsx}'], + languageOptions: { + parserOptions: { + project: ['./tsconfig.json'], + }, + }, + plugins: { + 'simple-import-sort': simpleImportSort, + }, + rules: { + '@typescript-eslint/no-unused-vars': 'error', + '@typescript-eslint/no-explicit-any': 'warn', + 'simple-import-sort/imports': [ + 'warn', + { + groups: [ + // 1. Side effect imports at the start. For me this is important because I want to import reset.css and global styles at the top of my main file. + ['^\\u0000'], + // 2. `react` and packages: Things that start with a letter (or digit or underscore), or `@` followed by a letter. + ['^react$', '^@?\\w'], + // 3. Absolute imports and other imports such as Vue-style `@/foo`. + // Anything not matched in another group. (also relative imports starting with "../") + ['^@', '^~'], + // 4. relative imports from same folder "./" (I like to have them grouped together) + ['^\\./', '^\\.\\./', '^\\.\\.'], + // 5. style module imports always come last, this helps to avoid CSS order issues + ['^.+\\.(module.css|module.scss)$'], + // 6. media imports + ['^.+\\.(gif|png|svg|jpg)$'], + ], + }, + ], + '@typescript-eslint/no-floating-promises': [ + 'error', + { + ignoreVoid: true, + allowForKnownSafeCalls: [ + { + from: 'package', + name: ['mock', 'module'], + package: 'bun:test', + }, + ], + }, + ], + '@typescript-eslint/consistent-type-imports': 'error', + }, + }, +) diff --git a/package.json b/package.json index bfd544c..3392503 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,28 @@ { "name": "@zeroin.earth/appwrite-graphql", "version": "22.4.1", - "description": "Appwrite Graphql library, utilizing @tanstack/react-query and inspired by react-appwrite", - "main": "./dist/index.js", - "module": "./dist/index.mjs", + "description": "Appwrite Graphql library, utilizing @tanstack/react-query", + "main": "./dist/index.cjs", + "module": "./dist/index.js", "types": "./dist/index.d.ts", + "exports": { + ".": { + "import": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + }, + "require": { + "types": "./dist/index.d.cts", + "default": "./dist/index.cjs" + } + }, + "./react-native": { + "require": { + "types": "./react-native/index.d.cts", + "default": "./react-native/index.cjs" + } + } + }, "files": [ "dist", "react-native" @@ -17,56 +35,67 @@ "license": "MIT", "scripts": { "build": "tsup && tsup --config tsup.native.config.ts && node post-build.js", - "codegen": "graphql-codegen --config codegen.ts", - "prepublishOnly": "bun run tsc && bun run codegen && bun run build", + "prepublishOnly": "bun run tsc && bun run build", "tsc": "tsc --noEmit", "typecheck": "tsc --noEmit", - "test": "bun test --timeout 30000 --only-failures", + "test": "bun test --timeout 30000", "test:setup": "bun run tests/setup/setup.ts", "test:teardown": "bun run tests/setup/teardown.ts" }, "dependencies": { "@graphql-typed-document-node/core": "^3.2.0", + "@tanstack/query-async-storage-persister": "^5.90.24", + "@tanstack/react-query-devtools": "^5.91.3", + "@tanstack/react-query-persist-client": "^5.90.24", + "gql.tada": "^1.9.0", "graphql": "^16.10.0", "graphql-scalars": "^1.24.2", "immer": "^11.1.4" }, "peerDependencies": { + "@react-native-async-storage/async-storage": "^3.0.1", + "@react-native-community/netinfo": "^12.0.1", "@tanstack/react-query": "^5.70.0", "appwrite": "^22.4.1", - "jotai": "^2.12.2", + "react": "19.1.0", "react-native-appwrite": "^0.24.1" }, "peerDependenciesMeta": { "react-native-appwrite": { "optional": true + }, + "@react-native-async-storage/async-storage": { + "optional": true + }, + "@react-native-community/netinfo": { + "optional": true } }, "devDependencies": { - "@apollo/client": "^4.1.6", - "@graphql-codegen/cli": "^6.1.2", - "@graphql-codegen/client-preset": "^5.2.3", + "@eslint/js": "^10.0.1", "@happy-dom/global-registrator": "^20.7.0", + "@react-native-async-storage/async-storage": "^3.0.1", + "@react-native-community/netinfo": "^12.0.1", "@tanstack/react-query": "^5.70.0", "@testing-library/react": "^16.3.2", "@testing-library/react-hooks": "^8.0.1", "@types/bun": "latest", "@types/identity-obj-proxy": "^3.0.2", - "@types/jest": "^29.5.14", "@types/react": "^19.2.14", "appwrite": "^22.4.1", + "eslint": "^10.0.2", + "eslint-plugin-simple-import-sort": "^12.1.1", "happy-dom": "^20.7.0", "identity-obj-proxy": "^3.0.0", - "jest": "^29.7.0", - "jotai": "^2.12.2", + "mailpit-api": "^1.7.1", "node-appwrite": "^22.1.2", "otpauth": "^9.5.0", "react": "19.1.0", "react-dom": "19.1.0", "react-native-appwrite": "^0.24.1", - "ts-jest": "^29.3.0", "tsup": "^8.4.0", - "typescript": "^5.8.2" + "typescript": "^5.9.3", + "typescript-eslint": "^8.56.1" }, "publishConfig": { "access": "public" diff --git a/src/AppwriteProvider.tsx b/src/AppwriteProvider.tsx index 3ee481b..9f42585 100644 --- a/src/AppwriteProvider.tsx +++ b/src/AppwriteProvider.tsx @@ -1,26 +1,57 @@ -import { QueryClient } from '@tanstack/react-query' -import { useHydrateAtoms } from 'jotai/utils' +import * as React from 'react' +import { type ReactNode } from 'react' +import type { Persister } from '@tanstack/query-persist-client-core' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import { ReactQueryDevtools } from '@tanstack/react-query-devtools' +import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client' -import { appwriteAtom } from './states/appwrite' -import { QueryAtom } from './states/query' +import type { AppwriteClient } from './client' + +export const AppwriteContext = React.createContext(null) + +const defaultQueryClient = new QueryClient() export function AppwriteProvider({ - endpoint, - projectId, + client, queryClient, + persister, + onCacheRestored, children, }: { - endpoint: string - projectId: string + client: AppwriteClient queryClient?: QueryClient - children: React.ReactNode + persister?: Persister + onCacheRestored?: () => void + children: ReactNode }) { - const atoms: [any, any][] = [[appwriteAtom, { endpoint, projectId }]] + const qc = queryClient ?? defaultQueryClient - if (queryClient) { - atoms.push([QueryAtom, queryClient]) + if (persister) { + return ( + mutation.state.isPaused, + shouldDehydrateQuery: (query) => query.state.status === 'success', + }, + }} + onSuccess={() => { + void qc.resumePausedMutations() + onCacheRestored?.() + }} + > + {children} + + + ) } - useHydrateAtoms(atoms) - return children + return ( + + {children} + + + ) } diff --git a/src/__generated__/fragment-masking.ts b/src/__generated__/fragment-masking.ts deleted file mode 100644 index 6155de5..0000000 --- a/src/__generated__/fragment-masking.ts +++ /dev/null @@ -1,87 +0,0 @@ -/* eslint-disable */ -import { ResultOf, DocumentTypeDecoration, TypedDocumentNode } from '@graphql-typed-document-node/core'; -import { FragmentDefinitionNode } from 'graphql'; -import { Incremental } from './graphql'; - - -export type FragmentType> = TDocumentType extends DocumentTypeDecoration< - infer TType, - any -> - ? [TType] extends [{ ' $fragmentName'?: infer TKey }] - ? TKey extends string - ? { ' $fragmentRefs'?: { [key in TKey]: TType } } - : never - : never - : never; - -// return non-nullable if `fragmentType` is non-nullable -export function getFragmentData( - _documentNode: DocumentTypeDecoration, - fragmentType: FragmentType> -): TType; -// return nullable if `fragmentType` is undefined -export function getFragmentData( - _documentNode: DocumentTypeDecoration, - fragmentType: FragmentType> | undefined -): TType | undefined; -// return nullable if `fragmentType` is nullable -export function getFragmentData( - _documentNode: DocumentTypeDecoration, - fragmentType: FragmentType> | null -): TType | null; -// return nullable if `fragmentType` is nullable or undefined -export function getFragmentData( - _documentNode: DocumentTypeDecoration, - fragmentType: FragmentType> | null | undefined -): TType | null | undefined; -// return array of non-nullable if `fragmentType` is array of non-nullable -export function getFragmentData( - _documentNode: DocumentTypeDecoration, - fragmentType: Array>> -): Array; -// return array of nullable if `fragmentType` is array of nullable -export function getFragmentData( - _documentNode: DocumentTypeDecoration, - fragmentType: Array>> | null | undefined -): Array | null | undefined; -// return readonly array of non-nullable if `fragmentType` is array of non-nullable -export function getFragmentData( - _documentNode: DocumentTypeDecoration, - fragmentType: ReadonlyArray>> -): ReadonlyArray; -// return readonly array of nullable if `fragmentType` is array of nullable -export function getFragmentData( - _documentNode: DocumentTypeDecoration, - fragmentType: ReadonlyArray>> | null | undefined -): ReadonlyArray | null | undefined; -export function getFragmentData( - _documentNode: DocumentTypeDecoration, - fragmentType: FragmentType> | Array>> | ReadonlyArray>> | null | undefined -): TType | Array | ReadonlyArray | null | undefined { - return fragmentType as any; -} - - -export function makeFragmentData< - F extends DocumentTypeDecoration, - FT extends ResultOf ->(data: FT, _fragment: F): FragmentType { - return data as FragmentType; -} -export function isFragmentReady( - queryNode: DocumentTypeDecoration, - fragmentNode: TypedDocumentNode, - data: FragmentType, any>> | null | undefined -): data is FragmentType { - const deferredFields = (queryNode as { __meta__?: { deferredFields: Record } }).__meta__ - ?.deferredFields; - - if (!deferredFields) return true; - - const fragDef = fragmentNode.definitions[0] as FragmentDefinitionNode | undefined; - const fragName = fragDef?.name?.value; - - const fields = (fragName && deferredFields[fragName]) || []; - return fields.length > 0 && fields.every(field => data && field in data); -} diff --git a/src/__generated__/gql.ts b/src/__generated__/gql.ts deleted file mode 100644 index a3390eb..0000000 --- a/src/__generated__/gql.ts +++ /dev/null @@ -1,628 +0,0 @@ -/* eslint-disable */ -import * as types from './graphql'; -import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; - -/** - * Map of all GraphQL operations in the project. - * - * This map has several performance disadvantages: - * 1. It is not tree-shakeable, so it will include all operations in the project. - * 2. It is not minifiable, so the string of a GraphQL query will be multiple times inside the bundle. - * 3. It does not support dead code elimination, so it will add unused operations. - * - * Therefore it is highly recommended to use the babel or swc plugin for production. - * Learn more about it here: https://the-guild.dev/graphql/codegen/plugins/presets/preset-client#reducing-bundle-size - */ -type Documents = { - "\n fragment Account_User on User {\n _id\n name\n email\n prefs {\n data\n }\n }\n": typeof types.Account_UserFragmentDoc, - "\n fragment Identity_Provider on Identity {\n _id\n userId\n provider\n }\n": typeof types.Identity_ProviderFragmentDoc, - "\n query AccountGet {\n accountGet {\n ...Account_User\n }\n }\n": typeof types.AccountGetDocument, - "\n mutation CreateAnonymousSession {\n accountCreateAnonymousSession {\n _id\n expire\n current\n }\n }\n": typeof types.CreateAnonymousSessionDocument, - "\n mutation CreateEmailToken($userId: String!, $email: String!, $phrase: Boolean) {\n accountCreateEmailToken(userId: $userId, email: $email, phrase: $phrase) {\n expire\n }\n }\n": typeof types.CreateEmailTokenDocument, - "\n mutation CreateEmailVerification($url: String!) {\n accountCreateEmailVerification(url: $url) {\n _id\n userId\n secret\n expire\n }\n }\n": typeof types.CreateEmailVerificationDocument, - "\n mutation CreateJWT {\n accountCreateJWT {\n jwt\n }\n }\n": typeof types.CreateJwtDocument, - "\n mutation CreateMagicURLToken($userId: String!, $email: String!, $url: String, $phrase: Boolean) {\n accountCreateMagicURLToken(userId: $userId, email: $email, url: $url, phrase: $phrase) {\n expire\n }\n }\n": typeof types.CreateMagicUrlTokenDocument, - "\n mutation CreateMfaAuthenticator($type: String!) {\n accountCreateMfaAuthenticator(type: $type) {\n secret\n uri\n }\n }\n": typeof types.CreateMfaAuthenticatorDocument, - "\n mutation CreateMfaChallenge($factor: String!) {\n accountCreateMfaChallenge(factor: $factor) {\n userId\n expire\n }\n }\n": typeof types.CreateMfaChallengeDocument, - "\n mutation CreateMfaRecoveryCodes {\n accountCreateMfaRecoveryCodes {\n recoveryCodes\n }\n }\n": typeof types.CreateMfaRecoveryCodesDocument, - "\n mutation CreatePhoneToken($userId: String!, $phone: String!) {\n accountCreatePhoneToken(userId: $userId, phone: $phone) {\n expire\n }\n }\n": typeof types.CreatePhoneTokenDocument, - "\n mutation CreatePhoneVerification {\n accountCreatePhoneVerification {\n expire\n }\n }\n": typeof types.CreatePhoneVerificationDocument, - "\n mutation CreatePushTarget($targetId: String!, $identifier: String!, $providerId: String) {\n accountCreatePushTarget(targetId: $targetId, identifier: $identifier, providerId: $providerId) {\n _id\n userId\n providerType\n identifier\n }\n }\n": typeof types.CreatePushTargetDocument, - "\n mutation CreateSession($userId: String!, $secret: String!) {\n accountCreateSession(userId: $userId, secret: $secret) {\n userId\n expire\n current\n }\n }\n": typeof types.CreateSessionDocument, - "\n mutation DeleteAccount {\n accountDelete {\n status\n }\n }\n": typeof types.DeleteAccountDocument, - "\n mutation DeleteIdentity($identityId: String!) {\n accountDeleteIdentity(identityId: $identityId) {\n status\n }\n }\n": typeof types.DeleteIdentityDocument, - "\n mutation DeleteMfaAuthenticator($type: String!) {\n accountDeleteMfaAuthenticator(type: $type) {\n status\n }\n }\n": typeof types.DeleteMfaAuthenticatorDocument, - "\n mutation DeletePushTarget($targetId: String!) {\n accountDeletePushTarget(targetId: $targetId) {\n status\n }\n }\n": typeof types.DeletePushTargetDocument, - "\n mutation DeleteSession($sessionId: String!) {\n accountDeleteSession(sessionId: $sessionId) {\n status\n }\n }\n": typeof types.DeleteSessionDocument, - "\n mutation DeleteSessions {\n accountDeleteSessions {\n status\n }\n }\n": typeof types.DeleteSessionsDocument, - "\n query GetMfaRecoveryCodes {\n accountGetMfaRecoveryCodes {\n recoveryCodes\n }\n }\n": typeof types.GetMfaRecoveryCodesDocument, - "\n query GetPrefs {\n accountGetPrefs {\n data\n }\n }\n": typeof types.GetPrefsDocument, - "\n query GetSession($sessionId: String!) {\n accountGetSession(sessionId: $sessionId) {\n userId\n expire\n current\n }\n }\n": typeof types.GetSessionDocument, - "\n query ListIdentities {\n accountListIdentities {\n total\n identities {\n ...Identity_Provider\n }\n }\n }\n": typeof types.ListIdentitiesDocument, - "\n query ListMfaFactors {\n accountListMfaFactors {\n totp\n phone\n email\n }\n }\n": typeof types.ListMfaFactorsDocument, - "\n query ListSessions {\n accountListSessions {\n sessions {\n _id\n _createdAt\n osName\n clientName\n }\n }\n }\n": typeof types.ListSessionsDocument, - "\n mutation CreateEmailPasswordSession($email: String!, $password: String!) {\n accountCreateEmailPasswordSession(email: $email, password: $password) {\n userId\n expire\n current\n }\n }\n": typeof types.CreateEmailPasswordSessionDocument, - "\n query ListLogs($queries: [String!]) {\n accountListLogs(queries: $queries) {\n total\n logs {\n event\n userId\n userEmail\n userName\n mode\n ip\n time\n osCode\n osName\n osVersion\n clientType\n clientCode\n clientName\n clientVersion\n clientEngine\n clientEngineVersion\n deviceName\n deviceBrand\n deviceModel\n countryCode\n countryName\n }\n }\n }\n": typeof types.ListLogsDocument, - "\n mutation CreateRecovery($email: String!, $url: String!) {\n accountCreateRecovery(email: $email, url: $url) {\n expire\n }\n }\n": typeof types.CreateRecoveryDocument, - "\n mutation UpdateRecovery($userId: String!, $secret: String!, $password: String!) {\n accountUpdateRecovery(userId: $userId, secret: $secret, password: $password) {\n expire\n }\n }\n": typeof types.UpdateRecoveryDocument, - "\n mutation CreateAccount($userId: String!, $name: String, $email: String!, $password: String!) {\n accountCreate(userId: $userId, name: $name, email: $email, password: $password) {\n name\n email\n }\n }\n": typeof types.CreateAccountDocument, - "\n mutation VerifyEmail($url: String!) {\n accountCreateVerification(url: $url) {\n expire\n }\n }\n": typeof types.VerifyEmailDocument, - "\n mutation UpdateEmail($email: String!, $password: String!) {\n accountUpdateEmail(email: $email, password: $password) {\n name\n email\n }\n }\n": typeof types.UpdateEmailDocument, - "\n mutation UpdateEmailVerification($userId: String!, $secret: String!) {\n accountUpdateEmailVerification(userId: $userId, secret: $secret) {\n _id\n userId\n secret\n expire\n }\n }\n": typeof types.UpdateEmailVerificationDocument, - "\n mutation UpdateMagicURLSession($userId: String!, $secret: String!) {\n accountUpdateMagicURLSession(userId: $userId, secret: $secret) {\n userId\n expire\n current\n }\n }\n": typeof types.UpdateMagicUrlSessionDocument, - "\n mutation UpdateMFA($mfa: Boolean!) {\n accountUpdateMFA(mfa: $mfa) {\n mfa\n }\n }\n": typeof types.UpdateMfaDocument, - "\n mutation UpdateMfaAuthenticator($type: String!, $otp: String!) {\n accountUpdateMfaAuthenticator(type: $type, otp: $otp) {\n mfa\n }\n }\n": typeof types.UpdateMfaAuthenticatorDocument, - "\n mutation UpdateMfaChallenge($challengeId: String!, $otp: String!) {\n accountUpdateMfaChallenge(challengeId: $challengeId, otp: $otp) {\n status\n }\n }\n": typeof types.UpdateMfaChallengeDocument, - "\n mutation UpdateMfaRecoveryCodes {\n accountUpdateMfaRecoveryCodes {\n recoveryCodes\n }\n }\n": typeof types.UpdateMfaRecoveryCodesDocument, - "\n mutation UpdateName($name: String!) {\n accountUpdateName(name: $name) {\n name\n }\n }\n": typeof types.UpdateNameDocument, - "\n mutation UpdatePassword($password: String!, $oldPassword: String!) {\n accountUpdatePassword(password: $password, oldPassword: $oldPassword) {\n status\n }\n }\n": typeof types.UpdatePasswordDocument, - "\n mutation UpdatePhone($phone: String!, $password: String!) {\n accountUpdatePhone(phone: $phone, password: $password) {\n phone\n }\n }\n": typeof types.UpdatePhoneDocument, - "\n mutation UpdatePhoneSession($userId: String!, $secret: String!) {\n accountUpdatePhoneSession(userId: $userId, secret: $secret) {\n userId\n expire\n current\n }\n }\n": typeof types.UpdatePhoneSessionDocument, - "\n mutation UpdatePhoneVerification($userId: String!, $secret: String!) {\n accountUpdatePhoneVerification(userId: $userId, secret: $secret) {\n expire\n }\n }\n": typeof types.UpdatePhoneVerificationDocument, - "\n mutation UpdatePrefs($prefs: Assoc!) {\n accountUpdatePrefs(prefs: $prefs) {\n prefs {\n data\n }\n }\n }\n": typeof types.UpdatePrefsDocument, - "\n mutation UpdatePushTarget($targetId: String!, $identifier: String!) {\n accountUpdatePushTarget(targetId: $targetId, identifier: $identifier) {\n _id\n userId\n providerType\n identifier\n }\n }\n": typeof types.UpdatePushTargetDocument, - "\n mutation UpdateSession($sessionId: String!) {\n accountUpdateSession(sessionId: $sessionId) {\n userId\n expire\n current\n }\n }\n": typeof types.UpdateSessionDocument, - "\n mutation UpdateStatus {\n accountUpdateStatus {\n _id\n status\n }\n }\n": typeof types.UpdateStatusDocument, - "\n mutation UpdateVerification($userId: String!, $secret: String!) {\n accountUpdateVerification(userId: $userId, secret: $secret) {\n secret\n expire\n userId\n }\n }\n": typeof types.UpdateVerificationDocument, - "\n query ListDocuments($databaseId: String!, $collectionId: String!, $queries: [String!]) {\n databasesListDocuments(\n databaseId: $databaseId\n collectionId: $collectionId\n queries: $queries\n ) {\n total\n documents {\n _id\n data\n }\n }\n }\n": typeof types.ListDocumentsDocument, - "\n mutation CreateDocument(\n $databaseId: String!\n $collectionId: String!\n $documentId: String!\n $data: Json!\n $permissions: [String!]\n ) {\n databasesCreateDocument(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n data: $data\n permissions: $permissions\n ) {\n _id\n }\n }\n": typeof types.CreateDocumentDocument, - "\n mutation CreateDocuments(\n $databaseId: String!\n $collectionId: String!\n $documents: [Json!]!\n ) {\n databasesCreateDocuments(\n databaseId: $databaseId\n collectionId: $collectionId\n documents: $documents\n ) {\n total\n documents {\n _id\n }\n }\n }\n": typeof types.CreateDocumentsDocument, - "\n mutation CreateOperations($transactionId: String!, $operations: [String!]) {\n databasesCreateOperations(transactionId: $transactionId, operations: $operations) {\n _id\n status\n operations\n expiresAt\n }\n }\n": typeof types.CreateOperationsDocument, - "\n mutation CreateTransaction($ttl: Int) {\n databasesCreateTransaction(ttl: $ttl) {\n _id\n status\n operations\n expiresAt\n }\n }\n": typeof types.CreateTransactionDocument, - "\n mutation DecrementDocumentAttribute(\n $databaseId: String!\n $collectionId: String!\n $documentId: String!\n $attribute: String!\n $value: Int\n $min: Int\n ) {\n databasesDecrementDocumentAttribute(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n attribute: $attribute\n value: $value\n min: $min\n ) {\n _id\n data\n }\n }\n": typeof types.DecrementDocumentAttributeDocument, - "\n mutation DeleteDocument($databaseId: String!, $collectionId: String!, $documentId: String!) {\n databasesDeleteDocument(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n ) {\n status\n }\n }\n": typeof types.DeleteDocumentDocument, - "\n mutation DeleteDocuments(\n $databaseId: String!\n $collectionId: String!\n $queries: [String!]\n ) {\n databasesDeleteDocuments(\n databaseId: $databaseId\n collectionId: $collectionId\n queries: $queries\n ) {\n total\n documents {\n _id\n }\n }\n }\n": typeof types.DeleteDocumentsDocument, - "\n mutation DeleteTransaction($transactionId: String!) {\n databasesDeleteTransaction(transactionId: $transactionId) {\n status\n }\n }\n": typeof types.DeleteTransactionDocument, - "\n query GetDocument($databaseId: String!, $collectionId: String!, $documentId: String!) {\n databasesGetDocument(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n ) {\n _id\n data\n }\n }\n": typeof types.GetDocumentDocument, - "\n query GetTransaction($transactionId: String!) {\n databasesGetTransaction(transactionId: $transactionId) {\n _id\n _createdAt\n _updatedAt\n status\n operations\n expiresAt\n }\n }\n": typeof types.GetTransactionDocument, - "\n mutation IncrementDocumentAttribute(\n $databaseId: String!\n $collectionId: String!\n $documentId: String!\n $attribute: String!\n $value: Int\n $max: Int\n ) {\n databasesIncrementDocumentAttribute(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n attribute: $attribute\n value: $value\n max: $max\n ) {\n _id\n data\n }\n }\n": typeof types.IncrementDocumentAttributeDocument, - "\n query ListTransactions($queries: String) {\n databasesListTransactions(queries: $queries) {\n total\n transactions {\n _id\n _createdAt\n _updatedAt\n status\n operations\n expiresAt\n }\n }\n }\n": typeof types.ListTransactionsDocument, - "\n mutation UpdateDocument(\n $databaseId: String!\n $collectionId: String!\n $documentId: String!\n $data: Json\n $permissions: [String!]\n ) {\n databasesUpdateDocument(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n data: $data\n permissions: $permissions\n ) {\n _id\n }\n }\n": typeof types.UpdateDocumentDocument, - "\n mutation UpdateDocuments(\n $databaseId: String!\n $collectionId: String!\n $data: Json\n $queries: [String!]\n ) {\n databasesUpdateDocuments(\n databaseId: $databaseId\n collectionId: $collectionId\n data: $data\n queries: $queries\n ) {\n total\n documents {\n _id\n }\n }\n }\n": typeof types.UpdateDocumentsDocument, - "\n mutation UpdateTransaction($transactionId: String!, $commit: Boolean, $rollback: Boolean) {\n databasesUpdateTransaction(\n transactionId: $transactionId\n commit: $commit\n rollback: $rollback\n ) {\n _id\n status\n operations\n }\n }\n": typeof types.UpdateTransactionDocument, - "\n mutation UpsertDocument(\n $databaseId: String!\n $collectionId: String!\n $documentId: String!\n $data: Json!\n $permissions: [String!]\n ) {\n databasesUpsertDocument(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n data: $data\n permissions: $permissions\n ) {\n _id\n }\n }\n": typeof types.UpsertDocumentDocument, - "\n mutation UpsertDocuments(\n $databaseId: String!\n $collectionId: String!\n $documents: [Json!]!\n ) {\n databasesUpsertDocuments(\n databaseId: $databaseId\n collectionId: $collectionId\n documents: $documents\n ) {\n total\n documents {\n _id\n }\n }\n }\n": typeof types.UpsertDocumentsDocument, - "\n mutation CreateExecution(\n $functionId: String!\n $body: String\n $async: Boolean\n $path: String\n $method: String # $headers: Json\n ) {\n functionsCreateExecution(\n functionId: $functionId\n body: $body\n async: $async\n path: $path\n method: $method # headers: $headers\n ) {\n _id\n status\n responseStatusCode\n responseBody\n errors\n duration\n }\n }\n": typeof types.CreateExecutionDocument, - "\n query GetFunctionExecution($functionId: String!, $executionId: String!) {\n functionsGetExecution(functionId: $functionId, executionId: $executionId) {\n status\n errors\n duration\n responseBody\n requestPath\n }\n }\n": typeof types.GetFunctionExecutionDocument, - "\n query GetExecution($functionId: String!, $executionId: String!) {\n functionsGetExecution(functionId: $functionId, executionId: $executionId) {\n _id\n _createdAt\n _updatedAt\n functionId\n trigger\n status\n requestMethod\n requestPath\n responseStatusCode\n responseBody\n errors\n duration\n }\n }\n": typeof types.GetExecutionDocument, - "\n query ListExecutions($functionId: String!, $queries: [String!]) {\n functionsListExecutions(functionId: $functionId, queries: $queries) {\n total\n executions {\n _id\n _createdAt\n _updatedAt\n functionId\n trigger\n status\n requestMethod\n requestPath\n responseStatusCode\n responseBody\n errors\n duration\n }\n }\n }\n": typeof types.ListExecutionsDocument, - "\n query GetLocale {\n localeGet {\n ip\n countryCode\n country\n continentCode\n continent\n eu\n currency\n }\n }\n": typeof types.GetLocaleDocument, - "\n query ListLocaleCodes {\n localeListCodes {\n total\n localeCodes {\n code\n name\n }\n }\n }\n": typeof types.ListLocaleCodesDocument, - "\n query ListContinents {\n localeListContinents {\n total\n continents {\n name\n code\n }\n }\n }\n": typeof types.ListContinentsDocument, - "\n query ListCountries {\n localeListCountries {\n total\n countries {\n name\n code\n }\n }\n }\n": typeof types.ListCountriesDocument, - "\n query ListCountriesEU {\n localeListCountriesEU {\n total\n countries {\n name\n code\n }\n }\n }\n": typeof types.ListCountriesEuDocument, - "\n query ListCountriesPhones {\n localeListCountriesPhones {\n total\n phones {\n code\n countryCode\n countryName\n }\n }\n }\n": typeof types.ListCountriesPhonesDocument, - "\n query ListCurrencies {\n localeListCurrencies {\n total\n currencies {\n symbol\n name\n symbolNative\n decimalDigits\n rounding\n code\n namePlural\n }\n }\n }\n": typeof types.ListCurrenciesDocument, - "\n query ListLanguages {\n localeListLanguages {\n total\n languages {\n name\n code\n nativeName\n }\n }\n }\n": typeof types.ListLanguagesDocument, - "\n mutation CreateFile(\n $bucketId: String!\n $fileId: String!\n $file: String!\n $permissions: [String!]\n ) {\n storageCreateFile(\n bucketId: $bucketId\n fileId: $fileId\n file: $file\n permissions: $permissions\n ) {\n _id\n bucketId\n name\n mimeType\n sizeOriginal\n }\n }\n": typeof types.CreateFileDocument, - "\n mutation DeleteFile($bucketId: String!, $fileId: String!) {\n storageDeleteFile(bucketId: $bucketId, fileId: $fileId) {\n status\n }\n }\n": typeof types.DeleteFileDocument, - "\n query GetFile($bucketId: String!, $fileId: String!) {\n storageGetFile(bucketId: $bucketId, fileId: $fileId) {\n _id\n bucketId\n _createdAt\n _updatedAt\n _permissions\n name\n signature\n mimeType\n sizeOriginal\n chunksTotal\n chunksUploaded\n }\n }\n": typeof types.GetFileDocument, - "\n query ListFiles($bucketId: String!, $queries: [String!], $search: String) {\n storageListFiles(bucketId: $bucketId, queries: $queries, search: $search) {\n total\n files {\n _id\n bucketId\n _createdAt\n _updatedAt\n _permissions\n name\n signature\n mimeType\n sizeOriginal\n chunksTotal\n chunksUploaded\n }\n }\n }\n": typeof types.ListFilesDocument, - "\n mutation UpdateFile(\n $bucketId: String!\n $fileId: String!\n $name: String\n $permissions: [String!]\n ) {\n storageUpdateFile(\n bucketId: $bucketId\n fileId: $fileId\n name: $name\n permissions: $permissions\n ) {\n _id\n bucketId\n name\n _permissions\n }\n }\n": typeof types.UpdateFileDocument, - "\n mutation CreateMembership(\n $teamId: String!\n $roles: [String!]!\n $email: String\n $userId: String\n $phone: String\n $url: String\n $name: String\n ) {\n teamsCreateMembership(\n teamId: $teamId\n roles: $roles\n email: $email\n userId: $userId\n phone: $phone\n url: $url\n name: $name\n ) {\n _id\n userId\n teamId\n roles\n confirm\n }\n }\n": typeof types.CreateMembershipDocument, - "\n mutation CreateTeam($teamId: String!, $name: String!, $roles: [String!]) {\n teamsCreate(teamId: $teamId, name: $name, roles: $roles) {\n _id\n name\n total\n }\n }\n": typeof types.CreateTeamDocument, - "\n mutation DeleteMembership($teamId: String!, $membershipId: String!) {\n teamsDeleteMembership(teamId: $teamId, membershipId: $membershipId) {\n status\n }\n }\n": typeof types.DeleteMembershipDocument, - "\n mutation DeleteTeam($teamId: String!) {\n teamsDelete(teamId: $teamId) {\n status\n }\n }\n": typeof types.DeleteTeamDocument, - "\n query GetTeam($teamId: String!) {\n teamsGet(teamId: $teamId) {\n _id\n _createdAt\n _updatedAt\n name\n total\n prefs {\n data\n }\n }\n }\n": typeof types.GetTeamDocument, - "\n query GetMembership($teamId: String!, $membershipId: String!) {\n teamsGetMembership(teamId: $teamId, membershipId: $membershipId) {\n _id\n _createdAt\n _updatedAt\n userId\n userName\n userEmail\n teamId\n teamName\n invited\n joined\n confirm\n mfa\n roles\n }\n }\n": typeof types.GetMembershipDocument, - "\n query ListMemberships($teamId: String!, $queries: [String!], $search: String) {\n teamsListMemberships(teamId: $teamId, queries: $queries, search: $search) {\n total\n memberships {\n _id\n _createdAt\n _updatedAt\n userId\n userName\n userEmail\n teamId\n teamName\n invited\n joined\n confirm\n mfa\n roles\n }\n }\n }\n": typeof types.ListMembershipsDocument, - "\n query GetTeamPrefs($teamId: String!) {\n teamsGetPrefs(teamId: $teamId) {\n data\n }\n }\n": typeof types.GetTeamPrefsDocument, - "\n query ListTeams($queries: [String!], $search: String) {\n teamsList(queries: $queries, search: $search) {\n total\n teams {\n _id\n _createdAt\n _updatedAt\n name\n total\n prefs {\n data\n }\n }\n }\n }\n": typeof types.ListTeamsDocument, - "\n mutation UpdateMembership($teamId: String!, $membershipId: String!, $roles: [String!]!) {\n teamsUpdateMembership(teamId: $teamId, membershipId: $membershipId, roles: $roles) {\n _id\n roles\n }\n }\n": typeof types.UpdateMembershipDocument, - "\n mutation UpdateMembershipStatus(\n $teamId: String!\n $membershipId: String!\n $userId: String!\n $secret: String!\n ) {\n teamsUpdateMembershipStatus(\n teamId: $teamId\n membershipId: $membershipId\n userId: $userId\n secret: $secret\n ) {\n _id\n confirm\n }\n }\n": typeof types.UpdateMembershipStatusDocument, - "\n mutation UpdateTeamName($teamId: String!, $name: String!) {\n teamsUpdateName(teamId: $teamId, name: $name) {\n _id\n name\n }\n }\n": typeof types.UpdateTeamNameDocument, - "\n mutation UpdateTeamPrefs($teamId: String!, $prefs: Assoc!) {\n teamsUpdatePrefs(teamId: $teamId, prefs: $prefs) {\n data\n }\n }\n": typeof types.UpdateTeamPrefsDocument, -}; -const documents: Documents = { - "\n fragment Account_User on User {\n _id\n name\n email\n prefs {\n data\n }\n }\n": types.Account_UserFragmentDoc, - "\n fragment Identity_Provider on Identity {\n _id\n userId\n provider\n }\n": types.Identity_ProviderFragmentDoc, - "\n query AccountGet {\n accountGet {\n ...Account_User\n }\n }\n": types.AccountGetDocument, - "\n mutation CreateAnonymousSession {\n accountCreateAnonymousSession {\n _id\n expire\n current\n }\n }\n": types.CreateAnonymousSessionDocument, - "\n mutation CreateEmailToken($userId: String!, $email: String!, $phrase: Boolean) {\n accountCreateEmailToken(userId: $userId, email: $email, phrase: $phrase) {\n expire\n }\n }\n": types.CreateEmailTokenDocument, - "\n mutation CreateEmailVerification($url: String!) {\n accountCreateEmailVerification(url: $url) {\n _id\n userId\n secret\n expire\n }\n }\n": types.CreateEmailVerificationDocument, - "\n mutation CreateJWT {\n accountCreateJWT {\n jwt\n }\n }\n": types.CreateJwtDocument, - "\n mutation CreateMagicURLToken($userId: String!, $email: String!, $url: String, $phrase: Boolean) {\n accountCreateMagicURLToken(userId: $userId, email: $email, url: $url, phrase: $phrase) {\n expire\n }\n }\n": types.CreateMagicUrlTokenDocument, - "\n mutation CreateMfaAuthenticator($type: String!) {\n accountCreateMfaAuthenticator(type: $type) {\n secret\n uri\n }\n }\n": types.CreateMfaAuthenticatorDocument, - "\n mutation CreateMfaChallenge($factor: String!) {\n accountCreateMfaChallenge(factor: $factor) {\n userId\n expire\n }\n }\n": types.CreateMfaChallengeDocument, - "\n mutation CreateMfaRecoveryCodes {\n accountCreateMfaRecoveryCodes {\n recoveryCodes\n }\n }\n": types.CreateMfaRecoveryCodesDocument, - "\n mutation CreatePhoneToken($userId: String!, $phone: String!) {\n accountCreatePhoneToken(userId: $userId, phone: $phone) {\n expire\n }\n }\n": types.CreatePhoneTokenDocument, - "\n mutation CreatePhoneVerification {\n accountCreatePhoneVerification {\n expire\n }\n }\n": types.CreatePhoneVerificationDocument, - "\n mutation CreatePushTarget($targetId: String!, $identifier: String!, $providerId: String) {\n accountCreatePushTarget(targetId: $targetId, identifier: $identifier, providerId: $providerId) {\n _id\n userId\n providerType\n identifier\n }\n }\n": types.CreatePushTargetDocument, - "\n mutation CreateSession($userId: String!, $secret: String!) {\n accountCreateSession(userId: $userId, secret: $secret) {\n userId\n expire\n current\n }\n }\n": types.CreateSessionDocument, - "\n mutation DeleteAccount {\n accountDelete {\n status\n }\n }\n": types.DeleteAccountDocument, - "\n mutation DeleteIdentity($identityId: String!) {\n accountDeleteIdentity(identityId: $identityId) {\n status\n }\n }\n": types.DeleteIdentityDocument, - "\n mutation DeleteMfaAuthenticator($type: String!) {\n accountDeleteMfaAuthenticator(type: $type) {\n status\n }\n }\n": types.DeleteMfaAuthenticatorDocument, - "\n mutation DeletePushTarget($targetId: String!) {\n accountDeletePushTarget(targetId: $targetId) {\n status\n }\n }\n": types.DeletePushTargetDocument, - "\n mutation DeleteSession($sessionId: String!) {\n accountDeleteSession(sessionId: $sessionId) {\n status\n }\n }\n": types.DeleteSessionDocument, - "\n mutation DeleteSessions {\n accountDeleteSessions {\n status\n }\n }\n": types.DeleteSessionsDocument, - "\n query GetMfaRecoveryCodes {\n accountGetMfaRecoveryCodes {\n recoveryCodes\n }\n }\n": types.GetMfaRecoveryCodesDocument, - "\n query GetPrefs {\n accountGetPrefs {\n data\n }\n }\n": types.GetPrefsDocument, - "\n query GetSession($sessionId: String!) {\n accountGetSession(sessionId: $sessionId) {\n userId\n expire\n current\n }\n }\n": types.GetSessionDocument, - "\n query ListIdentities {\n accountListIdentities {\n total\n identities {\n ...Identity_Provider\n }\n }\n }\n": types.ListIdentitiesDocument, - "\n query ListMfaFactors {\n accountListMfaFactors {\n totp\n phone\n email\n }\n }\n": types.ListMfaFactorsDocument, - "\n query ListSessions {\n accountListSessions {\n sessions {\n _id\n _createdAt\n osName\n clientName\n }\n }\n }\n": types.ListSessionsDocument, - "\n mutation CreateEmailPasswordSession($email: String!, $password: String!) {\n accountCreateEmailPasswordSession(email: $email, password: $password) {\n userId\n expire\n current\n }\n }\n": types.CreateEmailPasswordSessionDocument, - "\n query ListLogs($queries: [String!]) {\n accountListLogs(queries: $queries) {\n total\n logs {\n event\n userId\n userEmail\n userName\n mode\n ip\n time\n osCode\n osName\n osVersion\n clientType\n clientCode\n clientName\n clientVersion\n clientEngine\n clientEngineVersion\n deviceName\n deviceBrand\n deviceModel\n countryCode\n countryName\n }\n }\n }\n": types.ListLogsDocument, - "\n mutation CreateRecovery($email: String!, $url: String!) {\n accountCreateRecovery(email: $email, url: $url) {\n expire\n }\n }\n": types.CreateRecoveryDocument, - "\n mutation UpdateRecovery($userId: String!, $secret: String!, $password: String!) {\n accountUpdateRecovery(userId: $userId, secret: $secret, password: $password) {\n expire\n }\n }\n": types.UpdateRecoveryDocument, - "\n mutation CreateAccount($userId: String!, $name: String, $email: String!, $password: String!) {\n accountCreate(userId: $userId, name: $name, email: $email, password: $password) {\n name\n email\n }\n }\n": types.CreateAccountDocument, - "\n mutation VerifyEmail($url: String!) {\n accountCreateVerification(url: $url) {\n expire\n }\n }\n": types.VerifyEmailDocument, - "\n mutation UpdateEmail($email: String!, $password: String!) {\n accountUpdateEmail(email: $email, password: $password) {\n name\n email\n }\n }\n": types.UpdateEmailDocument, - "\n mutation UpdateEmailVerification($userId: String!, $secret: String!) {\n accountUpdateEmailVerification(userId: $userId, secret: $secret) {\n _id\n userId\n secret\n expire\n }\n }\n": types.UpdateEmailVerificationDocument, - "\n mutation UpdateMagicURLSession($userId: String!, $secret: String!) {\n accountUpdateMagicURLSession(userId: $userId, secret: $secret) {\n userId\n expire\n current\n }\n }\n": types.UpdateMagicUrlSessionDocument, - "\n mutation UpdateMFA($mfa: Boolean!) {\n accountUpdateMFA(mfa: $mfa) {\n mfa\n }\n }\n": types.UpdateMfaDocument, - "\n mutation UpdateMfaAuthenticator($type: String!, $otp: String!) {\n accountUpdateMfaAuthenticator(type: $type, otp: $otp) {\n mfa\n }\n }\n": types.UpdateMfaAuthenticatorDocument, - "\n mutation UpdateMfaChallenge($challengeId: String!, $otp: String!) {\n accountUpdateMfaChallenge(challengeId: $challengeId, otp: $otp) {\n status\n }\n }\n": types.UpdateMfaChallengeDocument, - "\n mutation UpdateMfaRecoveryCodes {\n accountUpdateMfaRecoveryCodes {\n recoveryCodes\n }\n }\n": types.UpdateMfaRecoveryCodesDocument, - "\n mutation UpdateName($name: String!) {\n accountUpdateName(name: $name) {\n name\n }\n }\n": types.UpdateNameDocument, - "\n mutation UpdatePassword($password: String!, $oldPassword: String!) {\n accountUpdatePassword(password: $password, oldPassword: $oldPassword) {\n status\n }\n }\n": types.UpdatePasswordDocument, - "\n mutation UpdatePhone($phone: String!, $password: String!) {\n accountUpdatePhone(phone: $phone, password: $password) {\n phone\n }\n }\n": types.UpdatePhoneDocument, - "\n mutation UpdatePhoneSession($userId: String!, $secret: String!) {\n accountUpdatePhoneSession(userId: $userId, secret: $secret) {\n userId\n expire\n current\n }\n }\n": types.UpdatePhoneSessionDocument, - "\n mutation UpdatePhoneVerification($userId: String!, $secret: String!) {\n accountUpdatePhoneVerification(userId: $userId, secret: $secret) {\n expire\n }\n }\n": types.UpdatePhoneVerificationDocument, - "\n mutation UpdatePrefs($prefs: Assoc!) {\n accountUpdatePrefs(prefs: $prefs) {\n prefs {\n data\n }\n }\n }\n": types.UpdatePrefsDocument, - "\n mutation UpdatePushTarget($targetId: String!, $identifier: String!) {\n accountUpdatePushTarget(targetId: $targetId, identifier: $identifier) {\n _id\n userId\n providerType\n identifier\n }\n }\n": types.UpdatePushTargetDocument, - "\n mutation UpdateSession($sessionId: String!) {\n accountUpdateSession(sessionId: $sessionId) {\n userId\n expire\n current\n }\n }\n": types.UpdateSessionDocument, - "\n mutation UpdateStatus {\n accountUpdateStatus {\n _id\n status\n }\n }\n": types.UpdateStatusDocument, - "\n mutation UpdateVerification($userId: String!, $secret: String!) {\n accountUpdateVerification(userId: $userId, secret: $secret) {\n secret\n expire\n userId\n }\n }\n": types.UpdateVerificationDocument, - "\n query ListDocuments($databaseId: String!, $collectionId: String!, $queries: [String!]) {\n databasesListDocuments(\n databaseId: $databaseId\n collectionId: $collectionId\n queries: $queries\n ) {\n total\n documents {\n _id\n data\n }\n }\n }\n": types.ListDocumentsDocument, - "\n mutation CreateDocument(\n $databaseId: String!\n $collectionId: String!\n $documentId: String!\n $data: Json!\n $permissions: [String!]\n ) {\n databasesCreateDocument(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n data: $data\n permissions: $permissions\n ) {\n _id\n }\n }\n": types.CreateDocumentDocument, - "\n mutation CreateDocuments(\n $databaseId: String!\n $collectionId: String!\n $documents: [Json!]!\n ) {\n databasesCreateDocuments(\n databaseId: $databaseId\n collectionId: $collectionId\n documents: $documents\n ) {\n total\n documents {\n _id\n }\n }\n }\n": types.CreateDocumentsDocument, - "\n mutation CreateOperations($transactionId: String!, $operations: [String!]) {\n databasesCreateOperations(transactionId: $transactionId, operations: $operations) {\n _id\n status\n operations\n expiresAt\n }\n }\n": types.CreateOperationsDocument, - "\n mutation CreateTransaction($ttl: Int) {\n databasesCreateTransaction(ttl: $ttl) {\n _id\n status\n operations\n expiresAt\n }\n }\n": types.CreateTransactionDocument, - "\n mutation DecrementDocumentAttribute(\n $databaseId: String!\n $collectionId: String!\n $documentId: String!\n $attribute: String!\n $value: Int\n $min: Int\n ) {\n databasesDecrementDocumentAttribute(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n attribute: $attribute\n value: $value\n min: $min\n ) {\n _id\n data\n }\n }\n": types.DecrementDocumentAttributeDocument, - "\n mutation DeleteDocument($databaseId: String!, $collectionId: String!, $documentId: String!) {\n databasesDeleteDocument(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n ) {\n status\n }\n }\n": types.DeleteDocumentDocument, - "\n mutation DeleteDocuments(\n $databaseId: String!\n $collectionId: String!\n $queries: [String!]\n ) {\n databasesDeleteDocuments(\n databaseId: $databaseId\n collectionId: $collectionId\n queries: $queries\n ) {\n total\n documents {\n _id\n }\n }\n }\n": types.DeleteDocumentsDocument, - "\n mutation DeleteTransaction($transactionId: String!) {\n databasesDeleteTransaction(transactionId: $transactionId) {\n status\n }\n }\n": types.DeleteTransactionDocument, - "\n query GetDocument($databaseId: String!, $collectionId: String!, $documentId: String!) {\n databasesGetDocument(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n ) {\n _id\n data\n }\n }\n": types.GetDocumentDocument, - "\n query GetTransaction($transactionId: String!) {\n databasesGetTransaction(transactionId: $transactionId) {\n _id\n _createdAt\n _updatedAt\n status\n operations\n expiresAt\n }\n }\n": types.GetTransactionDocument, - "\n mutation IncrementDocumentAttribute(\n $databaseId: String!\n $collectionId: String!\n $documentId: String!\n $attribute: String!\n $value: Int\n $max: Int\n ) {\n databasesIncrementDocumentAttribute(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n attribute: $attribute\n value: $value\n max: $max\n ) {\n _id\n data\n }\n }\n": types.IncrementDocumentAttributeDocument, - "\n query ListTransactions($queries: String) {\n databasesListTransactions(queries: $queries) {\n total\n transactions {\n _id\n _createdAt\n _updatedAt\n status\n operations\n expiresAt\n }\n }\n }\n": types.ListTransactionsDocument, - "\n mutation UpdateDocument(\n $databaseId: String!\n $collectionId: String!\n $documentId: String!\n $data: Json\n $permissions: [String!]\n ) {\n databasesUpdateDocument(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n data: $data\n permissions: $permissions\n ) {\n _id\n }\n }\n": types.UpdateDocumentDocument, - "\n mutation UpdateDocuments(\n $databaseId: String!\n $collectionId: String!\n $data: Json\n $queries: [String!]\n ) {\n databasesUpdateDocuments(\n databaseId: $databaseId\n collectionId: $collectionId\n data: $data\n queries: $queries\n ) {\n total\n documents {\n _id\n }\n }\n }\n": types.UpdateDocumentsDocument, - "\n mutation UpdateTransaction($transactionId: String!, $commit: Boolean, $rollback: Boolean) {\n databasesUpdateTransaction(\n transactionId: $transactionId\n commit: $commit\n rollback: $rollback\n ) {\n _id\n status\n operations\n }\n }\n": types.UpdateTransactionDocument, - "\n mutation UpsertDocument(\n $databaseId: String!\n $collectionId: String!\n $documentId: String!\n $data: Json!\n $permissions: [String!]\n ) {\n databasesUpsertDocument(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n data: $data\n permissions: $permissions\n ) {\n _id\n }\n }\n": types.UpsertDocumentDocument, - "\n mutation UpsertDocuments(\n $databaseId: String!\n $collectionId: String!\n $documents: [Json!]!\n ) {\n databasesUpsertDocuments(\n databaseId: $databaseId\n collectionId: $collectionId\n documents: $documents\n ) {\n total\n documents {\n _id\n }\n }\n }\n": types.UpsertDocumentsDocument, - "\n mutation CreateExecution(\n $functionId: String!\n $body: String\n $async: Boolean\n $path: String\n $method: String # $headers: Json\n ) {\n functionsCreateExecution(\n functionId: $functionId\n body: $body\n async: $async\n path: $path\n method: $method # headers: $headers\n ) {\n _id\n status\n responseStatusCode\n responseBody\n errors\n duration\n }\n }\n": types.CreateExecutionDocument, - "\n query GetFunctionExecution($functionId: String!, $executionId: String!) {\n functionsGetExecution(functionId: $functionId, executionId: $executionId) {\n status\n errors\n duration\n responseBody\n requestPath\n }\n }\n": types.GetFunctionExecutionDocument, - "\n query GetExecution($functionId: String!, $executionId: String!) {\n functionsGetExecution(functionId: $functionId, executionId: $executionId) {\n _id\n _createdAt\n _updatedAt\n functionId\n trigger\n status\n requestMethod\n requestPath\n responseStatusCode\n responseBody\n errors\n duration\n }\n }\n": types.GetExecutionDocument, - "\n query ListExecutions($functionId: String!, $queries: [String!]) {\n functionsListExecutions(functionId: $functionId, queries: $queries) {\n total\n executions {\n _id\n _createdAt\n _updatedAt\n functionId\n trigger\n status\n requestMethod\n requestPath\n responseStatusCode\n responseBody\n errors\n duration\n }\n }\n }\n": types.ListExecutionsDocument, - "\n query GetLocale {\n localeGet {\n ip\n countryCode\n country\n continentCode\n continent\n eu\n currency\n }\n }\n": types.GetLocaleDocument, - "\n query ListLocaleCodes {\n localeListCodes {\n total\n localeCodes {\n code\n name\n }\n }\n }\n": types.ListLocaleCodesDocument, - "\n query ListContinents {\n localeListContinents {\n total\n continents {\n name\n code\n }\n }\n }\n": types.ListContinentsDocument, - "\n query ListCountries {\n localeListCountries {\n total\n countries {\n name\n code\n }\n }\n }\n": types.ListCountriesDocument, - "\n query ListCountriesEU {\n localeListCountriesEU {\n total\n countries {\n name\n code\n }\n }\n }\n": types.ListCountriesEuDocument, - "\n query ListCountriesPhones {\n localeListCountriesPhones {\n total\n phones {\n code\n countryCode\n countryName\n }\n }\n }\n": types.ListCountriesPhonesDocument, - "\n query ListCurrencies {\n localeListCurrencies {\n total\n currencies {\n symbol\n name\n symbolNative\n decimalDigits\n rounding\n code\n namePlural\n }\n }\n }\n": types.ListCurrenciesDocument, - "\n query ListLanguages {\n localeListLanguages {\n total\n languages {\n name\n code\n nativeName\n }\n }\n }\n": types.ListLanguagesDocument, - "\n mutation CreateFile(\n $bucketId: String!\n $fileId: String!\n $file: String!\n $permissions: [String!]\n ) {\n storageCreateFile(\n bucketId: $bucketId\n fileId: $fileId\n file: $file\n permissions: $permissions\n ) {\n _id\n bucketId\n name\n mimeType\n sizeOriginal\n }\n }\n": types.CreateFileDocument, - "\n mutation DeleteFile($bucketId: String!, $fileId: String!) {\n storageDeleteFile(bucketId: $bucketId, fileId: $fileId) {\n status\n }\n }\n": types.DeleteFileDocument, - "\n query GetFile($bucketId: String!, $fileId: String!) {\n storageGetFile(bucketId: $bucketId, fileId: $fileId) {\n _id\n bucketId\n _createdAt\n _updatedAt\n _permissions\n name\n signature\n mimeType\n sizeOriginal\n chunksTotal\n chunksUploaded\n }\n }\n": types.GetFileDocument, - "\n query ListFiles($bucketId: String!, $queries: [String!], $search: String) {\n storageListFiles(bucketId: $bucketId, queries: $queries, search: $search) {\n total\n files {\n _id\n bucketId\n _createdAt\n _updatedAt\n _permissions\n name\n signature\n mimeType\n sizeOriginal\n chunksTotal\n chunksUploaded\n }\n }\n }\n": types.ListFilesDocument, - "\n mutation UpdateFile(\n $bucketId: String!\n $fileId: String!\n $name: String\n $permissions: [String!]\n ) {\n storageUpdateFile(\n bucketId: $bucketId\n fileId: $fileId\n name: $name\n permissions: $permissions\n ) {\n _id\n bucketId\n name\n _permissions\n }\n }\n": types.UpdateFileDocument, - "\n mutation CreateMembership(\n $teamId: String!\n $roles: [String!]!\n $email: String\n $userId: String\n $phone: String\n $url: String\n $name: String\n ) {\n teamsCreateMembership(\n teamId: $teamId\n roles: $roles\n email: $email\n userId: $userId\n phone: $phone\n url: $url\n name: $name\n ) {\n _id\n userId\n teamId\n roles\n confirm\n }\n }\n": types.CreateMembershipDocument, - "\n mutation CreateTeam($teamId: String!, $name: String!, $roles: [String!]) {\n teamsCreate(teamId: $teamId, name: $name, roles: $roles) {\n _id\n name\n total\n }\n }\n": types.CreateTeamDocument, - "\n mutation DeleteMembership($teamId: String!, $membershipId: String!) {\n teamsDeleteMembership(teamId: $teamId, membershipId: $membershipId) {\n status\n }\n }\n": types.DeleteMembershipDocument, - "\n mutation DeleteTeam($teamId: String!) {\n teamsDelete(teamId: $teamId) {\n status\n }\n }\n": types.DeleteTeamDocument, - "\n query GetTeam($teamId: String!) {\n teamsGet(teamId: $teamId) {\n _id\n _createdAt\n _updatedAt\n name\n total\n prefs {\n data\n }\n }\n }\n": types.GetTeamDocument, - "\n query GetMembership($teamId: String!, $membershipId: String!) {\n teamsGetMembership(teamId: $teamId, membershipId: $membershipId) {\n _id\n _createdAt\n _updatedAt\n userId\n userName\n userEmail\n teamId\n teamName\n invited\n joined\n confirm\n mfa\n roles\n }\n }\n": types.GetMembershipDocument, - "\n query ListMemberships($teamId: String!, $queries: [String!], $search: String) {\n teamsListMemberships(teamId: $teamId, queries: $queries, search: $search) {\n total\n memberships {\n _id\n _createdAt\n _updatedAt\n userId\n userName\n userEmail\n teamId\n teamName\n invited\n joined\n confirm\n mfa\n roles\n }\n }\n }\n": types.ListMembershipsDocument, - "\n query GetTeamPrefs($teamId: String!) {\n teamsGetPrefs(teamId: $teamId) {\n data\n }\n }\n": types.GetTeamPrefsDocument, - "\n query ListTeams($queries: [String!], $search: String) {\n teamsList(queries: $queries, search: $search) {\n total\n teams {\n _id\n _createdAt\n _updatedAt\n name\n total\n prefs {\n data\n }\n }\n }\n }\n": types.ListTeamsDocument, - "\n mutation UpdateMembership($teamId: String!, $membershipId: String!, $roles: [String!]!) {\n teamsUpdateMembership(teamId: $teamId, membershipId: $membershipId, roles: $roles) {\n _id\n roles\n }\n }\n": types.UpdateMembershipDocument, - "\n mutation UpdateMembershipStatus(\n $teamId: String!\n $membershipId: String!\n $userId: String!\n $secret: String!\n ) {\n teamsUpdateMembershipStatus(\n teamId: $teamId\n membershipId: $membershipId\n userId: $userId\n secret: $secret\n ) {\n _id\n confirm\n }\n }\n": types.UpdateMembershipStatusDocument, - "\n mutation UpdateTeamName($teamId: String!, $name: String!) {\n teamsUpdateName(teamId: $teamId, name: $name) {\n _id\n name\n }\n }\n": types.UpdateTeamNameDocument, - "\n mutation UpdateTeamPrefs($teamId: String!, $prefs: Assoc!) {\n teamsUpdatePrefs(teamId: $teamId, prefs: $prefs) {\n data\n }\n }\n": types.UpdateTeamPrefsDocument, -}; - -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - * - * - * @example - * ```ts - * const query = gql(`query GetUser($id: ID!) { user(id: $id) { name } }`); - * ``` - * - * The query argument is unknown! - * Please regenerate the types. - */ -export function gql(source: string): unknown; - -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n fragment Account_User on User {\n _id\n name\n email\n prefs {\n data\n }\n }\n"): (typeof documents)["\n fragment Account_User on User {\n _id\n name\n email\n prefs {\n data\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n fragment Identity_Provider on Identity {\n _id\n userId\n provider\n }\n"): (typeof documents)["\n fragment Identity_Provider on Identity {\n _id\n userId\n provider\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query AccountGet {\n accountGet {\n ...Account_User\n }\n }\n"): (typeof documents)["\n query AccountGet {\n accountGet {\n ...Account_User\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation CreateAnonymousSession {\n accountCreateAnonymousSession {\n _id\n expire\n current\n }\n }\n"): (typeof documents)["\n mutation CreateAnonymousSession {\n accountCreateAnonymousSession {\n _id\n expire\n current\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation CreateEmailToken($userId: String!, $email: String!, $phrase: Boolean) {\n accountCreateEmailToken(userId: $userId, email: $email, phrase: $phrase) {\n expire\n }\n }\n"): (typeof documents)["\n mutation CreateEmailToken($userId: String!, $email: String!, $phrase: Boolean) {\n accountCreateEmailToken(userId: $userId, email: $email, phrase: $phrase) {\n expire\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation CreateEmailVerification($url: String!) {\n accountCreateEmailVerification(url: $url) {\n _id\n userId\n secret\n expire\n }\n }\n"): (typeof documents)["\n mutation CreateEmailVerification($url: String!) {\n accountCreateEmailVerification(url: $url) {\n _id\n userId\n secret\n expire\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation CreateJWT {\n accountCreateJWT {\n jwt\n }\n }\n"): (typeof documents)["\n mutation CreateJWT {\n accountCreateJWT {\n jwt\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation CreateMagicURLToken($userId: String!, $email: String!, $url: String, $phrase: Boolean) {\n accountCreateMagicURLToken(userId: $userId, email: $email, url: $url, phrase: $phrase) {\n expire\n }\n }\n"): (typeof documents)["\n mutation CreateMagicURLToken($userId: String!, $email: String!, $url: String, $phrase: Boolean) {\n accountCreateMagicURLToken(userId: $userId, email: $email, url: $url, phrase: $phrase) {\n expire\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation CreateMfaAuthenticator($type: String!) {\n accountCreateMfaAuthenticator(type: $type) {\n secret\n uri\n }\n }\n"): (typeof documents)["\n mutation CreateMfaAuthenticator($type: String!) {\n accountCreateMfaAuthenticator(type: $type) {\n secret\n uri\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation CreateMfaChallenge($factor: String!) {\n accountCreateMfaChallenge(factor: $factor) {\n userId\n expire\n }\n }\n"): (typeof documents)["\n mutation CreateMfaChallenge($factor: String!) {\n accountCreateMfaChallenge(factor: $factor) {\n userId\n expire\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation CreateMfaRecoveryCodes {\n accountCreateMfaRecoveryCodes {\n recoveryCodes\n }\n }\n"): (typeof documents)["\n mutation CreateMfaRecoveryCodes {\n accountCreateMfaRecoveryCodes {\n recoveryCodes\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation CreatePhoneToken($userId: String!, $phone: String!) {\n accountCreatePhoneToken(userId: $userId, phone: $phone) {\n expire\n }\n }\n"): (typeof documents)["\n mutation CreatePhoneToken($userId: String!, $phone: String!) {\n accountCreatePhoneToken(userId: $userId, phone: $phone) {\n expire\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation CreatePhoneVerification {\n accountCreatePhoneVerification {\n expire\n }\n }\n"): (typeof documents)["\n mutation CreatePhoneVerification {\n accountCreatePhoneVerification {\n expire\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation CreatePushTarget($targetId: String!, $identifier: String!, $providerId: String) {\n accountCreatePushTarget(targetId: $targetId, identifier: $identifier, providerId: $providerId) {\n _id\n userId\n providerType\n identifier\n }\n }\n"): (typeof documents)["\n mutation CreatePushTarget($targetId: String!, $identifier: String!, $providerId: String) {\n accountCreatePushTarget(targetId: $targetId, identifier: $identifier, providerId: $providerId) {\n _id\n userId\n providerType\n identifier\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation CreateSession($userId: String!, $secret: String!) {\n accountCreateSession(userId: $userId, secret: $secret) {\n userId\n expire\n current\n }\n }\n"): (typeof documents)["\n mutation CreateSession($userId: String!, $secret: String!) {\n accountCreateSession(userId: $userId, secret: $secret) {\n userId\n expire\n current\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation DeleteAccount {\n accountDelete {\n status\n }\n }\n"): (typeof documents)["\n mutation DeleteAccount {\n accountDelete {\n status\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation DeleteIdentity($identityId: String!) {\n accountDeleteIdentity(identityId: $identityId) {\n status\n }\n }\n"): (typeof documents)["\n mutation DeleteIdentity($identityId: String!) {\n accountDeleteIdentity(identityId: $identityId) {\n status\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation DeleteMfaAuthenticator($type: String!) {\n accountDeleteMfaAuthenticator(type: $type) {\n status\n }\n }\n"): (typeof documents)["\n mutation DeleteMfaAuthenticator($type: String!) {\n accountDeleteMfaAuthenticator(type: $type) {\n status\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation DeletePushTarget($targetId: String!) {\n accountDeletePushTarget(targetId: $targetId) {\n status\n }\n }\n"): (typeof documents)["\n mutation DeletePushTarget($targetId: String!) {\n accountDeletePushTarget(targetId: $targetId) {\n status\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation DeleteSession($sessionId: String!) {\n accountDeleteSession(sessionId: $sessionId) {\n status\n }\n }\n"): (typeof documents)["\n mutation DeleteSession($sessionId: String!) {\n accountDeleteSession(sessionId: $sessionId) {\n status\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation DeleteSessions {\n accountDeleteSessions {\n status\n }\n }\n"): (typeof documents)["\n mutation DeleteSessions {\n accountDeleteSessions {\n status\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query GetMfaRecoveryCodes {\n accountGetMfaRecoveryCodes {\n recoveryCodes\n }\n }\n"): (typeof documents)["\n query GetMfaRecoveryCodes {\n accountGetMfaRecoveryCodes {\n recoveryCodes\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query GetPrefs {\n accountGetPrefs {\n data\n }\n }\n"): (typeof documents)["\n query GetPrefs {\n accountGetPrefs {\n data\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query GetSession($sessionId: String!) {\n accountGetSession(sessionId: $sessionId) {\n userId\n expire\n current\n }\n }\n"): (typeof documents)["\n query GetSession($sessionId: String!) {\n accountGetSession(sessionId: $sessionId) {\n userId\n expire\n current\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query ListIdentities {\n accountListIdentities {\n total\n identities {\n ...Identity_Provider\n }\n }\n }\n"): (typeof documents)["\n query ListIdentities {\n accountListIdentities {\n total\n identities {\n ...Identity_Provider\n }\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query ListMfaFactors {\n accountListMfaFactors {\n totp\n phone\n email\n }\n }\n"): (typeof documents)["\n query ListMfaFactors {\n accountListMfaFactors {\n totp\n phone\n email\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query ListSessions {\n accountListSessions {\n sessions {\n _id\n _createdAt\n osName\n clientName\n }\n }\n }\n"): (typeof documents)["\n query ListSessions {\n accountListSessions {\n sessions {\n _id\n _createdAt\n osName\n clientName\n }\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation CreateEmailPasswordSession($email: String!, $password: String!) {\n accountCreateEmailPasswordSession(email: $email, password: $password) {\n userId\n expire\n current\n }\n }\n"): (typeof documents)["\n mutation CreateEmailPasswordSession($email: String!, $password: String!) {\n accountCreateEmailPasswordSession(email: $email, password: $password) {\n userId\n expire\n current\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query ListLogs($queries: [String!]) {\n accountListLogs(queries: $queries) {\n total\n logs {\n event\n userId\n userEmail\n userName\n mode\n ip\n time\n osCode\n osName\n osVersion\n clientType\n clientCode\n clientName\n clientVersion\n clientEngine\n clientEngineVersion\n deviceName\n deviceBrand\n deviceModel\n countryCode\n countryName\n }\n }\n }\n"): (typeof documents)["\n query ListLogs($queries: [String!]) {\n accountListLogs(queries: $queries) {\n total\n logs {\n event\n userId\n userEmail\n userName\n mode\n ip\n time\n osCode\n osName\n osVersion\n clientType\n clientCode\n clientName\n clientVersion\n clientEngine\n clientEngineVersion\n deviceName\n deviceBrand\n deviceModel\n countryCode\n countryName\n }\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation CreateRecovery($email: String!, $url: String!) {\n accountCreateRecovery(email: $email, url: $url) {\n expire\n }\n }\n"): (typeof documents)["\n mutation CreateRecovery($email: String!, $url: String!) {\n accountCreateRecovery(email: $email, url: $url) {\n expire\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdateRecovery($userId: String!, $secret: String!, $password: String!) {\n accountUpdateRecovery(userId: $userId, secret: $secret, password: $password) {\n expire\n }\n }\n"): (typeof documents)["\n mutation UpdateRecovery($userId: String!, $secret: String!, $password: String!) {\n accountUpdateRecovery(userId: $userId, secret: $secret, password: $password) {\n expire\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation CreateAccount($userId: String!, $name: String, $email: String!, $password: String!) {\n accountCreate(userId: $userId, name: $name, email: $email, password: $password) {\n name\n email\n }\n }\n"): (typeof documents)["\n mutation CreateAccount($userId: String!, $name: String, $email: String!, $password: String!) {\n accountCreate(userId: $userId, name: $name, email: $email, password: $password) {\n name\n email\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation VerifyEmail($url: String!) {\n accountCreateVerification(url: $url) {\n expire\n }\n }\n"): (typeof documents)["\n mutation VerifyEmail($url: String!) {\n accountCreateVerification(url: $url) {\n expire\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdateEmail($email: String!, $password: String!) {\n accountUpdateEmail(email: $email, password: $password) {\n name\n email\n }\n }\n"): (typeof documents)["\n mutation UpdateEmail($email: String!, $password: String!) {\n accountUpdateEmail(email: $email, password: $password) {\n name\n email\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdateEmailVerification($userId: String!, $secret: String!) {\n accountUpdateEmailVerification(userId: $userId, secret: $secret) {\n _id\n userId\n secret\n expire\n }\n }\n"): (typeof documents)["\n mutation UpdateEmailVerification($userId: String!, $secret: String!) {\n accountUpdateEmailVerification(userId: $userId, secret: $secret) {\n _id\n userId\n secret\n expire\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdateMagicURLSession($userId: String!, $secret: String!) {\n accountUpdateMagicURLSession(userId: $userId, secret: $secret) {\n userId\n expire\n current\n }\n }\n"): (typeof documents)["\n mutation UpdateMagicURLSession($userId: String!, $secret: String!) {\n accountUpdateMagicURLSession(userId: $userId, secret: $secret) {\n userId\n expire\n current\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdateMFA($mfa: Boolean!) {\n accountUpdateMFA(mfa: $mfa) {\n mfa\n }\n }\n"): (typeof documents)["\n mutation UpdateMFA($mfa: Boolean!) {\n accountUpdateMFA(mfa: $mfa) {\n mfa\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdateMfaAuthenticator($type: String!, $otp: String!) {\n accountUpdateMfaAuthenticator(type: $type, otp: $otp) {\n mfa\n }\n }\n"): (typeof documents)["\n mutation UpdateMfaAuthenticator($type: String!, $otp: String!) {\n accountUpdateMfaAuthenticator(type: $type, otp: $otp) {\n mfa\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdateMfaChallenge($challengeId: String!, $otp: String!) {\n accountUpdateMfaChallenge(challengeId: $challengeId, otp: $otp) {\n status\n }\n }\n"): (typeof documents)["\n mutation UpdateMfaChallenge($challengeId: String!, $otp: String!) {\n accountUpdateMfaChallenge(challengeId: $challengeId, otp: $otp) {\n status\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdateMfaRecoveryCodes {\n accountUpdateMfaRecoveryCodes {\n recoveryCodes\n }\n }\n"): (typeof documents)["\n mutation UpdateMfaRecoveryCodes {\n accountUpdateMfaRecoveryCodes {\n recoveryCodes\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdateName($name: String!) {\n accountUpdateName(name: $name) {\n name\n }\n }\n"): (typeof documents)["\n mutation UpdateName($name: String!) {\n accountUpdateName(name: $name) {\n name\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdatePassword($password: String!, $oldPassword: String!) {\n accountUpdatePassword(password: $password, oldPassword: $oldPassword) {\n status\n }\n }\n"): (typeof documents)["\n mutation UpdatePassword($password: String!, $oldPassword: String!) {\n accountUpdatePassword(password: $password, oldPassword: $oldPassword) {\n status\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdatePhone($phone: String!, $password: String!) {\n accountUpdatePhone(phone: $phone, password: $password) {\n phone\n }\n }\n"): (typeof documents)["\n mutation UpdatePhone($phone: String!, $password: String!) {\n accountUpdatePhone(phone: $phone, password: $password) {\n phone\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdatePhoneSession($userId: String!, $secret: String!) {\n accountUpdatePhoneSession(userId: $userId, secret: $secret) {\n userId\n expire\n current\n }\n }\n"): (typeof documents)["\n mutation UpdatePhoneSession($userId: String!, $secret: String!) {\n accountUpdatePhoneSession(userId: $userId, secret: $secret) {\n userId\n expire\n current\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdatePhoneVerification($userId: String!, $secret: String!) {\n accountUpdatePhoneVerification(userId: $userId, secret: $secret) {\n expire\n }\n }\n"): (typeof documents)["\n mutation UpdatePhoneVerification($userId: String!, $secret: String!) {\n accountUpdatePhoneVerification(userId: $userId, secret: $secret) {\n expire\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdatePrefs($prefs: Assoc!) {\n accountUpdatePrefs(prefs: $prefs) {\n prefs {\n data\n }\n }\n }\n"): (typeof documents)["\n mutation UpdatePrefs($prefs: Assoc!) {\n accountUpdatePrefs(prefs: $prefs) {\n prefs {\n data\n }\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdatePushTarget($targetId: String!, $identifier: String!) {\n accountUpdatePushTarget(targetId: $targetId, identifier: $identifier) {\n _id\n userId\n providerType\n identifier\n }\n }\n"): (typeof documents)["\n mutation UpdatePushTarget($targetId: String!, $identifier: String!) {\n accountUpdatePushTarget(targetId: $targetId, identifier: $identifier) {\n _id\n userId\n providerType\n identifier\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdateSession($sessionId: String!) {\n accountUpdateSession(sessionId: $sessionId) {\n userId\n expire\n current\n }\n }\n"): (typeof documents)["\n mutation UpdateSession($sessionId: String!) {\n accountUpdateSession(sessionId: $sessionId) {\n userId\n expire\n current\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdateStatus {\n accountUpdateStatus {\n _id\n status\n }\n }\n"): (typeof documents)["\n mutation UpdateStatus {\n accountUpdateStatus {\n _id\n status\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdateVerification($userId: String!, $secret: String!) {\n accountUpdateVerification(userId: $userId, secret: $secret) {\n secret\n expire\n userId\n }\n }\n"): (typeof documents)["\n mutation UpdateVerification($userId: String!, $secret: String!) {\n accountUpdateVerification(userId: $userId, secret: $secret) {\n secret\n expire\n userId\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query ListDocuments($databaseId: String!, $collectionId: String!, $queries: [String!]) {\n databasesListDocuments(\n databaseId: $databaseId\n collectionId: $collectionId\n queries: $queries\n ) {\n total\n documents {\n _id\n data\n }\n }\n }\n"): (typeof documents)["\n query ListDocuments($databaseId: String!, $collectionId: String!, $queries: [String!]) {\n databasesListDocuments(\n databaseId: $databaseId\n collectionId: $collectionId\n queries: $queries\n ) {\n total\n documents {\n _id\n data\n }\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation CreateDocument(\n $databaseId: String!\n $collectionId: String!\n $documentId: String!\n $data: Json!\n $permissions: [String!]\n ) {\n databasesCreateDocument(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n data: $data\n permissions: $permissions\n ) {\n _id\n }\n }\n"): (typeof documents)["\n mutation CreateDocument(\n $databaseId: String!\n $collectionId: String!\n $documentId: String!\n $data: Json!\n $permissions: [String!]\n ) {\n databasesCreateDocument(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n data: $data\n permissions: $permissions\n ) {\n _id\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation CreateDocuments(\n $databaseId: String!\n $collectionId: String!\n $documents: [Json!]!\n ) {\n databasesCreateDocuments(\n databaseId: $databaseId\n collectionId: $collectionId\n documents: $documents\n ) {\n total\n documents {\n _id\n }\n }\n }\n"): (typeof documents)["\n mutation CreateDocuments(\n $databaseId: String!\n $collectionId: String!\n $documents: [Json!]!\n ) {\n databasesCreateDocuments(\n databaseId: $databaseId\n collectionId: $collectionId\n documents: $documents\n ) {\n total\n documents {\n _id\n }\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation CreateOperations($transactionId: String!, $operations: [String!]) {\n databasesCreateOperations(transactionId: $transactionId, operations: $operations) {\n _id\n status\n operations\n expiresAt\n }\n }\n"): (typeof documents)["\n mutation CreateOperations($transactionId: String!, $operations: [String!]) {\n databasesCreateOperations(transactionId: $transactionId, operations: $operations) {\n _id\n status\n operations\n expiresAt\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation CreateTransaction($ttl: Int) {\n databasesCreateTransaction(ttl: $ttl) {\n _id\n status\n operations\n expiresAt\n }\n }\n"): (typeof documents)["\n mutation CreateTransaction($ttl: Int) {\n databasesCreateTransaction(ttl: $ttl) {\n _id\n status\n operations\n expiresAt\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation DecrementDocumentAttribute(\n $databaseId: String!\n $collectionId: String!\n $documentId: String!\n $attribute: String!\n $value: Int\n $min: Int\n ) {\n databasesDecrementDocumentAttribute(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n attribute: $attribute\n value: $value\n min: $min\n ) {\n _id\n data\n }\n }\n"): (typeof documents)["\n mutation DecrementDocumentAttribute(\n $databaseId: String!\n $collectionId: String!\n $documentId: String!\n $attribute: String!\n $value: Int\n $min: Int\n ) {\n databasesDecrementDocumentAttribute(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n attribute: $attribute\n value: $value\n min: $min\n ) {\n _id\n data\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation DeleteDocument($databaseId: String!, $collectionId: String!, $documentId: String!) {\n databasesDeleteDocument(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n ) {\n status\n }\n }\n"): (typeof documents)["\n mutation DeleteDocument($databaseId: String!, $collectionId: String!, $documentId: String!) {\n databasesDeleteDocument(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n ) {\n status\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation DeleteDocuments(\n $databaseId: String!\n $collectionId: String!\n $queries: [String!]\n ) {\n databasesDeleteDocuments(\n databaseId: $databaseId\n collectionId: $collectionId\n queries: $queries\n ) {\n total\n documents {\n _id\n }\n }\n }\n"): (typeof documents)["\n mutation DeleteDocuments(\n $databaseId: String!\n $collectionId: String!\n $queries: [String!]\n ) {\n databasesDeleteDocuments(\n databaseId: $databaseId\n collectionId: $collectionId\n queries: $queries\n ) {\n total\n documents {\n _id\n }\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation DeleteTransaction($transactionId: String!) {\n databasesDeleteTransaction(transactionId: $transactionId) {\n status\n }\n }\n"): (typeof documents)["\n mutation DeleteTransaction($transactionId: String!) {\n databasesDeleteTransaction(transactionId: $transactionId) {\n status\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query GetDocument($databaseId: String!, $collectionId: String!, $documentId: String!) {\n databasesGetDocument(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n ) {\n _id\n data\n }\n }\n"): (typeof documents)["\n query GetDocument($databaseId: String!, $collectionId: String!, $documentId: String!) {\n databasesGetDocument(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n ) {\n _id\n data\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query GetTransaction($transactionId: String!) {\n databasesGetTransaction(transactionId: $transactionId) {\n _id\n _createdAt\n _updatedAt\n status\n operations\n expiresAt\n }\n }\n"): (typeof documents)["\n query GetTransaction($transactionId: String!) {\n databasesGetTransaction(transactionId: $transactionId) {\n _id\n _createdAt\n _updatedAt\n status\n operations\n expiresAt\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation IncrementDocumentAttribute(\n $databaseId: String!\n $collectionId: String!\n $documentId: String!\n $attribute: String!\n $value: Int\n $max: Int\n ) {\n databasesIncrementDocumentAttribute(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n attribute: $attribute\n value: $value\n max: $max\n ) {\n _id\n data\n }\n }\n"): (typeof documents)["\n mutation IncrementDocumentAttribute(\n $databaseId: String!\n $collectionId: String!\n $documentId: String!\n $attribute: String!\n $value: Int\n $max: Int\n ) {\n databasesIncrementDocumentAttribute(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n attribute: $attribute\n value: $value\n max: $max\n ) {\n _id\n data\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query ListTransactions($queries: String) {\n databasesListTransactions(queries: $queries) {\n total\n transactions {\n _id\n _createdAt\n _updatedAt\n status\n operations\n expiresAt\n }\n }\n }\n"): (typeof documents)["\n query ListTransactions($queries: String) {\n databasesListTransactions(queries: $queries) {\n total\n transactions {\n _id\n _createdAt\n _updatedAt\n status\n operations\n expiresAt\n }\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdateDocument(\n $databaseId: String!\n $collectionId: String!\n $documentId: String!\n $data: Json\n $permissions: [String!]\n ) {\n databasesUpdateDocument(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n data: $data\n permissions: $permissions\n ) {\n _id\n }\n }\n"): (typeof documents)["\n mutation UpdateDocument(\n $databaseId: String!\n $collectionId: String!\n $documentId: String!\n $data: Json\n $permissions: [String!]\n ) {\n databasesUpdateDocument(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n data: $data\n permissions: $permissions\n ) {\n _id\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdateDocuments(\n $databaseId: String!\n $collectionId: String!\n $data: Json\n $queries: [String!]\n ) {\n databasesUpdateDocuments(\n databaseId: $databaseId\n collectionId: $collectionId\n data: $data\n queries: $queries\n ) {\n total\n documents {\n _id\n }\n }\n }\n"): (typeof documents)["\n mutation UpdateDocuments(\n $databaseId: String!\n $collectionId: String!\n $data: Json\n $queries: [String!]\n ) {\n databasesUpdateDocuments(\n databaseId: $databaseId\n collectionId: $collectionId\n data: $data\n queries: $queries\n ) {\n total\n documents {\n _id\n }\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdateTransaction($transactionId: String!, $commit: Boolean, $rollback: Boolean) {\n databasesUpdateTransaction(\n transactionId: $transactionId\n commit: $commit\n rollback: $rollback\n ) {\n _id\n status\n operations\n }\n }\n"): (typeof documents)["\n mutation UpdateTransaction($transactionId: String!, $commit: Boolean, $rollback: Boolean) {\n databasesUpdateTransaction(\n transactionId: $transactionId\n commit: $commit\n rollback: $rollback\n ) {\n _id\n status\n operations\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpsertDocument(\n $databaseId: String!\n $collectionId: String!\n $documentId: String!\n $data: Json!\n $permissions: [String!]\n ) {\n databasesUpsertDocument(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n data: $data\n permissions: $permissions\n ) {\n _id\n }\n }\n"): (typeof documents)["\n mutation UpsertDocument(\n $databaseId: String!\n $collectionId: String!\n $documentId: String!\n $data: Json!\n $permissions: [String!]\n ) {\n databasesUpsertDocument(\n databaseId: $databaseId\n collectionId: $collectionId\n documentId: $documentId\n data: $data\n permissions: $permissions\n ) {\n _id\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpsertDocuments(\n $databaseId: String!\n $collectionId: String!\n $documents: [Json!]!\n ) {\n databasesUpsertDocuments(\n databaseId: $databaseId\n collectionId: $collectionId\n documents: $documents\n ) {\n total\n documents {\n _id\n }\n }\n }\n"): (typeof documents)["\n mutation UpsertDocuments(\n $databaseId: String!\n $collectionId: String!\n $documents: [Json!]!\n ) {\n databasesUpsertDocuments(\n databaseId: $databaseId\n collectionId: $collectionId\n documents: $documents\n ) {\n total\n documents {\n _id\n }\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation CreateExecution(\n $functionId: String!\n $body: String\n $async: Boolean\n $path: String\n $method: String # $headers: Json\n ) {\n functionsCreateExecution(\n functionId: $functionId\n body: $body\n async: $async\n path: $path\n method: $method # headers: $headers\n ) {\n _id\n status\n responseStatusCode\n responseBody\n errors\n duration\n }\n }\n"): (typeof documents)["\n mutation CreateExecution(\n $functionId: String!\n $body: String\n $async: Boolean\n $path: String\n $method: String # $headers: Json\n ) {\n functionsCreateExecution(\n functionId: $functionId\n body: $body\n async: $async\n path: $path\n method: $method # headers: $headers\n ) {\n _id\n status\n responseStatusCode\n responseBody\n errors\n duration\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query GetFunctionExecution($functionId: String!, $executionId: String!) {\n functionsGetExecution(functionId: $functionId, executionId: $executionId) {\n status\n errors\n duration\n responseBody\n requestPath\n }\n }\n"): (typeof documents)["\n query GetFunctionExecution($functionId: String!, $executionId: String!) {\n functionsGetExecution(functionId: $functionId, executionId: $executionId) {\n status\n errors\n duration\n responseBody\n requestPath\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query GetExecution($functionId: String!, $executionId: String!) {\n functionsGetExecution(functionId: $functionId, executionId: $executionId) {\n _id\n _createdAt\n _updatedAt\n functionId\n trigger\n status\n requestMethod\n requestPath\n responseStatusCode\n responseBody\n errors\n duration\n }\n }\n"): (typeof documents)["\n query GetExecution($functionId: String!, $executionId: String!) {\n functionsGetExecution(functionId: $functionId, executionId: $executionId) {\n _id\n _createdAt\n _updatedAt\n functionId\n trigger\n status\n requestMethod\n requestPath\n responseStatusCode\n responseBody\n errors\n duration\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query ListExecutions($functionId: String!, $queries: [String!]) {\n functionsListExecutions(functionId: $functionId, queries: $queries) {\n total\n executions {\n _id\n _createdAt\n _updatedAt\n functionId\n trigger\n status\n requestMethod\n requestPath\n responseStatusCode\n responseBody\n errors\n duration\n }\n }\n }\n"): (typeof documents)["\n query ListExecutions($functionId: String!, $queries: [String!]) {\n functionsListExecutions(functionId: $functionId, queries: $queries) {\n total\n executions {\n _id\n _createdAt\n _updatedAt\n functionId\n trigger\n status\n requestMethod\n requestPath\n responseStatusCode\n responseBody\n errors\n duration\n }\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query GetLocale {\n localeGet {\n ip\n countryCode\n country\n continentCode\n continent\n eu\n currency\n }\n }\n"): (typeof documents)["\n query GetLocale {\n localeGet {\n ip\n countryCode\n country\n continentCode\n continent\n eu\n currency\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query ListLocaleCodes {\n localeListCodes {\n total\n localeCodes {\n code\n name\n }\n }\n }\n"): (typeof documents)["\n query ListLocaleCodes {\n localeListCodes {\n total\n localeCodes {\n code\n name\n }\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query ListContinents {\n localeListContinents {\n total\n continents {\n name\n code\n }\n }\n }\n"): (typeof documents)["\n query ListContinents {\n localeListContinents {\n total\n continents {\n name\n code\n }\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query ListCountries {\n localeListCountries {\n total\n countries {\n name\n code\n }\n }\n }\n"): (typeof documents)["\n query ListCountries {\n localeListCountries {\n total\n countries {\n name\n code\n }\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query ListCountriesEU {\n localeListCountriesEU {\n total\n countries {\n name\n code\n }\n }\n }\n"): (typeof documents)["\n query ListCountriesEU {\n localeListCountriesEU {\n total\n countries {\n name\n code\n }\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query ListCountriesPhones {\n localeListCountriesPhones {\n total\n phones {\n code\n countryCode\n countryName\n }\n }\n }\n"): (typeof documents)["\n query ListCountriesPhones {\n localeListCountriesPhones {\n total\n phones {\n code\n countryCode\n countryName\n }\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query ListCurrencies {\n localeListCurrencies {\n total\n currencies {\n symbol\n name\n symbolNative\n decimalDigits\n rounding\n code\n namePlural\n }\n }\n }\n"): (typeof documents)["\n query ListCurrencies {\n localeListCurrencies {\n total\n currencies {\n symbol\n name\n symbolNative\n decimalDigits\n rounding\n code\n namePlural\n }\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query ListLanguages {\n localeListLanguages {\n total\n languages {\n name\n code\n nativeName\n }\n }\n }\n"): (typeof documents)["\n query ListLanguages {\n localeListLanguages {\n total\n languages {\n name\n code\n nativeName\n }\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation CreateFile(\n $bucketId: String!\n $fileId: String!\n $file: String!\n $permissions: [String!]\n ) {\n storageCreateFile(\n bucketId: $bucketId\n fileId: $fileId\n file: $file\n permissions: $permissions\n ) {\n _id\n bucketId\n name\n mimeType\n sizeOriginal\n }\n }\n"): (typeof documents)["\n mutation CreateFile(\n $bucketId: String!\n $fileId: String!\n $file: String!\n $permissions: [String!]\n ) {\n storageCreateFile(\n bucketId: $bucketId\n fileId: $fileId\n file: $file\n permissions: $permissions\n ) {\n _id\n bucketId\n name\n mimeType\n sizeOriginal\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation DeleteFile($bucketId: String!, $fileId: String!) {\n storageDeleteFile(bucketId: $bucketId, fileId: $fileId) {\n status\n }\n }\n"): (typeof documents)["\n mutation DeleteFile($bucketId: String!, $fileId: String!) {\n storageDeleteFile(bucketId: $bucketId, fileId: $fileId) {\n status\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query GetFile($bucketId: String!, $fileId: String!) {\n storageGetFile(bucketId: $bucketId, fileId: $fileId) {\n _id\n bucketId\n _createdAt\n _updatedAt\n _permissions\n name\n signature\n mimeType\n sizeOriginal\n chunksTotal\n chunksUploaded\n }\n }\n"): (typeof documents)["\n query GetFile($bucketId: String!, $fileId: String!) {\n storageGetFile(bucketId: $bucketId, fileId: $fileId) {\n _id\n bucketId\n _createdAt\n _updatedAt\n _permissions\n name\n signature\n mimeType\n sizeOriginal\n chunksTotal\n chunksUploaded\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query ListFiles($bucketId: String!, $queries: [String!], $search: String) {\n storageListFiles(bucketId: $bucketId, queries: $queries, search: $search) {\n total\n files {\n _id\n bucketId\n _createdAt\n _updatedAt\n _permissions\n name\n signature\n mimeType\n sizeOriginal\n chunksTotal\n chunksUploaded\n }\n }\n }\n"): (typeof documents)["\n query ListFiles($bucketId: String!, $queries: [String!], $search: String) {\n storageListFiles(bucketId: $bucketId, queries: $queries, search: $search) {\n total\n files {\n _id\n bucketId\n _createdAt\n _updatedAt\n _permissions\n name\n signature\n mimeType\n sizeOriginal\n chunksTotal\n chunksUploaded\n }\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdateFile(\n $bucketId: String!\n $fileId: String!\n $name: String\n $permissions: [String!]\n ) {\n storageUpdateFile(\n bucketId: $bucketId\n fileId: $fileId\n name: $name\n permissions: $permissions\n ) {\n _id\n bucketId\n name\n _permissions\n }\n }\n"): (typeof documents)["\n mutation UpdateFile(\n $bucketId: String!\n $fileId: String!\n $name: String\n $permissions: [String!]\n ) {\n storageUpdateFile(\n bucketId: $bucketId\n fileId: $fileId\n name: $name\n permissions: $permissions\n ) {\n _id\n bucketId\n name\n _permissions\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation CreateMembership(\n $teamId: String!\n $roles: [String!]!\n $email: String\n $userId: String\n $phone: String\n $url: String\n $name: String\n ) {\n teamsCreateMembership(\n teamId: $teamId\n roles: $roles\n email: $email\n userId: $userId\n phone: $phone\n url: $url\n name: $name\n ) {\n _id\n userId\n teamId\n roles\n confirm\n }\n }\n"): (typeof documents)["\n mutation CreateMembership(\n $teamId: String!\n $roles: [String!]!\n $email: String\n $userId: String\n $phone: String\n $url: String\n $name: String\n ) {\n teamsCreateMembership(\n teamId: $teamId\n roles: $roles\n email: $email\n userId: $userId\n phone: $phone\n url: $url\n name: $name\n ) {\n _id\n userId\n teamId\n roles\n confirm\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation CreateTeam($teamId: String!, $name: String!, $roles: [String!]) {\n teamsCreate(teamId: $teamId, name: $name, roles: $roles) {\n _id\n name\n total\n }\n }\n"): (typeof documents)["\n mutation CreateTeam($teamId: String!, $name: String!, $roles: [String!]) {\n teamsCreate(teamId: $teamId, name: $name, roles: $roles) {\n _id\n name\n total\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation DeleteMembership($teamId: String!, $membershipId: String!) {\n teamsDeleteMembership(teamId: $teamId, membershipId: $membershipId) {\n status\n }\n }\n"): (typeof documents)["\n mutation DeleteMembership($teamId: String!, $membershipId: String!) {\n teamsDeleteMembership(teamId: $teamId, membershipId: $membershipId) {\n status\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation DeleteTeam($teamId: String!) {\n teamsDelete(teamId: $teamId) {\n status\n }\n }\n"): (typeof documents)["\n mutation DeleteTeam($teamId: String!) {\n teamsDelete(teamId: $teamId) {\n status\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query GetTeam($teamId: String!) {\n teamsGet(teamId: $teamId) {\n _id\n _createdAt\n _updatedAt\n name\n total\n prefs {\n data\n }\n }\n }\n"): (typeof documents)["\n query GetTeam($teamId: String!) {\n teamsGet(teamId: $teamId) {\n _id\n _createdAt\n _updatedAt\n name\n total\n prefs {\n data\n }\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query GetMembership($teamId: String!, $membershipId: String!) {\n teamsGetMembership(teamId: $teamId, membershipId: $membershipId) {\n _id\n _createdAt\n _updatedAt\n userId\n userName\n userEmail\n teamId\n teamName\n invited\n joined\n confirm\n mfa\n roles\n }\n }\n"): (typeof documents)["\n query GetMembership($teamId: String!, $membershipId: String!) {\n teamsGetMembership(teamId: $teamId, membershipId: $membershipId) {\n _id\n _createdAt\n _updatedAt\n userId\n userName\n userEmail\n teamId\n teamName\n invited\n joined\n confirm\n mfa\n roles\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query ListMemberships($teamId: String!, $queries: [String!], $search: String) {\n teamsListMemberships(teamId: $teamId, queries: $queries, search: $search) {\n total\n memberships {\n _id\n _createdAt\n _updatedAt\n userId\n userName\n userEmail\n teamId\n teamName\n invited\n joined\n confirm\n mfa\n roles\n }\n }\n }\n"): (typeof documents)["\n query ListMemberships($teamId: String!, $queries: [String!], $search: String) {\n teamsListMemberships(teamId: $teamId, queries: $queries, search: $search) {\n total\n memberships {\n _id\n _createdAt\n _updatedAt\n userId\n userName\n userEmail\n teamId\n teamName\n invited\n joined\n confirm\n mfa\n roles\n }\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query GetTeamPrefs($teamId: String!) {\n teamsGetPrefs(teamId: $teamId) {\n data\n }\n }\n"): (typeof documents)["\n query GetTeamPrefs($teamId: String!) {\n teamsGetPrefs(teamId: $teamId) {\n data\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n query ListTeams($queries: [String!], $search: String) {\n teamsList(queries: $queries, search: $search) {\n total\n teams {\n _id\n _createdAt\n _updatedAt\n name\n total\n prefs {\n data\n }\n }\n }\n }\n"): (typeof documents)["\n query ListTeams($queries: [String!], $search: String) {\n teamsList(queries: $queries, search: $search) {\n total\n teams {\n _id\n _createdAt\n _updatedAt\n name\n total\n prefs {\n data\n }\n }\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdateMembership($teamId: String!, $membershipId: String!, $roles: [String!]!) {\n teamsUpdateMembership(teamId: $teamId, membershipId: $membershipId, roles: $roles) {\n _id\n roles\n }\n }\n"): (typeof documents)["\n mutation UpdateMembership($teamId: String!, $membershipId: String!, $roles: [String!]!) {\n teamsUpdateMembership(teamId: $teamId, membershipId: $membershipId, roles: $roles) {\n _id\n roles\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdateMembershipStatus(\n $teamId: String!\n $membershipId: String!\n $userId: String!\n $secret: String!\n ) {\n teamsUpdateMembershipStatus(\n teamId: $teamId\n membershipId: $membershipId\n userId: $userId\n secret: $secret\n ) {\n _id\n confirm\n }\n }\n"): (typeof documents)["\n mutation UpdateMembershipStatus(\n $teamId: String!\n $membershipId: String!\n $userId: String!\n $secret: String!\n ) {\n teamsUpdateMembershipStatus(\n teamId: $teamId\n membershipId: $membershipId\n userId: $userId\n secret: $secret\n ) {\n _id\n confirm\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdateTeamName($teamId: String!, $name: String!) {\n teamsUpdateName(teamId: $teamId, name: $name) {\n _id\n name\n }\n }\n"): (typeof documents)["\n mutation UpdateTeamName($teamId: String!, $name: String!) {\n teamsUpdateName(teamId: $teamId, name: $name) {\n _id\n name\n }\n }\n"]; -/** - * The gql function is used to parse GraphQL queries into a document that can be used by GraphQL clients. - */ -export function gql(source: "\n mutation UpdateTeamPrefs($teamId: String!, $prefs: Assoc!) {\n teamsUpdatePrefs(teamId: $teamId, prefs: $prefs) {\n data\n }\n }\n"): (typeof documents)["\n mutation UpdateTeamPrefs($teamId: String!, $prefs: Assoc!) {\n teamsUpdatePrefs(teamId: $teamId, prefs: $prefs) {\n data\n }\n }\n"]; - -export function gql(source: string) { - return (documents as any)[source] ?? {}; -} - -export type DocumentType> = TDocumentNode extends DocumentNode< infer TType, any> ? TType : never; \ No newline at end of file diff --git a/src/__generated__/graphql.ts b/src/__generated__/graphql.ts deleted file mode 100644 index 00addb7..0000000 --- a/src/__generated__/graphql.ts +++ /dev/null @@ -1,1833 +0,0 @@ -/* eslint-disable */ -import { TypedDocumentNode as DocumentNode } from '@graphql-typed-document-node/core'; -export type Maybe = T | null; -export type InputMaybe = T | null | undefined; -export type Exact = { [K in keyof T]: T[K] }; -export type MakeOptional = Omit & { [SubKey in K]?: Maybe }; -export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; -export type MakeEmpty = { [_ in K]?: never }; -export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; -/** All built-in and custom scalars, mapped to their actual values */ -export type Scalars = { - ID: { input: string; output: string; } - String: { input: string; output: string; } - Boolean: { input: boolean; output: boolean; } - Int: { input: number; output: number; } - Float: { input: number; output: number; } - Assoc: { input: any; output: any; } - Date: { input: any; output: any; } - Json: { input: any; output: any; } -}; - -export type Continent = { - __typename?: 'Continent'; - code?: Maybe; - name?: Maybe; -}; - -export type ContinentList = { - __typename?: 'ContinentList'; - continents?: Maybe>>; - total?: Maybe; -}; - -export type Country = { - __typename?: 'Country'; - code?: Maybe; - name?: Maybe; -}; - -export type CountryList = { - __typename?: 'CountryList'; - countries?: Maybe>>; - total?: Maybe; -}; - -export type Currency = { - __typename?: 'Currency'; - code?: Maybe; - decimalDigits?: Maybe; - name?: Maybe; - namePlural?: Maybe; - rounding?: Maybe; - symbol?: Maybe; - symbolNative?: Maybe; -}; - -export type CurrencyList = { - __typename?: 'CurrencyList'; - currencies?: Maybe>>; - total?: Maybe; -}; - -export type Document = { - __typename?: 'Document'; - _collectionId?: Maybe; - _createdAt?: Maybe; - _databaseId?: Maybe; - _id?: Maybe; - _permissions?: Maybe>>; - _updatedAt?: Maybe; - data?: Maybe; -}; - -export type DocumentList = { - __typename?: 'DocumentList'; - documents?: Maybe>>; - total?: Maybe; -}; - -export type Execution = { - __typename?: 'Execution'; - _createdAt?: Maybe; - _id?: Maybe; - _updatedAt?: Maybe; - duration?: Maybe; - errors?: Maybe; - functionId?: Maybe; - requestMethod?: Maybe; - requestPath?: Maybe; - responseBody?: Maybe; - responseStatusCode?: Maybe; - status?: Maybe; - trigger?: Maybe; -}; - -export type ExecutionList = { - __typename?: 'ExecutionList'; - executions?: Maybe>>; - total?: Maybe; -}; - -export type File = { - __typename?: 'File'; - _createdAt?: Maybe; - _id?: Maybe; - _permissions?: Maybe>>; - _updatedAt?: Maybe; - bucketId?: Maybe; - chunksTotal?: Maybe; - chunksUploaded?: Maybe; - mimeType?: Maybe; - name?: Maybe; - signature?: Maybe; - sizeOriginal?: Maybe; -}; - -export type FileList = { - __typename?: 'FileList'; - files?: Maybe>>; - total?: Maybe; -}; - -export type Identity = { - __typename?: 'Identity'; - _createdAt?: Maybe; - _id?: Maybe; - _updatedAt?: Maybe; - provider?: Maybe; - providerAccessToken?: Maybe; - providerAccessTokenExpiry?: Maybe; - providerEmail?: Maybe; - providerRefreshToken?: Maybe; - providerUid?: Maybe; - userId?: Maybe; -}; - -export type IdentityList = { - __typename?: 'IdentityList'; - identities?: Maybe>; - total: Scalars['Int']['output']; -}; - -export type Jwt = { - __typename?: 'JWT'; - jwt?: Maybe; -}; - -export type Language = { - __typename?: 'Language'; - code?: Maybe; - name?: Maybe; - nativeName?: Maybe; -}; - -export type LanguageList = { - __typename?: 'LanguageList'; - languages?: Maybe>>; - total?: Maybe; -}; - -export type Locale = { - __typename?: 'Locale'; - continent?: Maybe; - continentCode?: Maybe; - country?: Maybe; - countryCode?: Maybe; - currency?: Maybe; - eu?: Maybe; - ip?: Maybe; -}; - -export type LocaleCode = { - __typename?: 'LocaleCode'; - code?: Maybe; - name?: Maybe; -}; - -export type LocaleCodeList = { - __typename?: 'LocaleCodeList'; - localeCodes?: Maybe>>; - total?: Maybe; -}; - -export type Log = { - __typename?: 'Log'; - _createdAt?: Maybe; - _id?: Maybe; - _updatedAt?: Maybe; - clientCode?: Maybe; - clientEngine?: Maybe; - clientEngineVersion?: Maybe; - clientName?: Maybe; - clientType?: Maybe; - clientVersion?: Maybe; - countryCode?: Maybe; - countryName?: Maybe; - deviceBrand?: Maybe; - deviceModel?: Maybe; - deviceName?: Maybe; - event?: Maybe; - ip?: Maybe; - mode?: Maybe; - osCode?: Maybe; - osName?: Maybe; - osVersion?: Maybe; - time?: Maybe; - userEmail?: Maybe; - userId?: Maybe; - userName?: Maybe; -}; - -export type LogsList = { - __typename?: 'LogsList'; - logs?: Maybe>; - total: Scalars['Int']['output']; -}; - -export type MfaChallenge = { - __typename?: 'MFAChallenge'; - _createdAt?: Maybe; - _id?: Maybe; - expire?: Maybe; - userId?: Maybe; -}; - -export type Membership = { - __typename?: 'Membership'; - _createdAt?: Maybe; - _id?: Maybe; - _updatedAt?: Maybe; - confirm?: Maybe; - invited?: Maybe; - joined?: Maybe; - mfa?: Maybe; - roles?: Maybe>>; - teamId?: Maybe; - teamName?: Maybe; - userEmail?: Maybe; - userId?: Maybe; - userName?: Maybe; -}; - -export type MembershipList = { - __typename?: 'MembershipList'; - memberships?: Maybe>>; - total?: Maybe; -}; - -export type MfaFactors = { - __typename?: 'MfaFactors'; - email?: Maybe; - phone?: Maybe; - totp?: Maybe; -}; - -export type MfaRecoveryCodes = { - __typename?: 'MfaRecoveryCodes'; - recoveryCodes: Array; -}; - -export type MfaType = { - __typename?: 'MfaType'; - secret?: Maybe; - uri?: Maybe; -}; - -export type Mutation = { - __typename?: 'Mutation'; - accountCreate?: Maybe; - accountCreateAnonymousSession?: Maybe; - accountCreateEmailPasswordSession?: Maybe; - accountCreateEmailToken?: Maybe; - accountCreateEmailVerification?: Maybe; - accountCreateJWT?: Maybe; - accountCreateMagicURLSession?: Maybe; - accountCreateMagicURLToken?: Maybe; - accountCreateMfaAuthenticator?: Maybe; - accountCreateMfaChallenge?: Maybe; - accountCreateMfaRecoveryCodes?: Maybe; - accountCreatePhoneSession?: Maybe; - accountCreatePhoneToken?: Maybe; - accountCreatePhoneVerification?: Maybe; - accountCreatePushTarget?: Maybe; - accountCreateRecovery?: Maybe; - accountCreateSession?: Maybe; - accountCreateVerification?: Maybe; - accountDelete?: Maybe; - accountDeleteIdentity?: Maybe; - accountDeleteMfaAuthenticator?: Maybe; - accountDeletePushTarget?: Maybe; - accountDeleteSession?: Maybe; - accountDeleteSessions?: Maybe; - accountUpdateEmail?: Maybe; - accountUpdateEmailVerification?: Maybe; - accountUpdateMFA?: Maybe; - accountUpdateMagicURLSession?: Maybe; - accountUpdateMfaAuthenticator?: Maybe; - accountUpdateMfaChallenge?: Maybe; - accountUpdateMfaRecoveryCodes?: Maybe; - accountUpdateName?: Maybe; - accountUpdatePassword?: Maybe; - accountUpdatePhone?: Maybe; - accountUpdatePhoneSession?: Maybe; - accountUpdatePhoneVerification?: Maybe; - accountUpdatePrefs?: Maybe; - accountUpdatePushTarget?: Maybe; - accountUpdateRecovery?: Maybe; - accountUpdateSession?: Maybe; - accountUpdateStatus?: Maybe; - accountUpdateVerification?: Maybe; - databasesCreateDocument?: Maybe; - databasesCreateDocuments?: Maybe; - databasesCreateOperations?: Maybe; - databasesCreateTransaction?: Maybe; - databasesDecrementDocumentAttribute?: Maybe; - databasesDeleteDocument?: Maybe; - databasesDeleteDocuments?: Maybe; - databasesDeleteTransaction?: Maybe; - databasesIncrementDocumentAttribute?: Maybe; - databasesUpdateDocument?: Maybe; - databasesUpdateDocuments?: Maybe; - databasesUpdateTransaction?: Maybe; - databasesUpsertDocument?: Maybe; - databasesUpsertDocuments?: Maybe; - functionsCreateExecution?: Maybe; - storageCreateFile?: Maybe; - storageDeleteFile?: Maybe; - storageUpdateFile?: Maybe; - teamsCreate?: Maybe; - teamsCreateMembership?: Maybe; - teamsDelete?: Maybe; - teamsDeleteMembership?: Maybe; - teamsUpdateMembership?: Maybe; - teamsUpdateMembershipStatus?: Maybe; - teamsUpdateName?: Maybe; - teamsUpdatePrefs?: Maybe; -}; - - -export type MutationAccountCreateArgs = { - email: Scalars['String']['input']; - name?: InputMaybe; - password: Scalars['String']['input']; - userId: Scalars['String']['input']; -}; - - -export type MutationAccountCreateEmailPasswordSessionArgs = { - email: Scalars['String']['input']; - password: Scalars['String']['input']; -}; - - -export type MutationAccountCreateEmailTokenArgs = { - email: Scalars['String']['input']; - phrase?: InputMaybe; - userId: Scalars['String']['input']; -}; - - -export type MutationAccountCreateEmailVerificationArgs = { - url: Scalars['String']['input']; -}; - - -export type MutationAccountCreateMagicUrlSessionArgs = { - email: Scalars['String']['input']; - url?: InputMaybe; - userId: Scalars['String']['input']; -}; - - -export type MutationAccountCreateMagicUrlTokenArgs = { - email: Scalars['String']['input']; - phrase?: InputMaybe; - url?: InputMaybe; - userId: Scalars['String']['input']; -}; - - -export type MutationAccountCreateMfaAuthenticatorArgs = { - type: Scalars['String']['input']; -}; - - -export type MutationAccountCreateMfaChallengeArgs = { - factor: Scalars['String']['input']; -}; - - -export type MutationAccountCreatePhoneSessionArgs = { - phone: Scalars['String']['input']; - userId: Scalars['String']['input']; -}; - - -export type MutationAccountCreatePhoneTokenArgs = { - phone: Scalars['String']['input']; - userId: Scalars['String']['input']; -}; - - -export type MutationAccountCreatePushTargetArgs = { - identifier: Scalars['String']['input']; - providerId?: InputMaybe; - targetId: Scalars['String']['input']; -}; - - -export type MutationAccountCreateRecoveryArgs = { - email: Scalars['String']['input']; - url: Scalars['String']['input']; -}; - - -export type MutationAccountCreateSessionArgs = { - secret: Scalars['String']['input']; - userId: Scalars['String']['input']; -}; - - -export type MutationAccountCreateVerificationArgs = { - url: Scalars['String']['input']; -}; - - -export type MutationAccountDeleteIdentityArgs = { - identityId: Scalars['String']['input']; -}; - - -export type MutationAccountDeleteMfaAuthenticatorArgs = { - type: Scalars['String']['input']; -}; - - -export type MutationAccountDeletePushTargetArgs = { - targetId: Scalars['String']['input']; -}; - - -export type MutationAccountDeleteSessionArgs = { - sessionId: Scalars['String']['input']; -}; - - -export type MutationAccountUpdateEmailArgs = { - email: Scalars['String']['input']; - password: Scalars['String']['input']; -}; - - -export type MutationAccountUpdateEmailVerificationArgs = { - secret: Scalars['String']['input']; - userId: Scalars['String']['input']; -}; - - -export type MutationAccountUpdateMfaArgs = { - mfa: Scalars['Boolean']['input']; -}; - - -export type MutationAccountUpdateMagicUrlSessionArgs = { - secret: Scalars['String']['input']; - userId: Scalars['String']['input']; -}; - - -export type MutationAccountUpdateMfaAuthenticatorArgs = { - otp: Scalars['String']['input']; - type: Scalars['String']['input']; -}; - - -export type MutationAccountUpdateMfaChallengeArgs = { - challengeId: Scalars['String']['input']; - otp: Scalars['String']['input']; -}; - - -export type MutationAccountUpdateNameArgs = { - name: Scalars['String']['input']; -}; - - -export type MutationAccountUpdatePasswordArgs = { - oldPassword: Scalars['String']['input']; - password: Scalars['String']['input']; -}; - - -export type MutationAccountUpdatePhoneArgs = { - password: Scalars['String']['input']; - phone: Scalars['String']['input']; -}; - - -export type MutationAccountUpdatePhoneSessionArgs = { - secret: Scalars['String']['input']; - userId: Scalars['String']['input']; -}; - - -export type MutationAccountUpdatePhoneVerificationArgs = { - secret: Scalars['String']['input']; - userId: Scalars['String']['input']; -}; - - -export type MutationAccountUpdatePrefsArgs = { - prefs: Scalars['Assoc']['input']; -}; - - -export type MutationAccountUpdatePushTargetArgs = { - identifier: Scalars['String']['input']; - targetId: Scalars['String']['input']; -}; - - -export type MutationAccountUpdateRecoveryArgs = { - password: Scalars['String']['input']; - secret: Scalars['String']['input']; - userId: Scalars['String']['input']; -}; - - -export type MutationAccountUpdateSessionArgs = { - sessionId: Scalars['String']['input']; -}; - - -export type MutationAccountUpdateVerificationArgs = { - secret: Scalars['String']['input']; - userId: Scalars['String']['input']; -}; - - -export type MutationDatabasesCreateDocumentArgs = { - collectionId: Scalars['String']['input']; - data: Scalars['Json']['input']; - databaseId: Scalars['String']['input']; - documentId: Scalars['String']['input']; - permissions?: InputMaybe>; -}; - - -export type MutationDatabasesCreateDocumentsArgs = { - collectionId: Scalars['String']['input']; - databaseId: Scalars['String']['input']; - documents: Array; -}; - - -export type MutationDatabasesCreateOperationsArgs = { - operations?: InputMaybe>; - transactionId: Scalars['String']['input']; -}; - - -export type MutationDatabasesCreateTransactionArgs = { - ttl?: InputMaybe; -}; - - -export type MutationDatabasesDecrementDocumentAttributeArgs = { - attribute: Scalars['String']['input']; - collectionId: Scalars['String']['input']; - databaseId: Scalars['String']['input']; - documentId: Scalars['String']['input']; - min?: InputMaybe; - value?: InputMaybe; -}; - - -export type MutationDatabasesDeleteDocumentArgs = { - collectionId: Scalars['String']['input']; - databaseId: Scalars['String']['input']; - documentId: Scalars['String']['input']; -}; - - -export type MutationDatabasesDeleteDocumentsArgs = { - collectionId: Scalars['String']['input']; - databaseId: Scalars['String']['input']; - queries?: InputMaybe>; -}; - - -export type MutationDatabasesDeleteTransactionArgs = { - transactionId: Scalars['String']['input']; -}; - - -export type MutationDatabasesIncrementDocumentAttributeArgs = { - attribute: Scalars['String']['input']; - collectionId: Scalars['String']['input']; - databaseId: Scalars['String']['input']; - documentId: Scalars['String']['input']; - max?: InputMaybe; - value?: InputMaybe; -}; - - -export type MutationDatabasesUpdateDocumentArgs = { - collectionId: Scalars['String']['input']; - data?: InputMaybe; - databaseId: Scalars['String']['input']; - documentId: Scalars['String']['input']; - permissions?: InputMaybe>; -}; - - -export type MutationDatabasesUpdateDocumentsArgs = { - collectionId: Scalars['String']['input']; - data?: InputMaybe; - databaseId: Scalars['String']['input']; - queries?: InputMaybe>; -}; - - -export type MutationDatabasesUpdateTransactionArgs = { - commit?: InputMaybe; - rollback?: InputMaybe; - transactionId: Scalars['String']['input']; -}; - - -export type MutationDatabasesUpsertDocumentArgs = { - collectionId: Scalars['String']['input']; - data: Scalars['Json']['input']; - databaseId: Scalars['String']['input']; - documentId: Scalars['String']['input']; - permissions?: InputMaybe>; -}; - - -export type MutationDatabasesUpsertDocumentsArgs = { - collectionId: Scalars['String']['input']; - databaseId: Scalars['String']['input']; - documents: Array; -}; - - -export type MutationFunctionsCreateExecutionArgs = { - async?: InputMaybe; - body?: InputMaybe; - functionId: Scalars['String']['input']; - headers?: InputMaybe; - method?: InputMaybe; - path?: InputMaybe; -}; - - -export type MutationStorageCreateFileArgs = { - bucketId: Scalars['String']['input']; - file: Scalars['String']['input']; - fileId: Scalars['String']['input']; - permissions?: InputMaybe>; -}; - - -export type MutationStorageDeleteFileArgs = { - bucketId: Scalars['String']['input']; - fileId: Scalars['String']['input']; -}; - - -export type MutationStorageUpdateFileArgs = { - bucketId: Scalars['String']['input']; - fileId: Scalars['String']['input']; - name?: InputMaybe; - permissions?: InputMaybe>; -}; - - -export type MutationTeamsCreateArgs = { - name: Scalars['String']['input']; - roles?: InputMaybe>; - teamId: Scalars['String']['input']; -}; - - -export type MutationTeamsCreateMembershipArgs = { - email?: InputMaybe; - name?: InputMaybe; - phone?: InputMaybe; - roles: Array; - teamId: Scalars['String']['input']; - url?: InputMaybe; - userId?: InputMaybe; -}; - - -export type MutationTeamsDeleteArgs = { - teamId: Scalars['String']['input']; -}; - - -export type MutationTeamsDeleteMembershipArgs = { - membershipId: Scalars['String']['input']; - teamId: Scalars['String']['input']; -}; - - -export type MutationTeamsUpdateMembershipArgs = { - membershipId: Scalars['String']['input']; - roles: Array; - teamId: Scalars['String']['input']; -}; - - -export type MutationTeamsUpdateMembershipStatusArgs = { - membershipId: Scalars['String']['input']; - secret: Scalars['String']['input']; - teamId: Scalars['String']['input']; - userId: Scalars['String']['input']; -}; - - -export type MutationTeamsUpdateNameArgs = { - name: Scalars['String']['input']; - teamId: Scalars['String']['input']; -}; - - -export type MutationTeamsUpdatePrefsArgs = { - prefs: Scalars['Assoc']['input']; - teamId: Scalars['String']['input']; -}; - -export type None = { - __typename?: 'None'; - status?: Maybe; -}; - -export type Phone = { - __typename?: 'Phone'; - code?: Maybe; - countryCode?: Maybe; - countryName?: Maybe; -}; - -export type PhoneList = { - __typename?: 'PhoneList'; - phones?: Maybe>>; - total?: Maybe; -}; - -export type Preferences = { - __typename?: 'Preferences'; - data?: Maybe; -}; - -export type Query = { - __typename?: 'Query'; - accountGet?: Maybe; - accountGetMfaRecoveryCodes?: Maybe; - accountGetPrefs?: Maybe; - accountGetSession?: Maybe; - accountListIdentities?: Maybe; - accountListLogs?: Maybe; - accountListMfaFactors?: Maybe; - accountListSessions?: Maybe; - databasesGetDocument?: Maybe; - databasesGetTransaction?: Maybe; - databasesListDocuments?: Maybe; - databasesListTransactions?: Maybe; - functionsGetExecution?: Maybe; - functionsListExecutions?: Maybe; - localeGet?: Maybe; - localeListCodes?: Maybe; - localeListContinents?: Maybe; - localeListCountries?: Maybe; - localeListCountriesEU?: Maybe; - localeListCountriesPhones?: Maybe; - localeListCurrencies?: Maybe; - localeListLanguages?: Maybe; - storageGetFile?: Maybe; - storageListFiles?: Maybe; - teamsGet?: Maybe; - teamsGetMembership?: Maybe; - teamsGetPrefs?: Maybe; - teamsList?: Maybe; - teamsListMemberships?: Maybe; -}; - - -export type QueryAccountGetSessionArgs = { - sessionId: Scalars['String']['input']; -}; - - -export type QueryAccountListLogsArgs = { - queries?: InputMaybe>; -}; - - -export type QueryDatabasesGetDocumentArgs = { - collectionId: Scalars['String']['input']; - databaseId: Scalars['String']['input']; - documentId: Scalars['String']['input']; -}; - - -export type QueryDatabasesGetTransactionArgs = { - transactionId: Scalars['String']['input']; -}; - - -export type QueryDatabasesListDocumentsArgs = { - collectionId: Scalars['String']['input']; - databaseId: Scalars['String']['input']; - queries?: InputMaybe>; -}; - - -export type QueryDatabasesListTransactionsArgs = { - queries?: InputMaybe; -}; - - -export type QueryFunctionsGetExecutionArgs = { - executionId: Scalars['String']['input']; - functionId: Scalars['String']['input']; -}; - - -export type QueryFunctionsListExecutionsArgs = { - functionId: Scalars['String']['input']; - queries?: InputMaybe>; -}; - - -export type QueryStorageGetFileArgs = { - bucketId: Scalars['String']['input']; - fileId: Scalars['String']['input']; -}; - - -export type QueryStorageListFilesArgs = { - bucketId: Scalars['String']['input']; - queries?: InputMaybe>; - search?: InputMaybe; -}; - - -export type QueryTeamsGetArgs = { - teamId: Scalars['String']['input']; -}; - - -export type QueryTeamsGetMembershipArgs = { - membershipId: Scalars['String']['input']; - teamId: Scalars['String']['input']; -}; - - -export type QueryTeamsGetPrefsArgs = { - teamId: Scalars['String']['input']; -}; - - -export type QueryTeamsListArgs = { - queries?: InputMaybe>; - search?: InputMaybe; -}; - - -export type QueryTeamsListMembershipsArgs = { - queries?: InputMaybe>; - search?: InputMaybe; - teamId: Scalars['String']['input']; -}; - -export type Session = { - __typename?: 'Session'; - _createdAt?: Maybe; - _id?: Maybe; - clientCode?: Maybe; - clientEngine?: Maybe; - clientEngineVersion?: Maybe; - clientName?: Maybe; - clientType?: Maybe; - clientVersion?: Maybe; - countryCode?: Maybe; - countryName?: Maybe; - current?: Maybe; - deviceBrand?: Maybe; - deviceModel?: Maybe; - deviceName?: Maybe; - expire?: Maybe; - factors?: Maybe>>; - ip?: Maybe; - mfaUpdatedAt?: Maybe; - osCode?: Maybe; - osName?: Maybe; - osVersion?: Maybe; - provider?: Maybe; - providerAccessToken?: Maybe; - providerAccessTokenExpiry?: Maybe; - providerRefreshToken?: Maybe; - providerUid?: Maybe; - secret?: Maybe; - userId?: Maybe; -}; - -export type SessionList = { - __typename?: 'SessionList'; - sessions?: Maybe>>; - total?: Maybe; -}; - -export type Status = { - __typename?: 'Status'; - status?: Maybe; -}; - -export type Target = { - __typename?: 'Target'; - _createdAt?: Maybe; - _id?: Maybe; - _updatedAt?: Maybe; - expired?: Maybe; - identifier?: Maybe; - name?: Maybe; - providerId?: Maybe; - providerType?: Maybe; - userId?: Maybe; -}; - -export type Team = { - __typename?: 'Team'; - _createdAt?: Maybe; - _id?: Maybe; - _updatedAt?: Maybe; - name?: Maybe; - prefs?: Maybe; - total?: Maybe; -}; - -export type TeamList = { - __typename?: 'TeamList'; - teams?: Maybe>>; - total?: Maybe; -}; - -export type Token = { - __typename?: 'Token'; - _createdAt?: Maybe; - _id?: Maybe; - expire?: Maybe; - phrase?: Maybe; - secret?: Maybe; - userId?: Maybe; -}; - -export type Transaction = { - __typename?: 'Transaction'; - _createdAt?: Maybe; - _id?: Maybe; - _updatedAt?: Maybe; - expiresAt?: Maybe; - operations?: Maybe; - status?: Maybe; -}; - -export type TransactionList = { - __typename?: 'TransactionList'; - total?: Maybe; - transactions?: Maybe>>; -}; - -export type User = { - __typename?: 'User'; - _createdAt?: Maybe; - _id?: Maybe; - _updatedAt?: Maybe; - accessedAt?: Maybe; - email?: Maybe; - emailVerification?: Maybe; - labels?: Maybe>>; - mfa?: Maybe; - name?: Maybe; - phone?: Maybe; - phoneVerification?: Maybe; - prefs?: Maybe; - registration?: Maybe; - status?: Maybe; - targets?: Maybe>>; -}; - -export type Account_UserFragment = { __typename?: 'User', _id?: string | null, name?: string | null, email?: string | null, prefs?: { __typename?: 'Preferences', data?: any | null } | null } & { ' $fragmentName'?: 'Account_UserFragment' }; - -export type Identity_ProviderFragment = { __typename?: 'Identity', _id?: string | null, userId?: string | null, provider?: string | null } & { ' $fragmentName'?: 'Identity_ProviderFragment' }; - -export type AccountGetQueryVariables = Exact<{ [key: string]: never; }>; - - -export type AccountGetQuery = { __typename?: 'Query', accountGet?: ( - { __typename?: 'User' } - & { ' $fragmentRefs'?: { 'Account_UserFragment': Account_UserFragment } } - ) | null }; - -export type CreateAnonymousSessionMutationVariables = Exact<{ [key: string]: never; }>; - - -export type CreateAnonymousSessionMutation = { __typename?: 'Mutation', accountCreateAnonymousSession?: { __typename?: 'Session', _id?: string | null, expire?: any | null, current?: boolean | null } | null }; - -export type CreateEmailTokenMutationVariables = Exact<{ - userId: Scalars['String']['input']; - email: Scalars['String']['input']; - phrase?: InputMaybe; -}>; - - -export type CreateEmailTokenMutation = { __typename?: 'Mutation', accountCreateEmailToken?: { __typename?: 'Token', expire?: any | null } | null }; - -export type CreateEmailVerificationMutationVariables = Exact<{ - url: Scalars['String']['input']; -}>; - - -export type CreateEmailVerificationMutation = { __typename?: 'Mutation', accountCreateEmailVerification?: { __typename?: 'Token', _id?: string | null, userId?: string | null, secret?: string | null, expire?: any | null } | null }; - -export type CreateJwtMutationVariables = Exact<{ [key: string]: never; }>; - - -export type CreateJwtMutation = { __typename?: 'Mutation', accountCreateJWT?: { __typename?: 'JWT', jwt?: string | null } | null }; - -export type CreateMagicUrlTokenMutationVariables = Exact<{ - userId: Scalars['String']['input']; - email: Scalars['String']['input']; - url?: InputMaybe; - phrase?: InputMaybe; -}>; - - -export type CreateMagicUrlTokenMutation = { __typename?: 'Mutation', accountCreateMagicURLToken?: { __typename?: 'Token', expire?: any | null } | null }; - -export type CreateMfaAuthenticatorMutationVariables = Exact<{ - type: Scalars['String']['input']; -}>; - - -export type CreateMfaAuthenticatorMutation = { __typename?: 'Mutation', accountCreateMfaAuthenticator?: { __typename?: 'MfaType', secret?: string | null, uri?: string | null } | null }; - -export type CreateMfaChallengeMutationVariables = Exact<{ - factor: Scalars['String']['input']; -}>; - - -export type CreateMfaChallengeMutation = { __typename?: 'Mutation', accountCreateMfaChallenge?: { __typename?: 'MFAChallenge', userId?: string | null, expire?: any | null } | null }; - -export type CreateMfaRecoveryCodesMutationVariables = Exact<{ [key: string]: never; }>; - - -export type CreateMfaRecoveryCodesMutation = { __typename?: 'Mutation', accountCreateMfaRecoveryCodes?: { __typename?: 'MfaRecoveryCodes', recoveryCodes: Array } | null }; - -export type CreatePhoneTokenMutationVariables = Exact<{ - userId: Scalars['String']['input']; - phone: Scalars['String']['input']; -}>; - - -export type CreatePhoneTokenMutation = { __typename?: 'Mutation', accountCreatePhoneToken?: { __typename?: 'Token', expire?: any | null } | null }; - -export type CreatePhoneVerificationMutationVariables = Exact<{ [key: string]: never; }>; - - -export type CreatePhoneVerificationMutation = { __typename?: 'Mutation', accountCreatePhoneVerification?: { __typename?: 'Token', expire?: any | null } | null }; - -export type CreatePushTargetMutationVariables = Exact<{ - targetId: Scalars['String']['input']; - identifier: Scalars['String']['input']; - providerId?: InputMaybe; -}>; - - -export type CreatePushTargetMutation = { __typename?: 'Mutation', accountCreatePushTarget?: { __typename?: 'Target', _id?: string | null, userId?: string | null, providerType?: string | null, identifier?: string | null } | null }; - -export type CreateSessionMutationVariables = Exact<{ - userId: Scalars['String']['input']; - secret: Scalars['String']['input']; -}>; - - -export type CreateSessionMutation = { __typename?: 'Mutation', accountCreateSession?: { __typename?: 'Session', userId?: string | null, expire?: any | null, current?: boolean | null } | null }; - -export type DeleteAccountMutationVariables = Exact<{ [key: string]: never; }>; - - -export type DeleteAccountMutation = { __typename?: 'Mutation', accountDelete?: { __typename?: 'None', status?: boolean | null } | null }; - -export type DeleteIdentityMutationVariables = Exact<{ - identityId: Scalars['String']['input']; -}>; - - -export type DeleteIdentityMutation = { __typename?: 'Mutation', accountDeleteIdentity?: { __typename?: 'Status', status?: boolean | null } | null }; - -export type DeleteMfaAuthenticatorMutationVariables = Exact<{ - type: Scalars['String']['input']; -}>; - - -export type DeleteMfaAuthenticatorMutation = { __typename?: 'Mutation', accountDeleteMfaAuthenticator?: { __typename?: 'None', status?: boolean | null } | null }; - -export type DeletePushTargetMutationVariables = Exact<{ - targetId: Scalars['String']['input']; -}>; - - -export type DeletePushTargetMutation = { __typename?: 'Mutation', accountDeletePushTarget?: { __typename?: 'Status', status?: boolean | null } | null }; - -export type DeleteSessionMutationVariables = Exact<{ - sessionId: Scalars['String']['input']; -}>; - - -export type DeleteSessionMutation = { __typename?: 'Mutation', accountDeleteSession?: { __typename?: 'Status', status?: boolean | null } | null }; - -export type DeleteSessionsMutationVariables = Exact<{ [key: string]: never; }>; - - -export type DeleteSessionsMutation = { __typename?: 'Mutation', accountDeleteSessions?: { __typename?: 'Status', status?: boolean | null } | null }; - -export type GetMfaRecoveryCodesQueryVariables = Exact<{ [key: string]: never; }>; - - -export type GetMfaRecoveryCodesQuery = { __typename?: 'Query', accountGetMfaRecoveryCodes?: { __typename?: 'MfaRecoveryCodes', recoveryCodes: Array } | null }; - -export type GetPrefsQueryVariables = Exact<{ [key: string]: never; }>; - - -export type GetPrefsQuery = { __typename?: 'Query', accountGetPrefs?: { __typename?: 'Preferences', data?: any | null } | null }; - -export type GetSessionQueryVariables = Exact<{ - sessionId: Scalars['String']['input']; -}>; - - -export type GetSessionQuery = { __typename?: 'Query', accountGetSession?: { __typename?: 'Session', userId?: string | null, expire?: any | null, current?: boolean | null } | null }; - -export type ListIdentitiesQueryVariables = Exact<{ [key: string]: never; }>; - - -export type ListIdentitiesQuery = { __typename?: 'Query', accountListIdentities?: { __typename?: 'IdentityList', total: number, identities?: Array<( - { __typename?: 'Identity' } - & { ' $fragmentRefs'?: { 'Identity_ProviderFragment': Identity_ProviderFragment } } - )> | null } | null }; - -export type ListMfaFactorsQueryVariables = Exact<{ [key: string]: never; }>; - - -export type ListMfaFactorsQuery = { __typename?: 'Query', accountListMfaFactors?: { __typename?: 'MfaFactors', totp?: boolean | null, phone?: boolean | null, email?: boolean | null } | null }; - -export type ListSessionsQueryVariables = Exact<{ [key: string]: never; }>; - - -export type ListSessionsQuery = { __typename?: 'Query', accountListSessions?: { __typename?: 'SessionList', sessions?: Array<{ __typename?: 'Session', _id?: string | null, _createdAt?: any | null, osName?: string | null, clientName?: string | null } | null> | null } | null }; - -export type CreateEmailPasswordSessionMutationVariables = Exact<{ - email: Scalars['String']['input']; - password: Scalars['String']['input']; -}>; - - -export type CreateEmailPasswordSessionMutation = { __typename?: 'Mutation', accountCreateEmailPasswordSession?: { __typename?: 'Session', userId?: string | null, expire?: any | null, current?: boolean | null } | null }; - -export type ListLogsQueryVariables = Exact<{ - queries?: InputMaybe | Scalars['String']['input']>; -}>; - - -export type ListLogsQuery = { __typename?: 'Query', accountListLogs?: { __typename?: 'LogsList', total: number, logs?: Array<{ __typename?: 'Log', event?: string | null, userId?: string | null, userEmail?: string | null, userName?: string | null, mode?: string | null, ip?: string | null, time?: string | null, osCode?: string | null, osName?: string | null, osVersion?: string | null, clientType?: string | null, clientCode?: string | null, clientName?: string | null, clientVersion?: string | null, clientEngine?: string | null, clientEngineVersion?: string | null, deviceName?: string | null, deviceBrand?: string | null, deviceModel?: string | null, countryCode?: string | null, countryName?: string | null }> | null } | null }; - -export type CreateRecoveryMutationVariables = Exact<{ - email: Scalars['String']['input']; - url: Scalars['String']['input']; -}>; - - -export type CreateRecoveryMutation = { __typename?: 'Mutation', accountCreateRecovery?: { __typename?: 'Token', expire?: any | null } | null }; - -export type UpdateRecoveryMutationVariables = Exact<{ - userId: Scalars['String']['input']; - secret: Scalars['String']['input']; - password: Scalars['String']['input']; -}>; - - -export type UpdateRecoveryMutation = { __typename?: 'Mutation', accountUpdateRecovery?: { __typename?: 'Token', expire?: any | null } | null }; - -export type CreateAccountMutationVariables = Exact<{ - userId: Scalars['String']['input']; - name?: InputMaybe; - email: Scalars['String']['input']; - password: Scalars['String']['input']; -}>; - - -export type CreateAccountMutation = { __typename?: 'Mutation', accountCreate?: { __typename?: 'User', name?: string | null, email?: string | null } | null }; - -export type VerifyEmailMutationVariables = Exact<{ - url: Scalars['String']['input']; -}>; - - -export type VerifyEmailMutation = { __typename?: 'Mutation', accountCreateVerification?: { __typename?: 'Token', expire?: any | null } | null }; - -export type UpdateEmailMutationVariables = Exact<{ - email: Scalars['String']['input']; - password: Scalars['String']['input']; -}>; - - -export type UpdateEmailMutation = { __typename?: 'Mutation', accountUpdateEmail?: { __typename?: 'User', name?: string | null, email?: string | null } | null }; - -export type UpdateEmailVerificationMutationVariables = Exact<{ - userId: Scalars['String']['input']; - secret: Scalars['String']['input']; -}>; - - -export type UpdateEmailVerificationMutation = { __typename?: 'Mutation', accountUpdateEmailVerification?: { __typename?: 'Token', _id?: string | null, userId?: string | null, secret?: string | null, expire?: any | null } | null }; - -export type UpdateMagicUrlSessionMutationVariables = Exact<{ - userId: Scalars['String']['input']; - secret: Scalars['String']['input']; -}>; - - -export type UpdateMagicUrlSessionMutation = { __typename?: 'Mutation', accountUpdateMagicURLSession?: { __typename?: 'Session', userId?: string | null, expire?: any | null, current?: boolean | null } | null }; - -export type UpdateMfaMutationVariables = Exact<{ - mfa: Scalars['Boolean']['input']; -}>; - - -export type UpdateMfaMutation = { __typename?: 'Mutation', accountUpdateMFA?: { __typename?: 'User', mfa?: boolean | null } | null }; - -export type UpdateMfaAuthenticatorMutationVariables = Exact<{ - type: Scalars['String']['input']; - otp: Scalars['String']['input']; -}>; - - -export type UpdateMfaAuthenticatorMutation = { __typename?: 'Mutation', accountUpdateMfaAuthenticator?: { __typename?: 'User', mfa?: boolean | null } | null }; - -export type UpdateMfaChallengeMutationVariables = Exact<{ - challengeId: Scalars['String']['input']; - otp: Scalars['String']['input']; -}>; - - -export type UpdateMfaChallengeMutation = { __typename?: 'Mutation', accountUpdateMfaChallenge?: { __typename?: 'Status', status?: boolean | null } | null }; - -export type UpdateMfaRecoveryCodesMutationVariables = Exact<{ [key: string]: never; }>; - - -export type UpdateMfaRecoveryCodesMutation = { __typename?: 'Mutation', accountUpdateMfaRecoveryCodes?: { __typename?: 'MfaRecoveryCodes', recoveryCodes: Array } | null }; - -export type UpdateNameMutationVariables = Exact<{ - name: Scalars['String']['input']; -}>; - - -export type UpdateNameMutation = { __typename?: 'Mutation', accountUpdateName?: { __typename?: 'User', name?: string | null } | null }; - -export type UpdatePasswordMutationVariables = Exact<{ - password: Scalars['String']['input']; - oldPassword: Scalars['String']['input']; -}>; - - -export type UpdatePasswordMutation = { __typename?: 'Mutation', accountUpdatePassword?: { __typename?: 'User', status?: string | null } | null }; - -export type UpdatePhoneMutationVariables = Exact<{ - phone: Scalars['String']['input']; - password: Scalars['String']['input']; -}>; - - -export type UpdatePhoneMutation = { __typename?: 'Mutation', accountUpdatePhone?: { __typename?: 'User', phone?: string | null } | null }; - -export type UpdatePhoneSessionMutationVariables = Exact<{ - userId: Scalars['String']['input']; - secret: Scalars['String']['input']; -}>; - - -export type UpdatePhoneSessionMutation = { __typename?: 'Mutation', accountUpdatePhoneSession?: { __typename?: 'Session', userId?: string | null, expire?: any | null, current?: boolean | null } | null }; - -export type UpdatePhoneVerificationMutationVariables = Exact<{ - userId: Scalars['String']['input']; - secret: Scalars['String']['input']; -}>; - - -export type UpdatePhoneVerificationMutation = { __typename?: 'Mutation', accountUpdatePhoneVerification?: { __typename?: 'Token', expire?: any | null } | null }; - -export type UpdatePrefsMutationVariables = Exact<{ - prefs: Scalars['Assoc']['input']; -}>; - - -export type UpdatePrefsMutation = { __typename?: 'Mutation', accountUpdatePrefs?: { __typename?: 'User', prefs?: { __typename?: 'Preferences', data?: any | null } | null } | null }; - -export type UpdatePushTargetMutationVariables = Exact<{ - targetId: Scalars['String']['input']; - identifier: Scalars['String']['input']; -}>; - - -export type UpdatePushTargetMutation = { __typename?: 'Mutation', accountUpdatePushTarget?: { __typename?: 'Target', _id?: string | null, userId?: string | null, providerType?: string | null, identifier?: string | null } | null }; - -export type UpdateSessionMutationVariables = Exact<{ - sessionId: Scalars['String']['input']; -}>; - - -export type UpdateSessionMutation = { __typename?: 'Mutation', accountUpdateSession?: { __typename?: 'Session', userId?: string | null, expire?: any | null, current?: boolean | null } | null }; - -export type UpdateStatusMutationVariables = Exact<{ [key: string]: never; }>; - - -export type UpdateStatusMutation = { __typename?: 'Mutation', accountUpdateStatus?: { __typename?: 'User', _id?: string | null, status?: string | null } | null }; - -export type UpdateVerificationMutationVariables = Exact<{ - userId: Scalars['String']['input']; - secret: Scalars['String']['input']; -}>; - - -export type UpdateVerificationMutation = { __typename?: 'Mutation', accountUpdateVerification?: { __typename?: 'Token', secret?: string | null, expire?: any | null, userId?: string | null } | null }; - -export type ListDocumentsQueryVariables = Exact<{ - databaseId: Scalars['String']['input']; - collectionId: Scalars['String']['input']; - queries?: InputMaybe | Scalars['String']['input']>; -}>; - - -export type ListDocumentsQuery = { __typename?: 'Query', databasesListDocuments?: { __typename?: 'DocumentList', total?: number | null, documents?: Array<{ __typename?: 'Document', _id?: string | null, data?: any | null } | null> | null } | null }; - -export type CreateDocumentMutationVariables = Exact<{ - databaseId: Scalars['String']['input']; - collectionId: Scalars['String']['input']; - documentId: Scalars['String']['input']; - data: Scalars['Json']['input']; - permissions?: InputMaybe | Scalars['String']['input']>; -}>; - - -export type CreateDocumentMutation = { __typename?: 'Mutation', databasesCreateDocument?: { __typename?: 'Document', _id?: string | null } | null }; - -export type CreateDocumentsMutationVariables = Exact<{ - databaseId: Scalars['String']['input']; - collectionId: Scalars['String']['input']; - documents: Array | Scalars['Json']['input']; -}>; - - -export type CreateDocumentsMutation = { __typename?: 'Mutation', databasesCreateDocuments?: { __typename?: 'DocumentList', total?: number | null, documents?: Array<{ __typename?: 'Document', _id?: string | null } | null> | null } | null }; - -export type CreateOperationsMutationVariables = Exact<{ - transactionId: Scalars['String']['input']; - operations?: InputMaybe | Scalars['String']['input']>; -}>; - - -export type CreateOperationsMutation = { __typename?: 'Mutation', databasesCreateOperations?: { __typename?: 'Transaction', _id?: string | null, status?: string | null, operations?: number | null, expiresAt?: string | null } | null }; - -export type CreateTransactionMutationVariables = Exact<{ - ttl?: InputMaybe; -}>; - - -export type CreateTransactionMutation = { __typename?: 'Mutation', databasesCreateTransaction?: { __typename?: 'Transaction', _id?: string | null, status?: string | null, operations?: number | null, expiresAt?: string | null } | null }; - -export type DecrementDocumentAttributeMutationVariables = Exact<{ - databaseId: Scalars['String']['input']; - collectionId: Scalars['String']['input']; - documentId: Scalars['String']['input']; - attribute: Scalars['String']['input']; - value?: InputMaybe; - min?: InputMaybe; -}>; - - -export type DecrementDocumentAttributeMutation = { __typename?: 'Mutation', databasesDecrementDocumentAttribute?: { __typename?: 'Document', _id?: string | null, data?: any | null } | null }; - -export type DeleteDocumentMutationVariables = Exact<{ - databaseId: Scalars['String']['input']; - collectionId: Scalars['String']['input']; - documentId: Scalars['String']['input']; -}>; - - -export type DeleteDocumentMutation = { __typename?: 'Mutation', databasesDeleteDocument?: { __typename?: 'Status', status?: boolean | null } | null }; - -export type DeleteDocumentsMutationVariables = Exact<{ - databaseId: Scalars['String']['input']; - collectionId: Scalars['String']['input']; - queries?: InputMaybe | Scalars['String']['input']>; -}>; - - -export type DeleteDocumentsMutation = { __typename?: 'Mutation', databasesDeleteDocuments?: { __typename?: 'DocumentList', total?: number | null, documents?: Array<{ __typename?: 'Document', _id?: string | null } | null> | null } | null }; - -export type DeleteTransactionMutationVariables = Exact<{ - transactionId: Scalars['String']['input']; -}>; - - -export type DeleteTransactionMutation = { __typename?: 'Mutation', databasesDeleteTransaction?: { __typename?: 'None', status?: boolean | null } | null }; - -export type GetDocumentQueryVariables = Exact<{ - databaseId: Scalars['String']['input']; - collectionId: Scalars['String']['input']; - documentId: Scalars['String']['input']; -}>; - - -export type GetDocumentQuery = { __typename?: 'Query', databasesGetDocument?: { __typename?: 'Document', _id?: string | null, data?: any | null } | null }; - -export type GetTransactionQueryVariables = Exact<{ - transactionId: Scalars['String']['input']; -}>; - - -export type GetTransactionQuery = { __typename?: 'Query', databasesGetTransaction?: { __typename?: 'Transaction', _id?: string | null, _createdAt?: string | null, _updatedAt?: string | null, status?: string | null, operations?: number | null, expiresAt?: string | null } | null }; - -export type IncrementDocumentAttributeMutationVariables = Exact<{ - databaseId: Scalars['String']['input']; - collectionId: Scalars['String']['input']; - documentId: Scalars['String']['input']; - attribute: Scalars['String']['input']; - value?: InputMaybe; - max?: InputMaybe; -}>; - - -export type IncrementDocumentAttributeMutation = { __typename?: 'Mutation', databasesIncrementDocumentAttribute?: { __typename?: 'Document', _id?: string | null, data?: any | null } | null }; - -export type ListTransactionsQueryVariables = Exact<{ - queries?: InputMaybe; -}>; - - -export type ListTransactionsQuery = { __typename?: 'Query', databasesListTransactions?: { __typename?: 'TransactionList', total?: number | null, transactions?: Array<{ __typename?: 'Transaction', _id?: string | null, _createdAt?: string | null, _updatedAt?: string | null, status?: string | null, operations?: number | null, expiresAt?: string | null } | null> | null } | null }; - -export type UpdateDocumentMutationVariables = Exact<{ - databaseId: Scalars['String']['input']; - collectionId: Scalars['String']['input']; - documentId: Scalars['String']['input']; - data?: InputMaybe; - permissions?: InputMaybe | Scalars['String']['input']>; -}>; - - -export type UpdateDocumentMutation = { __typename?: 'Mutation', databasesUpdateDocument?: { __typename?: 'Document', _id?: string | null } | null }; - -export type UpdateDocumentsMutationVariables = Exact<{ - databaseId: Scalars['String']['input']; - collectionId: Scalars['String']['input']; - data?: InputMaybe; - queries?: InputMaybe | Scalars['String']['input']>; -}>; - - -export type UpdateDocumentsMutation = { __typename?: 'Mutation', databasesUpdateDocuments?: { __typename?: 'DocumentList', total?: number | null, documents?: Array<{ __typename?: 'Document', _id?: string | null } | null> | null } | null }; - -export type UpdateTransactionMutationVariables = Exact<{ - transactionId: Scalars['String']['input']; - commit?: InputMaybe; - rollback?: InputMaybe; -}>; - - -export type UpdateTransactionMutation = { __typename?: 'Mutation', databasesUpdateTransaction?: { __typename?: 'Transaction', _id?: string | null, status?: string | null, operations?: number | null } | null }; - -export type UpsertDocumentMutationVariables = Exact<{ - databaseId: Scalars['String']['input']; - collectionId: Scalars['String']['input']; - documentId: Scalars['String']['input']; - data: Scalars['Json']['input']; - permissions?: InputMaybe | Scalars['String']['input']>; -}>; - - -export type UpsertDocumentMutation = { __typename?: 'Mutation', databasesUpsertDocument?: { __typename?: 'Document', _id?: string | null } | null }; - -export type UpsertDocumentsMutationVariables = Exact<{ - databaseId: Scalars['String']['input']; - collectionId: Scalars['String']['input']; - documents: Array | Scalars['Json']['input']; -}>; - - -export type UpsertDocumentsMutation = { __typename?: 'Mutation', databasesUpsertDocuments?: { __typename?: 'DocumentList', total?: number | null, documents?: Array<{ __typename?: 'Document', _id?: string | null } | null> | null } | null }; - -export type CreateExecutionMutationVariables = Exact<{ - functionId: Scalars['String']['input']; - body?: InputMaybe; - async?: InputMaybe; - path?: InputMaybe; - method?: InputMaybe; -}>; - - -export type CreateExecutionMutation = { __typename?: 'Mutation', functionsCreateExecution?: { __typename?: 'Execution', _id?: string | null, status?: string | null, responseStatusCode?: number | null, responseBody?: string | null, errors?: string | null, duration?: number | null } | null }; - -export type GetFunctionExecutionQueryVariables = Exact<{ - functionId: Scalars['String']['input']; - executionId: Scalars['String']['input']; -}>; - - -export type GetFunctionExecutionQuery = { __typename?: 'Query', functionsGetExecution?: { __typename?: 'Execution', status?: string | null, errors?: string | null, duration?: number | null, responseBody?: string | null, requestPath?: string | null } | null }; - -export type GetExecutionQueryVariables = Exact<{ - functionId: Scalars['String']['input']; - executionId: Scalars['String']['input']; -}>; - - -export type GetExecutionQuery = { __typename?: 'Query', functionsGetExecution?: { __typename?: 'Execution', _id?: string | null, _createdAt?: string | null, _updatedAt?: string | null, functionId?: string | null, trigger?: string | null, status?: string | null, requestMethod?: string | null, requestPath?: string | null, responseStatusCode?: number | null, responseBody?: string | null, errors?: string | null, duration?: number | null } | null }; - -export type ListExecutionsQueryVariables = Exact<{ - functionId: Scalars['String']['input']; - queries?: InputMaybe | Scalars['String']['input']>; -}>; - - -export type ListExecutionsQuery = { __typename?: 'Query', functionsListExecutions?: { __typename?: 'ExecutionList', total?: number | null, executions?: Array<{ __typename?: 'Execution', _id?: string | null, _createdAt?: string | null, _updatedAt?: string | null, functionId?: string | null, trigger?: string | null, status?: string | null, requestMethod?: string | null, requestPath?: string | null, responseStatusCode?: number | null, responseBody?: string | null, errors?: string | null, duration?: number | null } | null> | null } | null }; - -export type GetLocaleQueryVariables = Exact<{ [key: string]: never; }>; - - -export type GetLocaleQuery = { __typename?: 'Query', localeGet?: { __typename?: 'Locale', ip?: string | null, countryCode?: string | null, country?: string | null, continentCode?: string | null, continent?: string | null, eu?: boolean | null, currency?: string | null } | null }; - -export type ListLocaleCodesQueryVariables = Exact<{ [key: string]: never; }>; - - -export type ListLocaleCodesQuery = { __typename?: 'Query', localeListCodes?: { __typename?: 'LocaleCodeList', total?: number | null, localeCodes?: Array<{ __typename?: 'LocaleCode', code?: string | null, name?: string | null } | null> | null } | null }; - -export type ListContinentsQueryVariables = Exact<{ [key: string]: never; }>; - - -export type ListContinentsQuery = { __typename?: 'Query', localeListContinents?: { __typename?: 'ContinentList', total?: number | null, continents?: Array<{ __typename?: 'Continent', name?: string | null, code?: string | null } | null> | null } | null }; - -export type ListCountriesQueryVariables = Exact<{ [key: string]: never; }>; - - -export type ListCountriesQuery = { __typename?: 'Query', localeListCountries?: { __typename?: 'CountryList', total?: number | null, countries?: Array<{ __typename?: 'Country', name?: string | null, code?: string | null } | null> | null } | null }; - -export type ListCountriesEuQueryVariables = Exact<{ [key: string]: never; }>; - - -export type ListCountriesEuQuery = { __typename?: 'Query', localeListCountriesEU?: { __typename?: 'CountryList', total?: number | null, countries?: Array<{ __typename?: 'Country', name?: string | null, code?: string | null } | null> | null } | null }; - -export type ListCountriesPhonesQueryVariables = Exact<{ [key: string]: never; }>; - - -export type ListCountriesPhonesQuery = { __typename?: 'Query', localeListCountriesPhones?: { __typename?: 'PhoneList', total?: number | null, phones?: Array<{ __typename?: 'Phone', code?: string | null, countryCode?: string | null, countryName?: string | null } | null> | null } | null }; - -export type ListCurrenciesQueryVariables = Exact<{ [key: string]: never; }>; - - -export type ListCurrenciesQuery = { __typename?: 'Query', localeListCurrencies?: { __typename?: 'CurrencyList', total?: number | null, currencies?: Array<{ __typename?: 'Currency', symbol?: string | null, name?: string | null, symbolNative?: string | null, decimalDigits?: number | null, rounding?: number | null, code?: string | null, namePlural?: string | null } | null> | null } | null }; - -export type ListLanguagesQueryVariables = Exact<{ [key: string]: never; }>; - - -export type ListLanguagesQuery = { __typename?: 'Query', localeListLanguages?: { __typename?: 'LanguageList', total?: number | null, languages?: Array<{ __typename?: 'Language', name?: string | null, code?: string | null, nativeName?: string | null } | null> | null } | null }; - -export type CreateFileMutationVariables = Exact<{ - bucketId: Scalars['String']['input']; - fileId: Scalars['String']['input']; - file: Scalars['String']['input']; - permissions?: InputMaybe | Scalars['String']['input']>; -}>; - - -export type CreateFileMutation = { __typename?: 'Mutation', storageCreateFile?: { __typename?: 'File', _id?: string | null, bucketId?: string | null, name?: string | null, mimeType?: string | null, sizeOriginal?: number | null } | null }; - -export type DeleteFileMutationVariables = Exact<{ - bucketId: Scalars['String']['input']; - fileId: Scalars['String']['input']; -}>; - - -export type DeleteFileMutation = { __typename?: 'Mutation', storageDeleteFile?: { __typename?: 'None', status?: boolean | null } | null }; - -export type GetFileQueryVariables = Exact<{ - bucketId: Scalars['String']['input']; - fileId: Scalars['String']['input']; -}>; - - -export type GetFileQuery = { __typename?: 'Query', storageGetFile?: { __typename?: 'File', _id?: string | null, bucketId?: string | null, _createdAt?: string | null, _updatedAt?: string | null, _permissions?: Array | null, name?: string | null, signature?: string | null, mimeType?: string | null, sizeOriginal?: number | null, chunksTotal?: number | null, chunksUploaded?: number | null } | null }; - -export type ListFilesQueryVariables = Exact<{ - bucketId: Scalars['String']['input']; - queries?: InputMaybe | Scalars['String']['input']>; - search?: InputMaybe; -}>; - - -export type ListFilesQuery = { __typename?: 'Query', storageListFiles?: { __typename?: 'FileList', total?: number | null, files?: Array<{ __typename?: 'File', _id?: string | null, bucketId?: string | null, _createdAt?: string | null, _updatedAt?: string | null, _permissions?: Array | null, name?: string | null, signature?: string | null, mimeType?: string | null, sizeOriginal?: number | null, chunksTotal?: number | null, chunksUploaded?: number | null } | null> | null } | null }; - -export type UpdateFileMutationVariables = Exact<{ - bucketId: Scalars['String']['input']; - fileId: Scalars['String']['input']; - name?: InputMaybe; - permissions?: InputMaybe | Scalars['String']['input']>; -}>; - - -export type UpdateFileMutation = { __typename?: 'Mutation', storageUpdateFile?: { __typename?: 'File', _id?: string | null, bucketId?: string | null, name?: string | null, _permissions?: Array | null } | null }; - -export type CreateMembershipMutationVariables = Exact<{ - teamId: Scalars['String']['input']; - roles: Array | Scalars['String']['input']; - email?: InputMaybe; - userId?: InputMaybe; - phone?: InputMaybe; - url?: InputMaybe; - name?: InputMaybe; -}>; - - -export type CreateMembershipMutation = { __typename?: 'Mutation', teamsCreateMembership?: { __typename?: 'Membership', _id?: string | null, userId?: string | null, teamId?: string | null, roles?: Array | null, confirm?: boolean | null } | null }; - -export type CreateTeamMutationVariables = Exact<{ - teamId: Scalars['String']['input']; - name: Scalars['String']['input']; - roles?: InputMaybe | Scalars['String']['input']>; -}>; - - -export type CreateTeamMutation = { __typename?: 'Mutation', teamsCreate?: { __typename?: 'Team', _id?: string | null, name?: string | null, total?: number | null } | null }; - -export type DeleteMembershipMutationVariables = Exact<{ - teamId: Scalars['String']['input']; - membershipId: Scalars['String']['input']; -}>; - - -export type DeleteMembershipMutation = { __typename?: 'Mutation', teamsDeleteMembership?: { __typename?: 'None', status?: boolean | null } | null }; - -export type DeleteTeamMutationVariables = Exact<{ - teamId: Scalars['String']['input']; -}>; - - -export type DeleteTeamMutation = { __typename?: 'Mutation', teamsDelete?: { __typename?: 'None', status?: boolean | null } | null }; - -export type GetTeamQueryVariables = Exact<{ - teamId: Scalars['String']['input']; -}>; - - -export type GetTeamQuery = { __typename?: 'Query', teamsGet?: { __typename?: 'Team', _id?: string | null, _createdAt?: string | null, _updatedAt?: string | null, name?: string | null, total?: number | null, prefs?: { __typename?: 'Preferences', data?: any | null } | null } | null }; - -export type GetMembershipQueryVariables = Exact<{ - teamId: Scalars['String']['input']; - membershipId: Scalars['String']['input']; -}>; - - -export type GetMembershipQuery = { __typename?: 'Query', teamsGetMembership?: { __typename?: 'Membership', _id?: string | null, _createdAt?: string | null, _updatedAt?: string | null, userId?: string | null, userName?: string | null, userEmail?: string | null, teamId?: string | null, teamName?: string | null, invited?: string | null, joined?: string | null, confirm?: boolean | null, mfa?: boolean | null, roles?: Array | null } | null }; - -export type ListMembershipsQueryVariables = Exact<{ - teamId: Scalars['String']['input']; - queries?: InputMaybe | Scalars['String']['input']>; - search?: InputMaybe; -}>; - - -export type ListMembershipsQuery = { __typename?: 'Query', teamsListMemberships?: { __typename?: 'MembershipList', total?: number | null, memberships?: Array<{ __typename?: 'Membership', _id?: string | null, _createdAt?: string | null, _updatedAt?: string | null, userId?: string | null, userName?: string | null, userEmail?: string | null, teamId?: string | null, teamName?: string | null, invited?: string | null, joined?: string | null, confirm?: boolean | null, mfa?: boolean | null, roles?: Array | null } | null> | null } | null }; - -export type GetTeamPrefsQueryVariables = Exact<{ - teamId: Scalars['String']['input']; -}>; - - -export type GetTeamPrefsQuery = { __typename?: 'Query', teamsGetPrefs?: { __typename?: 'Preferences', data?: any | null } | null }; - -export type ListTeamsQueryVariables = Exact<{ - queries?: InputMaybe | Scalars['String']['input']>; - search?: InputMaybe; -}>; - - -export type ListTeamsQuery = { __typename?: 'Query', teamsList?: { __typename?: 'TeamList', total?: number | null, teams?: Array<{ __typename?: 'Team', _id?: string | null, _createdAt?: string | null, _updatedAt?: string | null, name?: string | null, total?: number | null, prefs?: { __typename?: 'Preferences', data?: any | null } | null } | null> | null } | null }; - -export type UpdateMembershipMutationVariables = Exact<{ - teamId: Scalars['String']['input']; - membershipId: Scalars['String']['input']; - roles: Array | Scalars['String']['input']; -}>; - - -export type UpdateMembershipMutation = { __typename?: 'Mutation', teamsUpdateMembership?: { __typename?: 'Membership', _id?: string | null, roles?: Array | null } | null }; - -export type UpdateMembershipStatusMutationVariables = Exact<{ - teamId: Scalars['String']['input']; - membershipId: Scalars['String']['input']; - userId: Scalars['String']['input']; - secret: Scalars['String']['input']; -}>; - - -export type UpdateMembershipStatusMutation = { __typename?: 'Mutation', teamsUpdateMembershipStatus?: { __typename?: 'Membership', _id?: string | null, confirm?: boolean | null } | null }; - -export type UpdateTeamNameMutationVariables = Exact<{ - teamId: Scalars['String']['input']; - name: Scalars['String']['input']; -}>; - - -export type UpdateTeamNameMutation = { __typename?: 'Mutation', teamsUpdateName?: { __typename?: 'Team', _id?: string | null, name?: string | null } | null }; - -export type UpdateTeamPrefsMutationVariables = Exact<{ - teamId: Scalars['String']['input']; - prefs: Scalars['Assoc']['input']; -}>; - - -export type UpdateTeamPrefsMutation = { __typename?: 'Mutation', teamsUpdatePrefs?: { __typename?: 'Preferences', data?: any | null } | null }; - -export const Account_UserFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Account_User"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"prefs"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"}}]}}]}}]} as unknown as DocumentNode; -export const Identity_ProviderFragmentDoc = {"kind":"Document","definitions":[{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Identity_Provider"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Identity"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"userId"}},{"kind":"Field","name":{"kind":"Name","value":"provider"}}]}}]} as unknown as DocumentNode; -export const AccountGetDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"AccountGet"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountGet"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Account_User"}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Account_User"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"User"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"email"}},{"kind":"Field","name":{"kind":"Name","value":"prefs"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"}}]}}]}}]} as unknown as DocumentNode; -export const CreateAnonymousSessionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateAnonymousSession"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountCreateAnonymousSession"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"expire"}},{"kind":"Field","name":{"kind":"Name","value":"current"}}]}}]}}]} as unknown as DocumentNode; -export const CreateEmailTokenDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateEmailToken"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"userId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"email"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"phrase"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountCreateEmailToken"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"userId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"userId"}}},{"kind":"Argument","name":{"kind":"Name","value":"email"},"value":{"kind":"Variable","name":{"kind":"Name","value":"email"}}},{"kind":"Argument","name":{"kind":"Name","value":"phrase"},"value":{"kind":"Variable","name":{"kind":"Name","value":"phrase"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"expire"}}]}}]}}]} as unknown as DocumentNode; -export const CreateEmailVerificationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateEmailVerification"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"url"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountCreateEmailVerification"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"url"},"value":{"kind":"Variable","name":{"kind":"Name","value":"url"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"userId"}},{"kind":"Field","name":{"kind":"Name","value":"secret"}},{"kind":"Field","name":{"kind":"Name","value":"expire"}}]}}]}}]} as unknown as DocumentNode; -export const CreateJwtDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateJWT"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountCreateJWT"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"jwt"}}]}}]}}]} as unknown as DocumentNode; -export const CreateMagicUrlTokenDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateMagicURLToken"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"userId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"email"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"url"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"phrase"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountCreateMagicURLToken"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"userId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"userId"}}},{"kind":"Argument","name":{"kind":"Name","value":"email"},"value":{"kind":"Variable","name":{"kind":"Name","value":"email"}}},{"kind":"Argument","name":{"kind":"Name","value":"url"},"value":{"kind":"Variable","name":{"kind":"Name","value":"url"}}},{"kind":"Argument","name":{"kind":"Name","value":"phrase"},"value":{"kind":"Variable","name":{"kind":"Name","value":"phrase"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"expire"}}]}}]}}]} as unknown as DocumentNode; -export const CreateMfaAuthenticatorDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateMfaAuthenticator"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"type"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountCreateMfaAuthenticator"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"type"},"value":{"kind":"Variable","name":{"kind":"Name","value":"type"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"secret"}},{"kind":"Field","name":{"kind":"Name","value":"uri"}}]}}]}}]} as unknown as DocumentNode; -export const CreateMfaChallengeDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateMfaChallenge"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"factor"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountCreateMfaChallenge"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"factor"},"value":{"kind":"Variable","name":{"kind":"Name","value":"factor"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userId"}},{"kind":"Field","name":{"kind":"Name","value":"expire"}}]}}]}}]} as unknown as DocumentNode; -export const CreateMfaRecoveryCodesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateMfaRecoveryCodes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountCreateMfaRecoveryCodes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"recoveryCodes"}}]}}]}}]} as unknown as DocumentNode; -export const CreatePhoneTokenDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreatePhoneToken"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"userId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"phone"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountCreatePhoneToken"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"userId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"userId"}}},{"kind":"Argument","name":{"kind":"Name","value":"phone"},"value":{"kind":"Variable","name":{"kind":"Name","value":"phone"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"expire"}}]}}]}}]} as unknown as DocumentNode; -export const CreatePhoneVerificationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreatePhoneVerification"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountCreatePhoneVerification"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"expire"}}]}}]}}]} as unknown as DocumentNode; -export const CreatePushTargetDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreatePushTarget"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"targetId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"identifier"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"providerId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountCreatePushTarget"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"targetId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetId"}}},{"kind":"Argument","name":{"kind":"Name","value":"identifier"},"value":{"kind":"Variable","name":{"kind":"Name","value":"identifier"}}},{"kind":"Argument","name":{"kind":"Name","value":"providerId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"providerId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"userId"}},{"kind":"Field","name":{"kind":"Name","value":"providerType"}},{"kind":"Field","name":{"kind":"Name","value":"identifier"}}]}}]}}]} as unknown as DocumentNode; -export const CreateSessionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateSession"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"userId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"secret"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountCreateSession"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"userId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"userId"}}},{"kind":"Argument","name":{"kind":"Name","value":"secret"},"value":{"kind":"Variable","name":{"kind":"Name","value":"secret"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userId"}},{"kind":"Field","name":{"kind":"Name","value":"expire"}},{"kind":"Field","name":{"kind":"Name","value":"current"}}]}}]}}]} as unknown as DocumentNode; -export const DeleteAccountDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteAccount"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountDelete"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}}]} as unknown as DocumentNode; -export const DeleteIdentityDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteIdentity"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"identityId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountDeleteIdentity"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"identityId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"identityId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}}]} as unknown as DocumentNode; -export const DeleteMfaAuthenticatorDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteMfaAuthenticator"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"type"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountDeleteMfaAuthenticator"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"type"},"value":{"kind":"Variable","name":{"kind":"Name","value":"type"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}}]} as unknown as DocumentNode; -export const DeletePushTargetDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeletePushTarget"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"targetId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountDeletePushTarget"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"targetId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}}]} as unknown as DocumentNode; -export const DeleteSessionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteSession"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountDeleteSession"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"sessionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sessionId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}}]} as unknown as DocumentNode; -export const DeleteSessionsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteSessions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountDeleteSessions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}}]} as unknown as DocumentNode; -export const GetMfaRecoveryCodesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetMfaRecoveryCodes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountGetMfaRecoveryCodes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"recoveryCodes"}}]}}]}}]} as unknown as DocumentNode; -export const GetPrefsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetPrefs"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountGetPrefs"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"}}]}}]}}]} as unknown as DocumentNode; -export const GetSessionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetSession"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountGetSession"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"sessionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sessionId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userId"}},{"kind":"Field","name":{"kind":"Name","value":"expire"}},{"kind":"Field","name":{"kind":"Name","value":"current"}}]}}]}}]} as unknown as DocumentNode; -export const ListIdentitiesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ListIdentities"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountListIdentities"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"identities"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"FragmentSpread","name":{"kind":"Name","value":"Identity_Provider"}}]}}]}}]}},{"kind":"FragmentDefinition","name":{"kind":"Name","value":"Identity_Provider"},"typeCondition":{"kind":"NamedType","name":{"kind":"Name","value":"Identity"}},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"userId"}},{"kind":"Field","name":{"kind":"Name","value":"provider"}}]}}]} as unknown as DocumentNode; -export const ListMfaFactorsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ListMfaFactors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountListMfaFactors"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"totp"}},{"kind":"Field","name":{"kind":"Name","value":"phone"}},{"kind":"Field","name":{"kind":"Name","value":"email"}}]}}]}}]} as unknown as DocumentNode; -export const ListSessionsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ListSessions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountListSessions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"sessions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"osName"}},{"kind":"Field","name":{"kind":"Name","value":"clientName"}}]}}]}}]}}]} as unknown as DocumentNode; -export const CreateEmailPasswordSessionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateEmailPasswordSession"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"email"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"password"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountCreateEmailPasswordSession"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"email"},"value":{"kind":"Variable","name":{"kind":"Name","value":"email"}}},{"kind":"Argument","name":{"kind":"Name","value":"password"},"value":{"kind":"Variable","name":{"kind":"Name","value":"password"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userId"}},{"kind":"Field","name":{"kind":"Name","value":"expire"}},{"kind":"Field","name":{"kind":"Name","value":"current"}}]}}]}}]} as unknown as DocumentNode; -export const ListLogsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ListLogs"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"queries"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountListLogs"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"queries"},"value":{"kind":"Variable","name":{"kind":"Name","value":"queries"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"logs"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"event"}},{"kind":"Field","name":{"kind":"Name","value":"userId"}},{"kind":"Field","name":{"kind":"Name","value":"userEmail"}},{"kind":"Field","name":{"kind":"Name","value":"userName"}},{"kind":"Field","name":{"kind":"Name","value":"mode"}},{"kind":"Field","name":{"kind":"Name","value":"ip"}},{"kind":"Field","name":{"kind":"Name","value":"time"}},{"kind":"Field","name":{"kind":"Name","value":"osCode"}},{"kind":"Field","name":{"kind":"Name","value":"osName"}},{"kind":"Field","name":{"kind":"Name","value":"osVersion"}},{"kind":"Field","name":{"kind":"Name","value":"clientType"}},{"kind":"Field","name":{"kind":"Name","value":"clientCode"}},{"kind":"Field","name":{"kind":"Name","value":"clientName"}},{"kind":"Field","name":{"kind":"Name","value":"clientVersion"}},{"kind":"Field","name":{"kind":"Name","value":"clientEngine"}},{"kind":"Field","name":{"kind":"Name","value":"clientEngineVersion"}},{"kind":"Field","name":{"kind":"Name","value":"deviceName"}},{"kind":"Field","name":{"kind":"Name","value":"deviceBrand"}},{"kind":"Field","name":{"kind":"Name","value":"deviceModel"}},{"kind":"Field","name":{"kind":"Name","value":"countryCode"}},{"kind":"Field","name":{"kind":"Name","value":"countryName"}}]}}]}}]}}]} as unknown as DocumentNode; -export const CreateRecoveryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateRecovery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"email"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"url"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountCreateRecovery"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"email"},"value":{"kind":"Variable","name":{"kind":"Name","value":"email"}}},{"kind":"Argument","name":{"kind":"Name","value":"url"},"value":{"kind":"Variable","name":{"kind":"Name","value":"url"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"expire"}}]}}]}}]} as unknown as DocumentNode; -export const UpdateRecoveryDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateRecovery"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"userId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"secret"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"password"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountUpdateRecovery"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"userId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"userId"}}},{"kind":"Argument","name":{"kind":"Name","value":"secret"},"value":{"kind":"Variable","name":{"kind":"Name","value":"secret"}}},{"kind":"Argument","name":{"kind":"Name","value":"password"},"value":{"kind":"Variable","name":{"kind":"Name","value":"password"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"expire"}}]}}]}}]} as unknown as DocumentNode; -export const CreateAccountDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateAccount"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"userId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"name"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"email"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"password"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountCreate"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"userId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"userId"}}},{"kind":"Argument","name":{"kind":"Name","value":"name"},"value":{"kind":"Variable","name":{"kind":"Name","value":"name"}}},{"kind":"Argument","name":{"kind":"Name","value":"email"},"value":{"kind":"Variable","name":{"kind":"Name","value":"email"}}},{"kind":"Argument","name":{"kind":"Name","value":"password"},"value":{"kind":"Variable","name":{"kind":"Name","value":"password"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"email"}}]}}]}}]} as unknown as DocumentNode; -export const VerifyEmailDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"VerifyEmail"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"url"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountCreateVerification"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"url"},"value":{"kind":"Variable","name":{"kind":"Name","value":"url"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"expire"}}]}}]}}]} as unknown as DocumentNode; -export const UpdateEmailDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateEmail"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"email"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"password"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountUpdateEmail"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"email"},"value":{"kind":"Variable","name":{"kind":"Name","value":"email"}}},{"kind":"Argument","name":{"kind":"Name","value":"password"},"value":{"kind":"Variable","name":{"kind":"Name","value":"password"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"email"}}]}}]}}]} as unknown as DocumentNode; -export const UpdateEmailVerificationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateEmailVerification"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"userId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"secret"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountUpdateEmailVerification"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"userId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"userId"}}},{"kind":"Argument","name":{"kind":"Name","value":"secret"},"value":{"kind":"Variable","name":{"kind":"Name","value":"secret"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"userId"}},{"kind":"Field","name":{"kind":"Name","value":"secret"}},{"kind":"Field","name":{"kind":"Name","value":"expire"}}]}}]}}]} as unknown as DocumentNode; -export const UpdateMagicUrlSessionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateMagicURLSession"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"userId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"secret"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountUpdateMagicURLSession"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"userId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"userId"}}},{"kind":"Argument","name":{"kind":"Name","value":"secret"},"value":{"kind":"Variable","name":{"kind":"Name","value":"secret"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userId"}},{"kind":"Field","name":{"kind":"Name","value":"expire"}},{"kind":"Field","name":{"kind":"Name","value":"current"}}]}}]}}]} as unknown as DocumentNode; -export const UpdateMfaDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateMFA"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"mfa"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountUpdateMFA"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"mfa"},"value":{"kind":"Variable","name":{"kind":"Name","value":"mfa"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"mfa"}}]}}]}}]} as unknown as DocumentNode; -export const UpdateMfaAuthenticatorDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateMfaAuthenticator"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"type"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"otp"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountUpdateMfaAuthenticator"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"type"},"value":{"kind":"Variable","name":{"kind":"Name","value":"type"}}},{"kind":"Argument","name":{"kind":"Name","value":"otp"},"value":{"kind":"Variable","name":{"kind":"Name","value":"otp"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"mfa"}}]}}]}}]} as unknown as DocumentNode; -export const UpdateMfaChallengeDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateMfaChallenge"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"challengeId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"otp"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountUpdateMfaChallenge"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"challengeId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"challengeId"}}},{"kind":"Argument","name":{"kind":"Name","value":"otp"},"value":{"kind":"Variable","name":{"kind":"Name","value":"otp"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}}]} as unknown as DocumentNode; -export const UpdateMfaRecoveryCodesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateMfaRecoveryCodes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountUpdateMfaRecoveryCodes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"recoveryCodes"}}]}}]}}]} as unknown as DocumentNode; -export const UpdateNameDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateName"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"name"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountUpdateName"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"name"},"value":{"kind":"Variable","name":{"kind":"Name","value":"name"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]} as unknown as DocumentNode; -export const UpdatePasswordDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdatePassword"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"password"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"oldPassword"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountUpdatePassword"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"password"},"value":{"kind":"Variable","name":{"kind":"Name","value":"password"}}},{"kind":"Argument","name":{"kind":"Name","value":"oldPassword"},"value":{"kind":"Variable","name":{"kind":"Name","value":"oldPassword"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}}]} as unknown as DocumentNode; -export const UpdatePhoneDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdatePhone"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"phone"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"password"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountUpdatePhone"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"phone"},"value":{"kind":"Variable","name":{"kind":"Name","value":"phone"}}},{"kind":"Argument","name":{"kind":"Name","value":"password"},"value":{"kind":"Variable","name":{"kind":"Name","value":"password"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"phone"}}]}}]}}]} as unknown as DocumentNode; -export const UpdatePhoneSessionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdatePhoneSession"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"userId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"secret"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountUpdatePhoneSession"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"userId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"userId"}}},{"kind":"Argument","name":{"kind":"Name","value":"secret"},"value":{"kind":"Variable","name":{"kind":"Name","value":"secret"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userId"}},{"kind":"Field","name":{"kind":"Name","value":"expire"}},{"kind":"Field","name":{"kind":"Name","value":"current"}}]}}]}}]} as unknown as DocumentNode; -export const UpdatePhoneVerificationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdatePhoneVerification"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"userId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"secret"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountUpdatePhoneVerification"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"userId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"userId"}}},{"kind":"Argument","name":{"kind":"Name","value":"secret"},"value":{"kind":"Variable","name":{"kind":"Name","value":"secret"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"expire"}}]}}]}}]} as unknown as DocumentNode; -export const UpdatePrefsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdatePrefs"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"prefs"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Assoc"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountUpdatePrefs"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"prefs"},"value":{"kind":"Variable","name":{"kind":"Name","value":"prefs"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"prefs"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"}}]}}]}}]}}]} as unknown as DocumentNode; -export const UpdatePushTargetDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdatePushTarget"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"targetId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"identifier"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountUpdatePushTarget"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"targetId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"targetId"}}},{"kind":"Argument","name":{"kind":"Name","value":"identifier"},"value":{"kind":"Variable","name":{"kind":"Name","value":"identifier"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"userId"}},{"kind":"Field","name":{"kind":"Name","value":"providerType"}},{"kind":"Field","name":{"kind":"Name","value":"identifier"}}]}}]}}]} as unknown as DocumentNode; -export const UpdateSessionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateSession"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"sessionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountUpdateSession"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"sessionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"sessionId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"userId"}},{"kind":"Field","name":{"kind":"Name","value":"expire"}},{"kind":"Field","name":{"kind":"Name","value":"current"}}]}}]}}]} as unknown as DocumentNode; -export const UpdateStatusDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateStatus"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountUpdateStatus"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}}]} as unknown as DocumentNode; -export const UpdateVerificationDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateVerification"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"userId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"secret"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"accountUpdateVerification"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"userId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"userId"}}},{"kind":"Argument","name":{"kind":"Name","value":"secret"},"value":{"kind":"Variable","name":{"kind":"Name","value":"secret"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"secret"}},{"kind":"Field","name":{"kind":"Name","value":"expire"}},{"kind":"Field","name":{"kind":"Name","value":"userId"}}]}}]}}]} as unknown as DocumentNode; -export const ListDocumentsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ListDocuments"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"databaseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"collectionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"queries"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"databasesListDocuments"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"databaseId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"databaseId"}}},{"kind":"Argument","name":{"kind":"Name","value":"collectionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"collectionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"queries"},"value":{"kind":"Variable","name":{"kind":"Name","value":"queries"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"documents"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"data"}}]}}]}}]}}]} as unknown as DocumentNode; -export const CreateDocumentDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateDocument"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"databaseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"collectionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"data"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Json"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"permissions"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"databasesCreateDocument"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"databaseId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"databaseId"}}},{"kind":"Argument","name":{"kind":"Name","value":"collectionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"collectionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"documentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"data"},"value":{"kind":"Variable","name":{"kind":"Name","value":"data"}}},{"kind":"Argument","name":{"kind":"Name","value":"permissions"},"value":{"kind":"Variable","name":{"kind":"Name","value":"permissions"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}}]}}]}}]} as unknown as DocumentNode; -export const CreateDocumentsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateDocuments"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"databaseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"collectionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"documents"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Json"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"databasesCreateDocuments"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"databaseId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"databaseId"}}},{"kind":"Argument","name":{"kind":"Name","value":"collectionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"collectionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"documents"},"value":{"kind":"Variable","name":{"kind":"Name","value":"documents"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"documents"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}}]}}]}}]}}]} as unknown as DocumentNode; -export const CreateOperationsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateOperations"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"transactionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"operations"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"databasesCreateOperations"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"transactionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"transactionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"operations"},"value":{"kind":"Variable","name":{"kind":"Name","value":"operations"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"operations"}},{"kind":"Field","name":{"kind":"Name","value":"expiresAt"}}]}}]}}]} as unknown as DocumentNode; -export const CreateTransactionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateTransaction"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"ttl"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"databasesCreateTransaction"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"ttl"},"value":{"kind":"Variable","name":{"kind":"Name","value":"ttl"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"operations"}},{"kind":"Field","name":{"kind":"Name","value":"expiresAt"}}]}}]}}]} as unknown as DocumentNode; -export const DecrementDocumentAttributeDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DecrementDocumentAttribute"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"databaseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"collectionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"attribute"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"value"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"min"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"databasesDecrementDocumentAttribute"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"databaseId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"databaseId"}}},{"kind":"Argument","name":{"kind":"Name","value":"collectionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"collectionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"documentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"attribute"},"value":{"kind":"Variable","name":{"kind":"Name","value":"attribute"}}},{"kind":"Argument","name":{"kind":"Name","value":"value"},"value":{"kind":"Variable","name":{"kind":"Name","value":"value"}}},{"kind":"Argument","name":{"kind":"Name","value":"min"},"value":{"kind":"Variable","name":{"kind":"Name","value":"min"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"data"}}]}}]}}]} as unknown as DocumentNode; -export const DeleteDocumentDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteDocument"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"databaseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"collectionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"databasesDeleteDocument"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"databaseId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"databaseId"}}},{"kind":"Argument","name":{"kind":"Name","value":"collectionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"collectionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"documentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}}]} as unknown as DocumentNode; -export const DeleteDocumentsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteDocuments"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"databaseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"collectionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"queries"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"databasesDeleteDocuments"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"databaseId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"databaseId"}}},{"kind":"Argument","name":{"kind":"Name","value":"collectionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"collectionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"queries"},"value":{"kind":"Variable","name":{"kind":"Name","value":"queries"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"documents"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}}]}}]}}]}}]} as unknown as DocumentNode; -export const DeleteTransactionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteTransaction"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"transactionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"databasesDeleteTransaction"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"transactionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"transactionId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}}]} as unknown as DocumentNode; -export const GetDocumentDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetDocument"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"databaseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"collectionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"databasesGetDocument"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"databaseId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"databaseId"}}},{"kind":"Argument","name":{"kind":"Name","value":"collectionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"collectionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"documentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"data"}}]}}]}}]} as unknown as DocumentNode; -export const GetTransactionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetTransaction"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"transactionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"databasesGetTransaction"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"transactionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"transactionId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"_updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"operations"}},{"kind":"Field","name":{"kind":"Name","value":"expiresAt"}}]}}]}}]} as unknown as DocumentNode; -export const IncrementDocumentAttributeDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"IncrementDocumentAttribute"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"databaseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"collectionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"attribute"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"value"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"max"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Int"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"databasesIncrementDocumentAttribute"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"databaseId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"databaseId"}}},{"kind":"Argument","name":{"kind":"Name","value":"collectionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"collectionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"documentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"attribute"},"value":{"kind":"Variable","name":{"kind":"Name","value":"attribute"}}},{"kind":"Argument","name":{"kind":"Name","value":"value"},"value":{"kind":"Variable","name":{"kind":"Name","value":"value"}}},{"kind":"Argument","name":{"kind":"Name","value":"max"},"value":{"kind":"Variable","name":{"kind":"Name","value":"max"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"data"}}]}}]}}]} as unknown as DocumentNode; -export const ListTransactionsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ListTransactions"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"queries"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"databasesListTransactions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"queries"},"value":{"kind":"Variable","name":{"kind":"Name","value":"queries"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"transactions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"_updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"operations"}},{"kind":"Field","name":{"kind":"Name","value":"expiresAt"}}]}}]}}]}}]} as unknown as DocumentNode; -export const UpdateDocumentDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateDocument"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"databaseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"collectionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"data"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Json"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"permissions"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"databasesUpdateDocument"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"databaseId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"databaseId"}}},{"kind":"Argument","name":{"kind":"Name","value":"collectionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"collectionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"documentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"data"},"value":{"kind":"Variable","name":{"kind":"Name","value":"data"}}},{"kind":"Argument","name":{"kind":"Name","value":"permissions"},"value":{"kind":"Variable","name":{"kind":"Name","value":"permissions"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}}]}}]}}]} as unknown as DocumentNode; -export const UpdateDocumentsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateDocuments"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"databaseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"collectionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"data"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Json"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"queries"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"databasesUpdateDocuments"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"databaseId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"databaseId"}}},{"kind":"Argument","name":{"kind":"Name","value":"collectionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"collectionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"data"},"value":{"kind":"Variable","name":{"kind":"Name","value":"data"}}},{"kind":"Argument","name":{"kind":"Name","value":"queries"},"value":{"kind":"Variable","name":{"kind":"Name","value":"queries"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"documents"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}}]}}]}}]}}]} as unknown as DocumentNode; -export const UpdateTransactionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateTransaction"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"transactionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"commit"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"rollback"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"databasesUpdateTransaction"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"transactionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"transactionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"commit"},"value":{"kind":"Variable","name":{"kind":"Name","value":"commit"}}},{"kind":"Argument","name":{"kind":"Name","value":"rollback"},"value":{"kind":"Variable","name":{"kind":"Name","value":"rollback"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"operations"}}]}}]}}]} as unknown as DocumentNode; -export const UpsertDocumentDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpsertDocument"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"databaseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"collectionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"data"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Json"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"permissions"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"databasesUpsertDocument"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"databaseId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"databaseId"}}},{"kind":"Argument","name":{"kind":"Name","value":"collectionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"collectionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"documentId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"documentId"}}},{"kind":"Argument","name":{"kind":"Name","value":"data"},"value":{"kind":"Variable","name":{"kind":"Name","value":"data"}}},{"kind":"Argument","name":{"kind":"Name","value":"permissions"},"value":{"kind":"Variable","name":{"kind":"Name","value":"permissions"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}}]}}]}}]} as unknown as DocumentNode; -export const UpsertDocumentsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpsertDocuments"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"databaseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"collectionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"documents"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Json"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"databasesUpsertDocuments"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"databaseId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"databaseId"}}},{"kind":"Argument","name":{"kind":"Name","value":"collectionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"collectionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"documents"},"value":{"kind":"Variable","name":{"kind":"Name","value":"documents"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"documents"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}}]}}]}}]}}]} as unknown as DocumentNode; -export const CreateExecutionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateExecution"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"functionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"body"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"async"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"Boolean"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"path"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"method"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"functionsCreateExecution"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"functionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"functionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"body"},"value":{"kind":"Variable","name":{"kind":"Name","value":"body"}}},{"kind":"Argument","name":{"kind":"Name","value":"async"},"value":{"kind":"Variable","name":{"kind":"Name","value":"async"}}},{"kind":"Argument","name":{"kind":"Name","value":"path"},"value":{"kind":"Variable","name":{"kind":"Name","value":"path"}}},{"kind":"Argument","name":{"kind":"Name","value":"method"},"value":{"kind":"Variable","name":{"kind":"Name","value":"method"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"responseStatusCode"}},{"kind":"Field","name":{"kind":"Name","value":"responseBody"}},{"kind":"Field","name":{"kind":"Name","value":"errors"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}}]}}]}}]} as unknown as DocumentNode; -export const GetFunctionExecutionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetFunctionExecution"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"functionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"executionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"functionsGetExecution"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"functionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"functionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"executionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"executionId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"errors"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}},{"kind":"Field","name":{"kind":"Name","value":"responseBody"}},{"kind":"Field","name":{"kind":"Name","value":"requestPath"}}]}}]}}]} as unknown as DocumentNode; -export const GetExecutionDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetExecution"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"functionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"executionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"functionsGetExecution"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"functionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"functionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"executionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"executionId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"_updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"functionId"}},{"kind":"Field","name":{"kind":"Name","value":"trigger"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"requestMethod"}},{"kind":"Field","name":{"kind":"Name","value":"requestPath"}},{"kind":"Field","name":{"kind":"Name","value":"responseStatusCode"}},{"kind":"Field","name":{"kind":"Name","value":"responseBody"}},{"kind":"Field","name":{"kind":"Name","value":"errors"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}}]}}]}}]} as unknown as DocumentNode; -export const ListExecutionsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ListExecutions"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"functionId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"queries"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"functionsListExecutions"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"functionId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"functionId"}}},{"kind":"Argument","name":{"kind":"Name","value":"queries"},"value":{"kind":"Variable","name":{"kind":"Name","value":"queries"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"executions"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"_updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"functionId"}},{"kind":"Field","name":{"kind":"Name","value":"trigger"}},{"kind":"Field","name":{"kind":"Name","value":"status"}},{"kind":"Field","name":{"kind":"Name","value":"requestMethod"}},{"kind":"Field","name":{"kind":"Name","value":"requestPath"}},{"kind":"Field","name":{"kind":"Name","value":"responseStatusCode"}},{"kind":"Field","name":{"kind":"Name","value":"responseBody"}},{"kind":"Field","name":{"kind":"Name","value":"errors"}},{"kind":"Field","name":{"kind":"Name","value":"duration"}}]}}]}}]}}]} as unknown as DocumentNode; -export const GetLocaleDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetLocale"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"localeGet"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"ip"}},{"kind":"Field","name":{"kind":"Name","value":"countryCode"}},{"kind":"Field","name":{"kind":"Name","value":"country"}},{"kind":"Field","name":{"kind":"Name","value":"continentCode"}},{"kind":"Field","name":{"kind":"Name","value":"continent"}},{"kind":"Field","name":{"kind":"Name","value":"eu"}},{"kind":"Field","name":{"kind":"Name","value":"currency"}}]}}]}}]} as unknown as DocumentNode; -export const ListLocaleCodesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ListLocaleCodes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"localeListCodes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"localeCodes"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"code"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]}}]} as unknown as DocumentNode; -export const ListContinentsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ListContinents"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"localeListContinents"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"continents"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"code"}}]}}]}}]}}]} as unknown as DocumentNode; -export const ListCountriesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ListCountries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"localeListCountries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"countries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"code"}}]}}]}}]}}]} as unknown as DocumentNode; -export const ListCountriesEuDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ListCountriesEU"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"localeListCountriesEU"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"countries"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"code"}}]}}]}}]}}]} as unknown as DocumentNode; -export const ListCountriesPhonesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ListCountriesPhones"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"localeListCountriesPhones"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"phones"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"code"}},{"kind":"Field","name":{"kind":"Name","value":"countryCode"}},{"kind":"Field","name":{"kind":"Name","value":"countryName"}}]}}]}}]}}]} as unknown as DocumentNode; -export const ListCurrenciesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ListCurrencies"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"localeListCurrencies"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"currencies"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"symbol"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"symbolNative"}},{"kind":"Field","name":{"kind":"Name","value":"decimalDigits"}},{"kind":"Field","name":{"kind":"Name","value":"rounding"}},{"kind":"Field","name":{"kind":"Name","value":"code"}},{"kind":"Field","name":{"kind":"Name","value":"namePlural"}}]}}]}}]}}]} as unknown as DocumentNode; -export const ListLanguagesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ListLanguages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"localeListLanguages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"languages"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"code"}},{"kind":"Field","name":{"kind":"Name","value":"nativeName"}}]}}]}}]}}]} as unknown as DocumentNode; -export const CreateFileDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateFile"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"bucketId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"fileId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"file"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"permissions"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"storageCreateFile"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"bucketId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"bucketId"}}},{"kind":"Argument","name":{"kind":"Name","value":"fileId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"fileId"}}},{"kind":"Argument","name":{"kind":"Name","value":"file"},"value":{"kind":"Variable","name":{"kind":"Name","value":"file"}}},{"kind":"Argument","name":{"kind":"Name","value":"permissions"},"value":{"kind":"Variable","name":{"kind":"Name","value":"permissions"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"bucketId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"mimeType"}},{"kind":"Field","name":{"kind":"Name","value":"sizeOriginal"}}]}}]}}]} as unknown as DocumentNode; -export const DeleteFileDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteFile"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"bucketId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"fileId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"storageDeleteFile"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"bucketId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"bucketId"}}},{"kind":"Argument","name":{"kind":"Name","value":"fileId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"fileId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}}]} as unknown as DocumentNode; -export const GetFileDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetFile"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"bucketId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"fileId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"storageGetFile"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"bucketId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"bucketId"}}},{"kind":"Argument","name":{"kind":"Name","value":"fileId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"fileId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"bucketId"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"_updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"_permissions"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"signature"}},{"kind":"Field","name":{"kind":"Name","value":"mimeType"}},{"kind":"Field","name":{"kind":"Name","value":"sizeOriginal"}},{"kind":"Field","name":{"kind":"Name","value":"chunksTotal"}},{"kind":"Field","name":{"kind":"Name","value":"chunksUploaded"}}]}}]}}]} as unknown as DocumentNode; -export const ListFilesDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ListFiles"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"bucketId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"queries"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"search"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"storageListFiles"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"bucketId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"bucketId"}}},{"kind":"Argument","name":{"kind":"Name","value":"queries"},"value":{"kind":"Variable","name":{"kind":"Name","value":"queries"}}},{"kind":"Argument","name":{"kind":"Name","value":"search"},"value":{"kind":"Variable","name":{"kind":"Name","value":"search"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"files"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"bucketId"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"_updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"_permissions"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"signature"}},{"kind":"Field","name":{"kind":"Name","value":"mimeType"}},{"kind":"Field","name":{"kind":"Name","value":"sizeOriginal"}},{"kind":"Field","name":{"kind":"Name","value":"chunksTotal"}},{"kind":"Field","name":{"kind":"Name","value":"chunksUploaded"}}]}}]}}]}}]} as unknown as DocumentNode; -export const UpdateFileDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateFile"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"bucketId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"fileId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"name"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"permissions"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"storageUpdateFile"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"bucketId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"bucketId"}}},{"kind":"Argument","name":{"kind":"Name","value":"fileId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"fileId"}}},{"kind":"Argument","name":{"kind":"Name","value":"name"},"value":{"kind":"Variable","name":{"kind":"Name","value":"name"}}},{"kind":"Argument","name":{"kind":"Name","value":"permissions"},"value":{"kind":"Variable","name":{"kind":"Name","value":"permissions"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"bucketId"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"_permissions"}}]}}]}}]} as unknown as DocumentNode; -export const CreateMembershipDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateMembership"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"roles"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"email"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"userId"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"phone"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"url"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"name"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"teamsCreateMembership"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"teamId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}}},{"kind":"Argument","name":{"kind":"Name","value":"roles"},"value":{"kind":"Variable","name":{"kind":"Name","value":"roles"}}},{"kind":"Argument","name":{"kind":"Name","value":"email"},"value":{"kind":"Variable","name":{"kind":"Name","value":"email"}}},{"kind":"Argument","name":{"kind":"Name","value":"userId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"userId"}}},{"kind":"Argument","name":{"kind":"Name","value":"phone"},"value":{"kind":"Variable","name":{"kind":"Name","value":"phone"}}},{"kind":"Argument","name":{"kind":"Name","value":"url"},"value":{"kind":"Variable","name":{"kind":"Name","value":"url"}}},{"kind":"Argument","name":{"kind":"Name","value":"name"},"value":{"kind":"Variable","name":{"kind":"Name","value":"name"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"userId"}},{"kind":"Field","name":{"kind":"Name","value":"teamId"}},{"kind":"Field","name":{"kind":"Name","value":"roles"}},{"kind":"Field","name":{"kind":"Name","value":"confirm"}}]}}]}}]} as unknown as DocumentNode; -export const CreateTeamDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"CreateTeam"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"name"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"roles"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"teamsCreate"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"teamId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}}},{"kind":"Argument","name":{"kind":"Name","value":"name"},"value":{"kind":"Variable","name":{"kind":"Name","value":"name"}}},{"kind":"Argument","name":{"kind":"Name","value":"roles"},"value":{"kind":"Variable","name":{"kind":"Name","value":"roles"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"total"}}]}}]}}]} as unknown as DocumentNode; -export const DeleteMembershipDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteMembership"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"membershipId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"teamsDeleteMembership"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"teamId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}}},{"kind":"Argument","name":{"kind":"Name","value":"membershipId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"membershipId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}}]} as unknown as DocumentNode; -export const DeleteTeamDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"DeleteTeam"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"teamsDelete"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"teamId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"status"}}]}}]}}]} as unknown as DocumentNode; -export const GetTeamDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetTeam"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"teamsGet"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"teamId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"_updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"prefs"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"}}]}}]}}]}}]} as unknown as DocumentNode; -export const GetMembershipDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetMembership"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"membershipId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"teamsGetMembership"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"teamId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}}},{"kind":"Argument","name":{"kind":"Name","value":"membershipId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"membershipId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"_updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"userId"}},{"kind":"Field","name":{"kind":"Name","value":"userName"}},{"kind":"Field","name":{"kind":"Name","value":"userEmail"}},{"kind":"Field","name":{"kind":"Name","value":"teamId"}},{"kind":"Field","name":{"kind":"Name","value":"teamName"}},{"kind":"Field","name":{"kind":"Name","value":"invited"}},{"kind":"Field","name":{"kind":"Name","value":"joined"}},{"kind":"Field","name":{"kind":"Name","value":"confirm"}},{"kind":"Field","name":{"kind":"Name","value":"mfa"}},{"kind":"Field","name":{"kind":"Name","value":"roles"}}]}}]}}]} as unknown as DocumentNode; -export const ListMembershipsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ListMemberships"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"queries"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"search"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"teamsListMemberships"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"teamId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}}},{"kind":"Argument","name":{"kind":"Name","value":"queries"},"value":{"kind":"Variable","name":{"kind":"Name","value":"queries"}}},{"kind":"Argument","name":{"kind":"Name","value":"search"},"value":{"kind":"Variable","name":{"kind":"Name","value":"search"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"memberships"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"_updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"userId"}},{"kind":"Field","name":{"kind":"Name","value":"userName"}},{"kind":"Field","name":{"kind":"Name","value":"userEmail"}},{"kind":"Field","name":{"kind":"Name","value":"teamId"}},{"kind":"Field","name":{"kind":"Name","value":"teamName"}},{"kind":"Field","name":{"kind":"Name","value":"invited"}},{"kind":"Field","name":{"kind":"Name","value":"joined"}},{"kind":"Field","name":{"kind":"Name","value":"confirm"}},{"kind":"Field","name":{"kind":"Name","value":"mfa"}},{"kind":"Field","name":{"kind":"Name","value":"roles"}}]}}]}}]}}]} as unknown as DocumentNode; -export const GetTeamPrefsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"GetTeamPrefs"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"teamsGetPrefs"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"teamId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"}}]}}]}}]} as unknown as DocumentNode; -export const ListTeamsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ListTeams"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"queries"}},"type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"search"}},"type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"teamsList"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"queries"},"value":{"kind":"Variable","name":{"kind":"Name","value":"queries"}}},{"kind":"Argument","name":{"kind":"Name","value":"search"},"value":{"kind":"Variable","name":{"kind":"Name","value":"search"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"teams"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"_createdAt"}},{"kind":"Field","name":{"kind":"Name","value":"_updatedAt"}},{"kind":"Field","name":{"kind":"Name","value":"name"}},{"kind":"Field","name":{"kind":"Name","value":"total"}},{"kind":"Field","name":{"kind":"Name","value":"prefs"},"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"}}]}}]}}]}}]}}]} as unknown as DocumentNode; -export const UpdateMembershipDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateMembership"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"membershipId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"roles"}},"type":{"kind":"NonNullType","type":{"kind":"ListType","type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"teamsUpdateMembership"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"teamId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}}},{"kind":"Argument","name":{"kind":"Name","value":"membershipId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"membershipId"}}},{"kind":"Argument","name":{"kind":"Name","value":"roles"},"value":{"kind":"Variable","name":{"kind":"Name","value":"roles"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"roles"}}]}}]}}]} as unknown as DocumentNode; -export const UpdateMembershipStatusDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateMembershipStatus"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"membershipId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"userId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"secret"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"teamsUpdateMembershipStatus"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"teamId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}}},{"kind":"Argument","name":{"kind":"Name","value":"membershipId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"membershipId"}}},{"kind":"Argument","name":{"kind":"Name","value":"userId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"userId"}}},{"kind":"Argument","name":{"kind":"Name","value":"secret"},"value":{"kind":"Variable","name":{"kind":"Name","value":"secret"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"confirm"}}]}}]}}]} as unknown as DocumentNode; -export const UpdateTeamNameDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateTeamName"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"name"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"teamsUpdateName"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"teamId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}}},{"kind":"Argument","name":{"kind":"Name","value":"name"},"value":{"kind":"Variable","name":{"kind":"Name","value":"name"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"_id"}},{"kind":"Field","name":{"kind":"Name","value":"name"}}]}}]}}]} as unknown as DocumentNode; -export const UpdateTeamPrefsDocument = {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"mutation","name":{"kind":"Name","value":"UpdateTeamPrefs"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"prefs"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"Assoc"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"teamsUpdatePrefs"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"teamId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"teamId"}}},{"kind":"Argument","name":{"kind":"Name","value":"prefs"},"value":{"kind":"Variable","name":{"kind":"Name","value":"prefs"}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"data"}}]}}]}}]} as unknown as DocumentNode; \ No newline at end of file diff --git a/src/__generated__/index.ts b/src/__generated__/index.ts deleted file mode 100644 index f515991..0000000 --- a/src/__generated__/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./fragment-masking"; -export * from "./gql"; \ No newline at end of file diff --git a/src/account/fragments.ts b/src/account/fragments.ts deleted file mode 100644 index 39f4aba..0000000 --- a/src/account/fragments.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { gql } from '../__generated__' - -export const Account_User = gql(/* GraphQL */ ` - fragment Account_User on User { - _id - name - email - prefs { - data - } - } -`) - -export const Identity_Provider = gql(/* GraphQL */ ` - fragment Identity_Provider on Identity { - _id - userId - provider - } -`) diff --git a/src/account/index.ts b/src/account/index.ts index 32813f9..b31dd03 100644 --- a/src/account/index.ts +++ b/src/account/index.ts @@ -1,3 +1,4 @@ +export { accountQueryOptions } from './queryOptions' export { useAccount, useLazyAccount } from './useAccount' export { useCreateAnonymousSession } from './useCreateAnonymousSession' export { useCreateEmailToken } from './useCreateEmailToken' @@ -11,7 +12,6 @@ export { useCreatePhoneToken } from './useCreatePhoneToken' export { useCreatePhoneVerification } from './useCreatePhoneVerification' export { useCreatePushTarget } from './useCreatePushTarget' export { useCreateSession } from './useCreateSession' -export { useDeleteAccount } from './useDeleteAccount' export { useCreateEmailVerification } from './useCreateEmailVerification' export { useDeleteIdentity } from './useDeleteIdentity' export { useDeleteMfaAuthenticator } from './useDeleteMfaAuthenticator' diff --git a/src/account/queryOptions.ts b/src/account/queryOptions.ts new file mode 100644 index 0000000..2157dbb --- /dev/null +++ b/src/account/queryOptions.ts @@ -0,0 +1,35 @@ +import { graphql as gql } from 'gql.tada' + +import type { AppwriteClient } from '../client' +import { Keys } from '../query/Keys' + +export const getAccount = gql(/* GraphQL */ ` + query AccountGet { + accountGet { + _id + name + email + prefs { + data + } + } + } +`) + +export function accountQueryOptions(client: AppwriteClient) { + return { + queryKey: Keys.account().key(), + queryFn: async () => { + const { data, errors } = await client.graphql.query({ + query: getAccount, + }) + + if (errors) { + throw errors + } + + return data.accountGet + }, + retry: false, + } +} diff --git a/src/account/useAccount.ts b/src/account/useAccount.ts index 2ae8a13..b83cf75 100644 --- a/src/account/useAccount.ts +++ b/src/account/useAccount.ts @@ -1,42 +1,36 @@ import { useEffect, useState } from 'react' - +import type { ResultOf } from '@graphql-typed-document-node/core' +import { Channel } from 'appwrite' import { castDraft, produce } from 'immer' -import { gql } from '../__generated__/gql' -import { AccountGetQuery } from '../__generated__/graphql' -import type { AppwriteException, Models, Realtime } from '../types' +import type { getAccount } from './queryOptions' +import { accountQueryOptions } from './queryOptions' +import { Keys } from '../query/Keys' +import type { AppwriteException, Models, QueryOptions, Realtime } from '../types' import { useAppwrite } from '../useAppwrite' import { useLazyQuery } from '../useLazyQuery' import { useQuery } from '../useQuery' import { useQueryClient } from '../useQueryClient' -export const getAccount = gql(/* GraphQL */ ` - query AccountGet { - accountGet { - ...Account_User - } - } -`) +type Result = ResultOf['accountGet'] export function useLazyAccount() { - const { graphql, realtime } = useAppwrite() + const client = useAppwrite() const queryClient = useQueryClient() const [isActive, setIsActive] = useState(false) - const queryResult = useLazyQuery< - AccountGetQuery['accountGet'], - AppwriteException[], - AccountGetQuery['accountGet'] - >(getAccountQueryOptions(graphql)) + const queryResult = useLazyQuery( + getAccountQueryOptions(client), + ) useEffect(() => { if (!isActive) return - const subscriptionPromise = subscribe(realtime, queryClient) + const subscriptionPromise = subscribe(client.realtime, queryClient) return () => { - subscriptionPromise.then((sub) => sub.close()) + void subscriptionPromise.then((sub) => sub.close()) } - }, [isActive, realtime, queryClient]) + }, [isActive, client.realtime, queryClient]) return { ...queryResult, @@ -47,53 +41,38 @@ export function useLazyAccount() { } } -export function useAccount() { - const { graphql, realtime } = useAppwrite() +export function useAccount(opts: QueryOptions = {}) { + const client = useAppwrite() const queryClient = useQueryClient() - const queryResult = useQuery< - AccountGetQuery['accountGet'], - AppwriteException[], - AccountGetQuery['accountGet'] - >(getAccountQueryOptions(graphql)) + const queryResult = useQuery({ + ...getAccountQueryOptions(client), + ...opts, + }) useEffect(() => { - const subscriptionPromise = subscribe(realtime, queryClient) + const subscriptionPromise = subscribe(client.realtime, queryClient) return () => { - subscriptionPromise.then((sub) => sub.close()) + void subscriptionPromise.then((sub) => sub.close()) } - }, [realtime, queryClient]) + }, [client.realtime, queryClient]) return queryResult } -function getAccountQueryOptions(graphql: ReturnType['graphql']) { - return { - queryKey: ['appwrite', 'account'], - queryFn: async () => { - const { data, errors } = await graphql.query({ - query: getAccount, - }) - - if (errors) { - throw errors - } - - return data.accountGet - }, - retry: false, - } +function getAccountQueryOptions(client: ReturnType) { + return accountQueryOptions(client) } function subscribe( realtime: Realtime, queryClient: ReturnType, ) { - return realtime.subscribe>('account', (response) => { + return realtime.subscribe>(Channel.account(), (response) => { const isUpdatingPreferences = response.events.some((event) => event.endsWith('prefs')) if (isUpdatingPreferences) { - queryClient.setQueryData>(['appwrite', 'account'], (account) => + queryClient.setQueryData>(Keys.account().key(), (account) => produce(account, (draft) => { if (draft) { draft.prefs = castDraft(response.payload.prefs) as typeof draft.prefs @@ -104,6 +83,6 @@ function subscribe( return } - queryClient.setQueryData>(['appwrite', 'account'], response.payload) + queryClient.setQueryData>(Keys.account().key(), response.payload) }) } diff --git a/src/account/useCreateAnonymousSession.ts b/src/account/useCreateAnonymousSession.ts index 205ce78..edda657 100644 --- a/src/account/useCreateAnonymousSession.ts +++ b/src/account/useCreateAnonymousSession.ts @@ -1,6 +1,8 @@ -import { gql } from '../__generated__' -import { CreateAnonymousSessionMutation } from '../__generated__/graphql' -import { AppwriteException } from '../types' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' + +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -15,14 +17,14 @@ const createAnonymousSession = gql(/* GraphQL */ ` } `) +type Result = ResultOf['accountCreateAnonymousSession'] + export function useCreateAnonymousSession() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - CreateAnonymousSessionMutation['accountCreateAnonymousSession'], - AppwriteException[] - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().anonymous().create(), mutationFn: async () => { const { data, errors } = await graphql.mutation({ query: createAnonymousSession, @@ -35,8 +37,8 @@ export function useCreateAnonymousSession() { return data.accountCreateAnonymousSession }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account'] }) - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account', 'sessions'] }) + void queryClient.invalidateQueries({ queryKey: Keys.account().key() }) + void queryClient.invalidateQueries({ queryKey: Keys.account().anonymous().create() }) }, }) diff --git a/src/account/useCreateEmailToken.ts b/src/account/useCreateEmailToken.ts index 732e4d7..8dcc365 100644 --- a/src/account/useCreateEmailToken.ts +++ b/src/account/useCreateEmailToken.ts @@ -1,9 +1,8 @@ -import { gql } from '../__generated__' -import { - CreateEmailTokenMutation, - CreateEmailTokenMutationVariables, -} from '../__generated__/graphql' -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' + +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' @@ -15,14 +14,14 @@ const createEmailToken = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountCreateEmailToken'] + export function useCreateEmailToken() { const { graphql } = useAppwrite() - const queryResult = useMutation< - CreateEmailTokenMutation['accountCreateEmailToken'], - AppwriteException[], - CreateEmailTokenMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().emailToken().create(), mutationFn: async ({ userId, email, phrase }) => { const { data, errors } = await graphql.mutation({ query: createEmailToken, diff --git a/src/account/useCreateEmailVerification.ts b/src/account/useCreateEmailVerification.ts index 2df24dc..e93a851 100644 --- a/src/account/useCreateEmailVerification.ts +++ b/src/account/useCreateEmailVerification.ts @@ -1,10 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { - CreateEmailVerificationMutation, - CreateEmailVerificationMutationVariables, -} from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' @@ -19,14 +17,14 @@ const createEmailVerification = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountCreateEmailVerification'] + export function useCreateEmailVerification() { const { graphql } = useAppwrite() - const queryResult = useMutation< - CreateEmailVerificationMutation['accountCreateEmailVerification'], - AppwriteException[], - CreateEmailVerificationMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().emailVerification().create(), mutationFn: async ({ url }) => { const { data, errors } = await graphql.mutation({ query: createEmailVerification, diff --git a/src/account/useCreateJWT.ts b/src/account/useCreateJWT.ts index 8004d9f..f073eed 100644 --- a/src/account/useCreateJWT.ts +++ b/src/account/useCreateJWT.ts @@ -1,11 +1,14 @@ -import { gql } from '../__generated__' -import { CreateJwtMutation } from '../__generated__/graphql' -import { AppwriteException } from '../types' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' + +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' import { useSuspenseQuery } from '../useSuspenseQuery' +//The documentation says there should be a duration parameter, but including one causes a server error. const accountCreateJWT = gql(/* GraphQL */ ` mutation CreateJWT { accountCreateJWT { @@ -14,13 +17,15 @@ const accountCreateJWT = gql(/* GraphQL */ ` } `) +type Result = ResultOf['accountCreateJWT'] + export function useCreateJWT({ gcTime = 600000 }: { gcTime?: number } = {}) { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation({ + const queryResult = useMutation({ gcTime, - mutationKey: ['appwrite', 'jwt'], + mutationKey: Keys.account().jwt().create(), mutationFn: async () => { const { data, errors } = await graphql.mutation({ query: accountCreateJWT, @@ -34,7 +39,7 @@ export function useCreateJWT({ gcTime = 600000 }: { gcTime?: number } = {}) { }, onSuccess: (data) => { graphql.client.setJWT(data.jwt) - queryClient.setQueryData(['appwrite', 'jwt'], data.jwt, { updatedAt: Date.now() }) + queryClient.setQueryData(Keys.account().jwt().create(), data.jwt, { updatedAt: Date.now() }) }, }) @@ -44,13 +49,9 @@ export function useCreateJWT({ gcTime = 600000 }: { gcTime?: number } = {}) { export function useSuspenseCreateJWT({ gcTime = 600000 }: { gcTime?: number } = {}) { const { graphql } = useAppwrite() - const queryResult = useSuspenseQuery< - CreateJwtMutation['accountCreateJWT'], - AppwriteException[], - CreateJwtMutation['accountCreateJWT'] - >({ + const queryResult = useSuspenseQuery({ gcTime, - queryKey: ['appwrite', 'jwt'], + queryKey: Keys.account().jwt().create(), queryFn: async () => { const { data, errors } = await graphql.mutation({ query: accountCreateJWT, diff --git a/src/account/useCreateMagicURLToken.ts b/src/account/useCreateMagicURLToken.ts index 1dce578..f53a2db 100644 --- a/src/account/useCreateMagicURLToken.ts +++ b/src/account/useCreateMagicURLToken.ts @@ -1,9 +1,8 @@ -import { gql } from '../__generated__' -import { - CreateMagicUrlTokenMutation, - CreateMagicUrlTokenMutationVariables, -} from '../__generated__/graphql' -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' + +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' @@ -15,14 +14,14 @@ const createMagicURLToken = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountCreateMagicURLToken'] + export function useCreateMagicURLToken() { const { graphql } = useAppwrite() - const queryResult = useMutation< - CreateMagicUrlTokenMutation['accountCreateMagicURLToken'], - AppwriteException[], - CreateMagicUrlTokenMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().magicUrl().create(), mutationFn: async ({ userId, email, url, phrase }) => { const { data, errors } = await graphql.mutation({ query: createMagicURLToken, diff --git a/src/account/useCreateMfaAuthenticator.ts b/src/account/useCreateMfaAuthenticator.ts index 998657a..11dfe6b 100644 --- a/src/account/useCreateMfaAuthenticator.ts +++ b/src/account/useCreateMfaAuthenticator.ts @@ -1,9 +1,8 @@ -import { gql } from '../__generated__' -import { - CreateMfaAuthenticatorMutation, - CreateMfaAuthenticatorMutationVariables, -} from '../__generated__/graphql' -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' + +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -17,15 +16,15 @@ const accountCreateMfaAuthenticator = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountCreateMfaAuthenticator'] + export function useCreateMfaAuthenticator() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - CreateMfaAuthenticatorMutation['accountCreateMfaAuthenticator'], - AppwriteException[], - CreateMfaAuthenticatorMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().mfaAuthenticator().create(), mutationFn: async ({ type = 'totp' }) => { const { data, errors } = await graphql.mutation({ query: accountCreateMfaAuthenticator, @@ -41,7 +40,7 @@ export function useCreateMfaAuthenticator() { return data.accountCreateMfaAuthenticator }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account', 'mfa', 'factors'] }) + void queryClient.invalidateQueries({ queryKey: Keys.account().mfaAuthenticator().key() }) }, }) diff --git a/src/account/useCreateMfaChallenge.ts b/src/account/useCreateMfaChallenge.ts index 9f7df4d..d781c3e 100644 --- a/src/account/useCreateMfaChallenge.ts +++ b/src/account/useCreateMfaChallenge.ts @@ -1,27 +1,29 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { CreateMfaChallengeMutation } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' const accountCreateMfaChallenge = gql(/* GraphQL */ ` mutation CreateMfaChallenge($factor: String!) { accountCreateMfaChallenge(factor: $factor) { + _id userId expire } } `) +type Variables = VariablesOf +type Result = ResultOf['accountCreateMfaChallenge'] + export function useCreateMfaChallenge() { const { graphql } = useAppwrite() - const queryResult = useMutation< - CreateMfaChallengeMutation['accountCreateMfaChallenge'], - AppwriteException[], - { factor: 'email' | 'phone' | 'totp' | 'recoveryCode' } - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().mfaChallenge().create(), mutationFn: async ({ factor }) => { const { data, errors } = await graphql.mutation({ query: accountCreateMfaChallenge, diff --git a/src/account/useCreateMfaRecoveryCodes.ts b/src/account/useCreateMfaRecoveryCodes.ts index 866a80d..ec07508 100644 --- a/src/account/useCreateMfaRecoveryCodes.ts +++ b/src/account/useCreateMfaRecoveryCodes.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { CreateMfaRecoveryCodesMutation } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -14,14 +15,14 @@ const accountCreateMfaRecoveryCodes = gql(/* GraphQL */ ` } `) +type Result = ResultOf['accountCreateMfaRecoveryCodes'] + export function useCreateMfaRecoveryCodes() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - CreateMfaRecoveryCodesMutation['accountCreateMfaRecoveryCodes'], - AppwriteException[] - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().mfaCodes().create(), mutationFn: async () => { const { data, errors } = await graphql.mutation({ query: accountCreateMfaRecoveryCodes, @@ -34,7 +35,9 @@ export function useCreateMfaRecoveryCodes() { return data.accountCreateMfaRecoveryCodes }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account', 'mfa', 'recovery-codes'] }) + void queryClient.invalidateQueries({ + queryKey: Keys.account().mfaCodes().key(), + }) }, }) diff --git a/src/account/useCreateOAuth2Token.ts b/src/account/useCreateOAuth2Token.ts index b16e09d..1467f0b 100644 --- a/src/account/useCreateOAuth2Token.ts +++ b/src/account/useCreateOAuth2Token.ts @@ -1,4 +1,5 @@ -import { AppwriteException, OAuthProvider } from '../types' +import { Keys } from '../query/Keys' +import type { AppwriteException, OAuthProvider } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' @@ -13,6 +14,7 @@ export function useCreateOAuth2Token() { const { account } = useAppwrite() const queryResult = useMutation({ + mutationKey: Keys.account().oauth2Token().create(), mutationFn: async ({ provider, success, failure, scopes }) => { return account.createOAuth2Token({ provider, success, failure, scopes }) }, diff --git a/src/account/useCreatePhoneToken.ts b/src/account/useCreatePhoneToken.ts index 1ccce84..2d6ca50 100644 --- a/src/account/useCreatePhoneToken.ts +++ b/src/account/useCreatePhoneToken.ts @@ -1,10 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { - CreatePhoneTokenMutation, - CreatePhoneTokenMutationVariables, -} from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' @@ -16,14 +14,14 @@ const createPhoneToken = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountCreatePhoneToken'] + export function useCreatePhoneToken() { const { graphql } = useAppwrite() - const queryResult = useMutation< - CreatePhoneTokenMutation['accountCreatePhoneToken'], - AppwriteException[], - CreatePhoneTokenMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().phoneToken().create(), mutationFn: async ({ userId, phone }) => { const { data, errors } = await graphql.mutation({ query: createPhoneToken, diff --git a/src/account/useCreatePhoneVerification.ts b/src/account/useCreatePhoneVerification.ts index 3a6a442..1ae1d9f 100644 --- a/src/account/useCreatePhoneVerification.ts +++ b/src/account/useCreatePhoneVerification.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { CreatePhoneVerificationMutation } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' @@ -13,13 +14,13 @@ const createPhoneVerification = gql(/* GraphQL */ ` } `) +type Result = ResultOf['accountCreatePhoneVerification'] + export function useCreatePhoneVerification() { const { graphql } = useAppwrite() - const queryResult = useMutation< - CreatePhoneVerificationMutation['accountCreatePhoneVerification'], - AppwriteException[] - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().phoneVerification().create(), mutationFn: async () => { const { data, errors } = await graphql.mutation({ query: createPhoneVerification, diff --git a/src/account/useCreatePushTarget.ts b/src/account/useCreatePushTarget.ts index 27f768f..83d6933 100644 --- a/src/account/useCreatePushTarget.ts +++ b/src/account/useCreatePushTarget.ts @@ -1,10 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { - CreatePushTargetMutation, - CreatePushTargetMutationVariables, -} from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -20,15 +18,15 @@ const accountCreatePushTarget = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountCreatePushTarget'] + export function useCreatePushTarget() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - CreatePushTargetMutation['accountCreatePushTarget'], - AppwriteException[], - CreatePushTargetMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().pushTarget().create(), mutationFn: async ({ targetId, identifier, providerId }) => { const { data, errors } = await graphql.mutation({ query: accountCreatePushTarget, @@ -46,7 +44,7 @@ export function useCreatePushTarget() { return data.accountCreatePushTarget }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account'] }) + void queryClient.invalidateQueries({ queryKey: Keys.account().key() }) }, }) diff --git a/src/account/useCreateSession.ts b/src/account/useCreateSession.ts index 24f8f06..356b647 100644 --- a/src/account/useCreateSession.ts +++ b/src/account/useCreateSession.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { CreateSessionMutation, CreateSessionMutationVariables } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -16,15 +17,15 @@ const createSession = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountCreateSession'] + export function useCreateSession() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - CreateSessionMutation['accountCreateSession'], - AppwriteException[], - CreateSessionMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().session().create(), mutationFn: async ({ userId, secret }) => { const { data, errors } = await graphql.mutation({ query: createSession, @@ -41,8 +42,8 @@ export function useCreateSession() { return data.accountCreateSession }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account'] }) - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account', 'sessions'] }) + void queryClient.invalidateQueries({ queryKey: Keys.account().key() }) + void queryClient.invalidateQueries({ queryKey: Keys.account().sessions() }) }, }) diff --git a/src/account/useDeleteAccount.ts b/src/account/useDeleteAccount.ts deleted file mode 100644 index 36a2b55..0000000 --- a/src/account/useDeleteAccount.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { AppwriteException } from '../types' - -import { gql } from '../__generated__' -import { DeleteAccountMutation } from '../__generated__/graphql' -import { useAppwrite } from '../useAppwrite' -import { useMutation } from '../useMutation' -import { useQueryClient } from '../useQueryClient' - -const accountDelete = gql(/* GraphQL */ ` - mutation DeleteAccount { - accountDelete { - status - } - } -`) - -export function useDeleteAccount() { - const { graphql } = useAppwrite() - const queryClient = useQueryClient() - - const queryResult = useMutation< - DeleteAccountMutation['accountDelete'], - AppwriteException[], - void - >({ - mutationFn: async () => { - const { data, errors } = await graphql.mutation({ - query: accountDelete, - }) - - if (errors) { - throw errors - } - - return data?.accountDelete ?? { status: true } - }, - onSuccess: () => { - queryClient.clear() - }, - }) - - return { ...queryResult } -} diff --git a/src/account/useDeleteIdentity.ts b/src/account/useDeleteIdentity.ts index 086c593..f18c86f 100644 --- a/src/account/useDeleteIdentity.ts +++ b/src/account/useDeleteIdentity.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { DeleteIdentityMutation, DeleteIdentityMutationVariables } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -14,15 +15,15 @@ const accountDeleteIdentity = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountDeleteIdentity'] + export function useDeleteIdentity() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - DeleteIdentityMutation['accountDeleteIdentity'], - AppwriteException[], - DeleteIdentityMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().identity().delete(), mutationFn: async ({ identityId }) => { const { data, errors } = await graphql.mutation({ query: accountDeleteIdentity, @@ -35,10 +36,10 @@ export function useDeleteIdentity() { throw errors } - return data?.accountDeleteIdentity ?? { status: true } + return data?.accountDeleteIdentity ?? { status: '' } }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account'] }) + void queryClient.invalidateQueries({ queryKey: Keys.account().key() }) }, }) diff --git a/src/account/useDeleteMfaAuthenticator.ts b/src/account/useDeleteMfaAuthenticator.ts index 9f095de..c7217f4 100644 --- a/src/account/useDeleteMfaAuthenticator.ts +++ b/src/account/useDeleteMfaAuthenticator.ts @@ -1,10 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { - DeleteMfaAuthenticatorMutation, - DeleteMfaAuthenticatorMutationVariables, -} from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -17,15 +15,15 @@ const deleteMFAAuthenticator = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountDeleteMfaAuthenticator'] + export function useDeleteMfaAuthenticator() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - DeleteMfaAuthenticatorMutation['accountDeleteMfaAuthenticator'], - AppwriteException[], - DeleteMfaAuthenticatorMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().mfaAuthenticator().delete(), mutationFn: async ({ type = 'totp' }) => { const { data, errors } = await graphql.mutation({ query: deleteMFAAuthenticator, @@ -38,11 +36,13 @@ export function useDeleteMfaAuthenticator() { throw errors } - return data?.accountDeleteMfaAuthenticator ?? { status: true } + return data?.accountDeleteMfaAuthenticator ?? { status: '' } }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account'] }) - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account', 'mfa', 'factors'] }) + void queryClient.invalidateQueries({ queryKey: Keys.account().key() }) + void queryClient.invalidateQueries({ + queryKey: Keys.account().mfaAuthenticator().key(), + }) }, }) diff --git a/src/account/useDeletePushTarget.ts b/src/account/useDeletePushTarget.ts index 678cac8..20cd0c9 100644 --- a/src/account/useDeletePushTarget.ts +++ b/src/account/useDeletePushTarget.ts @@ -1,10 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { - DeletePushTargetMutation, - DeletePushTargetMutationVariables, -} from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -17,15 +15,15 @@ const accountDeletePushTarget = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountDeletePushTarget'] + export function useDeletePushTarget() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - DeletePushTargetMutation['accountDeletePushTarget'], - AppwriteException[], - DeletePushTargetMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().pushTarget().delete(), mutationFn: async ({ targetId }) => { const { data, errors } = await graphql.mutation({ query: accountDeletePushTarget, @@ -38,10 +36,10 @@ export function useDeletePushTarget() { throw errors } - return data.accountDeletePushTarget + return data?.accountDeletePushTarget ?? { status: '' } }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account'] }) + void queryClient.invalidateQueries({ queryKey: Keys.account().key() }) }, }) diff --git a/src/account/useDeleteSession.ts b/src/account/useDeleteSession.ts index aa0d3ed..915265a 100644 --- a/src/account/useDeleteSession.ts +++ b/src/account/useDeleteSession.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { DeleteSessionMutation, DeleteSessionMutationVariables } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -14,15 +15,15 @@ const deleteSession = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountDeleteSession'] + export function useDeleteSession() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - DeleteSessionMutation['accountDeleteSession'], - AppwriteException[], - DeleteSessionMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().session().delete(), mutationFn: async ({ sessionId }) => { const { data, errors } = await graphql.mutation({ query: deleteSession, @@ -35,10 +36,10 @@ export function useDeleteSession() { throw errors } - return data?.accountDeleteSession ?? { status: true } + return data?.accountDeleteSession ?? { status: '' } }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account', 'sessions'] }) + void queryClient.invalidateQueries({ queryKey: Keys.account().sessions() }) }, }) diff --git a/src/account/useDeleteSessions.ts b/src/account/useDeleteSessions.ts index 24a45d6..971f14e 100644 --- a/src/account/useDeleteSessions.ts +++ b/src/account/useDeleteSessions.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { DeleteSessionsMutation } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -14,14 +15,14 @@ const deleteSessions = gql(/* GraphQL */ ` } `) +type Result = ResultOf['accountDeleteSessions'] + export function useDeleteSessions() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - DeleteSessionsMutation['accountDeleteSessions'], - AppwriteException[] - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().session().delete(), mutationFn: async () => { const { data, errors } = await graphql.mutation({ query: deleteSessions, @@ -31,11 +32,12 @@ export function useDeleteSessions() { throw errors } - return data?.accountDeleteSessions ?? { status: true } + return data?.accountDeleteSessions ?? { status: '' } }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account'] }) - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account', 'sessions'] }) + void queryClient.invalidateQueries({ queryKey: Keys.account().key() }) + void queryClient.invalidateQueries({ queryKey: Keys.account().sessions() }) + queryClient.clear() }, }) diff --git a/src/account/useGetMfaRecoveryCodes.ts b/src/account/useGetMfaRecoveryCodes.ts index 2ae1962..da91d47 100644 --- a/src/account/useGetMfaRecoveryCodes.ts +++ b/src/account/useGetMfaRecoveryCodes.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { GetMfaRecoveryCodesQuery } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException, QueryOptions } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' @@ -13,15 +14,13 @@ const getMFARecoveryCodes = gql(/* GraphQL */ ` } `) -export function useGetMfaRecoveryCodes() { +type Result = ResultOf['accountGetMfaRecoveryCodes'] + +export function useGetMfaRecoveryCodes(opts: QueryOptions = {}) { const { graphql } = useAppwrite() - const queryResult = useQuery< - GetMfaRecoveryCodesQuery['accountGetMfaRecoveryCodes'], - AppwriteException[], - GetMfaRecoveryCodesQuery['accountGetMfaRecoveryCodes'] - >({ - queryKey: ['appwrite', 'account', 'mfa', 'recovery-codes'], + const queryResult = useQuery({ + queryKey: Keys.account().mfaCodes().key(), queryFn: async () => { const { data, errors } = await graphql.query({ query: getMFARecoveryCodes, @@ -33,6 +32,7 @@ export function useGetMfaRecoveryCodes() { return data.accountGetMfaRecoveryCodes }, + ...opts, }) return { ...queryResult } diff --git a/src/account/useGetPrefs.ts b/src/account/useGetPrefs.ts index 2ded4c8..4f9dd47 100644 --- a/src/account/useGetPrefs.ts +++ b/src/account/useGetPrefs.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { GetPrefsQuery } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException, QueryOptions } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' @@ -13,15 +14,13 @@ const accountGetPrefs = gql(/* GraphQL */ ` } `) -export function useGetPrefs() { +type Result = ResultOf['accountGetPrefs'] + +export function useGetPrefs(opts: QueryOptions = {}) { const { graphql } = useAppwrite() - const queryResult = useQuery< - GetPrefsQuery['accountGetPrefs'], - AppwriteException[], - GetPrefsQuery['accountGetPrefs'] - >({ - queryKey: ['appwrite', 'account', 'prefs'], + const queryResult = useQuery({ + queryKey: Keys.account().prefs().key(), queryFn: async () => { const { data, errors } = await graphql.query({ query: accountGetPrefs, @@ -33,6 +32,7 @@ export function useGetPrefs() { return data.accountGetPrefs }, + ...opts, }) return { ...queryResult } diff --git a/src/account/useGetSession.ts b/src/account/useGetSession.ts index bec17cc..e34635f 100644 --- a/src/account/useGetSession.ts +++ b/src/account/useGetSession.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { GetSessionQuery, GetSessionQueryVariables } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException, QueryOptions } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' @@ -15,15 +16,14 @@ const getSession = gql(/* GraphQL */ ` } `) -export function useGetSession({ sessionId }: GetSessionQueryVariables) { +type Variables = VariablesOf +type Result = ResultOf['accountGetSession'] + +export function useGetSession({ sessionId }: Variables, opts: QueryOptions = {}) { const { graphql } = useAppwrite() - const queryResult = useQuery< - GetSessionQuery['accountGetSession'], - AppwriteException[], - GetSessionQueryVariables - >({ - queryKey: ['appwrite', 'account', 'sessions', sessionId], + const queryResult = useQuery({ + queryKey: Keys.account().session(sessionId).key(), queryFn: async () => { const { data, errors } = await graphql.query({ query: getSession, @@ -36,6 +36,7 @@ export function useGetSession({ sessionId }: GetSessionQueryVariables) { return data.accountGetSession }, + ...opts, }) return queryResult diff --git a/src/account/useListIdentities.ts b/src/account/useListIdentities.ts index 764ac00..1340b3f 100644 --- a/src/account/useListIdentities.ts +++ b/src/account/useListIdentities.ts @@ -1,30 +1,31 @@ -import { AppwriteException } from '../types' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' +import { Keys } from '../query/Keys' +import type { AppwriteException, QueryOptions } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' -import { ListIdentitiesQuery } from '../__generated__/graphql' const accountListIdentities = gql(/* GraphQL */ ` query ListIdentities { accountListIdentities { total identities { - ...Identity_Provider + _id + userId + provider } } } `) -export function useListIdentities() { +type Result = ResultOf['accountListIdentities'] + +export function useListIdentities(opts: QueryOptions = {}) { const { graphql } = useAppwrite() - const queryResult = useQuery< - ListIdentitiesQuery['accountListIdentities'], - AppwriteException[], - ListIdentitiesQuery['accountListIdentities'] - >({ - queryKey: ['appwrite', 'account', 'identities'], + const queryResult = useQuery({ + queryKey: Keys.account().identities(), queryFn: async () => { const { data, errors } = await graphql.query({ query: accountListIdentities, @@ -36,6 +37,7 @@ export function useListIdentities() { return data.accountListIdentities }, + ...opts, }) return { ...queryResult } diff --git a/src/account/useListMfaFactors.ts b/src/account/useListMfaFactors.ts index ae1dbdc..dc8db70 100644 --- a/src/account/useListMfaFactors.ts +++ b/src/account/useListMfaFactors.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { ListMfaFactorsQuery } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException, QueryOptions } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' @@ -15,15 +16,13 @@ const listMFAFactors = gql(/* GraphQL */ ` } `) -export function useListMfaFactors() { +type Result = ResultOf['accountListMfaFactors'] + +export function useListMfaFactors(opts: QueryOptions = {}) { const { graphql } = useAppwrite() - const queryResult = useQuery< - ListMfaFactorsQuery['accountListMfaFactors'], - AppwriteException[], - ListMfaFactorsQuery['accountListMfaFactors'] - >({ - queryKey: ['appwrite', 'account', 'mfa', 'factors'], + const queryResult = useQuery({ + queryKey: Keys.account().mfaFactors(), queryFn: async () => { const { data, errors } = await graphql.query({ query: listMFAFactors, @@ -35,6 +34,7 @@ export function useListMfaFactors() { return data.accountListMfaFactors }, + ...opts, }) return { ...queryResult } diff --git a/src/account/useListSessions.ts b/src/account/useListSessions.ts index 4a05159..d2b04d4 100644 --- a/src/account/useListSessions.ts +++ b/src/account/useListSessions.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { ListSessionsQuery } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException, QueryOptions } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' @@ -18,15 +19,13 @@ const accountListSessions = gql(/* GraphQL */ ` } `) -export function useListSessions() { +type Result = ResultOf['accountListSessions'] + +export function useListSessions(opts: QueryOptions = {}) { const { graphql } = useAppwrite() - const queryResult = useQuery< - ListSessionsQuery['accountListSessions'], - AppwriteException[], - ListSessionsQuery['accountListSessions'] - >({ - queryKey: ['appwrite', 'account', 'sessions'], + const queryResult = useQuery({ + queryKey: Keys.account().sessions(), queryFn: async () => { const { data, errors } = await graphql.query({ query: accountListSessions, @@ -38,6 +37,7 @@ export function useListSessions() { return data.accountListSessions }, + ...opts, }) return { ...queryResult } diff --git a/src/account/useLogin.ts b/src/account/useLogin.ts index 700f86d..5751c7c 100644 --- a/src/account/useLogin.ts +++ b/src/account/useLogin.ts @@ -1,9 +1,8 @@ -import { gql } from '../__generated__/gql' -import { - CreateEmailPasswordSessionMutation, - CreateEmailPasswordSessionMutationVariables, -} from '../__generated__/graphql' -import { AppwriteException, OAuthProvider } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' + +import { Keys } from '../query/Keys' +import type { AppwriteException, OAuthProvider } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -24,15 +23,17 @@ const accountCreateEmailPasswordSession = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf< + typeof accountCreateEmailPasswordSession +>['accountCreateEmailPasswordSession'] + export function useLogin() { const { account, graphql } = useAppwrite() const queryClient = useQueryClient() - const login = useMutation< - CreateEmailPasswordSessionMutation['accountCreateEmailPasswordSession'], - AppwriteException[], - CreateEmailPasswordSessionMutationVariables - >({ + const login = useMutation({ + mutationKey: Keys.account().login().create(), mutationFn: async ({ email, password }) => { const { data, errors } = await graphql.mutation({ query: accountCreateEmailPasswordSession, @@ -49,8 +50,8 @@ export function useLogin() { return data.accountCreateEmailPasswordSession }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account'] }) - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account', 'sessions'] }) + void queryClient.invalidateQueries({ queryKey: Keys.account().key() }) + void queryClient.invalidateQueries({ queryKey: Keys.account().sessions() }) }, }) diff --git a/src/account/useLogout.ts b/src/account/useLogout.ts index 21388bf..c48e6a8 100644 --- a/src/account/useLogout.ts +++ b/src/account/useLogout.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { DeleteSessionMutation, DeleteSessionMutationVariables } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -14,15 +15,15 @@ const deleteSession = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountDeleteSession'] + export function useLogout() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - DeleteSessionMutation['accountDeleteSession'], - AppwriteException[], - DeleteSessionMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().session().delete(), mutationFn: async ({ sessionId }) => { const { data, errors } = await graphql.mutation({ query: deleteSession, @@ -35,7 +36,7 @@ export function useLogout() { throw errors } - return data?.accountDeleteSession ?? { status: true } + return data?.accountDeleteSession ?? { status: '' } }, onSuccess: async () => { queryClient.clear() diff --git a/src/account/useLogs.ts b/src/account/useLogs.ts index 700869f..1b2f928 100644 --- a/src/account/useLogs.ts +++ b/src/account/useLogs.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { ListLogsQuery, ListLogsQueryVariables } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException, QueryOptions } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' @@ -36,15 +37,14 @@ const accountListLogs = gql(/* GraphQL */ ` } `) -export function useLogs({ queries }: ListLogsQueryVariables) { +type Variables = VariablesOf +type Result = ResultOf['accountListLogs'] + +export function useLogs({ queries }: Variables, opts: QueryOptions = {}) { const { graphql } = useAppwrite() - const queryResult = useQuery< - ListLogsQuery['accountListLogs'], - AppwriteException[], - ListLogsQuery['accountListLogs'] - >({ - queryKey: ['appwrite', 'account', 'logs', queries], + const queryResult = useQuery({ + queryKey: [...Keys.account().logs().key(), ...(queries ?? [])], queryFn: async () => { const { data, errors } = await graphql.query({ query: accountListLogs, @@ -59,6 +59,7 @@ export function useLogs({ queries }: ListLogsQueryVariables) { return data.accountListLogs }, + ...opts, }) return { ...queryResult } diff --git a/src/account/usePasswordRecovery.ts b/src/account/usePasswordRecovery.ts index ab646fc..b6bf607 100644 --- a/src/account/usePasswordRecovery.ts +++ b/src/account/usePasswordRecovery.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { CreateRecoveryMutation, CreateRecoveryMutationVariables } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' @@ -13,17 +14,17 @@ const createRecovery = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountCreateRecovery'] + /** * Send the recovery email to the address supplied */ export function usePasswordRecovery() { const { graphql } = useAppwrite() - const queryResult = useMutation< - CreateRecoveryMutation['accountCreateRecovery'], - AppwriteException[], - CreateRecoveryMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().recovery().create(), mutationFn: async ({ email, url: resetUrl }) => { const { data, errors } = await graphql.mutation({ query: createRecovery, @@ -42,9 +43,10 @@ export function usePasswordRecovery() { onSuccess: async (_, variables) => { try { localStorage?.setItem('email', variables.email) - } catch (e) { + } catch (e: any) { console.error( 'Could not save email to local storage. If you are using react-native, this is expected.', + e, ) } }, diff --git a/src/account/useResetPassword.ts b/src/account/useResetPassword.ts index 035b3af..53bc08a 100644 --- a/src/account/useResetPassword.ts +++ b/src/account/useResetPassword.ts @@ -1,11 +1,8 @@ -import { AppwriteException } from '../types' - -import { gql } from '../__generated__' -import { - Token, - UpdateRecoveryMutation, - UpdateRecoveryMutationVariables, -} from '../__generated__/graphql' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' + +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' @@ -17,14 +14,14 @@ const updateRecovery = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountUpdateRecovery'] + export function useResetPassword() { const { graphql } = useAppwrite() - const queryResult = useMutation< - UpdateRecoveryMutation['accountUpdateRecovery'], - AppwriteException[], - UpdateRecoveryMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().recovery().update(), mutationFn: async ({ userId, secret, password }) => { const { data, errors } = await graphql.mutation({ query: updateRecovery, @@ -39,7 +36,7 @@ export function useResetPassword() { throw errors } - return data.accountUpdateRecovery ?? ({} as Token) + return data.accountUpdateRecovery }, }) diff --git a/src/account/useSignUp.ts b/src/account/useSignUp.ts index f4016b4..7b63028 100644 --- a/src/account/useSignUp.ts +++ b/src/account/useSignUp.ts @@ -1,18 +1,12 @@ -import { AppwriteException, ID } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { - CreateAccountMutation, - CreateAccountMutationVariables, - VerifyEmailMutation, -} from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' +import { ID } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' -type VerifyProps = { - verifyUrl: string -} - const createAccount = gql(/* GraphQL */ ` mutation CreateAccount($userId: String!, $name: String, $email: String!, $password: String!) { accountCreate(userId: $userId, name: $name, email: $email, password: $password) { @@ -30,14 +24,19 @@ const verify = gql(/* GraphQL */ ` } `) +type CreateVariables = VariablesOf +type CreateResult = ResultOf['accountCreate'] + +type VerifyProps = { + verifyUrl: string +} +type VerifyResult = ResultOf['accountCreateVerification'] + export function useSignUp() { const { graphql } = useAppwrite() - const signUp = useMutation< - CreateAccountMutation['accountCreate'], - AppwriteException[], - CreateAccountMutationVariables - >({ + const signUp = useMutation({ + mutationKey: Keys.account().signUp().create(), mutationFn: async ({ userId, email, password, name }) => { const { data, errors } = await graphql.mutation({ query: createAccount, @@ -57,11 +56,8 @@ export function useSignUp() { }, }) - const verifyEmail = useMutation< - VerifyEmailMutation['accountCreateVerification'], - Error, - VerifyProps - >({ + const verifyEmail = useMutation({ + mutationKey: Keys.account().emailVerification().create(), mutationFn: async ({ verifyUrl }) => { const { data, errors } = await graphql.mutation({ query: verify, diff --git a/src/account/useUpdateEmail.ts b/src/account/useUpdateEmail.ts index 387e6ac..607449d 100644 --- a/src/account/useUpdateEmail.ts +++ b/src/account/useUpdateEmail.ts @@ -1,12 +1,13 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { UpdateEmailMutation, UpdateEmailMutationVariables } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' -const accountUpdateEmail = gql(/* GraphQL */ ` +export const accountUpdateEmail = gql(/* GraphQL */ ` mutation UpdateEmail($email: String!, $password: String!) { accountUpdateEmail(email: $email, password: $password) { name @@ -15,15 +16,15 @@ const accountUpdateEmail = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountUpdateEmail'] + export function useUpdateEmail() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - UpdateEmailMutation['accountUpdateEmail'], - AppwriteException[], - UpdateEmailMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().email().update(), mutationFn: async ({ email, password }) => { const { data, errors } = await graphql.mutation({ query: accountUpdateEmail, @@ -40,7 +41,7 @@ export function useUpdateEmail() { return data.accountUpdateEmail }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account'] }) + void queryClient.invalidateQueries({ queryKey: Keys.account().key() }) }, }) diff --git a/src/account/useUpdateEmailVerification.ts b/src/account/useUpdateEmailVerification.ts index 7cb21e1..0399cdd 100644 --- a/src/account/useUpdateEmailVerification.ts +++ b/src/account/useUpdateEmailVerification.ts @@ -1,10 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { - UpdateEmailVerificationMutation, - UpdateEmailVerificationMutationVariables, -} from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -20,15 +18,15 @@ const updateEmailVerification = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountUpdateEmailVerification'] + export function useUpdateEmailVerification() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - UpdateEmailVerificationMutation['accountUpdateEmailVerification'], - AppwriteException[], - UpdateEmailVerificationMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().emailVerification().update(), mutationFn: async ({ userId, secret }) => { const { data, errors } = await graphql.mutation({ query: updateEmailVerification, @@ -42,7 +40,7 @@ export function useUpdateEmailVerification() { return data.accountUpdateEmailVerification }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account'] }) + void queryClient.invalidateQueries({ queryKey: Keys.account().key() }) }, }) diff --git a/src/account/useUpdateMagicURLSession.ts b/src/account/useUpdateMagicURLSession.ts index 02f8da5..ff78209 100644 --- a/src/account/useUpdateMagicURLSession.ts +++ b/src/account/useUpdateMagicURLSession.ts @@ -1,10 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { - UpdateMagicUrlSessionMutation, - UpdateMagicUrlSessionMutationVariables, -} from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -19,15 +17,15 @@ const updateMagicURLSession = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountUpdateMagicURLSession'] + export function useUpdateMagicURLSession() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - UpdateMagicUrlSessionMutation['accountUpdateMagicURLSession'], - AppwriteException[], - UpdateMagicUrlSessionMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().magicUrl().update(), mutationFn: async ({ userId, secret }) => { const { data, errors } = await graphql.mutation({ query: updateMagicURLSession, @@ -44,8 +42,8 @@ export function useUpdateMagicURLSession() { return data.accountUpdateMagicURLSession }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account'] }) - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account', 'sessions'] }) + void queryClient.invalidateQueries({ queryKey: Keys.account().key() }) + void queryClient.invalidateQueries({ queryKey: Keys.account().sessions() }) }, }) diff --git a/src/account/useUpdateMfa.ts b/src/account/useUpdateMfa.ts index d0d7efd..8e0c4bc 100644 --- a/src/account/useUpdateMfa.ts +++ b/src/account/useUpdateMfa.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { UpdateMfaMutation, UpdateMfaMutationVariables } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -14,15 +15,15 @@ const accountUpdateMFA = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountUpdateMFA'] + export function useUpdateMfa() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - UpdateMfaMutation['accountUpdateMFA'], - AppwriteException[], - UpdateMfaMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().mfa().update(), mutationFn: async ({ mfa }) => { const { data, errors } = await graphql.mutation({ query: accountUpdateMFA, @@ -38,8 +39,8 @@ export function useUpdateMfa() { return data.accountUpdateMFA }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account'] }) - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account', 'mfa'] }) + void queryClient.invalidateQueries({ queryKey: Keys.account().key() }) + void queryClient.invalidateQueries({ queryKey: Keys.account().mfaFactors() }) }, }) diff --git a/src/account/useUpdateMfaAuthenticator.ts b/src/account/useUpdateMfaAuthenticator.ts index a5fd6e6..46bcdb8 100644 --- a/src/account/useUpdateMfaAuthenticator.ts +++ b/src/account/useUpdateMfaAuthenticator.ts @@ -1,10 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { - UpdateMfaAuthenticatorMutation, - UpdateMfaAuthenticatorMutationVariables, -} from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -17,15 +15,15 @@ const updateMFAAuthenticator = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountUpdateMfaAuthenticator'] + export function useUpdateMfaAuthenticator() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - UpdateMfaAuthenticatorMutation['accountUpdateMfaAuthenticator'], - AppwriteException[], - UpdateMfaAuthenticatorMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().mfaAuthenticator().update(), mutationFn: async ({ type = 'totp', otp }) => { const { data, errors } = await graphql.mutation({ query: updateMFAAuthenticator, @@ -42,8 +40,8 @@ export function useUpdateMfaAuthenticator() { return data.accountUpdateMfaAuthenticator }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account'] }) - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account', 'mfa', 'factors'] }) + void queryClient.invalidateQueries({ queryKey: Keys.account().key() }) + void queryClient.invalidateQueries({ queryKey: Keys.account().mfaFactors() }) }, }) diff --git a/src/account/useUpdateMfaChallenge.ts b/src/account/useUpdateMfaChallenge.ts index 7676ea8..f19b604 100644 --- a/src/account/useUpdateMfaChallenge.ts +++ b/src/account/useUpdateMfaChallenge.ts @@ -1,29 +1,30 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { - UpdateMfaChallengeMutation, - UpdateMfaChallengeMutationVariables, -} from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' const accountUpdateMfaChallenge = gql(/* GraphQL */ ` mutation UpdateMfaChallenge($challengeId: String!, $otp: String!) { accountUpdateMfaChallenge(challengeId: $challengeId, otp: $otp) { - status + _id + userId + expire + current } } `) +type Variables = VariablesOf +type Result = ResultOf['accountUpdateMfaChallenge'] + export function useUpdateMfaChallenge() { const { graphql } = useAppwrite() - const queryResult = useMutation< - UpdateMfaChallengeMutation['accountUpdateMfaChallenge'], - AppwriteException[], - UpdateMfaChallengeMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().mfaChallenge().update(), mutationFn: async ({ challengeId, otp }) => { const { data, errors } = await graphql.mutation({ query: accountUpdateMfaChallenge, @@ -37,7 +38,7 @@ export function useUpdateMfaChallenge() { throw errors } - return data?.accountUpdateMfaChallenge ?? { status: false } + return data?.accountUpdateMfaChallenge ?? null }, }) diff --git a/src/account/useUpdateMfaRecoveryCodes.ts b/src/account/useUpdateMfaRecoveryCodes.ts index 4ced382..111cc45 100644 --- a/src/account/useUpdateMfaRecoveryCodes.ts +++ b/src/account/useUpdateMfaRecoveryCodes.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { UpdateMfaRecoveryCodesMutation } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -14,14 +15,14 @@ const accountUpdateMfaRecoveryCodes = gql(/* GraphQL */ ` } `) +type Result = ResultOf['accountUpdateMfaRecoveryCodes'] + export function useUpdateMfaRecoveryCodes() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - UpdateMfaRecoveryCodesMutation['accountUpdateMfaRecoveryCodes'], - AppwriteException[] - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().mfaCodes().update(), mutationFn: async () => { const { data, errors } = await graphql.mutation({ query: accountUpdateMfaRecoveryCodes, @@ -34,7 +35,9 @@ export function useUpdateMfaRecoveryCodes() { return data.accountUpdateMfaRecoveryCodes }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account', 'mfa', 'recovery-codes'] }) + void queryClient.invalidateQueries({ + queryKey: Keys.account().mfaCodes().key(), + }) }, }) diff --git a/src/account/useUpdateName.ts b/src/account/useUpdateName.ts index 0fd4636..8b9939d 100644 --- a/src/account/useUpdateName.ts +++ b/src/account/useUpdateName.ts @@ -1,11 +1,13 @@ -import { gql } from '../__generated__' -import { UpdateNameMutation, UpdateNameMutationVariables, User } from '../__generated__/graphql' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' + +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' -import { AppwriteException } from '../types' -const accountUpdateName = gql(/* GraphQL */ ` +export const accountUpdateName = gql(/* GraphQL */ ` mutation UpdateName($name: String!) { accountUpdateName(name: $name) { name @@ -13,15 +15,15 @@ const accountUpdateName = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountUpdateName'] + export function useUpdateName() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - UpdateNameMutation['accountUpdateName'], - AppwriteException[], - UpdateNameMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().name().update(), mutationFn: async ({ name }) => { const { data: mutationData, errors } = await graphql.mutation({ query: accountUpdateName, @@ -37,7 +39,7 @@ export function useUpdateName() { return mutationData.accountUpdateName }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account'] }) + void queryClient.invalidateQueries({ queryKey: Keys.account().key() }) }, }) diff --git a/src/account/useUpdatePassword.ts b/src/account/useUpdatePassword.ts index f6cf881..cc3f90a 100644 --- a/src/account/useUpdatePassword.ts +++ b/src/account/useUpdatePassword.ts @@ -1,12 +1,13 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { UpdatePasswordMutation, UpdatePasswordMutationVariables } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' -const updatePassword = gql(/* GraphQL */ ` +export const updatePassword = gql(/* GraphQL */ ` mutation UpdatePassword($password: String!, $oldPassword: String!) { accountUpdatePassword(password: $password, oldPassword: $oldPassword) { status @@ -14,15 +15,15 @@ const updatePassword = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountUpdatePassword'] + export function useUpdatePassword() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - UpdatePasswordMutation['accountUpdatePassword'], - AppwriteException[], - UpdatePasswordMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().password().update(), mutationFn: async ({ password, oldPassword }) => { const { data, errors } = await graphql.mutation({ query: updatePassword, @@ -39,7 +40,7 @@ export function useUpdatePassword() { return data?.accountUpdatePassword }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account'] }) + void queryClient.invalidateQueries({ queryKey: Keys.account().key() }) }, }) diff --git a/src/account/useUpdatePhone.ts b/src/account/useUpdatePhone.ts index 971a3d3..a9199eb 100644 --- a/src/account/useUpdatePhone.ts +++ b/src/account/useUpdatePhone.ts @@ -1,11 +1,13 @@ -import { gql } from '../__generated__' -import { UpdatePhoneMutation, UpdatePhoneMutationVariables } from '../__generated__/graphql' -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' + +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' -const accountUpdatePhone = gql(/* GraphQL */ ` +export const accountUpdatePhone = gql(/* GraphQL */ ` mutation UpdatePhone($phone: String!, $password: String!) { accountUpdatePhone(phone: $phone, password: $password) { phone @@ -13,15 +15,15 @@ const accountUpdatePhone = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountUpdatePhone'] + export function useUpdatePhone() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - UpdatePhoneMutation['accountUpdatePhone'], - AppwriteException[], - UpdatePhoneMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().phone().update(), mutationFn: async ({ phone, password }) => { const { data, errors } = await graphql.mutation({ query: accountUpdatePhone, @@ -38,7 +40,7 @@ export function useUpdatePhone() { return data.accountUpdatePhone }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account'] }) + void queryClient.invalidateQueries({ queryKey: Keys.account().key() }) }, }) diff --git a/src/account/useUpdatePhoneSession.ts b/src/account/useUpdatePhoneSession.ts index 8fee251..ab5aa21 100644 --- a/src/account/useUpdatePhoneSession.ts +++ b/src/account/useUpdatePhoneSession.ts @@ -1,9 +1,8 @@ -import { gql } from '../__generated__' -import { - UpdatePhoneSessionMutation, - UpdatePhoneSessionMutationVariables, -} from '../__generated__/graphql' -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' + +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -18,15 +17,15 @@ const updatePhoneSession = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountUpdatePhoneSession'] + export function useUpdatePhoneSession() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - UpdatePhoneSessionMutation['accountUpdatePhoneSession'], - AppwriteException[], - UpdatePhoneSessionMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().phoneToken().update(), mutationFn: async ({ userId, secret }) => { const { data, errors } = await graphql.mutation({ query: updatePhoneSession, @@ -43,8 +42,8 @@ export function useUpdatePhoneSession() { return data.accountUpdatePhoneSession }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account'] }) - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account', 'sessions'] }) + void queryClient.invalidateQueries({ queryKey: Keys.account().key() }) + void queryClient.invalidateQueries({ queryKey: Keys.account().sessions() }) }, }) diff --git a/src/account/useUpdatePhoneVerification.ts b/src/account/useUpdatePhoneVerification.ts index 5ffe369..21c2606 100644 --- a/src/account/useUpdatePhoneVerification.ts +++ b/src/account/useUpdatePhoneVerification.ts @@ -1,10 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { - UpdatePhoneVerificationMutation, - UpdatePhoneVerificationMutationVariables, -} from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' @@ -16,14 +14,14 @@ const updatePhoneVerification = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountUpdatePhoneVerification'] + export function useUpdatePhoneVerification() { const { graphql } = useAppwrite() - const queryResult = useMutation< - UpdatePhoneVerificationMutation['accountUpdatePhoneVerification'], - AppwriteException[], - UpdatePhoneVerificationMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().phoneVerification().update(), mutationFn: async ({ userId, secret }) => { const { data, errors } = await graphql.mutation({ query: updatePhoneVerification, diff --git a/src/account/useUpdatePrefs.ts b/src/account/useUpdatePrefs.ts index edb7126..d0e411a 100644 --- a/src/account/useUpdatePrefs.ts +++ b/src/account/useUpdatePrefs.ts @@ -1,12 +1,13 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { UpdatePrefsMutation, UpdatePrefsMutationVariables } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' -const accountUpdatePrefs = gql(/* GraphQL */ ` +export const accountUpdatePrefs = gql(/* GraphQL */ ` mutation UpdatePrefs($prefs: Assoc!) { accountUpdatePrefs(prefs: $prefs) { prefs { @@ -16,15 +17,15 @@ const accountUpdatePrefs = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountUpdatePrefs'] + export function useUpdatePrefs() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - UpdatePrefsMutation['accountUpdatePrefs'], - AppwriteException[], - UpdatePrefsMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().prefs().update(), mutationFn: async ({ prefs }) => { const { data, errors } = await graphql.mutation({ query: accountUpdatePrefs, @@ -38,7 +39,7 @@ export function useUpdatePrefs() { return data?.accountUpdatePrefs }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account'] }) + void queryClient.invalidateQueries({ queryKey: Keys.account().key() }) }, }) diff --git a/src/account/useUpdatePushTarget.ts b/src/account/useUpdatePushTarget.ts index 3824f71..51aa139 100644 --- a/src/account/useUpdatePushTarget.ts +++ b/src/account/useUpdatePushTarget.ts @@ -1,10 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { - UpdatePushTargetMutation, - UpdatePushTargetMutationVariables, -} from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -20,15 +18,15 @@ const accountUpdatePushTarget = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountUpdatePushTarget'] + export function useUpdatePushTarget() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - UpdatePushTargetMutation['accountUpdatePushTarget'], - AppwriteException[], - UpdatePushTargetMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().pushTarget().update(), mutationFn: async ({ targetId, identifier }) => { const { data, errors } = await graphql.mutation({ query: accountUpdatePushTarget, @@ -45,7 +43,7 @@ export function useUpdatePushTarget() { return data.accountUpdatePushTarget }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account'] }) + void queryClient.invalidateQueries({ queryKey: Keys.account().key() }) }, }) diff --git a/src/account/useUpdateSession.ts b/src/account/useUpdateSession.ts index 1f37a5d..5d2f04b 100644 --- a/src/account/useUpdateSession.ts +++ b/src/account/useUpdateSession.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { UpdateSessionMutation, UpdateSessionMutationVariables } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -16,15 +17,15 @@ const updateSession = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountUpdateSession'] + export function useUpdateSession() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - UpdateSessionMutation['accountUpdateSession'], - AppwriteException[], - UpdateSessionMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().session().update(), mutationFn: async ({ sessionId }) => { const { data, errors } = await graphql.mutation({ query: updateSession, @@ -40,7 +41,7 @@ export function useUpdateSession() { return data.accountUpdateSession }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account', 'sessions'] }) + void queryClient.invalidateQueries({ queryKey: Keys.account().sessions() }) }, }) diff --git a/src/account/useUpdateStatus.ts b/src/account/useUpdateStatus.ts index 573ae9e..737a36e 100644 --- a/src/account/useUpdateStatus.ts +++ b/src/account/useUpdateStatus.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { UpdateStatusMutation } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -15,14 +16,14 @@ const accountUpdateStatus = gql(/* GraphQL */ ` } `) +type Result = ResultOf['accountUpdateStatus'] + export function useUpdateStatus() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - UpdateStatusMutation['accountUpdateStatus'], - AppwriteException[] - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().status().update(), mutationFn: async () => { const { data, errors } = await graphql.mutation({ query: accountUpdateStatus, @@ -35,7 +36,7 @@ export function useUpdateStatus() { return data.accountUpdateStatus }, onSuccess: async () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'account'] }) + void queryClient.invalidateQueries({ queryKey: Keys.account().key() }) }, }) diff --git a/src/account/useVerification.ts b/src/account/useVerification.ts index f306952..02936c5 100644 --- a/src/account/useVerification.ts +++ b/src/account/useVerification.ts @@ -1,11 +1,8 @@ -import { AppwriteException } from '../types' - -import { gql } from '../__generated__' -import { - Token, - UpdateVerificationMutation, - UpdateVerificationMutationVariables, -} from '../__generated__/graphql' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' + +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -20,15 +17,15 @@ const updateVerification = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['accountUpdateVerification'] + export function useVerification() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const queryResult = useMutation< - UpdateVerificationMutation['accountUpdateVerification'], - AppwriteException[], - UpdateVerificationMutationVariables - >({ + const queryResult = useMutation({ + mutationKey: Keys.account().verification().update(), mutationFn: async ({ userId, secret }) => { if (!userId || !secret) { throw new Error('Missing userId or secret') @@ -46,10 +43,10 @@ export function useVerification() { throw errors } - return data.accountUpdateVerification ?? ({} as Token) + return data.accountUpdateVerification }, onSuccess: async () => { - queryClient.setQueryData(['appwrite', 'account'], null) + queryClient.setQueryData(Keys.account().key(), null) }, }) diff --git a/src/client.ts b/src/client.ts new file mode 100644 index 0000000..310b0f7 --- /dev/null +++ b/src/client.ts @@ -0,0 +1,75 @@ +import type { ResultOf, TypedDocumentNode } from '@graphql-typed-document-node/core' +import { print } from 'graphql' + +import { + Account, + Avatars, + Client, + Databases, + Functions, + Graphql, + Locale, + Messaging, + Realtime, + Storage, + TablesDB, + Teams, +} from './types' + +type Variables = Record + +const graphqlObject = (graphqlAppwrite: Graphql) => ({ + client: graphqlAppwrite.client, + query: async ({ + query, + variables, + }: { + query: TypedDocumentNode + variables?: V + }) => { + const { data, errors } = (await graphqlAppwrite.query({ + query: { query: print(query), variables }, + })) as { data: ResultOf; errors: unknown[] } + return { data, errors } + }, + mutation: async ({ + query, + variables, + }: { + query: TypedDocumentNode + variables?: V + }) => { + const { data, errors } = (await graphqlAppwrite.mutation({ + query: { query: print(query), variables }, + })) as { data: ResultOf; errors: unknown[] } + return { data, errors } + }, +}) + +export function createAppwriteClient({ + endpoint, + projectId, +}: { + endpoint: string + projectId: string +}) { + const client = new Client() + client.setEndpoint(endpoint).setProject(projectId) + + return { + client, + account: new Account(client), + avatars: new Avatars(client), + realtime: new Realtime(client), + storage: new Storage(client), + graphql: graphqlObject(new Graphql(client)), + databases: new Databases(client), + functions: new Functions(client), + locale: new Locale(client), + messaging: new Messaging(client), + tablesDB: new TablesDB(client), + teams: new Teams(client), + } +} + +export type AppwriteClient = ReturnType diff --git a/src/databases/index.ts b/src/databases/index.ts index 1984633..2c25507 100644 --- a/src/databases/index.ts +++ b/src/databases/index.ts @@ -1,18 +1,20 @@ +export { documentQueryOptions, collectionQueryOptions } from './queryOptions' export { useCollection, useSuspenseCollection } from './useCollection' +export { + useCollectionWithPagination, + useSuspenseCollectionWithPagination, +} from './useCollectionWithPagination' export { useCreateDocument } from './useCreateDocument' -export { useCreateDocuments } from './useCreateDocuments' export { useCreateOperations } from './useCreateOperations' export { useCreateTransaction } from './useCreateTransaction' export { useDecrementAttribute } from './useDecrementAttribute' export { useDeleteDocument } from './useDeleteDocument' -export { useDeleteDocuments } from './useDeleteDocuments' export { useDeleteTransaction } from './useDeleteTransaction' -export { useDocument } from './useDocument' +export { useDocument, useSuspenseDocument } from './useDocument' export { useGetTransaction } from './useGetTransaction' export { useIncrementAttribute } from './useIncrementAttribute' +export { useInfiniteCollection } from './useInfiniteCollection' export { useListTransactions } from './useListTransactions' export { useUpdateDocument } from './useUpdateDocument' -export { useUpdateDocuments } from './useUpdateDocuments' export { useUpdateTransaction } from './useUpdateTransaction' export { useUpsertDocument } from './useUpsertDocument' -export { useUpsertDocuments } from './useUpsertDocuments' diff --git a/src/databases/queryOptions.ts b/src/databases/queryOptions.ts new file mode 100644 index 0000000..b8373c1 --- /dev/null +++ b/src/databases/queryOptions.ts @@ -0,0 +1,151 @@ +import { graphql as gql } from 'gql.tada' + +import type { Collection, Document } from './types' +import { mergeFieldsQuery } from './utils' +import type { AppwriteClient } from '../client' +import { Keys } from '../query/Keys' + +type DocumentParams> = { + databaseId: string + collectionId: string + documentId: string + queries?: string[] + transactionId?: string + fields?: (keyof TDocument & string)[] +} + +export const getDocument = gql(/* GraphQL */ ` + query GetDocument( + $databaseId: String! + $collectionId: String! + $documentId: String! + $queries: [String!] + $transactionId: String + ) { + databasesGetDocument( + databaseId: $databaseId + collectionId: $collectionId + documentId: $documentId + queries: $queries + transactionId: $transactionId + ) { + _id + data + } + } +`) + +export function documentQueryOptions( + client: AppwriteClient, + { + databaseId, + collectionId, + documentId, + queries, + transactionId, + fields, + }: DocumentParams, +) { + const rawQueries = Array.isArray(queries) ? queries : queries ? [queries] : [] + const mergedQueries = mergeFieldsQuery(rawQueries, fields) + + return { + queryKey: [ + ...Keys.database(databaseId).collection(collectionId).document(documentId).key(), + ...mergedQueries, + ] as const, + queryFn: async () => { + const { data, errors } = await client.graphql.query({ + query: getDocument, + variables: { + databaseId, + collectionId, + documentId, + queries: mergedQueries.length > 0 ? mergedQueries : undefined, + transactionId, + }, + }) + + if (errors) { + throw errors + } + + const document = { + ...data.databasesGetDocument, + ...(data.databasesGetDocument + ? (JSON.parse(data.databasesGetDocument.data as string) as TDocument) + : {}), + } as unknown as Document + + return document + }, + } +} + +export const listDocuments = gql(/* GraphQL */ ` + query ListDocuments( + $databaseId: String! + $collectionId: String! + $queries: [String!] + $transactionId: String + ) { + databasesListDocuments( + databaseId: $databaseId + collectionId: $collectionId + queries: $queries + transactionId: $transactionId + ) { + total + documents { + _id + data + } + } + } +`) + +export function collectionQueryOptions( + client: AppwriteClient, + { + databaseId, + collectionId, + queries, + transactionId, + fields, + }: Omit, 'documentId'>, +) { + const mergedQueries = mergeFieldsQuery(queries ?? [], fields) + + return { + queryKey: [ + ...Keys.database(databaseId).collection(collectionId).key(), + ...mergedQueries, + ] as const, + queryFn: async () => { + const { data, errors } = await client.graphql.query({ + query: listDocuments, + variables: { + databaseId, + collectionId, + queries: mergedQueries, + transactionId, + }, + }) + + if (errors) { + throw errors + } + + const documents = + data.databasesListDocuments?.documents?.map((document) => ({ + ...document, + ...(document ? (JSON.parse(document.data as string) as TDocument) : {}), + })) ?? [] + + return { + total: data.databasesListDocuments?.total ?? 0, + documents, + } as unknown as Collection + }, + } +} diff --git a/src/databases/types.ts b/src/databases/types.ts index b7db249..e1f422c 100644 --- a/src/databases/types.ts +++ b/src/databases/types.ts @@ -1,4 +1,4 @@ -import { Models } from '../types' +import type { Models } from '../types' export type Document = T & Models.Document export type Collection = Models.DocumentList> diff --git a/src/databases/useCollection.ts b/src/databases/useCollection.ts index 6736549..8b08da6 100644 --- a/src/databases/useCollection.ts +++ b/src/databases/useCollection.ts @@ -1,74 +1,53 @@ import { useEffect } from 'react' +import { Channel } from 'appwrite' -import { gql } from '../__generated__' -import { AppwriteException } from '../types' +import { collectionQueryOptions } from './queryOptions' +import type { Collection, Document } from './types' +import { Keys } from '../query/Keys' +import type { AppwriteException, QueryOptions } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' import { useQueryClient } from '../useQueryClient' import { useSuspenseQuery } from '../useSuspenseQuery' -import type { Collection, Document } from './types' type DocumentOperation = 'create' | 'update' | 'delete' -const listDocuments = gql(/* GraphQL */ ` - query ListDocuments($databaseId: String!, $collectionId: String!, $queries: [String!]) { - databasesListDocuments( - databaseId: $databaseId - collectionId: $collectionId - queries: $queries - ) { - total - documents { - _id - data - } - } - } -`) - -export function useCollection({ - databaseId, - collectionId, - queries, - subscribe = true, -}: { +type CollectionParams> = { databaseId: string collectionId: string queries: string[] + transactionId?: string subscribe?: boolean -}) { - const { graphql, realtime } = useAppwrite() - const queryClient = useQueryClient() - const queriesKey = JSON.stringify(queries) + fields?: (keyof TDocument & string)[] +} - const collection = useQuery, AppwriteException[], Collection>({ - queryKey: ['appwrite', 'databases', databaseId, collectionId, { queries }], - queryFn: async () => { - const { data, errors } = await graphql.query({ - query: listDocuments, - variables: { - databaseId, - collectionId, - queries, - }, - }) - - if (errors) { - throw errors - } - - const documents = - data.databasesListDocuments?.documents?.map((document) => ({ - ...document, - ...(document ? (JSON.parse(document.data) as TDocument) : {}), - })) ?? [] - - return { - total: data.databasesListDocuments?.total ?? 0, - documents, - } as Collection - }, +function useCollectionQueryConfig({ + databaseId, + collectionId, + queries, + transactionId, + fields, +}: Omit, 'subscribe'>) { + const client = useAppwrite() + + return collectionQueryOptions(client, { + databaseId, + collectionId, + queries, + transactionId, + fields, }) +} + +function useCollectionRealtime( + databaseId: string, + collectionId: string, + queries: string[], + subscribe: boolean, +) { + const { realtime } = useAppwrite() + const queryClient = useQueryClient() + const queriesKey = JSON.stringify(queries) useEffect(() => { if (!subscribe) { @@ -76,7 +55,7 @@ export function useCollection({ } const subscriptionPromise = realtime.subscribe( - `databases.${databaseId}.collections.${collectionId}.documents`, + Channel.tablesdb(databaseId).table(collectionId).row(), (response) => { const [, operation] = response.events[0].match(/\.(\w+)$/) as RegExpMatchArray const document = response.payload as Document @@ -86,13 +65,12 @@ export function useCollection({ case 'update': case 'delete': queryClient.setQueryData( - ['appwrite', 'databases', databaseId, collectionId, 'documents', document.$id], + Keys.database(databaseId).collection(collectionId).document(document.$id).key(), document, ) - queryClient.invalidateQueries({ - queryKey: ['appwrite', 'databases', databaseId, collectionId, { queries }], - exact: true, + void queryClient.invalidateQueries({ + queryKey: Keys.database(databaseId).collection(collectionId).key(), }) break @@ -101,9 +79,36 @@ export function useCollection({ ) return () => { - subscriptionPromise.then((sub) => sub.close()) + void subscriptionPromise.then((sub) => sub.close()) } }, [databaseId, collectionId, realtime, queryClient, queriesKey, subscribe]) +} + +export function useCollection( + { + databaseId, + collectionId, + queries, + transactionId, + subscribe = true, + fields, + }: CollectionParams, + opts: QueryOptions = {}, +) { + const config = useCollectionQueryConfig({ + databaseId, + collectionId, + queries, + transactionId, + fields, + }) + + const collection = useQuery, AppwriteException[], Collection>({ + ...config, + ...opts, + }) + + useCollectionRealtime(databaseId, collectionId, queries, subscribe) return { ...collection, @@ -112,88 +117,35 @@ export function useCollection({ } } -export function useSuspenseCollection({ - databaseId, - collectionId, - queries, - subscribe = true, -}: { - databaseId: string - collectionId: string - queries: string[] - subscribe?: boolean -}) { - const { graphql, realtime } = useAppwrite() - const queryClient = useQueryClient() - const queriesKey = JSON.stringify(queries) +export function useSuspenseCollection( + { + databaseId, + collectionId, + queries, + transactionId, + subscribe = true, + fields, + }: CollectionParams, + opts: QueryOptions = {}, +) { + const config = useCollectionQueryConfig({ + databaseId, + collectionId, + queries, + transactionId, + fields, + }) const collection = useSuspenseQuery< Collection, AppwriteException[], Collection >({ - queryKey: ['appwrite', 'databases', databaseId, collectionId, { queries }], - queryFn: async () => { - const { data, errors } = await graphql.query({ - query: listDocuments, - variables: { - databaseId, - collectionId, - queries, - }, - }) - - if (errors) { - throw errors - } - - const documents = - data.databasesListDocuments?.documents?.map((document) => ({ - ...document, - ...(document ? (JSON.parse(document.data) as TDocument) : {}), - })) ?? [] - - return { - total: data.databasesListDocuments?.total ?? 0, - documents, - } as Collection - }, + ...config, + ...opts, }) - useEffect(() => { - if (!subscribe) { - return - } - - const subscriptionPromise = realtime.subscribe( - `databases.${databaseId}.collections.${collectionId}.documents`, - (response) => { - const [, operation] = response.events[0].match(/\.(\w+)$/) as RegExpMatchArray - const document = response.payload as Document - - switch (operation as DocumentOperation) { - case 'create': - case 'update': - case 'delete': - queryClient.setQueryData( - ['appwrite', 'databases', databaseId, collectionId, 'documents', document.$id], - document, - ) - - queryClient.invalidateQueries({ - queryKey: ['appwrite', 'databases', databaseId, collectionId, { queries }], - exact: true, - }) - - break - } - }, - ) - - return () => { - subscriptionPromise.then((sub) => sub.close()) - } - }, [databaseId, collectionId, realtime, queryClient, queriesKey]) + useCollectionRealtime(databaseId, collectionId, queries, subscribe) return { ...collection, diff --git a/src/databases/useCollectionWithPagination.ts b/src/databases/useCollectionWithPagination.ts new file mode 100644 index 0000000..6f24aef --- /dev/null +++ b/src/databases/useCollectionWithPagination.ts @@ -0,0 +1,133 @@ +import { useRef, useState } from 'react' +import { Query } from 'appwrite' + +import { useCollection, useSuspenseCollection } from './useCollection' +import type { QueryOptions } from '../types' + +type PaginationParams> = { + databaseId: string + collectionId: string + queries: string[] + transactionId?: string + limit?: number + fields?: (keyof TDocument & string)[] +} + +function usePaginationState(limit: number) { + const [page, setPage] = useState(1) + const totalRef = useRef(0) + const offset = (page - 1) * limit + + const nextPage = () => { + setPage((prevPage) => { + const currentOffset = (prevPage - 1) * limit + if (totalRef.current > 0 && currentOffset + limit < totalRef.current) { + return prevPage + 1 + } + return prevPage + }) + } + + const previousPage = () => { + setPage((prevPage) => (prevPage > 1 ? prevPage - 1 : prevPage)) + } + + const handlePageChange = (newPage: number) => { + if (newPage < 1) return + if (totalRef.current > 0) { + const maxPage = Math.ceil(totalRef.current / limit) + if (newPage > maxPage) return + } + setPage(newPage) + } + + return { page, offset, totalRef, nextPage, previousPage, handlePageChange } +} + +export function useCollectionWithPagination( + { + databaseId, + collectionId, + queries, + transactionId, + limit = 25, + fields, + }: PaginationParams, + opts: QueryOptions = {}, +) { + const { page, offset, totalRef, nextPage, previousPage, handlePageChange } = + usePaginationState(limit) + + const collection = useCollection( + { + databaseId, + collectionId, + queries: [...queries, Query.limit(limit), Query.offset(offset)], + transactionId, + fields, + }, + opts, + ) + + const total = collection.data?.total ?? 0 + totalRef.current = total + + return { + documents: collection.data?.documents ?? [], + total, + page, + hasNextPage: total > 0 && offset + limit < total, + hasPreviousPage: page > 1, + handlePageChange, + nextPage, + previousPage, + isLoading: collection.isLoading, + isError: collection.isError, + error: collection.error, + isFetching: collection.isFetching, + } +} + +export function useSuspenseCollectionWithPagination( + { + databaseId, + collectionId, + queries, + transactionId, + limit = 25, + fields, + }: PaginationParams, + opts: QueryOptions = {}, +) { + const { page, offset, totalRef, nextPage, previousPage, handlePageChange } = + usePaginationState(limit) + + const collection = useSuspenseCollection( + { + databaseId, + collectionId, + queries: [...queries, Query.limit(limit), Query.offset(offset)], + transactionId, + fields, + }, + opts, + ) + + const total = collection.total ?? 0 + totalRef.current = total + + return { + documents: collection.documents ?? [], + total, + page, + hasNextPage: total > 0 && offset + limit < total, + hasPreviousPage: page > 1, + handlePageChange, + nextPage, + previousPage, + isLoading: collection.isLoading, + isError: collection.isError, + error: collection.error, + isFetching: collection.isFetching, + } +} diff --git a/src/databases/useCreateDocument.ts b/src/databases/useCreateDocument.ts index 6669488..4156ff8 100644 --- a/src/databases/useCreateDocument.ts +++ b/src/databases/useCreateDocument.ts @@ -1,24 +1,20 @@ -import { Models } from 'appwrite' -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' -import { - CreateDocumentMutation, - CreateDocumentMutationVariables, - InputMaybe, - Scalars, -} from '../__generated__/graphql' -const createDocument = gql(/* GraphQL */ ` +export const createDocument = gql(/* GraphQL */ ` mutation CreateDocument( $databaseId: String! $collectionId: String! $documentId: String! $data: Json! $permissions: [String!] + $transactionId: String ) { databasesCreateDocument( databaseId: $databaseId @@ -26,24 +22,36 @@ const createDocument = gql(/* GraphQL */ ` documentId: $documentId data: $data permissions: $permissions + transactionId: $transactionId ) { _id } } `) +type Variables = VariablesOf +type Result = ResultOf['databasesCreateDocument'] + export function useCreateDocument() { const { graphql } = useAppwrite() const queryClient = useQueryClient() const mutationResult = useMutation< - CreateDocumentMutation['databasesCreateDocument'], + Result, AppwriteException[], - Omit & { - permissions?: InputMaybe> + Omit & { + permissions?: string[] | null } >({ - mutationFn: async ({ databaseId, collectionId, documentId, data, permissions }) => { + mutationKey: Keys.databases().collections().documents().create(), + mutationFn: async ({ + databaseId, + collectionId, + documentId, + data, + permissions, + transactionId, + }) => { const { data: mutationData, errors } = await graphql.mutation({ query: createDocument, variables: { @@ -52,6 +60,7 @@ export function useCreateDocument() { documentId, data: JSON.stringify(data), permissions, + transactionId, }, }) @@ -61,8 +70,8 @@ export function useCreateDocument() { return mutationData.databasesCreateDocument }, onSuccess: (_, variables) => { - queryClient.invalidateQueries({ - queryKey: ['appwrite', 'databases', variables.databaseId, variables.collectionId], + void queryClient.invalidateQueries({ + queryKey: Keys.database(variables.databaseId).collection(variables.collectionId).key(), }) }, }) diff --git a/src/databases/useCreateDocuments.ts b/src/databases/useCreateDocuments.ts deleted file mode 100644 index 7a1889a..0000000 --- a/src/databases/useCreateDocuments.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { AppwriteException } from '../types' - -import { gql } from '../__generated__' -import { - CreateDocumentsMutation, - CreateDocumentsMutationVariables, -} from '../__generated__/graphql' -import { useAppwrite } from '../useAppwrite' -import { useMutation } from '../useMutation' -import { useQueryClient } from '../useQueryClient' - -const createDocuments = gql(/* GraphQL */ ` - mutation CreateDocuments( - $databaseId: String! - $collectionId: String! - $documents: [Json!]! - ) { - databasesCreateDocuments( - databaseId: $databaseId - collectionId: $collectionId - documents: $documents - ) { - total - documents { - _id - } - } - } -`) - -export function useCreateDocuments() { - const { graphql } = useAppwrite() - const queryClient = useQueryClient() - - const mutationResult = useMutation< - CreateDocumentsMutation['databasesCreateDocuments'], - AppwriteException[], - CreateDocumentsMutationVariables - >({ - mutationFn: async ({ databaseId, collectionId, documents }) => { - const { data: mutationData, errors } = await graphql.mutation({ - query: createDocuments, - variables: { - databaseId, - collectionId, - documents: documents.map((doc) => JSON.stringify(doc)), - }, - }) - - if (errors) { - throw errors - } - - return mutationData.databasesCreateDocuments - }, - onSuccess: (_, variables) => { - queryClient.invalidateQueries({ - queryKey: ['appwrite', 'databases', variables.databaseId, variables.collectionId], - }) - }, - }) - - return { ...mutationResult } -} diff --git a/src/databases/useCreateOperations.ts b/src/databases/useCreateOperations.ts index 7a63114..7ecff6c 100644 --- a/src/databases/useCreateOperations.ts +++ b/src/databases/useCreateOperations.ts @@ -1,10 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { - CreateOperationsMutation, - CreateOperationsMutationVariables, -} from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -20,15 +18,15 @@ const createOperations = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['databasesCreateOperations'] + export function useCreateOperations() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const mutationResult = useMutation< - CreateOperationsMutation['databasesCreateOperations'], - AppwriteException[], - CreateOperationsMutationVariables - >({ + const mutationResult = useMutation({ + mutationKey: Keys.databases().transactions().operations().create(), mutationFn: async ({ transactionId, operations }) => { const { data, errors } = await graphql.mutation({ query: createOperations, @@ -42,8 +40,8 @@ export function useCreateOperations() { return data.databasesCreateOperations }, onSuccess: (_, variables) => { - queryClient.invalidateQueries({ - queryKey: ['appwrite', 'databases', 'transactions', variables.transactionId], + void queryClient.invalidateQueries({ + queryKey: Keys.databases().transaction(variables.transactionId).key(), }) }, }) diff --git a/src/databases/useCreateTransaction.ts b/src/databases/useCreateTransaction.ts index 7523529..1365245 100644 --- a/src/databases/useCreateTransaction.ts +++ b/src/databases/useCreateTransaction.ts @@ -1,10 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { - CreateTransactionMutation, - CreateTransactionMutationVariables, -} from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -20,15 +18,15 @@ const createTransaction = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['databasesCreateTransaction'] + export function useCreateTransaction() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const mutationResult = useMutation< - CreateTransactionMutation['databasesCreateTransaction'], - AppwriteException[], - CreateTransactionMutationVariables - >({ + const mutationResult = useMutation({ + mutationKey: Keys.databases().transactions().create(), mutationFn: async ({ ttl } = {}) => { const { data, errors } = await graphql.mutation({ query: createTransaction, @@ -42,8 +40,8 @@ export function useCreateTransaction() { return data.databasesCreateTransaction }, onSuccess: () => { - queryClient.invalidateQueries({ - queryKey: ['appwrite', 'databases', 'transactions'], + void queryClient.invalidateQueries({ + queryKey: Keys.databases().transactions().key(), }) }, }) diff --git a/src/databases/useDecrementAttribute.ts b/src/databases/useDecrementAttribute.ts index d31478f..2479c3d 100644 --- a/src/databases/useDecrementAttribute.ts +++ b/src/databases/useDecrementAttribute.ts @@ -1,15 +1,13 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { - DecrementDocumentAttributeMutation, - DecrementDocumentAttributeMutationVariables, -} from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' -const decrementDocumentAttribute = gql(/* GraphQL */ ` +export const decrementDocumentAttribute = gql(/* GraphQL */ ` mutation DecrementDocumentAttribute( $databaseId: String! $collectionId: String! @@ -17,6 +15,7 @@ const decrementDocumentAttribute = gql(/* GraphQL */ ` $attribute: String! $value: Int $min: Int + $transactionId: String ) { databasesDecrementDocumentAttribute( databaseId: $databaseId @@ -25,6 +24,7 @@ const decrementDocumentAttribute = gql(/* GraphQL */ ` attribute: $attribute value: $value min: $min + transactionId: $transactionId ) { _id data @@ -32,19 +32,35 @@ const decrementDocumentAttribute = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['databasesDecrementDocumentAttribute'] + export function useDecrementAttribute() { const { graphql } = useAppwrite() const queryClient = useQueryClient() const mutationResult = useMutation< - DecrementDocumentAttributeMutation['databasesDecrementDocumentAttribute'], + Result, AppwriteException[], - DecrementDocumentAttributeMutationVariables + Variables, + { + previousEntries: [queryKey: readonly unknown[], data: unknown][] + documentKeyPrefix: readonly unknown[] + } >({ - mutationFn: async ({ databaseId, collectionId, documentId, attribute, value, min }) => { + mutationKey: [...Keys.databases().transactions().operations().key(), 'decrementAttribute'], + mutationFn: async ({ + databaseId, + collectionId, + documentId, + attribute, + value, + min, + transactionId, + }) => { const { data: mutationData, errors } = await graphql.mutation({ query: decrementDocumentAttribute, - variables: { databaseId, collectionId, documentId, attribute, value, min }, + variables: { databaseId, collectionId, documentId, attribute, value, min, transactionId }, }) if (errors) { @@ -53,9 +69,43 @@ export function useDecrementAttribute() { return mutationData.databasesDecrementDocumentAttribute }, - onSuccess: (_, variables) => { - queryClient.invalidateQueries({ - queryKey: ['appwrite', 'databases', variables.databaseId, variables.collectionId], + onMutate: async (variables) => { + const documentKeyPrefix = Keys.database(variables.databaseId) + .collection(variables.collectionId) + .document(variables.documentId) + .key() + + await queryClient.cancelQueries({ queryKey: documentKeyPrefix }) + + const previousEntries = queryClient.getQueriesData({ queryKey: documentKeyPrefix }) + + queryClient.setQueriesData( + { queryKey: documentKeyPrefix }, + (old: Record | undefined) => { + if (!old) return old + const current = (old[variables.attribute] as number) ?? 0 + const decrement = variables.value ?? 1 + const newValue = + variables.min != null + ? Math.max(current - decrement, variables.min) + : current - decrement + + return { ...old, [variables.attribute]: newValue } + }, + ) + + return { previousEntries, documentKeyPrefix } + }, + onError: (_, __, context) => { + if (context?.previousEntries) { + for (const [key, data] of context.previousEntries) { + queryClient.setQueryData(key, data) + } + } + }, + onSettled: (_, __, variables) => { + void queryClient.invalidateQueries({ + queryKey: Keys.database(variables.databaseId).collection(variables.collectionId).key(), }) }, }) diff --git a/src/databases/useDeleteDocument.ts b/src/databases/useDeleteDocument.ts index 1228e9e..59b42ab 100644 --- a/src/databases/useDeleteDocument.ts +++ b/src/databases/useDeleteDocument.ts @@ -1,38 +1,55 @@ -import { gql } from '../__generated__' -import { DeleteDocumentMutation, DeleteDocumentMutationVariables } from '../__generated__/graphql' -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' + +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' -const deleteDocument = gql(/* GraphQL */ ` - mutation DeleteDocument($databaseId: String!, $collectionId: String!, $documentId: String!) { +export const deleteDocument = gql(/* GraphQL */ ` + mutation DeleteDocument( + $databaseId: String! + $collectionId: String! + $documentId: String! + $transactionId: String + ) { databasesDeleteDocument( databaseId: $databaseId collectionId: $collectionId documentId: $documentId + transactionId: $transactionId ) { status } } `) +type Variables = VariablesOf +type Result = ResultOf['databasesDeleteDocument'] + export function useDeleteDocument() { const { graphql } = useAppwrite() const queryClient = useQueryClient() const mutationResult = useMutation< - DeleteDocumentMutation['databasesDeleteDocument'], + Result, AppwriteException[], - DeleteDocumentMutationVariables + Variables, + { + previousEntries: [queryKey: readonly unknown[], data: unknown][] + documentKeyPrefix: readonly unknown[] + } >({ - mutationFn: async ({ databaseId, collectionId, documentId }) => { + mutationKey: Keys.databases().collections().documents().delete(), + mutationFn: async ({ databaseId, collectionId, documentId, transactionId }) => { const { data: mutationData, errors } = await graphql.mutation({ query: deleteDocument, variables: { databaseId, collectionId, documentId, + transactionId, }, }) @@ -40,21 +57,38 @@ export function useDeleteDocument() { throw errors } - return mutationData?.databasesDeleteDocument ?? { status: true } + return mutationData?.databasesDeleteDocument ?? { status: '' } + }, + onMutate: async (variables) => { + const documentKeyPrefix = Keys.database(variables.databaseId) + .collection(variables.collectionId) + .document(variables.documentId) + .key() + + await queryClient.cancelQueries({ queryKey: documentKeyPrefix }) + + const previousEntries = queryClient.getQueriesData({ queryKey: documentKeyPrefix }) + + queryClient.removeQueries({ queryKey: documentKeyPrefix }) + + return { previousEntries, documentKeyPrefix } + }, + onError: (_, __, context) => { + if (context?.previousEntries) { + for (const [key, data] of context.previousEntries) { + queryClient.setQueryData(key, data) + } + } }, - onSuccess: async (_, variables) => { + onSettled: (_, __, variables) => { queryClient.removeQueries({ - queryKey: [ - 'appwrite', - 'databases', - variables.databaseId, - variables.collectionId, - 'documents', - variables.documentId, - ], + queryKey: Keys.database(variables.databaseId) + .collection(variables.collectionId) + .document(variables.documentId) + .key(), }) - queryClient.invalidateQueries({ - queryKey: ['appwrite', 'databases', variables.databaseId, variables.collectionId], + void queryClient.invalidateQueries({ + queryKey: Keys.database(variables.databaseId).collection(variables.collectionId).key(), }) }, }) diff --git a/src/databases/useDeleteDocuments.ts b/src/databases/useDeleteDocuments.ts deleted file mode 100644 index 87a9682..0000000 --- a/src/databases/useDeleteDocuments.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { AppwriteException } from '../types' - -import { gql } from '../__generated__' -import { - DeleteDocumentsMutation, - DeleteDocumentsMutationVariables, -} from '../__generated__/graphql' -import { useAppwrite } from '../useAppwrite' -import { useMutation } from '../useMutation' -import { useQueryClient } from '../useQueryClient' - -const deleteDocuments = gql(/* GraphQL */ ` - mutation DeleteDocuments( - $databaseId: String! - $collectionId: String! - $queries: [String!] - ) { - databasesDeleteDocuments( - databaseId: $databaseId - collectionId: $collectionId - queries: $queries - ) { - total - documents { - _id - } - } - } -`) - -export function useDeleteDocuments() { - const { graphql } = useAppwrite() - const queryClient = useQueryClient() - - const mutationResult = useMutation< - DeleteDocumentsMutation['databasesDeleteDocuments'], - AppwriteException[], - DeleteDocumentsMutationVariables - >({ - mutationFn: async ({ databaseId, collectionId, queries }) => { - const { data: mutationData, errors } = await graphql.mutation({ - query: deleteDocuments, - variables: { - databaseId, - collectionId, - queries, - }, - }) - - if (errors) { - throw errors - } - - return mutationData?.databasesDeleteDocuments ?? { total: 0, documents: [] } - }, - onSuccess: (_, variables) => { - queryClient.invalidateQueries({ - queryKey: ['appwrite', 'databases', variables.databaseId, variables.collectionId], - }) - }, - }) - - return { ...mutationResult } -} diff --git a/src/databases/useDeleteTransaction.ts b/src/databases/useDeleteTransaction.ts index 59e5bb1..637c892 100644 --- a/src/databases/useDeleteTransaction.ts +++ b/src/databases/useDeleteTransaction.ts @@ -1,10 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { - DeleteTransactionMutation, - DeleteTransactionMutationVariables, -} from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -17,15 +15,15 @@ const deleteTransaction = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['databasesDeleteTransaction'] + export function useDeleteTransaction() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const mutationResult = useMutation< - DeleteTransactionMutation['databasesDeleteTransaction'], - AppwriteException[], - DeleteTransactionMutationVariables - >({ + const mutationResult = useMutation({ + mutationKey: Keys.databases().transactions().delete(), mutationFn: async ({ transactionId }) => { const { data, errors } = await graphql.mutation({ query: deleteTransaction, @@ -36,14 +34,14 @@ export function useDeleteTransaction() { throw errors } - return data?.databasesDeleteTransaction ?? { status: true } + return data?.databasesDeleteTransaction ?? { status: '' } }, onSuccess: (_, variables) => { queryClient.removeQueries({ - queryKey: ['appwrite', 'databases', 'transactions', variables.transactionId], + queryKey: Keys.databases().transaction(variables.transactionId).key(), }) - queryClient.invalidateQueries({ - queryKey: ['appwrite', 'databases', 'transactions'], + void queryClient.invalidateQueries({ + queryKey: Keys.databases().transactions().key(), }) }, }) diff --git a/src/databases/useDocument.ts b/src/databases/useDocument.ts index a16411b..6f69e4b 100644 --- a/src/databases/useDocument.ts +++ b/src/databases/useDocument.ts @@ -1,77 +1,128 @@ import { useEffect } from 'react' +import { Channel } from 'appwrite' +import type { VariablesOf } from 'gql.tada' -import { AppwriteException } from '../types' - -import { gql } from '../__generated__' +import type { getDocument } from './queryOptions' +import { documentQueryOptions } from './queryOptions' +import type { Document } from './types' +import { Keys } from '../query/Keys' +import type { AppwriteException, QueryOptions } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' import { useQueryClient } from '../useQueryClient' -import type { Document } from './types' -import { GetDocumentQueryVariables } from '../__generated__/graphql' - -const getDocument = gql(/* GraphQL */ ` - query GetDocument($databaseId: String!, $collectionId: String!, $documentId: String!) { - databasesGetDocument( - databaseId: $databaseId - collectionId: $collectionId - documentId: $documentId - ) { - _id - data - } - } -`) +import { useSuspenseQuery } from '../useSuspenseQuery' + +type Variables = VariablesOf + +type DocumentParams> = Variables & { + fields?: (keyof TDocument & string)[] +} -export function useDocument({ +function useDocumentQueryConfig({ databaseId, collectionId, documentId, -}: GetDocumentQueryVariables) { - const { graphql, realtime } = useAppwrite() - const queryClient = useQueryClient() + queries, + transactionId, + fields, +}: DocumentParams) { + const client = useAppwrite() - const queryResult = useQuery, AppwriteException[], Document>({ - queryKey: ['appwrite', 'databases', databaseId, collectionId, 'documents', documentId], - queryFn: async () => { - const { data, errors } = await graphql.query({ - query: getDocument, - variables: { - databaseId, - collectionId, - documentId, - }, - }) - - if (errors) { - throw errors - } - - const document = { - ...data.databasesGetDocument, - ...(data.databasesGetDocument - ? (JSON.parse(data.databasesGetDocument.data) as TDocument) - : {}), - } as Document - - return document - }, + return documentQueryOptions(client, { + databaseId, + collectionId, + documentId, + queries, + transactionId, + fields, }) +} + +function useDocumentRealtime( + databaseId: string, + collectionId: string, + documentId: string, + queriesKey: string, +) { + const { realtime } = useAppwrite() + const queryClient = useQueryClient() useEffect(() => { const subscriptionPromise = realtime.subscribe( - `databases.${databaseId}.collections.${collectionId}.documents.${documentId}`, + Channel.tablesdb(databaseId).table(collectionId).row(documentId).update(), (response) => { queryClient.setQueryData( - ['appwrite', 'databases', databaseId, collectionId, 'documents', documentId], + Keys.database(databaseId).collection(collectionId).document(documentId).key(), response.payload, ) }, ) return () => { - subscriptionPromise.then((sub) => sub.close()) + void subscriptionPromise.then((sub) => sub.close()) } - }, [databaseId, collectionId, documentId, realtime, queryClient]) + }, [databaseId, collectionId, documentId, realtime, queryClient, queriesKey]) +} + +export function useDocument( + { + databaseId, + collectionId, + documentId, + queries, + transactionId, + fields, + }: DocumentParams, + opts: QueryOptions = {}, +) { + const config = useDocumentQueryConfig({ + databaseId, + collectionId, + documentId, + queries, + transactionId, + fields, + }) + const queriesKey = JSON.stringify(queries) + + const queryResult = useQuery, AppwriteException[], Document>({ + ...config, + ...opts, + }) + + useDocumentRealtime(databaseId, collectionId, documentId, queriesKey) + + return { ...queryResult } +} + +export function useSuspenseDocument( + { + databaseId, + collectionId, + documentId, + queries, + transactionId, + fields, + }: DocumentParams, + opts: QueryOptions = {}, +) { + const config = useDocumentQueryConfig({ + databaseId, + collectionId, + documentId, + queries, + transactionId, + fields, + }) + const queriesKey = JSON.stringify(queries) + + const queryResult = useSuspenseQuery< + Document, + AppwriteException[], + Document + >({ ...config, ...opts }) + + useDocumentRealtime(databaseId, collectionId, documentId, queriesKey) return { ...queryResult } } diff --git a/src/databases/useGetTransaction.ts b/src/databases/useGetTransaction.ts index 74f4976..45fc6a2 100644 --- a/src/databases/useGetTransaction.ts +++ b/src/databases/useGetTransaction.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { GetTransactionQuery, GetTransactionQueryVariables } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException, QueryOptions } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' @@ -18,15 +19,14 @@ const getTransaction = gql(/* GraphQL */ ` } `) -export function useGetTransaction({ transactionId }: GetTransactionQueryVariables) { +type Variables = VariablesOf +type Result = ResultOf['databasesGetTransaction'] + +export function useGetTransaction({ transactionId }: Variables, opts: QueryOptions = {}) { const { graphql } = useAppwrite() - const queryResult = useQuery< - GetTransactionQuery['databasesGetTransaction'], - AppwriteException[], - GetTransactionQuery['databasesGetTransaction'] - >({ - queryKey: ['appwrite', 'databases', 'transactions', transactionId], + const queryResult = useQuery({ + queryKey: Keys.databases().transaction(transactionId).key(), queryFn: async () => { const { data, errors } = await graphql.query({ query: getTransaction, @@ -39,6 +39,7 @@ export function useGetTransaction({ transactionId }: GetTransactionQueryVariable return data.databasesGetTransaction }, + ...opts, }) return { ...queryResult } diff --git a/src/databases/useIncrementAttribute.ts b/src/databases/useIncrementAttribute.ts index 061dea4..8ffaa08 100644 --- a/src/databases/useIncrementAttribute.ts +++ b/src/databases/useIncrementAttribute.ts @@ -1,15 +1,13 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { - IncrementDocumentAttributeMutation, - IncrementDocumentAttributeMutationVariables, -} from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' -const incrementDocumentAttribute = gql(/* GraphQL */ ` +export const incrementDocumentAttribute = gql(/* GraphQL */ ` mutation IncrementDocumentAttribute( $databaseId: String! $collectionId: String! @@ -17,6 +15,7 @@ const incrementDocumentAttribute = gql(/* GraphQL */ ` $attribute: String! $value: Int $max: Int + $transactionId: String ) { databasesIncrementDocumentAttribute( databaseId: $databaseId @@ -25,6 +24,7 @@ const incrementDocumentAttribute = gql(/* GraphQL */ ` attribute: $attribute value: $value max: $max + transactionId: $transactionId ) { _id data @@ -32,19 +32,35 @@ const incrementDocumentAttribute = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['databasesIncrementDocumentAttribute'] + export function useIncrementAttribute() { const { graphql } = useAppwrite() const queryClient = useQueryClient() const mutationResult = useMutation< - IncrementDocumentAttributeMutation['databasesIncrementDocumentAttribute'], + Result, AppwriteException[], - IncrementDocumentAttributeMutationVariables + Variables, + { + previousEntries: [queryKey: readonly unknown[], data: unknown][] + documentKeyPrefix: readonly unknown[] + } >({ - mutationFn: async ({ databaseId, collectionId, documentId, attribute, value, max }) => { + mutationKey: [...Keys.databases().transactions().operations().key(), 'incrementAttribute'], + mutationFn: async ({ + databaseId, + collectionId, + documentId, + attribute, + value, + max, + transactionId, + }) => { const { data: mutationData, errors } = await graphql.mutation({ query: incrementDocumentAttribute, - variables: { databaseId, collectionId, documentId, attribute, value, max }, + variables: { databaseId, collectionId, documentId, attribute, value, max, transactionId }, }) if (errors) { @@ -53,9 +69,43 @@ export function useIncrementAttribute() { return mutationData.databasesIncrementDocumentAttribute }, - onSuccess: (_, variables) => { - queryClient.invalidateQueries({ - queryKey: ['appwrite', 'databases', variables.databaseId, variables.collectionId], + onMutate: async (variables) => { + const documentKeyPrefix = Keys.database(variables.databaseId) + .collection(variables.collectionId) + .document(variables.documentId) + .key() + + await queryClient.cancelQueries({ queryKey: documentKeyPrefix }) + + const previousEntries = queryClient.getQueriesData({ queryKey: documentKeyPrefix }) + + queryClient.setQueriesData( + { queryKey: documentKeyPrefix }, + (old: Record | undefined) => { + if (!old) return old + const current = (old[variables.attribute] as number) ?? 0 + const increment = variables.value ?? 1 + const newValue = + variables.max != null + ? Math.min(current + increment, variables.max) + : current + increment + + return { ...old, [variables.attribute]: newValue } + }, + ) + + return { previousEntries, documentKeyPrefix } + }, + onError: (_, __, context) => { + if (context?.previousEntries) { + for (const [key, data] of context.previousEntries) { + queryClient.setQueryData(key, data) + } + } + }, + onSettled: (_, __, variables) => { + void queryClient.invalidateQueries({ + queryKey: Keys.database(variables.databaseId).collection(variables.collectionId).key(), }) }, }) diff --git a/src/databases/useInfiniteCollection.ts b/src/databases/useInfiniteCollection.ts new file mode 100644 index 0000000..337618c --- /dev/null +++ b/src/databases/useInfiniteCollection.ts @@ -0,0 +1,83 @@ +import { useCallback, useEffect, useState } from 'react' +import { Query } from 'appwrite' + +import type { Document } from './types' +import { useCollection } from './useCollection' + +export function useInfiniteCollection({ + databaseId, + collectionId, + queries, + transactionId, + limit = 25, + subscribe = true, + fields, +}: { + databaseId: string + collectionId: string + queries: string[] + transactionId?: string + limit?: number + subscribe?: boolean + fields?: (keyof TDocument & string)[] +}) { + const [page, setPage] = useState(1) + const [accumulated, setAccumulated] = useState[]>([]) + + const offset = (page - 1) * limit + const paginatedQueries = [...queries, Query.limit(limit), Query.offset(offset)] + + const collection = useCollection({ + databaseId, + collectionId, + queries: paginatedQueries, + transactionId, + subscribe, + fields, + }) + + // Accumulate documents across pages + useEffect(() => { + if (collection.documents) { + if (page === 1) { + setAccumulated([...collection.documents]) + } else { + setAccumulated((prev) => { + // Only append if we don't already have documents for this page + const expectedLength = (page - 1) * limit + collection.documents!.length + if (prev.length < expectedLength) { + return [...prev, ...collection.documents!] + } + return prev + }) + } + } + }, [collection.documents, page, limit]) + + const total = collection.total ?? 0 + const hasNextPage = total > 0 && offset + limit < total + + const fetchNextPage = useCallback(() => { + if (hasNextPage && !collection.isFetching) { + setPage((prev) => prev + 1) + } + }, [hasNextPage, collection.isFetching]) + + const reset = useCallback(() => { + setAccumulated([]) + setPage(1) + }, []) + + return { + documents: accumulated, + total, + hasNextPage, + fetchNextPage, + isFetchingNextPage: page > 1 && collection.isFetching, + isLoading: collection.isLoading, + isError: collection.isError, + error: collection.error, + isFetching: collection.isFetching, + reset, + } +} diff --git a/src/databases/useListTransactions.ts b/src/databases/useListTransactions.ts index a91cf9d..d686986 100644 --- a/src/databases/useListTransactions.ts +++ b/src/databases/useListTransactions.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { ListTransactionsQuery } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException, QueryOptions } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' @@ -21,15 +22,16 @@ const listTransactions = gql(/* GraphQL */ ` } `) -export function useListTransactions({ queries }: { queries?: string } = {}) { +type Result = ResultOf['databasesListTransactions'] + +export function useListTransactions( + { queries }: { queries?: string } = {}, + opts: QueryOptions = {}, +) { const { graphql } = useAppwrite() - const queryResult = useQuery< - ListTransactionsQuery['databasesListTransactions'], - AppwriteException[], - ListTransactionsQuery['databasesListTransactions'] - >({ - queryKey: ['appwrite', 'databases', 'transactions', { queries }], + const queryResult = useQuery({ + queryKey: [...Keys.databases().transactions().key(), ...(queries ? [queries] : [])], queryFn: async () => { const { data, errors } = await graphql.query({ query: listTransactions, @@ -42,6 +44,7 @@ export function useListTransactions({ queries }: { queries?: string } = {}) { return data.databasesListTransactions }, + ...opts, }) return { ...queryResult } diff --git a/src/databases/useUpdateDocument.ts b/src/databases/useUpdateDocument.ts index 3244995..e387501 100644 --- a/src/databases/useUpdateDocument.ts +++ b/src/databases/useUpdateDocument.ts @@ -1,23 +1,20 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { - CreateDocumentMutation, - InputMaybe, - Scalars, - UpdateDocumentMutationVariables, -} from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' -const updateDocument = gql(/* GraphQL */ ` +export const updateDocument = gql(/* GraphQL */ ` mutation UpdateDocument( $databaseId: String! $collectionId: String! $documentId: String! $data: Json $permissions: [String!] + $transactionId: String ) { databasesUpdateDocument( databaseId: $databaseId @@ -25,24 +22,42 @@ const updateDocument = gql(/* GraphQL */ ` documentId: $documentId data: $data permissions: $permissions + transactionId: $transactionId ) { _id } } `) -export function useUpdateDocument() { +type Variables = VariablesOf +type Result = ResultOf['databasesUpdateDocument'] + +type UpdateDocumentVariables = Omit & { + permissions?: string[] | null +} + +export function useUpdateDocument() { const { graphql } = useAppwrite() const queryClient = useQueryClient() const mutationResult = useMutation< - CreateDocumentMutation['databasesCreateDocument'], + Result, AppwriteException[], - Omit & { - permissions?: InputMaybe> + UpdateDocumentVariables, + { + previousEntries: [queryKey: readonly unknown[], data: unknown][] + documentKeyPrefix: readonly unknown[] } >({ - mutationFn: async ({ databaseId, collectionId, documentId, data, permissions }) => { + mutationKey: Keys.databases().collections().documents().update(), + mutationFn: async ({ + databaseId, + collectionId, + documentId, + data, + permissions, + transactionId, + }) => { const { data: mutationData, errors } = await graphql.mutation({ query: updateDocument, variables: { @@ -51,17 +66,44 @@ export function useUpdateDocument() { documentId, data: JSON.stringify(data), permissions, + transactionId, }, }) if (errors) { throw errors } + return mutationData.databasesUpdateDocument }, - onSuccess: (_, variables) => { - queryClient.invalidateQueries({ - queryKey: ['appwrite', 'databases', variables.databaseId, variables.collectionId], + onMutate: async (variables) => { + const documentKeyPrefix = Keys.database(variables.databaseId) + .collection(variables.collectionId) + .document(variables.documentId) + .key() + + await queryClient.cancelQueries({ queryKey: documentKeyPrefix }) + + const previousEntries = queryClient.getQueriesData({ queryKey: documentKeyPrefix }) + + queryClient.setQueriesData( + { queryKey: documentKeyPrefix }, + (old: Record | undefined) => + old ? { ...old, ...(variables.data as Record) } : old, + ) + + return { previousEntries, documentKeyPrefix } + }, + onError: (_, __, context) => { + if (context?.previousEntries) { + for (const [key, data] of context.previousEntries) { + queryClient.setQueryData(key, data) + } + } + }, + onSettled: (_, __, variables) => { + void queryClient.invalidateQueries({ + queryKey: Keys.database(variables.databaseId).collection(variables.collectionId).key(), }) }, }) diff --git a/src/databases/useUpdateDocuments.ts b/src/databases/useUpdateDocuments.ts deleted file mode 100644 index c5207c6..0000000 --- a/src/databases/useUpdateDocuments.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { AppwriteException } from '../types' - -import { gql } from '../__generated__' -import { - UpdateDocumentsMutation, - UpdateDocumentsMutationVariables, -} from '../__generated__/graphql' -import { useAppwrite } from '../useAppwrite' -import { useMutation } from '../useMutation' -import { useQueryClient } from '../useQueryClient' - -const updateDocuments = gql(/* GraphQL */ ` - mutation UpdateDocuments( - $databaseId: String! - $collectionId: String! - $data: Json - $queries: [String!] - ) { - databasesUpdateDocuments( - databaseId: $databaseId - collectionId: $collectionId - data: $data - queries: $queries - ) { - total - documents { - _id - } - } - } -`) - -export function useUpdateDocuments() { - const { graphql } = useAppwrite() - const queryClient = useQueryClient() - - const mutationResult = useMutation< - UpdateDocumentsMutation['databasesUpdateDocuments'], - AppwriteException[], - UpdateDocumentsMutationVariables - >({ - mutationFn: async ({ databaseId, collectionId, data, queries }) => { - const { data: mutationData, errors } = await graphql.mutation({ - query: updateDocuments, - variables: { - databaseId, - collectionId, - data: data ? JSON.stringify(data) : undefined, - queries, - }, - }) - - if (errors) { - throw errors - } - - return mutationData.databasesUpdateDocuments - }, - onSuccess: (_, variables) => { - queryClient.invalidateQueries({ - queryKey: ['appwrite', 'databases', variables.databaseId, variables.collectionId], - }) - }, - }) - - return { ...mutationResult } -} diff --git a/src/databases/useUpdateTransaction.ts b/src/databases/useUpdateTransaction.ts index c4244ca..3e80f23 100644 --- a/src/databases/useUpdateTransaction.ts +++ b/src/databases/useUpdateTransaction.ts @@ -1,10 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { - UpdateTransactionMutation, - UpdateTransactionMutationVariables, -} from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -23,15 +21,15 @@ const updateTransaction = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['databasesUpdateTransaction'] + export function useUpdateTransaction() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const mutationResult = useMutation< - UpdateTransactionMutation['databasesUpdateTransaction'], - AppwriteException[], - UpdateTransactionMutationVariables - >({ + const mutationResult = useMutation({ + mutationKey: Keys.databases().transactions().update(), mutationFn: async ({ transactionId, commit, rollback }) => { const { data, errors } = await graphql.mutation({ query: updateTransaction, @@ -45,11 +43,11 @@ export function useUpdateTransaction() { return data.databasesUpdateTransaction }, onSuccess: (_, variables) => { - queryClient.invalidateQueries({ - queryKey: ['appwrite', 'databases', 'transactions', variables.transactionId], + void queryClient.invalidateQueries({ + queryKey: Keys.databases().transaction(variables.transactionId).key(), }) - queryClient.invalidateQueries({ - queryKey: ['appwrite', 'databases', 'transactions'], + void queryClient.invalidateQueries({ + queryKey: Keys.databases().transactions().key(), }) }, }) diff --git a/src/databases/useUpsertDocument.ts b/src/databases/useUpsertDocument.ts index 97c5946..fba96f0 100644 --- a/src/databases/useUpsertDocument.ts +++ b/src/databases/useUpsertDocument.ts @@ -1,23 +1,20 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { - InputMaybe, - Scalars, - UpsertDocumentMutation, - UpsertDocumentMutationVariables, -} from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' -const upsertDocument = gql(/* GraphQL */ ` +export const upsertDocument = gql(/* GraphQL */ ` mutation UpsertDocument( $databaseId: String! $collectionId: String! $documentId: String! $data: Json! $permissions: [String!] + $transactionId: String ) { databasesUpsertDocument( databaseId: $databaseId @@ -25,24 +22,42 @@ const upsertDocument = gql(/* GraphQL */ ` documentId: $documentId data: $data permissions: $permissions + transactionId: $transactionId ) { _id } } `) +type Variables = VariablesOf +type Result = ResultOf['databasesUpsertDocument'] + +type UpsertDocumentVariables = Omit & { + permissions?: string[] | null +} + export function useUpsertDocument() { const { graphql } = useAppwrite() const queryClient = useQueryClient() const mutationResult = useMutation< - UpsertDocumentMutation['databasesUpsertDocument'], + Result, AppwriteException[], - Omit & { - permissions?: InputMaybe> + UpsertDocumentVariables, + { + previousEntries: [queryKey: readonly unknown[], data: unknown][] + documentKeyPrefix: readonly unknown[] } >({ - mutationFn: async ({ databaseId, collectionId, documentId, data, permissions }) => { + mutationKey: Keys.databases().collections().documents().upsert(), + mutationFn: async ({ + databaseId, + collectionId, + documentId, + data, + permissions, + transactionId, + }) => { const { data: mutationData, errors } = await graphql.mutation({ query: upsertDocument, variables: { @@ -51,6 +66,7 @@ export function useUpsertDocument() { documentId, data: JSON.stringify(data), permissions, + transactionId, }, }) @@ -60,9 +76,34 @@ export function useUpsertDocument() { return mutationData.databasesUpsertDocument }, - onSuccess: (_, variables) => { - queryClient.invalidateQueries({ - queryKey: ['appwrite', 'databases', variables.databaseId, variables.collectionId], + onMutate: async (variables) => { + const documentKeyPrefix = Keys.database(variables.databaseId) + .collection(variables.collectionId) + .document(variables.documentId) + .key() + + await queryClient.cancelQueries({ queryKey: documentKeyPrefix }) + + const previousEntries = queryClient.getQueriesData({ queryKey: documentKeyPrefix }) + + queryClient.setQueriesData( + { queryKey: documentKeyPrefix }, + (old: Record | undefined) => + old ? { ...old, ...(variables.data as Record) } : old, + ) + + return { previousEntries, documentKeyPrefix } + }, + onError: (_, __, context) => { + if (context?.previousEntries) { + for (const [key, data] of context.previousEntries) { + queryClient.setQueryData(key, data) + } + } + }, + onSettled: (_, __, variables) => { + void queryClient.invalidateQueries({ + queryKey: Keys.database(variables.databaseId).collection(variables.collectionId).key(), }) }, }) diff --git a/src/databases/useUpsertDocuments.ts b/src/databases/useUpsertDocuments.ts deleted file mode 100644 index ad20473..0000000 --- a/src/databases/useUpsertDocuments.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { AppwriteException } from '../types' - -import { gql } from '../__generated__' -import { - UpsertDocumentsMutation, - UpsertDocumentsMutationVariables, -} from '../__generated__/graphql' -import { useAppwrite } from '../useAppwrite' -import { useMutation } from '../useMutation' -import { useQueryClient } from '../useQueryClient' - -const upsertDocuments = gql(/* GraphQL */ ` - mutation UpsertDocuments( - $databaseId: String! - $collectionId: String! - $documents: [Json!]! - ) { - databasesUpsertDocuments( - databaseId: $databaseId - collectionId: $collectionId - documents: $documents - ) { - total - documents { - _id - } - } - } -`) - -export function useUpsertDocuments() { - const { graphql } = useAppwrite() - const queryClient = useQueryClient() - - const mutationResult = useMutation< - UpsertDocumentsMutation['databasesUpsertDocuments'], - AppwriteException[], - UpsertDocumentsMutationVariables - >({ - mutationFn: async ({ databaseId, collectionId, documents }) => { - const { data: mutationData, errors } = await graphql.mutation({ - query: upsertDocuments, - variables: { - databaseId, - collectionId, - documents: documents.map((doc) => JSON.stringify(doc)), - }, - }) - - if (errors) { - throw errors - } - - return mutationData.databasesUpsertDocuments - }, - onSuccess: (_, variables) => { - queryClient.invalidateQueries({ - queryKey: ['appwrite', 'databases', variables.databaseId, variables.collectionId], - }) - }, - }) - - return { ...mutationResult } -} diff --git a/src/databases/utils.ts b/src/databases/utils.ts new file mode 100644 index 0000000..ce3de88 --- /dev/null +++ b/src/databases/utils.ts @@ -0,0 +1,6 @@ +import { Query } from 'appwrite' + +export function mergeFieldsQuery(queries: string[], fields?: string[]): string[] { + if (!fields || fields.length === 0) return queries + return [Query.select(fields), ...queries] +} diff --git a/src/functions/useFunction.ts b/src/functions/useFunction.ts index 3ae019e..153475d 100644 --- a/src/functions/useFunction.ts +++ b/src/functions/useFunction.ts @@ -1,21 +1,22 @@ import { useState } from 'react' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { AppwriteException } from '../types' - -import { gql } from '../__generated__' -import { GetFunctionExecutionQuery } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' -import { useLazyQuery } from '../useLazyQuery' import { useMutation } from '../useMutation' import { useQuery } from '../useQuery' +import { useSuspenseQuery } from '../useSuspenseQuery' type Props = { functionId: string - body?: Record + body?: Record async?: boolean path?: string method?: string - // headers?: Record + headers?: Record + scheduledAt?: string } const createExecution = gql(/* GraphQL */ ` @@ -24,14 +25,18 @@ const createExecution = gql(/* GraphQL */ ` $body: String $async: Boolean $path: String - $method: String # $headers: Json + $method: String + $headers: String + $scheduledAt: String ) { functionsCreateExecution( functionId: $functionId body: $body async: $async path: $path - method: $method # headers: $headers + method: $method + headers: $headers + scheduledAt: $scheduledAt ) { _id status @@ -55,6 +60,10 @@ const getFunctionExecution = gql(/* GraphQL */ ` } `) +type GetExecutionResult = ResultOf['functionsGetExecution'] + +type ResponseBody = string | null | undefined | Record + function useCurrentExecution({ currentExecution, currentFunction, @@ -63,30 +72,36 @@ function useCurrentExecution({ currentFunction: string | null }) { const { graphql } = useAppwrite() + const enabled = !!currentFunction && !!currentExecution - const getExecution = useLazyQuery< - GetFunctionExecutionQuery['functionsGetExecution'], - AppwriteException[], - GetFunctionExecutionQuery['functionsGetExecution'] - >({ - queryKey: ['appwrite', 'functions', currentFunction, currentExecution], - queryFn: async () => { - if (!currentExecution || !currentFunction) { - return null - } - const { data } = await graphql.query({ - query: getFunctionExecution, - variables: { - functionId: currentFunction, - executionId: currentExecution, - }, - }) + const query = useQuery( + { + queryKey: enabled + ? Keys.function(currentFunction).execution(currentExecution).key() + : Keys.functions().key(), + queryFn: async () => { + if (!currentExecution || !currentFunction) { + return null + } + const { data } = await graphql.query({ + query: getFunctionExecution, + variables: { + functionId: currentFunction, + executionId: currentExecution, + }, + }) + + if (!data?.functionsGetExecution) { + throw new Error('Execution not found') + } - return data.functionsGetExecution ?? {} + return data.functionsGetExecution ?? null + }, + enabled, }, - }) + ) - return getExecution + return { ...query } } export function useFunction() { @@ -95,47 +110,53 @@ export function useFunction() { const [currentFunction, setCurrentFunction] = useState(null) const getExecution = useCurrentExecution({ currentExecution, currentFunction }) - const executeFunction = useMutation, AppwriteException[], Props, unknown>( - { - mutationFn: async ({ - functionId, - body = {}, - async = false, - path = '/', - method = 'POST', - // headers = {}, - }) => { - setCurrentFunction(functionId) - - const { data } = await graphql.mutation({ - query: createExecution, - variables: { - functionId, - body: JSON.stringify(body), - async, - path, - method, - // headers: JSON.stringify(headers), - }, - }) + const executeFunction = useMutation({ + mutationKey: Keys.functions().executions().create(), + mutationFn: async ({ + functionId, + body = {}, + async = false, + path = '/', + method = 'POST', + headers = {}, + scheduledAt, + }) => { + setCurrentFunction(functionId) - const { _id, status, responseBody, errors } = data.functionsCreateExecution ?? {} + const { data } = await graphql.mutation({ + query: createExecution, + variables: { + functionId, + body: JSON.stringify(body), + async, + path, + method, + headers: JSON.stringify(headers), + scheduledAt, + }, + }) - if (status === 'failed') { - throw new Error(errors) - } + const { _id, status, errors, responseBody } = data.functionsCreateExecution ?? {} - setCurrentExecution(_id ?? null) + if (status === 'failed') { + throw new Error(errors) + } - let parsedResponseBody = {} - try { - parsedResponseBody = JSON.parse(responseBody ?? '{}') - } catch (error) {} + setCurrentExecution(_id ?? null) - return parsedResponseBody - }, + if (typeof responseBody === 'string') { + if (responseBody.trim().startsWith('{') && responseBody.trim().endsWith('}')) { + try { + return JSON.parse(responseBody) + } catch (error) { + console.error('Failed to parse response body:', error) + return responseBody + } + } + return responseBody + } }, - ) + }) return { executeFunction, @@ -149,16 +170,13 @@ export function useSuspenseFunction({ async = false, path = '/', method = 'POST', -}: // headers = {}, -Props) { + headers = {}, + scheduledAt, +}: Props) { const { graphql } = useAppwrite() - const executeFunction = useQuery< - Record, - AppwriteException[], - Record - >({ - queryKey: ['appwrite', 'functions', functionId, path], + const executeFunction = useSuspenseQuery({ + queryKey: [...Keys.function(functionId).key(), 'execute', { path, method, body }], queryFn: async () => { const { data } = await graphql.mutation({ query: createExecution, @@ -168,23 +186,30 @@ Props) { async, path, method, - // headers, + headers: JSON.stringify(headers), + scheduledAt, }, }) - const { status, responseBody, errors } = data.functionsCreateExecution ?? {} - - if (status === 'failed') { - throw new Error(errors) + if (data?.functionsCreateExecution?.status === 'failed') { + throw new Error(data.functionsCreateExecution.errors) } - let parsedResponseBody = {} - try { - parsedResponseBody = JSON.parse(responseBody ?? '{}') - } catch (error) {} + const { responseBody } = data.functionsCreateExecution ?? {} - return parsedResponseBody + if (typeof responseBody === 'string') { + if (responseBody.trim().startsWith('{') && responseBody.trim().endsWith('}')) { + try { + return JSON.parse(responseBody) + } catch (error) { + console.error('Failed to parse response body:', error) + return responseBody + } + } + } + return responseBody }, + staleTime: Infinity, }) return { diff --git a/src/functions/useGetExecution.ts b/src/functions/useGetExecution.ts index b6ab0f3..20d20fe 100644 --- a/src/functions/useGetExecution.ts +++ b/src/functions/useGetExecution.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { GetExecutionQuery, GetExecutionQueryVariables } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException, QueryOptions } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' @@ -24,15 +25,14 @@ const getExecution = gql(/* GraphQL */ ` } `) -export function useGetExecution({ functionId, executionId }: GetExecutionQueryVariables) { +type Variables = VariablesOf +type Result = ResultOf['functionsGetExecution'] + +export function useGetExecution({ functionId, executionId }: Variables, opts: QueryOptions = {}) { const { graphql } = useAppwrite() - const queryResult = useQuery< - GetExecutionQuery['functionsGetExecution'], - AppwriteException[], - GetExecutionQuery['functionsGetExecution'] - >({ - queryKey: ['appwrite', 'functions', functionId, 'executions', executionId], + const queryResult = useQuery({ + queryKey: Keys.function(functionId).execution(executionId).key(), queryFn: async () => { const { data, errors } = await graphql.query({ query: getExecution, @@ -45,6 +45,7 @@ export function useGetExecution({ functionId, executionId }: GetExecutionQueryVa return data.functionsGetExecution }, + ...opts, }) return { ...queryResult } diff --git a/src/functions/useListExecutions.ts b/src/functions/useListExecutions.ts index fa23e96..81b5d4d 100644 --- a/src/functions/useListExecutions.ts +++ b/src/functions/useListExecutions.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { ListExecutionsQuery } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException, QueryOptions } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' @@ -27,21 +28,22 @@ const listExecutions = gql(/* GraphQL */ ` } `) -export function useListExecutions({ - functionId, - queries, -}: { - functionId: string - queries?: string[] -}) { +type Result = ResultOf['functionsListExecutions'] + +export function useListExecutions( + { + functionId, + queries, + }: { + functionId: string + queries?: string[] + }, + opts: QueryOptions = {}, +) { const { graphql } = useAppwrite() - const queryResult = useQuery< - ListExecutionsQuery['functionsListExecutions'], - AppwriteException[], - ListExecutionsQuery['functionsListExecutions'] - >({ - queryKey: ['appwrite', 'functions', functionId, 'executions', { queries }], + const queryResult = useQuery({ + queryKey: [...Keys.function(functionId).executions().key(), ...(queries ?? [])], queryFn: async () => { const { data, errors } = await graphql.query({ query: listExecutions, @@ -57,6 +59,7 @@ export function useListExecutions({ return data.functionsListExecutions }, + ...opts, }) return { ...queryResult } diff --git a/src/graphql-env.d.ts b/src/graphql-env.d.ts new file mode 100644 index 0000000..539e58e --- /dev/null +++ b/src/graphql-env.d.ts @@ -0,0 +1,81 @@ +/* eslint-disable */ +/* prettier-ignore */ + +export type introspection_types = { + 'Assoc': unknown; + 'Boolean': unknown; + 'Continent': { kind: 'OBJECT'; name: 'Continent'; fields: { 'code': { name: 'code'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'name': { name: 'name'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; }; + 'ContinentList': { kind: 'OBJECT'; name: 'ContinentList'; fields: { 'continents': { name: 'continents'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'Continent'; ofType: null; }; } }; 'total': { name: 'total'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; }; }; + 'Country': { kind: 'OBJECT'; name: 'Country'; fields: { 'code': { name: 'code'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'name': { name: 'name'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; }; + 'CountryList': { kind: 'OBJECT'; name: 'CountryList'; fields: { 'countries': { name: 'countries'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'Country'; ofType: null; }; } }; 'total': { name: 'total'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; }; }; + 'Currency': { kind: 'OBJECT'; name: 'Currency'; fields: { 'code': { name: 'code'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'decimalDigits': { name: 'decimalDigits'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; 'name': { name: 'name'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'namePlural': { name: 'namePlural'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'rounding': { name: 'rounding'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; } }; 'symbol': { name: 'symbol'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'symbolNative': { name: 'symbolNative'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; }; + 'CurrencyList': { kind: 'OBJECT'; name: 'CurrencyList'; fields: { 'currencies': { name: 'currencies'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'Currency'; ofType: null; }; } }; 'total': { name: 'total'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; }; }; + 'Document': { kind: 'OBJECT'; name: 'Document'; fields: { '_collectionId': { name: '_collectionId'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_createdAt': { name: '_createdAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_databaseId': { name: '_databaseId'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_id': { name: '_id'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_permissions': { name: '_permissions'; type: { kind: 'LIST'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; '_updatedAt': { name: '_updatedAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'data': { name: 'data'; type: { kind: 'SCALAR'; name: 'Json'; ofType: null; } }; }; }; + 'DocumentList': { kind: 'OBJECT'; name: 'DocumentList'; fields: { 'documents': { name: 'documents'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'Document'; ofType: null; }; } }; 'total': { name: 'total'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; }; }; + 'Execution': { kind: 'OBJECT'; name: 'Execution'; fields: { '_createdAt': { name: '_createdAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_id': { name: '_id'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_permissions': { name: '_permissions'; type: { kind: 'LIST'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; '_updatedAt': { name: '_updatedAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'deploymentId': { name: 'deploymentId'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'duration': { name: 'duration'; type: { kind: 'SCALAR'; name: 'Float'; ofType: null; } }; 'errors': { name: 'errors'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'functionId': { name: 'functionId'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'logs': { name: 'logs'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'requestHeaders': { name: 'requestHeaders'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'Headers'; ofType: null; }; } }; 'requestMethod': { name: 'requestMethod'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'requestPath': { name: 'requestPath'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'responseBody': { name: 'responseBody'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'responseHeaders': { name: 'responseHeaders'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'Headers'; ofType: null; }; } }; 'responseStatusCode': { name: 'responseStatusCode'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; 'scheduledAt': { name: 'scheduledAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'status': { name: 'status'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'trigger': { name: 'trigger'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; }; + 'ExecutionList': { kind: 'OBJECT'; name: 'ExecutionList'; fields: { 'executions': { name: 'executions'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'Execution'; ofType: null; }; } }; 'total': { name: 'total'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; }; }; + 'File': { kind: 'OBJECT'; name: 'File'; fields: { '_createdAt': { name: '_createdAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_id': { name: '_id'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_permissions': { name: '_permissions'; type: { kind: 'LIST'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; '_updatedAt': { name: '_updatedAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'bucketId': { name: 'bucketId'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'chunksTotal': { name: 'chunksTotal'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; 'chunksUploaded': { name: 'chunksUploaded'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; 'mimeType': { name: 'mimeType'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'name': { name: 'name'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'signature': { name: 'signature'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'sizeOriginal': { name: 'sizeOriginal'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; }; }; + 'FileList': { kind: 'OBJECT'; name: 'FileList'; fields: { 'files': { name: 'files'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'File'; ofType: null; }; } }; 'total': { name: 'total'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; }; }; + 'Float': unknown; + 'Headers': { kind: 'OBJECT'; name: 'Headers'; fields: { 'name': { name: 'name'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'value': { name: 'value'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; }; + 'Identity': { kind: 'OBJECT'; name: 'Identity'; fields: { '_createdAt': { name: '_createdAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_id': { name: '_id'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_updatedAt': { name: '_updatedAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'provider': { name: 'provider'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'providerAccessToken': { name: 'providerAccessToken'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'providerAccessTokenExpiry': { name: 'providerAccessTokenExpiry'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'providerEmail': { name: 'providerEmail'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'providerRefreshToken': { name: 'providerRefreshToken'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'providerUid': { name: 'providerUid'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'userId': { name: 'userId'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; }; + 'IdentityList': { kind: 'OBJECT'; name: 'IdentityList'; fields: { 'identities': { name: 'identities'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'Identity'; ofType: null; }; } }; 'total': { name: 'total'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; }; }; + 'InputFile': unknown; + 'Int': unknown; + 'Json': unknown; + 'Jwt': { kind: 'OBJECT'; name: 'Jwt'; fields: { 'jwt': { name: 'jwt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; }; + 'Language': { kind: 'OBJECT'; name: 'Language'; fields: { 'code': { name: 'code'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'name': { name: 'name'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'nativeName': { name: 'nativeName'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; }; + 'LanguageList': { kind: 'OBJECT'; name: 'LanguageList'; fields: { 'languages': { name: 'languages'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'Language'; ofType: null; }; } }; 'total': { name: 'total'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; }; }; + 'Locale': { kind: 'OBJECT'; name: 'Locale'; fields: { 'continent': { name: 'continent'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'continentCode': { name: 'continentCode'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'country': { name: 'country'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'countryCode': { name: 'countryCode'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'currency': { name: 'currency'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'eu': { name: 'eu'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; } }; 'ip': { name: 'ip'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; }; + 'LocaleCode': { kind: 'OBJECT'; name: 'LocaleCode'; fields: { 'code': { name: 'code'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'name': { name: 'name'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; }; + 'LocaleCodeList': { kind: 'OBJECT'; name: 'LocaleCodeList'; fields: { 'localeCodes': { name: 'localeCodes'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'LocaleCode'; ofType: null; }; } }; 'total': { name: 'total'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; }; }; + 'Log': { kind: 'OBJECT'; name: 'Log'; fields: { 'clientCode': { name: 'clientCode'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'clientEngine': { name: 'clientEngine'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'clientEngineVersion': { name: 'clientEngineVersion'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'clientName': { name: 'clientName'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'clientType': { name: 'clientType'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'clientVersion': { name: 'clientVersion'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'countryCode': { name: 'countryCode'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'countryName': { name: 'countryName'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'deviceBrand': { name: 'deviceBrand'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'deviceModel': { name: 'deviceModel'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'deviceName': { name: 'deviceName'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'event': { name: 'event'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'ip': { name: 'ip'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'mode': { name: 'mode'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'osCode': { name: 'osCode'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'osName': { name: 'osName'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'osVersion': { name: 'osVersion'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'time': { name: 'time'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'userEmail': { name: 'userEmail'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'userId': { name: 'userId'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'userName': { name: 'userName'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; }; + 'LogList': { kind: 'OBJECT'; name: 'LogList'; fields: { 'logs': { name: 'logs'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'Log'; ofType: null; }; } }; 'total': { name: 'total'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; }; }; + 'Membership': { kind: 'OBJECT'; name: 'Membership'; fields: { '_createdAt': { name: '_createdAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_id': { name: '_id'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_updatedAt': { name: '_updatedAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'confirm': { name: 'confirm'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; } }; 'invited': { name: 'invited'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'joined': { name: 'joined'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'mfa': { name: 'mfa'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; } }; 'roles': { name: 'roles'; type: { kind: 'LIST'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'teamId': { name: 'teamId'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'teamName': { name: 'teamName'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'userEmail': { name: 'userEmail'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'userId': { name: 'userId'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'userName': { name: 'userName'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; }; + 'MembershipList': { kind: 'OBJECT'; name: 'MembershipList'; fields: { 'memberships': { name: 'memberships'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'Membership'; ofType: null; }; } }; 'total': { name: 'total'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; }; }; + 'MfaChallenge': { kind: 'OBJECT'; name: 'MfaChallenge'; fields: { '_createdAt': { name: '_createdAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_id': { name: '_id'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'expire': { name: 'expire'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'userId': { name: 'userId'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; }; + 'MfaFactors': { kind: 'OBJECT'; name: 'MfaFactors'; fields: { 'email': { name: 'email'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; } }; 'phone': { name: 'phone'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; } }; 'recoveryCode': { name: 'recoveryCode'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; } }; 'totp': { name: 'totp'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; } }; }; }; + 'MfaRecoveryCodes': { kind: 'OBJECT'; name: 'MfaRecoveryCodes'; fields: { 'recoveryCodes': { name: 'recoveryCodes'; type: { kind: 'LIST'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; }; }; + 'MfaType': { kind: 'OBJECT'; name: 'MfaType'; fields: { 'secret': { name: 'secret'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'uri': { name: 'uri'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; }; + 'Mutation': { kind: 'OBJECT'; name: 'Mutation'; fields: { 'accountCreate': { name: 'accountCreate'; type: { kind: 'OBJECT'; name: 'User'; ofType: null; } }; 'accountCreateAnonymousSession': { name: 'accountCreateAnonymousSession'; type: { kind: 'OBJECT'; name: 'Session'; ofType: null; } }; 'accountCreateEmailPasswordSession': { name: 'accountCreateEmailPasswordSession'; type: { kind: 'OBJECT'; name: 'Session'; ofType: null; } }; 'accountCreateEmailToken': { name: 'accountCreateEmailToken'; type: { kind: 'OBJECT'; name: 'Token'; ofType: null; } }; 'accountCreateEmailVerification': { name: 'accountCreateEmailVerification'; type: { kind: 'OBJECT'; name: 'Token'; ofType: null; } }; 'accountCreateJWT': { name: 'accountCreateJWT'; type: { kind: 'OBJECT'; name: 'Jwt'; ofType: null; } }; 'accountCreateMagicURLToken': { name: 'accountCreateMagicURLToken'; type: { kind: 'OBJECT'; name: 'Token'; ofType: null; } }; 'accountCreateMfaAuthenticator': { name: 'accountCreateMfaAuthenticator'; type: { kind: 'OBJECT'; name: 'MfaType'; ofType: null; } }; 'accountCreateMfaChallenge': { name: 'accountCreateMfaChallenge'; type: { kind: 'OBJECT'; name: 'MfaChallenge'; ofType: null; } }; 'accountCreateMfaRecoveryCodes': { name: 'accountCreateMfaRecoveryCodes'; type: { kind: 'OBJECT'; name: 'MfaRecoveryCodes'; ofType: null; } }; 'accountCreatePhoneToken': { name: 'accountCreatePhoneToken'; type: { kind: 'OBJECT'; name: 'Token'; ofType: null; } }; 'accountCreatePhoneVerification': { name: 'accountCreatePhoneVerification'; type: { kind: 'OBJECT'; name: 'Token'; ofType: null; } }; 'accountCreatePushTarget': { name: 'accountCreatePushTarget'; type: { kind: 'OBJECT'; name: 'Target'; ofType: null; } }; 'accountCreateRecovery': { name: 'accountCreateRecovery'; type: { kind: 'OBJECT'; name: 'Token'; ofType: null; } }; 'accountCreateSession': { name: 'accountCreateSession'; type: { kind: 'OBJECT'; name: 'Session'; ofType: null; } }; 'accountCreateVerification': { name: 'accountCreateVerification'; type: { kind: 'OBJECT'; name: 'Token'; ofType: null; } }; 'accountDeleteIdentity': { name: 'accountDeleteIdentity'; type: { kind: 'OBJECT'; name: 'None'; ofType: null; } }; 'accountDeleteMfaAuthenticator': { name: 'accountDeleteMfaAuthenticator'; type: { kind: 'OBJECT'; name: 'None'; ofType: null; } }; 'accountDeletePushTarget': { name: 'accountDeletePushTarget'; type: { kind: 'OBJECT'; name: 'None'; ofType: null; } }; 'accountDeleteSession': { name: 'accountDeleteSession'; type: { kind: 'OBJECT'; name: 'None'; ofType: null; } }; 'accountDeleteSessions': { name: 'accountDeleteSessions'; type: { kind: 'OBJECT'; name: 'None'; ofType: null; } }; 'accountUpdateEmail': { name: 'accountUpdateEmail'; type: { kind: 'OBJECT'; name: 'User'; ofType: null; } }; 'accountUpdateEmailVerification': { name: 'accountUpdateEmailVerification'; type: { kind: 'OBJECT'; name: 'Token'; ofType: null; } }; 'accountUpdateMFA': { name: 'accountUpdateMFA'; type: { kind: 'OBJECT'; name: 'User'; ofType: null; } }; 'accountUpdateMagicURLSession': { name: 'accountUpdateMagicURLSession'; type: { kind: 'OBJECT'; name: 'Session'; ofType: null; } }; 'accountUpdateMfaAuthenticator': { name: 'accountUpdateMfaAuthenticator'; type: { kind: 'OBJECT'; name: 'User'; ofType: null; } }; 'accountUpdateMfaChallenge': { name: 'accountUpdateMfaChallenge'; type: { kind: 'OBJECT'; name: 'Session'; ofType: null; } }; 'accountUpdateMfaRecoveryCodes': { name: 'accountUpdateMfaRecoveryCodes'; type: { kind: 'OBJECT'; name: 'MfaRecoveryCodes'; ofType: null; } }; 'accountUpdateName': { name: 'accountUpdateName'; type: { kind: 'OBJECT'; name: 'User'; ofType: null; } }; 'accountUpdatePassword': { name: 'accountUpdatePassword'; type: { kind: 'OBJECT'; name: 'User'; ofType: null; } }; 'accountUpdatePhone': { name: 'accountUpdatePhone'; type: { kind: 'OBJECT'; name: 'User'; ofType: null; } }; 'accountUpdatePhoneSession': { name: 'accountUpdatePhoneSession'; type: { kind: 'OBJECT'; name: 'Session'; ofType: null; } }; 'accountUpdatePhoneVerification': { name: 'accountUpdatePhoneVerification'; type: { kind: 'OBJECT'; name: 'Token'; ofType: null; } }; 'accountUpdatePrefs': { name: 'accountUpdatePrefs'; type: { kind: 'OBJECT'; name: 'User'; ofType: null; } }; 'accountUpdatePushTarget': { name: 'accountUpdatePushTarget'; type: { kind: 'OBJECT'; name: 'Target'; ofType: null; } }; 'accountUpdateRecovery': { name: 'accountUpdateRecovery'; type: { kind: 'OBJECT'; name: 'Token'; ofType: null; } }; 'accountUpdateSession': { name: 'accountUpdateSession'; type: { kind: 'OBJECT'; name: 'Session'; ofType: null; } }; 'accountUpdateStatus': { name: 'accountUpdateStatus'; type: { kind: 'OBJECT'; name: 'User'; ofType: null; } }; 'accountUpdateVerification': { name: 'accountUpdateVerification'; type: { kind: 'OBJECT'; name: 'Token'; ofType: null; } }; 'databasesCreateDocument': { name: 'databasesCreateDocument'; type: { kind: 'OBJECT'; name: 'Document'; ofType: null; } }; 'databasesCreateOperations': { name: 'databasesCreateOperations'; type: { kind: 'OBJECT'; name: 'Transaction'; ofType: null; } }; 'databasesCreateTransaction': { name: 'databasesCreateTransaction'; type: { kind: 'OBJECT'; name: 'Transaction'; ofType: null; } }; 'databasesDecrementDocumentAttribute': { name: 'databasesDecrementDocumentAttribute'; type: { kind: 'OBJECT'; name: 'Document'; ofType: null; } }; 'databasesDeleteDocument': { name: 'databasesDeleteDocument'; type: { kind: 'OBJECT'; name: 'None'; ofType: null; } }; 'databasesDeleteTransaction': { name: 'databasesDeleteTransaction'; type: { kind: 'OBJECT'; name: 'None'; ofType: null; } }; 'databasesIncrementDocumentAttribute': { name: 'databasesIncrementDocumentAttribute'; type: { kind: 'OBJECT'; name: 'Document'; ofType: null; } }; 'databasesUpdateDocument': { name: 'databasesUpdateDocument'; type: { kind: 'OBJECT'; name: 'Document'; ofType: null; } }; 'databasesUpdateTransaction': { name: 'databasesUpdateTransaction'; type: { kind: 'OBJECT'; name: 'Transaction'; ofType: null; } }; 'databasesUpsertDocument': { name: 'databasesUpsertDocument'; type: { kind: 'OBJECT'; name: 'Document'; ofType: null; } }; 'functionsCreateExecution': { name: 'functionsCreateExecution'; type: { kind: 'OBJECT'; name: 'Execution'; ofType: null; } }; 'messagingCreateSubscriber': { name: 'messagingCreateSubscriber'; type: { kind: 'OBJECT'; name: 'Subscriber'; ofType: null; } }; 'messagingDeleteSubscriber': { name: 'messagingDeleteSubscriber'; type: { kind: 'OBJECT'; name: 'None'; ofType: null; } }; 'storageCreateFile': { name: 'storageCreateFile'; type: { kind: 'OBJECT'; name: 'File'; ofType: null; } }; 'storageDeleteFile': { name: 'storageDeleteFile'; type: { kind: 'OBJECT'; name: 'None'; ofType: null; } }; 'storageUpdateFile': { name: 'storageUpdateFile'; type: { kind: 'OBJECT'; name: 'File'; ofType: null; } }; 'teamsCreate': { name: 'teamsCreate'; type: { kind: 'OBJECT'; name: 'Team'; ofType: null; } }; 'teamsCreateMembership': { name: 'teamsCreateMembership'; type: { kind: 'OBJECT'; name: 'Membership'; ofType: null; } }; 'teamsDelete': { name: 'teamsDelete'; type: { kind: 'OBJECT'; name: 'None'; ofType: null; } }; 'teamsDeleteMembership': { name: 'teamsDeleteMembership'; type: { kind: 'OBJECT'; name: 'None'; ofType: null; } }; 'teamsUpdateMembership': { name: 'teamsUpdateMembership'; type: { kind: 'OBJECT'; name: 'Membership'; ofType: null; } }; 'teamsUpdateMembershipStatus': { name: 'teamsUpdateMembershipStatus'; type: { kind: 'OBJECT'; name: 'Membership'; ofType: null; } }; 'teamsUpdateName': { name: 'teamsUpdateName'; type: { kind: 'OBJECT'; name: 'Team'; ofType: null; } }; 'teamsUpdatePrefs': { name: 'teamsUpdatePrefs'; type: { kind: 'OBJECT'; name: 'Preferences'; ofType: null; } }; }; }; + 'None': { kind: 'OBJECT'; name: 'None'; fields: { 'status': { name: 'status'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; }; + 'Phone': { kind: 'OBJECT'; name: 'Phone'; fields: { 'code': { name: 'code'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'countryCode': { name: 'countryCode'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'countryName': { name: 'countryName'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; }; + 'PhoneList': { kind: 'OBJECT'; name: 'PhoneList'; fields: { 'phones': { name: 'phones'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'Phone'; ofType: null; }; } }; 'total': { name: 'total'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; }; }; + 'Preferences': { kind: 'OBJECT'; name: 'Preferences'; fields: { 'data': { name: 'data'; type: { kind: 'SCALAR'; name: 'Json'; ofType: null; } }; }; }; + 'Query': { kind: 'OBJECT'; name: 'Query'; fields: { 'accountGet': { name: 'accountGet'; type: { kind: 'OBJECT'; name: 'User'; ofType: null; } }; 'accountGetMfaRecoveryCodes': { name: 'accountGetMfaRecoveryCodes'; type: { kind: 'OBJECT'; name: 'MfaRecoveryCodes'; ofType: null; } }; 'accountGetPrefs': { name: 'accountGetPrefs'; type: { kind: 'OBJECT'; name: 'Preferences'; ofType: null; } }; 'accountGetSession': { name: 'accountGetSession'; type: { kind: 'OBJECT'; name: 'Session'; ofType: null; } }; 'accountListIdentities': { name: 'accountListIdentities'; type: { kind: 'OBJECT'; name: 'IdentityList'; ofType: null; } }; 'accountListLogs': { name: 'accountListLogs'; type: { kind: 'OBJECT'; name: 'LogList'; ofType: null; } }; 'accountListMfaFactors': { name: 'accountListMfaFactors'; type: { kind: 'OBJECT'; name: 'MfaFactors'; ofType: null; } }; 'accountListSessions': { name: 'accountListSessions'; type: { kind: 'OBJECT'; name: 'SessionList'; ofType: null; } }; 'databasesGetDocument': { name: 'databasesGetDocument'; type: { kind: 'OBJECT'; name: 'Document'; ofType: null; } }; 'databasesGetTransaction': { name: 'databasesGetTransaction'; type: { kind: 'OBJECT'; name: 'Transaction'; ofType: null; } }; 'databasesListDocuments': { name: 'databasesListDocuments'; type: { kind: 'OBJECT'; name: 'DocumentList'; ofType: null; } }; 'databasesListTransactions': { name: 'databasesListTransactions'; type: { kind: 'OBJECT'; name: 'TransactionList'; ofType: null; } }; 'functionsGetExecution': { name: 'functionsGetExecution'; type: { kind: 'OBJECT'; name: 'Execution'; ofType: null; } }; 'functionsListExecutions': { name: 'functionsListExecutions'; type: { kind: 'OBJECT'; name: 'ExecutionList'; ofType: null; } }; 'localeGet': { name: 'localeGet'; type: { kind: 'OBJECT'; name: 'Locale'; ofType: null; } }; 'localeListCodes': { name: 'localeListCodes'; type: { kind: 'OBJECT'; name: 'LocaleCodeList'; ofType: null; } }; 'localeListContinents': { name: 'localeListContinents'; type: { kind: 'OBJECT'; name: 'ContinentList'; ofType: null; } }; 'localeListCountries': { name: 'localeListCountries'; type: { kind: 'OBJECT'; name: 'CountryList'; ofType: null; } }; 'localeListCountriesEU': { name: 'localeListCountriesEU'; type: { kind: 'OBJECT'; name: 'CountryList'; ofType: null; } }; 'localeListCountriesPhones': { name: 'localeListCountriesPhones'; type: { kind: 'OBJECT'; name: 'PhoneList'; ofType: null; } }; 'localeListCurrencies': { name: 'localeListCurrencies'; type: { kind: 'OBJECT'; name: 'CurrencyList'; ofType: null; } }; 'localeListLanguages': { name: 'localeListLanguages'; type: { kind: 'OBJECT'; name: 'LanguageList'; ofType: null; } }; 'storageGetFile': { name: 'storageGetFile'; type: { kind: 'OBJECT'; name: 'File'; ofType: null; } }; 'storageGetFileDownload': { name: 'storageGetFileDownload'; type: { kind: 'OBJECT'; name: 'None'; ofType: null; } }; 'storageGetFilePreview': { name: 'storageGetFilePreview'; type: { kind: 'OBJECT'; name: 'None'; ofType: null; } }; 'storageGetFileView': { name: 'storageGetFileView'; type: { kind: 'OBJECT'; name: 'None'; ofType: null; } }; 'storageListFiles': { name: 'storageListFiles'; type: { kind: 'OBJECT'; name: 'FileList'; ofType: null; } }; 'teamsGet': { name: 'teamsGet'; type: { kind: 'OBJECT'; name: 'Team'; ofType: null; } }; 'teamsGetMembership': { name: 'teamsGetMembership'; type: { kind: 'OBJECT'; name: 'Membership'; ofType: null; } }; 'teamsGetPrefs': { name: 'teamsGetPrefs'; type: { kind: 'OBJECT'; name: 'Preferences'; ofType: null; } }; 'teamsList': { name: 'teamsList'; type: { kind: 'OBJECT'; name: 'TeamList'; ofType: null; } }; 'teamsListMemberships': { name: 'teamsListMemberships'; type: { kind: 'OBJECT'; name: 'MembershipList'; ofType: null; } }; }; }; + 'Session': { kind: 'OBJECT'; name: 'Session'; fields: { '_createdAt': { name: '_createdAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_id': { name: '_id'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_updatedAt': { name: '_updatedAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'clientCode': { name: 'clientCode'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'clientEngine': { name: 'clientEngine'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'clientEngineVersion': { name: 'clientEngineVersion'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'clientName': { name: 'clientName'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'clientType': { name: 'clientType'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'clientVersion': { name: 'clientVersion'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'countryCode': { name: 'countryCode'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'countryName': { name: 'countryName'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'current': { name: 'current'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; } }; 'deviceBrand': { name: 'deviceBrand'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'deviceModel': { name: 'deviceModel'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'deviceName': { name: 'deviceName'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'expire': { name: 'expire'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'factors': { name: 'factors'; type: { kind: 'LIST'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'ip': { name: 'ip'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'mfaUpdatedAt': { name: 'mfaUpdatedAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'osCode': { name: 'osCode'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'osName': { name: 'osName'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'osVersion': { name: 'osVersion'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'provider': { name: 'provider'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'providerAccessToken': { name: 'providerAccessToken'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'providerAccessTokenExpiry': { name: 'providerAccessTokenExpiry'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'providerRefreshToken': { name: 'providerRefreshToken'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'providerUid': { name: 'providerUid'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'secret': { name: 'secret'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'userId': { name: 'userId'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; }; + 'SessionList': { kind: 'OBJECT'; name: 'SessionList'; fields: { 'sessions': { name: 'sessions'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'Session'; ofType: null; }; } }; 'total': { name: 'total'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; }; }; + 'String': unknown; + 'Subscriber': { kind: 'OBJECT'; name: 'Subscriber'; fields: { '_createdAt': { name: '_createdAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_id': { name: '_id'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_updatedAt': { name: '_updatedAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'providerType': { name: 'providerType'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'target': { name: 'target'; type: { kind: 'OBJECT'; name: 'Target'; ofType: null; } }; 'targetId': { name: 'targetId'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'topicId': { name: 'topicId'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'userId': { name: 'userId'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'userName': { name: 'userName'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; }; + 'Target': { kind: 'OBJECT'; name: 'Target'; fields: { '_createdAt': { name: '_createdAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_id': { name: '_id'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_updatedAt': { name: '_updatedAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'expired': { name: 'expired'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; } }; 'identifier': { name: 'identifier'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'name': { name: 'name'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'providerId': { name: 'providerId'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'providerType': { name: 'providerType'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'userId': { name: 'userId'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; }; + 'Team': { kind: 'OBJECT'; name: 'Team'; fields: { '_createdAt': { name: '_createdAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_id': { name: '_id'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_updatedAt': { name: '_updatedAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'name': { name: 'name'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'prefs': { name: 'prefs'; type: { kind: 'OBJECT'; name: 'Preferences'; ofType: null; } }; 'total': { name: 'total'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; }; }; + 'TeamList': { kind: 'OBJECT'; name: 'TeamList'; fields: { 'teams': { name: 'teams'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'Team'; ofType: null; }; } }; 'total': { name: 'total'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; }; }; + 'Token': { kind: 'OBJECT'; name: 'Token'; fields: { '_createdAt': { name: '_createdAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_id': { name: '_id'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'expire': { name: 'expire'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'phrase': { name: 'phrase'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'secret': { name: 'secret'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'userId': { name: 'userId'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; }; + 'Transaction': { kind: 'OBJECT'; name: 'Transaction'; fields: { '_createdAt': { name: '_createdAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_id': { name: '_id'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_updatedAt': { name: '_updatedAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'expiresAt': { name: 'expiresAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'operations': { name: 'operations'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; 'status': { name: 'status'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; }; }; + 'TransactionList': { kind: 'OBJECT'; name: 'TransactionList'; fields: { 'total': { name: 'total'; type: { kind: 'SCALAR'; name: 'Int'; ofType: null; } }; 'transactions': { name: 'transactions'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'Transaction'; ofType: null; }; } }; }; }; + 'User': { kind: 'OBJECT'; name: 'User'; fields: { '_createdAt': { name: '_createdAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_id': { name: '_id'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; '_updatedAt': { name: '_updatedAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'accessedAt': { name: 'accessedAt'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'email': { name: 'email'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'emailVerification': { name: 'emailVerification'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; } }; 'labels': { name: 'labels'; type: { kind: 'LIST'; name: never; ofType: { kind: 'SCALAR'; name: 'String'; ofType: null; }; } }; 'mfa': { name: 'mfa'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; } }; 'name': { name: 'name'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'phone': { name: 'phone'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'phoneVerification': { name: 'phoneVerification'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; } }; 'prefs': { name: 'prefs'; type: { kind: 'OBJECT'; name: 'Preferences'; ofType: null; } }; 'registration': { name: 'registration'; type: { kind: 'SCALAR'; name: 'String'; ofType: null; } }; 'status': { name: 'status'; type: { kind: 'SCALAR'; name: 'Boolean'; ofType: null; } }; 'targets': { name: 'targets'; type: { kind: 'LIST'; name: never; ofType: { kind: 'OBJECT'; name: 'Target'; ofType: null; }; } }; }; }; +}; + +/** An IntrospectionQuery representation of your schema. + * + * @remarks + * This is an introspection of your schema saved as a file by GraphQLSP. + * It will automatically be used by `gql.tada` to infer the types of your GraphQL documents. + * If you need to reuse this data or update your `scalars`, update `tadaOutputLocation` to + * instead save to a .ts instead of a .d.ts file. + */ +export type introspection = { + name: never; + query: 'Query'; + mutation: 'Mutation'; + subscription: never; + types: introspection_types; +}; + +import * as gqlTada from 'gql.tada'; + +declare module 'gql.tada' { + interface setupSchema { + introspection: introspection + } +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 4efbcc9..a5a29fe 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,31 +1,26 @@ -import * as frags from './account/fragments' -import { Account_UserFragment, Identity_ProviderFragment } from './__generated__/graphql' - export { useAppwrite } from './useAppwrite' export { useMutation } from './useMutation' export { useQuery } from './useQuery' export { useLazyQuery } from './useLazyQuery' export { useSuspenseQuery } from './useSuspenseQuery' export { useQueryClient } from './useQueryClient' + +export { createAppwriteClient } from './client' export { AppwriteProvider } from './AppwriteProvider' export * from './account' export * from './avatars' export * from './databases' export * from './locale' +export * from './messaging' export * from './storage' export * from './teams' +export * from './query/QueryBuilder' +export { Keys } from './query/Keys' + +export * from './offline' + export * from './functions/useFunction' export * from './functions/useGetExecution' export * from './functions/useListExecutions' - -export { getFragmentData } from './__generated__' - -export namespace fragments { - export const Account_UserFragment = frags.Account_User - export type Account_UserFragmentType = Account_UserFragment - - export const Identity_ProviderFragment = frags.Identity_Provider - export type Identity_ProviderFragmentType = Identity_ProviderFragment -} diff --git a/src/locale/useLocale.ts b/src/locale/useLocale.ts index dc7540a..7dc98b2 100644 --- a/src/locale/useLocale.ts +++ b/src/locale/useLocale.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { GetLocaleQuery } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' @@ -19,15 +20,13 @@ const getLocale = gql(/* GraphQL */ ` } `) +type Result = ResultOf['localeGet'] + export function useLocale() { const { graphql } = useAppwrite() - const queryResult = useQuery< - GetLocaleQuery['localeGet'], - AppwriteException[], - GetLocaleQuery['localeGet'] - >({ - queryKey: ['appwrite', 'locale'], + const queryResult = useQuery({ + queryKey: Keys.locale().key(), queryFn: async () => { const { data, errors } = await graphql.query({ query: getLocale, diff --git a/src/locale/useLocaleCodes.ts b/src/locale/useLocaleCodes.ts index c99ad6d..bb6b076 100644 --- a/src/locale/useLocaleCodes.ts +++ b/src/locale/useLocaleCodes.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { ListLocaleCodesQuery } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' @@ -17,15 +18,13 @@ const listLocaleCodes = gql(/* GraphQL */ ` } `) +type Result = ResultOf['localeListCodes'] + export function useLocaleCodes() { const { graphql } = useAppwrite() - const queryResult = useQuery< - ListLocaleCodesQuery['localeListCodes'], - AppwriteException[], - ListLocaleCodesQuery['localeListCodes'] - >({ - queryKey: ['appwrite', 'locale', 'codes'], + const queryResult = useQuery({ + queryKey: Keys.locale().codes(), queryFn: async () => { const { data, errors } = await graphql.query({ query: listLocaleCodes, diff --git a/src/locale/useLocaleContinents.ts b/src/locale/useLocaleContinents.ts index a2eb515..5b77d06 100644 --- a/src/locale/useLocaleContinents.ts +++ b/src/locale/useLocaleContinents.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { ListContinentsQuery } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' @@ -17,15 +18,13 @@ const listContinents = gql(/* GraphQL */ ` } `) +type Result = ResultOf['localeListContinents'] + export function useLocaleContinents() { const { graphql } = useAppwrite() - const queryResult = useQuery< - ListContinentsQuery['localeListContinents'], - AppwriteException[], - ListContinentsQuery['localeListContinents'] - >({ - queryKey: ['appwrite', 'locale', 'continents'], + const queryResult = useQuery({ + queryKey: Keys.locale().continents(), queryFn: async () => { const { data, errors } = await graphql.query({ query: listContinents, diff --git a/src/locale/useLocaleCountries.ts b/src/locale/useLocaleCountries.ts index ea0e265..ffe88d9 100644 --- a/src/locale/useLocaleCountries.ts +++ b/src/locale/useLocaleCountries.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { ListCountriesQuery } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' @@ -17,15 +18,13 @@ const listCountries = gql(/* GraphQL */ ` } `) +type Result = ResultOf['localeListCountries'] + export function useLocaleCountries() { const { graphql } = useAppwrite() - const queryResult = useQuery< - ListCountriesQuery['localeListCountries'], - AppwriteException[], - ListCountriesQuery['localeListCountries'] - >({ - queryKey: ['appwrite', 'locale', 'countries'], + const queryResult = useQuery({ + queryKey: Keys.locale().countries(), queryFn: async () => { const { data, errors } = await graphql.query({ query: listCountries, diff --git a/src/locale/useLocaleCountriesEU.ts b/src/locale/useLocaleCountriesEU.ts index 72f6f93..09ce839 100644 --- a/src/locale/useLocaleCountriesEU.ts +++ b/src/locale/useLocaleCountriesEU.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { ListCountriesEuQuery } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' @@ -17,15 +18,13 @@ const listCountriesEU = gql(/* GraphQL */ ` } `) +type Result = ResultOf['localeListCountriesEU'] + export function useLocaleCountriesEU() { const { graphql } = useAppwrite() - const queryResult = useQuery< - ListCountriesEuQuery['localeListCountriesEU'], - AppwriteException[], - ListCountriesEuQuery['localeListCountriesEU'] - >({ - queryKey: ['appwrite', 'locale', 'countries-eu'], + const queryResult = useQuery({ + queryKey: Keys.locale().countriesEU(), queryFn: async () => { const { data, errors } = await graphql.query({ query: listCountriesEU, diff --git a/src/locale/useLocaleCountriesPhones.ts b/src/locale/useLocaleCountriesPhones.ts index 62a0be9..c5acc30 100644 --- a/src/locale/useLocaleCountriesPhones.ts +++ b/src/locale/useLocaleCountriesPhones.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { ListCountriesPhonesQuery } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' @@ -18,15 +19,13 @@ const listCountriesPhones = gql(/* GraphQL */ ` } `) +type Result = ResultOf['localeListCountriesPhones'] + export function useLocaleCountriesPhones() { const { graphql } = useAppwrite() - const queryResult = useQuery< - ListCountriesPhonesQuery['localeListCountriesPhones'], - AppwriteException[], - ListCountriesPhonesQuery['localeListCountriesPhones'] - >({ - queryKey: ['appwrite', 'locale', 'countries-phones'], + const queryResult = useQuery({ + queryKey: Keys.locale().countriesPhones(), queryFn: async () => { const { data, errors } = await graphql.query({ query: listCountriesPhones, diff --git a/src/locale/useLocaleCurrencies.ts b/src/locale/useLocaleCurrencies.ts index 0d4b1fc..a618d3a 100644 --- a/src/locale/useLocaleCurrencies.ts +++ b/src/locale/useLocaleCurrencies.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { ListCurrenciesQuery } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' @@ -22,15 +23,13 @@ const listCurrencies = gql(/* GraphQL */ ` } `) +type Result = ResultOf['localeListCurrencies'] + export function useLocaleCurrencies() { const { graphql } = useAppwrite() - const queryResult = useQuery< - ListCurrenciesQuery['localeListCurrencies'], - AppwriteException[], - ListCurrenciesQuery['localeListCurrencies'] - >({ - queryKey: ['appwrite', 'locale', 'currencies'], + const queryResult = useQuery({ + queryKey: Keys.locale().currencies(), queryFn: async () => { const { data, errors } = await graphql.query({ query: listCurrencies, diff --git a/src/locale/useLocaleLanguages.ts b/src/locale/useLocaleLanguages.ts index 673f24c..fbf9097 100644 --- a/src/locale/useLocaleLanguages.ts +++ b/src/locale/useLocaleLanguages.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { ListLanguagesQuery } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' @@ -18,15 +19,13 @@ const listLanguages = gql(/* GraphQL */ ` } `) +type Result = ResultOf['localeListLanguages'] + export function useLocaleLanguages() { const { graphql } = useAppwrite() - const queryResult = useQuery< - ListLanguagesQuery['localeListLanguages'], - AppwriteException[], - ListLanguagesQuery['localeListLanguages'] - >({ - queryKey: ['appwrite', 'locale', 'languages'], + const queryResult = useQuery({ + queryKey: Keys.locale().languages(), queryFn: async () => { const { data, errors } = await graphql.query({ query: listLanguages, diff --git a/src/messaging/index.ts b/src/messaging/index.ts new file mode 100644 index 0000000..1a96f0b --- /dev/null +++ b/src/messaging/index.ts @@ -0,0 +1,2 @@ +export { useCreateSubscriber } from './useCreateSubscriber' +export { useDeleteSubscriber } from './useDeleteSubscriber' diff --git a/src/messaging/useCreateSubscriber.ts b/src/messaging/useCreateSubscriber.ts new file mode 100644 index 0000000..b196fdc --- /dev/null +++ b/src/messaging/useCreateSubscriber.ts @@ -0,0 +1,51 @@ +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' + +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' +import { useAppwrite } from '../useAppwrite' +import { useMutation } from '../useMutation' + +export const createSubscriber = gql(/* GraphQL */ ` + mutation CreateSubscriber($subscriberId: String!, $topicId: String!, $targetId: String!) { + messagingCreateSubscriber(subscriberId: $subscriberId, topicId: $topicId, targetId: $targetId) { + _id + _createdAt + _updatedAt + targetId + userId + userName + topicId + providerType + } + } +`) + +type Variables = VariablesOf +type Result = ResultOf['messagingCreateSubscriber'] + +export function useCreateSubscriber() { + const { graphql } = useAppwrite() + + const mutationResult = useMutation({ + mutationKey: Keys.messaging().subscriber().create(), + mutationFn: async ({ subscriberId, topicId, targetId }) => { + const { data: mutationData, errors } = await graphql.mutation({ + query: createSubscriber, + variables: { + subscriberId, + topicId, + targetId, + }, + }) + + if (errors) { + throw errors + } + + return mutationData?.messagingCreateSubscriber + }, + }) + + return { ...mutationResult } +} diff --git a/src/messaging/useDeleteSubscriber.ts b/src/messaging/useDeleteSubscriber.ts new file mode 100644 index 0000000..21acbf5 --- /dev/null +++ b/src/messaging/useDeleteSubscriber.ts @@ -0,0 +1,43 @@ +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' + +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' +import { useAppwrite } from '../useAppwrite' +import { useMutation } from '../useMutation' + +export const deleteSubscriber = gql(/* GraphQL */ ` + mutation DeleteSubscriber($topicId: String!, $subscriberId: String!) { + messagingDeleteSubscriber(topicId: $topicId, subscriberId: $subscriberId) { + status + } + } +`) + +type Variables = VariablesOf +type Result = ResultOf['messagingDeleteSubscriber'] + +export function useDeleteSubscriber() { + const { graphql } = useAppwrite() + + const mutationResult = useMutation({ + mutationKey: Keys.messaging().subscriber().delete(), + mutationFn: async ({ topicId, subscriberId }) => { + const { data: mutationData, errors } = await graphql.mutation({ + query: deleteSubscriber, + variables: { + topicId, + subscriberId, + }, + }) + + if (errors) { + throw errors + } + + return mutationData?.messagingDeleteSubscriber ?? { status: '' } + }, + }) + + return { ...mutationResult } +} diff --git a/src/offline/createOfflineClient.ts b/src/offline/createOfflineClient.ts new file mode 100644 index 0000000..159809f --- /dev/null +++ b/src/offline/createOfflineClient.ts @@ -0,0 +1,117 @@ +import { createAsyncStoragePersister } from '@tanstack/query-async-storage-persister' +import type { AsyncStorage, Persister } from '@tanstack/query-persist-client-core' +import { persistQueryClient } from '@tanstack/query-persist-client-core' +import { onlineManager, QueryClient } from '@tanstack/react-query' + +import { hydrateMutationDefaults } from './mutations/registry' +import type { NetworkAdapter } from './types' +import type { AppwriteClient } from '../client' +import { createAppwriteClient } from '../client' + +export type OfflineClient = { + appwrite: AppwriteClient + queryClient: QueryClient + persister: Persister | undefined + /** + * Start persistence for non-React (imperative) usage. + * Restores the persisted cache, subscribes to future changes, + * and replays any paused mutations once the cache is restored. + * + * @returns `unsubscribe` to stop persisting and `restored` which resolves + * when the cache has been rehydrated from storage. + * @throws If no persister was configured via `storage` or `persister`. + */ + startPersistence: () => { unsubscribe: () => void; restored: Promise } +} + +const dehydrateOptions = { + shouldDehydrateMutation: (mutation: { state: { isPaused: boolean } }) => mutation.state.isPaused, + shouldDehydrateQuery: (query: { state: { status: string } }) => query.state.status === 'success', +} + +/** + * Creates an offline-capable Appwrite client with a pre-configured QueryClient. + * + * Persistence can be configured in three ways: + * - **Batteries-included**: pass `storage` (an `AsyncStorage` interface) and + * the factory builds a TanStack persister automatically. + * - **Bring your own**: pass a pre-built `persister` (TanStack `Persister` + * interface) — e.g. one backed by TinyBase, SQLite, etc. + * - **No persistence**: omit both — you still get offline mutation queuing + * and network state management. + * + * For React apps, pass `client.persister` to ``. + * For non-React (imperative) usage, call `client.startPersistence()`. + */ +export function createOfflineClient({ + endpoint, + projectId, + storage, + persister: externalPersister, + networkAdapter, + throttleTime = 1000, +}: { + endpoint: string + projectId: string + /** Batteries-included: provide a simple getItem/setItem/removeItem storage. */ + storage?: AsyncStorage + /** BYOP: provide a pre-built TanStack Persister. */ + persister?: Persister + networkAdapter: NetworkAdapter + /** Throttle time for network status changes to prevent rapid toggling. Default: 1000ms. */ + throttleTime?: number +}): OfflineClient { + if (storage && externalPersister) { + throw new Error('Provide either `storage` or `persister`, not both.') + } + + const appwrite = createAppwriteClient({ endpoint, projectId }) + + const queryClient = new QueryClient({ + defaultOptions: { + mutations: { networkMode: 'offlineFirst' }, + queries: { networkMode: 'offlineFirst', gcTime: 1000 * 60 * 60 * 24 }, + }, + }) + + hydrateMutationDefaults(queryClient, appwrite) + + const persister = + externalPersister ?? + (storage + ? createAsyncStoragePersister({ + storage, + key: 'appwrite-graphql-offline-cache', + throttleTime, + }) + : undefined) + + networkAdapter.listen((isOnline) => { + onlineManager.setOnline(isOnline) + }) + + return { + appwrite, + queryClient, + persister, + startPersistence() { + if (!persister) { + throw new Error( + 'No persister configured. Provide `storage` or `persister` to createOfflineClient.', + ) + } + + const [unsubscribe, restored] = persistQueryClient({ + queryClient, + persister, + dehydrateOptions, + }) + + const restoredWithResume = restored.then(() => { + void queryClient.resumePausedMutations() + }) + + return { unsubscribe, restored: restoredWithResume } + }, + } +} diff --git a/src/offline/index.ts b/src/offline/index.ts new file mode 100644 index 0000000..378542e --- /dev/null +++ b/src/offline/index.ts @@ -0,0 +1,7 @@ +export { createOfflineClient } from './createOfflineClient' +export type { OfflineClient } from './createOfflineClient' +export { hydrateMutationDefaults, mutationRegistry } from './mutations/registry' +export { webNetworkAdapter } from './network/web' +export type { NetworkAdapter } from './types' +export type { Persister } from '@tanstack/query-persist-client-core' +export type { AsyncStorage } from '@tanstack/query-persist-client-core' \ No newline at end of file diff --git a/src/offline/mutations/registry.ts b/src/offline/mutations/registry.ts new file mode 100644 index 0000000..adf38d0 --- /dev/null +++ b/src/offline/mutations/registry.ts @@ -0,0 +1,152 @@ +import type { QueryClient } from '@tanstack/react-query' +import type { TadaDocumentNode } from 'gql.tada' + +import { accountUpdateEmail } from '../../account/useUpdateEmail' +import { accountUpdateName } from '../../account/useUpdateName' +import { updatePassword } from '../../account/useUpdatePassword' +import { accountUpdatePhone } from '../../account/useUpdatePhone' +import { accountUpdatePrefs } from '../../account/useUpdatePrefs' +import type { AppwriteClient } from '../../client' +import { createDocument } from '../../databases/useCreateDocument' +import { decrementDocumentAttribute } from '../../databases/useDecrementAttribute' +import { deleteDocument } from '../../databases/useDeleteDocument' +import { incrementDocumentAttribute } from '../../databases/useIncrementAttribute' +import { updateDocument } from '../../databases/useUpdateDocument' +import { upsertDocument } from '../../databases/useUpsertDocument' +import { createSubscriber } from '../../messaging/useCreateSubscriber' +import { deleteSubscriber } from '../../messaging/useDeleteSubscriber' +import { Keys } from '../../query/Keys' +import { createMembership } from '../../teams/useCreateMembership' +import { createTeam } from '../../teams/useCreateTeam' +import { deleteMembership } from '../../teams/useDeleteMembership' +import { deleteTeam } from '../../teams/useDeleteTeam' +import { updateMembership } from '../../teams/useUpdateMembership' +import { updateTeamName } from '../../teams/useUpdateTeamName' +import { updateTeamPrefs } from '../../teams/useUpdateTeamPrefs' + +type Vars = Record +type MutationFn = (client: AppwriteClient, variables: Vars) => Promise + +/** + * Creates a mutationFn that executes a GraphQL mutation and returns the + * first field from the response data. + */ +function gqlMutation( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + query: TadaDocumentNode, + resultKey: string, + options?: { serializeData?: boolean }, +): MutationFn { + return async (client, variables) => { + const vars = options?.serializeData + ? { ...variables, data: JSON.stringify(variables.data) } + : variables + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const { data, errors } = await client.graphql.mutation({ query, variables: vars as any }) + if (errors) throw errors + return (data as Vars)[resultKey] + } +} + +type MutationEntry = { + mutationKey: readonly string[] + mutationFn: MutationFn +} + +export const mutationRegistry: MutationEntry[] = [ + { + mutationKey: Keys.databases().collections().documents().create(), + mutationFn: gqlMutation(createDocument, 'databasesCreateDocument', { serializeData: true }), + }, + { + mutationKey: Keys.databases().collections().documents().update(), + mutationFn: gqlMutation(updateDocument, 'databasesUpdateDocument', { serializeData: true }), + }, + { + mutationKey: Keys.databases().collections().documents().delete(), + mutationFn: gqlMutation(deleteDocument, 'databasesDeleteDocument'), + }, + { + mutationKey: Keys.databases().collections().documents().upsert(), + mutationFn: gqlMutation(upsertDocument, 'databasesUpsertDocument', { serializeData: true }), + }, + + { + mutationKey: [...Keys.databases().transactions().operations().key(), 'incrementAttribute'], + mutationFn: gqlMutation(incrementDocumentAttribute, 'databasesIncrementDocumentAttribute'), + }, + + { + mutationKey: [...Keys.databases().transactions().operations().key(), 'decrementAttribute'], + mutationFn: gqlMutation(decrementDocumentAttribute, 'databasesDecrementDocumentAttribute'), + }, + + { + mutationKey: Keys.account().prefs().update(), + mutationFn: gqlMutation(accountUpdatePrefs, 'accountUpdatePrefs'), + }, + { + mutationKey: Keys.account().name().update(), + mutationFn: gqlMutation(accountUpdateName, 'accountUpdateName'), + }, + { + mutationKey: Keys.account().email().update(), + mutationFn: gqlMutation(accountUpdateEmail, 'accountUpdateEmail'), + }, + { + mutationKey: Keys.account().password().update(), + mutationFn: gqlMutation(updatePassword, 'accountUpdatePassword'), + }, + { + mutationKey: Keys.account().phone().update(), + mutationFn: gqlMutation(accountUpdatePhone, 'accountUpdatePhone'), + }, + + { mutationKey: Keys.teams().create(), mutationFn: gqlMutation(createTeam, 'teamsCreate') }, + { mutationKey: Keys.teams().delete(), mutationFn: gqlMutation(deleteTeam, 'teamsDelete') }, + { + mutationKey: Keys.teams().teamName().update(), + mutationFn: gqlMutation(updateTeamName, 'teamsUpdateName'), + }, + { + mutationKey: Keys.teams().teamPrefs().update(), + mutationFn: gqlMutation(updateTeamPrefs, 'teamsUpdatePrefs'), + }, + { + mutationKey: Keys.teams().memberships().create(), + mutationFn: gqlMutation(createMembership, 'teamsCreateMembership'), + }, + { + mutationKey: Keys.teams().memberships().delete(), + mutationFn: gqlMutation(deleteMembership, 'teamsDeleteMembership'), + }, + { + mutationKey: Keys.teams().memberships().update(), + mutationFn: gqlMutation(updateMembership, 'teamsUpdateMembership'), + }, + + { + mutationKey: Keys.messaging().subscriber().create(), + mutationFn: gqlMutation(createSubscriber, 'messagingCreateSubscriber'), + }, + { + mutationKey: Keys.messaging().subscriber().delete(), + mutationFn: gqlMutation(deleteSubscriber, 'messagingDeleteSubscriber'), + }, +] + +/** + * Registers all mutation defaults with the QueryClient so that + * dehydrated/persisted mutations can be replayed on app restart. + * + * Call once during app initialization, before rehydrating the persisted + * mutation cache. + */ +export function hydrateMutationDefaults(queryClient: QueryClient, client: AppwriteClient) { + for (const entry of mutationRegistry) { + queryClient.setMutationDefaults(entry.mutationKey, { + mutationFn: (variables: Vars) => entry.mutationFn(client, variables), + }) + } +} diff --git a/src/offline/network/native.ts b/src/offline/network/native.ts new file mode 100644 index 0000000..8dedeed --- /dev/null +++ b/src/offline/network/native.ts @@ -0,0 +1,24 @@ +import NetInfo from '@react-native-community/netinfo' + +import type { NetworkAdapter } from '../types' + +export function reactNativeNetworkAdapter(): NetworkAdapter { + return { + listen: (callback) => { + const handleConnectivityChange = (state: { isConnected: boolean }) => { + callback(state.isConnected) + } + + const unsubscribe = NetInfo.addEventListener(handleConnectivityChange) + + // Initial status + void NetInfo.fetch().then((state: { isConnected: boolean }) => { + callback(state.isConnected) + }) + + return () => { + unsubscribe() + } + }, + } +} diff --git a/src/offline/network/web.ts b/src/offline/network/web.ts new file mode 100644 index 0000000..259a990 --- /dev/null +++ b/src/offline/network/web.ts @@ -0,0 +1,22 @@ +import type { NetworkAdapter } from '../types' + +export function webNetworkAdapter(): NetworkAdapter { + return { + listen: (callback) => { + const updateOnlineStatus = () => { + callback(navigator.onLine) + } + + window.addEventListener('online', updateOnlineStatus) + window.addEventListener('offline', updateOnlineStatus) + + // Initial status + callback(navigator.onLine) + + return () => { + window.removeEventListener('online', updateOnlineStatus) + window.removeEventListener('offline', updateOnlineStatus) + } + }, + } +} diff --git a/src/offline/types.ts b/src/offline/types.ts new file mode 100644 index 0000000..cc3b27e --- /dev/null +++ b/src/offline/types.ts @@ -0,0 +1,3 @@ +export type NetworkAdapter = { + listen: (callback: (isOnline: boolean) => void) => () => void +} diff --git a/src/query/Keys.ts b/src/query/Keys.ts new file mode 100644 index 0000000..59509c2 --- /dev/null +++ b/src/query/Keys.ts @@ -0,0 +1,419 @@ +interface Account { + acc?: string +} + +interface Database { + db?: string +} + +interface Collection { + col?: string +} + +interface Document { + doc?: string +} + +interface TablesDB { + tdb?: string +} + +interface Table { + tbl?: string +} + +interface Row { + row?: string +} + +interface Bucket { + bucket?: string +} + +interface FileResource { + file?: string +} + +interface Actionable { + actionable?: string +} + +interface Execution { + exec?: string +} + +interface Func { + func?: string +} + +interface Team { + team?: string +} + +interface Membership { + membership?: string +} + +interface Locale { + locale?: string +} + +interface Messaging { + messaging?: string +} + +interface Transaction { + transaction?: string +} + +export class Keys { + private keys: string[] = ['appwrite'] + private _type!: T + + private constructor() {} + + private static create(...segments: string[]) { + const k = new Keys() + k.keys.push(...segments) + return k + } + + static account() { + return Keys.create('account') + } + + static databases() { + return Keys.create('databases') + } + + static database(id: string) { + return Keys.create('databases', id) + } + + static tablesDB(id: string) { + return Keys.create('tablesDB', id) + } + + static buckets() { + return Keys.create('buckets') + } + + static bucket(id: string) { + return Keys.create('buckets', id) + } + + static functions() { + return Keys.create('functions') + } + + static function(id: string) { + return Keys.create('functions', id) + } + + static teams() { + return Keys.create('teams') + } + + static team(id: string) { + return Keys.create('teams', id) + } + + static locale() { + return Keys.create('locale') + } + + static messaging() { + return Keys.create('messaging') + } + + jwt(this: Keys) { + this.keys.push('jwt') + return this as unknown as Keys + } + + anonymous(this: Keys) { + this.keys.push('anonymous') + return this as unknown as Keys + } + + emailToken(this: Keys) { + this.keys.push('emailToken') + return this as unknown as Keys + } + + emailVerification(this: Keys) { + this.keys.push('emailVerification') + return this as unknown as Keys + } + + magicUrl(this: Keys) { + this.keys.push('magicUrl') + return this as unknown as Keys + } + + mfaAuthenticator(this: Keys) { + this.keys.push('mfaAuthenticator') + return this as unknown as Keys + } + + mfaChallenge(this: Keys) { + this.keys.push('mfaChallenge') + return this as unknown as Keys + } + + mfaCodes(this: Keys) { + this.keys.push('mfaCodes') + return this as unknown as Keys + } + + oauth2Token(this: Keys) { + this.keys.push('oauth2Token') + return this as unknown as Keys + } + + phoneToken(this: Keys) { + this.keys.push('phoneToken') + return this as unknown as Keys + } + + phoneVerification(this: Keys) { + this.keys.push('phoneVerification') + return this as unknown as Keys + } + + pushTarget(this: Keys) { + this.keys.push('pushTarget') + return this as unknown as Keys + } + + identity(this: Keys) { + this.keys.push('identity') + return this as unknown as Keys + } + + prefs(this: Keys) { + this.keys.push('prefs') + return this as unknown as Keys + } + + login(this: Keys) { + this.keys.push('login') + return this as unknown as Keys + } + + signUp(this: Keys) { + this.keys.push('signUp') + return this as unknown as Keys + } + + name(this: Keys) { + this.keys.push('name') + return this as unknown as Keys + } + + email(this: Keys) { + this.keys.push('email') + return this as unknown as Keys + } + + phone(this: Keys) { + this.keys.push('phone') + return this as unknown as Keys + } + + password(this: Keys) { + this.keys.push('password') + return this as unknown as Keys + } + + recovery(this: Keys) { + this.keys.push('recovery') + return this as unknown as Keys + } + + mfa(this: Keys) { + this.keys.push('mfa') + return this as unknown as Keys + } + + status(this: Keys) { + this.keys.push('status') + return this as unknown as Keys + } + + logs(this: Keys) { + this.keys.push('logs') + return this as unknown as Keys + } + + verification(this: Keys) { + this.keys.push('verification') + return this as unknown as Keys + } + + session(this: Keys, id?: string) { + this.keys.push('sessions') + if (id) this.keys.push(id) + return this as unknown as Keys + } + + sessions(this: Keys) { + return [...this.keys, 'sessions'] as const + } + + identities(this: Keys) { + return [...this.keys, 'identities'] as const + } + + mfaFactors(this: Keys) { + return [...this.keys, 'mfaFactors'] as const + } + + collections(this: Keys) { + this.keys.push('collections') + return this as unknown as Keys + } + + collection(this: Keys, id: string) { + this.keys.push('collections', id) + return this as unknown as Keys + } + + transactions(this: Keys) { + this.keys.push('transactions') + return this as unknown as Keys + } + + transaction(this: Keys, id: string) { + this.keys.push('transactions', id) + return this as unknown as Keys + } + + documents(this: Keys) { + this.keys.push('documents') + return this as unknown as Keys + } + + document(this: Keys, id: string) { + this.keys.push('documents', id) + return this as unknown as Keys + } + + operations(this: Keys) { + this.keys.push('operations') + return this as unknown as Keys + } + + table(this: Keys, id: string) { + this.keys.push('table', id) + return this as unknown as Keys + } + + rows(this: Keys
) { + this.keys.push('rows') + return this as unknown as Keys + } + + row(this: Keys
, id: string) { + this.keys.push('row', id) + return this as unknown as Keys + } + + files(this: Keys) { + this.keys.push('files') + return this as unknown as Keys + } + + file(this: Keys, id: string) { + this.keys.push('files', id) + return this as unknown as Keys + } + + executions(this: Keys) { + this.keys.push('executions') + return this as unknown as Keys + } + + execution(this: Keys, id: string) { + this.keys.push('executions', id) + return this as unknown as Keys + } + + teamName(this: Keys) { + this.keys.push('name') + return this as unknown as Keys + } + + teamPrefs(this: Keys) { + this.keys.push('prefs') + return this as unknown as Keys + } + + memberships(this: Keys) { + this.keys.push('memberships') + return this as unknown as Keys + } + + membership(this: Keys, id: string) { + this.keys.push('memberships', id) + return this as unknown as Keys + } + + membershipStatus(this: Keys) { + this.keys.push('membershipStatus') + return this as unknown as Keys + } + + continents(this: Keys) { + return [...this.keys, 'continents'] as const + } + + countries(this: Keys) { + return [...this.keys, 'countries'] as const + } + + countriesEU(this: Keys) { + return [...this.keys, 'countriesEU'] as const + } + + countriesPhones(this: Keys) { + return [...this.keys, 'countriesPhones'] as const + } + + currencies(this: Keys) { + return [...this.keys, 'currencies'] as const + } + + languages(this: Keys) { + return [...this.keys, 'languages'] as const + } + + codes(this: Keys) { + return [...this.keys, 'codes'] as const + } + + subscriber(this: Keys) { + this.keys.push('subscriber') + return this as unknown as Keys + } + + create() { + return [...this.keys, 'create'] as const + } + + upsert() { + return [...this.keys, 'upsert'] as const + } + + update() { + return [...this.keys, 'update'] as const + } + + delete() { + return [...this.keys, 'delete'] as const + } + + key() { + return [...this.keys] as const + } +} diff --git a/src/query/QueryBuilder.ts b/src/query/QueryBuilder.ts new file mode 100644 index 0000000..bd428be --- /dev/null +++ b/src/query/QueryBuilder.ts @@ -0,0 +1,321 @@ +import type { QueryTypes } from 'appwrite' +import { Query } from 'appwrite' + +type FieldValue = T[K] + +type ArrayElement = T extends (infer E)[] ? E : never + +type ContainsValue = T[K] extends unknown[] + ? ArrayElement | ArrayElement[] + : T[K] extends string + ? string + : T[K] | T[K][] + +export class QueryBuilder> { + private queries: string[] = [] + + equal(field: K, value: FieldValue | FieldValue[]): this { + this.queries.push(Query.equal(field, value as QueryTypes)) + return this + } + + notEqual( + field: K, + value: FieldValue | FieldValue[], + ): this { + this.queries.push(Query.notEqual(field, value as QueryTypes)) + return this + } + + regex(field: K, pattern: string): this { + this.queries.push(Query.regex(field, pattern)) + return this + } + + lessThan(field: K, value: FieldValue): this { + this.queries.push(Query.lessThan(field, value as QueryTypes)) + return this + } + + lessThanEqual(field: K, value: FieldValue): this { + this.queries.push(Query.lessThanEqual(field, value as QueryTypes)) + return this + } + + greaterThan(field: K, value: FieldValue): this { + this.queries.push(Query.greaterThan(field, value as QueryTypes)) + return this + } + + greaterThanEqual(field: K, value: FieldValue): this { + this.queries.push(Query.greaterThanEqual(field, value as QueryTypes)) + return this + } + + isNull(field: K): this { + this.queries.push(Query.isNull(field)) + return this + } + + isNotNull(field: K): this { + this.queries.push(Query.isNotNull(field)) + return this + } + + exists(fields: K[]): this { + this.queries.push(Query.exists(fields)) + return this + } + + notExists(fields: K[]): this { + this.queries.push(Query.notExists(fields)) + return this + } + + between( + field: K, + start: string | number | bigint, + end: string | number | bigint, + ): this { + this.queries.push(Query.between(field, start, end)) + return this + } + + startsWith(field: K, prefix: string): this { + this.queries.push(Query.startsWith(field, prefix)) + return this + } + + endsWith(field: K, suffix: string): this { + this.queries.push(Query.endsWith(field, suffix)) + return this + } + + select(fields: K[]): this { + this.queries.push(Query.select(fields)) + return this + } + + search(field: K, term: string): this { + this.queries.push(Query.search(field, term)) + return this + } + + orderAsc(field: K): this { + this.queries.push(Query.orderAsc(field)) + return this + } + + orderDesc(field: K): this { + this.queries.push(Query.orderDesc(field)) + return this + } + + orderRandom(): this { + this.queries.push(Query.orderRandom()) + return this + } + + cursorAfter(id: string): this { + this.queries.push(Query.cursorAfter(id)) + return this + } + + cursorBefore(id: string): this { + this.queries.push(Query.cursorBefore(id)) + return this + } + + limit(count: number): this { + this.queries.push(Query.limit(count)) + return this + } + + offset(count: number): this { + this.queries.push(Query.offset(count)) + return this + } + + contains(field: K, value: ContainsValue): this { + this.queries.push(Query.contains(field, value as string | any[])) + return this + } + + containsAny(field: K, values: ContainsValue[]): this { + this.queries.push(Query.containsAny(field, values as any[])) + return this + } + + containsAll(field: K, values: ContainsValue[]): this { + this.queries.push(Query.containsAll(field, values as any[])) + return this + } + + notContains(field: K, value: ContainsValue): this { + this.queries.push(Query.notContains(field, value as string | any[])) + return this + } + + notSearch(field: K, term: string): this { + this.queries.push(Query.notSearch(field, term)) + return this + } + + notBetween( + field: K, + start: string | number | bigint, + end: string | number | bigint, + ): this { + this.queries.push(Query.notBetween(field, start, end)) + return this + } + + notStartsWith(field: K, prefix: string): this { + this.queries.push(Query.notStartsWith(field, prefix)) + return this + } + + notEndsWith(field: K, suffix: string): this { + this.queries.push(Query.notEndsWith(field, suffix)) + return this + } + + createdBefore(date: string): this { + this.queries.push(Query.createdBefore(date)) + return this + } + + createdAfter(date: string): this { + this.queries.push(Query.createdAfter(date)) + return this + } + + createdBetween(start: string, end: string): this { + this.queries.push(Query.createdBetween(start, end)) + return this + } + + updatedBefore(date: string): this { + this.queries.push(Query.updatedBefore(date)) + return this + } + + updatedAfter(date: string): this { + this.queries.push(Query.updatedAfter(date)) + return this + } + + updatedBetween(start: string, end: string): this { + this.queries.push(Query.updatedBetween(start, end)) + return this + } + + or(...queries: QueryBuilder[]): this { + const orQueries = queries.flatMap((q) => q.queries) + this.queries.push(Query.or(orQueries)) + return this + } + + and(...queries: QueryBuilder[]): this { + const andQueries = queries.flatMap((q) => q.queries) + this.queries.push(Query.and(andQueries)) + return this + } + + elemMatch(field: K, query: QueryBuilder): this { + this.queries.push(Query.elemMatch(field, query.queries)) + return this + } + + distanceEqual( + field: K, + latitude: number, + longitude: number, + distance: number, + meters: boolean = true, + ): this { + this.queries.push(Query.distanceEqual(field, [latitude, longitude], distance, meters)) + return this + } + + distanceNotEqual( + field: K, + latitude: number, + longitude: number, + distance: number, + meters: boolean = true, + ): this { + this.queries.push(Query.distanceNotEqual(field, [latitude, longitude], distance, meters)) + return this + } + + distanceGreaterThan( + field: K, + latitude: number, + longitude: number, + distance: number, + meters: boolean = true, + ): this { + this.queries.push(Query.distanceGreaterThan(field, [latitude, longitude], distance, meters)) + return this + } + + distanceLessThan( + field: K, + latitude: number, + longitude: number, + distance: number, + meters: boolean = true, + ): this { + this.queries.push(Query.distanceLessThan(field, [latitude, longitude], distance, meters)) + return this + } + + intersects(field: K, points: [number, number][]): this { + this.queries.push(Query.intersects(field, points)) + return this + } + + notIntersects(field: K, points: [number, number][]): this { + this.queries.push(Query.notIntersects(field, points)) + return this + } + + crosses(field: K, points: [number, number][]): this { + this.queries.push(Query.crosses(field, points)) + return this + } + + notCrosses(field: K, points: [number, number][]): this { + this.queries.push(Query.notCrosses(field, points)) + return this + } + + overlaps(field: K, points: [number, number][]): this { + this.queries.push(Query.overlaps(field, points)) + return this + } + + notOverlaps(field: K, points: [number, number][]): this { + this.queries.push(Query.notOverlaps(field, points)) + return this + } + + touches(field: K, points: [number, number][]): this { + this.queries.push(Query.touches(field, points)) + return this + } + + notTouches(field: K, points: [number, number][]): this { + this.queries.push(Query.notTouches(field, points)) + return this + } + + build() { + return [...this.queries] + } +} + +export function q>(): QueryBuilder { + return new QueryBuilder() +} diff --git a/src/schema.graphql b/src/schema.graphql index 5263926..119cfbf 100644 --- a/src/schema.graphql +++ b/src/schema.graphql @@ -1,6 +1,6 @@ scalar Json -scalar Date scalar Assoc +scalar InputFile schema { query: Query @@ -13,24 +13,32 @@ type Query { accountGetPrefs: Preferences accountGetMfaRecoveryCodes: MfaRecoveryCodes accountGetSession(sessionId: String!): Session - accountListIdentities: IdentityList - accountListLogs(queries: [String!]): LogsList + accountListIdentities(queries: String, total: Boolean): IdentityList + accountListLogs(queries: [String], total: Boolean): LogList accountListMfaFactors: MfaFactors accountListSessions: SessionList # Databases - databasesGetDocument(databaseId: String!, collectionId: String!, documentId: String!): Document + databasesGetDocument( + databaseId: String! + collectionId: String! + documentId: String! + queries: [String] + transactionId: String + ): Document databasesGetTransaction(transactionId: String!): Transaction databasesListDocuments( databaseId: String! collectionId: String! - queries: [String!] + queries: [String] + transactionId: String + total: Boolean ): DocumentList databasesListTransactions(queries: String): TransactionList # Functions functionsGetExecution(functionId: String!, executionId: String!): Execution - functionsListExecutions(functionId: String!, queries: [String!]): ExecutionList + functionsListExecutions(functionId: String!, queries: [String], total: Boolean): ExecutionList # Locale localeGet: Locale @@ -44,14 +52,37 @@ type Query { # Storage storageGetFile(bucketId: String!, fileId: String!): File - storageListFiles(bucketId: String!, queries: [String!], search: String): FileList + storageGetFileDownload(bucketId: String!, fileId: String!, token: String): None + storageGetFilePreview( + bucketId: String! + fileId: String! + width: Int + height: Int + gravity: String + quality: Int + borderWidth: Int + borderColor: String + borderRadius: Int + opacity: Float + rotation: Int + background: String + output: String + token: String + ): None + storageGetFileView(bucketId: String!, fileId: String!, token: String): None + storageListFiles(bucketId: String!, queries: [String], search: String, total: Boolean): FileList # Teams teamsGet(teamId: String!): Team teamsGetMembership(teamId: String!, membershipId: String!): Membership teamsGetPrefs(teamId: String!): Preferences - teamsList(queries: [String!], search: String): TeamList - teamsListMemberships(teamId: String!, queries: [String!], search: String): MembershipList + teamsList(queries: [String], search: String, total: Boolean): TeamList + teamsListMemberships( + teamId: String! + queries: [String] + search: String + total: Boolean + ): MembershipList } type Mutation { @@ -59,33 +90,30 @@ type Mutation { accountCreate(userId: String!, email: String!, password: String!, name: String): User accountCreateAnonymousSession: Session accountCreateEmailPasswordSession(email: String!, password: String!): Session - accountCreateJWT: JWT + accountCreateJWT: Jwt accountCreateEmailToken(userId: String!, email: String!, phrase: Boolean): Token - accountCreateMagicURLSession(userId: String!, email: String!, url: String): Token accountCreateMagicURLToken(userId: String!, email: String!, url: String, phrase: Boolean): Token accountCreateMfaAuthenticator(type: String!): MfaType - accountCreateMfaChallenge(factor: String!): MFAChallenge + accountCreateMfaChallenge(factor: String!): MfaChallenge accountCreateMfaRecoveryCodes: MfaRecoveryCodes - accountCreatePhoneSession(userId: String!, phone: String!): Token accountCreatePhoneToken(userId: String!, phone: String!): Token accountCreatePhoneVerification: Token accountCreateRecovery(email: String!, url: String!): Token accountCreateSession(userId: String!, secret: String!): Session accountCreateVerification(url: String!): Token accountCreateEmailVerification(url: String!): Token - accountDelete: None - accountDeleteIdentity(identityId: String!): Status + accountDeleteIdentity(identityId: String!): None accountDeleteMfaAuthenticator(type: String!): None - accountDeleteSession(sessionId: String!): Status - accountDeleteSessions: Status + accountDeleteSession(sessionId: String!): None + accountDeleteSessions: None accountUpdateEmail(email: String!, password: String!): User accountUpdateMagicURLSession(userId: String!, secret: String!): Session accountUpdateMFA(mfa: Boolean!): User accountUpdateMfaAuthenticator(type: String!, otp: String!): User - accountUpdateMfaChallenge(challengeId: String!, otp: String!): Status + accountUpdateMfaChallenge(challengeId: String!, otp: String!): Session accountUpdateMfaRecoveryCodes: MfaRecoveryCodes accountUpdateName(name: String!): User - accountUpdatePassword(password: String!, oldPassword: String!): User + accountUpdatePassword(password: String!, oldPassword: String): User accountUpdatePhone(phone: String!, password: String!): User accountUpdatePhoneSession(userId: String!, secret: String!): Session accountUpdatePhoneVerification(userId: String!, secret: String!): Token @@ -96,53 +124,40 @@ type Mutation { accountUpdateEmailVerification(userId: String!, secret: String!): Token accountCreatePushTarget(targetId: String!, identifier: String!, providerId: String): Target accountUpdatePushTarget(targetId: String!, identifier: String!): Target - accountDeletePushTarget(targetId: String!): Status + accountDeletePushTarget(targetId: String!): None accountUpdateStatus: User # Databases databasesCreateDocument( databaseId: String! - collectionId: String! documentId: String! + collectionId: String! data: Json! - permissions: [String!] + permissions: [String] + transactionId: String ): Document - databasesCreateDocuments( + databasesDeleteDocument( databaseId: String! collectionId: String! - documents: [Json!]! - ): DocumentList - databasesDeleteDocument(databaseId: String!, collectionId: String!, documentId: String!): Status - databasesDeleteDocuments( - databaseId: String! - collectionId: String! - queries: [String!] - ): DocumentList + documentId: String! + transactionId: String + ): None databasesUpdateDocument( databaseId: String! collectionId: String! documentId: String! data: Json - permissions: [String!] + permissions: [String] + transactionId: String ): Document - databasesUpdateDocuments( - databaseId: String! - collectionId: String! - data: Json - queries: [String!] - ): DocumentList databasesUpsertDocument( databaseId: String! collectionId: String! documentId: String! data: Json! - permissions: [String!] + permissions: [String] + transactionId: String ): Document - databasesUpsertDocuments( - databaseId: String! - collectionId: String! - documents: [Json!]! - ): DocumentList databasesIncrementDocumentAttribute( databaseId: String! collectionId: String! @@ -150,6 +165,7 @@ type Mutation { attribute: String! value: Int max: Int + transactionId: String ): Document databasesDecrementDocumentAttribute( databaseId: String! @@ -158,10 +174,15 @@ type Mutation { attribute: String! value: Int min: Int + transactionId: String ): Document databasesCreateTransaction(ttl: Int): Transaction - databasesCreateOperations(transactionId: String!, operations: [String!]): Transaction - databasesUpdateTransaction(transactionId: String!, commit: Boolean, rollback: Boolean): Transaction + databasesCreateOperations(transactionId: String!, operations: [String]): Transaction + databasesUpdateTransaction( + transactionId: String! + commit: Boolean + rollback: Boolean + ): Transaction databasesDeleteTransaction(transactionId: String!): None # Functions @@ -171,22 +192,32 @@ type Mutation { async: Boolean path: String method: String - headers: Json + headers: String + scheduledAt: String ): Execution + # Messaging + messagingCreateSubscriber(subscriberId: String!, topicId: String!, targetId: String!): Subscriber + messagingDeleteSubscriber(topicId: String!, subscriberId: String!): None + # Storage - storageCreateFile(bucketId: String!, fileId: String!, file: String!, permissions: [String!]): File - storageUpdateFile(bucketId: String!, fileId: String!, name: String, permissions: [String!]): File + storageCreateFile( + bucketId: String! + fileId: String! + file: InputFile! + permissions: [String] + ): File + storageUpdateFile(bucketId: String!, fileId: String!, name: String, permissions: [String]): File storageDeleteFile(bucketId: String!, fileId: String!): None # Teams - teamsCreate(teamId: String!, name: String!, roles: [String!]): Team + teamsCreate(teamId: String!, name: String!, roles: [String]): Team teamsCreateMembership( teamId: String! - roles: [String!]! email: String userId: String phone: String + roles: [String!]! url: String name: String ): Membership @@ -205,11 +236,11 @@ type Mutation { type User { _id: String - _createdAt: Date - _updatedAt: Date + _createdAt: String + _updatedAt: String name: String registration: String - status: String + status: Boolean labels: [String] email: String phone: String @@ -219,13 +250,12 @@ type User { accessedAt: String prefs: Preferences targets: [Target] - accessedAt: String } type Target { _id: String - _createdAt: Date - _updatedAt: Date + _createdAt: String + _updatedAt: String name: String userId: String providerId: String @@ -240,13 +270,14 @@ type Preferences { type Session { _id: String - _createdAt: Date + _createdAt: String + _updatedAt: String userId: String - expire: Date + expire: String provider: String providerUid: String providerAccessToken: String - providerAccessTokenExpiry: Date + providerAccessTokenExpiry: String providerRefreshToken: String ip: String osCode: String @@ -266,7 +297,7 @@ type Session { current: Boolean factors: [String] secret: String - mfaUpdatedAt: Date + mfaUpdatedAt: String } type SessionList { @@ -294,7 +325,7 @@ type Token { _createdAt: String userId: String secret: String - expire: Date + expire: String phrase: String } @@ -307,32 +338,39 @@ type Execution { _id: String _createdAt: String _updatedAt: String + _permissions: [String] functionId: String + deploymentId: String trigger: String status: String requestMethod: String requestPath: String + requestHeaders: [Headers] responseStatusCode: Int responseBody: String + responseHeaders: [Headers] + logs: String errors: String duration: Float + scheduledAt: String } -type Status { - status: Boolean +type Headers { + name: String + value: String } type None { - status: Boolean + status: String } -type JWT { +type Jwt { jwt: String } type IdentityList { - total: Int! - identities: [Identity!] + total: Int + identities: [Identity] } type Identity { @@ -348,15 +386,12 @@ type Identity { providerRefreshToken: String } -type LogsList { - total: Int! - logs: [Log!] +type LogList { + total: Int + logs: [Log] } type Log { - _id: String - _createdAt: String - _updatedAt: String event: String userId: String userEmail: String @@ -385,21 +420,34 @@ type MfaType { uri: String } -type MFAChallenge { +type MfaChallenge { _id: String - _createdAt: Date + _createdAt: String userId: String - expire: Date + expire: String } type MfaFactors { totp: Boolean phone: Boolean email: Boolean + recoveryCode: Boolean } type MfaRecoveryCodes { - recoveryCodes: [String!]! + recoveryCodes: [String] +} + +type Subscriber { + _id: String + _createdAt: String + _updatedAt: String + targetId: String + target: Target + userId: String + userName: String + topicId: String + providerType: String } type Locale { diff --git a/src/states/appwrite.ts b/src/states/appwrite.ts deleted file mode 100644 index fe7ae08..0000000 --- a/src/states/appwrite.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { ResultOf, TypedDocumentNode } from '@graphql-typed-document-node/core' -import { print } from 'graphql' -import { atom } from 'jotai' - -import { Account, Avatars, Client, Graphql, Realtime, Storage } from '../types' - -type Variables = Record - -type AtomProps = { - account: Account | null - avatars: Avatars | null - realtime: Realtime - storage: Storage | null - graphql: { - client: Graphql['client'] - query: ({ - query, - variables, - }: { - query: TypedDocumentNode - variables?: V - }) => Promise<{ data: ResultOf; errors: unknown[] }> - mutation: ({ - query, - variables, - }: { - query: TypedDocumentNode - variables?: V - }) => Promise<{ data: ResultOf; errors: unknown[] }> - } -} - -const endpoint = - process.env.APPWRITE_ENDPOINT ?? - process.env.EXPO_PUBLIC_APPWRITE_URL ?? - process.env.NEXT_PUBLIC_APPWRITE_URL ?? - 'http://localhost/v1' - -const projectId = - process.env.APPWRITE_PROJECT_ID ?? - process.env.EXPO_PUBLIC_APPWRITE_PROJECT_ID ?? - process.env.NEXT_PUBLIC_APPWRITE_PROJECT_ID ?? - '[PROJECT_ID]' - -const defaultAppwriteClient = new Client() -defaultAppwriteClient.setEndpoint(endpoint).setProject(projectId) - -const graphqlObject = (graphqlAppwrite: Graphql) => ({ - client: graphqlAppwrite.client, - query: async ({ - query, - variables, - }: { - query: TypedDocumentNode - variables?: V - }) => { - const { data, errors } = (await graphqlAppwrite.query({ - query: { query: print(query), variables }, - })) as { data: ResultOf; errors: unknown[] } - return { data, errors } - }, - mutation: async ({ - query, - variables, - }: { - query: TypedDocumentNode - variables?: V - }) => { - const { data, errors } = (await graphqlAppwrite.mutation({ - query: { query: print(query), variables }, - })) as { data: ResultOf; errors: unknown[] } - return { data, errors } - }, -}) - -const appwriteModelsAtom = atom({ - account: new Account(defaultAppwriteClient), - avatars: new Avatars(defaultAppwriteClient), - realtime: new Realtime(defaultAppwriteClient), - storage: new Storage(defaultAppwriteClient), - graphql: graphqlObject(new Graphql(defaultAppwriteClient)), -}) - -export const appwriteAtom = atom( - (get) => get(appwriteModelsAtom), - (_, set, { endpoint, projectId }: { endpoint: string; projectId: string }) => { - const client = new Client() - client.setEndpoint(endpoint).setProject(projectId) - - const account = new Account(client) - const avatars = new Avatars(client) - const realtime = new Realtime(client) - const storage = new Storage(client) - const graphqlAppwrite = new Graphql(client) - - set(appwriteModelsAtom, { - account, - avatars, - realtime, - storage, - graphql: graphqlObject(graphqlAppwrite), - }) - }, -) diff --git a/src/states/query.ts b/src/states/query.ts deleted file mode 100644 index 4c4d404..0000000 --- a/src/states/query.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { QueryClient } from '@tanstack/react-query' -import { atom } from 'jotai' - -const queryClient = new QueryClient() - -export const QueryAtom = atom(queryClient) diff --git a/src/storage/useCreateFile.ts b/src/storage/useCreateFile.ts index 00c2484..8e2215b 100644 --- a/src/storage/useCreateFile.ts +++ b/src/storage/useCreateFile.ts @@ -1,57 +1,41 @@ -import { AppwriteException } from '../types' - -import { gql } from '../__generated__' -import { CreateFileMutation, CreateFileMutationVariables } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException, Models } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' -const createFile = gql(/* GraphQL */ ` - mutation CreateFile( - $bucketId: String! - $fileId: String! - $file: String! - $permissions: [String!] - ) { - storageCreateFile( - bucketId: $bucketId - fileId: $fileId - file: $file - permissions: $permissions - ) { - _id - bucketId - name - mimeType - sizeOriginal - } - } -`) +type CreateFileVariables = { + bucketId: string + fileId: string + file: File + permissions?: string[] + onProgress?: (progress: { + $id: string + progress: number + sizeUploaded: number + chunksTotal: number + chunksUploaded: number + }) => void +} export function useCreateFile() { - const { graphql } = useAppwrite() + const { storage } = useAppwrite() const queryClient = useQueryClient() - const mutationResult = useMutation< - CreateFileMutation['storageCreateFile'], - AppwriteException[], - CreateFileMutationVariables - >({ - mutationFn: async ({ bucketId, fileId, file, permissions }) => { - const { data, errors } = await graphql.mutation({ - query: createFile, - variables: { bucketId, fileId, file, permissions }, + const mutationResult = useMutation({ + mutationKey: Keys.buckets().files().create(), + mutationFn: async ({ bucketId, fileId, file, permissions, onProgress }) => { + return storage.createFile({ + bucketId, + fileId, + file, + permissions, + onProgress, }) - - if (errors) { - throw errors - } - - return data.storageCreateFile }, onSuccess: (_, variables) => { - queryClient.invalidateQueries({ - queryKey: ['appwrite', 'storage', variables.bucketId, 'files'], + void queryClient.invalidateQueries({ + queryKey: Keys.bucket(variables.bucketId).files().key(), }) }, }) diff --git a/src/storage/useDeleteFile.ts b/src/storage/useDeleteFile.ts index be99a26..f397c13 100644 --- a/src/storage/useDeleteFile.ts +++ b/src/storage/useDeleteFile.ts @@ -1,12 +1,13 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { DeleteFileMutation, DeleteFileMutationVariables } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' -const deleteFile = gql(/* GraphQL */ ` +export const deleteFile = gql(/* GraphQL */ ` mutation DeleteFile($bucketId: String!, $fileId: String!) { storageDeleteFile(bucketId: $bucketId, fileId: $fileId) { status @@ -14,15 +15,15 @@ const deleteFile = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['storageDeleteFile'] + export function useDeleteFile() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const mutationResult = useMutation< - DeleteFileMutation['storageDeleteFile'], - AppwriteException[], - DeleteFileMutationVariables - >({ + const mutationResult = useMutation({ + mutationKey: Keys.buckets().files().delete(), mutationFn: async ({ bucketId, fileId }) => { const { data, errors } = await graphql.mutation({ query: deleteFile, @@ -33,14 +34,14 @@ export function useDeleteFile() { throw errors } - return data?.storageDeleteFile ?? { status: true } + return data?.storageDeleteFile ?? { status: '' } }, onSuccess: (_, variables) => { queryClient.removeQueries({ - queryKey: ['appwrite', 'storage', variables.bucketId, 'files', variables.fileId], + queryKey: Keys.bucket(variables.bucketId).file(variables.fileId).key(), }) - queryClient.invalidateQueries({ - queryKey: ['appwrite', 'storage', variables.bucketId, 'files'], + void queryClient.invalidateQueries({ + queryKey: Keys.bucket(variables.bucketId).files().key(), }) }, }) diff --git a/src/storage/useFile.ts b/src/storage/useFile.ts index d6ef8b7..a94e8bf 100644 --- a/src/storage/useFile.ts +++ b/src/storage/useFile.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { GetFileQuery, GetFileQueryVariables } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' @@ -23,15 +24,14 @@ const getFile = gql(/* GraphQL */ ` } `) -export function useFile({ bucketId, fileId }: GetFileQueryVariables) { +type Variables = VariablesOf +type Result = ResultOf['storageGetFile'] + +export function useFile({ bucketId, fileId }: Variables) { const { graphql } = useAppwrite() - const queryResult = useQuery< - GetFileQuery['storageGetFile'], - AppwriteException[], - GetFileQuery['storageGetFile'] - >({ - queryKey: ['appwrite', 'storage', bucketId, 'files', fileId], + const queryResult = useQuery({ + queryKey: Keys.bucket(bucketId).file(fileId).key(), queryFn: async () => { const { data, errors } = await graphql.query({ query: getFile, diff --git a/src/storage/useFiles.ts b/src/storage/useFiles.ts index f98dc2b..664437d 100644 --- a/src/storage/useFiles.ts +++ b/src/storage/useFiles.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { ListFilesQuery } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' @@ -26,6 +27,8 @@ const listFiles = gql(/* GraphQL */ ` } `) +type Result = ResultOf['storageListFiles'] + export function useFiles({ bucketId, queries, @@ -37,12 +40,8 @@ export function useFiles({ }) { const { graphql } = useAppwrite() - const queryResult = useQuery< - ListFilesQuery['storageListFiles'], - AppwriteException[], - ListFilesQuery['storageListFiles'] - >({ - queryKey: ['appwrite', 'storage', bucketId, 'files', { queries, search }], + const queryResult = useQuery({ + queryKey: [...Keys.bucket(bucketId).files().key(), ...(queries ?? []), ...(search ? [search] : [])], queryFn: async () => { const { data, errors } = await graphql.query({ query: listFiles, diff --git a/src/storage/useUpdateFile.ts b/src/storage/useUpdateFile.ts index 18102d8..446391e 100644 --- a/src/storage/useUpdateFile.ts +++ b/src/storage/useUpdateFile.ts @@ -1,12 +1,13 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { UpdateFileMutation, UpdateFileMutationVariables } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' -const updateFile = gql(/* GraphQL */ ` +export const updateFile = gql(/* GraphQL */ ` mutation UpdateFile( $bucketId: String! $fileId: String! @@ -27,15 +28,15 @@ const updateFile = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['storageUpdateFile'] + export function useUpdateFile() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const mutationResult = useMutation< - UpdateFileMutation['storageUpdateFile'], - AppwriteException[], - UpdateFileMutationVariables - >({ + const mutationResult = useMutation({ + mutationKey: Keys.buckets().files().update(), mutationFn: async ({ bucketId, fileId, name, permissions }) => { const { data, errors } = await graphql.mutation({ query: updateFile, @@ -49,8 +50,8 @@ export function useUpdateFile() { return data.storageUpdateFile }, onSuccess: (_, variables) => { - queryClient.invalidateQueries({ - queryKey: ['appwrite', 'storage', variables.bucketId, 'files'], + void queryClient.invalidateQueries({ + queryKey: Keys.bucket(variables.bucketId).files().key(), }) }, }) diff --git a/src/teams/index.ts b/src/teams/index.ts index 21d7190..b5b2234 100644 --- a/src/teams/index.ts +++ b/src/teams/index.ts @@ -1,3 +1,4 @@ +export { teamQueryOptions } from './queryOptions' export { useTeam } from './useTeam' export { useTeams } from './useTeams' export { useTeamPrefs } from './useTeamPrefs' diff --git a/src/teams/queryOptions.ts b/src/teams/queryOptions.ts new file mode 100644 index 0000000..e1fa2e7 --- /dev/null +++ b/src/teams/queryOptions.ts @@ -0,0 +1,37 @@ +import { graphql as gql } from 'gql.tada' + +import type { AppwriteClient } from '../client' +import { Keys } from '../query/Keys' + +export const getTeam = gql(/* GraphQL */ ` + query GetTeam($teamId: String!) { + teamsGet(teamId: $teamId) { + _id + _createdAt + _updatedAt + name + total + prefs { + data + } + } + } +`) + +export function teamQueryOptions(client: AppwriteClient, { teamId }: { teamId: string }) { + return { + queryKey: Keys.team(teamId).key(), + queryFn: async () => { + const { data, errors } = await client.graphql.query({ + query: getTeam, + variables: { teamId }, + }) + + if (errors) { + throw errors + } + + return data.teamsGet + }, + } +} diff --git a/src/teams/useCreateMembership.ts b/src/teams/useCreateMembership.ts index 6faf531..b606231 100644 --- a/src/teams/useCreateMembership.ts +++ b/src/teams/useCreateMembership.ts @@ -1,15 +1,13 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { - CreateMembershipMutation, - CreateMembershipMutationVariables, -} from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' -const createMembership = gql(/* GraphQL */ ` +export const createMembership = gql(/* GraphQL */ ` mutation CreateMembership( $teamId: String! $roles: [String!]! @@ -37,15 +35,15 @@ const createMembership = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['teamsCreateMembership'] + export function useCreateMembership() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const mutationResult = useMutation< - CreateMembershipMutation['teamsCreateMembership'], - AppwriteException[], - CreateMembershipMutationVariables - >({ + const mutationResult = useMutation({ + mutationKey: Keys.teams().memberships().create(), mutationFn: async ({ teamId, roles, email, userId, phone, url, name }) => { const { data, errors } = await graphql.mutation({ query: createMembership, @@ -59,10 +57,10 @@ export function useCreateMembership() { return data.teamsCreateMembership }, onSuccess: (_, variables) => { - queryClient.invalidateQueries({ - queryKey: ['appwrite', 'teams', variables.teamId, 'memberships'], + void queryClient.invalidateQueries({ + queryKey: Keys.team(variables.teamId).memberships().key(), }) - queryClient.invalidateQueries({ queryKey: ['appwrite', 'teams', variables.teamId] }) + void queryClient.invalidateQueries({ queryKey: Keys.team(variables.teamId).key() }) }, }) diff --git a/src/teams/useCreateTeam.ts b/src/teams/useCreateTeam.ts index 748bada..a2876e9 100644 --- a/src/teams/useCreateTeam.ts +++ b/src/teams/useCreateTeam.ts @@ -1,12 +1,13 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { CreateTeamMutation, CreateTeamMutationVariables } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' -const createTeam = gql(/* GraphQL */ ` +export const createTeam = gql(/* GraphQL */ ` mutation CreateTeam($teamId: String!, $name: String!, $roles: [String!]) { teamsCreate(teamId: $teamId, name: $name, roles: $roles) { _id @@ -16,15 +17,15 @@ const createTeam = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['teamsCreate'] + export function useCreateTeam() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const mutationResult = useMutation< - CreateTeamMutation['teamsCreate'], - AppwriteException[], - CreateTeamMutationVariables - >({ + const mutationResult = useMutation({ + mutationKey: Keys.teams().create(), mutationFn: async ({ teamId, name, roles }) => { const { data, errors } = await graphql.mutation({ query: createTeam, @@ -38,7 +39,7 @@ export function useCreateTeam() { return data.teamsCreate }, onSuccess: () => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'teams'] }) + void queryClient.invalidateQueries({ queryKey: Keys.teams().key() }) }, }) diff --git a/src/teams/useDeleteMembership.ts b/src/teams/useDeleteMembership.ts index 7083106..5d3efaf 100644 --- a/src/teams/useDeleteMembership.ts +++ b/src/teams/useDeleteMembership.ts @@ -1,15 +1,13 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { - DeleteMembershipMutation, - DeleteMembershipMutationVariables, -} from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' -const deleteMembership = gql(/* GraphQL */ ` +export const deleteMembership = gql(/* GraphQL */ ` mutation DeleteMembership($teamId: String!, $membershipId: String!) { teamsDeleteMembership(teamId: $teamId, membershipId: $membershipId) { status @@ -17,15 +15,15 @@ const deleteMembership = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['teamsDeleteMembership'] + export function useDeleteMembership() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const mutationResult = useMutation< - DeleteMembershipMutation['teamsDeleteMembership'], - AppwriteException[], - DeleteMembershipMutationVariables - >({ + const mutationResult = useMutation({ + mutationKey: Keys.teams().memberships().delete(), mutationFn: async ({ teamId, membershipId }) => { const { data, errors } = await graphql.mutation({ query: deleteMembership, @@ -36,16 +34,16 @@ export function useDeleteMembership() { throw errors } - return data?.teamsDeleteMembership ?? { status: true } + return data?.teamsDeleteMembership ?? { status: '' } }, onSuccess: (_, variables) => { queryClient.removeQueries({ - queryKey: ['appwrite', 'teams', variables.teamId, 'memberships', variables.membershipId], + queryKey: Keys.team(variables.teamId).membership(variables.membershipId).key(), }) - queryClient.invalidateQueries({ - queryKey: ['appwrite', 'teams', variables.teamId, 'memberships'], + void queryClient.invalidateQueries({ + queryKey: Keys.team(variables.teamId).memberships().key(), }) - queryClient.invalidateQueries({ queryKey: ['appwrite', 'teams', variables.teamId] }) + void queryClient.invalidateQueries({ queryKey: Keys.team(variables.teamId).key() }) }, }) diff --git a/src/teams/useDeleteTeam.ts b/src/teams/useDeleteTeam.ts index 39c5587..743da2c 100644 --- a/src/teams/useDeleteTeam.ts +++ b/src/teams/useDeleteTeam.ts @@ -1,12 +1,13 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { DeleteTeamMutation, DeleteTeamMutationVariables } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' -const deleteTeam = gql(/* GraphQL */ ` +export const deleteTeam = gql(/* GraphQL */ ` mutation DeleteTeam($teamId: String!) { teamsDelete(teamId: $teamId) { status @@ -14,15 +15,15 @@ const deleteTeam = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['teamsDelete'] + export function useDeleteTeam() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const mutationResult = useMutation< - DeleteTeamMutation['teamsDelete'], - AppwriteException[], - DeleteTeamMutationVariables - >({ + const mutationResult = useMutation({ + mutationKey: Keys.teams().delete(), mutationFn: async ({ teamId }) => { const { data, errors } = await graphql.mutation({ query: deleteTeam, @@ -33,11 +34,11 @@ export function useDeleteTeam() { throw errors } - return data?.teamsDelete ?? { status: true } + return data?.teamsDelete ?? { status: '' } }, onSuccess: (_, variables) => { - queryClient.removeQueries({ queryKey: ['appwrite', 'teams', variables.teamId] }) - queryClient.invalidateQueries({ queryKey: ['appwrite', 'teams'] }) + queryClient.removeQueries({ queryKey: Keys.team(variables.teamId).key() }) + void queryClient.invalidateQueries({ queryKey: Keys.teams().key() }) }, }) diff --git a/src/teams/useTeam.ts b/src/teams/useTeam.ts index 4677224..1a2011d 100644 --- a/src/teams/useTeam.ts +++ b/src/teams/useTeam.ts @@ -1,46 +1,20 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' -import { gql } from '../__generated__' -import { GetTeamQuery, GetTeamQueryVariables } from '../__generated__/graphql' +import type { getTeam } from './queryOptions' +import { teamQueryOptions } from './queryOptions' +import type { AppwriteException, QueryOptions } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' -const getTeam = gql(/* GraphQL */ ` - query GetTeam($teamId: String!) { - teamsGet(teamId: $teamId) { - _id - _createdAt - _updatedAt - name - total - prefs { - data - } - } - } -`) +type Variables = VariablesOf +type Result = ResultOf['teamsGet'] -export function useTeam({ teamId }: GetTeamQueryVariables) { - const { graphql } = useAppwrite() +export function useTeam({ teamId }: Variables, opts: QueryOptions = {}) { + const client = useAppwrite() - const queryResult = useQuery< - GetTeamQuery['teamsGet'], - AppwriteException[], - GetTeamQuery['teamsGet'] - >({ - queryKey: ['appwrite', 'teams', teamId], - queryFn: async () => { - const { data, errors } = await graphql.query({ - query: getTeam, - variables: { teamId }, - }) - - if (errors) { - throw errors - } - - return data.teamsGet - }, + const queryResult = useQuery({ + ...teamQueryOptions(client, { teamId }), + ...opts, }) return { ...queryResult } diff --git a/src/teams/useTeamMembership.ts b/src/teams/useTeamMembership.ts index 47bd3ec..0398bcd 100644 --- a/src/teams/useTeamMembership.ts +++ b/src/teams/useTeamMembership.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { GetMembershipQuery, GetMembershipQueryVariables } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException, QueryOptions } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' @@ -25,15 +26,14 @@ const getMembership = gql(/* GraphQL */ ` } `) -export function useTeamMembership({ teamId, membershipId }: GetMembershipQueryVariables) { +type Variables = VariablesOf +type Result = ResultOf['teamsGetMembership'] + +export function useTeamMembership({ teamId, membershipId }: Variables, opts: QueryOptions = {}) { const { graphql } = useAppwrite() - const queryResult = useQuery< - GetMembershipQuery['teamsGetMembership'], - AppwriteException[], - GetMembershipQuery['teamsGetMembership'] - >({ - queryKey: ['appwrite', 'teams', teamId, 'memberships', membershipId], + const queryResult = useQuery({ + queryKey: Keys.team(teamId).membership(membershipId).key(), queryFn: async () => { const { data, errors } = await graphql.query({ query: getMembership, @@ -46,6 +46,7 @@ export function useTeamMembership({ teamId, membershipId }: GetMembershipQueryVa return data.teamsGetMembership }, + ...opts, }) return { ...queryResult } diff --git a/src/teams/useTeamMemberships.ts b/src/teams/useTeamMemberships.ts index fa1c234..7a9d070 100644 --- a/src/teams/useTeamMemberships.ts +++ b/src/teams/useTeamMemberships.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { ListMembershipsQuery } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException, QueryOptions } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' @@ -28,23 +29,28 @@ const listMemberships = gql(/* GraphQL */ ` } `) -export function useTeamMemberships({ - teamId, - queries, - search, -}: { - teamId: string - queries?: string[] - search?: string -}) { +type Result = ResultOf['teamsListMemberships'] + +export function useTeamMemberships( + { + teamId, + queries, + search, + }: { + teamId: string + queries?: string[] + search?: string + }, + opts: QueryOptions = {}, +) { const { graphql } = useAppwrite() - const queryResult = useQuery< - ListMembershipsQuery['teamsListMemberships'], - AppwriteException[], - ListMembershipsQuery['teamsListMemberships'] - >({ - queryKey: ['appwrite', 'teams', teamId, 'memberships', { queries, search }], + const queryResult = useQuery({ + queryKey: [ + ...Keys.team(teamId).memberships().key(), + ...(queries ?? []), + ...(search ? [search] : []), + ], queryFn: async () => { const { data, errors } = await graphql.query({ query: listMemberships, @@ -57,6 +63,7 @@ export function useTeamMemberships({ return data.teamsListMemberships }, + ...opts, }) return { ...queryResult } diff --git a/src/teams/useTeamPrefs.ts b/src/teams/useTeamPrefs.ts index e7558ec..47244f6 100644 --- a/src/teams/useTeamPrefs.ts +++ b/src/teams/useTeamPrefs.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { GetTeamPrefsQuery, GetTeamPrefsQueryVariables } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException, QueryOptions } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' @@ -13,15 +14,14 @@ const getTeamPrefs = gql(/* GraphQL */ ` } `) -export function useTeamPrefs({ teamId }: GetTeamPrefsQueryVariables) { +type Variables = VariablesOf +type Result = ResultOf['teamsGetPrefs'] + +export function useTeamPrefs({ teamId }: Variables, opts: QueryOptions = {}) { const { graphql } = useAppwrite() - const queryResult = useQuery< - GetTeamPrefsQuery['teamsGetPrefs'], - AppwriteException[], - GetTeamPrefsQuery['teamsGetPrefs'] - >({ - queryKey: ['appwrite', 'teams', teamId, 'prefs'], + const queryResult = useQuery({ + queryKey: Keys.team(teamId).teamPrefs().key(), queryFn: async () => { const { data, errors } = await graphql.query({ query: getTeamPrefs, @@ -34,6 +34,7 @@ export function useTeamPrefs({ teamId }: GetTeamPrefsQueryVariables) { return data.teamsGetPrefs }, + ...opts, }) return { ...queryResult } diff --git a/src/teams/useTeams.ts b/src/teams/useTeams.ts index 08cb0d9..be89f9a 100644 --- a/src/teams/useTeams.ts +++ b/src/teams/useTeams.ts @@ -1,7 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { ListTeamsQuery } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException, QueryOptions } from '../types' import { useAppwrite } from '../useAppwrite' import { useQuery } from '../useQuery' @@ -23,21 +24,22 @@ const listTeams = gql(/* GraphQL */ ` } `) -export function useTeams({ - queries, - search, -}: { - queries?: string[] - search?: string -} = {}) { +type Result = ResultOf['teamsList'] + +export function useTeams( + { + queries, + search, + }: { + queries?: string[] + search?: string + } = {}, + opts: QueryOptions = {}, +) { const { graphql } = useAppwrite() - const queryResult = useQuery< - ListTeamsQuery['teamsList'], - AppwriteException[], - ListTeamsQuery['teamsList'] - >({ - queryKey: ['appwrite', 'teams', { queries, search }], + const queryResult = useQuery({ + queryKey: [...Keys.teams().key(), ...(queries ?? []), ...(search ? [search] : [])], queryFn: async () => { const { data, errors } = await graphql.query({ query: listTeams, @@ -50,6 +52,7 @@ export function useTeams({ return data.teamsList }, + ...opts, }) return { ...queryResult } diff --git a/src/teams/useUpdateMembership.ts b/src/teams/useUpdateMembership.ts index fd51c11..5cf85c4 100644 --- a/src/teams/useUpdateMembership.ts +++ b/src/teams/useUpdateMembership.ts @@ -1,15 +1,13 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { - UpdateMembershipMutation, - UpdateMembershipMutationVariables, -} from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' -const updateMembership = gql(/* GraphQL */ ` +export const updateMembership = gql(/* GraphQL */ ` mutation UpdateMembership($teamId: String!, $membershipId: String!, $roles: [String!]!) { teamsUpdateMembership(teamId: $teamId, membershipId: $membershipId, roles: $roles) { _id @@ -18,15 +16,15 @@ const updateMembership = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['teamsUpdateMembership'] + export function useUpdateMembership() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const mutationResult = useMutation< - UpdateMembershipMutation['teamsUpdateMembership'], - AppwriteException[], - UpdateMembershipMutationVariables - >({ + const mutationResult = useMutation({ + mutationKey: Keys.teams().memberships().update(), mutationFn: async ({ teamId, membershipId, roles }) => { const { data, errors } = await graphql.mutation({ query: updateMembership, @@ -40,8 +38,8 @@ export function useUpdateMembership() { return data.teamsUpdateMembership }, onSuccess: (_, variables) => { - queryClient.invalidateQueries({ - queryKey: ['appwrite', 'teams', variables.teamId, 'memberships'], + void queryClient.invalidateQueries({ + queryKey: Keys.team(variables.teamId).memberships().key(), }) }, }) diff --git a/src/teams/useUpdateMembershipStatus.ts b/src/teams/useUpdateMembershipStatus.ts index c7e4245..7520ace 100644 --- a/src/teams/useUpdateMembershipStatus.ts +++ b/src/teams/useUpdateMembershipStatus.ts @@ -1,10 +1,8 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { - UpdateMembershipStatusMutation, - UpdateMembershipStatusMutationVariables, -} from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' @@ -28,15 +26,15 @@ const updateMembershipStatus = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['teamsUpdateMembershipStatus'] + export function useUpdateMembershipStatus() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const mutationResult = useMutation< - UpdateMembershipStatusMutation['teamsUpdateMembershipStatus'], - AppwriteException[], - UpdateMembershipStatusMutationVariables - >({ + const mutationResult = useMutation({ + mutationKey: Keys.teams().membershipStatus().update(), mutationFn: async ({ teamId, membershipId, userId, secret }) => { const { data, errors } = await graphql.mutation({ query: updateMembershipStatus, @@ -50,8 +48,8 @@ export function useUpdateMembershipStatus() { return data.teamsUpdateMembershipStatus }, onSuccess: (_, variables) => { - queryClient.invalidateQueries({ - queryKey: ['appwrite', 'teams', variables.teamId, 'memberships'], + void queryClient.invalidateQueries({ + queryKey: Keys.team(variables.teamId).memberships().key(), }) }, }) diff --git a/src/teams/useUpdateTeamName.ts b/src/teams/useUpdateTeamName.ts index cba34b9..e73a0bd 100644 --- a/src/teams/useUpdateTeamName.ts +++ b/src/teams/useUpdateTeamName.ts @@ -1,12 +1,13 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { UpdateTeamNameMutation, UpdateTeamNameMutationVariables } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' -const updateTeamName = gql(/* GraphQL */ ` +export const updateTeamName = gql(/* GraphQL */ ` mutation UpdateTeamName($teamId: String!, $name: String!) { teamsUpdateName(teamId: $teamId, name: $name) { _id @@ -15,15 +16,15 @@ const updateTeamName = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['teamsUpdateName'] + export function useUpdateTeamName() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const mutationResult = useMutation< - UpdateTeamNameMutation['teamsUpdateName'], - AppwriteException[], - UpdateTeamNameMutationVariables - >({ + const mutationResult = useMutation({ + mutationKey: Keys.teams().teamName().update(), mutationFn: async ({ teamId, name }) => { const { data, errors } = await graphql.mutation({ query: updateTeamName, @@ -37,8 +38,8 @@ export function useUpdateTeamName() { return data.teamsUpdateName }, onSuccess: (_, variables) => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'teams', variables.teamId] }) - queryClient.invalidateQueries({ queryKey: ['appwrite', 'teams'] }) + void queryClient.invalidateQueries({ queryKey: Keys.team(variables.teamId).key() }) + void queryClient.invalidateQueries({ queryKey: Keys.teams().key() }) }, }) diff --git a/src/teams/useUpdateTeamPrefs.ts b/src/teams/useUpdateTeamPrefs.ts index 8193508..afaec9c 100644 --- a/src/teams/useUpdateTeamPrefs.ts +++ b/src/teams/useUpdateTeamPrefs.ts @@ -1,12 +1,13 @@ -import { AppwriteException } from '../types' +import type { ResultOf, VariablesOf } from 'gql.tada' +import { graphql as gql } from 'gql.tada' -import { gql } from '../__generated__' -import { UpdateTeamPrefsMutation, UpdateTeamPrefsMutationVariables } from '../__generated__/graphql' +import { Keys } from '../query/Keys' +import type { AppwriteException } from '../types' import { useAppwrite } from '../useAppwrite' import { useMutation } from '../useMutation' import { useQueryClient } from '../useQueryClient' -const updateTeamPrefs = gql(/* GraphQL */ ` +export const updateTeamPrefs = gql(/* GraphQL */ ` mutation UpdateTeamPrefs($teamId: String!, $prefs: Assoc!) { teamsUpdatePrefs(teamId: $teamId, prefs: $prefs) { data @@ -14,15 +15,15 @@ const updateTeamPrefs = gql(/* GraphQL */ ` } `) +type Variables = VariablesOf +type Result = ResultOf['teamsUpdatePrefs'] + export function useUpdateTeamPrefs() { const { graphql } = useAppwrite() const queryClient = useQueryClient() - const mutationResult = useMutation< - UpdateTeamPrefsMutation['teamsUpdatePrefs'], - AppwriteException[], - UpdateTeamPrefsMutationVariables - >({ + const mutationResult = useMutation({ + mutationKey: Keys.teams().teamPrefs().update(), mutationFn: async ({ teamId, prefs }) => { const { data, errors } = await graphql.mutation({ query: updateTeamPrefs, @@ -36,7 +37,7 @@ export function useUpdateTeamPrefs() { return data.teamsUpdatePrefs }, onSuccess: (_, variables) => { - queryClient.invalidateQueries({ queryKey: ['appwrite', 'teams', variables.teamId] }) + void queryClient.invalidateQueries({ queryKey: Keys.team(variables.teamId).key() }) }, }) diff --git a/src/types.ts b/src/types.ts index 59fc099..525490e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -17,3 +17,10 @@ export { } from 'appwrite' export type { Models, Browser, CreditCard, Flag, ImageGravity, ImageFormat } from 'appwrite' + +export type QueryOptions = { + enabled?: boolean + retry?: boolean | number | ((failureCount: number, error: unknown) => boolean) + retryDelay?: number | ((attemptIndex: number) => number) + staleTime?: number +} diff --git a/src/useAppwrite.ts b/src/useAppwrite.ts index f12f022..c31bbed 100644 --- a/src/useAppwrite.ts +++ b/src/useAppwrite.ts @@ -1,15 +1,9 @@ -import { useAtomValue } from 'jotai' +import { useContext } from 'react' -import { appwriteAtom } from './states/appwrite' +import { AppwriteContext } from './AppwriteProvider' export function useAppwrite() { - const { account, avatars, realtime, storage, graphql } = useAtomValue(appwriteAtom) - - return { - avatars, - realtime, - storage, - account, - graphql, - } + const ctx = useContext(AppwriteContext) + if (!ctx) throw new Error('Wrap your app in ') + return ctx } diff --git a/src/useLazyQuery.ts b/src/useLazyQuery.ts index efb607d..004bd25 100644 --- a/src/useLazyQuery.ts +++ b/src/useLazyQuery.ts @@ -1,14 +1,20 @@ -import { +import type { DefinedInitialDataOptions, QueryKey, UndefinedInitialDataOptions, UseQueryOptions, - useQuery as useReactQuery, } from '@tanstack/react-query' +import { useQuery as useReactQuery } from '@tanstack/react-query' +import type { AppwriteException } from './types' import { useQueryClient } from './useQueryClient' -export function useLazyQuery( +export function useLazyQuery< + TQueryFnData, + TError extends AppwriteException[], + TData, + TQueryKey extends QueryKey = QueryKey, +>( options: | UndefinedInitialDataOptions | DefinedInitialDataOptions diff --git a/src/useMutation.ts b/src/useMutation.ts index a0bb05d..c33c002 100644 --- a/src/useMutation.ts +++ b/src/useMutation.ts @@ -1,14 +1,12 @@ -import { - DefaultError, - UseMutationOptions, - useMutation as useReactMutation, -} from '@tanstack/react-query' +import type { UseMutationOptions } from '@tanstack/react-query' +import { useMutation as useReactMutation } from '@tanstack/react-query' +import type { AppwriteException } from './types' import { useQueryClient } from './useQueryClient' export function useMutation< TData = unknown, - TError = DefaultError, + TError extends AppwriteException[] = [], TVariables = void, TContext = unknown, >(options: UseMutationOptions) { diff --git a/src/useQuery.ts b/src/useQuery.ts index 3a99720..eb0809f 100644 --- a/src/useQuery.ts +++ b/src/useQuery.ts @@ -1,14 +1,20 @@ -import { +import type { DefinedInitialDataOptions, QueryKey, UndefinedInitialDataOptions, UseQueryOptions, - useQuery as useReactQuery, } from '@tanstack/react-query' +import { useQuery as useReactQuery } from '@tanstack/react-query' +import type { AppwriteException } from './types' import { useQueryClient } from './useQueryClient' -export function useQuery( +export function useQuery< + TQueryFnData, + TError extends AppwriteException[], + TData, + TQueryKey extends QueryKey = QueryKey, +>( options: | UndefinedInitialDataOptions | DefinedInitialDataOptions diff --git a/src/useQueryClient.ts b/src/useQueryClient.ts index 0346895..c3efad1 100644 --- a/src/useQueryClient.ts +++ b/src/useQueryClient.ts @@ -1,7 +1,8 @@ -import { useAtomValue } from 'jotai' - -import { QueryAtom } from './states/query' +import { useContext } from 'react' +import { QueryClientContext } from '@tanstack/react-query' export function useQueryClient() { - return useAtomValue(QueryAtom) + const ctx = useContext(QueryClientContext) + if (!ctx) throw new Error('Wrap your app in ') + return ctx } diff --git a/src/useSuspenseQuery.ts b/src/useSuspenseQuery.ts index 2a9f6e4..e4a6292 100644 --- a/src/useSuspenseQuery.ts +++ b/src/useSuspenseQuery.ts @@ -1,14 +1,12 @@ -import { - QueryKey, - UseSuspenseQueryOptions, - useSuspenseQuery as useSuspenseReactQuery, -} from '@tanstack/react-query' +import type { QueryKey, UseSuspenseQueryOptions } from '@tanstack/react-query' +import { useSuspenseQuery as useSuspenseReactQuery } from '@tanstack/react-query' +import type { AppwriteException } from './types' import { useQueryClient } from './useQueryClient' export function useSuspenseQuery< TQueryFnData, - TError, + TError extends AppwriteException[], TData, TQueryKey extends QueryKey = QueryKey, >(options: UseSuspenseQueryOptions) { diff --git a/test.ts b/test.ts new file mode 100644 index 0000000..8b5dbb3 --- /dev/null +++ b/test.ts @@ -0,0 +1,18 @@ +import { useDocument } from './src' + +type Person = { + name: string + age: number +} + +const person = useDocument( + { + databaseId: 'db1', + collectionId: 'col1', + documentId: 'doc1', + fields: ['name', 'age'], + }, + { + staleTime: 1000 * 60, // 1 minute + }, +) diff --git a/tests/.env b/tests/.env index 07c6c9d..2d0d6ac 100644 --- a/tests/.env +++ b/tests/.env @@ -36,13 +36,13 @@ _APP_DB_SCHEMA=appwrite _APP_DB_USER=user _APP_DB_PASS=password _APP_DB_ROOT_PASS=rootsecretpassword -_APP_SMTP_HOST= -_APP_SMTP_PORT= -_APP_SMTP_SECURE= -_APP_SMTP_USERNAME= -_APP_SMTP_PASSWORD= -_APP_SMS_PROVIDER= -_APP_SMS_FROM= +_APP_SMTP_HOST=host.docker.internal +_APP_SMTP_PORT=1025 +_APP_SMTP_SECURE=false +_APP_SMTP_USERNAME="" +_APP_SMTP_PASSWORD="" +_APP_SMS_PROVIDER=sms://username:password@mock +_APP_SMS_FROM=+15005550006 _APP_STORAGE_LIMIT=30000000 _APP_STORAGE_PREVIEW_LIMIT=20000000 _APP_STORAGE_ANTIVIRUS=disabled @@ -53,7 +53,7 @@ _APP_FUNCTIONS_TIMEOUT=900 _APP_COMPUTE_BUILD_TIMEOUT=900 _APP_COMPUTE_CPUS=0 _APP_COMPUTE_MEMORY=0 -_APP_FUNCTIONS_RUNTIMES=node-22.0 +_APP_FUNCTIONS_RUNTIMES=node-22 _APP_SITES_RUNTIMES=static-1 _APP_EXECUTOR_SECRET=executor-secret-key _APP_EXECUTOR_HOST=http://exc1/v1 diff --git a/tests/__mocks__/Realtime.ts b/tests/__mocks__/Realtime.ts new file mode 100644 index 0000000..b88a29a --- /dev/null +++ b/tests/__mocks__/Realtime.ts @@ -0,0 +1,64 @@ +import { + Avatars, + type Channel, + Client, + Functions, + Graphql, + ID, + type Query, + type RealtimeResponseEvent, + type RealtimeSubscription, +} from 'appwrite' +import type { ActionableChannel, ResolvedChannel } from 'appwrite/types/channel' +import { mock } from 'bun:test' + +const subscriptions = new Map< + string[], + (event: RealtimeResponseEvent) => void +>() + +class Realtime { + subscribe( + channel: string | Channel | ActionableChannel | ResolvedChannel, + callback: (event: RealtimeResponseEvent) => void, + queries?: (string | Query)[], + ): Promise { + const key = [channel.toString(), ...(queries ?? []).map((q) => q.toString())] + subscriptions.set(key, callback) + return Promise.resolve({ + close() { + subscriptions.delete(key) + return Promise.resolve() + }, + } as unknown as RealtimeSubscription) + } +} + +mock.module('appwrite', () => { + return { + Realtime, + Avatars, + ID, + Functions, + Graphql, + Client, + } +}) + +export const triggerRealtimeEvent = ( + channel: string | Channel | ActionableChannel | ResolvedChannel, + payload: any, + events?: string[], +) => { + for (const [subChannels, callback] of subscriptions.entries()) { + if (subChannels.includes(channel.toString())) { + callback({ + channels: subChannels, + payload, + events: events ?? [], + timestamp: new Date().toISOString(), + subscriptions: subChannels, + } as RealtimeResponseEvent) + } + } +} diff --git a/tests/account/auth.test.tsx b/tests/account/auth.test.tsx index bec4ed6..4fdd529 100644 --- a/tests/account/auth.test.tsx +++ b/tests/account/auth.test.tsx @@ -1,9 +1,8 @@ -import { act, renderHook, waitFor } from '@testing-library/react' -import { afterAll, beforeAll, describe, expect, test } from 'bun:test' +import { act, renderHook, waitFor, within } from '@testing-library/react' +import { Channel } from 'appwrite' +import { afterAll, afterEach, beforeAll, describe, expect, spyOn, test } from 'bun:test' import { - fragments, - getFragmentData, useAccount, useCreateAnonymousSession, useLazyAccount, @@ -12,27 +11,23 @@ import { useSignUp, } from '../../src' import { ID } from '../../src/types' -import { createTestUser, deleteTestUser } from '../setup/helpers' +import { triggerRealtimeEvent } from '../__mocks__/Realtime' +import { + checkMail, + createTestUser, + deleteTestUser, + emptyMail, + loginUser, + renderMessage, +} from '../setup/helpers' import { createQueryClient, createWrapper } from '../setup/wrapper' -/* - * Integration tests for account authentication hooks. - * - * These tests require a running Appwrite instance configured via - * `tests/.test-config.json` or environment variables. They exercise - * the full GraphQL mutation/query lifecycle through React hooks. - * - * Run `bun test tests/account/auth.test.tsx` with a local Appwrite - * instance (see tests/docker-compose.yml). - */ - -// --------------------------------------------------------------------------- -// Shared test user created once for the login / logout / account test suites -// --------------------------------------------------------------------------- let testUser: Awaited> beforeAll(async () => { testUser = await createTestUser({ name: 'Auth Test User' }) + await emptyMail() + document.body.innerHTML = '' }) afterAll(async () => { @@ -41,10 +36,12 @@ afterAll(async () => { } }) -// --------------------------------------------------------------------------- -// useSignUp -// --------------------------------------------------------------------------- describe('useSignUp', () => { + afterEach(async () => { + await emptyMail() + document.body.innerHTML = '' + }) + test('should sign up a new user with email and password', async () => { const queryClient = createQueryClient() const wrapper = createWrapper({ queryClient }) @@ -55,9 +52,11 @@ describe('useSignUp', () => { // signUp mutation should be idle initially expect(result.current.signUp.isIdle).toBe(true) + const userId_signup = ID.unique() + await act(async () => { result.current.signUp.mutate({ - userId: ID.unique(), + userId: userId_signup, email: uniqueEmail, password: 'securepassword123', name: 'SignUp Test User', @@ -73,13 +72,44 @@ describe('useSignUp', () => { expect(data?.name).toBe('SignUp Test User') expect(data?.email).toBe(uniqueEmail) - // Clean up: delete the user we just created via the server SDK - // The signUp mutation returns the accountCreate fragment (name, email) - // but not $id — we need to look up or rely on server SDK for cleanup. - // Since we can't easily get the userId from signUp response, we use - // the server helper to find-and-delete by listing or accept the leak - // in test environments. In practice, teardown.ts handles this. - }) + // Login to get an active session (required to request verification) + await loginUser(uniqueEmail, 'securepassword123', wrapper) + + // Request email verification + await act(async () => { + result.current.verifyEmail.mutate({ verifyUrl: 'http://localhost/verify' }) + }) + + await waitFor(() => { + expect(result.current.verifyEmail.isSuccess).toBe(true) + }) + + const message = await waitFor(async () => { + const emails = await checkMail() + expect(emails.messages.length).toBeGreaterThan(0) + return emails.messages[0] + }) + + await renderMessage(message.ID) + const emailBody = within(document.body) + + expect(emailBody.getByText(/Confirm email address/)).toBeDefined() + + const button = emailBody.getByText(/Confirm email address/) + + expect(button.getAttribute('href')).toBeDefined() + + const url = new URL(button.getAttribute('href') || '') + expect(url.pathname).toBe('/verify') + + const params = new URLSearchParams(url.search) + + const userId = params.get('userId') + const secret = params.get('secret') + + expect(userId).toBe(userId_signup) + expect(secret).toBeDefined() + }, 15000) test('should expose verifyEmail mutation alongside signUp', () => { const queryClient = createQueryClient() @@ -117,9 +147,6 @@ describe('useSignUp', () => { }) }) -// --------------------------------------------------------------------------- -// useLogin -// --------------------------------------------------------------------------- describe('useLogin', () => { test('should log in with email and password', async () => { const queryClient = createQueryClient() @@ -183,33 +210,17 @@ describe('useLogin', () => { }) }) -// --------------------------------------------------------------------------- -// useLogout -// --------------------------------------------------------------------------- describe('useLogout', () => { test('should log out the current session', async () => { const queryClient = createQueryClient() const wrapper = createWrapper({ queryClient }) - // First, log in to create a session to log out from - const { result: loginResult } = renderHook(() => useLogin(), { wrapper }) - - await act(async () => { - loginResult.current.login.mutate({ - email: testUser.email, - password: testUser.password, - }) - }) - - await waitFor(() => { - expect(loginResult.current.login.isSuccess).toBe(true) - }) + await loginUser(testUser.email, testUser.password, wrapper) - // Now log out const { result: logoutResult } = renderHook(() => useLogout(), { wrapper }) await act(async () => { - logoutResult.current.mutate({ sessionId: 'current' }) + await logoutResult.current.mutateAsync({ sessionId: 'current' }) }) await waitFor(() => { @@ -237,9 +248,6 @@ describe('useLogout', () => { }) }) -// --------------------------------------------------------------------------- -// useAccount -// --------------------------------------------------------------------------- describe('useAccount', () => { test('should return current user data after login', async () => { const queryClient = createQueryClient() @@ -266,10 +274,9 @@ describe('useAccount', () => { expect(accountResult.current.isSuccess).toBe(true) }) - const rawAccountData = accountResult.current.data - expect(rawAccountData).toBeDefined() + const accountData = accountResult.current.data + expect(accountData).toBeDefined() - const accountData = getFragmentData(fragments.Account_UserFragment, rawAccountData) expect(accountData._id).toBeDefined() expect(typeof accountData._id).toBe('string') expect(accountData.name).toBe(testUser.name) @@ -291,9 +298,6 @@ describe('useAccount', () => { }) }) -// --------------------------------------------------------------------------- -// useLazyAccount -// --------------------------------------------------------------------------- describe('useLazyAccount', () => { test('should not fetch until run() is called', async () => { const queryClient = createQueryClient() @@ -343,26 +347,21 @@ describe('useLazyAccount', () => { const { result } = renderHook(() => useLazyAccount(), { wrapper }) await act(async () => { - result.current.run() + await result.current.run() }) await waitFor(() => { expect(result.current.query.isSuccess).toBe(true) }) - const rawAccountData = result.current.query.data - expect(rawAccountData).toBeDefined() - - const accountData = getFragmentData(fragments.Account_UserFragment, rawAccountData) + const accountData = result.current.query.data + expect(accountData).toBeDefined() expect(accountData._id).toBeDefined() expect(accountData.name).toBe(testUser.name) expect(accountData.email).toBe(testUser.email) }) }) -// --------------------------------------------------------------------------- -// useCreateAnonymousSession -// --------------------------------------------------------------------------- describe('useCreateAnonymousSession', () => { test('should create an anonymous session', async () => { const queryClient = createQueryClient() @@ -373,7 +372,7 @@ describe('useCreateAnonymousSession', () => { expect(result.current.isIdle).toBe(true) await act(async () => { - result.current.mutate(undefined) + await result.current.mutateAsync(undefined) }) await waitFor(() => { @@ -402,14 +401,13 @@ describe('useCreateAnonymousSession', () => { }) }) -// --------------------------------------------------------------------------- -// Cross-cutting: login → account → logout lifecycle -// --------------------------------------------------------------------------- describe('auth lifecycle', () => { test('should complete full login → fetch account → logout cycle', async () => { const queryClient = createQueryClient() const wrapper = createWrapper({ queryClient }) + const spy = spyOn(queryClient, 'setQueryData') + // 1. Login const { result: loginResult } = renderHook(() => useLogin(), { wrapper }) @@ -431,16 +429,26 @@ describe('auth lifecycle', () => { expect(accountResult.current.isSuccess).toBe(true) }) - const rawAccountData = accountResult.current.data - const accountData = getFragmentData(fragments.Account_UserFragment, rawAccountData) + const accountData = accountResult.current.data expect(accountData._id).toBeDefined() expect(accountData.email).toBe(testUser.email) + // 2.1 Update preferences and check if subscription works + triggerRealtimeEvent( + Channel.account(), + { + theme: 'dark', + }, + ['account.update.prefs'], + ) + + expect(spy).toHaveBeenCalled() + // 3. Logout const { result: logoutResult } = renderHook(() => useLogout(), { wrapper }) await act(async () => { - logoutResult.current.mutate({ sessionId: 'current' }) + await logoutResult.current.mutateAsync({ sessionId: 'current' }) }) await waitFor(() => { diff --git a/tests/account/mfa-challenge.test.tsx b/tests/account/mfa-challenge.test.tsx new file mode 100644 index 0000000..bb61265 --- /dev/null +++ b/tests/account/mfa-challenge.test.tsx @@ -0,0 +1,190 @@ +import type { QueryClient } from '@tanstack/react-query' +import { act, renderHook, waitFor } from '@testing-library/react' +import { afterAll, beforeAll, describe, expect, test } from 'bun:test' + +import { + useCreateMfaChallenge, + useCreateMfaRecoveryCodes, + useDeleteMfaAuthenticator, + useGetMfaRecoveryCodes, + useUpdateMfa, + useUpdateMfaChallenge, + useUpdateMfaRecoveryCodes, +} from '../../src' +import { createTestUser, deleteTestUser, generateTOTP, loginUser, setupOTP } from '../setup/helpers' +import { createQueryClient, createWrapper } from '../setup/wrapper' + +type Wrapper = ReturnType + +describe('MFA (Multi-Factor Authentication) Challenge', () => { + let userId: string + let email: string + let password: string + let queryClient: QueryClient + let wrapper: Wrapper + + /** TOTP secret returned when creating the authenticator. */ + let totpSecret: string + + /** Recovery codes created during the MFA setup flow. */ + let recoveryCodes: string[] + + beforeAll(async () => { + const user = await createTestUser({ name: 'MFA Challenge Test User' }) + userId = user.userId + email = user.email + password = user.password + + queryClient = createQueryClient() + wrapper = createWrapper({ queryClient }) + + await loginUser(email, password, wrapper) + const otp = await setupOTP(wrapper) + totpSecret = otp.totpSecret + }) + + afterAll(async () => { + try { + // Attempt to disable MFA in case a test failed mid-flow + const { result: mfaResult } = renderHook(() => useUpdateMfa(), { wrapper }) + await act(async () => { + await mfaResult.current.mutateAsync({ mfa: false }) + }) + await waitFor(() => expect(mfaResult.current.isSuccess).toBe(true)) + } catch { + // MFA may already be disabled – ignore + } + + await deleteTestUser(userId) + }) + + test('useCreateMfaChallenge, useUpdateMfaChallenge with valid OTP', async () => { + const { result: createMfaChallengeResult } = renderHook(() => useCreateMfaChallenge(), { + wrapper, + }) + + await act(async () => { + await createMfaChallengeResult.current.mutateAsync({ factor: 'totp' }) + }) + + await waitFor(() => expect(createMfaChallengeResult.current.isSuccess).toBe(true)) + + const { result: updateMfaChallengeResult } = renderHook(() => useUpdateMfaChallenge(), { + wrapper, + }) + + await waitFor(async () => + expect( + updateMfaChallengeResult.current.mutateAsync({ + challengeId: createMfaChallengeResult.current.data?._id || '', + otp: '777777', // Invalid OTP, but we just want to verify the flow works + }), + ).rejects.toBeDefined(), + ) + + await waitFor(() => expect(updateMfaChallengeResult.current.isError).toBe(true)) + + await act(async () => + updateMfaChallengeResult.current.mutateAsync({ + challengeId: createMfaChallengeResult.current.data?._id || '', + otp: generateTOTP(totpSecret), + }), + ) + + await waitFor(() => expect(updateMfaChallengeResult.current.isSuccess).toBe(true)) + }) + + test('useGetMfaRecoveryCodes', async () => { + const { result: codes } = renderHook(() => useCreateMfaRecoveryCodes(), { wrapper }) + + await act(async () => { + await codes.current.mutateAsync() + }) + await waitFor(() => expect(codes.current.isSuccess).toBe(true)) + + // Store the codes from CREATE – these are the actual usable codes + recoveryCodes = codes.current.data!.recoveryCodes + + const { result } = renderHook(() => useGetMfaRecoveryCodes(), { wrapper }) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + + expect(result.current.data).toBeDefined() + expect(result.current.data?.recoveryCodes).toBeDefined() + + expect(Array.isArray(result.current.data?.recoveryCodes)).toBe(true) + expect(result.current.data!.recoveryCodes.length).toBe(codes.current.data!.recoveryCodes.length) + }) + + test.skip('useCreateMfaChallenge, useUpdateMfaChallenge with valid Recovery Code — Appwrite 1.8.1 returns user_invalid_token on both REST and GraphQL endpoints (server bug, not GraphQL-specific)', async () => { + const { result } = renderHook(() => useGetMfaRecoveryCodes(), { wrapper }) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + + expect(result.current.data).toBeDefined() + expect(result.current.data?.recoveryCodes).toBeDefined() + + // Store the codes from CREATE – these are the actual usable codes + const rCodes = result.current.data!.recoveryCodes + + const { result: createResult, unmount: unmountCreate } = renderHook( + () => useCreateMfaChallenge(), + { wrapper }, + ) + + await act(async () => { + await createResult.current.mutateAsync({ factor: 'recoveryCode' }) + }) + + await waitFor(() => expect(createResult.current.isSuccess).toBe(true)) + const challengeId = createResult.current.data?._id || '' + unmountCreate() + + const { result: updateResult, unmount: unmountUpdate } = renderHook( + () => useUpdateMfaChallenge(), + { wrapper }, + ) + + await act(async () => + updateResult.current.mutateAsync({ + challengeId, + otp: rCodes[0], + }), + ) + + await waitFor(() => expect(updateResult.current.isSuccess).toBe(true)) + unmountUpdate() + }) + + test('useUpdateMfaRecoveryCodes', async () => { + const { result } = renderHook(() => useUpdateMfaRecoveryCodes(), { wrapper }) + + await act(async () => { + await result.current.mutateAsync() + }) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + + expect(result.current.data).toBeDefined() + expect(result.current.data?.recoveryCodes).toBeDefined() + expect(Array.isArray(result.current.data?.recoveryCodes)).toBe(true) + expect(result.current.data!.recoveryCodes.length).toBeGreaterThan(0) + + // New codes should differ from the original set + const newCodes = result.current.data!.recoveryCodes + const codesChanged = newCodes.some((code) => !recoveryCodes.includes(code)) + expect(codesChanged).toBe(true) + }) + + test('useDeleteMfaAuthenticator', async () => { + const { result } = renderHook(() => useDeleteMfaAuthenticator(), { wrapper }) + + await act(async () => { + await result.current.mutateAsync({ type: 'totp' }) + }) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + + expect(result.current.data).toBeDefined() + }) +}) diff --git a/tests/account/mfa.test.tsx b/tests/account/mfa.test.tsx index 9c99c7e..53fd777 100644 --- a/tests/account/mfa.test.tsx +++ b/tests/account/mfa.test.tsx @@ -1,46 +1,19 @@ -import { QueryClient } from '@tanstack/react-query' +import type { QueryClient } from '@tanstack/react-query' import { act, renderHook, waitFor } from '@testing-library/react' import { afterAll, beforeAll, describe, expect, test } from 'bun:test' -import { TOTP } from 'otpauth' + import { useCreateMfaAuthenticator, useCreateMfaRecoveryCodes, - useDeleteMfaAuthenticator, - useGetMfaRecoveryCodes, useListMfaFactors, - useLogin, useUpdateMfa, useUpdateMfaAuthenticator, - useUpdateMfaRecoveryCodes, } from '../../src' -import { createTestUser, deleteTestUser } from '../setup/helpers' +import { createTestUser, deleteTestUser, generateTOTP, loginUser } from '../setup/helpers' import { createQueryClient, createWrapper } from '../setup/wrapper' -// --------------------------------------------------------------------------- -// Helpers -// --------------------------------------------------------------------------- - type Wrapper = ReturnType -function generateTOTP(secret: string): string { - const totp = new TOTP({ secret, algorithm: 'SHA1', digits: 6, period: 30 }) - return totp.generate() -} - -async function loginUser(email: string, password: string, wrapper: Wrapper) { - const { result } = renderHook(() => useLogin(), { wrapper }) - - await act(async () => { - result.current.login.mutateAsync({ email, password }) - }) - - await waitFor(() => expect(result.current.login.isSuccess).toBe(true)) -} - -// --------------------------------------------------------------------------- -// MFA Integration Tests -// --------------------------------------------------------------------------- - describe('MFA (Multi-Factor Authentication)', () => { let userId: string let email: string @@ -51,14 +24,6 @@ describe('MFA (Multi-Factor Authentication)', () => { /** TOTP secret returned when creating the authenticator. */ let totpSecret: string - /** Recovery codes created during the MFA setup flow. */ - let recoveryCodes: string[] - - // ----------------------------------------------------------------------- - // Setup – create user, login, and share a single QueryClient / wrapper - // so that the session cookie persists across all ordered tests. - // ----------------------------------------------------------------------- - beforeAll(async () => { const user = await createTestUser({ name: 'MFA Test User' }) userId = user.userId @@ -71,16 +36,12 @@ describe('MFA (Multi-Factor Authentication)', () => { await loginUser(email, password, wrapper) }) - // ----------------------------------------------------------------------- - // Teardown – best-effort MFA disable & user cleanup - // ----------------------------------------------------------------------- - afterAll(async () => { try { // Attempt to disable MFA in case a test failed mid-flow const { result: mfaResult } = renderHook(() => useUpdateMfa(), { wrapper }) await act(async () => { - mfaResult.current.mutateAsync({ mfa: false }) + await mfaResult.current.mutateAsync({ mfa: false }) }) await waitFor(() => expect(mfaResult.current.isSuccess).toBe(true)) } catch { @@ -90,15 +51,11 @@ describe('MFA (Multi-Factor Authentication)', () => { await deleteTestUser(userId) }) - // ----------------------------------------------------------------------- - // 1. Enable MFA - // ----------------------------------------------------------------------- - test('useUpdateMfa – enables MFA on the account', async () => { const { result } = renderHook(() => useUpdateMfa(), { wrapper }) await act(async () => { - result.current.mutateAsync({ mfa: true }) + await result.current.mutateAsync({ mfa: true }) }) await waitFor(() => expect(result.current.isSuccess).toBe(true)) @@ -107,15 +64,11 @@ describe('MFA (Multi-Factor Authentication)', () => { expect(result.current.data?.mfa).toBe(true) }) - // ----------------------------------------------------------------------- - // 2. Create TOTP Authenticator - // ----------------------------------------------------------------------- - test('useCreateMfaAuthenticator – creates a TOTP authenticator', async () => { const { result } = renderHook(() => useCreateMfaAuthenticator(), { wrapper }) await act(async () => { - result.current.mutateAsync({ type: 'totp' }) + await result.current.mutateAsync({ type: 'totp' }) }) await waitFor(() => expect(result.current.isSuccess).toBe(true)) @@ -130,17 +83,13 @@ describe('MFA (Multi-Factor Authentication)', () => { totpSecret = result.current.data!.secret }) - // ----------------------------------------------------------------------- - // 3. Verify / Activate the Authenticator - // ----------------------------------------------------------------------- - test('useUpdateMfaAuthenticator – verifies the TOTP authenticator', async () => { const otp = generateTOTP(totpSecret) const { result } = renderHook(() => useUpdateMfaAuthenticator(), { wrapper }) await act(async () => { - result.current.mutateAsync({ type: 'totp', otp }) + await result.current.mutateAsync({ type: 'totp', otp }) }) await waitFor(() => expect(result.current.isSuccess).toBe(true)) @@ -149,10 +98,6 @@ describe('MFA (Multi-Factor Authentication)', () => { expect(result.current.data?.mfa).toBe(true) }) - // ----------------------------------------------------------------------- - // 4. List MFA Factors - // ----------------------------------------------------------------------- - test('useListMfaFactors – lists factors with totp enabled', async () => { const { result } = renderHook(() => useListMfaFactors(), { wrapper }) @@ -162,15 +107,11 @@ describe('MFA (Multi-Factor Authentication)', () => { expect(result.current.data?.totp).toBe(true) }) - // ----------------------------------------------------------------------- - // 5. Create Recovery Codes - // ----------------------------------------------------------------------- - test('useCreateMfaRecoveryCodes – generates recovery codes', async () => { const { result } = renderHook(() => useCreateMfaRecoveryCodes(), { wrapper }) await act(async () => { - result.current.mutateAsync() + await result.current.mutateAsync() }) await waitFor(() => expect(result.current.isSuccess).toBe(true)) @@ -179,74 +120,13 @@ describe('MFA (Multi-Factor Authentication)', () => { expect(result.current.data?.recoveryCodes).toBeDefined() expect(Array.isArray(result.current.data?.recoveryCodes)).toBe(true) expect(result.current.data!.recoveryCodes.length).toBeGreaterThan(0) - - recoveryCodes = result.current.data!.recoveryCodes - }) - - // ----------------------------------------------------------------------- - // 6. Get Recovery Codes - // ----------------------------------------------------------------------- - - test.skip('useGetMfaRecoveryCodes – retrieves the stored recovery codes (requires recent MFA challenge)', async () => { - const { result } = renderHook(() => useGetMfaRecoveryCodes(), { wrapper }) - - await waitFor(() => expect(result.current.isSuccess).toBe(true)) - - expect(result.current.data).toBeDefined() - expect(result.current.data?.recoveryCodes).toBeDefined() - expect(Array.isArray(result.current.data?.recoveryCodes)).toBe(true) - expect(result.current.data!.recoveryCodes.length).toBe(recoveryCodes.length) }) - // ----------------------------------------------------------------------- - // 7. Regenerate Recovery Codes - // ----------------------------------------------------------------------- - - test.skip('useUpdateMfaRecoveryCodes – regenerates recovery codes (requires recent MFA challenge)', async () => { - const { result } = renderHook(() => useUpdateMfaRecoveryCodes(), { wrapper }) - - await act(async () => { - result.current.mutateAsync() - }) - - await waitFor(() => expect(result.current.isSuccess).toBe(true)) - - expect(result.current.data).toBeDefined() - expect(result.current.data?.recoveryCodes).toBeDefined() - expect(Array.isArray(result.current.data?.recoveryCodes)).toBe(true) - expect(result.current.data!.recoveryCodes.length).toBeGreaterThan(0) - - // New codes should differ from the original set - const newCodes = result.current.data!.recoveryCodes - const codesChanged = newCodes.some((code) => !recoveryCodes.includes(code)) - expect(codesChanged).toBe(true) - }) - - // ----------------------------------------------------------------------- - // 8. Delete TOTP Authenticator - // ----------------------------------------------------------------------- - - test.skip('useDeleteMfaAuthenticator – removes the TOTP authenticator (requires recent MFA challenge)', async () => { - const { result } = renderHook(() => useDeleteMfaAuthenticator(), { wrapper }) - - await act(async () => { - result.current.mutateAsync({ type: 'totp' }) - }) - - await waitFor(() => expect(result.current.isSuccess).toBe(true)) - - expect(result.current.data).toBeDefined() - }) - - // ----------------------------------------------------------------------- - // 9. Disable MFA - // ----------------------------------------------------------------------- - test('useUpdateMfa – disables MFA on the account', async () => { const { result } = renderHook(() => useUpdateMfa(), { wrapper }) await act(async () => { - result.current.mutateAsync({ mfa: false }) + await result.current.mutateAsync({ mfa: false }) }) await waitFor(() => expect(result.current.isSuccess).toBe(true)) @@ -254,27 +134,4 @@ describe('MFA (Multi-Factor Authentication)', () => { expect(result.current.data).toBeDefined() expect(result.current.data?.mfa).toBe(false) }) - - // ----------------------------------------------------------------------- - // MFA Challenge hooks – skipped - // ----------------------------------------------------------------------- - - test.skip('useCreateMfaChallenge – requires a separate login flow with MFA enforcement', () => { - // useCreateMfaChallenge creates a challenge during the login flow when - // MFA is enforced. Testing it requires a full login attempt against an - // account with MFA already active, which produces a challenge instead of - // a session. This needs a dedicated test harness that: - // 1. Enables MFA and registers an authenticator (done above) - // 2. Starts a NEW login (separate client / session) to trigger the challenge - // 3. Calls useCreateMfaChallenge with factor: 'totp' - // 4. Solves the challenge via useUpdateMfaChallenge - // This is not feasible within the current shared-session test setup. - }) - - test.skip('useUpdateMfaChallenge – requires a challengeId from useCreateMfaChallenge', () => { - // useUpdateMfaChallenge completes a challenge started by - // useCreateMfaChallenge. It requires a valid challengeId and a TOTP code. - // Since creating the challenge depends on an active MFA-enforced login - // flow (see above), this hook cannot be tested in isolation here. - }) }) diff --git a/tests/account/misc.test.tsx b/tests/account/misc.test.tsx index c97ea56..ee67f62 100644 --- a/tests/account/misc.test.tsx +++ b/tests/account/misc.test.tsx @@ -1,22 +1,27 @@ -import { act, renderHook, waitFor } from '@testing-library/react' +import { act, renderHook, waitFor, within } from '@testing-library/react' import { afterAll, beforeAll, describe, expect, test } from 'bun:test' -import { useListIdentities, useLogin, useLogs } from '../../src' -import { createTestUser, deleteTestUser } from '../setup/helpers' +import { + useCreateEmailToken, + useCreateMagicURLToken, + useListIdentities, + useLogs, + usePasswordRecovery, + useResetPassword, + useUpdateMagicURLSession, +} from '../../src' +import { + checkMail, + createServerClient, + createTestUser, + deleteTestUser, + emptyMail, + loginUser, + logoutUser, + renderMessage, +} from '../setup/helpers' import { createQueryClient, createWrapper } from '../setup/wrapper' -async function loginUser( - email: string, - password: string, - wrapper: ReturnType, -) { - const { result } = renderHook(() => useLogin(), { wrapper }) - await act(async () => { - result.current.login.mutateAsync({ email, password }) - }) - await waitFor(() => expect(result.current.login.isSuccess).toBe(true)) -} - describe('Account misc hooks', () => { let user: Awaited> @@ -39,6 +44,7 @@ describe('Account misc hooks', () => { await waitFor(() => expect(result.current.isSuccess).toBe(true)) expect(result.current.data).toBeDefined() + await logoutUser(wrapper) }) test('useLogs returns activity logs after login', async () => { @@ -54,22 +60,160 @@ describe('Account misc hooks', () => { expect(result.current.data).toBeDefined() expect(result.current.data?.logs).toBeDefined() expect(Array.isArray(result.current.data?.logs)).toBe(true) + + await logoutUser(wrapper) + }) + + test('useCreateEmailToken', async () => { + const wrapper = createWrapper() + + const { result } = renderHook(() => useCreateEmailToken(), { wrapper }) + + await act(async () => { + await result.current.mutateAsync({ + userId: user.userId, + email: user.email, + phrase: false, + }) + }) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + + await act(async () => { + await new Promise((r) => setTimeout(r, 3000)) + }) + + const message = await waitFor(async () => { + const emails = await checkMail() + expect(emails.messages.length).toBeGreaterThan(0) + return emails.messages[0] + }) + + await renderMessage(message.ID) + const emailBody = within(document.body) + + expect(emailBody.getByText(/verification code/)).toBeDefined() + + await emptyMail() + }) + + test('useCreateMagicURLToken & useUpdateMagicURLSession', async () => { + const wrapper = createWrapper() + + const { result } = renderHook(() => useCreateMagicURLToken(), { wrapper }) + + await act(async () => { + await result.current.mutateAsync({ + userId: user.userId, + email: user.email, + phrase: false, + }) + }) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + + await act(async () => { + await new Promise((r) => setTimeout(r, 3000)) + }) + + const message = await waitFor(async () => { + const emails = await checkMail() + expect(emails.messages.length).toBeGreaterThan(0) + return emails.messages[0] + }) + + await renderMessage(message.ID) + const emailBody = within(document.body) + + expect(emailBody.getAllByText(/Sign in to Test Project/)).toBeDefined() + + const button = emailBody.getAllByText(/Sign in to Test Project/)[1] + + expect(button.getAttribute('href')).toBeDefined() + + const url = new URL(button.getAttribute('href') || '') + expect(url.pathname).toBe('/console/auth/magic-url') + + await emptyMail() + + const userId = url.searchParams.get('userId') + const secret = url.searchParams.get('secret') + + const { result: updateResult } = renderHook(() => useUpdateMagicURLSession(), { wrapper }) + + await act(async () => { + await updateResult.current.mutateAsync({ + userId: userId || '', + secret: secret || '', + }) + }) + + await waitFor(() => expect(updateResult.current.isSuccess).toBe(true)) + await logoutUser(wrapper) + }) + + test('usePasswordRecovery & useResetPassword', async () => { + const wrapper = createWrapper() + + const { result } = renderHook(() => usePasswordRecovery(), { wrapper }) + + await act(async () => { + await result.current.mutateAsync({ + email: user.email, + url: 'https://localhost/reset-password', + }) + }) + + await act(async () => { + await new Promise((r) => setTimeout(r, 3000)) + }) + + const message = await waitFor(async () => { + const emails = await checkMail() + expect(emails.messages.length).toBeGreaterThan(0) + return emails.messages[0] + }) + + await renderMessage(message.ID) + const emailBody = within(document.body) + + expect(emailBody.getByText(/Reset password/)).toBeDefined() + + const button = emailBody.getByText(/Reset password/) + + expect(button.getAttribute('href')).toBeDefined() + + const url = new URL(button.getAttribute('href') || '') + expect(url.pathname).toBe('/reset-password') + + const params = new URLSearchParams(url.search) + + expect(params.get('userId')).toBe(user.userId) + expect(params.get('secret')).toBeDefined() + + const secret = params.get('secret') || '' + + const { result: resetResult } = renderHook(() => useResetPassword(), { wrapper }) + + await act(async () => { + await resetResult.current.mutateAsync({ + userId: user.userId, + secret, + password: 'newpassword', + }) + }) + + await waitFor(() => expect(resetResult.current.isSuccess).toBe(true)) + + // Login with new password to verify it works + await loginUser(user.email, 'newpassword', wrapper) + await logoutUser(wrapper) + + // Reset password back to original via server SDK (recovery tokens are single-use) + const { users } = createServerClient() + await users.updatePassword({ userId: user.userId, password: user.password }) }) test.skip('useCreateOAuth2Token requires OAuth provider configuration', () => {}) - test.skip('useCreateEmailToken requires email delivery', () => {}) - test.skip('useCreateMagicURLToken requires email delivery', () => {}) - test.skip('useCreatePhoneToken requires SMS provider', () => {}) - test.skip('useCreatePhoneVerification requires SMS provider', () => {}) - test.skip('useUpdatePhoneVerification requires SMS provider', () => {}) - test.skip('useUpdatePhoneSession requires SMS provider', () => {}) - test.skip('useUpdateMagicURLSession requires email delivery', () => {}) - test.skip('usePasswordRecovery requires email delivery', () => {}) - test.skip('useResetPassword requires email delivery and recovery token', () => {}) - test.skip('useVerification requires email delivery', () => {}) - test.skip('useCreatePushTarget requires messaging provider', () => {}) - test.skip('useUpdatePushTarget requires messaging provider', () => {}) - test.skip('useDeletePushTarget requires messaging provider', () => {}) test.skip('useDeleteIdentity requires identity from OAuth provider', () => {}) - test.skip('useUpdateStatus destructive: disables account', () => {}) }) diff --git a/tests/account/new-hooks.test.tsx b/tests/account/new-hooks.test.tsx index a4fd00c..2b91151 100644 --- a/tests/account/new-hooks.test.tsx +++ b/tests/account/new-hooks.test.tsx @@ -1,48 +1,18 @@ -import { act, renderHook, waitFor } from '@testing-library/react' +import { act, renderHook, waitFor, within } from '@testing-library/react' import { afterAll, beforeAll, describe, expect, test } from 'bun:test' -import { useAccount, useCreateEmailVerification, useDeleteAccount, useLogin } from '../../src' -import { createTestUser, deleteTestUser } from '../setup/helpers' +import { useCreateEmailVerification, useUpdateEmailVerification } from '../../src' +import { + checkMail, + createTestUser, + deleteTestUser, + emptyMail, + loginUser, + renderMessage, +} from '../setup/helpers' import { createWrapper } from '../setup/wrapper' -type Wrapper = ReturnType - -async function loginUser(email: string, password: string, wrapper: Wrapper) { - const { result } = renderHook(() => useLogin(), { wrapper }) - - await act(async () => { - result.current.login.mutateAsync({ email, password }) - }) - - await waitFor(() => expect(result.current.login.isSuccess).toBe(true)) -} - describe('New account hooks', () => { - describe('useDeleteAccount', () => { - test('deletes the currently logged-in account', async () => { - // Create a throwaway user just for this test - const user = await createTestUser({ name: 'Delete Me User' }) - const wrapper = createWrapper() - await loginUser(user.email, user.password, wrapper) - - const { result } = renderHook(() => useDeleteAccount(), { wrapper }) - - await act(async () => { - result.current.mutateAsync() - }) - - await waitFor(() => expect(result.current.isSuccess).toBe(true)) - - // Verify the account is gone by checking useAccount fails - const wrapper2 = createWrapper() - const { result: accountResult } = renderHook(() => useAccount(), { wrapper: wrapper2 }) - - await waitFor(() => - expect(accountResult.current.isError || accountResult.current.data === null).toBe(true), - ) - }) - }) - describe('useCreateEmailVerification', () => { let userId: string let userEmail: string @@ -59,25 +29,59 @@ describe('New account hooks', () => { await deleteTestUser(userId) }) - test('sends an email verification request', async () => { + test('sends and updates an email verification request', async () => { const wrapper = createWrapper() await loginUser(userEmail, userPassword, wrapper) const { result } = renderHook(() => useCreateEmailVerification(), { wrapper }) await act(async () => { - // The URL is where the user would be redirected to confirm - result.current.mutate({ url: 'http://localhost/verify' }) + await result.current.mutateAsync({ url: 'http://localhost/verify' }) + }) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + + await act(async () => { + await new Promise((r) => setTimeout(r, 3000)) + }) + + const message = await waitFor(async () => { + const emails = await checkMail() + expect(emails.messages.length).toBeGreaterThan(0) + return emails.messages[0] + }) + + await renderMessage(message.ID) + const emailBody = within(document.body) + + expect(emailBody.getByText(/Confirm email address/)).toBeDefined() + + const button = emailBody.getByText(/Confirm email address/) + + expect(button.getAttribute('href')).toBeDefined() + + const url = new URL(button.getAttribute('href') || '') + expect(url.pathname).toBe('/verify') + + const params = new URLSearchParams(url.search) + + expect(params.get('userId')).toBe(userId) + expect(params.get('secret')).toBeDefined() + + const secret = params.get('secret') || '' + + const { result: updateResult } = renderHook(() => useUpdateEmailVerification(), { wrapper }) + + await act(async () => { + await updateResult.current.mutateAsync({ + userId, + secret, + }) }) - // This may fail if SMTP is not configured, which is expected in test environments - await waitFor(() => expect(result.current.isSuccess || result.current.isError).toBe(true)) + await waitFor(() => expect(updateResult.current.isSuccess).toBe(true)) - // If it succeeded, it should return a token - if (result.current.isSuccess) { - expect(result.current.data).toBeDefined() - expect(result.current.data?.userId).toBeDefined() - } + await emptyMail() }) }) }) diff --git a/tests/account/phone.test.tsx b/tests/account/phone.test.tsx new file mode 100644 index 0000000..9511701 --- /dev/null +++ b/tests/account/phone.test.tsx @@ -0,0 +1,141 @@ +import { act, renderHook, waitFor } from '@testing-library/react' +import { afterAll, beforeAll, describe, expect, test } from 'bun:test' + +import { + useCreatePhoneToken, + useCreatePhoneVerification, + useUpdatePhone, + useUpdatePhoneSession, + useUpdatePhoneVerification, +} from '../../src' +import { + clearSMSMessages, + createTestUser, + deleteTestUser, + getSMSMessages, + loginUser, + logoutUser, +} from '../setup/helpers' +import { createQueryClient, createWrapper } from '../setup/wrapper' + +describe('phone hooks', () => { + let userId: string + let email: string + let password: string + const phone = '+12065551234' + + beforeAll(async () => { + const user = await createTestUser({ name: 'UpdatePhone User' }) + userId = user.userId + email = user.email + password = user.password + + await clearSMSMessages() + }) + + afterAll(async () => { + await deleteTestUser(userId) + }) + + test('updates the account phone number', async () => { + const queryClient = createQueryClient() + const wrapper = createWrapper({ queryClient }) + await loginUser(email, password, wrapper) + + const { result } = renderHook(() => useUpdatePhone(), { wrapper }) + + await act(async () => { + await result.current.mutateAsync({ phone, password }) + }) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + + expect(result.current.data).toBeDefined() + expect(result.current.data?.phone).toBe(phone) + }) + + test('fails with incorrect password', async () => { + const queryClient = createQueryClient() + const wrapper = createWrapper({ queryClient }) + await loginUser(email, password, wrapper) + + const { result } = renderHook(() => useUpdatePhone(), { wrapper }) + + await act(async () => { + result.current.mutate({ phone: '+12065559999', password: 'wrongpassword' }) + }) + + await waitFor(() => expect(result.current.isError).toBe(true)) + }) + describe('phone verification hooks', () => { + test('create and update phone verification flow', async () => { + const queryClient = createQueryClient() + const wrapper = createWrapper({ queryClient }) + await loginUser(email, password, wrapper) + + const { result } = renderHook(() => useCreatePhoneVerification(), { wrapper }) + + await act(async () => { + await result.current.mutateAsync() + }) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + + expect(result.current.data).toBeDefined() + + const messages = await getSMSMessages() + expect(messages.length).toBeGreaterThan(0) + + const secret = messages[0].message + + const { result: updateResult } = renderHook(() => useUpdatePhoneVerification(), { wrapper }) + + await act(async () => { + await updateResult.current.mutateAsync({ userId, secret }) + }) + + await waitFor(() => expect(updateResult.current.isSuccess).toBe(true)) + + expect(updateResult.current.data).toBeDefined() + + await clearSMSMessages() + }) + }) + + describe('phone token hooks', () => { + test('create phone token flow', async () => { + const queryClient = createQueryClient() + const wrapper = createWrapper({ queryClient }) + await loginUser(email, password, wrapper) + + const { result } = renderHook(() => useCreatePhoneToken(), { wrapper }) + + await act(async () => { + await result.current.mutateAsync({ userId, phone }) + }) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + + expect(result.current.data).toBeDefined() + + const messages = await getSMSMessages() + expect(messages.length).toBeGreaterThan(0) + + const secret = messages[0].message + + await logoutUser(wrapper) + + const { result: updateResult } = renderHook(() => useUpdatePhoneSession(), { wrapper }) + + await act(async () => { + await updateResult.current.mutateAsync({ userId, secret }) + }) + + await waitFor(() => expect(updateResult.current.isSuccess).toBe(true)) + + expect(updateResult.current.data).toBeDefined() + + await clearSMSMessages() + }) + }) +}) diff --git a/tests/account/profile.test.tsx b/tests/account/profile.test.tsx index 6549b79..992891e 100644 --- a/tests/account/profile.test.tsx +++ b/tests/account/profile.test.tsx @@ -1,37 +1,19 @@ -import { QueryClient } from '@tanstack/react-query' +import type { QueryClient } from '@tanstack/react-query' import { act, renderHook, waitFor } from '@testing-library/react' import { afterAll, beforeAll, beforeEach, describe, expect, test } from 'bun:test' + import { useGetPrefs, - useLogin, useUpdateEmail, useUpdateName, useUpdatePassword, useUpdatePrefs, } from '../../src' -import { createTestUser, deleteTestUser } from '../setup/helpers' +import { createTestUser, deleteTestUser, loginUser } from '../setup/helpers' import { createQueryClient, createWrapper } from '../setup/wrapper' -// --------------------------------------------------------------------------- -// Helpers -// --------------------------------------------------------------------------- - type Wrapper = ReturnType -async function loginUser(email: string, password: string, wrapper: Wrapper) { - const { result } = renderHook(() => useLogin(), { wrapper }) - - await act(async () => { - result.current.login.mutateAsync({ email, password }) - }) - - await waitFor(() => expect(result.current.login.isSuccess).toBe(true)) -} - -// --------------------------------------------------------------------------- -// useUpdateName -// --------------------------------------------------------------------------- - describe('useUpdateName', () => { let userId: string let email: string @@ -61,7 +43,7 @@ describe('useUpdateName', () => { const { result } = renderHook(() => useUpdateName(), { wrapper }) await act(async () => { - result.current.mutate({ name: 'Updated Name' }) + await result.current.mutateAsync({ name: 'Updated Name' }) }) await waitFor(() => expect(result.current.isSuccess).toBe(true)) @@ -71,10 +53,6 @@ describe('useUpdateName', () => { }) }) -// --------------------------------------------------------------------------- -// useUpdateEmail -// --------------------------------------------------------------------------- - describe('useUpdateEmail', () => { let userId: string let email: string @@ -106,7 +84,7 @@ describe('useUpdateEmail', () => { const { result } = renderHook(() => useUpdateEmail(), { wrapper }) await act(async () => { - result.current.mutate({ email: newEmail, password }) + await result.current.mutateAsync({ email: newEmail, password }) }) await waitFor(() => expect(result.current.isSuccess).toBe(true)) @@ -116,10 +94,6 @@ describe('useUpdateEmail', () => { }) }) -// --------------------------------------------------------------------------- -// useUpdatePassword -// --------------------------------------------------------------------------- - describe('useUpdatePassword', () => { let userId: string let email: string @@ -151,7 +125,7 @@ describe('useUpdatePassword', () => { const { result } = renderHook(() => useUpdatePassword(), { wrapper }) await act(async () => { - result.current.mutate({ password: newPassword, oldPassword: password }) + await result.current.mutateAsync({ password: newPassword, oldPassword: password }) }) await waitFor(() => expect(result.current.isSuccess).toBe(true)) @@ -161,10 +135,6 @@ describe('useUpdatePassword', () => { }) }) -// --------------------------------------------------------------------------- -// useUpdatePrefs & useGetPrefs -// --------------------------------------------------------------------------- - describe('useUpdatePrefs', () => { let userId: string let email: string @@ -194,7 +164,7 @@ describe('useUpdatePrefs', () => { const { result } = renderHook(() => useUpdatePrefs(), { wrapper }) await act(async () => { - result.current.mutate({ prefs: { theme: 'dark', fontSize: 14 } }) + await result.current.mutateAsync({ prefs: { theme: 'dark', fontSize: 14 } }) }) await waitFor(() => expect(result.current.isSuccess).toBe(true)) @@ -209,7 +179,7 @@ describe('useUpdatePrefs', () => { const { result: updateResult } = renderHook(() => useUpdatePrefs(), { wrapper }) await act(async () => { - updateResult.current.mutate({ prefs: { theme: 'light', notifications: true } }) + await updateResult.current.mutateAsync({ prefs: { theme: 'light', notifications: true } }) }) await waitFor(() => expect(updateResult.current.isSuccess).toBe(true)) @@ -228,10 +198,6 @@ describe('useUpdatePrefs', () => { }) }) -// --------------------------------------------------------------------------- -// useUpdateStatus — skipped (destructive: disables the account) -// --------------------------------------------------------------------------- - describe('useUpdateStatus', () => { test.skip('is skipped because it disables the account (destructive operation)', () => { // useUpdateStatus sets the account status to disabled. diff --git a/tests/account/push.test.tsx b/tests/account/push.test.tsx new file mode 100644 index 0000000..b86670a --- /dev/null +++ b/tests/account/push.test.tsx @@ -0,0 +1,74 @@ +import { act, renderHook, waitFor } from '@testing-library/react' +import { afterAll, beforeAll, describe, expect, test } from 'bun:test' + +import { useCreatePushTarget, useDeletePushTarget, useUpdatePushTarget } from '../../src' +import { createTestUser, deleteTestUser, loginUser } from '../setup/helpers' +import { createQueryClient, createWrapper } from '../setup/wrapper' + +describe('push target hooks', () => { + let userId: string + let email: string + let password: string + // const phone = '+12065551234' + + beforeAll(async () => { + const user = await createTestUser({ name: 'UpdatePhone User' }) + userId = user.userId + email = user.email + password = user.password + }) + + afterAll(async () => { + await deleteTestUser(userId) + }) + + test('useCreatePushTarget', async () => { + const queryClient = createQueryClient() + const wrapper = createWrapper({ queryClient }) + await loginUser(email, password, wrapper) + + const { result } = renderHook(() => useCreatePushTarget(), { wrapper }) + + await act(async () => { + await result.current.mutateAsync({ + targetId: 'test-push-target', + identifier: 'push-token', + }) + }) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + }) + + test('useUpdatePushTarget', async () => { + const queryClient = createQueryClient() + const wrapper = createWrapper({ queryClient }) + await loginUser(email, password, wrapper) + + const { result } = renderHook(() => useUpdatePushTarget(), { wrapper }) + + await act(async () => { + await result.current.mutateAsync({ + targetId: 'test-push-target', + identifier: 'new-push-token', + }) + }) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + }) + + test('useDeletePushTarget', async () => { + const queryClient = createQueryClient() + const wrapper = createWrapper({ queryClient }) + await loginUser(email, password, wrapper) + + const { result } = renderHook(() => useDeletePushTarget(), { wrapper }) + + await act(async () => { + await result.current.mutateAsync({ + targetId: 'test-push-target', + }) + }) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + }) +}) diff --git a/tests/account/sessions.test.tsx b/tests/account/sessions.test.tsx index 1669b61..cd07ffd 100644 --- a/tests/account/sessions.test.tsx +++ b/tests/account/sessions.test.tsx @@ -1,37 +1,110 @@ -import { QueryClient } from '@tanstack/react-query' -import { act, renderHook, waitFor } from '@testing-library/react' +import type { QueryClient } from '@tanstack/react-query' +import { act, renderHook, waitFor, within } from '@testing-library/react' import { afterAll, beforeAll, beforeEach, describe, expect, test } from 'bun:test' + import { useCreateJWT, + useCreateMagicURLToken, + useCreateSession, useDeleteSession, useDeleteSessions, useGetSession, useListSessions, - useLogin, + useSuspenseCreateJWT, useUpdateSession, } from '../../src' -import { createTestUser, deleteTestUser } from '../setup/helpers' +import { + checkMail, + createTestUser, + deleteTestUser, + emptyMail, + loginUser, + logoutUser, + renderMessage, +} from '../setup/helpers' import { createQueryClient, createWrapper } from '../setup/wrapper' -// --------------------------------------------------------------------------- -// Helpers -// --------------------------------------------------------------------------- - type Wrapper = ReturnType -async function loginUser(email: string, password: string, wrapper: Wrapper) { - const { result } = renderHook(() => useLogin(), { wrapper }) +describe('useCreateSession', () => { + let userId: string + let email: string + let password: string + let queryClient: QueryClient + let wrapper: Wrapper + + beforeAll(async () => { + const user = await createTestUser({ name: 'ListSessions User' }) + userId = user.userId + email = user.email + password = user.password + }) + + afterAll(async () => { + await deleteTestUser(userId) + }) - await act(async () => { - result.current.login.mutateAsync({ email, password }) + beforeEach(() => { + queryClient = createQueryClient() + wrapper = createWrapper({ queryClient }) }) - await waitFor(() => expect(result.current.login.isSuccess).toBe(true)) -} + test('creates a session from a magic URL token', async () => { + await loginUser(email, password, wrapper) + + const { result: magicURLResult } = renderHook(() => useCreateMagicURLToken(), { wrapper }) + + await act(async () => { + await magicURLResult.current.mutateAsync({ + userId, + email, + phrase: false, + }) + }) + + await waitFor(() => expect(magicURLResult.current.isSuccess).toBe(true)) + + await act(async () => { + await new Promise((r) => setTimeout(r, 3000)) + }) + + const message = await waitFor(async () => { + const emails = await checkMail() + expect(emails.messages.length).toBeGreaterThan(0) + return emails.messages[0] + }) + + await renderMessage(message.ID) + const emailBody = within(document.body) + + expect(emailBody.getAllByText(/Sign in to Test Project/)).toBeDefined() + + const button = emailBody.getAllByText(/Sign in to Test Project/)[1] + + expect(button.getAttribute('href')).toBeDefined() + + const url = new URL(button.getAttribute('href') || '') + expect(url.pathname).toBe('/console/auth/magic-url') + + await emptyMail() + + const uid = url.searchParams.get('userId') + const secret = url.searchParams.get('secret') -// --------------------------------------------------------------------------- -// useListSessions -// --------------------------------------------------------------------------- + await logoutUser(wrapper) + + const { result } = renderHook(() => useCreateSession(), { wrapper }) + + await act(async () => { + await result.current.mutateAsync({ + userId: uid || '', + secret: secret || '', + }) + }) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + }) +}) describe('useListSessions', () => { let userId: string @@ -76,10 +149,6 @@ describe('useListSessions', () => { }) }) -// --------------------------------------------------------------------------- -// useGetSession -// --------------------------------------------------------------------------- - describe('useGetSession', () => { let userId: string let email: string @@ -121,10 +190,6 @@ describe('useGetSession', () => { }) }) -// --------------------------------------------------------------------------- -// useCreateJWT -// --------------------------------------------------------------------------- - describe('useCreateJWT', () => { let userId: string let email: string @@ -154,7 +219,7 @@ describe('useCreateJWT', () => { const { result } = renderHook(() => useCreateJWT(), { wrapper }) await act(async () => { - result.current.mutate() + await result.current.mutateAsync() }) await waitFor(() => expect(result.current.isSuccess).toBe(true)) @@ -164,11 +229,21 @@ describe('useCreateJWT', () => { expect(typeof result.current.data?.jwt).toBe('string') expect(result.current.data!.jwt.length).toBeGreaterThan(0) }) -}) -// --------------------------------------------------------------------------- -// useUpdateSession -// --------------------------------------------------------------------------- + test('creates a JWT token with useSuspenseQuery', async () => { + wrapper = createWrapper({ queryClient, suspense: true }) + await loginUser(email, password, wrapper) + + const { result } = renderHook(() => useSuspenseCreateJWT(), { wrapper }) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + + expect(result.current.data).toBeDefined() + expect(result.current.data?.jwt).toBeDefined() + expect(typeof result.current.data?.jwt).toBe('string') + expect(result.current.data!.jwt.length).toBeGreaterThan(0) + }) +}) describe('useUpdateSession', () => { let userId: string @@ -207,7 +282,7 @@ describe('useUpdateSession', () => { const { result } = renderHook(() => useUpdateSession(), { wrapper }) await act(async () => { - result.current.mutate({ sessionId }) + await result.current.mutateAsync({ sessionId }) }) await waitFor(() => expect(result.current.isSuccess).toBe(true)) @@ -218,10 +293,6 @@ describe('useUpdateSession', () => { }) }) -// --------------------------------------------------------------------------- -// useDeleteSession -// --------------------------------------------------------------------------- - describe('useDeleteSession', () => { let userId: string let email: string @@ -259,20 +330,16 @@ describe('useDeleteSession', () => { const { result } = renderHook(() => useDeleteSession(), { wrapper }) await act(async () => { - result.current.mutate({ sessionId }) + await result.current.mutateAsync({ sessionId }) }) await waitFor(() => expect(result.current.isSuccess).toBe(true)) expect(result.current.data).toBeDefined() - expect(result.current.data?.status).toBe(true) + expect(result.current.data?.status).toBeDefined() }) }) -// --------------------------------------------------------------------------- -// useDeleteSessions — tested last because it logs out all sessions -// --------------------------------------------------------------------------- - describe('useDeleteSessions', () => { let userId: string let email: string @@ -302,12 +369,12 @@ describe('useDeleteSessions', () => { const { result } = renderHook(() => useDeleteSessions(), { wrapper }) await act(async () => { - result.current.mutate() + await result.current.mutateAsync() }) await waitFor(() => expect(result.current.isSuccess).toBe(true)) expect(result.current.data).toBeDefined() - expect(result.current.data?.status).toBe(true) + expect(result.current.data?.status).toBeDefined() }) }) diff --git a/tests/account/verification.test.tsx b/tests/account/verification.test.tsx new file mode 100644 index 0000000..233d0d6 --- /dev/null +++ b/tests/account/verification.test.tsx @@ -0,0 +1,109 @@ +import { act, renderHook, waitFor, within } from '@testing-library/react' +import { afterAll, beforeAll, describe, expect, test } from 'bun:test' + +import { useCreateEmailVerification, useVerification } from '../../src' +import { + checkMail, + createTestUser, + deleteTestUser, + emptyMail, + loginUser, + renderMessage, +} from '../setup/helpers' +import { createWrapper } from '../setup/wrapper' + +describe('useVerification', () => { + let userId: string + let userEmail: string + let userPassword: string + + beforeAll(async () => { + const user = await createTestUser({ name: 'Verification Hook User' }) + userId = user.userId + userEmail = user.email + userPassword = user.password + }) + + afterAll(async () => { + await emptyMail() + await deleteTestUser(userId) + }) + + test('confirms email verification via useVerification', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + // Step 1: Create email verification request + const { result: createResult } = renderHook(() => useCreateEmailVerification(), { wrapper }) + + await act(async () => { + await createResult.current.mutateAsync({ url: 'http://localhost/verify' }) + }) + + await waitFor(() => expect(createResult.current.isSuccess).toBe(true)) + + // Wait for email delivery + await act(async () => { + await new Promise((r) => setTimeout(r, 3000)) + }) + + // Step 2: Extract verification secret from email + const message = await waitFor(async () => { + const emails = await checkMail() + expect(emails.messages.length).toBeGreaterThan(0) + return emails.messages[0] + }) + + await renderMessage(message.ID) + const emailBody = within(document.body) + + const button = emailBody.getByText(/Confirm email address/) + expect(button.getAttribute('href')).toBeDefined() + + const url = new URL(button.getAttribute('href') || '') + const secret = url.searchParams.get('secret') || '' + expect(secret).toBeTruthy() + + // Step 3: Confirm verification using useVerification hook + const { result } = renderHook(() => useVerification(), { wrapper }) + + await act(async () => { + await result.current.mutateAsync({ userId, secret }) + }) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + + expect(result.current.data).toBeDefined() + expect(result.current.data?.userId).toBe(userId) + expect(result.current.data?.secret).toBeDefined() + expect(result.current.data?.expire).toBeDefined() + + await emptyMail() + }) + + test('fails with invalid secret', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook(() => useVerification(), { wrapper }) + + await act(async () => { + result.current.mutate({ userId, secret: 'invalid-secret' }) + }) + + await waitFor(() => expect(result.current.isError).toBe(true)) + }) + + test('fails with missing userId', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook(() => useVerification(), { wrapper }) + + await act(async () => { + result.current.mutate({ userId: '', secret: 'some-secret' }) + }) + + await waitFor(() => expect(result.current.isError).toBe(true)) + }) +}) diff --git a/tests/avatars/avatars.test.tsx b/tests/avatars/avatars.test.tsx index 438f1c7..77c0ca2 100644 --- a/tests/avatars/avatars.test.tsx +++ b/tests/avatars/avatars.test.tsx @@ -11,7 +11,7 @@ import { useAvatarQR, useAvatarScreenshot, } from '../../src' -import { Browser, CreditCard, Flag } from '../../src/types' +import type { Browser, CreditCard, Flag } from '../../src/types' import { createWrapper } from '../setup/wrapper' /* diff --git a/tests/cache/invalidation.test.tsx b/tests/cache/invalidation.test.tsx index 8153054..410d07b 100644 --- a/tests/cache/invalidation.test.tsx +++ b/tests/cache/invalidation.test.tsx @@ -2,33 +2,24 @@ import { act, renderHook, waitFor } from '@testing-library/react' import { afterAll, beforeAll, describe, expect, test } from 'bun:test' import { - fragments, - getFragmentData, useAccount, useCollection, useCreateDocument, useDeleteDocument, - useLogin, useLogout, useUpdateName, useUpdatePrefs, } from '../../src' import { ID } from '../../src/types' -import { createTestDocument, createTestUser, deleteTestUser, getTestConfig } from '../setup/helpers' +import { + createTestDocument, + createTestUser, + deleteTestUser, + getTestConfig, + loginUser, +} from '../setup/helpers' import { createQueryClient, createWrapper } from '../setup/wrapper' -async function loginUser( - email: string, - password: string, - wrapper: ReturnType, -) { - const { result } = renderHook(() => useLogin(), { wrapper }) - await act(async () => { - result.current.login.mutateAsync({ email, password }) - }) - await waitFor(() => expect(result.current.login.isSuccess).toBe(true)) -} - describe('Cache invalidation', () => { let user: Awaited> @@ -48,13 +39,10 @@ describe('Cache invalidation', () => { const { result: accountResult } = renderHook(() => useAccount(), { wrapper }) - await waitFor(() => expect(accountResult.current.isSuccess).toBe(true)) - - const originalAccount = getFragmentData( - fragments.Account_UserFragment, - accountResult.current.data, - ) - const originalName = originalAccount?.name + const originalName = await waitFor(() => { + expect(accountResult.current.isSuccess).toBe(true) + return accountResult.current.data?.name + }) const newName = `Updated ${Date.now()}` const { result: updateNameResult } = renderHook(() => useUpdateName(), { wrapper }) @@ -64,15 +52,8 @@ describe('Cache invalidation', () => { }) await waitFor(() => { - const account = getFragmentData(fragments.Account_UserFragment, accountResult.current.data) - expect(account?.name).toBe(newName) + expect(accountResult.current.data.name).not.toBe(originalName) }) - - const updatedAccount = getFragmentData( - fragments.Account_UserFragment, - accountResult.current.data, - ) - expect(updatedAccount?.name).not.toBe(originalName) }) test('account prefs change invalidates account query', async () => { @@ -93,8 +74,9 @@ describe('Cache invalidation', () => { }) await waitFor(() => { - const account = getFragmentData(fragments.Account_UserFragment, accountResult.current.data) - expect(account?.prefs).toBeDefined() + expect(accountResult.current.data).toBeDefined() + const account = accountResult.current.data + expect(JSON.parse(account.prefs.data as string)).toMatchObject(newPrefs) }) }) @@ -187,7 +169,7 @@ describe('Cache invalidation', () => { await waitFor(() => expect(accountResult.current.isSuccess).toBe(true)) expect(accountResult.current.data).toBeDefined() - const account = getFragmentData(fragments.Account_UserFragment, accountResult.current.data) + const account = accountResult.current.data expect(account?.email).toBe(freshUser.email) } finally { await deleteTestUser(freshUser.userId) diff --git a/tests/databases/batch.test.tsx b/tests/databases/batch.test.tsx index 87f6229..0280953 100644 --- a/tests/databases/batch.test.tsx +++ b/tests/databases/batch.test.tsx @@ -1,22 +1,10 @@ import { act, renderHook, waitFor } from '@testing-library/react' import { afterAll, beforeAll, describe, expect, test } from 'bun:test' -import { useDecrementAttribute, useIncrementAttribute, useLogin } from '../../src' -import { createTestUser, deleteTestUser, getTestConfig } from '../setup/helpers' +import { useDecrementAttribute, useIncrementAttribute } from '../../src' +import { createTestUser, deleteTestUser, getTestConfig, loginUser } from '../setup/helpers' import { createWrapper } from '../setup/wrapper' -type Wrapper = ReturnType - -async function loginUser(email: string, password: string, wrapper: Wrapper) { - const { result } = renderHook(() => useLogin(), { wrapper }) - - await act(async () => { - result.current.login.mutateAsync({ email, password }) - }) - - await waitFor(() => expect(result.current.login.isSuccess).toBe(true)) -} - describe('Database batch & atomic hooks', () => { const config = getTestConfig() const { databaseId, collectionId } = config @@ -47,7 +35,7 @@ describe('Database batch & atomic hooks', () => { const { result } = renderHook(() => useIncrementAttribute(), { wrapper }) await act(async () => { - result.current.mutateAsync({ + await result.current.mutateAsync({ databaseId, collectionId, documentId: doc.$id, @@ -76,7 +64,7 @@ describe('Database batch & atomic hooks', () => { const { result } = renderHook(() => useDecrementAttribute(), { wrapper }) await act(async () => { - result.current.mutateAsync({ + await result.current.mutateAsync({ databaseId, collectionId, documentId: doc.$id, diff --git a/tests/databases/collection.test.tsx b/tests/databases/collection.test.tsx index bbdf75a..8db46cc 100644 --- a/tests/databases/collection.test.tsx +++ b/tests/databases/collection.test.tsx @@ -1,13 +1,16 @@ -import { act, renderHook, waitFor } from '@testing-library/react' -import { afterAll, beforeAll, describe, expect, test } from 'bun:test' +import { renderHook, waitFor } from '@testing-library/react' +import { Channel, Query } from 'appwrite' +import { afterAll, beforeAll, describe, expect, spyOn, test } from 'bun:test' -import { useCollection, useLogin, useSuspenseCollection } from '../../src' +import { useCollection, useQueryClient, useSuspenseCollection } from '../../src' +import { triggerRealtimeEvent } from '../__mocks__/Realtime' import { createTestDocument, createTestUser, deleteTestDocument, deleteTestUser, getTestConfig, + loginUser, } from '../setup/helpers' import { createWrapper } from '../setup/wrapper' @@ -17,20 +20,6 @@ interface TestDocumentData { active?: boolean } -async function loginUser( - email: string, - password: string, - wrapper: ReturnType, -): Promise { - const { result } = renderHook(() => useLogin(), { wrapper }) - - await act(async () => { - result.current.login.mutateAsync({ email, password }) - }) - - await waitFor(() => expect(result.current.login.isSuccess).toBe(true)) -} - describe('Collection query hooks', () => { const config = getTestConfig() const { databaseId, collectionId } = config @@ -91,12 +80,14 @@ describe('Collection query hooks', () => { const wrapper = createWrapper() await loginUser(userEmail, userPassword, wrapper) + const knownNames = testDocuments.map((d) => d.name) + const { result } = renderHook( () => useCollection({ databaseId, collectionId, - queries: [], + queries: [Query.equal('name', knownNames)], }), { wrapper }, ) @@ -104,10 +95,9 @@ describe('Collection query hooks', () => { await waitFor(() => expect(result.current.isSuccess).toBe(true)) const documents = result.current.documents ?? [] - expect(documents.length).toBeGreaterThanOrEqual(testDocuments.length) + expect(documents.length).toBe(testDocuments.length) // Verify that the returned documents have parsed fields (not raw JSON strings) - const knownNames = testDocuments.map((d) => d.name) const matchedDocuments = documents.filter((doc) => knownNames.includes(doc.name)) expect(matchedDocuments.length).toBe(testDocuments.length) @@ -126,7 +116,7 @@ describe('Collection query hooks', () => { useCollection({ databaseId, collectionId, - queries: [], + queries: [Query.equal('name', ['Alice'])], }), { wrapper }, ) @@ -205,6 +195,49 @@ describe('Collection query hooks', () => { expect(result.current.documents).toBeDefined() expect(result.current.total).toBeGreaterThanOrEqual(testDocuments.length) }) + + test('is listening for realtime updates', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result: queryClient } = renderHook(() => useQueryClient(), { wrapper }) + + const spy = spyOn(queryClient.current, 'setQueryData') + + const { result } = renderHook( + () => + useCollection({ + databaseId, + collectionId, + queries: [], + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + + // Standard react-query properties should be present + expect(result.current.isLoading).toBe(false) + expect(result.current.isError).toBe(false) + expect(result.current.data).toBeDefined() + + triggerRealtimeEvent( + Channel.tablesdb(databaseId).table(collectionId).row(), + { + $id: 'some-doc-id', + name: 'Updated Name', + age: 20, + }, + ['databases.test-db.collections.test-collection.documents.some-doc-id.update'], + ) + + expect(spy).toHaveBeenCalledWith( + ['appwrite', 'databases', databaseId, 'collections', collectionId, 'documents', 'some-doc-id'], + expect.objectContaining({ + name: 'Updated Name', + }), + ) + }) }) describe('useSuspenseCollection', () => { @@ -218,6 +251,7 @@ describe('Collection query hooks', () => { databaseId, collectionId, queries: [], + subscribe: false, }), { wrapper }, ) @@ -240,7 +274,7 @@ describe('Collection query hooks', () => { useSuspenseCollection({ databaseId, collectionId, - queries: [], + queries: [Query.equal('name', ['Bob'])], }), { wrapper }, ) @@ -275,5 +309,43 @@ describe('Collection query hooks', () => { expect(typeof result.current.total).toBe('number') expect(result.current.total).toBeGreaterThanOrEqual(3) }) + + test('is listening for realtime updates', async () => { + const wrapper = createWrapper({ suspense: true }) + await loginUser(userEmail, userPassword, wrapper) + + const { result: queryClient } = renderHook(() => useQueryClient(), { wrapper }) + + const spy = spyOn(queryClient.current, 'setQueryData') + + const { result } = renderHook( + () => + useSuspenseCollection({ + databaseId, + collectionId, + queries: [], + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + + triggerRealtimeEvent( + Channel.tablesdb(databaseId).table(collectionId).row(), + { + $id: 'some-doc-id', + name: 'Updated Name', + age: 20, + }, + ['databases.test-db.collections.test-collection.documents.some-doc-id.update'], + ) + + expect(spy).toHaveBeenCalledWith( + ['appwrite', 'databases', databaseId, 'collections', collectionId, 'documents', 'some-doc-id'], + expect.objectContaining({ + name: 'Updated Name', + }), + ) + }) }) }) diff --git a/tests/databases/documents.test.tsx b/tests/databases/documents.test.tsx index 4aa3b7f..a9aed97 100644 --- a/tests/databases/documents.test.tsx +++ b/tests/databases/documents.test.tsx @@ -1,21 +1,25 @@ import { act, renderHook, waitFor } from '@testing-library/react' -import { afterAll, beforeAll, describe, expect, test } from 'bun:test' +import { Channel } from 'appwrite' +import { afterAll, beforeAll, describe, expect, spyOn, test } from 'bun:test' import { useCreateDocument, useDeleteDocument, useDocument, - useLogin, + useQueryClient, + useSuspenseDocument, useUpdateDocument, useUpsertDocument, } from '../../src' import { ID } from '../../src/types' +import { triggerRealtimeEvent } from '../__mocks__/Realtime' import { createTestDocument, createTestUser, deleteTestDocument, deleteTestUser, getTestConfig, + loginUser, } from '../setup/helpers' import { createWrapper } from '../setup/wrapper' @@ -25,20 +29,6 @@ interface TestDocumentData { active?: boolean } -async function loginUser( - email: string, - password: string, - wrapper: ReturnType, -): Promise { - const { result } = renderHook(() => useLogin(), { wrapper }) - - await act(async () => { - result.current.login.mutateAsync({ email, password }) - }) - - await waitFor(() => expect(result.current.login.isSuccess).toBe(true)) -} - describe('Document CRUD hooks', () => { const config = getTestConfig() const { databaseId, collectionId } = config @@ -71,7 +61,7 @@ describe('Document CRUD hooks', () => { const documentId = ID.unique() await act(async () => { - result.current.mutateAsync({ + await result.current.mutateAsync({ databaseId, collectionId, documentId, @@ -96,7 +86,7 @@ describe('Document CRUD hooks', () => { const documentId = ID.unique() await act(async () => { - result.current.mutateAsync({ + await result.current.mutateAsync({ databaseId, collectionId, documentId, @@ -192,14 +182,31 @@ describe('Document CRUD hooks', () => { createdDocumentIds.push(documentId) }) - test('updates a document and returns updated data', async () => { + test('updates a document and returns updated data as well as updating the realtime subscription', async () => { const wrapper = createWrapper() await loginUser(userEmail, userPassword, wrapper) - const { result } = renderHook(() => useUpdateDocument(), { wrapper }) + const { result } = renderHook(() => useUpdateDocument(), { wrapper }) + const { result: queryClient } = renderHook(() => useQueryClient(), { wrapper }) + + const spy = spyOn(queryClient.current, 'setQueryData') + + const { result: readResult } = renderHook( + () => + useDocument({ + databaseId, + collectionId, + documentId, + }), + { wrapper }, + ) + + await waitFor(() => expect(readResult.current.isSuccess).toBe(true)) + + expect(readResult.current.data?.name).toBe('Update Test') await act(async () => { - result.current.mutateAsync({ + await result.current.mutateAsync({ databaseId, collectionId, documentId, @@ -209,6 +216,22 @@ describe('Document CRUD hooks', () => { await waitFor(() => expect(result.current.isSuccess).toBe(true)) + triggerRealtimeEvent( + Channel.tablesdb(databaseId).table(collectionId).row(documentId).update(), + { + _id: documentId, + name: 'Updated Name', + age: 20, + }, + ) + + expect(spy).toHaveBeenCalledWith( + ['appwrite', 'databases', databaseId, 'collections', collectionId, 'documents', documentId], + expect.objectContaining({ + name: 'Updated Name', + }), + ) + expect(result.current.data).toBeDefined() }) @@ -216,12 +239,12 @@ describe('Document CRUD hooks', () => { const wrapper = createWrapper() await loginUser(userEmail, userPassword, wrapper) - const { result: updateResult } = renderHook(() => useUpdateDocument(), { + const { result: updateResult } = renderHook(() => useUpdateDocument(), { wrapper, }) await act(async () => { - updateResult.current.mutateAsync({ + await updateResult.current.mutateAsync({ databaseId, collectionId, documentId, @@ -259,7 +282,7 @@ describe('Document CRUD hooks', () => { const documentId = ID.unique() await act(async () => { - result.current.mutateAsync({ + await result.current.mutateAsync({ databaseId, collectionId, documentId, @@ -287,7 +310,7 @@ describe('Document CRUD hooks', () => { const { result } = renderHook(() => useUpsertDocument(), { wrapper }) await act(async () => { - result.current.mutateAsync({ + await result.current.mutateAsync({ databaseId, collectionId, documentId: existingDocId, @@ -313,7 +336,7 @@ describe('Document CRUD hooks', () => { const { result } = renderHook(() => useDeleteDocument(), { wrapper }) await act(async () => { - result.current.mutateAsync({ + await result.current.mutateAsync({ databaseId, collectionId, documentId: doc.$id, @@ -343,4 +366,95 @@ describe('Document CRUD hooks', () => { await waitFor(() => expect(result.current.isError).toBe(true)) }) }) + + describe('useSuspenseDocument', () => { + let documentId: string + + beforeAll(async () => { + const doc = await createTestDocument({ name: 'Suspense Test', age: 99, active: true }) + documentId = doc.$id + createdDocumentIds.push(documentId) + }) + + test('loads a document with suspense boundary', async () => { + const wrapper = createWrapper({ suspense: true }) + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useSuspenseDocument({ + databaseId, + collectionId, + documentId, + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.data).toBeDefined()) + + expect((result.current.data as any)?._id).toBe(documentId) + expect(result.current.data?.name).toBe('Suspense Test') + expect(result.current.data?.age).toBe(99) + expect(result.current.data?.active).toBe(true) + }) + + test('returns parsed document fields from JSON data through suspense', async () => { + const wrapper = createWrapper({ suspense: true }) + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useSuspenseDocument({ + databaseId, + collectionId, + documentId, + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.data).toBeDefined()) + + expect(result.current.data?.name).toEqual('Suspense Test') + expect(result.current.data?.age).toEqual(99) + expect(result.current.data?.active).toEqual(true) + }) + + test('is listening for realtime updates', async () => { + const wrapper = createWrapper({ suspense: true }) + await loginUser(userEmail, userPassword, wrapper) + + const { result: queryClient } = renderHook(() => useQueryClient(), { wrapper }) + + const spy = spyOn(queryClient.current, 'setQueryData') + + const { result } = renderHook( + () => + useSuspenseDocument({ + databaseId, + collectionId, + documentId, + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.data).toBeDefined()) + + triggerRealtimeEvent( + Channel.tablesdb(databaseId).table(collectionId).row(documentId).update(), + { + $id: documentId, + name: 'Realtime Updated', + age: 100, + }, + [`databases.${databaseId}.collections.${collectionId}.documents.${documentId}.update`], + ) + + expect(spy).toHaveBeenCalledWith( + ['appwrite', 'databases', databaseId, 'collections', collectionId, 'documents', documentId], + expect.objectContaining({ + name: 'Realtime Updated', + }), + ) + }) + }) }) diff --git a/tests/databases/optimistic.test.tsx b/tests/databases/optimistic.test.tsx new file mode 100644 index 0000000..7782342 --- /dev/null +++ b/tests/databases/optimistic.test.tsx @@ -0,0 +1,446 @@ +import { act, renderHook, waitFor } from '@testing-library/react' +import { afterAll, beforeAll, describe, expect, test } from 'bun:test' + +import { + Keys, + useDecrementAttribute, + useDeleteDocument, + useDocument, + useIncrementAttribute, + useQueryClient, + useUpdateDocument, + useUpsertDocument, +} from '../../src' +import { + createTestDocument, + createTestUser, + deleteTestDocument, + deleteTestUser, + getTestConfig, + loginUser, +} from '../setup/helpers' +import { createWrapper } from '../setup/wrapper' + +interface TestDocumentData { + name: string + age?: number + active?: boolean + score?: number +} + +describe('Optimistic update hooks', () => { + const config = getTestConfig() + const { databaseId, collectionId } = config + let userId: string + let userEmail: string + let userPassword: string + const createdDocumentIds: string[] = [] + + beforeAll(async () => { + const user = await createTestUser({ name: 'Optimistic User' }) + userId = user.userId + userEmail = user.email + userPassword = user.password + }) + + afterAll(async () => { + for (const docId of createdDocumentIds) { + await deleteTestDocument(docId).catch(() => {}) + } + await deleteTestUser(userId) + }) + + describe('useUpdateDocument optimistic', () => { + test('optimistically updates the document cache before server responds', async () => { + const doc = await createTestDocument({ name: 'Optimistic Update', age: 25 }) + createdDocumentIds.push(doc.$id) + + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + // First, populate the document cache + const { result: readResult } = renderHook( + () => + useDocument({ + databaseId, + collectionId, + documentId: doc.$id, + }), + { wrapper }, + ) + + await waitFor(() => expect(readResult.current.isSuccess).toBe(true)) + expect(readResult.current.data?.name).toBe('Optimistic Update') + + const { result: queryClient } = renderHook(() => useQueryClient(), { wrapper }) + + // Perform the mutation + const { result: mutation } = renderHook(() => useUpdateDocument(), { wrapper }) + + await act(async () => { + mutation.current.mutate({ + databaseId, + collectionId, + documentId: doc.$id, + data: { name: 'Instantly Updated' }, + }) + }) + + // The cache should be optimistically updated immediately (before server response) + const entries = queryClient.current.getQueriesData({ + queryKey: Keys.database(databaseId).collection(collectionId).document(doc.$id).key(), + }) + + expect(entries.length).toBeGreaterThan(0) + const cachedDoc = entries[0][1] as TestDocumentData | undefined + + expect(cachedDoc?.name).toBe('Instantly Updated') + // Other fields should be preserved + expect(cachedDoc?.age).toBe(25) + + await waitFor(() => expect(mutation.current.isSuccess).toBe(true)) + }) + + test('preserves unmodified fields during optimistic update', async () => { + const doc = await createTestDocument({ name: 'Partial Update', age: 40, active: true }) + createdDocumentIds.push(doc.$id) + + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result: readResult } = renderHook( + () => + useDocument({ + databaseId, + collectionId, + documentId: doc.$id, + }), + { wrapper }, + ) + + await waitFor(() => expect(readResult.current.isSuccess).toBe(true)) + + const { result: queryClient } = renderHook(() => useQueryClient(), { wrapper }) + const { result: mutation } = renderHook(() => useUpdateDocument(), { wrapper }) + + // Only update name, leave age and active untouched + await act(async () => { + mutation.current.mutate({ + databaseId, + collectionId, + documentId: doc.$id, + data: { name: 'Only Name Changed' }, + }) + }) + + const entries = queryClient.current.getQueriesData({ + queryKey: Keys.database(databaseId).collection(collectionId).document(doc.$id).key(), + }) + + expect(entries.length).toBeGreaterThan(0) + const cachedDoc = entries[0][1] as TestDocumentData | undefined + + expect(cachedDoc?.name).toBe('Only Name Changed') + expect(cachedDoc?.age).toBe(40) + expect(cachedDoc?.active).toBe(true) + + await waitFor(() => expect(mutation.current.isSuccess).toBe(true)) + }) + }) + + describe('useDeleteDocument optimistic', () => { + test('optimistically removes document from cache', async () => { + const doc = await createTestDocument({ name: 'Optimistic Delete' }) + createdDocumentIds.push(doc.$id) + + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + // Populate cache + const { result: readResult } = renderHook( + () => + useDocument({ + databaseId, + collectionId, + documentId: doc.$id, + }), + { wrapper }, + ) + + await waitFor(() => expect(readResult.current.isSuccess).toBe(true)) + + const { result: queryClient } = renderHook(() => useQueryClient(), { wrapper }) + + const documentKeyPrefix = [ + 'appwrite', + 'databases', + databaseId, + 'collections', + collectionId, + 'documents', + doc.$id, + ] + + // Verify cache is populated + const beforeEntries = queryClient.current.getQueriesData({ queryKey: documentKeyPrefix }) + expect(beforeEntries.length).toBeGreaterThan(0) + + const { result: mutation } = renderHook(() => useDeleteDocument(), { wrapper }) + + await act(async () => { + mutation.current.mutate({ + databaseId, + collectionId, + documentId: doc.$id, + }) + }) + + // Cache should be immediately cleared + const afterEntries = queryClient.current.getQueriesData({ queryKey: documentKeyPrefix }) + const hasData = afterEntries.some(([, data]) => data !== undefined) + expect(hasData).toBe(false) + + await waitFor(() => expect(mutation.current.isSuccess).toBe(true)) + + // Remove from cleanup list since already deleted + const idx = createdDocumentIds.indexOf(doc.$id) + if (idx !== -1) createdDocumentIds.splice(idx, 1) + }) + }) + + describe('useUpsertDocument optimistic', () => { + test('optimistically updates existing document cache', async () => { + const doc = await createTestDocument({ name: 'Optimistic Upsert', age: 50 }) + createdDocumentIds.push(doc.$id) + + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + // Populate cache + const { result: readResult } = renderHook( + () => + useDocument({ + databaseId, + collectionId, + documentId: doc.$id, + }), + { wrapper }, + ) + + await waitFor(() => expect(readResult.current.isSuccess).toBe(true)) + + const { result: queryClient } = renderHook(() => useQueryClient(), { wrapper }) + + const { result: mutation } = renderHook(() => useUpsertDocument(), { wrapper }) + + await act(async () => { + mutation.current.mutate({ + databaseId, + collectionId, + documentId: doc.$id, + data: { name: 'Upserted Instantly', age: 51 }, + }) + }) + + const entries = queryClient.current.getQueriesData({ + queryKey: Keys.database(databaseId).collection(collectionId).document(doc.$id).key(), + }) + + expect(entries.length).toBeGreaterThan(0) + const cachedDoc = entries[0][1] as TestDocumentData | undefined + + expect(cachedDoc?.name).toBe('Upserted Instantly') + expect(cachedDoc?.age).toBe(51) + + await waitFor(() => expect(mutation.current.isSuccess).toBe(true)) + }) + }) + + describe('useIncrementAttribute optimistic', () => { + test('optimistically increments the attribute in cache', async () => { + const doc = await createTestDocument({ name: 'Inc Test', age: 10 }) + createdDocumentIds.push(doc.$id) + + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + // Populate cache + const { result: readResult } = renderHook( + () => + useDocument({ + databaseId, + collectionId, + documentId: doc.$id, + }), + { wrapper }, + ) + + await waitFor(() => expect(readResult.current.isSuccess).toBe(true)) + expect(readResult.current.data?.age).toBe(10) + + const { result: queryClient } = renderHook(() => useQueryClient(), { wrapper }) + + const { result: mutation } = renderHook(() => useIncrementAttribute(), { wrapper }) + + await act(async () => { + mutation.current.mutate({ + databaseId, + collectionId, + documentId: doc.$id, + attribute: 'age', + value: 5, + }) + }) + + const incEntries = queryClient.current.getQueriesData({ + queryKey: Keys.database(databaseId).collection(collectionId).document(doc.$id).key(), + }) + + expect(incEntries.length).toBeGreaterThan(0) + const incCachedDoc = incEntries[0][1] as TestDocumentData | undefined + + expect(incCachedDoc?.age).toBe(15) + + await waitFor(() => expect(mutation.current.isSuccess).toBe(true)) + }) + + test('respects max bound in optimistic update', async () => { + const doc = await createTestDocument({ name: 'Max Test', age: 95 }) + createdDocumentIds.push(doc.$id) + + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result: readResult } = renderHook( + () => + useDocument({ + databaseId, + collectionId, + documentId: doc.$id, + }), + { wrapper }, + ) + + await waitFor(() => expect(readResult.current.isSuccess).toBe(true)) + + const { result: queryClient } = renderHook(() => useQueryClient(), { wrapper }) + const { result: mutation } = renderHook(() => useIncrementAttribute(), { wrapper }) + + await act(async () => { + mutation.current.mutate({ + databaseId, + collectionId, + documentId: doc.$id, + attribute: 'age', + value: 10, + max: 100, + }) + }) + + const maxEntries = queryClient.current.getQueriesData({ + queryKey: Keys.database(databaseId).collection(collectionId).document(doc.$id).key(), + }) + + expect(maxEntries.length).toBeGreaterThan(0) + const maxCachedDoc = maxEntries[0][1] as TestDocumentData | undefined + + // 95 + 10 = 105, but max is 100 + expect(maxCachedDoc?.age).toBe(100) + + await waitFor(() => expect(mutation.current.isSuccess || mutation.current.isError).toBe(true)) + }) + }) + + describe('useDecrementAttribute optimistic', () => { + test('optimistically decrements the attribute in cache', async () => { + const doc = await createTestDocument({ name: 'Dec Test', age: 20 }) + createdDocumentIds.push(doc.$id) + + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result: readResult } = renderHook( + () => + useDocument({ + databaseId, + collectionId, + documentId: doc.$id, + }), + { wrapper }, + ) + + await waitFor(() => expect(readResult.current.isSuccess).toBe(true)) + expect(readResult.current.data?.age).toBe(20) + + const { result: queryClient } = renderHook(() => useQueryClient(), { wrapper }) + const { result: mutation } = renderHook(() => useDecrementAttribute(), { wrapper }) + + await act(async () => { + mutation.current.mutate({ + databaseId, + collectionId, + documentId: doc.$id, + attribute: 'age', + value: 7, + }) + }) + + const decEntries = queryClient.current.getQueriesData({ + queryKey: Keys.database(databaseId).collection(collectionId).document(doc.$id).key(), + }) + + expect(decEntries.length).toBeGreaterThan(0) + const decCachedDoc = decEntries[0][1] as TestDocumentData | undefined + + expect(decCachedDoc?.age).toBe(13) + + await waitFor(() => expect(mutation.current.isSuccess).toBe(true)) + }) + + test('respects min bound in optimistic update', async () => { + const doc = await createTestDocument({ name: 'Min Test', age: 3 }) + createdDocumentIds.push(doc.$id) + + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result: readResult } = renderHook( + () => + useDocument({ + databaseId, + collectionId, + documentId: doc.$id, + }), + { wrapper }, + ) + + await waitFor(() => expect(readResult.current.isSuccess).toBe(true)) + + const { result: queryClient } = renderHook(() => useQueryClient(), { wrapper }) + const { result: mutation } = renderHook(() => useDecrementAttribute(), { wrapper }) + + await act(async () => { + mutation.current.mutate({ + databaseId, + collectionId, + documentId: doc.$id, + attribute: 'age', + value: 10, + min: 0, + }) + }) + + const minEntries = queryClient.current.getQueriesData({ + queryKey: Keys.database(databaseId).collection(collectionId).document(doc.$id).key(), + }) + + expect(minEntries.length).toBeGreaterThan(0) + const minCachedDoc = minEntries[0][1] as TestDocumentData | undefined + + // 3 - 10 = -7, but min is 0 + expect(minCachedDoc?.age).toBe(0) + + await waitFor(() => expect(mutation.current.isSuccess || mutation.current.isError).toBe(true)) + }) + }) +}) diff --git a/tests/databases/pagination.test.tsx b/tests/databases/pagination.test.tsx new file mode 100644 index 0000000..8877fa3 --- /dev/null +++ b/tests/databases/pagination.test.tsx @@ -0,0 +1,652 @@ +import { act, renderHook, waitFor } from '@testing-library/react' +import { afterAll, beforeAll, describe, expect, test } from 'bun:test' + +import { + useCollectionWithPagination, + useInfiniteCollection, + useSuspenseCollectionWithPagination, +} from '../../src' +import { + createTestDocument, + createTestUser, + deleteTestDocument, + deleteTestUser, + getTestConfig, + loginUser, +} from '../setup/helpers' +import { createWrapper } from '../setup/wrapper' + +interface TestDocumentData { + name: string + age?: number +} + +describe('Pagination hooks', () => { + const config = getTestConfig() + const { databaseId, collectionId } = config + let userId: string + let userEmail: string + let userPassword: string + const createdDocumentIds: string[] = [] + + // Create 7 documents to test pagination with small page sizes + beforeAll(async () => { + const user = await createTestUser({ name: 'Pagination User' }) + userId = user.userId + userEmail = user.email + userPassword = user.password + + for (let i = 1; i <= 7; i++) { + const doc = await createTestDocument( + { name: `Page Item ${i}`, age: i }, + `pagination-doc-${i}`, + ) + createdDocumentIds.push(doc.$id) + } + }) + + afterAll(async () => { + for (const docId of createdDocumentIds) { + await deleteTestDocument(docId).catch(() => {}) + } + await deleteTestUser(userId) + }) + + describe('useCollectionWithPagination', () => { + test('returns first page of documents with correct limit', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useCollectionWithPagination({ + databaseId, + collectionId, + queries: [], + limit: 3, + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.documents.length).toBeGreaterThan(0)) + + expect(result.current.documents.length).toBeLessThanOrEqual(3) + expect(result.current.page).toBe(1) + expect(result.current.hasPreviousPage).toBe(false) + }) + + test('hasNextPage is true when more documents exist', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useCollectionWithPagination({ + databaseId, + collectionId, + queries: [], + limit: 3, + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.documents.length).toBeGreaterThan(0)) + + // We have 7+ docs with limit=3, so there must be a next page + expect(result.current.hasNextPage).toBe(true) + expect(result.current.total).toBeGreaterThanOrEqual(7) + }) + + test('nextPage advances to the next page', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useCollectionWithPagination({ + databaseId, + collectionId, + queries: [], + limit: 3, + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.documents.length).toBeGreaterThan(0)) + + const firstPageDocs = [...result.current.documents] + + act(() => { + result.current.nextPage() + }) + + expect(result.current.page).toBe(2) + + await waitFor(() => expect(result.current.documents.length).toBeGreaterThan(0)) + + expect(result.current.hasPreviousPage).toBe(true) + + // Page 2 documents should be different from page 1 + const secondPageIds = result.current.documents.map((d: any) => d._id) + const firstPageIds = firstPageDocs.map((d: any) => d._id) + const overlap = secondPageIds.filter((id: string) => firstPageIds.includes(id)) + expect(overlap.length).toBe(0) + }) + + test('previousPage goes back', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useCollectionWithPagination({ + databaseId, + collectionId, + queries: [], + limit: 3, + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.documents.length).toBeGreaterThan(0)) + + // Go to page 2 + act(() => { + result.current.nextPage() + }) + expect(result.current.page).toBe(2) + + // Go back to page 1 + act(() => { + result.current.previousPage() + }) + expect(result.current.page).toBe(1) + expect(result.current.hasPreviousPage).toBe(false) + }) + + test('handlePageChange jumps to a specific page', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useCollectionWithPagination({ + databaseId, + collectionId, + queries: [], + limit: 3, + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.documents.length).toBeGreaterThan(0)) + + act(() => { + result.current.handlePageChange(3) + }) + expect(result.current.page).toBe(3) + + await waitFor(() => expect(result.current.documents.length).toBeGreaterThanOrEqual(0)) + }) + + test('handlePageChange ignores invalid page numbers', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useCollectionWithPagination({ + databaseId, + collectionId, + queries: [], + limit: 3, + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.documents.length).toBeGreaterThan(0)) + + // Page 0 and negative should be ignored + act(() => { + result.current.handlePageChange(0) + }) + expect(result.current.page).toBe(1) + + act(() => { + result.current.handlePageChange(-1) + }) + expect(result.current.page).toBe(1) + }) + + test('previousPage does nothing on first page', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useCollectionWithPagination({ + databaseId, + collectionId, + queries: [], + limit: 3, + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.documents.length).toBeGreaterThan(0)) + + act(() => { + result.current.previousPage() + }) + expect(result.current.page).toBe(1) + }) + + test('exposes loading states', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useCollectionWithPagination({ + databaseId, + collectionId, + queries: [], + limit: 3, + }), + { wrapper }, + ) + + // Should eventually resolve + await waitFor(() => expect(result.current.isLoading).toBe(false)) + + expect(result.current.isError).toBe(false) + expect(result.current.error).toBeNull() + }) + }) + + describe('useSuspenseCollectionWithPagination', () => { + test('returns first page of documents with correct limit', async () => { + const wrapper = createWrapper({ suspense: true }) + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useSuspenseCollectionWithPagination({ + databaseId, + collectionId, + queries: [], + limit: 3, + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.documents.length).toBeGreaterThan(0)) + + expect(result.current.documents.length).toBeLessThanOrEqual(3) + expect(result.current.page).toBe(1) + expect(result.current.hasPreviousPage).toBe(false) + }) + + test('hasNextPage is true when more documents exist', async () => { + const wrapper = createWrapper({ suspense: true }) + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useSuspenseCollectionWithPagination({ + databaseId, + collectionId, + queries: [], + limit: 3, + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.documents.length).toBeGreaterThan(0)) + + // We have 7+ docs with limit=3, so there must be a next page + expect(result.current.hasNextPage).toBe(true) + expect(result.current.total).toBeGreaterThanOrEqual(7) + }) + + test('nextPage advances to the next page', async () => { + const wrapper = createWrapper({ suspense: true }) + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useSuspenseCollectionWithPagination({ + databaseId, + collectionId, + queries: [], + limit: 3, + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.documents.length).toBeGreaterThan(0)) + + const firstPageDocs = [...result.current.documents] + + act(() => { + result.current.nextPage() + }) + + // Suspense re-suspends while fetching page 2, so wait for it + await waitFor(() => expect(result.current.page).toBe(2)) + await waitFor(() => expect(result.current.documents.length).toBeGreaterThan(0)) + + expect(result.current.hasPreviousPage).toBe(true) + + // Page 2 documents should be different from page 1 + const secondPageIds = result.current.documents.map((d: any) => d._id) + const firstPageIds = firstPageDocs.map((d: any) => d._id) + const overlap = secondPageIds.filter((id: string) => firstPageIds.includes(id)) + expect(overlap.length).toBe(0) + }) + + test('previousPage goes back', async () => { + const wrapper = createWrapper({ suspense: true }) + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useSuspenseCollectionWithPagination({ + databaseId, + collectionId, + queries: [], + limit: 3, + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.documents.length).toBeGreaterThan(0)) + + // Go to page 2 + act(() => { + result.current.nextPage() + }) + await waitFor(() => expect(result.current.page).toBe(2)) + + // Go back to page 1 + act(() => { + result.current.previousPage() + }) + await waitFor(() => expect(result.current.page).toBe(1)) + expect(result.current.hasPreviousPage).toBe(false) + }) + + test('handlePageChange jumps to a specific page', async () => { + const wrapper = createWrapper({ suspense: true }) + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useSuspenseCollectionWithPagination({ + databaseId, + collectionId, + queries: [], + limit: 3, + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.documents.length).toBeGreaterThan(0)) + + act(() => { + result.current.handlePageChange(3) + }) + await waitFor(() => expect(result.current.page).toBe(3)) + + await waitFor(() => expect(result.current.documents.length).toBeGreaterThanOrEqual(0)) + }) + + test('handlePageChange ignores invalid page numbers', async () => { + const wrapper = createWrapper({ suspense: true }) + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useSuspenseCollectionWithPagination({ + databaseId, + collectionId, + queries: [], + limit: 3, + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.documents.length).toBeGreaterThan(0)) + + // Page 0 and negative should be ignored + act(() => { + result.current.handlePageChange(0) + }) + expect(result.current.page).toBe(1) + + act(() => { + result.current.handlePageChange(-1) + }) + expect(result.current.page).toBe(1) + }) + + test('previousPage does nothing on first page', async () => { + const wrapper = createWrapper({ suspense: true }) + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useSuspenseCollectionWithPagination({ + databaseId, + collectionId, + queries: [], + limit: 3, + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.documents.length).toBeGreaterThan(0)) + + act(() => { + result.current.previousPage() + }) + expect(result.current.page).toBe(1) + }) + + test('exposes loading states', async () => { + const wrapper = createWrapper({ suspense: true }) + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useSuspenseCollectionWithPagination({ + databaseId, + collectionId, + queries: [], + limit: 3, + }), + { wrapper }, + ) + + // Should eventually resolve + await waitFor(() => expect(result.current.isLoading).toBe(false)) + + expect(result.current.isError).toBe(false) + expect(result.current.error).toBeNull() + }) + }) + + describe('useInfiniteCollection', () => { + test('returns first page of documents', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useInfiniteCollection({ + databaseId, + collectionId, + queries: [], + limit: 3, + subscribe: false, + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.documents.length).toBeGreaterThan(0)) + + expect(result.current.documents.length).toBeLessThanOrEqual(3) + expect(result.current.hasNextPage).toBe(true) + expect(result.current.total).toBeGreaterThanOrEqual(7) + }) + + test('fetchNextPage accumulates documents across pages', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useInfiniteCollection({ + databaseId, + collectionId, + queries: [], + limit: 3, + subscribe: false, + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.documents.length).toBe(3)) + + const firstPageCount = result.current.documents.length + + // Fetch page 2 + act(() => { + result.current.fetchNextPage() + }) + + await waitFor(() => expect(result.current.documents.length).toBeGreaterThan(firstPageCount)) + + // Should now have page1 + page2 documents accumulated + expect(result.current.documents.length).toBe(6) + }) + + test('fetchNextPage does nothing when no more pages', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useInfiniteCollection({ + databaseId, + collectionId, + queries: [], + limit: 100, + subscribe: false, + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.documents.length).toBeGreaterThan(0)) + + expect(result.current.hasNextPage).toBe(false) + + const docCount = result.current.documents.length + + act(() => { + result.current.fetchNextPage() + }) + + // Count should not change + expect(result.current.documents.length).toBe(docCount) + }) + + test('isFetchingNextPage is true while loading a subsequent page', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useInfiniteCollection({ + databaseId, + collectionId, + queries: [], + limit: 3, + subscribe: false, + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.documents.length).toBe(3)) + + // isFetchingNextPage should be false on first page + expect(result.current.isFetchingNextPage).toBe(false) + + act(() => { + result.current.fetchNextPage() + }) + + // After fetching completes + await waitFor(() => expect(result.current.isFetchingNextPage).toBe(false)) + expect(result.current.documents.length).toBe(6) + }) + + test('reset clears accumulated documents and returns to page 1', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useInfiniteCollection({ + databaseId, + collectionId, + queries: [], + limit: 3, + subscribe: false, + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.documents.length).toBe(3)) + + // Load a second page + act(() => { + result.current.fetchNextPage() + }) + + await waitFor(() => expect(result.current.documents.length).toBe(6)) + + // Reset + act(() => { + result.current.reset() + }) + + await waitFor(() => expect(result.current.documents.length).toBe(3)) + + expect(result.current.documents.length).toBe(3) + expect(result.current.hasNextPage).toBe(true) + }) + + test('exposes loading and error states', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useInfiniteCollection({ + databaseId, + collectionId, + queries: [], + limit: 3, + subscribe: false, + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.isLoading).toBe(false)) + + expect(result.current.isError).toBe(false) + expect(result.current.error).toBeNull() + }) + }) +}) diff --git a/tests/databases/transactions.test.tsx b/tests/databases/transactions.test.tsx new file mode 100644 index 0000000..b870903 --- /dev/null +++ b/tests/databases/transactions.test.tsx @@ -0,0 +1,341 @@ +import { act, renderHook, waitFor } from '@testing-library/react' +import { afterAll, beforeAll, describe, expect, test } from 'bun:test' + +import { + useCreateOperations, + useCreateTransaction, + useDeleteTransaction, + useGetTransaction, + useListTransactions, + useUpdateTransaction, +} from '../../src' +import { createTestUser, deleteTestUser, getTestConfig, loginUser } from '../setup/helpers' +import { createWrapper } from '../setup/wrapper' + +describe('Database transaction hooks', () => { + const config = getTestConfig() + const { databaseId, collectionId } = config + let userId: string + let userEmail: string + let userPassword: string + + beforeAll(async () => { + const user = await createTestUser({ name: 'Transaction User' }) + userId = user.userId + userEmail = user.email + userPassword = user.password + }) + + afterAll(async () => { + await deleteTestUser(userId) + }) + + describe('useCreateTransaction', () => { + test('creates a transaction and returns transaction data', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result, unmount } = renderHook(() => useCreateTransaction(), { wrapper }) + + await act(async () => { + await result.current.mutateAsync({}) + }) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + + expect(result.current.data).toBeDefined() + expect(result.current.data?._id).toBeDefined() + expect(result.current.data?.status).toBeDefined() + + const transactionId = result.current.data!._id! + unmount() + + // Clean up: delete the transaction + const { result: deleteResult, unmount: unmountDelete } = renderHook(() => useDeleteTransaction(), { wrapper }) + await act(async () => { + await deleteResult.current.mutateAsync({ transactionId }) + }) + unmountDelete() + }) + + test('creates a transaction with custom TTL', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result, unmount } = renderHook(() => useCreateTransaction(), { wrapper }) + + await act(async () => { + await result.current.mutateAsync({ ttl: 60 }) + }) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + + expect(result.current.data).toBeDefined() + expect(result.current.data?._id).toBeDefined() + expect(result.current.data?.expiresAt).toBeDefined() + + const transactionId = result.current.data!._id! + unmount() + + // Clean up + const { result: deleteResult, unmount: unmountDelete } = renderHook(() => useDeleteTransaction(), { wrapper }) + await act(async () => { + await deleteResult.current.mutateAsync({ transactionId }) + }) + unmountDelete() + }) + }) + + describe('useGetTransaction', () => { + test('retrieves a transaction by ID', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + // First create a transaction + const { result: createResult, unmount: unmountCreate } = renderHook(() => useCreateTransaction(), { wrapper }) + + await act(async () => { + await createResult.current.mutateAsync({}) + }) + + await waitFor(() => expect(createResult.current.isSuccess).toBe(true)) + const transactionId = createResult.current.data!._id! + unmountCreate() + + // Now get it + const { result, unmount } = renderHook( + () => useGetTransaction({ transactionId }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + + expect(result.current.data).toBeDefined() + expect(result.current.data?._id).toBe(transactionId) + expect(result.current.data?.status).toBeDefined() + unmount() + + // Clean up + const { result: deleteResult, unmount: unmountDelete } = renderHook(() => useDeleteTransaction(), { wrapper }) + await act(async () => { + await deleteResult.current.mutateAsync({ transactionId }) + }) + unmountDelete() + }) + }) + + describe('useListTransactions', () => { + test('lists transactions', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + // Create a transaction so there's at least one + const { result: createResult, unmount: unmountCreate } = renderHook(() => useCreateTransaction(), { wrapper }) + + await act(async () => { + await createResult.current.mutateAsync({}) + }) + + await waitFor(() => expect(createResult.current.isSuccess).toBe(true)) + const transactionId = createResult.current.data!._id! + unmountCreate() + + const { result, unmount } = renderHook( + () => useListTransactions(), + { wrapper }, + ) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + + expect(result.current.data).toBeDefined() + expect(result.current.data?.total).toBeGreaterThanOrEqual(1) + expect(result.current.data?.transactions).toBeDefined() + expect(Array.isArray(result.current.data?.transactions)).toBe(true) + unmount() + + // Clean up + const { result: deleteResult, unmount: unmountDelete } = renderHook(() => useDeleteTransaction(), { wrapper }) + await act(async () => { + await deleteResult.current.mutateAsync({ transactionId }) + }) + unmountDelete() + }) + }) + + describe('useCreateOperations', () => { + test('adds a document create operation to a transaction', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + // Create a transaction + const { result: createResult, unmount: unmountCreate } = renderHook(() => useCreateTransaction(), { wrapper }) + + await act(async () => { + await createResult.current.mutateAsync({}) + }) + + await waitFor(() => expect(createResult.current.isSuccess).toBe(true)) + const transactionId = createResult.current.data!._id! + unmountCreate() + + // Add a create-document operation + const { result, unmount } = renderHook(() => useCreateOperations(), { wrapper }) + + // Appwrite transaction operations are JSON-encoded operation descriptors + const operation = JSON.stringify({ + $id: 'op1', + type: 'create', + collection: `${databaseId}.${collectionId}`, + data: { name: 'Transaction Doc' }, + }) + + await act(async () => { + result.current.mutate({ + transactionId, + operations: [operation], + }) + }) + + // The hook should complete (success or error depending on Appwrite's operation format) + await waitFor(() => + expect(result.current.isSuccess || result.current.isError).toBe(true), + ) + unmount() + + // Clean up + const { result: deleteResult, unmount: unmountDelete } = renderHook(() => useDeleteTransaction(), { wrapper }) + await act(async () => { + await deleteResult.current.mutateAsync({ transactionId }) + }) + unmountDelete() + }) + + test('fails with invalid transaction ID', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result, unmount } = renderHook(() => useCreateOperations(), { wrapper }) + + await act(async () => { + result.current.mutate({ + transactionId: 'non-existent-txn', + operations: ['{}'], + }) + }) + + await waitFor(() => expect(result.current.isError).toBe(true)) + unmount() + }) + }) + + describe('useUpdateTransaction', () => { + test('commits a transaction', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + // Create a transaction + const { result: createResult, unmount: unmountCreate } = renderHook(() => useCreateTransaction(), { wrapper }) + + await act(async () => { + await createResult.current.mutateAsync({}) + }) + + await waitFor(() => expect(createResult.current.isSuccess).toBe(true)) + const transactionId = createResult.current.data!._id! + unmountCreate() + + // Commit it + const { result, unmount } = renderHook(() => useUpdateTransaction(), { wrapper }) + + await act(async () => { + await result.current.mutateAsync({ + transactionId, + commit: true, + }) + }) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + + expect(result.current.data).toBeDefined() + expect(result.current.data?._id).toBe(transactionId) + unmount() + }) + + test('rolls back a transaction', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + // Create a transaction + const { result: createResult, unmount: unmountCreate } = renderHook(() => useCreateTransaction(), { wrapper }) + + await act(async () => { + await createResult.current.mutateAsync({}) + }) + + await waitFor(() => expect(createResult.current.isSuccess).toBe(true)) + const transactionId = createResult.current.data!._id! + unmountCreate() + + // Rollback + const { result, unmount } = renderHook(() => useUpdateTransaction(), { wrapper }) + + await act(async () => { + await result.current.mutateAsync({ + transactionId, + rollback: true, + }) + }) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + + expect(result.current.data).toBeDefined() + expect(result.current.data?._id).toBe(transactionId) + unmount() + }) + }) + + describe('useDeleteTransaction', () => { + test('deletes a transaction and returns status', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + // Create a transaction to delete + const { result: createResult, unmount: unmountCreate } = renderHook(() => useCreateTransaction(), { wrapper }) + + await act(async () => { + await createResult.current.mutateAsync({}) + }) + + await waitFor(() => expect(createResult.current.isSuccess).toBe(true)) + const transactionId = createResult.current.data!._id! + unmountCreate() + + // Delete it + const { result, unmount } = renderHook(() => useDeleteTransaction(), { wrapper }) + + await act(async () => { + await result.current.mutateAsync({ transactionId }) + }) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + + expect(result.current.data).toBeDefined() + expect(result.current.data?.status).toBeDefined() + unmount() + }) + + test('fails when deleting a non-existent transaction', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result, unmount } = renderHook(() => useDeleteTransaction(), { wrapper }) + + await act(async () => { + result.current.mutate({ transactionId: 'non-existent-id' }) + }) + + await waitFor(() => expect(result.current.isError).toBe(true)) + unmount() + }) + }) +}) diff --git a/tests/docker-compose.yml b/tests/docker-compose.yml index a87b822..a47e961 100644 --- a/tests/docker-compose.yml +++ b/tests/docker-compose.yml @@ -1,9 +1,9 @@ x-logging: &x-logging logging: - driver: 'json-file' + driver: "json-file" options: - max-file: '5' - max-size: '10m' + max-file: "5" + max-size: "10m" services: traefik: @@ -316,6 +316,206 @@ services: - _APP_DOMAIN - _APP_OPTIONS_FORCE_HTTPS + appwrite-worker-messaging: + image: appwrite/appwrite:1.8.1 + entrypoint: worker-messaging + container_name: appwrite-worker-messaging + <<: *x-logging + restart: unless-stopped + networks: + - appwrite + depends_on: + - redis + - mariadb + environment: + - _APP_ENV + - _APP_WORKER_PER_CORE + - _APP_OPENSSL_KEY_V1 + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_SMTP_HOST + - _APP_SMTP_PORT + - _APP_SMTP_SECURE + - _APP_SMTP_USERNAME + - _APP_SMTP_PASSWORD + - _APP_LOGGING_CONFIG + - _APP_SMS_PROVIDER + - _APP_SMS_FROM + + openruntimes-executor: + container_name: openruntimes-executor + hostname: exc1 + <<: *x-logging + stop_signal: SIGINT + image: openruntimes/executor:0.11.4 + restart: unless-stopped + networks: + - appwrite + - runtimes + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - appwrite-builds:/storage/builds:rw + - appwrite-functions:/storage/functions:rw + - appwrite-sites:/storage/sites:rw + # Host mount nessessary to share files between executor and runtimes. + # It's not possible to share mount file between 2 containers without host mount (copying is too slow) + - /tmp:/tmp:rw + environment: + - OPR_EXECUTOR_IMAGE_PULL=enabled + - OPR_EXECUTOR_INACTIVE_TRESHOLD=$_APP_COMPUTE_INACTIVE_THRESHOLD + - OPR_EXECUTOR_MAINTENANCE_INTERVAL=$_APP_COMPUTE_MAINTENANCE_INTERVAL + - OPR_EXECUTOR_NETWORK=$_APP_COMPUTE_RUNTIMES_NETWORK + - OPR_EXECUTOR_DOCKER_HUB_USERNAME=$_APP_DOCKER_HUB_USERNAME + - OPR_EXECUTOR_DOCKER_HUB_PASSWORD=$_APP_DOCKER_HUB_PASSWORD + - OPR_EXECUTOR_ENV=$_APP_ENV + - OPR_EXECUTOR_RUNTIMES=$_APP_FUNCTIONS_RUNTIMES,$_APP_SITES_RUNTIMES + - OPR_EXECUTOR_SECRET=$_APP_EXECUTOR_SECRET + - OPR_EXECUTOR_RUNTIME_VERSIONS=v5 + - OPR_EXECUTOR_LOGGING_CONFIG=$_APP_LOGGING_CONFIG + - OPR_EXECUTOR_STORAGE_DEVICE=$_APP_STORAGE_DEVICE + - OPR_EXECUTOR_STORAGE_S3_ACCESS_KEY=$_APP_STORAGE_S3_ACCESS_KEY + - OPR_EXECUTOR_STORAGE_S3_SECRET=$_APP_STORAGE_S3_SECRET + - OPR_EXECUTOR_STORAGE_S3_REGION=$_APP_STORAGE_S3_REGION + - OPR_EXECUTOR_STORAGE_S3_BUCKET=$_APP_STORAGE_S3_BUCKET + - OPR_EXECUTOR_STORAGE_S3_ENDPOINT=$_APP_STORAGE_S3_ENDPOINT + - OPR_EXECUTOR_STORAGE_DO_SPACES_ACCESS_KEY=$_APP_STORAGE_DO_SPACES_ACCESS_KEY + - OPR_EXECUTOR_STORAGE_DO_SPACES_SECRET=$_APP_STORAGE_DO_SPACES_SECRET + - OPR_EXECUTOR_STORAGE_DO_SPACES_REGION=$_APP_STORAGE_DO_SPACES_REGION + - OPR_EXECUTOR_STORAGE_DO_SPACES_BUCKET=$_APP_STORAGE_DO_SPACES_BUCKET + - OPR_EXECUTOR_STORAGE_BACKBLAZE_ACCESS_KEY=$_APP_STORAGE_BACKBLAZE_ACCESS_KEY + - OPR_EXECUTOR_STORAGE_BACKBLAZE_SECRET=$_APP_STORAGE_BACKBLAZE_SECRET + - OPR_EXECUTOR_STORAGE_BACKBLAZE_REGION=$_APP_STORAGE_BACKBLAZE_REGION + - OPR_EXECUTOR_STORAGE_BACKBLAZE_BUCKET=$_APP_STORAGE_BACKBLAZE_BUCKET + - OPR_EXECUTOR_STORAGE_LINODE_ACCESS_KEY=$_APP_STORAGE_LINODE_ACCESS_KEY + - OPR_EXECUTOR_STORAGE_LINODE_SECRET=$_APP_STORAGE_LINODE_SECRET + - OPR_EXECUTOR_STORAGE_LINODE_REGION=$_APP_STORAGE_LINODE_REGION + - OPR_EXECUTOR_STORAGE_LINODE_BUCKET=$_APP_STORAGE_LINODE_BUCKET + - OPR_EXECUTOR_STORAGE_WASABI_ACCESS_KEY=$_APP_STORAGE_WASABI_ACCESS_KEY + - OPR_EXECUTOR_STORAGE_WASABI_SECRET=$_APP_STORAGE_WASABI_SECRET + - OPR_EXECUTOR_STORAGE_WASABI_REGION=$_APP_STORAGE_WASABI_REGION + - OPR_EXECUTOR_STORAGE_WASABI_BUCKET=$_APP_STORAGE_WASABI_BUCKET + + appwrite-worker-builds: + entrypoint: worker-builds + <<: *x-logging + container_name: appwrite-worker-builds + image: appwrite/appwrite:1.8.1 + networks: + - appwrite + volumes: + - appwrite-functions:/storage/functions:rw + - appwrite-sites:/storage/sites:rw + - appwrite-builds:/storage/builds:rw + - appwrite-uploads:/storage/uploads:rw + # - ./app:/usr/src/code/app + # - ./src:/usr/src/code/src + depends_on: + - redis + - mariadb + environment: + - _APP_BROWSER_HOST + - _APP_ENV + - _APP_WORKER_PER_CORE + - _APP_OPENSSL_KEY_V1 + - _APP_EXECUTOR_SECRET + - _APP_EXECUTOR_HOST + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_LOGGING_CONFIG + - _APP_VCS_GITHUB_APP_NAME + - _APP_VCS_GITHUB_PRIVATE_KEY + - _APP_VCS_GITHUB_APP_ID + - _APP_FUNCTIONS_TIMEOUT + - _APP_SITES_TIMEOUT + - _APP_COMPUTE_BUILD_TIMEOUT + - _APP_COMPUTE_CPUS + - _APP_COMPUTE_MEMORY + - _APP_COMPUTE_SIZE_LIMIT + - _APP_OPTIONS_FORCE_HTTPS + - _APP_OPTIONS_ROUTER_FORCE_HTTPS + - _APP_DOMAIN + - _APP_CONSOLE_DOMAIN + - _APP_STORAGE_DEVICE + - _APP_STORAGE_S3_ACCESS_KEY + - _APP_STORAGE_S3_SECRET + - _APP_STORAGE_S3_REGION + - _APP_STORAGE_S3_BUCKET + - _APP_STORAGE_S3_ENDPOINT + - _APP_STORAGE_DO_SPACES_ACCESS_KEY + - _APP_STORAGE_DO_SPACES_SECRET + - _APP_STORAGE_DO_SPACES_REGION + - _APP_STORAGE_DO_SPACES_BUCKET + - _APP_STORAGE_BACKBLAZE_ACCESS_KEY + - _APP_STORAGE_BACKBLAZE_SECRET + - _APP_STORAGE_BACKBLAZE_REGION + - _APP_STORAGE_BACKBLAZE_BUCKET + - _APP_STORAGE_LINODE_ACCESS_KEY + - _APP_STORAGE_LINODE_SECRET + - _APP_STORAGE_LINODE_REGION + - _APP_STORAGE_LINODE_BUCKET + - _APP_STORAGE_WASABI_ACCESS_KEY + - _APP_STORAGE_WASABI_SECRET + - _APP_STORAGE_WASABI_REGION + - _APP_STORAGE_WASABI_BUCKET + - _APP_DATABASE_SHARED_TABLES + - _APP_DOMAIN_SITES + extra_hosts: + - "host.docker.internal:host-gateway" + + appwrite-worker-functions: + entrypoint: worker-functions + <<: *x-logging + container_name: appwrite-worker-functions + image: appwrite/appwrite:1.8.1 + networks: + - appwrite + depends_on: + - redis + - mariadb + - openruntimes-executor + environment: + - _APP_ENV + - _APP_WORKER_PER_CORE + - _APP_OPENSSL_KEY_V1 + - _APP_DOMAIN + - _APP_OPTIONS_FORCE_HTTPS + - _APP_REDIS_HOST + - _APP_REDIS_PORT + - _APP_REDIS_USER + - _APP_REDIS_PASS + - _APP_DB_HOST + - _APP_DB_PORT + - _APP_DB_SCHEMA + - _APP_DB_USER + - _APP_DB_PASS + - _APP_FUNCTIONS_TIMEOUT + - _APP_SITES_TIMEOUT + - _APP_COMPUTE_BUILD_TIMEOUT + - _APP_COMPUTE_CPUS + - _APP_COMPUTE_MEMORY + - _APP_EXECUTOR_SECRET + - _APP_EXECUTOR_HOST + - _APP_USAGE_STATS + - _APP_DOCKER_HUB_USERNAME + - _APP_DOCKER_HUB_PASSWORD + - _APP_LOGGING_CONFIG + - _APP_LOGGING_PROVIDER + - _APP_DATABASE_SHARED_TABLES + mariadb: image: mariadb:10.11 container_name: appwrite-mariadb @@ -331,7 +531,7 @@ services: - MYSQL_USER=${_APP_DB_USER} - MYSQL_PASSWORD=${_APP_DB_PASS} - MARIADB_AUTO_UPGRADE=1 - command: 'mysqld --innodb-flush-method=fsync' + command: "mysqld --innodb-flush-method=fsync" redis: image: redis:7.2.4-alpine @@ -348,11 +548,42 @@ services: volumes: - appwrite-redis:/data:rw + mailpit: + image: axllent/mailpit + container_name: mailpit + restart: unless-stopped + volumes: + - ./data:/data + ports: + - 8025:8025 + - 1025:1025 + environment: + MP_MAX_MESSAGES: 5000 + MP_DATABASE: /data/mailpit.db + MP_SMTP_AUTH_ACCEPT_ANY: 1 + MP_SMTP_AUTH_ALLOW_INSECURE: 1 + networks: + - appwrite + + sms-mock: + image: "node:22-alpine" + container_name: request-catcher-sms + working_dir: /app + volumes: + - ./sms-mock:/app:ro + ports: + - "8888:5000" + command: "node server.js" + networks: + - appwrite + networks: gateway: name: gateway appwrite: name: appwrite + runtimes: + name: runtimes volumes: appwrite-mariadb: diff --git a/tests/functions/functions.test.ts b/tests/functions/functions.test.ts new file mode 100644 index 0000000..252ecd5 --- /dev/null +++ b/tests/functions/functions.test.ts @@ -0,0 +1,231 @@ +import { act, renderHook, waitFor } from '@testing-library/react' +import { afterAll, beforeAll, describe, expect, test } from 'bun:test' + +import { useGetExecution, useListExecutions } from '../../src' +import { useFunction, useSuspenseFunction } from '../../src/functions/useFunction' +import { createTestUser, deleteTestUser, loginUser } from '../setup/helpers' +import { createWrapper } from '../setup/wrapper' + +describe('Function hooks', () => { + let userId: string + let userEmail: string + let userPassword: string + + beforeAll(async () => { + const user = await createTestUser({ name: 'Func User' }) + userId = user.userId + userEmail = user.email + userPassword = user.password + }) + + afterAll(async () => { + await deleteTestUser(userId) + }) + + describe('useFunction', () => { + test( + 'executes a long-running function at /long', + async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook(() => useFunction(), { wrapper }) + + const start = Date.now() + await act(async () => { + const response = await result.current.executeFunction.mutateAsync({ + functionId: 'test-function', + path: '/long', + }) + expect(response).toBe('This response was delayed by 5 seconds') + }) + const elapsed = Date.now() - start + expect(elapsed).toBeGreaterThanOrEqual(5000) + }, + { timeout: 30_000 }, + ) + + test( + 'handles a 500 error response at /error', + async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook(() => useFunction(), { wrapper }) + + let didThrow = false + await act(async () => { + try { + await result.current.executeFunction.mutateAsync({ + functionId: 'test-function', + path: '/error', + }) + } catch { + didThrow = true + } + }) + + expect(didThrow).toBe(true) + await waitFor(() => expect(result.current.executeFunction.isError).toBe(true)) + }, + { timeout: 15_000 }, + ) + + test( + 'returns parsed JSON from /json', + async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook(() => useFunction(), { wrapper }) + + await act(async () => { + const response = await result.current.executeFunction.mutateAsync({ + functionId: 'test-function', + path: '/json', + }) + expect(response).toEqual({ message: 'This is a JSON response' }) + }) + + await waitFor( + () => { + expect(result.current.currentExecution.isSuccess).toBe(true) + }, + { timeout: 10_000 }, + ) + const executionData = result.current.currentExecution.data + expect(executionData).toHaveProperty('status', 'completed') + expect(executionData).toHaveProperty('requestPath', '/json') + }, + { timeout: 15_000 }, + ) + + test( + 'returns a text string for an invalid path', + async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook(() => useFunction(), { wrapper }) + + await act(async () => { + const response = await result.current.executeFunction.mutateAsync({ + functionId: 'test-function', + path: '/noop', + }) + expect(response).toBe('Invalid path') + }) + }, + { timeout: 15_000 }, + ) + + describe('useSuspenseFunction', () => { + test( + 'executes a function and returns the response', + async () => { + const wrapper = createWrapper({ suspense: true }) + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useSuspenseFunction({ + functionId: 'test-function', + path: '/long', + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.executeFunction.isSuccess).toBe(true), { + timeout: 10_000, + }) + + const response = result.current.executeFunction.data + expect(response).toBe('This response was delayed by 5 seconds') + }, + { timeout: 15_000 }, + ) + + test.skip( + 'handles errors and returns the error message', + async () => { + const wrapper = createWrapper({ suspense: true }) + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useSuspenseFunction({ + functionId: 'test-function', + path: '/error', + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.executeFunction).toBeDefined()) + + console.log(result.current.executeFunction) + }, + { timeout: 15_000 }, + ) + + test( + 'returns parsed JSON from a function response', + async () => { + const wrapper = createWrapper({ suspense: true }) + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook( + () => + useSuspenseFunction({ + functionId: 'test-function', + path: '/json', + }), + { wrapper }, + ) + + await waitFor(() => expect(result.current.executeFunction.isSuccess).toBe(true), { + timeout: 10_000, + }) + + const response = result.current.executeFunction.data + expect(response).toEqual({ message: 'This is a JSON response' }) + }, + { timeout: 15_000 }, + ) + }) + }) + + describe('useListExecutions & useGetExecution', () => { + test('lists executions for a function', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook(() => useListExecutions({ functionId: 'test-function' }), { + wrapper, + }) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + + const data = result.current.data + expect(data).toHaveProperty('total') + expect(data).toHaveProperty('executions') + expect(Array.isArray(data?.executions)).toBe(true) + + const { result: getExecutionResult } = renderHook( + () => + useGetExecution({ + functionId: 'test-function', + executionId: data?.executions[0]._id ?? '', + }), + { + wrapper, + }, + ) + + await waitFor(() => expect(getExecutionResult.current.isSuccess).toBe(true)) + + const executionData = getExecutionResult.current.data + expect(executionData).toHaveProperty('_id') + expect(executionData).toHaveProperty('functionId', 'test-function') + }) + }) +}) diff --git a/tests/messaging/subscriber.test.tsx b/tests/messaging/subscriber.test.tsx new file mode 100644 index 0000000..588ea7d --- /dev/null +++ b/tests/messaging/subscriber.test.tsx @@ -0,0 +1,200 @@ +import { act, renderHook, waitFor } from '@testing-library/react' +import { afterAll, afterEach, beforeAll, describe, expect, test } from 'bun:test' + +import { useCreateSubscriber, useDeleteSubscriber } from '../../src' +import { ID } from '../../src/types' +import { + checkMail, + createServerClient, + createTestUser, + deleteTestUser, + emptyMail, + getUserEmailTargetId, + loginUser, + sendTopicEmail, +} from '../setup/helpers' +import { createWrapper } from '../setup/wrapper' + +const TOPIC_ID = 'test-topic' + +describe('Subscriber hooks', () => { + let userId: string + let userEmail: string + let userPassword: string + let targetId: string + + beforeAll(async () => { + const user = await createTestUser({ name: 'Subscriber Test User' }) + userId = user.userId + userEmail = user.email + userPassword = user.password + targetId = await getUserEmailTargetId(userId) + }) + + afterAll(async () => { + await deleteTestUser(userId) + }) + + afterEach(async () => { + await emptyMail() + }) + + describe('useCreateSubscriber', () => { + test('subscribes a user to a topic and returns subscriber data', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook(() => useCreateSubscriber(), { wrapper }) + + const subscriberId = ID.unique() + + await act(async () => { + await result.current.mutateAsync({ + subscriberId, + topicId: TOPIC_ID, + targetId, + }) + }) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + + expect(result.current.data).toBeDefined() + expect(result.current.data?._id).toBe(subscriberId) + expect(result.current.data?.topicId).toBe(TOPIC_ID) + expect(result.current.data?.targetId).toBe(targetId) + expect(result.current.data?.providerType).toBe('email') + + // Clean up subscription via server SDK + const { messaging } = createServerClient() + await messaging.deleteSubscriber({ topicId: TOPIC_ID, subscriberId }) + }) + + test('receives an email after subscribing to a topic', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + const { result } = renderHook(() => useCreateSubscriber(), { wrapper }) + + const subscriberId = ID.unique() + + await act(async () => { + await result.current.mutateAsync({ + subscriberId, + topicId: TOPIC_ID, + targetId, + }) + }) + + await waitFor(() => expect(result.current.isSuccess).toBe(true)) + + // Send a message to the topic via server SDK + await sendTopicEmail({ + topicId: TOPIC_ID, + subject: 'Subscriber Hook Test', + content: '

Hello from subscriber test

', + }) + + // Verify the email was received via Mailpit + await waitFor( + async () => { + const emails = await checkMail() + expect(emails.messages.length).toBeGreaterThan(0) + expect(emails.messages[0].Subject).toBe('Subscriber Hook Test') + return true + }, + { timeout: 10000 }, + ) + + // Clean up subscription via server SDK + const { messaging } = createServerClient() + await messaging.deleteSubscriber({ topicId: TOPIC_ID, subscriberId }) + }) + }) + + describe('useDeleteSubscriber', () => { + test('unsubscribes a user from a topic and returns status', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + // First create a subscription + const { result: createResult } = renderHook(() => useCreateSubscriber(), { wrapper }) + + const subscriberId = ID.unique() + + await act(async () => { + await createResult.current.mutateAsync({ + subscriberId, + topicId: TOPIC_ID, + targetId, + }) + }) + + await waitFor(() => expect(createResult.current.isSuccess).toBe(true)) + + // Now delete the subscription + const { result: deleteResult } = renderHook(() => useDeleteSubscriber(), { wrapper }) + + await act(async () => { + await deleteResult.current.mutateAsync({ + topicId: TOPIC_ID, + subscriberId, + }) + }) + + await waitFor(() => expect(deleteResult.current.isSuccess).toBe(true)) + + expect(deleteResult.current.data).toBeDefined() + expect(deleteResult.current.data?.status).toBeDefined() + }) + + test('does not receive an email after unsubscribing from a topic', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + // Subscribe + const { result: createResult } = renderHook(() => useCreateSubscriber(), { wrapper }) + + const subscriberId = ID.unique() + + await act(async () => { + await createResult.current.mutateAsync({ + subscriberId, + topicId: TOPIC_ID, + targetId, + }) + }) + + await waitFor(() => expect(createResult.current.isSuccess).toBe(true)) + + // Unsubscribe + const { result: deleteResult } = renderHook(() => useDeleteSubscriber(), { wrapper }) + + await act(async () => { + await deleteResult.current.mutateAsync({ + topicId: TOPIC_ID, + subscriberId, + }) + }) + + await waitFor(() => expect(deleteResult.current.isSuccess).toBe(true)) + + // Send a message to the topic + await sendTopicEmail({ + topicId: TOPIC_ID, + subject: 'Should Not Arrive', + content: '

This should not be delivered

', + }) + + // Wait a bit and verify no email was received + await act(async () => { + await new Promise((r) => setTimeout(r, 3000)) + }) + + const emails = await checkMail() + const matchingEmails = emails.messages?.filter( + (m: { Subject: string }) => m.Subject === 'Should Not Arrive', + ) + expect(matchingEmails?.length ?? 0).toBe(0) + }, 30000) + }) +}) diff --git a/tests/offline/client.test.ts b/tests/offline/client.test.ts new file mode 100644 index 0000000..8504fc9 --- /dev/null +++ b/tests/offline/client.test.ts @@ -0,0 +1,69 @@ +import { onlineManager } from '@tanstack/react-query' +import { describe, expect, mock, test } from 'bun:test' + +import { createOfflineClient } from '../../src' + +describe('Offline Client', () => { + test('client throws if storage and persister are both provided', () => { + expect(() => + createOfflineClient({ + endpoint: 'https://example.com', + projectId: 'projectId', + networkAdapter: { listen: mock() }, + storage: localStorage, + persister: { persistClient: mock(), restoreClient: mock(), removeClient: mock() }, + }), + ).toThrow('Provide either `storage` or `persister`, not both.') + }) + + test('client runs startPersistence normally', () => { + const client = createOfflineClient({ + endpoint: 'https://example.com', + projectId: 'projectId', + networkAdapter: { listen: mock() }, + storage: localStorage, + }) + + const { unsubscribe, restored } = client.startPersistence() + + expect(typeof unsubscribe).toBe('function') + expect(restored).toBeInstanceOf(Promise) + }) + + test('client throws if startPersistence is called without a persister', () => { + const client = createOfflineClient({ + endpoint: 'https://example.com', + projectId: 'projectId', + networkAdapter: { listen: mock() }, + }) + + expect(() => client.startPersistence()).toThrow( + 'No persister configured. Provide `storage` or `persister` to createOfflineClient.', + ) + }) + + test('client sets online status based on network adapter', () => { + let onlineCallback: ((isOnline: boolean) => void) | null = null + + createOfflineClient({ + endpoint: 'https://example.com', + projectId: 'projectId', + networkAdapter: { + listen: (callback) => { + onlineCallback = callback + return () => {} + }, + }, + }) + + expect(onlineManager.isOnline()).toBe(true) + + // Simulate going offline + onlineCallback?.(false) + expect(onlineManager.isOnline()).toBe(false) + + // Simulate going back online + onlineCallback?.(true) + expect(onlineManager.isOnline()).toBe(true) + }) +}) diff --git a/tests/offline/registry.test.ts b/tests/offline/registry.test.ts new file mode 100644 index 0000000..3f07590 --- /dev/null +++ b/tests/offline/registry.test.ts @@ -0,0 +1,217 @@ +import { onlineManager } from '@tanstack/react-query' +import { act, renderHook, waitFor } from '@testing-library/react' +import { afterAll, beforeAll, describe, expect, mock, test } from 'bun:test' +export type { AsyncStorage } from '@tanstack/query-persist-client-core' + +import { + createOfflineClient, + Keys, + useCreateDocument, + useDocument, + useUpdateDocument, +} from '../../src' +import { ID } from '../../src/types' +import { + createTestUser, + deleteTestDocument, + deleteTestUser, + getTestConfig, + loginUser, +} from '../setup/helpers' +import { createWrapper } from '../setup/wrapper' + +describe('Mutation Registry', () => { + const config = getTestConfig() + const { databaseId, collectionId } = config + let userId: string + let userEmail: string + let userPassword: string + const createdDocumentIds: string[] = [] + + let documentCreatedOfflineId: string + + beforeAll(async () => { + const user = await createTestUser({ name: 'Doc CRUD User' }) + userId = user.userId + userEmail = user.email + userPassword = user.password + }) + + afterAll(async () => { + for (const docId of createdDocumentIds) { + await deleteTestDocument(docId) + } + await deleteTestUser(userId) + }) + + test('databasesCreateDocument mutation queues mutation when offline and executes when back online', async () => { + const { appwrite, queryClient, persister } = createOfflineClient({ + endpoint: config.endpoint, + projectId: config.projectId, + networkAdapter: { + listen: mock(), + }, + storage: localStorage, + }) + + queryClient.setDefaultOptions({ + mutations: { networkMode: 'online' }, + }) + + const wrapper = createWrapper({ + client: appwrite, + queryClient, + persister, + }) + + await loginUser(userEmail, userPassword, wrapper) + onlineManager.setOnline(false) + + const { result: createResult } = renderHook(() => useCreateDocument(), { wrapper }) + + const documentId = ID.unique() + + await act(async () => { + createResult.current.mutate({ + databaseId, + collectionId, + documentId, + data: { name: 'Test Document', age: 25 }, + }) + }) + + await waitFor(() => expect(createResult.current.isPaused).toBe(true)) + + act(() => { + onlineManager.setOnline(true) + }) + + await waitFor(() => expect(createResult.current.isSuccess).toBe(true)) + + createdDocumentIds.push(documentId) + }) + + test('mutations save to localStorage when offline', async () => { + const { appwrite, queryClient, persister } = createOfflineClient({ + endpoint: config.endpoint, + projectId: config.projectId, + networkAdapter: { + listen: mock(), + }, + storage: localStorage, + throttleTime: 0, // Disable throttling for testing + }) + + queryClient.setDefaultOptions({ + mutations: { networkMode: 'online' }, + }) + + const wrapper = createWrapper({ + client: appwrite, + queryClient, + persister, + }) + + await loginUser(userEmail, userPassword, wrapper) + onlineManager.setOnline(false) + + const { result: createResult } = renderHook(() => useCreateDocument(), { wrapper }) + + const documentId = ID.unique() + documentCreatedOfflineId = documentId + + await act(async () => { + createResult.current.mutate({ + databaseId, + collectionId, + documentId, + data: { name: 'Test Document', age: 25 }, + }) + }) + + await waitFor(() => expect(createResult.current.isPaused).toBe(true)) + + const { result: updateResult } = renderHook(() => useUpdateDocument(), { wrapper }) + + await act(async () => { + updateResult.current.mutate({ + databaseId, + collectionId, + documentId, + data: { age: 26 }, + }) + }) + + await waitFor(() => expect(updateResult.current.isPaused).toBe(true)) + await new Promise((r) => setTimeout(r, 50)) // Wait for localStorage to update + + const offlineCache = localStorage.getItem('appwrite-graphql-offline-cache') // For debugging: check the persisted mutations + expect(offlineCache).toBeTruthy() + + const parsedCache = JSON.parse(offlineCache!) + const mutationKeys = parsedCache.clientState.mutations.map((m: { mutationKey: string[] }) => + m.mutationKey.join('.'), + ) + expect(mutationKeys).toContain(Keys.databases().collections().documents().create().join('.')) + expect(mutationKeys).toContain(Keys.databases().collections().documents().update().join('.')) + }) + + test('mutations are replayed when app restarts', async () => { + onlineManager.setOnline(true) + + const { appwrite, queryClient, persister } = createOfflineClient({ + endpoint: config.endpoint, + projectId: config.projectId, + networkAdapter: { + listen: mock(), + }, + storage: localStorage, + }) + + const wrapper = createWrapper({ + client: appwrite, + queryClient, + persister, + }) + + await appwrite.account.createEmailPasswordSession({ email: userEmail, password: userPassword }) + + const { result: getResult } = renderHook( + () => + useDocument<{ + name: string + age: number + }>({ + databaseId, + collectionId, + documentId: documentCreatedOfflineId, + }), + { wrapper }, + ) + + // Wait for the document to exist (create mutation replayed) + await waitFor(() => expect(getResult.current.data).toBeTruthy(), { timeout: 12_000 }) + expect(getResult.current.data?.name).toBe('Test Document') + + // Wait for all persisted mutations to finish replaying (including the update) + await waitFor( + () => { + const pending = queryClient + .getMutationCache() + .getAll() + .filter((m) => m.state.status === 'pending' || m.state.isPaused) + expect(pending.length).toBe(0) + }, + { timeout: 10_000 }, + ) + + // Refetch after mutations complete — replayed mutations lack onSuccess invalidation + await act(async () => { + await queryClient.refetchQueries() + }) + + await waitFor(() => expect(getResult.current.data?.age).toBe(26), { timeout: 5_000 }) + + createdDocumentIds.push(documentCreatedOfflineId) + }, { timeout: 20_000 }) +}) diff --git a/tests/query/keys.test.ts b/tests/query/keys.test.ts new file mode 100644 index 0000000..c6c558b --- /dev/null +++ b/tests/query/keys.test.ts @@ -0,0 +1,444 @@ +import { describe, expect, test } from 'bun:test' + +import { Keys } from '../../src/query/Keys' + +describe('Query Keys', () => { + describe('account keys', () => { + test('account', () => { + expect(Keys.account().key()).toEqual(['appwrite', 'account']) + }) + + test('account jwt', () => { + expect(Keys.account().jwt().key()).toEqual(['appwrite', 'account', 'jwt']) + }) + + test('account anonymous', () => { + expect(Keys.account().anonymous().key()).toEqual(['appwrite', 'account', 'anonymous']) + }) + + test('account emailToken', () => { + expect(Keys.account().emailToken().key()).toEqual(['appwrite', 'account', 'emailToken']) + }) + + test('account emailVerification', () => { + expect(Keys.account().emailVerification().key()).toEqual([ + 'appwrite', + 'account', + 'emailVerification', + ]) + }) + + test('account magicUrl', () => { + expect(Keys.account().magicUrl().key()).toEqual(['appwrite', 'account', 'magicUrl']) + }) + + test('account mfaAuthenticator', () => { + expect(Keys.account().mfaAuthenticator().key()).toEqual([ + 'appwrite', + 'account', + 'mfaAuthenticator', + ]) + }) + + test('account mfaChallenge', () => { + expect(Keys.account().mfaChallenge().key()).toEqual(['appwrite', 'account', 'mfaChallenge']) + }) + + test('account mfaCodes', () => { + expect(Keys.account().mfaCodes().key()).toEqual(['appwrite', 'account', 'mfaCodes']) + }) + + test('account oauth2Token', () => { + expect(Keys.account().oauth2Token().key()).toEqual(['appwrite', 'account', 'oauth2Token']) + }) + + test('account phoneToken', () => { + expect(Keys.account().phoneToken().key()).toEqual(['appwrite', 'account', 'phoneToken']) + }) + + test('account phoneVerification', () => { + expect(Keys.account().phoneVerification().key()).toEqual([ + 'appwrite', + 'account', + 'phoneVerification', + ]) + }) + + test('account pushTarget', () => { + expect(Keys.account().pushTarget().key()).toEqual(['appwrite', 'account', 'pushTarget']) + }) + + test('account identity', () => { + expect(Keys.account().identity().key()).toEqual(['appwrite', 'account', 'identity']) + }) + + test('account prefs', () => { + expect(Keys.account().prefs().key()).toEqual(['appwrite', 'account', 'prefs']) + }) + + test('account login', () => { + expect(Keys.account().login().key()).toEqual(['appwrite', 'account', 'login']) + }) + + test('signUp', () => { + expect(Keys.account().signUp().key()).toEqual(['appwrite', 'account', 'signUp']) + }) + + test('account name', () => { + expect(Keys.account().name().key()).toEqual(['appwrite', 'account', 'name']) + }) + + test('account email', () => { + expect(Keys.account().email().key()).toEqual(['appwrite', 'account', 'email']) + }) + + test('account phone', () => { + expect(Keys.account().phone().key()).toEqual(['appwrite', 'account', 'phone']) + }) + + test('account password', () => { + expect(Keys.account().password().key()).toEqual(['appwrite', 'account', 'password']) + }) + + test('account recovery', () => { + expect(Keys.account().recovery().key()).toEqual(['appwrite', 'account', 'recovery']) + }) + + test('account mfa', () => { + expect(Keys.account().mfa().key()).toEqual(['appwrite', 'account', 'mfa']) + }) + + test('account status', () => { + expect(Keys.account().status().key()).toEqual(['appwrite', 'account', 'status']) + }) + + test('account logs', () => { + expect(Keys.account().logs().key()).toEqual(['appwrite', 'account', 'logs']) + }) + + test('account verifications', () => { + expect(Keys.account().verification().key()).toEqual(['appwrite', 'account', 'verification']) + }) + + test('account session', () => { + expect(Keys.account().session('sessionId').key()).toEqual([ + 'appwrite', + 'account', + 'sessions', + 'sessionId', + ]) + }) + + test('account sessions', () => { + expect(Keys.account().sessions()).toEqual(['appwrite', 'account', 'sessions']) + }) + + test('account identities', () => { + expect(Keys.account().identities()).toEqual(['appwrite', 'account', 'identities']) + }) + + test('account mfaFactors', () => { + expect(Keys.account().mfaFactors()).toEqual(['appwrite', 'account', 'mfaFactors']) + }) + }) + + describe('database keys', () => { + test('collections', () => { + expect(Keys.database('databaseId').collections().key()).toEqual([ + 'appwrite', + 'databases', + 'databaseId', + 'collections', + ]) + }) + + test('collection', () => { + expect(Keys.database('databaseId').collection('collectionId').key()).toEqual([ + 'appwrite', + 'databases', + 'databaseId', + 'collections', + 'collectionId', + ]) + }) + + test('transaction', () => { + expect(Keys.database('databaseId').transaction('transactionId').key()).toEqual([ + 'appwrite', + 'databases', + 'databaseId', + 'transactions', + 'transactionId', + ]) + }) + + test('transactions', () => { + expect(Keys.database('databaseId').transactions().key()).toEqual([ + 'appwrite', + 'databases', + 'databaseId', + 'transactions', + ]) + }) + + test('operations', () => { + expect(Keys.database('databaseId').transaction('transactionId').operations().key()).toEqual([ + 'appwrite', + 'databases', + 'databaseId', + 'transactions', + 'transactionId', + 'operations', + ]) + }) + }) + + describe('collection keys', () => { + test('documents', () => { + expect(Keys.database('databaseId').collection('collectionId').documents().key()).toEqual([ + 'appwrite', + 'databases', + 'databaseId', + 'collections', + 'collectionId', + 'documents', + ]) + }) + + test('document', () => { + expect( + Keys.database('databaseId').collection('collectionId').document('documentId').key(), + ).toEqual([ + 'appwrite', + 'databases', + 'databaseId', + 'collections', + 'collectionId', + 'documents', + 'documentId', + ]) + }) + }) + + describe('tableDB keys', () => { + test('tableDB', () => { + expect(Keys.tablesDB('databaseId').key()).toEqual(['appwrite', 'tablesDB', 'databaseId']) + }) + + test('tableDB table', () => { + expect(Keys.tablesDB('databaseId').table('tableId').key()).toEqual([ + 'appwrite', + 'tablesDB', + 'databaseId', + 'table', + 'tableId', + ]) + }) + + test('tableDB table rows', () => { + expect(Keys.tablesDB('databaseId').table('tableId').rows().key()).toEqual([ + 'appwrite', + 'tablesDB', + 'databaseId', + 'table', + 'tableId', + 'rows', + ]) + }) + + test('tableDB table row', () => { + expect(Keys.tablesDB('databaseId').table('tableId').row('rowId').key()).toEqual([ + 'appwrite', + 'tablesDB', + 'databaseId', + 'table', + 'tableId', + 'row', + 'rowId', + ]) + }) + }) + + describe('bucket keys', () => { + test('files', () => { + expect(Keys.bucket('bucketId').files().key()).toEqual([ + 'appwrite', + 'buckets', + 'bucketId', + 'files', + ]) + }) + + test('file', () => { + expect(Keys.bucket('bucketId').file('fileId').key()).toEqual([ + 'appwrite', + 'buckets', + 'bucketId', + 'files', + 'fileId', + ]) + }) + }) + + describe('functions keys', () => { + test('executions', () => { + expect(Keys.function('functionId').executions().key()).toEqual([ + 'appwrite', + 'functions', + 'functionId', + 'executions', + ]) + }) + + test('execution', () => { + expect(Keys.function('functionId').execution('executionId').key()).toEqual([ + 'appwrite', + 'functions', + 'functionId', + 'executions', + 'executionId', + ]) + }) + }) + + describe('team keys', () => { + test('teamName', () => { + expect(Keys.team('teamId').teamName().key()).toEqual(['appwrite', 'teams', 'teamId', 'name']) + }) + + test('teamPrefs', () => { + expect(Keys.team('teamId').teamPrefs().key()).toEqual([ + 'appwrite', + 'teams', + 'teamId', + 'prefs', + ]) + }) + + test('memberships', () => { + expect(Keys.team('teamId').memberships().key()).toEqual([ + 'appwrite', + 'teams', + 'teamId', + 'memberships', + ]) + }) + + test('membership', () => { + expect(Keys.team('teamId').membership('membershipId').key()).toEqual([ + 'appwrite', + 'teams', + 'teamId', + 'memberships', + 'membershipId', + ]) + }) + + test('membershipStatus', () => { + expect(Keys.team('teamId').membershipStatus().key()).toEqual([ + 'appwrite', + 'teams', + 'teamId', + 'membershipStatus', + ]) + }) + }) + + describe('locale keys', () => { + test('continents', () => { + expect(Keys.locale().continents()).toEqual(['appwrite', 'locale', 'continents']) + }) + + test('countries', () => { + expect(Keys.locale().countries()).toEqual(['appwrite', 'locale', 'countries']) + }) + + test('countriesEU', () => { + expect(Keys.locale().countriesEU()).toEqual(['appwrite', 'locale', 'countriesEU']) + }) + + test('countriesPhones', () => { + expect(Keys.locale().countriesPhones()).toEqual(['appwrite', 'locale', 'countriesPhones']) + }) + + test('currencies', () => { + expect(Keys.locale().currencies()).toEqual(['appwrite', 'locale', 'currencies']) + }) + + test('languages', () => { + expect(Keys.locale().languages()).toEqual(['appwrite', 'locale', 'languages']) + }) + + test('codes', () => { + expect(Keys.locale().codes()).toEqual(['appwrite', 'locale', 'codes']) + }) + }) + + describe('messaging keys', () => { + test('subscriber', () => { + expect(Keys.messaging().subscriber().key()).toEqual(['appwrite', 'messaging', 'subscriber']) + }) + }) + + describe('actionable keys', () => { + test('create', () => { + expect( + Keys.database('databaseId').collection('collectionId').document('documentId').create(), + ).toEqual([ + 'appwrite', + 'databases', + 'databaseId', + 'collections', + 'collectionId', + 'documents', + 'documentId', + 'create', + ]) + }) + + test('upsert', () => { + expect( + Keys.database('databaseId').collection('collectionId').document('documentId').upsert(), + ).toEqual([ + 'appwrite', + 'databases', + 'databaseId', + 'collections', + 'collectionId', + 'documents', + 'documentId', + 'upsert', + ]) + }) + + test('update', () => { + expect( + Keys.database('databaseId').collection('collectionId').document('documentId').update(), + ).toEqual([ + 'appwrite', + 'databases', + 'databaseId', + 'collections', + 'collectionId', + 'documents', + 'documentId', + 'update', + ]) + }) + + test('delete', () => { + expect( + Keys.database('databaseId').collection('collectionId').document('documentId').delete(), + ).toEqual([ + 'appwrite', + 'databases', + 'databaseId', + 'collections', + 'collectionId', + 'documents', + 'documentId', + 'delete', + ]) + }) + }) +}) diff --git a/tests/query/query-builder.test.ts b/tests/query/query-builder.test.ts new file mode 100644 index 0000000..9035735 --- /dev/null +++ b/tests/query/query-builder.test.ts @@ -0,0 +1,530 @@ +import { Query } from 'appwrite' +import { describe, expect, test } from 'bun:test' + +import { q, QueryBuilder } from '../../src/query/QueryBuilder' + +type User = { + name: string + age: number + active: boolean + tags: string[] + scores: number[] + location: [number, number] +} + +type Post = { + title: string + body: string + views: number + published: boolean +} + +describe('QueryBuilder', () => { + describe('q() factory', () => { + test('returns a QueryBuilder instance', () => { + const builder = q() + expect(builder).toBeInstanceOf(QueryBuilder) + }) + + test('build() returns empty array for empty builder', () => { + expect(q().build()).toEqual([]) + }) + + test('each builder instance is independent', () => { + const a = q().equal('name', 'Alice') + const b = q().equal('name', 'Bob') + expect(a.build()).not.toEqual(b.build()) + }) + + test('build() returns a copy (mutations do not affect output)', () => { + const builder = q().equal('name', 'Alice') + const first = builder.build() + const second = builder.build() + expect(first).toEqual(second) + first.push('extra') + expect(builder.build()).not.toContain('extra') + }) + }) + + describe('comparison methods', () => { + test('equal with single value', () => { + const result = q().equal('name', 'Alice').build() + expect(result).toEqual([Query.equal('name', 'Alice')]) + }) + + test('equal with array of values', () => { + const result = q().equal('name', ['Alice', 'Bob']).build() + expect(result).toEqual([Query.equal('name', ['Alice', 'Bob'])]) + }) + + test('notEqual', () => { + const result = q().notEqual('name', 'Bob').build() + expect(result).toEqual([Query.notEqual('name', 'Bob')]) + }) + + test('lessThan', () => { + const result = q().lessThan('age', 30).build() + expect(result).toEqual([Query.lessThan('age', 30)]) + }) + + test('lessThanEqual', () => { + const result = q().lessThanEqual('age', 30).build() + expect(result).toEqual([Query.lessThanEqual('age', 30)]) + }) + + test('greaterThan', () => { + const result = q().greaterThan('age', 18).build() + expect(result).toEqual([Query.greaterThan('age', 18)]) + }) + + test('greaterThanEqual', () => { + const result = q().greaterThanEqual('age', 18).build() + expect(result).toEqual([Query.greaterThanEqual('age', 18)]) + }) + + test('between', () => { + const result = q().between('age', 18, 65).build() + expect(result).toEqual([Query.between('age', 18, 65)]) + }) + + test('notBetween', () => { + const result = q().notBetween('age', 0, 17).build() + expect(result).toEqual([Query.notBetween('age', 0, 17)]) + }) + + test('regex', () => { + const result = q().regex('name', '^A.*').build() + expect(result).toEqual([Query.regex('name', '^A.*')]) + }) + }) + + describe('null and existence checks', () => { + test('isNull', () => { + const result = q().isNull('name').build() + expect(result).toEqual([Query.isNull('name')]) + }) + + test('isNotNull', () => { + const result = q().isNotNull('name').build() + expect(result).toEqual([Query.isNotNull('name')]) + }) + + test('exists', () => { + const result = q().exists(['name', 'age']).build() + expect(result).toEqual([Query.exists(['name', 'age'])]) + }) + + test('notExists', () => { + const result = q().notExists(['tags']).build() + expect(result).toEqual([Query.notExists(['tags'])]) + }) + }) + + describe('string methods', () => { + test('search', () => { + const result = q().search('name', 'Ali').build() + expect(result).toEqual([Query.search('name', 'Ali')]) + }) + + test('notSearch', () => { + const result = q().notSearch('name', 'spam').build() + expect(result).toEqual([Query.notSearch('name', 'spam')]) + }) + + test('startsWith', () => { + const result = q().startsWith('name', 'A').build() + expect(result).toEqual([Query.startsWith('name', 'A')]) + }) + + test('endsWith', () => { + const result = q().endsWith('name', 'ce').build() + expect(result).toEqual([Query.endsWith('name', 'ce')]) + }) + + test('notStartsWith', () => { + const result = q().notStartsWith('name', 'Z').build() + expect(result).toEqual([Query.notStartsWith('name', 'Z')]) + }) + + test('notEndsWith', () => { + const result = q().notEndsWith('name', 'zz').build() + expect(result).toEqual([Query.notEndsWith('name', 'zz')]) + }) + }) + + describe('contains methods', () => { + test('contains on string field', () => { + const result = q().contains('name', 'li').build() + expect(result).toEqual([Query.contains('name', 'li')]) + }) + + test('contains on array field', () => { + const result = q().contains('tags', 'admin').build() + expect(result).toEqual([Query.contains('tags', 'admin')]) + }) + + test('containsAny', () => { + const result = q().containsAny('tags', ['admin', 'mod']).build() + expect(result).toEqual([Query.containsAny('tags', ['admin', 'mod'])]) + }) + + test('containsAll', () => { + const result = q().containsAll('tags', ['admin', 'verified']).build() + expect(result).toEqual([Query.containsAll('tags', ['admin', 'verified'])]) + }) + + test('notContains', () => { + const result = q().notContains('tags', 'banned').build() + expect(result).toEqual([Query.notContains('tags', 'banned')]) + }) + }) + + describe('select', () => { + test('select specific fields', () => { + const result = q().select(['name', 'age']).build() + expect(result).toEqual([Query.select(['name', 'age'])]) + }) + + test('select single field', () => { + const result = q().select(['name']).build() + expect(result).toEqual([Query.select(['name'])]) + }) + }) + + describe('ordering', () => { + test('orderAsc', () => { + const result = q().orderAsc('name').build() + expect(result).toEqual([Query.orderAsc('name')]) + }) + + test('orderDesc', () => { + const result = q().orderDesc('age').build() + expect(result).toEqual([Query.orderDesc('age')]) + }) + + test('orderRandom', () => { + const result = q().orderRandom().build() + expect(result).toEqual([Query.orderRandom()]) + }) + + test('multiple orderings', () => { + const result = q().orderAsc('name').orderDesc('age').build() + expect(result).toEqual([Query.orderAsc('name'), Query.orderDesc('age')]) + }) + }) + + describe('pagination', () => { + test('limit', () => { + const result = q().limit(25).build() + expect(result).toEqual([Query.limit(25)]) + }) + + test('offset', () => { + const result = q().offset(50).build() + expect(result).toEqual([Query.offset(50)]) + }) + + test('cursorAfter', () => { + const result = q().cursorAfter('doc123').build() + expect(result).toEqual([Query.cursorAfter('doc123')]) + }) + + test('cursorBefore', () => { + const result = q().cursorBefore('doc456').build() + expect(result).toEqual([Query.cursorBefore('doc456')]) + }) + + test('limit and offset together', () => { + const result = q().limit(10).offset(20).build() + expect(result).toEqual([Query.limit(10), Query.offset(20)]) + }) + }) + + describe('timestamp methods', () => { + const iso = '2025-01-01T00:00:00.000Z' + const isoEnd = '2025-12-31T23:59:59.999Z' + + test('createdBefore', () => { + const result = q().createdBefore(iso).build() + expect(result).toEqual([Query.createdBefore(iso)]) + }) + + test('createdAfter', () => { + const result = q().createdAfter(iso).build() + expect(result).toEqual([Query.createdAfter(iso)]) + }) + + test('createdBetween', () => { + const result = q().createdBetween(iso, isoEnd).build() + expect(result).toEqual([Query.createdBetween(iso, isoEnd)]) + }) + + test('updatedBefore', () => { + const result = q().updatedBefore(iso).build() + expect(result).toEqual([Query.updatedBefore(iso)]) + }) + + test('updatedAfter', () => { + const result = q().updatedAfter(iso).build() + expect(result).toEqual([Query.updatedAfter(iso)]) + }) + + test('updatedBetween', () => { + const result = q().updatedBetween(iso, isoEnd).build() + expect(result).toEqual([Query.updatedBetween(iso, isoEnd)]) + }) + }) + + // ─── Logical Composition ──────────────────────────────────────── + + describe('logical composition', () => { + test('or with two sub-builders', () => { + const result = q() + .or(q().equal('name', 'Alice'), q().equal('name', 'Bob')) + .build() + + expect(result).toEqual([Query.or([Query.equal('name', 'Alice'), Query.equal('name', 'Bob')])]) + }) + + test('and with two sub-builders', () => { + const result = q() + .and(q().equal('name', 'Alice'), q().greaterThan('age', 18)) + .build() + + expect(result).toEqual([ + Query.and([Query.equal('name', 'Alice'), Query.greaterThan('age', 18)]), + ]) + }) + + test('or with multiple conditions per sub-builder', () => { + const result = q() + .or( + q().equal('name', 'Alice').greaterThan('age', 30), + q().equal('name', 'Bob').lessThan('age', 20), + ) + .build() + + expect(result).toEqual([ + Query.or([ + Query.equal('name', 'Alice'), + Query.greaterThan('age', 30), + Query.equal('name', 'Bob'), + Query.lessThan('age', 20), + ]), + ]) + }) + + test('nested or inside and', () => { + const result = q() + .and( + q().greaterThan('age', 18), + q().or(q().equal('name', 'Alice'), q().equal('name', 'Bob')), + ) + .build() + + expect(result).toEqual([ + Query.and([ + Query.greaterThan('age', 18), + Query.or([Query.equal('name', 'Alice'), Query.equal('name', 'Bob')]), + ]), + ]) + }) + }) + + describe('elemMatch', () => { + test('elemMatch with sub-query', () => { + const result = q() + .elemMatch('scores', q().greaterThan('age', 90)) + .build() + + expect(result).toEqual([Query.elemMatch('scores', [Query.greaterThan('age', 90)])]) + }) + }) + + describe('geo and distance methods', () => { + const points: [number, number][] = [ + [0, 0], + [1, 0], + [1, 1], + [0, 1], + ] + + test('distanceEqual', () => { + const result = q().distanceEqual('location', 40.7, -74.0, 1000).build() + expect(result).toEqual([Query.distanceEqual('location', [40.7, -74.0], 1000, true)]) + }) + + test('distanceEqual with meters=false', () => { + const result = q().distanceEqual('location', 40.7, -74.0, 1000, false).build() + expect(result).toEqual([Query.distanceEqual('location', [40.7, -74.0], 1000, false)]) + }) + + test('distanceNotEqual', () => { + const result = q().distanceNotEqual('location', 40.7, -74.0, 500).build() + expect(result).toEqual([Query.distanceNotEqual('location', [40.7, -74.0], 500, true)]) + }) + + test('distanceGreaterThan', () => { + const result = q().distanceGreaterThan('location', 40.7, -74.0, 100).build() + expect(result).toEqual([Query.distanceGreaterThan('location', [40.7, -74.0], 100, true)]) + }) + + test('distanceLessThan', () => { + const result = q().distanceLessThan('location', 40.7, -74.0, 5000).build() + expect(result).toEqual([Query.distanceLessThan('location', [40.7, -74.0], 5000, true)]) + }) + + test('intersects', () => { + const result = q().intersects('location', points).build() + expect(result).toEqual([Query.intersects('location', points)]) + }) + + test('notIntersects', () => { + const result = q().notIntersects('location', points).build() + expect(result).toEqual([Query.notIntersects('location', points)]) + }) + + test('crosses', () => { + const result = q().crosses('location', points).build() + expect(result).toEqual([Query.crosses('location', points)]) + }) + + test('notCrosses', () => { + const result = q().notCrosses('location', points).build() + expect(result).toEqual([Query.notCrosses('location', points)]) + }) + + test('overlaps', () => { + const result = q().overlaps('location', points).build() + expect(result).toEqual([Query.overlaps('location', points)]) + }) + + test('notOverlaps', () => { + const result = q().notOverlaps('location', points).build() + expect(result).toEqual([Query.notOverlaps('location', points)]) + }) + + test('touches', () => { + const result = q().touches('location', points).build() + expect(result).toEqual([Query.touches('location', points)]) + }) + + test('notTouches', () => { + const result = q().notTouches('location', points).build() + expect(result).toEqual([Query.notTouches('location', points)]) + }) + }) + + describe('chaining', () => { + test('multiple different methods produce correct array', () => { + const result = q() + .equal('name', 'Alice') + .greaterThan('age', 18) + .isNotNull('tags') + .orderAsc('name') + .limit(10) + .offset(0) + .build() + + expect(result).toEqual([ + Query.equal('name', 'Alice'), + Query.greaterThan('age', 18), + Query.isNotNull('tags'), + Query.orderAsc('name'), + Query.limit(10), + Query.offset(0), + ]) + }) + + test('preserves insertion order', () => { + const result = q().limit(5).equal('name', 'Alice').orderDesc('age').build() + + expect(result).toEqual([Query.limit(5), Query.equal('name', 'Alice'), Query.orderDesc('age')]) + }) + + test('complex real-world query', () => { + const result = q() + .greaterThanEqual('age', 21) + .equal('active', true) + .contains('tags', 'verified') + .select(['name', 'age', 'tags']) + .orderDesc('age') + .limit(50) + .build() + + expect(result).toEqual([ + Query.greaterThanEqual('age', 21), + Query.equal('active', true), + Query.contains('tags', 'verified'), + Query.select(['name', 'age', 'tags']), + Query.orderDesc('age'), + Query.limit(50), + ]) + }) + }) + + describe('interoperability', () => { + test('build() output can be spread with raw Query strings', () => { + const builderQueries = q().equal('name', 'Alice').greaterThan('age', 18).build() + const combined = [...builderQueries, Query.limit(10)] + + expect(combined).toEqual([ + Query.equal('name', 'Alice'), + Query.greaterThan('age', 18), + Query.limit(10), + ]) + }) + + test('output strings match Query class output exactly', () => { + const builderOutput = q().equal('name', 'Alice').build()[0] + const directOutput = Query.equal('name', 'Alice') + expect(builderOutput).toBe(directOutput) + }) + }) + + describe('type safety', () => { + test('rejects invalid field names', () => { + // @ts-expect-error — 'nme' is not a key of User + q().equal('nme', 'Alice') + }) + + test('rejects wrong value type for numeric field', () => { + // @ts-expect-error — age expects number, not string + q().greaterThan('age', '18') + }) + + test('rejects wrong value type for boolean field', () => { + // @ts-expect-error — active expects boolean, not string + q().equal('active', 'yes') + }) + + test('rejects invalid field in select', () => { + // @ts-expect-error — 'invalid' is not a key of User + q().select(['name', 'invalid']) + }) + + test('rejects invalid field in orderAsc', () => { + // @ts-expect-error — 'invalid' is not a key of User + q().orderAsc('invalid') + }) + + test('rejects invalid field in isNull', () => { + // @ts-expect-error — 'invalid' is not a key of User + q().isNull('invalid') + }) + + test('works with different document types', () => { + const result = q() + .equal('title', 'Hello World') + .greaterThan('views', 100) + .equal('published', true) + .build() + + expect(result).toEqual([ + Query.equal('title', 'Hello World'), + Query.greaterThan('views', 100), + Query.equal('published', true), + ]) + }) + }) +}) diff --git a/tests/setup/ErrorBoundry.tsx b/tests/setup/ErrorBoundry.tsx new file mode 100644 index 0000000..ceadd08 --- /dev/null +++ b/tests/setup/ErrorBoundry.tsx @@ -0,0 +1,40 @@ +import { Component } from 'react' +import type { ReactNode } from 'react' + +interface ErrorBoundaryProps { + children: ReactNode + fallback: ReactNode +} + +interface ErrorBoundaryState { + hasError: boolean + error: Error | null +} + +class ErrorBoundary extends Component { + state: ErrorBoundaryState = { hasError: false, error: null } + + // This lifecycle method is called if an error is thrown during rendering + static getDerivedStateFromError(error) { + // Update state so the next render shows the fallback UI. + return { hasError: true, error: error } + } + + // This lifecycle method is used for logging error information + componentDidCatch(error, info) { + // Example: Log the error to an error reporting service + // logErrorToMyService(error, info.componentStack); + console.error('Error caught by ErrorBoundary:', error, info) + } + + render() { + if (this.state.hasError) { + // You can render any custom fallback UI + return this.props.fallback + } + + return this.props.children + } +} + +export default ErrorBoundary diff --git a/tests/setup/code.tar.gz b/tests/setup/code.tar.gz new file mode 100644 index 0000000..1e9d128 Binary files /dev/null and b/tests/setup/code.tar.gz differ diff --git a/tests/setup/helpers.ts b/tests/setup/helpers.ts index 752edb7..44ba4cc 100644 --- a/tests/setup/helpers.ts +++ b/tests/setup/helpers.ts @@ -1,16 +1,35 @@ +import { act, renderHook, waitFor as waitForTest } from '@testing-library/react' +import { expect } from 'bun:test' +import { MailpitClient } from 'mailpit-api' import { existsSync, readFileSync } from 'node:fs' -import { Client, Account, Databases, Users, ID } from 'node-appwrite' +import { Account, Client, Databases, ID, Messaging, TablesDB, Users } from 'node-appwrite' +import { TOTP } from 'otpauth' -type TestConfig = { +import type { createWrapper } from './wrapper' +import { + useCreateMfaAuthenticator, + useLogin, + useLogout, + useUpdateMfa, + useUpdateMfaAuthenticator, +} from '../../src' + +export type TestConfig = { endpoint: string projectId: string apiKey: string databaseId: string collectionId: string + bucketId: string + smtpProviderId: string + smsProviderId: string + topicId: string } let _config: TestConfig | null = null +const mailpit = new MailpitClient('http://localhost:8025') + export function getTestConfig(): TestConfig { if (_config) return _config @@ -28,6 +47,10 @@ export function getTestConfig(): TestConfig { apiKey: process.env.APPWRITE_API_KEY || '', databaseId: process.env.APPWRITE_DATABASE_ID || 'test-db', collectionId: process.env.APPWRITE_COLLECTION_ID || 'test-collection', + bucketId: 'test-bucket', + smtpProviderId: 'test-smtp', + smsProviderId: 'test-sms', + topicId: 'test-topic', } return _config } @@ -35,13 +58,18 @@ export function getTestConfig(): TestConfig { /** Create a server-side Appwrite client with API key */ export function createServerClient() { const config = getTestConfig() - const client = new Client().setEndpoint(config.endpoint).setProject(config.projectId).setKey(config.apiKey) + const client = new Client() + .setEndpoint(config.endpoint) + .setProject(config.projectId) + .setKey(config.apiKey) return { client, databases: new Databases(client), users: new Users(client), account: new Account(client), + tablesDB: new TablesDB(client), + messaging: new Messaging(client), } } @@ -56,7 +84,7 @@ export async function createTestUser(opts?: { name?: string }) { const name = opts?.name || `Test User ${_userCounter}` const { users } = createServerClient() - const user = await users.create(ID.unique(), email, undefined, password, name) + const user = await users.create({ userId: ID.unique(), email, password, name }) return { userId: user.$id, email, password, name } } @@ -65,7 +93,7 @@ export async function createTestUser(opts?: { name?: string }) { export async function deleteTestUser(userId: string) { const { users } = createServerClient() try { - await users.delete(userId) + await users.delete({ userId }) } catch { // User may already be deleted } @@ -74,24 +102,37 @@ export async function deleteTestUser(userId: string) { /** Create a test document via server SDK */ export async function createTestDocument(data: Record, documentId?: string) { const config = getTestConfig() - const { databases } = createServerClient() + const { tablesDB } = createServerClient() - return databases.createDocument(config.databaseId, config.collectionId, documentId || ID.unique(), data) + return tablesDB.createRow({ + databaseId: config.databaseId, + tableId: config.collectionId, + rowId: documentId || ID.unique(), + data, + }) } /** Delete a test document via server SDK */ export async function deleteTestDocument(documentId: string) { const config = getTestConfig() - const { databases } = createServerClient() + const { tablesDB } = createServerClient() try { - await databases.deleteDocument(config.databaseId, config.collectionId, documentId) + await tablesDB.deleteRow({ + databaseId: config.databaseId, + tableId: config.collectionId, + rowId: documentId, + }) } catch { // Document may already be deleted } } /** Wait for a condition to be true, with timeout */ -export async function waitFor(fn: () => boolean | Promise, timeoutMs = 10000, intervalMs = 100) { +export async function waitFor( + fn: () => boolean | Promise, + timeoutMs = 10000, + intervalMs = 100, +) { const start = Date.now() while (Date.now() - start < timeoutMs) { if (await fn()) return @@ -99,3 +140,122 @@ export async function waitFor(fn: () => boolean | Promise, timeoutMs = } throw new Error(`waitFor timed out after ${timeoutMs}ms`) } + +/** Get a user's email target ID via server SDK */ +export async function getUserEmailTargetId(userId: string): Promise { + const { users } = createServerClient() + const user = await users.get({ userId }) + const emailTarget = user.targets.find((t: any) => t.providerType === 'email') + if (!emailTarget) { + throw new Error(`No email target found for user ${userId}`) + } + return emailTarget.$id +} + +/** Send a test email to a topic via server SDK and wait for delivery */ +export async function sendTopicEmail(opts: { + topicId: string + subject: string + content: string +}): Promise { + const { messaging } = createServerClient() + const msg = await messaging.createEmail({ + messageId: ID.unique(), + subject: opts.subject, + content: opts.content, + topics: [opts.topicId], + }) + + // Poll for delivery (max 10s) + for (let i = 0; i < 10; i++) { + await new Promise((r) => setTimeout(r, 1000)) + const status = await messaging.getMessage({ messageId: msg.$id }) + if (status.status !== 'processing') break + } + + return msg.$id +} + +export function generateTOTP(secret: string): string { + const totp = new TOTP({ secret, algorithm: 'SHA1', digits: 6, period: 30 }) + return totp.generate() +} + +export async function setupOTP(wrapper: ReturnType) { + const { result } = renderHook(() => useUpdateMfa(), { wrapper }) + + await act(async () => { + await result.current.mutateAsync({ mfa: true }) + }) + + await waitForTest(() => expect(result.current.isSuccess).toBe(true)) + + const { result: createMfaAuthenticatorResult } = renderHook(() => useCreateMfaAuthenticator(), { + wrapper, + }) + await act(async () => { + await createMfaAuthenticatorResult.current.mutateAsync({ type: 'totp' }) + }) + await waitForTest(() => expect(createMfaAuthenticatorResult.current.isSuccess).toBe(true)) + + const totpSecret = createMfaAuthenticatorResult.current.data?.secret || '' + const otp = generateTOTP(totpSecret) + + const { result: updateMfaAuthenticatorResult } = renderHook(() => useUpdateMfaAuthenticator(), { + wrapper, + }) + + await act(async () => { + await updateMfaAuthenticatorResult.current.mutateAsync({ type: 'totp', otp }) + }) + + await waitForTest(() => expect(updateMfaAuthenticatorResult.current.isSuccess).toBe(true)) + + return { totpSecret } +} + +export async function loginUser( + email: string, + password: string, + wrapper: ReturnType, +): Promise { + const { result } = renderHook(() => useLogin(), { wrapper }) + + await act(async () => { + await result.current.login.mutateAsync({ email, password }) + }) + + await waitForTest(() => expect(result.current.login.isSuccess).toBe(true)) +} + +export async function logoutUser(wrapper: ReturnType): Promise { + const { result } = renderHook(() => useLogout(), { wrapper }) + await act(async () => { + await result.current.mutateAsync({ sessionId: 'current' }) + }) + await waitForTest(() => expect(result.current.isSuccess).toBe(true)) +} + +export async function checkMail() { + const emails = await mailpit.listMessages() + return emails +} + +export async function renderMessage(messageId: string) { + const content = await mailpit.renderMessageHTML(messageId) + document.body.innerHTML = content + return content +} + +export async function emptyMail() { + await mailpit.deleteMessages() +} + +export async function getSMSMessages() { + const messages = await fetch('http://localhost:8888/messages').then((res) => res.json()) + return messages +} + +export async function clearSMSMessages() { + await fetch('http://localhost:8888/messages', { method: 'DELETE' }) +} diff --git a/tests/setup/preload.ts b/tests/setup/preload.ts index 4b178f9..dd34d79 100644 --- a/tests/setup/preload.ts +++ b/tests/setup/preload.ts @@ -1,4 +1,3 @@ -// @ts-ignore - happy-dom may not ship type declarations import { GlobalRegistrator } from '@happy-dom/global-registrator' import { configure } from '@testing-library/react' @@ -8,6 +7,14 @@ configure({ asyncUtilTimeout: 5000 }) // Prevent happy-dom's fetch cookie jar from leaking sessions between tests. // The Appwrite SDK falls back to localStorage (X-Fallback-Cookies header) when // browser cookies are unavailable, which we control via createWrapper(). +// Suppress Appwrite's localStorage session warning in test output +const _warn = console.warn +console.warn = (...args: unknown[]) => { + if (typeof args[0] === 'string' && args[0].includes('Appwrite is using localStorage')) + return + _warn(...args) +} + const _fetch = globalThis.fetch const patchedFetch = (input: any, init?: any) => _fetch(input, init ? { ...init, credentials: 'omit' as const } : init) diff --git a/tests/setup/setup.ts b/tests/setup/setup.ts index 5c34286..f7eb6cf 100644 --- a/tests/setup/setup.ts +++ b/tests/setup/setup.ts @@ -3,7 +3,9 @@ * Creates admin account, project, API key, database, and collections. * Run this once before tests: `bun run tests/setup/setup.ts` */ -import { Client, Databases, ID, Permission, Role } from 'node-appwrite' +import { Client, Databases, ID, Permission, Role, Runtime, TablesDB } from 'node-appwrite' + +import type { TestConfig } from './helpers' const ENDPOINT = process.env.APPWRITE_ENDPOINT || 'http://localhost/v1' const ADMIN_EMAIL = 'admin@test.local' @@ -11,23 +13,46 @@ const ADMIN_PASSWORD = 'password123456' const PROJECT_ID = 'test-project' const DATABASE_ID = 'test-db' const COLLECTION_ID = 'test-collection' +const BUCKET_ID = 'test-bucket' +const SMTP_PROVIDER_ID = 'test-smtp' +const TOPIC_ID = 'test-topic' +const SMS_PROVIDER_ID = 'test-sms' const ALL_SCOPES = [ - 'users.read', 'users.write', - 'teams.read', 'teams.write', - 'databases.read', 'databases.write', - 'collections.read', 'collections.write', - 'attributes.read', 'attributes.write', - 'indexes.read', 'indexes.write', - 'documents.read', 'documents.write', - 'files.read', 'files.write', - 'buckets.read', 'buckets.write', - 'functions.read', 'functions.write', - 'execution.read', 'execution.write', + 'users.read', + 'users.write', + 'teams.read', + 'teams.write', + 'databases.read', + 'databases.write', + 'collections.read', + 'collections.write', + 'attributes.read', + 'attributes.write', + 'indexes.read', + 'indexes.write', + 'documents.read', + 'documents.write', + 'files.read', + 'files.write', + 'buckets.read', + 'buckets.write', + 'functions.read', + 'functions.write', + 'execution.read', + 'execution.write', 'locale.read', 'avatars.read', 'health.read', 'sessions.write', + 'providers.read', + 'providers.write', + 'topics.write', + 'subscribers.read', + 'subscribers.write', + 'targets.read', + 'messages.read', + 'messages.write', ] async function waitForAppwrite(maxRetries = 60) { @@ -66,7 +91,11 @@ async function createAdminAccount(): Promise { if (!resp.ok) { const body = await resp.text() - if (body.includes('already exists') || body.includes('user_already_exists') || body.includes('user_console_count_exceeded')) { + if ( + body.includes('already exists') || + body.includes('user_already_exists') || + body.includes('user_console_count_exceeded') + ) { console.log('Admin account already exists, logging in...') return loginAdmin() } @@ -239,11 +268,12 @@ async function setupDatabase(apiKey: string) { console.log('Setting up database and collections...') const client = new Client().setEndpoint(ENDPOINT).setProject(PROJECT_ID).setKey(apiKey) + const tablesDb = new TablesDB(client) const databases = new Databases(client) // Create database try { - await databases.create(DATABASE_ID, 'Test Database') + await tablesDb.create({ databaseId: DATABASE_ID, name: 'Test Database' }) console.log(`Database "${DATABASE_ID}" created`) } catch (e: any) { if (e?.code === 409) { @@ -255,25 +285,49 @@ async function setupDatabase(apiKey: string) { // Create collection with document-level permissions try { - await databases.createCollection(DATABASE_ID, COLLECTION_ID, 'Test Collection', [ - Permission.read(Role.any()), - Permission.create(Role.users()), - Permission.update(Role.users()), - Permission.delete(Role.users()), - ]) + await tablesDb.createTable({ + databaseId: DATABASE_ID, + tableId: COLLECTION_ID, + name: 'Test Collection', + permissions: [ + Permission.read(Role.any()), + Permission.create(Role.users()), + Permission.update(Role.users()), + Permission.delete(Role.users()), + ], + }) console.log(`Collection "${COLLECTION_ID}" created`) } catch (e: any) { if (e?.code === 409) { console.log('Collection already exists') - return + } else { + throw e } - throw e } - // Create attributes - await databases.createStringAttribute(DATABASE_ID, COLLECTION_ID, 'name', 255, true) - await databases.createIntegerAttribute(DATABASE_ID, COLLECTION_ID, 'age', false) - await databases.createBooleanAttribute(DATABASE_ID, COLLECTION_ID, 'active', false) + // Create attributes via Databases API (TablesDB.createTable columns param is not supported) + const attributes = [ + { method: 'createStringAttribute', params: { key: 'name', size: 255, required: true } }, + { method: 'createIntegerAttribute', params: { key: 'age', required: false } }, + { method: 'createBooleanAttribute', params: { key: 'active', required: false } }, + ] as const + + for (const attr of attributes) { + try { + await (databases[attr.method] as any)({ + databaseId: DATABASE_ID, + collectionId: COLLECTION_ID, + ...attr.params, + }) + console.log(`Attribute "${attr.params.key}" created`) + } catch (e: any) { + if (e?.code === 409) { + console.log(`Attribute "${attr.params.key}" already exists`) + } else { + throw e + } + } + } // Wait for attributes to be processed console.log('Waiting for attributes to be processed...') @@ -282,6 +336,259 @@ async function setupDatabase(apiKey: string) { console.log('Database setup complete!') } +async function setupBucket(apiKey: string) { + console.log('Setting up storage bucket...') + + const resp = await fetch(`${ENDPOINT}/storage/buckets`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-Appwrite-Project': PROJECT_ID, + 'X-Appwrite-Key': apiKey, + }, + body: JSON.stringify({ + bucketId: BUCKET_ID, + name: 'Test Bucket', + fileSecurity: true, + permissions: [ + Permission.read(Role.any()), + Permission.create(Role.users()), + Permission.update(Role.users()), + Permission.delete(Role.users()), + ], + }), + }) + + if (!resp.ok) { + const body = await resp.text() + if (body.includes('already exists') || body.includes('storage_bucket_already_exists')) { + console.log('Bucket already exists') + return + } + throw new Error(`Failed to create bucket: ${body}`) + } + + console.log(`Bucket "${BUCKET_ID}" created!`) +} + +async function setupMessaging(apiKey: string) { + console.log('Setting up messaging topics...') + + const resp = await fetch(`${ENDPOINT}/messaging/providers/smtp`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-Appwrite-Project': PROJECT_ID, + 'X-Appwrite-Key': apiKey, + }, + body: JSON.stringify({ + providerId: SMTP_PROVIDER_ID, + name: 'Test SMTP Provider', + host: 'host.docker.internal', + port: 1025, + secure: false, + enabled: true, + fromEmail: 'test@test.local', + fromName: 'Test Sender', + }), + }) + + if (!resp.ok) { + const body = await resp.text() + if (body.includes('already exists') || body.includes('messaging_provider_already_exists')) { + console.log('Messaging provider already exists, updating...') + const updateResp = await fetch(`${ENDPOINT}/messaging/providers/smtp/${SMTP_PROVIDER_ID}`, { + method: 'PATCH', + headers: { + 'Content-Type': 'application/json', + 'X-Appwrite-Project': PROJECT_ID, + 'X-Appwrite-Key': apiKey, + }, + body: JSON.stringify({ + enabled: true, + fromEmail: 'test@test.local', + fromName: 'Test Sender', + host: 'host.docker.internal', + port: 1025, + }), + }) + if (!updateResp.ok) { + console.warn(`Warning: Failed to update provider: ${await updateResp.text()}`) + } + } else { + throw new Error(`Failed to create messaging provider: ${body}`) + } + } + + console.log('SMTP provider created!') + + const smsResp = await fetch(`${ENDPOINT}/messaging/providers/twilio`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-Appwrite-Project': PROJECT_ID, + 'X-Appwrite-Key': apiKey, + }, + body: JSON.stringify({ + providerId: SMS_PROVIDER_ID, + name: 'Test Twilio SMS Provider', + accountSid: 'test', + enabled: true, + }), + }) + + if (!smsResp.ok) { + const body = await smsResp.text() + if (body.includes('already exists') || body.includes('messaging_provider_already_exists')) { + console.log('SMS provider already exists, updating...') + const updateResp = await fetch(`${ENDPOINT}/messaging/providers/twilio/${SMS_PROVIDER_ID}`, { + method: 'PATCH', + headers: { + 'Content-Type': 'application/json', + 'X-Appwrite-Project': PROJECT_ID, + 'X-Appwrite-Key': apiKey, + }, + body: JSON.stringify({ + enabled: true, + accountSid: 'test', + }), + }) + if (!updateResp.ok) { + console.warn(`Warning: Failed to update SMS provider: ${await updateResp.text()}`) + } + } else { + throw new Error(`Failed to create SMS provider: ${body}`) + } + } + + console.log('SMS provider created!') + + // Create a topic + console.log('Creating messaging topic...') + + const topicResp = await fetch(`${ENDPOINT}/messaging/topics`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-Appwrite-Project': PROJECT_ID, + 'X-Appwrite-Key': apiKey, + }, + body: JSON.stringify({ + topicId: TOPIC_ID, + name: 'Test Topic', + }), + }) + + if (!topicResp.ok) { + const body = await topicResp.text() + if (body.includes('already exists') || body.includes('messaging_topic_already_exists')) { + console.log('Messaging topic already exists') + return + } + throw new Error(`Failed to create messaging topic: ${body}`) + } + + console.log('Messaging topic created!') +} + +async function deployFunction(apiKey: string) { + console.log('Deploying test function...') + + const resp = await fetch(`${ENDPOINT}/functions`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-Appwrite-Project': PROJECT_ID, + 'X-Appwrite-Key': apiKey, + }, + body: JSON.stringify({ + functionId: 'test-function', + name: 'Test Function', + execute: [Role.any()], + runtime: Runtime.Node22, + enabled: true, + entrypoint: 'index.js', + commands: 'npm i', + }), + }) + + if (!resp.ok) { + const body = await resp.text() + if (body.includes('already exists') || body.includes('function_already_exists')) { + console.log('Function already exists, skipping deployment') + return + } else { + const runtimes = await fetch(`${ENDPOINT}/functions/runtimes`, { + headers: { + 'X-Appwrite-Project': PROJECT_ID, + }, + }).then((r) => r.json()) + console.error('Available runtimes:', runtimes) + throw new Error(`Failed to create function: ${body}`) + } + } + + //@ts-expect-error - FormData types are wrong + const codePath = new URL('./code.tar.gz', import.meta.url) + const codeFile = Bun.file(codePath) + const formData = new FormData() + formData.append('functionId', 'test-function') + formData.append('code', codeFile, 'code.tar.gz') + formData.append('activate', 'true') + + const deployResp = await fetch(`${ENDPOINT}/functions/test-function/deployments`, { + method: 'POST', + headers: { + 'X-Appwrite-Project': PROJECT_ID, + 'X-Appwrite-Key': apiKey, + }, + body: formData, + }) + + if (!deployResp.ok) { + throw new Error(`Failed to deploy function: ${await deployResp.text()}`) + } + + const deployment = await deployResp.json() + + const deploymentId = deployment.$id + console.log('Waiting for deployment to be ready...') + await new Promise((r) => setTimeout(r, 3000)) + + console.log(`Deployment "${deploymentId}" created, activating...`) + + const setDeployment = await fetch(`${ENDPOINT}/functions/test-function/deployment`, { + method: 'PATCH', + headers: { + 'Content-Type': 'application/json', + 'X-Appwrite-Project': PROJECT_ID, + 'X-Appwrite-Key': apiKey, + }, + body: JSON.stringify({ + functionId: 'test-function', + deploymentId, + }), + }) + + if (!setDeployment.ok) { + const theDeplymnet = await fetch( + `${ENDPOINT}/functions/test-function/deployments/${deploymentId}`, + { + headers: { + 'X-Appwrite-Project': PROJECT_ID, + 'X-Appwrite-Key': apiKey, + }, + }, + ).then((r) => r.json()) + console.log('Deployment details:', theDeplymnet) + + console.error(`Failed to set active deployment: ${deploymentId}`) + throw new Error(`Failed to set active deployment: ${await setDeployment.text()}`) + } + + console.log('Function created!') +} + async function main() { await waitForAppwrite() @@ -290,6 +597,9 @@ async function main() { await createProject(cookies, teamId) const apiKey = await createApiKey(cookies) await setupDatabase(apiKey) + await setupBucket(apiKey) + await setupMessaging(apiKey) + await deployFunction(apiKey) // Output env vars for tests console.log('\n=== Test Configuration ===') @@ -302,12 +612,16 @@ async function main() { ) // Write config to a file for test consumption - const config = { + const config: TestConfig = { endpoint: ENDPOINT, projectId: PROJECT_ID, apiKey, databaseId: DATABASE_ID, collectionId: COLLECTION_ID, + bucketId: BUCKET_ID, + smtpProviderId: SMTP_PROVIDER_ID, + smsProviderId: SMS_PROVIDER_ID, + topicId: TOPIC_ID, } await Bun.write('tests/.test-config.json', JSON.stringify(config, null, 2)) diff --git a/tests/setup/test-function/index.js b/tests/setup/test-function/index.js new file mode 100644 index 0000000..d6a958d --- /dev/null +++ b/tests/setup/test-function/index.js @@ -0,0 +1,18 @@ +import { setTimeout as delay } from 'node:timers/promises'; + +export default async function ({ req, res }) { + if (req.path === '/long') { + await delay(5000); + return res.text('This response was delayed by 5 seconds'); + } + + if (req.path === '/error') { + return res.status(500).text('This is an error response'); + } + + if (req.path === '/json') { + return res.json({ message: 'This is a JSON response' }); + } + + return res.text('Invalid path'); +} \ No newline at end of file diff --git a/tests/setup/test-function/package.json b/tests/setup/test-function/package.json new file mode 100644 index 0000000..7b84d23 --- /dev/null +++ b/tests/setup/test-function/package.json @@ -0,0 +1,11 @@ +{ + "name": "test-function", + "version": "1.0.0", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "description": "" +} diff --git a/tests/setup/wrapper.tsx b/tests/setup/wrapper.tsx index 7c61560..fd146b3 100644 --- a/tests/setup/wrapper.tsx +++ b/tests/setup/wrapper.tsx @@ -1,11 +1,20 @@ -import { QueryClient } from '@tanstack/react-query' -import { Provider } from 'jotai' import * as React from 'react' -import { AppwriteProvider } from '../../src/AppwriteProvider' +import { QueryClient } from '@tanstack/react-query' + +import ErrorBoundary from './ErrorBoundry' import { getTestConfig } from './helpers' +import type { Persister } from '../../src' +import { createAppwriteClient } from '../../src' +import { AppwriteProvider } from '../../src/AppwriteProvider' +import type { AppwriteClient } from '../../src/client' const { Suspense } = React -export function createWrapper(opts?: { queryClient?: QueryClient; suspense?: boolean }) { +export function createWrapper(opts?: { + queryClient?: QueryClient + suspense?: boolean + client?: AppwriteClient + persister?: Persister +}) { const config = getTestConfig() const queryClient = opts?.queryClient ?? @@ -21,21 +30,30 @@ export function createWrapper(opts?: { queryClient?: QueryClient; suspense?: boo globalThis.localStorage.removeItem('cookieFallback') } + const appwriteClient = + opts?.client ?? + createAppwriteClient({ + endpoint: config.endpoint, + projectId: config.projectId, + }) + return function TestWrapper({ children }: { children: React.ReactNode }) { const inner = ( - - - {children} - - + + {children} + ) if (opts?.suspense) { - return Loading...}>{inner} + return ( + Error occurred}> + Loading...}>{inner} + + ) } return inner diff --git a/tests/sms-mock/server.js b/tests/sms-mock/server.js new file mode 100644 index 0000000..7dacb9e --- /dev/null +++ b/tests/sms-mock/server.js @@ -0,0 +1,38 @@ +const http = require('http') + +const messages = [] + +const server = http.createServer((req, res) => { + if (req.method === 'POST') { + let body = '' + req.on('data', (chunk) => (body += chunk)) + req.on('end', () => { + try { + const msg = JSON.parse(body) + messages.push({ ...msg, timestamp: Date.now() }) + console.log(`SMS to ${msg.to}: ${msg.message}`) + } catch { + messages.push({ raw: body, timestamp: Date.now() }) + } + res.writeHead(200, { 'Content-Type': 'application/json' }) + res.end(JSON.stringify({ ok: true })) + }) + } else if (req.method === 'GET' && req.url === '/messages') { + res.writeHead(200, { 'Content-Type': 'application/json' }) + res.end(JSON.stringify(messages.sort((a, b) => b.timestamp - a.timestamp))) + } else if (req.method === 'GET' && req.url.startsWith('/messages/')) { + const phone = decodeURIComponent(req.url.slice('/messages/'.length)) + const filtered = messages.filter((m) => m.to?.includes(phone)) + res.writeHead(200, { 'Content-Type': 'application/json' }) + res.end(JSON.stringify(filtered.sort((a, b) => b.timestamp - a.timestamp))) + } else if (req.method === 'DELETE' && req.url === '/messages') { + messages.length = 0 + res.writeHead(200, { 'Content-Type': 'application/json' }) + res.end(JSON.stringify({ ok: true })) + } else { + res.writeHead(200, { 'Content-Type': 'application/json' }) + res.end(JSON.stringify({ status: 'sms-mock running', count: messages.length })) + } +}) + +server.listen(5000, '0.0.0.0', () => console.log('SMS mock catcher listening on :5000')) diff --git a/tests/storage/storage.test.tsx b/tests/storage/storage.test.tsx index bee35ba..add35fa 100644 --- a/tests/storage/storage.test.tsx +++ b/tests/storage/storage.test.tsx @@ -1,20 +1,149 @@ -import { renderHook } from '@testing-library/react' -import { describe, expect, test } from 'bun:test' +import { act } from 'react' +import { renderHook, waitFor } from '@testing-library/react' +import { afterAll, beforeAll, describe, expect, test } from 'bun:test' +import { Permission, Role } from 'node-appwrite' -import { useFileDownload, useFilePreview, useFileView } from '../../src' +import { + useCreateFile, + useDeleteFile, + useFile, + useFileDownload, + useFilePreview, + useFiles, + useFileView, + useUpdateFile, +} from '../../src' +import { createTestUser, deleteTestUser, loginUser } from '../setup/helpers' import { createWrapper } from '../setup/wrapper' -/* - * Storage content hooks (useFileDownload, useFilePreview, useFileView) - * return URL strings via the REST SDK — they don't make API calls. - * We verify they produce well-formed URLs. - * - * The GraphQL-based storage hooks (useFile, useFiles, useCreateFile, etc.) - * require a storage bucket to be set up. Since the test setup doesn't create one, - * we test the URL-generating hooks which work without server state. - */ - describe('Storage content URL hooks', () => { + let userEmail: string + let userPassword: string + let userId: string + + beforeAll(async () => { + const user = await createTestUser({ name: 'Storage Test User' }) + userId = user.userId + userEmail = user.email + userPassword = user.password + }) + + afterAll(async () => { + await deleteTestUser(userId) + }) + + describe('full file lifecycle', () => { + test('useCreateFile', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + const { result: createResult } = renderHook(() => useCreateFile(), { wrapper }) + + expect(createResult.current).toBeDefined() + + await act(async () => { + const file = new File(['This is a test file.'], 'test-file.txt', { type: 'text/plain' }) + await createResult.current.mutateAsync({ + bucketId: 'test-bucket', + fileId: 'test-file', + file, + permissions: [ + Permission.read(Role.any()), + Permission.update(Role.users()), + Permission.delete(Role.users()), + Permission.write(Role.users()), + ], + }) + }) + + await waitFor(() => { + expect(createResult.current.isSuccess).toBe(true) + expect(createResult.current.data).toBeDefined() + expect(createResult.current.data.bucketId).toBe('test-bucket') + expect(createResult.current.data.name).toBe('test-file.txt') + }) + }) + + test('useFile', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + const { result: fileResult } = renderHook( + () => useFile({ bucketId: 'test-bucket', fileId: 'test-file' }), + { wrapper }, + ) + + await waitFor(() => { + expect(fileResult.current.isSuccess).toBe(true) + expect(fileResult.current.data).toBeDefined() + expect(fileResult.current.data.bucketId).toBe('test-bucket') + expect(fileResult.current.data.name).toBe('test-file.txt') + }) + }) + + test('useUpdateFile', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + const { result: updateResult } = renderHook(() => useUpdateFile(), { wrapper }) + + expect(updateResult.current).toBeDefined() + + await act(async () => { + await updateResult.current.mutateAsync({ + bucketId: 'test-bucket', + fileId: 'test-file', + name: 'updated-file.txt', + permissions: [ + Permission.read(Role.any()), + Permission.update(Role.users()), + Permission.delete(Role.users()), + Permission.write(Role.users()), + ], + }) + }) + + await waitFor(() => { + expect(updateResult.current.isSuccess).toBe(true) + expect(updateResult.current.data).toBeDefined() + expect(updateResult.current.data.bucketId).toBe('test-bucket') + expect(updateResult.current.data.name).toBe('updated-file.txt') + }) + }) + + test('useFiles', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + const { result: filesResult } = renderHook( + () => useFiles({ bucketId: 'test-bucket', search: 'updated-file' }), + { wrapper }, + ) + + await waitFor(() => { + expect(filesResult.current.isSuccess).toBe(true) + expect(filesResult.current.data).toBeDefined() + expect(filesResult.current.data.total).toBe(1) + expect(filesResult.current.data.files[0].name).toBe('updated-file.txt') + }) + }) + + test('useDeleteFile', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + const { result: deleteResult } = renderHook(() => useDeleteFile(), { wrapper }) + + expect(deleteResult.current).toBeDefined() + + await act(async () => { + await deleteResult.current.mutateAsync({ + bucketId: 'test-bucket', + fileId: 'test-file', + }) + }) + + await waitFor(() => { + expect(deleteResult.current.isSuccess).toBe(true) + }) + }) + }) + describe('useFileDownload', () => { test('returns a download URL for a file', () => { const wrapper = createWrapper() diff --git a/tests/teams/teams.test.tsx b/tests/teams/teams.test.tsx index 5d80f16..ae60427 100644 --- a/tests/teams/teams.test.tsx +++ b/tests/teams/teams.test.tsx @@ -1,25 +1,37 @@ +import { within } from '@testing-library/dom' import { act, renderHook, waitFor } from '@testing-library/react' -import { afterAll, beforeAll, describe, expect, test } from 'bun:test' +import { afterAll, afterEach, beforeAll, describe, expect, test } from 'bun:test' +import { URLSearchParams } from 'happy-dom' import { Client as ServerClient, ID as ServerID, Teams as ServerTeams } from 'node-appwrite' import { useCreateMembership, useCreateTeam, + useDeleteMembership, useDeleteTeam, - useLogin, useTeam, + useTeamMembership, useTeamMemberships, useTeamPrefs, useTeams, + useUpdateMembership, + useUpdateMembershipStatus, useUpdateTeamName, - useUpdateTeamPrefs + useUpdateTeamPrefs, } from '../../src' import { ID } from '../../src/types' -import { createTestUser, deleteTestUser, getTestConfig } from '../setup/helpers' +import { + checkMail, + createTestUser, + deleteTestUser, + emptyMail, + getTestConfig, + loginUser, + logoutUser, + renderMessage, +} from '../setup/helpers' import { createWrapper } from '../setup/wrapper' -type Wrapper = ReturnType - function createServerTeams() { const config = getTestConfig() const client = new ServerClient() @@ -29,16 +41,6 @@ function createServerTeams() { return new ServerTeams(client) } -async function loginUser(email: string, password: string, wrapper: Wrapper) { - const { result } = renderHook(() => useLogin(), { wrapper }) - - await act(async () => { - result.current.login.mutateAsync({ email, password }) - }) - - await waitFor(() => expect(result.current.login.isSuccess).toBe(true)) -} - describe('Teams hooks', () => { let userId: string let userEmail: string @@ -56,7 +58,7 @@ describe('Teams hooks', () => { const teams = createServerTeams() for (const teamId of createdTeamIds) { try { - await teams.delete(teamId) + await teams.delete({ teamId }) } catch { // Team may already be deleted } @@ -74,7 +76,7 @@ describe('Teams hooks', () => { const teamId = ID.unique() await act(async () => { - result.current.mutateAsync({ teamId, name: 'Test Team' }) + await result.current.mutateAsync({ teamId, name: 'Test Team' }) }) await waitFor(() => expect(result.current.isSuccess).toBe(true)) @@ -95,7 +97,7 @@ describe('Teams hooks', () => { const { result: createResult } = renderHook(() => useCreateTeam(), { wrapper }) const teamId = ID.unique() await act(async () => { - createResult.current.mutateAsync({ teamId, name: 'List Test Team' }) + await createResult.current.mutateAsync({ teamId, name: 'List Test Team' }) }) await waitFor(() => expect(createResult.current.isSuccess).toBe(true)) createdTeamIds.push(teamId) @@ -147,7 +149,7 @@ describe('Teams hooks', () => { const { result: createResult } = renderHook(() => useCreateTeam(), { wrapper }) const teamId = ID.unique() await act(async () => { - createResult.current.mutateAsync({ teamId, name: 'Old Name' }) + await createResult.current.mutateAsync({ teamId, name: 'Old Name' }) }) await waitFor(() => expect(createResult.current.isSuccess).toBe(true)) createdTeamIds.push(teamId) @@ -155,7 +157,7 @@ describe('Teams hooks', () => { const { result } = renderHook(() => useUpdateTeamName(), { wrapper }) await act(async () => { - result.current.mutateAsync({ teamId, name: 'New Name' }) + await result.current.mutateAsync({ teamId, name: 'New Name' }) }) await waitFor(() => expect(result.current.isSuccess).toBe(true)) @@ -186,7 +188,7 @@ describe('Teams hooks', () => { const { result: updateResult } = renderHook(() => useUpdateTeamPrefs(), { wrapper }) await act(async () => { - updateResult.current.mutateAsync({ teamId, prefs: { color: 'blue' } }) + await updateResult.current.mutateAsync({ teamId, prefs: { color: 'blue' } }) }) await waitFor(() => expect(updateResult.current.isSuccess).toBe(true)) @@ -208,14 +210,14 @@ describe('Teams hooks', () => { const { result: createResult } = renderHook(() => useCreateTeam(), { wrapper }) const teamId = ID.unique() await act(async () => { - createResult.current.mutateAsync({ teamId, name: 'Delete Me' }) + await createResult.current.mutateAsync({ teamId, name: 'Delete Me' }) }) await waitFor(() => expect(createResult.current.isSuccess).toBe(true)) const { result } = renderHook(() => useDeleteTeam(), { wrapper }) await act(async () => { - result.current.mutateAsync({ teamId }) + await result.current.mutateAsync({ teamId }) }) await waitFor(() => expect(result.current.isSuccess).toBe(true)) @@ -237,6 +239,11 @@ describe('Teams hooks', () => { await teams.createMembership({ teamId, roles: ['owner'], email: userEmail }) }) + afterEach(async () => { + await emptyMail() + document.body.innerHTML = '' + }) + test('lists team memberships', async () => { const wrapper = createWrapper() await loginUser(userEmail, userPassword, wrapper) @@ -260,7 +267,7 @@ describe('Teams hooks', () => { const { result } = renderHook(() => useCreateMembership(), { wrapper }) await act(async () => { - result.current.mutate({ + await result.current.mutateAsync({ teamId, roles: ['member'], userId: invited.userId, @@ -268,8 +275,6 @@ describe('Teams hooks', () => { }) }) - // SMTP is not configured in test env, so this may fail with SMTP error - // We verify the hook executes and returns either success or a known SMTP error await waitFor(() => expect(result.current.isSuccess || result.current.isError).toBe(true)) if (result.current.isSuccess) { @@ -279,5 +284,139 @@ describe('Teams hooks', () => { await deleteTestUser(invited.userId) }) + + test('updates team memberships after creating a membership', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + // Create another user to invite + const invited = await createTestUser({ name: 'Membership Update Test User' }) + + const { result } = renderHook(() => useCreateMembership(), { wrapper }) + + await act(async () => { + await result.current.mutateAsync({ + teamId, + roles: ['member'], + userId: invited.userId, + url: 'http://localhost/accept', + }) + }) + + await waitFor(() => expect(result.current.isSuccess || result.current.isError).toBe(true)) + + const { result: membershipsResult } = renderHook(() => useUpdateMembership(), { wrapper }) + + await act(async () => { + await membershipsResult.current.mutateAsync({ + teamId, + membershipId: result.current.data?._id || '', + roles: ['admin'], + }) + }) + + await waitFor(() => expect(membershipsResult.current.isSuccess).toBe(true)) + + expect(membershipsResult.current.data).toBeDefined() + expect(membershipsResult.current.data?.roles).toContain('admin') + }) + + test('acknowledges invite email', async () => { + const wrapper = createWrapper() + await loginUser(userEmail, userPassword, wrapper) + + // Create another user to invite + const invited = await createTestUser({ name: 'Membership Update Test User' }) + + const { result } = renderHook(() => useCreateMembership(), { wrapper }) + + await act(async () => { + await result.current.mutateAsync({ + teamId, + roles: ['member'], + userId: invited.userId, + url: 'http://localhost/accept', + }) + }) + + await waitFor(() => expect(result.current.isSuccess || result.current.isError).toBe(true)) + + await logoutUser(wrapper) + + await act(async () => { + await new Promise((r) => setTimeout(r, 3000)) + }) + + const message = await waitFor(async () => { + const emails = await checkMail() + expect(emails.messages.length).toBeGreaterThan(0) + return emails.messages[0] + }) + + await renderMessage(message.ID) + const emailBody = within(document.body) + + expect(emailBody.getByText(/Accept invite to Membership Team Test/)).toBeDefined() + + const button = emailBody.getByText(/Accept invite to Membership Team Test/) + + expect(button.getAttribute('href')).toBeDefined() + + const url = new URL(button.getAttribute('href') || '') + expect(url.pathname).toBe('/accept') + + const params = new URLSearchParams(url.search) + + expect(params.get('teamId')).toBe(teamId) + expect(params.get('membershipId')).toBe(result.current.data?._id) + expect(params.get('userId')).toBe(invited.userId) + expect(params.get('secret')).toBeDefined() + + const { result: updateMembershipStatusResult } = renderHook( + () => useUpdateMembershipStatus(), + { wrapper }, + ) + + await act(async () => { + await updateMembershipStatusResult.current.mutateAsync({ + teamId, + membershipId: result.current.data?._id || '', + userId: invited.userId, + secret: params.get('secret') || '', + }) + }) + + await waitFor(() => + expect( + updateMembershipStatusResult.current.isSuccess || + updateMembershipStatusResult.current.isError, + ).toBe(true), + ) + + const { result: teamMembershipResult } = renderHook( + () => useTeamMembership({ teamId, membershipId: result.current.data?._id || '' }), + { wrapper }, + ) + + await waitFor(() => expect(teamMembershipResult.current.isSuccess).toBe(true)) + + expect(teamMembershipResult.current.data).toBeDefined() + expect(teamMembershipResult.current.data?.teamName).toBe('Membership Team Test') + + const { result: deleteMembershipResult } = renderHook(() => useDeleteMembership(), { + wrapper, + }) + + await act(async () => { + await deleteMembershipResult.current.mutateAsync({ + teamId, + membershipId: result.current.data?._id || '', + }) + }) + + await waitFor(() => expect(deleteMembershipResult.current.isSuccess).toBe(true)) + + await deleteTestUser(invited.userId) + }) }) }) diff --git a/tsconfig.json b/tsconfig.json index 6dac90d..74e3eec 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -5,6 +5,13 @@ "sourceMap": true, "outDir": "./out", "skipLibCheck": true, - "jsx": "react" + "jsx": "react", + "plugins": [ + { + "name": "gql.tada/ts-plugin", + "schema": "./src/schema.graphql", + "tadaOutputLocation": "./src/graphql-env.d.ts" + } + ] } } diff --git a/tsup.config.ts b/tsup.config.ts index 0c6bc85..c7e4ee2 100644 --- a/tsup.config.ts +++ b/tsup.config.ts @@ -10,4 +10,5 @@ export default defineConfig({ clean: true, treeshake: true, minify: true, + external: ['react'], }) diff --git a/tsup.native.config.ts b/tsup.native.config.ts index d282b20..951936c 100644 --- a/tsup.native.config.ts +++ b/tsup.native.config.ts @@ -10,4 +10,5 @@ export default defineConfig({ clean: true, treeshake: true, minify: true, + external: ['react-native', 'react'], })